1a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* libs/diskconfig/diskconfig.c 2a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 3a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Copyright 2008, The Android Open Source Project 4a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 5a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 6a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * you may not use this file except in compliance with the License. 7a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * You may obtain a copy of the License at 8a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 9a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * http://www.apache.org/licenses/LICENSE-2.0 10a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 11a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Unless required by applicable law or agreed to in writing, software 12a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * distributed under the License is distributed on an "AS IS" BASIS, 13a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * See the License for the specific language governing permissions and 15a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * limitations under the License. 16a6391f1006b961ca89d1c79a826375380684a4deSan Mehat */ 17a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 18a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#define LOG_TAG "diskconfig" 19a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 20a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <errno.h> 21a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <fcntl.h> 22ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes#include <inttypes.h> 23a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdio.h> 24a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdlib.h> 25a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <string.h> 26a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <unistd.h> 27a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <sys/ioctl.h> 28a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <sys/stat.h> 29a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 30a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <linux/fs.h> 31a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 32a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <cutils/config_utils.h> 331874e6557cbaf36e6893e502d4cdd7c645444b8fMark Salyzyn#include <log/log.h> 34a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 35a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <diskconfig/diskconfig.h> 36a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 37a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 38a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 39a6391f1006b961ca89d1c79a826375380684a4deSan Mehatparse_len(const char *str, uint64_t *plen) 40a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 41a6391f1006b961ca89d1c79a826375380684a4deSan Mehat char tmp[64]; 42a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int len_str; 43a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint32_t multiple = 1; 44a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 45a6391f1006b961ca89d1c79a826375380684a4deSan Mehat strncpy(tmp, str, sizeof(tmp)); 46a6391f1006b961ca89d1c79a826375380684a4deSan Mehat tmp[sizeof(tmp)-1] = '\0'; 47a6391f1006b961ca89d1c79a826375380684a4deSan Mehat len_str = strlen(tmp); 48a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!len_str) { 4901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid disk length specified."); 50a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 51a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 52a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 53a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch(tmp[len_str - 1]) { 54a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case 'M': case 'm': 55a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* megabyte */ 56a6391f1006b961ca89d1c79a826375380684a4deSan Mehat multiple <<= 10; 57a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case 'K': case 'k': 58a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* kilobytes */ 59a6391f1006b961ca89d1c79a826375380684a4deSan Mehat multiple <<= 10; 60a6391f1006b961ca89d1c79a826375380684a4deSan Mehat tmp[len_str - 1] = '\0'; 61a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 62a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 63a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 64a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 65a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 66a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *plen = strtoull(tmp, NULL, 0); 67a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!*plen) { 6801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid length specified: %s", str); 69a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 70a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 71a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 72a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (*plen == (uint64_t)-1) { 73a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (multiple > 1) { 7401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Size modifier illegal when len is -1"); 75a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 76a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 77a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 78a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* convert len to kilobytes */ 79a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (multiple > 1024) 80a6391f1006b961ca89d1c79a826375380684a4deSan Mehat multiple >>= 10; 81a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *plen *= multiple; 82a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 83a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (*plen > 0xffffffffULL) { 84ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes ALOGE("Length specified is too large!: %"PRIu64" KB", *plen); 85a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 86a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 87a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 88a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 89a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 90a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 91a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 92a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 93a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 94a6391f1006b961ca89d1c79a826375380684a4deSan Mehatload_partitions(cnode *root, struct disk_info *dinfo) 95a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 96a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *partnode; 97a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 98a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_parts = 0; 99a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (partnode = root->first_child; partnode; partnode = partnode->next) { 100a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *pinfo = &dinfo->part_lst[dinfo->num_parts]; 101a6391f1006b961ca89d1c79a826375380684a4deSan Mehat const char *tmp; 102a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 103a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* bleh, i will leak memory here, but i DONT CARE since 104a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * the only right thing to do when this function fails 105a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * is to quit */ 106a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->name = strdup(partnode->name); 107a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 108a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if(config_bool(partnode, "active", 0)) 109a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->flags |= PART_ACTIVE_FLAG; 110a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 111a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(partnode, "type", NULL))) { 11201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Partition type required: %s", pinfo->name); 113a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 114a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 115a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 116a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* possible values are: linux, fat32 */ 117a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!strcmp(tmp, "linux")) { 118a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->type = PC_PART_TYPE_LINUX; 119a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (!strcmp(tmp, "fat32")) { 120a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->type = PC_PART_TYPE_FAT32; 121a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 12201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unsupported partition type found: %s", tmp); 123a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 124a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 125a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 126a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((tmp = config_str(partnode, "len", NULL)) != NULL) { 127a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t len; 128a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (parse_len(tmp, &len)) 129a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 130a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->len_kb = (uint32_t) len; 131a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else 132a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->len_kb = 0; 133a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 134a6391f1006b961ca89d1c79a826375380684a4deSan Mehat ++dinfo->num_parts; 135a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 136a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 137a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 138a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 139a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 140a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstruct disk_info * 141a6391f1006b961ca89d1c79a826375380684a4deSan Mehatload_diskconfig(const char *fn, char *path_override) 142a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 143a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct disk_info *dinfo; 144a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *devroot; 145a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *partnode; 146a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *root = config_node("", ""); 147a6391f1006b961ca89d1c79a826375380684a4deSan Mehat const char *tmp; 148a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 149a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(dinfo = malloc(sizeof(struct disk_info)))) { 15001dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not malloc disk_info"); 151a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 152a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 153a6391f1006b961ca89d1c79a826375380684a4deSan Mehat memset(dinfo, 0, sizeof(struct disk_info)); 154a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 155a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(dinfo->part_lst = malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) { 15601dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not malloc part_lst"); 157a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 158a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 159a6391f1006b961ca89d1c79a826375380684a4deSan Mehat memset(dinfo->part_lst, 0, 160a6391f1006b961ca89d1c79a826375380684a4deSan Mehat (MAX_NUM_PARTS * sizeof(struct part_info))); 161a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 162a6391f1006b961ca89d1c79a826375380684a4deSan Mehat config_load_file(root, fn); 163a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (root->first_child == NULL) { 16401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not read config file %s", fn); 165a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 166a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 167a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 168a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(devroot = config_find(root, "device"))) { 16901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not find device section in config file '%s'", fn); 170a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 171a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 172a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 173a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 174a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "path", path_override))) { 17501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("device path is requried"); 176a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 177a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 178a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->device = strdup(tmp); 179a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 180a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* find the partition scheme */ 181a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "scheme", NULL))) { 18201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("partition scheme is required"); 183a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 184a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (!strcmp(tmp, "mbr")) { 185a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->scheme = PART_SCHEME_MBR; 186a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (!strcmp(tmp, "gpt")) { 18701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("'gpt' partition scheme not supported yet."); 188a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 189a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 19001dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unknown partition scheme specified: %s", tmp); 191a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 192a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 193a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 194a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* grab the sector size (in bytes) */ 195a6391f1006b961ca89d1c79a826375380684a4deSan Mehat tmp = config_str(devroot, "sector_size", "512"); 196a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->sect_size = strtol(tmp, NULL, 0); 197a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo->sect_size) { 19801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid sector size: %s", tmp); 199a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 200a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 201a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 202a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* first lba where the partitions will start on disk */ 203a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "start_lba", NULL))) { 20401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("start_lba must be provided"); 205a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 206a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 207a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 208a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(dinfo->skip_lba = strtol(tmp, NULL, 0))) { 20901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid starting LBA (or zero): %s", tmp); 210a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 211a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 212a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 213a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* Number of LBAs on disk */ 214a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "num_lba", NULL))) { 21501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("num_lba is required"); 216a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 217a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 218a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_lba = strtoul(tmp, NULL, 0); 219a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 220a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(partnode = config_find(devroot, "partitions"))) { 22101dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Device must specify partition list"); 222a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 223a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 224a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 225a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (load_partitions(partnode, dinfo)) 226a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 227a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 228a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return dinfo; 229a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 230a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 231a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dinfo->part_lst) 232a6391f1006b961ca89d1c79a826375380684a4deSan Mehat free(dinfo->part_lst); 233a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dinfo->device) 234a6391f1006b961ca89d1c79a826375380684a4deSan Mehat free(dinfo->device); 235a6391f1006b961ca89d1c79a826375380684a4deSan Mehat free(dinfo); 236a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 237a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 238a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 239a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 240a6391f1006b961ca89d1c79a826375380684a4deSan Mehatsync_ptable(int fd) 241a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 242a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct stat stat; 243a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int rv; 244a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 245a6391f1006b961ca89d1c79a826375380684a4deSan Mehat sync(); 246a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 247a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (fstat(fd, &stat)) { 24801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot stat, errno=%d.", errno); 249a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 250a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 251a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 252a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (S_ISBLK(stat.st_mode) && ((rv = ioctl(fd, BLKRRPART, NULL)) < 0)) { 25301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not re-read partition table. REBOOT!. (errno=%d)", errno); 254a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 255a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 256a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 257a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 258a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 259a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 260a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* This function verifies that the disk info provided is valid, and if so, 261a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * returns an open file descriptor. 262a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 263a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * This does not necessarily mean that it will later be successfully written 264a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * though. If we use the pc-bios partitioning scheme, we must use extended 265a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * partitions, which eat up some hd space. If the user manually provisioned 266a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * every single partition, but did not account for the extra needed space, 267a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * then we will later fail. 268a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 269a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * TODO: Make validation more complete. 270a6391f1006b961ca89d1c79a826375380684a4deSan Mehat */ 271a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 272a6391f1006b961ca89d1c79a826375380684a4deSan Mehatvalidate(struct disk_info *dinfo) 273a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 274a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int fd; 275a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int sect_sz; 276a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t disk_size; 277a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t total_size; 278a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int cnt; 279a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct stat stat; 280a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 281a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo) 282a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 283a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 284a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((fd = open(dinfo->device, O_RDWR)) < 0) { 28501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot open device '%s' (errno=%d)", dinfo->device, errno); 286a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 287a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 288a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 289a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (fstat(fd, &stat)) { 29001dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot stat file '%s', errno=%d.", dinfo->device, errno); 291a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 292a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 293a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 294a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 295a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: Some of the code below is kind of redundant and should probably 296a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * be refactored a little, but it will do for now. */ 297a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 298a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* Verify that we can operate on the device that was requested. 299a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * We presently only support block devices and regular file images. */ 300a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (S_ISBLK(stat.st_mode)) { 301a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* get the sector size and make sure we agree */ 302a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (ioctl(fd, BLKSSZGET, §_sz) < 0) { 30301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot get sector size (errno=%d)", errno); 304a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 305a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 306a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 307a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!sect_sz || sect_sz != dinfo->sect_size) { 30801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Device sector size is zero or sector sizes do not match!"); 309a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 310a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 311a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 312a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* allow the user override the "disk size" if they provided num_lba */ 313a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo->num_lba) { 314a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (ioctl(fd, BLKGETSIZE64, &disk_size) < 0) { 31501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not get block device size (errno=%d)", errno); 316a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 317a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 318a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: we assume that the disk has < 2^32 sectors :-) */ 319a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_lba = (uint32_t)(disk_size / (uint64_t)dinfo->sect_size); 320a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else 321a6391f1006b961ca89d1c79a826375380684a4deSan Mehat disk_size = (uint64_t)dinfo->num_lba * (uint64_t)dinfo->sect_size; 322a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (S_ISREG(stat.st_mode)) { 323fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("Requesting operation on a regular file, not block device."); 324a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo->sect_size) { 32501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Sector size for regular file images cannot be zero"); 326a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 327a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 328a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dinfo->num_lba) 329a6391f1006b961ca89d1c79a826375380684a4deSan Mehat disk_size = (uint64_t)dinfo->num_lba * (uint64_t)dinfo->sect_size; 330a6391f1006b961ca89d1c79a826375380684a4deSan Mehat else { 331a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_lba = (uint32_t)(stat.st_size / dinfo->sect_size); 332a6391f1006b961ca89d1c79a826375380684a4deSan Mehat disk_size = (uint64_t)stat.st_size; 333a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 334a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 33501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Device does not refer to a regular file or a block device!"); 336a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 337a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 338a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 339a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#if 1 3401874e6557cbaf36e6893e502d4cdd7c645444b8fMark Salyzyn ALOGV("Device/file %s: size=%" PRIu64 " bytes, num_lba=%u, sect_size=%d", 341a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->device, disk_size, dinfo->num_lba, dinfo->sect_size); 342a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#endif 343a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 344a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* since this is our offset into the disk, we start off with that as 345a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * our size of needed partitions */ 346a6391f1006b961ca89d1c79a826375380684a4deSan Mehat total_size = dinfo->skip_lba * dinfo->sect_size; 347a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 348a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* add up all the partition sizes and make sure it fits */ 349a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (cnt = 0; cnt < dinfo->num_parts; ++cnt) { 350a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *part = &dinfo->part_lst[cnt]; 351a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (part->len_kb != (uint32_t)-1) { 352a6391f1006b961ca89d1c79a826375380684a4deSan Mehat total_size += part->len_kb * 1024; 353a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (part->len_kb == 0) { 35401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Zero-size partition '%s' is invalid.", part->name); 355a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 356a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 357a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* the partition requests the rest of the disk. */ 358a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (cnt + 1 != dinfo->num_parts) { 35901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Only the last partition in the list can request to fill " 360a6391f1006b961ca89d1c79a826375380684a4deSan Mehat "the rest of disk."); 361a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 362a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 363a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 364a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 365a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((part->type != PC_PART_TYPE_LINUX) && 366a6391f1006b961ca89d1c79a826375380684a4deSan Mehat (part->type != PC_PART_TYPE_FAT32)) { 36701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unknown partition type (0x%x) encountered for partition " 368a6391f1006b961ca89d1c79a826375380684a4deSan Mehat "'%s'\n", part->type, part->name); 369a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 370a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 371a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 372a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 373a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* only matters for disks, not files */ 374a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (S_ISBLK(stat.st_mode) && total_size > disk_size) { 375ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes ALOGE("Total requested size of partitions (%"PRIu64") is greater than disk " 376ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes "size (%"PRIu64").", total_size, disk_size); 377a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 378a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 379a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 380a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return fd; 381a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 382a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 383a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 384a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 385a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 386a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 387a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 388a6391f1006b961ca89d1c79a826375380684a4deSan Mehatvalidate_and_config(struct disk_info *dinfo, int *fd, struct write_list **lst) 389a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 390a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *lst = NULL; 391a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *fd = -1; 392a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 393a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((*fd = validate(dinfo)) < 0) 394a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 395a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 396a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch (dinfo->scheme) { 397a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_MBR: 398a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *lst = config_mbr(dinfo); 399a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return *lst == NULL; 400a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_GPT: 401a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* not supported yet */ 402a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 40301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Uknown partition scheme."); 404a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 405a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 406a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 407a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(*fd); 408a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *lst = NULL; 409a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 410a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 411a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 412a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* validate and process the disk layout configuration. 413a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * This will cause an update to the partitions' start lba. 414a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 415a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Basically, this does the same thing as apply_disk_config in test mode, 416a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * except that wlist_commit is not called to print out the data to be 417a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * written. 418a6391f1006b961ca89d1c79a826375380684a4deSan Mehat */ 419a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 420a6391f1006b961ca89d1c79a826375380684a4deSan Mehatprocess_disk_config(struct disk_info *dinfo) 421a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 422a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct write_list *lst; 423a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int fd; 424a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 425a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (validate_and_config(dinfo, &fd, &lst) != 0) 426a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 427a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 428a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 429a6391f1006b961ca89d1c79a826375380684a4deSan Mehat wlist_free(lst); 430a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 431a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 432a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 433a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 434a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 435a6391f1006b961ca89d1c79a826375380684a4deSan Mehatapply_disk_config(struct disk_info *dinfo, int test) 436a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 437a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int fd; 438a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct write_list *wr_lst = NULL; 439a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int rv; 440a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 441a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (validate_and_config(dinfo, &fd, &wr_lst) != 0) { 44201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Configuration is invalid."); 443a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 444a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 445a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 446a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((rv = wlist_commit(fd, wr_lst, test)) >= 0) 447a6391f1006b961ca89d1c79a826375380684a4deSan Mehat rv = test ? 0 : sync_ptable(fd); 448a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 449a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 450a6391f1006b961ca89d1c79a826375380684a4deSan Mehat wlist_free(wr_lst); 451a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return rv; 452a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 453a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 454a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 455a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (wr_lst) 456a6391f1006b961ca89d1c79a826375380684a4deSan Mehat wlist_free(wr_lst); 457a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 458a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 459a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 460a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 461a6391f1006b961ca89d1c79a826375380684a4deSan Mehatdump_disk_config(struct disk_info *dinfo) 462a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 463a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int cnt; 464a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *part; 465a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 466a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Device: %s\n", dinfo->device); 467a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Scheme: "); 468a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch (dinfo->scheme) { 469a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_MBR: 470a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("MBR"); 471a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 472a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_GPT: 473a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("GPT (unsupported)"); 474a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 475a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 476a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Unknown"); 477a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 478a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 479a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf ("\n"); 480a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 481a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Sector size: %d\n", dinfo->sect_size); 482a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Skip leading LBAs: %u\n", dinfo->skip_lba); 483a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Number of LBAs: %u\n", dinfo->num_lba); 484a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Partitions:\n"); 485a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 486a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (cnt = 0; cnt < dinfo->num_parts; ++cnt) { 487a6391f1006b961ca89d1c79a826375380684a4deSan Mehat part = &dinfo->part_lst[cnt]; 488a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\tname = %s\n", part->name); 489a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\tflags = %s\n", 490a6391f1006b961ca89d1c79a826375380684a4deSan Mehat part->flags & PART_ACTIVE_FLAG ? "Active" : "None"); 491a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\ttype = %s\n", 492a6391f1006b961ca89d1c79a826375380684a4deSan Mehat part->type == PC_PART_TYPE_LINUX ? "Linux" : "Unknown"); 493a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (part->len_kb == (uint32_t)-1) 494a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\tlen = rest of disk\n"); 495a6391f1006b961ca89d1c79a826375380684a4deSan Mehat else 496a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\tlen = %uKB\n", part->len_kb); 497a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 498a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Total number of partitions: %d\n", cnt); 499a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\n"); 500a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 501a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 502a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 503a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 504a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstruct part_info * 505a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfind_part(struct disk_info *dinfo, const char *name) 506a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 507a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *pinfo; 508a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int cnt; 509a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 510a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (cnt = 0; cnt < dinfo->num_parts; ++cnt) { 511a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo = &dinfo->part_lst[cnt]; 512a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!strcmp(pinfo->name, name)) 513a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return pinfo; 514a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 515a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 516a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 517a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 518a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 519a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* NOTE: If the returned ptr is non-NULL, it must be freed by the caller. */ 520a6391f1006b961ca89d1c79a826375380684a4deSan Mehatchar * 521a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfind_part_device(struct disk_info *dinfo, const char *name) 522a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 523a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch (dinfo->scheme) { 524a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_MBR: 525a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return find_mbr_part(dinfo, name); 526a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_GPT: 52701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("GPT is presently not supported"); 528a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 529a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 53001dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unknown partition table scheme"); 531a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 532a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 533a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 534a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 535a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 536a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 537a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 538