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> 22a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdio.h> 23a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdlib.h> 24a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <string.h> 25a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <unistd.h> 26a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <sys/ioctl.h> 27a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <sys/stat.h> 28a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 29a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <linux/fs.h> 30a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 31a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <cutils/config_utils.h> 32a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <cutils/log.h> 33a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 34a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <diskconfig/diskconfig.h> 35a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 36a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 37a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 38a6391f1006b961ca89d1c79a826375380684a4deSan Mehatparse_len(const char *str, uint64_t *plen) 39a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 40a6391f1006b961ca89d1c79a826375380684a4deSan Mehat char tmp[64]; 41a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int len_str; 42a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint32_t multiple = 1; 43a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 44a6391f1006b961ca89d1c79a826375380684a4deSan Mehat strncpy(tmp, str, sizeof(tmp)); 45a6391f1006b961ca89d1c79a826375380684a4deSan Mehat tmp[sizeof(tmp)-1] = '\0'; 46a6391f1006b961ca89d1c79a826375380684a4deSan Mehat len_str = strlen(tmp); 47a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!len_str) { 4801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid disk length specified."); 49a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 50a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 51a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 52a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch(tmp[len_str - 1]) { 53a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case 'M': case 'm': 54a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* megabyte */ 55a6391f1006b961ca89d1c79a826375380684a4deSan Mehat multiple <<= 10; 56a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case 'K': case 'k': 57a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* kilobytes */ 58a6391f1006b961ca89d1c79a826375380684a4deSan Mehat multiple <<= 10; 59a6391f1006b961ca89d1c79a826375380684a4deSan Mehat tmp[len_str - 1] = '\0'; 60a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 61a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 62a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 63a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 64a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 65a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *plen = strtoull(tmp, NULL, 0); 66a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!*plen) { 6701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid length specified: %s", str); 68a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 69a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 70a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 71a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (*plen == (uint64_t)-1) { 72a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (multiple > 1) { 7301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Size modifier illegal when len is -1"); 74a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 75a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 76a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 77a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* convert len to kilobytes */ 78a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (multiple > 1024) 79a6391f1006b961ca89d1c79a826375380684a4deSan Mehat multiple >>= 10; 80a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *plen *= multiple; 81a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 82a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (*plen > 0xffffffffULL) { 8301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Length specified is too large!: %llu KB", *plen); 84a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 85a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 86a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 87a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 88a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 89a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 90a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 91a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 92a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 93a6391f1006b961ca89d1c79a826375380684a4deSan Mehatload_partitions(cnode *root, struct disk_info *dinfo) 94a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 95a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *partnode; 96a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 97a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_parts = 0; 98a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (partnode = root->first_child; partnode; partnode = partnode->next) { 99a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *pinfo = &dinfo->part_lst[dinfo->num_parts]; 100a6391f1006b961ca89d1c79a826375380684a4deSan Mehat const char *tmp; 101a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 102a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* bleh, i will leak memory here, but i DONT CARE since 103a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * the only right thing to do when this function fails 104a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * is to quit */ 105a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->name = strdup(partnode->name); 106a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 107a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if(config_bool(partnode, "active", 0)) 108a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->flags |= PART_ACTIVE_FLAG; 109a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 110a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(partnode, "type", NULL))) { 11101dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Partition type required: %s", pinfo->name); 112a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 113a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 114a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 115a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* possible values are: linux, fat32 */ 116a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!strcmp(tmp, "linux")) { 117a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->type = PC_PART_TYPE_LINUX; 118a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (!strcmp(tmp, "fat32")) { 119a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->type = PC_PART_TYPE_FAT32; 120a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 12101dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unsupported partition type found: %s", tmp); 122a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 123a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 124a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 125a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((tmp = config_str(partnode, "len", NULL)) != NULL) { 126a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t len; 127a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (parse_len(tmp, &len)) 128a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 129a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->len_kb = (uint32_t) len; 130a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else 131a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo->len_kb = 0; 132a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 133a6391f1006b961ca89d1c79a826375380684a4deSan Mehat ++dinfo->num_parts; 134a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 135a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 136a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 137a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 138a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 139a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstruct disk_info * 140a6391f1006b961ca89d1c79a826375380684a4deSan Mehatload_diskconfig(const char *fn, char *path_override) 141a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 142a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct disk_info *dinfo; 143a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *devroot; 144a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *partnode; 145a6391f1006b961ca89d1c79a826375380684a4deSan Mehat cnode *root = config_node("", ""); 146a6391f1006b961ca89d1c79a826375380684a4deSan Mehat const char *tmp; 147a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 148a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(dinfo = malloc(sizeof(struct disk_info)))) { 14901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not malloc disk_info"); 150a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 151a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 152a6391f1006b961ca89d1c79a826375380684a4deSan Mehat memset(dinfo, 0, sizeof(struct disk_info)); 153a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 154a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(dinfo->part_lst = malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) { 15501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not malloc part_lst"); 156a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 157a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 158a6391f1006b961ca89d1c79a826375380684a4deSan Mehat memset(dinfo->part_lst, 0, 159a6391f1006b961ca89d1c79a826375380684a4deSan Mehat (MAX_NUM_PARTS * sizeof(struct part_info))); 160a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 161a6391f1006b961ca89d1c79a826375380684a4deSan Mehat config_load_file(root, fn); 162a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (root->first_child == NULL) { 16301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not read config file %s", fn); 164a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 165a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 166a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 167a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(devroot = config_find(root, "device"))) { 16801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not find device section in config file '%s'", fn); 169a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 170a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 171a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 172a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 173a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "path", path_override))) { 17401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("device path is requried"); 175a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 176a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 177a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->device = strdup(tmp); 178a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 179a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* find the partition scheme */ 180a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "scheme", NULL))) { 18101dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("partition scheme is required"); 182a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 183a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (!strcmp(tmp, "mbr")) { 184a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->scheme = PART_SCHEME_MBR; 185a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (!strcmp(tmp, "gpt")) { 18601dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("'gpt' partition scheme not supported yet."); 187a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 188a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 18901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unknown partition scheme specified: %s", tmp); 190a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 191a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 192a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 193a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* grab the sector size (in bytes) */ 194a6391f1006b961ca89d1c79a826375380684a4deSan Mehat tmp = config_str(devroot, "sector_size", "512"); 195a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->sect_size = strtol(tmp, NULL, 0); 196a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo->sect_size) { 19701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid sector size: %s", tmp); 198a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 199a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 200a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 201a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* first lba where the partitions will start on disk */ 202a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "start_lba", NULL))) { 20301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("start_lba must be provided"); 204a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 205a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 206a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 207a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(dinfo->skip_lba = strtol(tmp, NULL, 0))) { 20801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Invalid starting LBA (or zero): %s", tmp); 209a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 210a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 211a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 212a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* Number of LBAs on disk */ 213a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(tmp = config_str(devroot, "num_lba", NULL))) { 21401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("num_lba is required"); 215a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 216a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 217a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_lba = strtoul(tmp, NULL, 0); 218a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 219a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!(partnode = config_find(devroot, "partitions"))) { 22001dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Device must specify partition list"); 221a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 222a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 223a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 224a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (load_partitions(partnode, dinfo)) 225a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 226a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 227a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return dinfo; 228a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 229a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 230a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dinfo->part_lst) 231a6391f1006b961ca89d1c79a826375380684a4deSan Mehat free(dinfo->part_lst); 232a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dinfo->device) 233a6391f1006b961ca89d1c79a826375380684a4deSan Mehat free(dinfo->device); 234a6391f1006b961ca89d1c79a826375380684a4deSan Mehat free(dinfo); 235a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 236a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 237a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 238a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 239a6391f1006b961ca89d1c79a826375380684a4deSan Mehatsync_ptable(int fd) 240a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 241a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct stat stat; 242a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int rv; 243a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 244a6391f1006b961ca89d1c79a826375380684a4deSan Mehat sync(); 245a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 246a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (fstat(fd, &stat)) { 24701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot stat, errno=%d.", errno); 248a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 249a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 250a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 251a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (S_ISBLK(stat.st_mode) && ((rv = ioctl(fd, BLKRRPART, NULL)) < 0)) { 25201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not re-read partition table. REBOOT!. (errno=%d)", errno); 253a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 254a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 255a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 256a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 257a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 258a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 259a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* This function verifies that the disk info provided is valid, and if so, 260a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * returns an open file descriptor. 261a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 262a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * This does not necessarily mean that it will later be successfully written 263a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * though. If we use the pc-bios partitioning scheme, we must use extended 264a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * partitions, which eat up some hd space. If the user manually provisioned 265a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * every single partition, but did not account for the extra needed space, 266a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * then we will later fail. 267a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 268a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * TODO: Make validation more complete. 269a6391f1006b961ca89d1c79a826375380684a4deSan Mehat */ 270a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 271a6391f1006b961ca89d1c79a826375380684a4deSan Mehatvalidate(struct disk_info *dinfo) 272a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 273a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int fd; 274a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int sect_sz; 275a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t disk_size; 276a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t total_size; 277a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int cnt; 278a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct stat stat; 279a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 280a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo) 281a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 282a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 283a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((fd = open(dinfo->device, O_RDWR)) < 0) { 28401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot open device '%s' (errno=%d)", dinfo->device, errno); 285a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 286a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 287a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 288a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (fstat(fd, &stat)) { 28901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot stat file '%s', errno=%d.", dinfo->device, errno); 290a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 291a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 292a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 293a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 294a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: Some of the code below is kind of redundant and should probably 295a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * be refactored a little, but it will do for now. */ 296a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 297a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* Verify that we can operate on the device that was requested. 298a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * We presently only support block devices and regular file images. */ 299a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (S_ISBLK(stat.st_mode)) { 300a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* get the sector size and make sure we agree */ 301a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (ioctl(fd, BLKSSZGET, §_sz) < 0) { 30201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Cannot get sector size (errno=%d)", errno); 303a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 304a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 305a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 306a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!sect_sz || sect_sz != dinfo->sect_size) { 30701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Device sector size is zero or sector sizes do not match!"); 308a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 309a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 310a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 311a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* allow the user override the "disk size" if they provided num_lba */ 312a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo->num_lba) { 313a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (ioctl(fd, BLKGETSIZE64, &disk_size) < 0) { 31401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not get block device size (errno=%d)", errno); 315a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 316a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 317a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: we assume that the disk has < 2^32 sectors :-) */ 318a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_lba = (uint32_t)(disk_size / (uint64_t)dinfo->sect_size); 319a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else 320a6391f1006b961ca89d1c79a826375380684a4deSan Mehat disk_size = (uint64_t)dinfo->num_lba * (uint64_t)dinfo->sect_size; 321a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (S_ISREG(stat.st_mode)) { 322fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("Requesting operation on a regular file, not block device."); 323a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!dinfo->sect_size) { 32401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Sector size for regular file images cannot be zero"); 325a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 326a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 327a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dinfo->num_lba) 328a6391f1006b961ca89d1c79a826375380684a4deSan Mehat disk_size = (uint64_t)dinfo->num_lba * (uint64_t)dinfo->sect_size; 329a6391f1006b961ca89d1c79a826375380684a4deSan Mehat else { 330a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->num_lba = (uint32_t)(stat.st_size / dinfo->sect_size); 331a6391f1006b961ca89d1c79a826375380684a4deSan Mehat disk_size = (uint64_t)stat.st_size; 332a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 333a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 33401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Device does not refer to a regular file or a block device!"); 335a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 336a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 337a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 338a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#if 1 33969f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Device/file %s: size=%llu bytes, num_lba=%u, sect_size=%d", 340a6391f1006b961ca89d1c79a826375380684a4deSan Mehat dinfo->device, disk_size, dinfo->num_lba, dinfo->sect_size); 341a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#endif 342a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 343a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* since this is our offset into the disk, we start off with that as 344a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * our size of needed partitions */ 345a6391f1006b961ca89d1c79a826375380684a4deSan Mehat total_size = dinfo->skip_lba * dinfo->sect_size; 346a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 347a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* add up all the partition sizes and make sure it fits */ 348a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (cnt = 0; cnt < dinfo->num_parts; ++cnt) { 349a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *part = &dinfo->part_lst[cnt]; 350a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (part->len_kb != (uint32_t)-1) { 351a6391f1006b961ca89d1c79a826375380684a4deSan Mehat total_size += part->len_kb * 1024; 352a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else if (part->len_kb == 0) { 35301dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Zero-size partition '%s' is invalid.", part->name); 354a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 355a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } else { 356a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* the partition requests the rest of the disk. */ 357a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (cnt + 1 != dinfo->num_parts) { 35801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Only the last partition in the list can request to fill " 359a6391f1006b961ca89d1c79a826375380684a4deSan Mehat "the rest of disk."); 360a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 361a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 362a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 363a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 364a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((part->type != PC_PART_TYPE_LINUX) && 365a6391f1006b961ca89d1c79a826375380684a4deSan Mehat (part->type != PC_PART_TYPE_FAT32)) { 36601dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unknown partition type (0x%x) encountered for partition " 367a6391f1006b961ca89d1c79a826375380684a4deSan Mehat "'%s'\n", part->type, part->name); 368a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 369a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 370a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 371a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 372a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* only matters for disks, not files */ 373a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (S_ISBLK(stat.st_mode) && total_size > disk_size) { 37401dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Total requested size of partitions (%llu) is greater than disk " 375a6391f1006b961ca89d1c79a826375380684a4deSan Mehat "size (%llu).", total_size, disk_size); 376a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 377a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 378a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 379a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return fd; 380a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 381a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 382a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 383a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return -1; 384a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 385a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 386a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstatic int 387a6391f1006b961ca89d1c79a826375380684a4deSan Mehatvalidate_and_config(struct disk_info *dinfo, int *fd, struct write_list **lst) 388a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 389a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *lst = NULL; 390a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *fd = -1; 391a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 392a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((*fd = validate(dinfo)) < 0) 393a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 394a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 395a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch (dinfo->scheme) { 396a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_MBR: 397a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *lst = config_mbr(dinfo); 398a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return *lst == NULL; 399a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_GPT: 400a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* not supported yet */ 401a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 40201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Uknown partition scheme."); 403a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 404a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 405a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 406a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(*fd); 407a6391f1006b961ca89d1c79a826375380684a4deSan Mehat *lst = NULL; 408a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 409a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 410a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 411a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* validate and process the disk layout configuration. 412a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * This will cause an update to the partitions' start lba. 413a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 414a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Basically, this does the same thing as apply_disk_config in test mode, 415a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * except that wlist_commit is not called to print out the data to be 416a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * written. 417a6391f1006b961ca89d1c79a826375380684a4deSan Mehat */ 418a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 419a6391f1006b961ca89d1c79a826375380684a4deSan Mehatprocess_disk_config(struct disk_info *dinfo) 420a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 421a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct write_list *lst; 422a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int fd; 423a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 424a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (validate_and_config(dinfo, &fd, &lst) != 0) 425a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 426a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 427a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 428a6391f1006b961ca89d1c79a826375380684a4deSan Mehat wlist_free(lst); 429a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 430a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 431a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 432a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 433a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 434a6391f1006b961ca89d1c79a826375380684a4deSan Mehatapply_disk_config(struct disk_info *dinfo, int test) 435a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 436a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int fd; 437a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct write_list *wr_lst = NULL; 438a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int rv; 439a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 440a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (validate_and_config(dinfo, &fd, &wr_lst) != 0) { 44101dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Configuration is invalid."); 442a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 443a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 444a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 445a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((rv = wlist_commit(fd, wr_lst, test)) >= 0) 446a6391f1006b961ca89d1c79a826375380684a4deSan Mehat rv = test ? 0 : sync_ptable(fd); 447a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 448a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 449a6391f1006b961ca89d1c79a826375380684a4deSan Mehat wlist_free(wr_lst); 450a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return rv; 451a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 452a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 453a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(fd); 454a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (wr_lst) 455a6391f1006b961ca89d1c79a826375380684a4deSan Mehat wlist_free(wr_lst); 456a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 457a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 458a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 459a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 460a6391f1006b961ca89d1c79a826375380684a4deSan Mehatdump_disk_config(struct disk_info *dinfo) 461a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 462a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int cnt; 463a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *part; 464a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 465a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Device: %s\n", dinfo->device); 466a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Scheme: "); 467a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch (dinfo->scheme) { 468a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_MBR: 469a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("MBR"); 470a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 471a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_GPT: 472a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("GPT (unsupported)"); 473a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 474a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 475a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Unknown"); 476a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 477a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 478a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf ("\n"); 479a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 480a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Sector size: %d\n", dinfo->sect_size); 481a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Skip leading LBAs: %u\n", dinfo->skip_lba); 482a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Number of LBAs: %u\n", dinfo->num_lba); 483a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Partitions:\n"); 484a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 485a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (cnt = 0; cnt < dinfo->num_parts; ++cnt) { 486a6391f1006b961ca89d1c79a826375380684a4deSan Mehat part = &dinfo->part_lst[cnt]; 487a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\tname = %s\n", part->name); 488a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\tflags = %s\n", 489a6391f1006b961ca89d1c79a826375380684a4deSan Mehat part->flags & PART_ACTIVE_FLAG ? "Active" : "None"); 490a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\ttype = %s\n", 491a6391f1006b961ca89d1c79a826375380684a4deSan Mehat part->type == PC_PART_TYPE_LINUX ? "Linux" : "Unknown"); 492a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (part->len_kb == (uint32_t)-1) 493a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\tlen = rest of disk\n"); 494a6391f1006b961ca89d1c79a826375380684a4deSan Mehat else 495a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\t\tlen = %uKB\n", part->len_kb); 496a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 497a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("Total number of partitions: %d\n", cnt); 498a6391f1006b961ca89d1c79a826375380684a4deSan Mehat printf("\n"); 499a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 500a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 501a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 502a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 503a6391f1006b961ca89d1c79a826375380684a4deSan Mehatstruct part_info * 504a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfind_part(struct disk_info *dinfo, const char *name) 505a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 506a6391f1006b961ca89d1c79a826375380684a4deSan Mehat struct part_info *pinfo; 507a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int cnt; 508a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 509a6391f1006b961ca89d1c79a826375380684a4deSan Mehat for (cnt = 0; cnt < dinfo->num_parts; ++cnt) { 510a6391f1006b961ca89d1c79a826375380684a4deSan Mehat pinfo = &dinfo->part_lst[cnt]; 511a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!strcmp(pinfo->name, name)) 512a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return pinfo; 513a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 514a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 515a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 516a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 517a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 518a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* NOTE: If the returned ptr is non-NULL, it must be freed by the caller. */ 519a6391f1006b961ca89d1c79a826375380684a4deSan Mehatchar * 520a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfind_part_device(struct disk_info *dinfo, const char *name) 521a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 522a6391f1006b961ca89d1c79a826375380684a4deSan Mehat switch (dinfo->scheme) { 523a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_MBR: 524a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return find_mbr_part(dinfo, name); 525a6391f1006b961ca89d1c79a826375380684a4deSan Mehat case PART_SCHEME_GPT: 52601dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("GPT is presently not supported"); 527a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 528a6391f1006b961ca89d1c79a826375380684a4deSan Mehat default: 52901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Unknown partition table scheme"); 530a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 531a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 532a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 533a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return NULL; 534a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 535a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 536a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 537