1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #ifndef _LIBFDISK_H_ 28 #define _LIBFDISK_H_ 29 30 #include <limits.h> 31 #include <sys/dktp/fdisk.h> 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #define MAX_LOGDRIVE_OFFSET 63 38 39 #define FDISK_ERRNO 200 40 #define FDISK_ETOOLONG (FDISK_ERRNO + 0) 41 #define FDISK_EOOBOUND (FDISK_ERRNO + 1) 42 #define FDISK_EZERO (FDISK_ERRNO + 2) 43 #define FDISK_EOVERLAP (FDISK_ERRNO + 3) 44 #define FDISK_ENOVGEOM (FDISK_ERRNO + 4) 45 #define FDISK_ENOPGEOM (FDISK_ERRNO + 5) 46 #define FDISK_ENOLGEOM (FDISK_ERRNO + 6) 47 #define FDISK_ENOLOGDRIVE (FDISK_ERRNO + 7) 48 #define FDISK_EBADLOGDRIVE (FDISK_ERRNO + 8) 49 #define FDISK_ENOEXTPART (FDISK_ERRNO + 9) 50 #define FDISK_EBADMAGIC (FDISK_ERRNO + 10) 51 #define FDISK_EMOUNTED (FDISK_ERRNO + 11) 52 53 #define FDISK_SUCCESS 0 54 55 #define FDISK_READ_DISK 0x00000001 56 57 #define LINUX_SWAP_MAGIC_LENGTH 10 58 enum { 59 PHYSGEOM = 0, 60 VIRTGEOM, 61 NCYL, 62 NHEADS, 63 NSECTPT, 64 SSIZE, 65 ACYL 66 }; 67 68 enum { 69 FDISK_MINOR_WRITE = 1, 70 FDISK_MAJOR_WRITE 71 }; 72 73 #define FDISK_SECTS_PER_CYL(epp) \ 74 (epp->disk_geom.phys_heads * epp->disk_geom.phys_sec) 75 #define FDISK_SECT_TO_CYL(epp, x) ((x) / (FDISK_SECTS_PER_CYL(epp))) 76 #define FDISK_CYL_TO_SECT(epp, x) ((x) * (FDISK_SECTS_PER_CYL(epp))) 77 #define FDISK_ABS_CYL_NUM(epp, x) (FDISK_SECT_TO_CYL(x) +\ 78 epp->ext_beg_cyl) 79 80 #define FDISK_CYL_BNDRY_ALIGN(epp, x) (((x) % (FDISK_SECTS_PER_CYL(epp))) ? \ 81 (((x)/(FDISK_SECTS_PER_CYL(epp))) + 1) :\ 82 ((x)/(FDISK_SECTS_PER_CYL(epp)))) 83 84 /* 85 * Extended partition structure : 86 * +--------------+ 87 * |+--+ | 88 * || |----------+---> structure at the beginning of the extended partition 89 * ||--| | ( Lets call it the EBR - Extended Boot Record ) 90 * || | +---+---> 91 * |+--+ | | Logical drive within the extended partition 92 * |+---------+--+| ( We will plainly call this a logical drive ) 93 * || || 94 * || || 95 * || || 96 * |+------------+| 97 * +--------------+ 98 * 99 * 100 * EBR is effectively "struct ipart parts[2]". 101 * The picture below shows what the EBR contains. The EBR has 102 * two important pieces of information. The first is the offset and the size 103 * of the logical drive in this extended partition. The second is the offset 104 * and size of the next extended partition. The offsets are relative to 105 * beginning of the first extended partition. These extended partitions are 106 * arranged like a linked list. 107 * Note that (currently) only one extended partition can exist in the MBR. 108 * The system ID of a logical drive within the extended partition cannot be 109 * that of an extended partition. 110 * 111 * +------+ 112 * | | 113 * +--------------+ | +-v------------+ 114 * |+--+ | | |+--+ | 115 * || |---+ | | || | | 116 * ||--| | | | ||--| | 117 * || |---|------+-+ || | | 118 * |+--+ | | |+--+ | 119 * |+------v-----+| |+------------+| 120 * || || || || 121 * || || || || 122 * || || || || 123 * |+------------+| |+------------+| 124 * +--------------+ +--------------+ 125 * 126 */ 127 128 /* 129 * Main structure used to record changes to the partitions made. 130 * Changes are not written to disk everytime, but maintained in this structure. 131 * This information is used when the user chooses to commit the changes. 132 * A linked list of this structure represents the ondisk partitions. 133 */ 134 typedef struct logical_drive { 135 136 /* structure holding the EBR data */ 137 struct ipart parts[2]; 138 139 /* 140 * Absolute beginning sector of the extended partition, and hence an 141 * indicator of where the EBR for this logical drive would go on disk. 142 * NOTE : In case the first logical drive in this extended partition is 143 * out of (disk) order, this indicates the beginning of the logical 144 * drive. The EBR will anyway be at the first sector of the extended 145 * partition, for the first logical drive. 146 */ 147 uint32_t abs_secnum; 148 149 /* 150 * Offset of the logical drive from the beginning of its extended 151 * partition 152 */ 153 uint32_t logdrive_offset; 154 155 /* Size of the logical drive in sectors */ 156 uint32_t numsect; 157 158 /* Beginning and ending cylinders of the extended partition */ 159 uint32_t begcyl, endcyl; 160 161 /* 162 * Flag to indicate if this record is to be sync'ed to disk. 163 * It takes two values : FDISK_MAJOR_WRITE and FDISK_MINOR_WRITE 164 * If it is a minor write, there is no need to update the information 165 * in the kernel structures. Example of a minor write is correction of 166 * a corrupt boot signature. 167 */ 168 int modified; 169 170 /* 171 * This pointer points to the next extended partition in the order 172 * found on disk. 173 */ 174 struct logical_drive *next; 175 176 /* 177 * This pointer points to the next extended partition in a sorted list 178 * sorted in the ascending order of their beginning cylinders. 179 */ 180 struct logical_drive *sorted_next; 181 182 } logical_drive_t; 183 184 typedef struct fdisk_disk_geom { 185 ushort_t phys_cyl; 186 ushort_t phys_sec; 187 ushort_t phys_heads; 188 ushort_t alt_cyl; 189 ushort_t virt_cyl; 190 ushort_t virt_sec; 191 ushort_t virt_heads; 192 ushort_t sectsize; 193 } fdisk_disk_geom_t; 194 195 typedef struct ext_part 196 { 197 /* Structure holding geometry information about the device */ 198 fdisk_disk_geom_t disk_geom; 199 200 struct ipart *mtable; 201 202 char device_name[PATH_MAX]; 203 204 int dev_fd; 205 206 int op_flag; 207 208 /* 209 * Head of the in memory structure (singly linked list) of extended 210 * partition information. 211 */ 212 logical_drive_t *ld_head; 213 logical_drive_t *sorted_ld_head; 214 215 /* Beginning cylinder of the extended partition */ 216 uint32_t ext_beg_cyl; 217 218 /* Ending cylinder of the extended partition */ 219 uint32_t ext_end_cyl; 220 221 /* Beginning sector of the extended partition */ 222 uint32_t ext_beg_sec; 223 224 /* Ending sector of the extended partition */ 225 uint32_t ext_end_sec; 226 227 /* Count of the number of logical drives in the extended partition */ 228 int logical_drive_count; 229 230 /* 231 * Flag to keep track of the update to be made to the Extended Boot 232 * Record (EBR) when all logical drives are deleted. The EBR is filled 233 * with zeroes in such a case. 234 */ 235 int first_ebr_is_null; 236 237 /* 238 * Flag to indicate corrupt logical drives. Can happen when a partition 239 * manager creates an extended partition and does not null the first EBR 240 * or when important ondisk structures are overwritten by a bad program 241 */ 242 int corrupt_logical_drives; 243 244 /* 245 * The boot block signature 0xAA55 might not be found on some of the 246 * EBRs. ( Even though the rest of the data might be good ) 247 * The following array is used to store the list of such logical drive 248 * numbers. 249 */ 250 uchar_t invalid_bb_sig[MAX_EXT_PARTS]; 251 252 /* 253 * Can add a "next" pointer here in case support for multiple 254 * extended partitions becomes the standard someday. 255 * 256 * struct ext_part *next; 257 */ 258 } ext_part_t; 259 260 #define fdisk_get_logical_drive_count(epp) ((epp)->logical_drive_count) 261 #define fdisk_corrupt_logical_drives(epp) ((epp)->corrupt_logical_drives) 262 #define fdisk_get_ext_beg_cyl(epp) ((epp)->ext_beg_cyl) 263 #define fdisk_get_ext_end_cyl(epp) ((epp)->ext_end_cyl) 264 #define fdisk_get_ext_beg_sec(epp) ((epp)->ext_beg_sec) 265 #define fdisk_get_ext_end_sec(epp) ((epp)->ext_end_sec) 266 #define fdisk_get_ld_head(epp) ((epp)->ld_head) 267 #define fdisk_is_solaris_part(id) (((id) == SUNIXOS) || ((id) == SUNIXOS2)) 268 #define fdisk_is_dos_extended(id) (((id) == EXTDOS) || ((id) == FDISK_EXTLBA)) 269 270 extern int fdisk_is_linux_swap(ext_part_t *epp, uint32_t part_start, 271 uint64_t *lsm_offset); 272 extern int libfdisk_init(ext_part_t **epp, char *devstr, struct ipart *parttab, 273 int opflag); 274 extern int libfdisk_reset(ext_part_t *epp); 275 extern void libfdisk_fini(ext_part_t **epp); 276 extern int fdisk_ext_find_first_free_sec(ext_part_t *epp, 277 uint32_t *first_free_sec); 278 extern uint32_t fdisk_ext_find_last_free_sec(ext_part_t *epp, uint32_t begsec); 279 extern int fdisk_ext_part_exists(ext_part_t *epp); 280 extern int fdisk_validate_logical_drive(ext_part_t *epp, uint32_t begsec, 281 uint32_t offset, uint32_t numsec); 282 extern int fdisk_ext_validate_part_start(ext_part_t *epp, uint32_t begcyl, 283 uint32_t *begsec); 284 extern int fdisk_get_solaris_part(ext_part_t *epp, int *pnum, uint32_t *begsec, 285 uint32_t *numsec); 286 extern int fdisk_get_part_info(ext_part_t *epp, int pnum, uchar_t *sysid, 287 uint32_t *begsec, uint32_t *numsec); 288 extern int fdisk_commit_ext_part(ext_part_t *epp); 289 extern void fdisk_change_logical_drive_id(ext_part_t *epp, int pno, 290 uchar_t partid); 291 extern void fdisk_add_logical_drive(ext_part_t *epp, uint32_t begsec, 292 uint32_t endsec, uchar_t partid); 293 extern void fdisk_delete_logical_drive(ext_part_t *epp, int pno); 294 extern int fdisk_init_ext_part(ext_part_t *epp, uint32_t rsect, uint32_t nsect); 295 extern int fdisk_delete_ext_part(ext_part_t *epp); 296 extern int fdisk_get_disk_geom(ext_part_t *epp, int type, int what); 297 extern int fdisk_invalid_bb_sig(ext_part_t *epp, uchar_t **bbsig_arr); 298 extern int fdisk_mounted_logical_drives(ext_part_t *epp); 299 300 #ifdef __cplusplus 301 } 302 #endif 303 304 #endif /* _LIBFDISK_H_ */ 305