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