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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <errno.h> 31 #include <strings.h> 32 #include <unistd.h> 33 #include <uuid/uuid.h> 34 #include <libintl.h> 35 #include <sys/types.h> 36 #include <sys/dkio.h> 37 #include <sys/vtoc.h> 38 #include <sys/mhd.h> 39 #include <sys/param.h> 40 #include <sys/dktp/fdisk.h> 41 #include <sys/efi_partition.h> 42 #include <sys/byteorder.h> 43 #include <sys/ddi.h> 44 45 static struct uuid_to_ptag { 46 struct uuid uuid; 47 } conversion_array[] = { 48 { EFI_UNUSED }, 49 { EFI_BOOT }, 50 { EFI_ROOT }, 51 { EFI_SWAP }, 52 { EFI_USR }, 53 { EFI_BACKUP }, 54 { 0 }, /* STAND is never used */ 55 { EFI_VAR }, 56 { EFI_HOME }, 57 { EFI_ALTSCTR }, 58 { 0 }, /* CACHE (cachefs) is never used */ 59 { EFI_RESERVED }, 60 { EFI_SYSTEM }, 61 { EFI_LEGACY_MBR }, 62 { EFI_RESV3 }, 63 { EFI_RESV4 }, 64 { EFI_MSFT_RESV }, 65 { EFI_DELL_BASIC }, 66 { EFI_DELL_RAID }, 67 { EFI_DELL_SWAP }, 68 { EFI_DELL_LVM }, 69 { EFI_DELL_RESV }, 70 { EFI_AAPL_HFS }, 71 { EFI_AAPL_UFS } 72 }; 73 74 /* 75 * Default vtoc information for non-SVr4 partitions 76 */ 77 struct dk_map2 default_vtoc_map[NDKMAP] = { 78 { V_ROOT, 0 }, /* a - 0 */ 79 { V_SWAP, V_UNMNT }, /* b - 1 */ 80 { V_BACKUP, V_UNMNT }, /* c - 2 */ 81 { V_UNASSIGNED, 0 }, /* d - 3 */ 82 { V_UNASSIGNED, 0 }, /* e - 4 */ 83 { V_UNASSIGNED, 0 }, /* f - 5 */ 84 { V_USR, 0 }, /* g - 6 */ 85 { V_UNASSIGNED, 0 }, /* h - 7 */ 86 87 #if defined(_SUNOS_VTOC_16) 88 89 #if defined(i386) || defined(__amd64) 90 { V_BOOT, V_UNMNT }, /* i - 8 */ 91 { V_ALTSCTR, 0 }, /* j - 9 */ 92 93 #else 94 #error No VTOC format defined. 95 #endif /* defined(i386) */ 96 97 { V_UNASSIGNED, 0 }, /* k - 10 */ 98 { V_UNASSIGNED, 0 }, /* l - 11 */ 99 { V_UNASSIGNED, 0 }, /* m - 12 */ 100 { V_UNASSIGNED, 0 }, /* n - 13 */ 101 { V_UNASSIGNED, 0 }, /* o - 14 */ 102 { V_UNASSIGNED, 0 }, /* p - 15 */ 103 #endif /* defined(_SUNOS_VTOC_16) */ 104 }; 105 106 #ifdef DEBUG 107 int efi_debug = 1; 108 #else 109 int efi_debug = 0; 110 #endif 111 112 extern unsigned int efi_crc32(const unsigned char *, unsigned int); 113 static int efi_read(int, struct dk_gpt *); 114 115 static int 116 read_disk_info(int fd, diskaddr_t *capacity, uint_t *lbsize) 117 { 118 struct dk_minfo disk_info; 119 120 if ((ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info)) == -1) 121 return (errno); 122 *capacity = disk_info.dki_capacity; 123 *lbsize = disk_info.dki_lbsize; 124 return (0); 125 } 126 127 /* 128 * the number of blocks the EFI label takes up (round up to nearest 129 * block) 130 */ 131 #define NBLOCKS(p, l) (1 + ((((p) * (int)sizeof (efi_gpe_t)) + \ 132 ((l) - 1)) / (l))) 133 /* number of partitions -- limited by what we can malloc */ 134 #define MAX_PARTS ((4294967295UL - sizeof (struct dk_gpt)) / \ 135 sizeof (struct dk_part)) 136 137 int 138 efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc) 139 { 140 diskaddr_t capacity; 141 uint_t lbsize; 142 uint_t nblocks; 143 size_t length; 144 struct dk_gpt *vptr; 145 struct uuid uuid; 146 147 if (read_disk_info(fd, &capacity, &lbsize) != 0) { 148 if (efi_debug) 149 (void) fprintf(stderr, 150 "couldn't read disk information\n"); 151 return (-1); 152 } 153 154 nblocks = NBLOCKS(nparts, lbsize); 155 if ((nblocks * lbsize) < EFI_MIN_ARRAY_SIZE + lbsize) { 156 /* 16K plus one block for the GPT */ 157 nblocks = EFI_MIN_ARRAY_SIZE / lbsize + 1; 158 } 159 160 if (nparts > MAX_PARTS) { 161 if (efi_debug) { 162 (void) fprintf(stderr, 163 "the maximum number of partitions supported is %lu\n", 164 MAX_PARTS); 165 } 166 return (-1); 167 } 168 169 length = sizeof (struct dk_gpt) + 170 sizeof (struct dk_part) * (nparts - 1); 171 172 if ((*vtoc = calloc(length, 1)) == NULL) 173 return (-1); 174 175 vptr = *vtoc; 176 177 vptr->efi_version = EFI_VERSION_CURRENT; 178 vptr->efi_lbasize = lbsize; 179 vptr->efi_nparts = nparts; 180 /* 181 * add one block here for the PMBR; on disks with a 512 byte 182 * block size and 128 or fewer partitions, efi_first_u_lba 183 * should work out to "34" 184 */ 185 vptr->efi_first_u_lba = nblocks + 1; 186 vptr->efi_last_lba = capacity - 1; 187 vptr->efi_last_u_lba = vptr->efi_last_lba - nblocks; 188 (void) uuid_generate((uchar_t *)&uuid); 189 UUID_LE_CONVERT(vptr->efi_disk_uguid, uuid); 190 return (0); 191 } 192 193 /* 194 * Read EFI - return partition number upon success. 195 */ 196 int 197 efi_alloc_and_read(int fd, struct dk_gpt **vtoc) 198 { 199 int rval; 200 uint32_t nparts; 201 int length; 202 203 /* figure out the number of entries that would fit into 16K */ 204 nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t); 205 length = (int) sizeof (struct dk_gpt) + 206 (int) sizeof (struct dk_part) * (nparts - 1); 207 if ((*vtoc = calloc(length, 1)) == NULL) 208 return (VT_ERROR); 209 210 (*vtoc)->efi_nparts = nparts; 211 rval = efi_read(fd, *vtoc); 212 213 if ((rval == VT_EINVAL) && (*vtoc)->efi_nparts > nparts) { 214 void *tmp; 215 length = (int) sizeof (struct dk_gpt) + 216 (int) sizeof (struct dk_part) * 217 ((*vtoc)->efi_nparts - 1); 218 nparts = (*vtoc)->efi_nparts; 219 if ((tmp = realloc(*vtoc, length)) == NULL) { 220 free (*vtoc); 221 *vtoc = NULL; 222 return (VT_ERROR); 223 } else { 224 *vtoc = tmp; 225 rval = efi_read(fd, *vtoc); 226 } 227 } 228 229 if (rval < 0) { 230 if (efi_debug) { 231 (void) fprintf(stderr, 232 "read of EFI table failed, rval=%d\n", rval); 233 } 234 free (*vtoc); 235 *vtoc = NULL; 236 } 237 238 return (rval); 239 } 240 241 static int 242 efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc) 243 { 244 void *data = dk_ioc->dki_data; 245 int error; 246 247 dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data; 248 error = ioctl(fd, cmd, (void *)dk_ioc); 249 dk_ioc->dki_data = data; 250 251 return (error); 252 } 253 254 static int 255 check_label(int fd, dk_efi_t *dk_ioc) 256 { 257 efi_gpt_t *efi; 258 uint_t crc; 259 260 if (efi_ioctl(fd, DKIOCGETEFI, dk_ioc) == -1) { 261 switch (errno) { 262 case EIO: 263 return (VT_EIO); 264 default: 265 return (VT_ERROR); 266 } 267 } 268 efi = dk_ioc->dki_data; 269 if (efi->efi_gpt_Signature != LE_64(EFI_SIGNATURE)) { 270 if (efi_debug) 271 (void) fprintf(stderr, 272 "Bad EFI signature: 0x%llx != 0x%llx\n", 273 (long long)efi->efi_gpt_Signature, 274 (long long)LE_64(EFI_SIGNATURE)); 275 return (VT_EINVAL); 276 } 277 278 /* 279 * check CRC of the header; the size of the header should 280 * never be larger than one block 281 */ 282 crc = efi->efi_gpt_HeaderCRC32; 283 efi->efi_gpt_HeaderCRC32 = 0; 284 285 if (((len_t)LE_32(efi->efi_gpt_HeaderSize) > dk_ioc->dki_length) || 286 crc != LE_32(efi_crc32((unsigned char *)efi, 287 LE_32(efi->efi_gpt_HeaderSize)))) { 288 if (efi_debug) 289 (void) fprintf(stderr, 290 "Bad EFI CRC: 0x%x != 0x%x\n", 291 crc, 292 LE_32(efi_crc32((unsigned char *)efi, 293 sizeof (struct efi_gpt)))); 294 return (VT_EINVAL); 295 } 296 297 return (0); 298 } 299 300 static int 301 efi_read(int fd, struct dk_gpt *vtoc) 302 { 303 int i, j; 304 int label_len; 305 int rval = 0; 306 int md_flag = 0; 307 struct dk_minfo disk_info; 308 dk_efi_t dk_ioc; 309 efi_gpt_t *efi; 310 efi_gpe_t *efi_parts; 311 struct dk_cinfo dki_info; 312 uint32_t user_length; 313 boolean_t legacy_label = B_FALSE; 314 315 /* 316 * get the partition number for this file descriptor. 317 */ 318 if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) { 319 if (efi_debug) 320 (void) fprintf(stderr, "DKIOCINFO errno 0x%x\n", errno); 321 switch (errno) { 322 case EIO: 323 return (VT_EIO); 324 case EINVAL: 325 return (VT_EINVAL); 326 default: 327 return (VT_ERROR); 328 } 329 } 330 if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) && 331 (strncmp(dki_info.dki_dname, "md", 3) == 0)) { 332 md_flag++; 333 } 334 /* get the LBA size */ 335 if (ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info) == -1) { 336 if (efi_debug) { 337 (void) fprintf(stderr, 338 "assuming LBA 512 bytes %d\n", 339 errno); 340 } 341 disk_info.dki_lbsize = DEV_BSIZE; 342 } 343 if (disk_info.dki_lbsize == 0) { 344 if (efi_debug) { 345 (void) fprintf(stderr, 346 "efi_read: assuming LBA 512 bytes\n"); 347 } 348 disk_info.dki_lbsize = DEV_BSIZE; 349 } 350 /* 351 * Read the EFI GPT to figure out how many partitions we need 352 * to deal with. 353 */ 354 dk_ioc.dki_lba = 1; 355 if (NBLOCKS(vtoc->efi_nparts, disk_info.dki_lbsize) < 34) { 356 label_len = EFI_MIN_ARRAY_SIZE + disk_info.dki_lbsize; 357 } else { 358 label_len = vtoc->efi_nparts * (int) sizeof (efi_gpe_t) + 359 disk_info.dki_lbsize; 360 if (label_len % disk_info.dki_lbsize) { 361 /* pad to physical sector size */ 362 label_len += disk_info.dki_lbsize; 363 label_len &= ~(disk_info.dki_lbsize - 1); 364 } 365 } 366 367 if ((dk_ioc.dki_data = calloc(label_len, 1)) == NULL) 368 return (VT_ERROR); 369 370 dk_ioc.dki_length = disk_info.dki_lbsize; 371 user_length = vtoc->efi_nparts; 372 efi = dk_ioc.dki_data; 373 if (md_flag) { 374 dk_ioc.dki_length = label_len; 375 if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1) { 376 switch (errno) { 377 case EIO: 378 return (VT_EIO); 379 default: 380 return (VT_ERROR); 381 } 382 } 383 } else if ((rval = check_label(fd, &dk_ioc)) == VT_EINVAL) { 384 /* 385 * No valid label here; try the alternate. Note that here 386 * we just read GPT header and save it into dk_ioc.data, 387 * Later, we will read GUID partition entry array if we 388 * can get valid GPT header. 389 */ 390 391 /* 392 * This is a workaround for legacy systems. In the past, the 393 * last sector of SCSI disk was invisible on x86 platform. At 394 * that time, backup label was saved on the next to the last 395 * sector. It is possible for users to move a disk from previous 396 * solaris system to present system. Here, we attempt to search 397 * legacy backup EFI label first. 398 */ 399 dk_ioc.dki_lba = disk_info.dki_capacity - 2; 400 dk_ioc.dki_length = disk_info.dki_lbsize; 401 rval = check_label(fd, &dk_ioc); 402 if (rval == VT_EINVAL) { 403 /* 404 * we didn't find legacy backup EFI label, try to 405 * search backup EFI label in the last block. 406 */ 407 dk_ioc.dki_lba = disk_info.dki_capacity - 1; 408 dk_ioc.dki_length = disk_info.dki_lbsize; 409 rval = check_label(fd, &dk_ioc); 410 if (rval == 0) { 411 legacy_label = B_TRUE; 412 if (efi_debug) 413 (void) fprintf(stderr, 414 "efi_read: primary label corrupt; " 415 "using EFI backup label located on" 416 " the last block\n"); 417 } 418 } else { 419 if ((efi_debug) && (rval == 0)) 420 (void) fprintf(stderr, "efi_read: primary label" 421 " corrupt; using legacy EFI backup label " 422 " located on the next to last block\n"); 423 } 424 425 if (rval == 0) { 426 dk_ioc.dki_lba = LE_64(efi->efi_gpt_PartitionEntryLBA); 427 vtoc->efi_flags |= EFI_GPT_PRIMARY_CORRUPT; 428 vtoc->efi_nparts = 429 LE_32(efi->efi_gpt_NumberOfPartitionEntries); 430 431 /* 432 * Partition tables are between backup GPT header 433 * table and ParitionEntryLBA (the starting LBA of 434 * the GUID partition entries array). Now that we 435 * already got valid GPT header and saved it in 436 * dk_ioc.dki_data, we try to get GUID partition 437 * entry array here. 438 */ 439 dk_ioc.dki_data++; 440 if (legacy_label) 441 dk_ioc.dki_length = disk_info.dki_capacity - 1 - 442 dk_ioc.dki_lba; 443 else 444 dk_ioc.dki_length = disk_info.dki_capacity - 2 - 445 dk_ioc.dki_lba; 446 dk_ioc.dki_length *= disk_info.dki_lbsize; 447 if (dk_ioc.dki_length > 448 ((len_t)label_len - sizeof (*dk_ioc.dki_data))) { 449 rval = VT_EINVAL; 450 } else { 451 /* 452 * read GUID partition entry array 453 */ 454 rval = efi_ioctl(fd, DKIOCGETEFI, &dk_ioc); 455 } 456 } 457 } else { 458 dk_ioc.dki_lba = LE_64(efi->efi_gpt_PartitionEntryLBA); 459 dk_ioc.dki_data++; 460 dk_ioc.dki_length = label_len - disk_info.dki_lbsize; 461 rval = efi_ioctl(fd, DKIOCGETEFI, &dk_ioc); 462 } 463 if (rval < 0) { 464 free(efi); 465 return (rval); 466 } 467 468 /* LINTED -- always longlong aligned */ 469 efi_parts = (efi_gpe_t *)(((char *)efi) + disk_info.dki_lbsize); 470 471 /* 472 * Assemble this into a "dk_gpt" struct for easier 473 * digestibility by applications. 474 */ 475 vtoc->efi_version = LE_32(efi->efi_gpt_Revision); 476 vtoc->efi_nparts = LE_32(efi->efi_gpt_NumberOfPartitionEntries); 477 vtoc->efi_part_size = LE_32(efi->efi_gpt_SizeOfPartitionEntry); 478 vtoc->efi_lbasize = disk_info.dki_lbsize; 479 vtoc->efi_last_lba = disk_info.dki_capacity - 1; 480 vtoc->efi_first_u_lba = LE_64(efi->efi_gpt_FirstUsableLBA); 481 vtoc->efi_last_u_lba = LE_64(efi->efi_gpt_LastUsableLBA); 482 UUID_LE_CONVERT(vtoc->efi_disk_uguid, efi->efi_gpt_DiskGUID); 483 484 /* 485 * If the array the user passed in is too small, set the length 486 * to what it needs to be and return 487 */ 488 if (user_length < vtoc->efi_nparts) { 489 return (VT_EINVAL); 490 } 491 492 for (i = 0; i < vtoc->efi_nparts; i++) { 493 494 UUID_LE_CONVERT(vtoc->efi_parts[i].p_guid, 495 efi_parts[i].efi_gpe_PartitionTypeGUID); 496 497 for (j = 0; 498 j < sizeof (conversion_array) / sizeof (struct uuid_to_ptag); 499 j++) { 500 501 if (bcmp(&vtoc->efi_parts[i].p_guid, 502 &conversion_array[j].uuid, 503 sizeof (struct uuid)) == 0) { 504 vtoc->efi_parts[i].p_tag = j; 505 break; 506 } 507 } 508 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) 509 continue; 510 vtoc->efi_parts[i].p_flag = 511 LE_16(efi_parts[i].efi_gpe_Attributes.PartitionAttrs); 512 vtoc->efi_parts[i].p_start = 513 LE_64(efi_parts[i].efi_gpe_StartingLBA); 514 vtoc->efi_parts[i].p_size = 515 LE_64(efi_parts[i].efi_gpe_EndingLBA) - 516 vtoc->efi_parts[i].p_start + 1; 517 for (j = 0; j < EFI_PART_NAME_LEN; j++) { 518 vtoc->efi_parts[i].p_name[j] = 519 (uchar_t)LE_16(efi_parts[i].efi_gpe_PartitionName[j]); 520 } 521 522 UUID_LE_CONVERT(vtoc->efi_parts[i].p_uguid, 523 efi_parts[i].efi_gpe_UniquePartitionGUID); 524 } 525 free(efi); 526 527 return (dki_info.dki_partition); 528 } 529 530 /* writes a "protective" MBR */ 531 static int 532 write_pmbr(int fd, struct dk_gpt *vtoc) 533 { 534 dk_efi_t dk_ioc; 535 struct mboot mb; 536 uchar_t *cp; 537 diskaddr_t size_in_lba; 538 539 mb.signature = LE_16(MBB_MAGIC); 540 bzero(&mb.parts, sizeof (mb.parts)); 541 cp = (uchar_t *)&mb.parts[0]; 542 /* bootable or not */ 543 *cp++ = 0; 544 /* beginning CHS; 0xffffff if not representable */ 545 *cp++ = 0xff; 546 *cp++ = 0xff; 547 *cp++ = 0xff; 548 /* OS type */ 549 *cp++ = EFI_PMBR; 550 /* ending CHS; 0xffffff if not representable */ 551 *cp++ = 0xff; 552 *cp++ = 0xff; 553 *cp++ = 0xff; 554 /* starting LBA: 1 (little endian format) by EFI definition */ 555 *cp++ = 0x01; 556 *cp++ = 0x00; 557 *cp++ = 0x00; 558 *cp++ = 0x00; 559 /* ending LBA: last block on the disk (little endian format) */ 560 size_in_lba = vtoc->efi_last_lba; 561 if (size_in_lba < 0xffffffff) { 562 *cp++ = (size_in_lba & 0x000000ff); 563 *cp++ = (size_in_lba & 0x0000ff00) >> 8; 564 *cp++ = (size_in_lba & 0x00ff0000) >> 16; 565 *cp++ = (size_in_lba & 0xff000000) >> 24; 566 } else { 567 *cp++ = 0xff; 568 *cp++ = 0xff; 569 *cp++ = 0xff; 570 *cp++ = 0xff; 571 } 572 /* LINTED -- always longlong aligned */ 573 dk_ioc.dki_data = (efi_gpt_t *)&mb; 574 dk_ioc.dki_lba = 0; 575 dk_ioc.dki_length = sizeof (mb); 576 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { 577 switch (errno) { 578 case EIO: 579 return (VT_EIO); 580 case EINVAL: 581 return (VT_EINVAL); 582 default: 583 return (VT_ERROR); 584 } 585 } 586 return (0); 587 } 588 589 /* make sure the user specified something reasonable */ 590 static int 591 check_input(struct dk_gpt *vtoc) 592 { 593 int resv_part = -1; 594 int i, j; 595 diskaddr_t istart, jstart, isize, jsize, endsect; 596 597 /* 598 * Sanity-check the input (make sure no partitions overlap) 599 */ 600 for (i = 0; i < vtoc->efi_nparts; i++) { 601 /* It can't be unassigned and have an actual size */ 602 if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) && 603 (vtoc->efi_parts[i].p_size != 0)) { 604 if (efi_debug) { 605 (void) fprintf(stderr, 606 "partition %d is \"unassigned\" but has a size of %llu", 607 i, 608 vtoc->efi_parts[i].p_size); 609 } 610 return (VT_EINVAL); 611 } 612 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) { 613 if (uuid_is_null((uchar_t *)&vtoc->efi_parts[i].p_guid)) 614 continue; 615 /* we have encountered an unknown uuid */ 616 vtoc->efi_parts[i].p_tag = 0xff; 617 } 618 if (vtoc->efi_parts[i].p_tag == V_RESERVED) { 619 if (resv_part != -1) { 620 if (efi_debug) { 621 (void) fprintf(stderr, 622 "found duplicate reserved partition at %d\n", 623 i); 624 } 625 return (VT_EINVAL); 626 } 627 resv_part = i; 628 } 629 if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) || 630 (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) { 631 if (efi_debug) { 632 (void) fprintf(stderr, 633 "Partition %d starts at %llu. ", 634 i, 635 vtoc->efi_parts[i].p_start); 636 (void) fprintf(stderr, 637 "It must be between %llu and %llu.\n", 638 vtoc->efi_first_u_lba, 639 vtoc->efi_last_u_lba); 640 } 641 return (VT_EINVAL); 642 } 643 if ((vtoc->efi_parts[i].p_start + 644 vtoc->efi_parts[i].p_size < 645 vtoc->efi_first_u_lba) || 646 (vtoc->efi_parts[i].p_start + 647 vtoc->efi_parts[i].p_size > 648 vtoc->efi_last_u_lba + 1)) { 649 if (efi_debug) { 650 (void) fprintf(stderr, 651 "Partition %d ends at %llu. ", 652 i, 653 vtoc->efi_parts[i].p_start + 654 vtoc->efi_parts[i].p_size); 655 (void) fprintf(stderr, 656 "It must be between %llu and %llu.\n", 657 vtoc->efi_first_u_lba, 658 vtoc->efi_last_u_lba); 659 } 660 return (VT_EINVAL); 661 } 662 663 for (j = 0; j < vtoc->efi_nparts; j++) { 664 isize = vtoc->efi_parts[i].p_size; 665 jsize = vtoc->efi_parts[j].p_size; 666 istart = vtoc->efi_parts[i].p_start; 667 jstart = vtoc->efi_parts[j].p_start; 668 if ((i != j) && (isize != 0) && (jsize != 0)) { 669 endsect = jstart + jsize -1; 670 if ((jstart <= istart) && 671 (istart <= endsect)) { 672 if (efi_debug) { 673 (void) fprintf(stderr, 674 "Partition %d overlaps partition %d.", 675 i, j); 676 } 677 return (VT_EINVAL); 678 } 679 } 680 } 681 } 682 /* just a warning for now */ 683 if ((resv_part == -1) && efi_debug) { 684 (void) fprintf(stderr, 685 "no reserved partition found\n"); 686 } 687 return (0); 688 } 689 690 /* 691 * write EFI label and backup label 692 */ 693 int 694 efi_write(int fd, struct dk_gpt *vtoc) 695 { 696 dk_efi_t dk_ioc; 697 efi_gpt_t *efi; 698 efi_gpe_t *efi_parts; 699 int i, j; 700 struct dk_cinfo dki_info; 701 int md_flag = 0; 702 int nblocks; 703 diskaddr_t lba_backup_gpt_hdr; 704 705 if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) { 706 if (efi_debug) 707 (void) fprintf(stderr, "DKIOCINFO errno 0x%x\n", errno); 708 switch (errno) { 709 case EIO: 710 return (VT_EIO); 711 case EINVAL: 712 return (VT_EINVAL); 713 default: 714 return (VT_ERROR); 715 } 716 } 717 718 /* check if we are dealing wih a metadevice */ 719 if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) && 720 (strncmp(dki_info.dki_dname, "md", 3) == 0)) { 721 md_flag = 1; 722 } 723 724 if (check_input(vtoc)) { 725 /* 726 * not valid; if it's a metadevice just pass it down 727 * because SVM will do its own checking 728 */ 729 if (md_flag == 0) { 730 return (VT_EINVAL); 731 } 732 } 733 734 dk_ioc.dki_lba = 1; 735 if (NBLOCKS(vtoc->efi_nparts, vtoc->efi_lbasize) < 34) { 736 dk_ioc.dki_length = EFI_MIN_ARRAY_SIZE + vtoc->efi_lbasize; 737 } else { 738 dk_ioc.dki_length = NBLOCKS(vtoc->efi_nparts, 739 vtoc->efi_lbasize) * 740 vtoc->efi_lbasize; 741 } 742 743 /* 744 * the number of blocks occupied by GUID partition entry array 745 */ 746 nblocks = dk_ioc.dki_length / vtoc->efi_lbasize - 1; 747 748 /* 749 * Backup GPT header is located on the block after GUID 750 * partition entry array. Here, we calculate the address 751 * for backup GPT header. 752 */ 753 lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks; 754 755 if ((dk_ioc.dki_data = calloc(dk_ioc.dki_length, 1)) == NULL) 756 return (VT_ERROR); 757 758 efi = dk_ioc.dki_data; 759 760 /* stuff user's input into EFI struct */ 761 efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE); 762 efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */ 763 efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt)); 764 efi->efi_gpt_Reserved1 = 0; 765 efi->efi_gpt_MyLBA = LE_64(1ULL); 766 efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr); 767 efi->efi_gpt_FirstUsableLBA = LE_64(vtoc->efi_first_u_lba); 768 efi->efi_gpt_LastUsableLBA = LE_64(vtoc->efi_last_u_lba); 769 efi->efi_gpt_PartitionEntryLBA = LE_64(2ULL); 770 efi->efi_gpt_NumberOfPartitionEntries = LE_32(vtoc->efi_nparts); 771 efi->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (struct efi_gpe)); 772 UUID_LE_CONVERT(efi->efi_gpt_DiskGUID, vtoc->efi_disk_uguid); 773 774 /* LINTED -- always longlong aligned */ 775 efi_parts = (efi_gpe_t *)((char *)dk_ioc.dki_data + sizeof (efi_gpt_t)); 776 777 for (i = 0; i < vtoc->efi_nparts; i++) { 778 for (j = 0; 779 j < sizeof (conversion_array) / sizeof (struct uuid_to_ptag); 780 j++) { 781 782 if (vtoc->efi_parts[i].p_tag == j) { 783 UUID_LE_CONVERT( 784 efi_parts[i].efi_gpe_PartitionTypeGUID, 785 conversion_array[j].uuid); 786 break; 787 } 788 } 789 790 if (j == sizeof (conversion_array) / sizeof (struct uuid_to_ptag)) { 791 /* 792 * If we didn't have a matching uuid match, bail here. 793 * Don't write a label with unknown uuid. 794 */ 795 if (efi_debug) 796 (void) fprintf(stderr, "Unknown uuid for p_tag %d\n", 797 vtoc->efi_parts[i].p_tag); 798 return (VT_EINVAL); 799 } 800 801 efi_parts[i].efi_gpe_StartingLBA = 802 LE_64(vtoc->efi_parts[i].p_start); 803 efi_parts[i].efi_gpe_EndingLBA = 804 LE_64(vtoc->efi_parts[i].p_start + 805 vtoc->efi_parts[i].p_size - 1); 806 efi_parts[i].efi_gpe_Attributes.PartitionAttrs = 807 LE_16(vtoc->efi_parts[i].p_flag); 808 for (j = 0; j < EFI_PART_NAME_LEN; j++) { 809 efi_parts[i].efi_gpe_PartitionName[j] = 810 LE_16((ushort_t)vtoc->efi_parts[i].p_name[j]); 811 } 812 if ((vtoc->efi_parts[i].p_tag != V_UNASSIGNED) && 813 uuid_is_null((uchar_t *)&vtoc->efi_parts[i].p_uguid)) { 814 (void) uuid_generate((uchar_t *) 815 &vtoc->efi_parts[i].p_uguid); 816 } 817 bcopy(&vtoc->efi_parts[i].p_uguid, 818 &efi_parts[i].efi_gpe_UniquePartitionGUID, 819 sizeof (uuid_t)); 820 } 821 efi->efi_gpt_PartitionEntryArrayCRC32 = 822 LE_32(efi_crc32((unsigned char *)efi_parts, 823 vtoc->efi_nparts * (int)sizeof (struct efi_gpe))); 824 efi->efi_gpt_HeaderCRC32 = 825 LE_32(efi_crc32((unsigned char *)efi, sizeof (struct efi_gpt))); 826 827 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { 828 free(dk_ioc.dki_data); 829 switch (errno) { 830 case EIO: 831 return (VT_EIO); 832 case EINVAL: 833 return (VT_EINVAL); 834 default: 835 return (VT_ERROR); 836 } 837 } 838 /* if it's a metadevice we're done */ 839 if (md_flag) { 840 free(dk_ioc.dki_data); 841 return (0); 842 } 843 /* write backup partition array */ 844 dk_ioc.dki_lba = vtoc->efi_last_u_lba + 1; 845 dk_ioc.dki_length -= vtoc->efi_lbasize; 846 dk_ioc.dki_data++; 847 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { 848 /* 849 * we wrote the primary label okay, so don't fail 850 */ 851 if (efi_debug) { 852 (void) fprintf(stderr, 853 "write of backup partitions to block %llu " 854 "failed, errno %d\n", 855 vtoc->efi_last_u_lba + 1, 856 errno); 857 } 858 } 859 /* 860 * now swap MyLBA and AlternateLBA fields and write backup 861 * partition table header 862 */ 863 dk_ioc.dki_lba = lba_backup_gpt_hdr; 864 dk_ioc.dki_length = vtoc->efi_lbasize; 865 dk_ioc.dki_data--; 866 efi->efi_gpt_AlternateLBA = LE_64(1ULL); 867 efi->efi_gpt_MyLBA = LE_64(lba_backup_gpt_hdr); 868 efi->efi_gpt_PartitionEntryLBA = LE_64(vtoc->efi_last_u_lba + 1); 869 efi->efi_gpt_HeaderCRC32 = 0; 870 efi->efi_gpt_HeaderCRC32 = 871 LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data, 872 sizeof (struct efi_gpt))); 873 874 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { 875 if (efi_debug) { 876 (void) fprintf(stderr, 877 "write of backup header to block %llu failed, " 878 "errno %d\n", 879 lba_backup_gpt_hdr, 880 errno); 881 } 882 } 883 /* write the PMBR */ 884 (void) write_pmbr(fd, vtoc); 885 free(dk_ioc.dki_data); 886 return (0); 887 } 888 889 void 890 efi_free(struct dk_gpt *ptr) 891 { 892 free(ptr); 893 } 894 895 /* 896 * Input: File descriptor 897 * Output: 1 if disk is >1TB OR has an EFI label, 0 otherwise. 898 */ 899 int 900 efi_type(int fd) 901 { 902 struct vtoc vtoc; 903 904 if (ioctl(fd, DKIOCGVTOC, &vtoc) == -1) { 905 if (errno == ENOTSUP) { 906 return (1); 907 } 908 } 909 return (0); 910 } 911 912 void 913 efi_err_check(struct dk_gpt *vtoc) 914 { 915 int resv_part = -1; 916 int i, j; 917 diskaddr_t istart, jstart, isize, jsize, endsect; 918 int overlap = 0; 919 920 /* 921 * make sure no partitions overlap 922 */ 923 for (i = 0; i < vtoc->efi_nparts; i++) { 924 /* It can't be unassigned and have an actual size */ 925 if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) && 926 (vtoc->efi_parts[i].p_size != 0)) { 927 (void) fprintf(stderr, 928 "partition %d is \"unassigned\" but has a size " 929 "of %llu\n", i, vtoc->efi_parts[i].p_size); 930 } 931 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) { 932 continue; 933 } 934 if (vtoc->efi_parts[i].p_tag == V_RESERVED) { 935 if (resv_part != -1) { 936 (void) fprintf(stderr, 937 "found duplicate reserved partition at " 938 "%d\n", i); 939 } 940 resv_part = i; 941 if (vtoc->efi_parts[i].p_size != EFI_MIN_RESV_SIZE) 942 (void) fprintf(stderr, 943 "Warning: reserved partition size must " 944 "be %d sectors\n", EFI_MIN_RESV_SIZE); 945 } 946 if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) || 947 (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) { 948 (void) fprintf(stderr, 949 "Partition %d starts at %llu\n", 950 i, 951 vtoc->efi_parts[i].p_start); 952 (void) fprintf(stderr, 953 "It must be between %llu and %llu.\n", 954 vtoc->efi_first_u_lba, 955 vtoc->efi_last_u_lba); 956 } 957 if ((vtoc->efi_parts[i].p_start + 958 vtoc->efi_parts[i].p_size < 959 vtoc->efi_first_u_lba) || 960 (vtoc->efi_parts[i].p_start + 961 vtoc->efi_parts[i].p_size > 962 vtoc->efi_last_u_lba + 1)) { 963 (void) fprintf(stderr, 964 "Partition %d ends at %llu\n", 965 i, 966 vtoc->efi_parts[i].p_start + 967 vtoc->efi_parts[i].p_size); 968 (void) fprintf(stderr, 969 "It must be between %llu and %llu.\n", 970 vtoc->efi_first_u_lba, 971 vtoc->efi_last_u_lba); 972 } 973 974 for (j = 0; j < vtoc->efi_nparts; j++) { 975 isize = vtoc->efi_parts[i].p_size; 976 jsize = vtoc->efi_parts[j].p_size; 977 istart = vtoc->efi_parts[i].p_start; 978 jstart = vtoc->efi_parts[j].p_start; 979 if ((i != j) && (isize != 0) && (jsize != 0)) { 980 endsect = jstart + jsize -1; 981 if ((jstart <= istart) && 982 (istart <= endsect)) { 983 if (!overlap) { 984 (void) fprintf(stderr, 985 "label error: EFI Labels do not " 986 "support overlapping partitions\n"); 987 } 988 (void) fprintf(stderr, 989 "Partition %d overlaps partition " 990 "%d.\n", i, j); 991 overlap = 1; 992 } 993 } 994 } 995 } 996 /* make sure there is a reserved partition */ 997 if (resv_part == -1) { 998 (void) fprintf(stderr, 999 "no reserved partition found\n"); 1000 } 1001 } 1002 1003 /* 1004 * We need to get information necessary to construct a *new* efi 1005 * label type 1006 */ 1007 int 1008 efi_auto_sense(int fd, struct dk_gpt **vtoc) 1009 { 1010 1011 int i; 1012 1013 /* 1014 * Now build the default partition table 1015 */ 1016 if (efi_alloc_and_init(fd, EFI_NUMPAR, vtoc) != 0) { 1017 if (efi_debug) { 1018 (void) fprintf(stderr, "efi_alloc_and_init failed.\n"); 1019 } 1020 return (-1); 1021 } 1022 1023 for (i = 0; i < min((*vtoc)->efi_nparts, V_NUMPAR); i++) { 1024 (*vtoc)->efi_parts[i].p_tag = default_vtoc_map[i].p_tag; 1025 (*vtoc)->efi_parts[i].p_flag = default_vtoc_map[i].p_flag; 1026 (*vtoc)->efi_parts[i].p_start = 0; 1027 (*vtoc)->efi_parts[i].p_size = 0; 1028 } 1029 /* 1030 * Make constants first 1031 * and variable partitions later 1032 */ 1033 1034 /* root partition - s0 128 MB */ 1035 (*vtoc)->efi_parts[0].p_start = 34; 1036 (*vtoc)->efi_parts[0].p_size = 262144; 1037 1038 /* partition - s1 128 MB */ 1039 (*vtoc)->efi_parts[1].p_start = 262178; 1040 (*vtoc)->efi_parts[1].p_size = 262144; 1041 1042 /* partition -s2 is NOT the Backup disk */ 1043 (*vtoc)->efi_parts[2].p_tag = V_UNASSIGNED; 1044 1045 /* partition -s6 /usr partition - HOG */ 1046 (*vtoc)->efi_parts[6].p_start = 524322; 1047 (*vtoc)->efi_parts[6].p_size = (*vtoc)->efi_last_u_lba - 524322 1048 - (1024 * 16); 1049 1050 /* efi reserved partition - s9 16K */ 1051 (*vtoc)->efi_parts[8].p_start = (*vtoc)->efi_last_u_lba - (1024 * 16); 1052 (*vtoc)->efi_parts[8].p_size = (1024 * 16); 1053 (*vtoc)->efi_parts[8].p_tag = V_RESERVED; 1054 return (0); 1055 } 1056