]> git.proxmox.com Git - mirror_zfs-debian.git/blob - lib/libefi/rdwr_efi.c
Imported Upstream version 0.6.4.2
[mirror_zfs-debian.git] / lib / libefi / rdwr_efi.c
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 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <strings.h>
30 #include <unistd.h>
31 #include <uuid/uuid.h>
32 #include <zlib.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 #if defined(__linux__)
43 #include <linux/fs.h>
44 #endif
45
46 static struct uuid_to_ptag {
47 struct uuid uuid;
48 } conversion_array[] = {
49 { EFI_UNUSED },
50 { EFI_BOOT },
51 { EFI_ROOT },
52 { EFI_SWAP },
53 { EFI_USR },
54 { EFI_BACKUP },
55 { EFI_UNUSED }, /* STAND is never used */
56 { EFI_VAR },
57 { EFI_HOME },
58 { EFI_ALTSCTR },
59 { EFI_UNUSED }, /* CACHE (cachefs) is never used */
60 { EFI_RESERVED },
61 { EFI_SYSTEM },
62 { EFI_LEGACY_MBR },
63 { EFI_SYMC_PUB },
64 { EFI_SYMC_CDS },
65 { EFI_MSFT_RESV },
66 { EFI_DELL_BASIC },
67 { EFI_DELL_RAID },
68 { EFI_DELL_SWAP },
69 { EFI_DELL_LVM },
70 { EFI_DELL_RESV },
71 { EFI_AAPL_HFS },
72 { EFI_AAPL_UFS }
73 };
74
75 /*
76 * Default vtoc information for non-SVr4 partitions
77 */
78 struct dk_map2 default_vtoc_map[NDKMAP] = {
79 { V_ROOT, 0 }, /* a - 0 */
80 { V_SWAP, V_UNMNT }, /* b - 1 */
81 { V_BACKUP, V_UNMNT }, /* c - 2 */
82 { V_UNASSIGNED, 0 }, /* d - 3 */
83 { V_UNASSIGNED, 0 }, /* e - 4 */
84 { V_UNASSIGNED, 0 }, /* f - 5 */
85 { V_USR, 0 }, /* g - 6 */
86 { V_UNASSIGNED, 0 }, /* h - 7 */
87
88 #if defined(_SUNOS_VTOC_16)
89
90 #if defined(i386) || defined(__amd64) || defined(__arm) || \
91 defined(__powerpc) || defined(__sparc)
92 { V_BOOT, V_UNMNT }, /* i - 8 */
93 { V_ALTSCTR, 0 }, /* j - 9 */
94
95 #else
96 #error No VTOC format defined.
97 #endif /* defined(i386) */
98
99 { V_UNASSIGNED, 0 }, /* k - 10 */
100 { V_UNASSIGNED, 0 }, /* l - 11 */
101 { V_UNASSIGNED, 0 }, /* m - 12 */
102 { V_UNASSIGNED, 0 }, /* n - 13 */
103 { V_UNASSIGNED, 0 }, /* o - 14 */
104 { V_UNASSIGNED, 0 }, /* p - 15 */
105 #endif /* defined(_SUNOS_VTOC_16) */
106 };
107
108 #ifdef DEBUG
109 int efi_debug = 1;
110 #else
111 int efi_debug = 0;
112 #endif
113
114 static int efi_read(int, struct dk_gpt *);
115
116 /*
117 * Return a 32-bit CRC of the contents of the buffer. Pre-and-post
118 * one's conditioning will be handled by crc32() internally.
119 */
120 static uint32_t
121 efi_crc32(const unsigned char *buf, unsigned int size)
122 {
123 uint32_t crc = crc32(0, Z_NULL, 0);
124
125 crc = crc32(crc, buf, size);
126
127 return (crc);
128 }
129
130 static int
131 read_disk_info(int fd, diskaddr_t *capacity, uint_t *lbsize)
132 {
133 int sector_size;
134 unsigned long long capacity_size;
135
136 if (ioctl(fd, BLKSSZGET, &sector_size) < 0)
137 return (-1);
138
139 if (ioctl(fd, BLKGETSIZE64, &capacity_size) < 0)
140 return (-1);
141
142 *lbsize = (uint_t)sector_size;
143 *capacity = (diskaddr_t)(capacity_size / sector_size);
144
145 return (0);
146 }
147
148 static int
149 efi_get_info(int fd, struct dk_cinfo *dki_info)
150 {
151 #if defined(__linux__)
152 char *path;
153 char *dev_path;
154 int rval = 0;
155
156 memset(dki_info, 0, sizeof (*dki_info));
157
158 path = calloc(PATH_MAX, 1);
159 if (path == NULL)
160 goto error;
161
162 /*
163 * The simplest way to get the partition number under linux is
164 * to parse it out of the /dev/<disk><parition> block device name.
165 * The kernel creates this using the partition number when it
166 * populates /dev/ so it may be trusted. The tricky bit here is
167 * that the naming convention is based on the block device type.
168 * So we need to take this in to account when parsing out the
169 * partition information. Another issue is that the libefi API
170 * API only provides the open fd and not the file path. To handle
171 * this realpath(3) is used to resolve the block device name from
172 * /proc/self/fd/<fd>. Aside from the partition number we collect
173 * some additional device info.
174 */
175 (void) sprintf(path, "/proc/self/fd/%d", fd);
176 dev_path = realpath(path, NULL);
177 free(path);
178
179 if (dev_path == NULL)
180 goto error;
181
182 if ((strncmp(dev_path, "/dev/sd", 7) == 0)) {
183 strcpy(dki_info->dki_cname, "sd");
184 dki_info->dki_ctype = DKC_SCSI_CCS;
185 rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
186 dki_info->dki_dname,
187 &dki_info->dki_partition);
188 } else if ((strncmp(dev_path, "/dev/hd", 7) == 0)) {
189 strcpy(dki_info->dki_cname, "hd");
190 dki_info->dki_ctype = DKC_DIRECT;
191 rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
192 dki_info->dki_dname,
193 &dki_info->dki_partition);
194 } else if ((strncmp(dev_path, "/dev/md", 7) == 0)) {
195 strcpy(dki_info->dki_cname, "pseudo");
196 dki_info->dki_ctype = DKC_MD;
197 strcpy(dki_info->dki_dname, "md");
198 rval = sscanf(dev_path, "/dev/md%[0-9]p%hu",
199 dki_info->dki_dname + 2,
200 &dki_info->dki_partition);
201 } else if ((strncmp(dev_path, "/dev/vd", 7) == 0)) {
202 strcpy(dki_info->dki_cname, "vd");
203 dki_info->dki_ctype = DKC_MD;
204 rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
205 dki_info->dki_dname,
206 &dki_info->dki_partition);
207 } else if ((strncmp(dev_path, "/dev/dm-", 8) == 0)) {
208 strcpy(dki_info->dki_cname, "pseudo");
209 dki_info->dki_ctype = DKC_VBD;
210 strcpy(dki_info->dki_dname, "dm-");
211 rval = sscanf(dev_path, "/dev/dm-%[0-9]p%hu",
212 dki_info->dki_dname + 3,
213 &dki_info->dki_partition);
214 } else if ((strncmp(dev_path, "/dev/ram", 8) == 0)) {
215 strcpy(dki_info->dki_cname, "pseudo");
216 dki_info->dki_ctype = DKC_PCMCIA_MEM;
217 strcpy(dki_info->dki_dname, "ram");
218 rval = sscanf(dev_path, "/dev/ram%[0-9]p%hu",
219 dki_info->dki_dname + 3,
220 &dki_info->dki_partition);
221 } else if ((strncmp(dev_path, "/dev/loop", 9) == 0)) {
222 strcpy(dki_info->dki_cname, "pseudo");
223 dki_info->dki_ctype = DKC_VBD;
224 strcpy(dki_info->dki_dname, "loop");
225 rval = sscanf(dev_path, "/dev/loop%[0-9]p%hu",
226 dki_info->dki_dname + 4,
227 &dki_info->dki_partition);
228 } else {
229 strcpy(dki_info->dki_dname, "unknown");
230 strcpy(dki_info->dki_cname, "unknown");
231 dki_info->dki_ctype = DKC_UNKNOWN;
232 }
233
234 switch (rval) {
235 case 0:
236 errno = EINVAL;
237 goto error;
238 case 1:
239 dki_info->dki_partition = 0;
240 }
241
242 free(dev_path);
243 #else
244 if (ioctl(fd, DKIOCINFO, (caddr_t)dki_info) == -1)
245 goto error;
246 #endif
247 return (0);
248 error:
249 if (efi_debug)
250 (void) fprintf(stderr, "DKIOCINFO errno 0x%x\n", errno);
251
252 switch (errno) {
253 case EIO:
254 return (VT_EIO);
255 case EINVAL:
256 return (VT_EINVAL);
257 default:
258 return (VT_ERROR);
259 }
260 }
261
262 /*
263 * the number of blocks the EFI label takes up (round up to nearest
264 * block)
265 */
266 #define NBLOCKS(p, l) (1 + ((((p) * (int)sizeof (efi_gpe_t)) + \
267 ((l) - 1)) / (l)))
268 /* number of partitions -- limited by what we can malloc */
269 #define MAX_PARTS ((4294967295UL - sizeof (struct dk_gpt)) / \
270 sizeof (struct dk_part))
271
272 int
273 efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc)
274 {
275 diskaddr_t capacity = 0;
276 uint_t lbsize = 0;
277 uint_t nblocks;
278 size_t length;
279 struct dk_gpt *vptr;
280 struct uuid uuid;
281 struct dk_cinfo dki_info;
282
283 if (read_disk_info(fd, &capacity, &lbsize) != 0)
284 return (-1);
285
286 #if defined(__linux__)
287 if (efi_get_info(fd, &dki_info) != 0)
288 return (-1);
289
290 if (dki_info.dki_partition != 0)
291 return (-1);
292
293 if ((dki_info.dki_ctype == DKC_PCMCIA_MEM) ||
294 (dki_info.dki_ctype == DKC_VBD) ||
295 (dki_info.dki_ctype == DKC_UNKNOWN))
296 return (-1);
297 #endif
298
299 nblocks = NBLOCKS(nparts, lbsize);
300 if ((nblocks * lbsize) < EFI_MIN_ARRAY_SIZE + lbsize) {
301 /* 16K plus one block for the GPT */
302 nblocks = EFI_MIN_ARRAY_SIZE / lbsize + 1;
303 }
304
305 if (nparts > MAX_PARTS) {
306 if (efi_debug) {
307 (void) fprintf(stderr,
308 "the maximum number of partitions supported is %lu\n",
309 MAX_PARTS);
310 }
311 return (-1);
312 }
313
314 length = sizeof (struct dk_gpt) +
315 sizeof (struct dk_part) * (nparts - 1);
316
317 if ((*vtoc = calloc(length, 1)) == NULL)
318 return (-1);
319
320 vptr = *vtoc;
321
322 vptr->efi_version = EFI_VERSION_CURRENT;
323 vptr->efi_lbasize = lbsize;
324 vptr->efi_nparts = nparts;
325 /*
326 * add one block here for the PMBR; on disks with a 512 byte
327 * block size and 128 or fewer partitions, efi_first_u_lba
328 * should work out to "34"
329 */
330 vptr->efi_first_u_lba = nblocks + 1;
331 vptr->efi_last_lba = capacity - 1;
332 vptr->efi_altern_lba = capacity -1;
333 vptr->efi_last_u_lba = vptr->efi_last_lba - nblocks;
334
335 (void) uuid_generate((uchar_t *)&uuid);
336 UUID_LE_CONVERT(vptr->efi_disk_uguid, uuid);
337 return (0);
338 }
339
340 /*
341 * Read EFI - return partition number upon success.
342 */
343 int
344 efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
345 {
346 int rval;
347 uint32_t nparts;
348 int length;
349
350 /* figure out the number of entries that would fit into 16K */
351 nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t);
352 length = (int) sizeof (struct dk_gpt) +
353 (int) sizeof (struct dk_part) * (nparts - 1);
354 if ((*vtoc = calloc(length, 1)) == NULL)
355 return (VT_ERROR);
356
357 (*vtoc)->efi_nparts = nparts;
358 rval = efi_read(fd, *vtoc);
359
360 if ((rval == VT_EINVAL) && (*vtoc)->efi_nparts > nparts) {
361 void *tmp;
362 length = (int) sizeof (struct dk_gpt) +
363 (int) sizeof (struct dk_part) *
364 ((*vtoc)->efi_nparts - 1);
365 nparts = (*vtoc)->efi_nparts;
366 if ((tmp = realloc(*vtoc, length)) == NULL) {
367 free (*vtoc);
368 *vtoc = NULL;
369 return (VT_ERROR);
370 } else {
371 *vtoc = tmp;
372 rval = efi_read(fd, *vtoc);
373 }
374 }
375
376 if (rval < 0) {
377 if (efi_debug) {
378 (void) fprintf(stderr,
379 "read of EFI table failed, rval=%d\n", rval);
380 }
381 free (*vtoc);
382 *vtoc = NULL;
383 }
384
385 return (rval);
386 }
387
388 static int
389 efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc)
390 {
391 void *data = dk_ioc->dki_data;
392 int error;
393 #if defined(__linux__)
394 diskaddr_t capacity;
395 uint_t lbsize;
396
397 /*
398 * When the IO is not being performed in kernel as an ioctl we need
399 * to know the sector size so we can seek to the proper byte offset.
400 */
401 if (read_disk_info(fd, &capacity, &lbsize) == -1) {
402 if (efi_debug)
403 fprintf(stderr, "unable to read disk info: %d", errno);
404
405 errno = EIO;
406 return (-1);
407 }
408
409 switch (cmd) {
410 case DKIOCGETEFI:
411 if (lbsize == 0) {
412 if (efi_debug)
413 (void) fprintf(stderr, "DKIOCGETEFI assuming "
414 "LBA %d bytes\n", DEV_BSIZE);
415
416 lbsize = DEV_BSIZE;
417 }
418
419 error = lseek(fd, dk_ioc->dki_lba * lbsize, SEEK_SET);
420 if (error == -1) {
421 if (efi_debug)
422 (void) fprintf(stderr, "DKIOCGETEFI lseek "
423 "error: %d\n", errno);
424 return (error);
425 }
426
427 error = read(fd, data, dk_ioc->dki_length);
428 if (error == -1) {
429 if (efi_debug)
430 (void) fprintf(stderr, "DKIOCGETEFI read "
431 "error: %d\n", errno);
432 return (error);
433 }
434
435 if (error != dk_ioc->dki_length) {
436 if (efi_debug)
437 (void) fprintf(stderr, "DKIOCGETEFI short "
438 "read of %d bytes\n", error);
439 errno = EIO;
440 return (-1);
441 }
442 error = 0;
443 break;
444
445 case DKIOCSETEFI:
446 if (lbsize == 0) {
447 if (efi_debug)
448 (void) fprintf(stderr, "DKIOCSETEFI unknown "
449 "LBA size\n");
450 errno = EIO;
451 return (-1);
452 }
453
454 error = lseek(fd, dk_ioc->dki_lba * lbsize, SEEK_SET);
455 if (error == -1) {
456 if (efi_debug)
457 (void) fprintf(stderr, "DKIOCSETEFI lseek "
458 "error: %d\n", errno);
459 return (error);
460 }
461
462 error = write(fd, data, dk_ioc->dki_length);
463 if (error == -1) {
464 if (efi_debug)
465 (void) fprintf(stderr, "DKIOCSETEFI write "
466 "error: %d\n", errno);
467 return (error);
468 }
469
470 if (error != dk_ioc->dki_length) {
471 if (efi_debug)
472 (void) fprintf(stderr, "DKIOCSETEFI short "
473 "write of %d bytes\n", error);
474 errno = EIO;
475 return (-1);
476 }
477
478 /* Sync the new EFI table to disk */
479 error = fsync(fd);
480 if (error == -1)
481 return (error);
482
483 /* Ensure any local disk cache is also flushed */
484 if (ioctl(fd, BLKFLSBUF, 0) == -1)
485 return (error);
486
487 error = 0;
488 break;
489
490 default:
491 if (efi_debug)
492 (void) fprintf(stderr, "unsupported ioctl()\n");
493
494 errno = EIO;
495 return (-1);
496 }
497 #else
498 dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data;
499 error = ioctl(fd, cmd, (void *)dk_ioc);
500 dk_ioc->dki_data = data;
501 #endif
502 return (error);
503 }
504
505 int
506 efi_rescan(int fd)
507 {
508 #if defined(__linux__)
509 int retry = 10;
510 int error;
511
512 /* Notify the kernel a devices partition table has been updated */
513 while ((error = ioctl(fd, BLKRRPART)) != 0) {
514 if ((--retry == 0) || (errno != EBUSY)) {
515 (void) fprintf(stderr, "the kernel failed to rescan "
516 "the partition table: %d\n", errno);
517 return (-1);
518 }
519 usleep(50000);
520 }
521 #endif
522
523 return (0);
524 }
525
526 static int
527 check_label(int fd, dk_efi_t *dk_ioc)
528 {
529 efi_gpt_t *efi;
530 uint_t crc;
531
532 if (efi_ioctl(fd, DKIOCGETEFI, dk_ioc) == -1) {
533 switch (errno) {
534 case EIO:
535 return (VT_EIO);
536 default:
537 return (VT_ERROR);
538 }
539 }
540 efi = dk_ioc->dki_data;
541 if (efi->efi_gpt_Signature != LE_64(EFI_SIGNATURE)) {
542 if (efi_debug)
543 (void) fprintf(stderr,
544 "Bad EFI signature: 0x%llx != 0x%llx\n",
545 (long long)efi->efi_gpt_Signature,
546 (long long)LE_64(EFI_SIGNATURE));
547 return (VT_EINVAL);
548 }
549
550 /*
551 * check CRC of the header; the size of the header should
552 * never be larger than one block
553 */
554 crc = efi->efi_gpt_HeaderCRC32;
555 efi->efi_gpt_HeaderCRC32 = 0;
556 len_t headerSize = (len_t)LE_32(efi->efi_gpt_HeaderSize);
557
558 if (headerSize < EFI_MIN_LABEL_SIZE || headerSize > EFI_LABEL_SIZE) {
559 if (efi_debug)
560 (void) fprintf(stderr,
561 "Invalid EFI HeaderSize %llu. Assuming %d.\n",
562 headerSize, EFI_MIN_LABEL_SIZE);
563 }
564
565 if ((headerSize > dk_ioc->dki_length) ||
566 crc != LE_32(efi_crc32((unsigned char *)efi, headerSize))) {
567 if (efi_debug)
568 (void) fprintf(stderr,
569 "Bad EFI CRC: 0x%x != 0x%x\n",
570 crc, LE_32(efi_crc32((unsigned char *)efi,
571 headerSize)));
572 return (VT_EINVAL);
573 }
574
575 return (0);
576 }
577
578 static int
579 efi_read(int fd, struct dk_gpt *vtoc)
580 {
581 int i, j;
582 int label_len;
583 int rval = 0;
584 int md_flag = 0;
585 int vdc_flag = 0;
586 diskaddr_t capacity = 0;
587 uint_t lbsize = 0;
588 struct dk_minfo disk_info;
589 dk_efi_t dk_ioc;
590 efi_gpt_t *efi;
591 efi_gpe_t *efi_parts;
592 struct dk_cinfo dki_info;
593 uint32_t user_length;
594 boolean_t legacy_label = B_FALSE;
595
596 /*
597 * get the partition number for this file descriptor.
598 */
599 if ((rval = efi_get_info(fd, &dki_info)) != 0)
600 return (rval);
601
602 if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) &&
603 (strncmp(dki_info.dki_dname, "md", 3) == 0)) {
604 md_flag++;
605 } else if ((strncmp(dki_info.dki_cname, "vdc", 4) == 0) &&
606 (strncmp(dki_info.dki_dname, "vdc", 4) == 0)) {
607 /*
608 * The controller and drive name "vdc" (virtual disk client)
609 * indicates a LDoms virtual disk.
610 */
611 vdc_flag++;
612 }
613
614 /* get the LBA size */
615 if (read_disk_info(fd, &capacity, &lbsize) == -1) {
616 if (efi_debug) {
617 (void) fprintf(stderr,
618 "unable to read disk info: %d",
619 errno);
620 }
621 return (VT_EINVAL);
622 }
623
624 disk_info.dki_lbsize = lbsize;
625 disk_info.dki_capacity = capacity;
626
627 if (disk_info.dki_lbsize == 0) {
628 if (efi_debug) {
629 (void) fprintf(stderr,
630 "efi_read: assuming LBA 512 bytes\n");
631 }
632 disk_info.dki_lbsize = DEV_BSIZE;
633 }
634 /*
635 * Read the EFI GPT to figure out how many partitions we need
636 * to deal with.
637 */
638 dk_ioc.dki_lba = 1;
639 if (NBLOCKS(vtoc->efi_nparts, disk_info.dki_lbsize) < 34) {
640 label_len = EFI_MIN_ARRAY_SIZE + disk_info.dki_lbsize;
641 } else {
642 label_len = vtoc->efi_nparts * (int) sizeof (efi_gpe_t) +
643 disk_info.dki_lbsize;
644 if (label_len % disk_info.dki_lbsize) {
645 /* pad to physical sector size */
646 label_len += disk_info.dki_lbsize;
647 label_len &= ~(disk_info.dki_lbsize - 1);
648 }
649 }
650
651 if (posix_memalign((void **)&dk_ioc.dki_data,
652 disk_info.dki_lbsize, label_len))
653 return (VT_ERROR);
654
655 memset(dk_ioc.dki_data, 0, label_len);
656 dk_ioc.dki_length = disk_info.dki_lbsize;
657 user_length = vtoc->efi_nparts;
658 efi = dk_ioc.dki_data;
659 if (md_flag) {
660 dk_ioc.dki_length = label_len;
661 if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1) {
662 switch (errno) {
663 case EIO:
664 return (VT_EIO);
665 default:
666 return (VT_ERROR);
667 }
668 }
669 } else if ((rval = check_label(fd, &dk_ioc)) == VT_EINVAL) {
670 /*
671 * No valid label here; try the alternate. Note that here
672 * we just read GPT header and save it into dk_ioc.data,
673 * Later, we will read GUID partition entry array if we
674 * can get valid GPT header.
675 */
676
677 /*
678 * This is a workaround for legacy systems. In the past, the
679 * last sector of SCSI disk was invisible on x86 platform. At
680 * that time, backup label was saved on the next to the last
681 * sector. It is possible for users to move a disk from previous
682 * solaris system to present system. Here, we attempt to search
683 * legacy backup EFI label first.
684 */
685 dk_ioc.dki_lba = disk_info.dki_capacity - 2;
686 dk_ioc.dki_length = disk_info.dki_lbsize;
687 rval = check_label(fd, &dk_ioc);
688 if (rval == VT_EINVAL) {
689 /*
690 * we didn't find legacy backup EFI label, try to
691 * search backup EFI label in the last block.
692 */
693 dk_ioc.dki_lba = disk_info.dki_capacity - 1;
694 dk_ioc.dki_length = disk_info.dki_lbsize;
695 rval = check_label(fd, &dk_ioc);
696 if (rval == 0) {
697 legacy_label = B_TRUE;
698 if (efi_debug)
699 (void) fprintf(stderr,
700 "efi_read: primary label corrupt; "
701 "using EFI backup label located on"
702 " the last block\n");
703 }
704 } else {
705 if ((efi_debug) && (rval == 0))
706 (void) fprintf(stderr, "efi_read: primary label"
707 " corrupt; using legacy EFI backup label "
708 " located on the next to last block\n");
709 }
710
711 if (rval == 0) {
712 dk_ioc.dki_lba = LE_64(efi->efi_gpt_PartitionEntryLBA);
713 vtoc->efi_flags |= EFI_GPT_PRIMARY_CORRUPT;
714 vtoc->efi_nparts =
715 LE_32(efi->efi_gpt_NumberOfPartitionEntries);
716 /*
717 * Partition tables are between backup GPT header
718 * table and ParitionEntryLBA (the starting LBA of
719 * the GUID partition entries array). Now that we
720 * already got valid GPT header and saved it in
721 * dk_ioc.dki_data, we try to get GUID partition
722 * entry array here.
723 */
724 /* LINTED */
725 dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data
726 + disk_info.dki_lbsize);
727 if (legacy_label)
728 dk_ioc.dki_length = disk_info.dki_capacity - 1 -
729 dk_ioc.dki_lba;
730 else
731 dk_ioc.dki_length = disk_info.dki_capacity - 2 -
732 dk_ioc.dki_lba;
733 dk_ioc.dki_length *= disk_info.dki_lbsize;
734 if (dk_ioc.dki_length >
735 ((len_t)label_len - sizeof (*dk_ioc.dki_data))) {
736 rval = VT_EINVAL;
737 } else {
738 /*
739 * read GUID partition entry array
740 */
741 rval = efi_ioctl(fd, DKIOCGETEFI, &dk_ioc);
742 }
743 }
744
745 } else if (rval == 0) {
746
747 dk_ioc.dki_lba = LE_64(efi->efi_gpt_PartitionEntryLBA);
748 /* LINTED */
749 dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data
750 + disk_info.dki_lbsize);
751 dk_ioc.dki_length = label_len - disk_info.dki_lbsize;
752 rval = efi_ioctl(fd, DKIOCGETEFI, &dk_ioc);
753
754 } else if (vdc_flag && rval == VT_ERROR && errno == EINVAL) {
755 /*
756 * When the device is a LDoms virtual disk, the DKIOCGETEFI
757 * ioctl can fail with EINVAL if the virtual disk backend
758 * is a ZFS volume serviced by a domain running an old version
759 * of Solaris. This is because the DKIOCGETEFI ioctl was
760 * initially incorrectly implemented for a ZFS volume and it
761 * expected the GPT and GPE to be retrieved with a single ioctl.
762 * So we try to read the GPT and the GPE using that old style
763 * ioctl.
764 */
765 dk_ioc.dki_lba = 1;
766 dk_ioc.dki_length = label_len;
767 rval = check_label(fd, &dk_ioc);
768 }
769
770 if (rval < 0) {
771 free(efi);
772 return (rval);
773 }
774
775 /* LINTED -- always longlong aligned */
776 efi_parts = (efi_gpe_t *)(((char *)efi) + disk_info.dki_lbsize);
777
778 /*
779 * Assemble this into a "dk_gpt" struct for easier
780 * digestibility by applications.
781 */
782 vtoc->efi_version = LE_32(efi->efi_gpt_Revision);
783 vtoc->efi_nparts = LE_32(efi->efi_gpt_NumberOfPartitionEntries);
784 vtoc->efi_part_size = LE_32(efi->efi_gpt_SizeOfPartitionEntry);
785 vtoc->efi_lbasize = disk_info.dki_lbsize;
786 vtoc->efi_last_lba = disk_info.dki_capacity - 1;
787 vtoc->efi_first_u_lba = LE_64(efi->efi_gpt_FirstUsableLBA);
788 vtoc->efi_last_u_lba = LE_64(efi->efi_gpt_LastUsableLBA);
789 vtoc->efi_altern_lba = LE_64(efi->efi_gpt_AlternateLBA);
790 UUID_LE_CONVERT(vtoc->efi_disk_uguid, efi->efi_gpt_DiskGUID);
791
792 /*
793 * If the array the user passed in is too small, set the length
794 * to what it needs to be and return
795 */
796 if (user_length < vtoc->efi_nparts) {
797 return (VT_EINVAL);
798 }
799
800 for (i = 0; i < vtoc->efi_nparts; i++) {
801
802 UUID_LE_CONVERT(vtoc->efi_parts[i].p_guid,
803 efi_parts[i].efi_gpe_PartitionTypeGUID);
804
805 for (j = 0;
806 j < sizeof (conversion_array)
807 / sizeof (struct uuid_to_ptag); j++) {
808
809 if (bcmp(&vtoc->efi_parts[i].p_guid,
810 &conversion_array[j].uuid,
811 sizeof (struct uuid)) == 0) {
812 vtoc->efi_parts[i].p_tag = j;
813 break;
814 }
815 }
816 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED)
817 continue;
818 vtoc->efi_parts[i].p_flag =
819 LE_16(efi_parts[i].efi_gpe_Attributes.PartitionAttrs);
820 vtoc->efi_parts[i].p_start =
821 LE_64(efi_parts[i].efi_gpe_StartingLBA);
822 vtoc->efi_parts[i].p_size =
823 LE_64(efi_parts[i].efi_gpe_EndingLBA) -
824 vtoc->efi_parts[i].p_start + 1;
825 for (j = 0; j < EFI_PART_NAME_LEN; j++) {
826 vtoc->efi_parts[i].p_name[j] =
827 (uchar_t)LE_16(
828 efi_parts[i].efi_gpe_PartitionName[j]);
829 }
830
831 UUID_LE_CONVERT(vtoc->efi_parts[i].p_uguid,
832 efi_parts[i].efi_gpe_UniquePartitionGUID);
833 }
834 free(efi);
835
836 return (dki_info.dki_partition);
837 }
838
839 /* writes a "protective" MBR */
840 static int
841 write_pmbr(int fd, struct dk_gpt *vtoc)
842 {
843 dk_efi_t dk_ioc;
844 struct mboot mb;
845 uchar_t *cp;
846 diskaddr_t size_in_lba;
847 uchar_t *buf;
848 int len;
849
850 len = (vtoc->efi_lbasize == 0) ? sizeof (mb) : vtoc->efi_lbasize;
851 if (posix_memalign((void **)&buf, len, len))
852 return (VT_ERROR);
853
854 /*
855 * Preserve any boot code and disk signature if the first block is
856 * already an MBR.
857 */
858 memset(buf, 0, len);
859 dk_ioc.dki_lba = 0;
860 dk_ioc.dki_length = len;
861 /* LINTED -- always longlong aligned */
862 dk_ioc.dki_data = (efi_gpt_t *)buf;
863 if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1) {
864 (void) memcpy(&mb, buf, sizeof (mb));
865 bzero(&mb, sizeof (mb));
866 mb.signature = LE_16(MBB_MAGIC);
867 } else {
868 (void) memcpy(&mb, buf, sizeof (mb));
869 if (mb.signature != LE_16(MBB_MAGIC)) {
870 bzero(&mb, sizeof (mb));
871 mb.signature = LE_16(MBB_MAGIC);
872 }
873 }
874
875 bzero(&mb.parts, sizeof (mb.parts));
876 cp = (uchar_t *)&mb.parts[0];
877 /* bootable or not */
878 *cp++ = 0;
879 /* beginning CHS; 0xffffff if not representable */
880 *cp++ = 0xff;
881 *cp++ = 0xff;
882 *cp++ = 0xff;
883 /* OS type */
884 *cp++ = EFI_PMBR;
885 /* ending CHS; 0xffffff if not representable */
886 *cp++ = 0xff;
887 *cp++ = 0xff;
888 *cp++ = 0xff;
889 /* starting LBA: 1 (little endian format) by EFI definition */
890 *cp++ = 0x01;
891 *cp++ = 0x00;
892 *cp++ = 0x00;
893 *cp++ = 0x00;
894 /* ending LBA: last block on the disk (little endian format) */
895 size_in_lba = vtoc->efi_last_lba;
896 if (size_in_lba < 0xffffffff) {
897 *cp++ = (size_in_lba & 0x000000ff);
898 *cp++ = (size_in_lba & 0x0000ff00) >> 8;
899 *cp++ = (size_in_lba & 0x00ff0000) >> 16;
900 *cp++ = (size_in_lba & 0xff000000) >> 24;
901 } else {
902 *cp++ = 0xff;
903 *cp++ = 0xff;
904 *cp++ = 0xff;
905 *cp++ = 0xff;
906 }
907
908 (void) memcpy(buf, &mb, sizeof (mb));
909 /* LINTED -- always longlong aligned */
910 dk_ioc.dki_data = (efi_gpt_t *)buf;
911 dk_ioc.dki_lba = 0;
912 dk_ioc.dki_length = len;
913 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
914 free(buf);
915 switch (errno) {
916 case EIO:
917 return (VT_EIO);
918 case EINVAL:
919 return (VT_EINVAL);
920 default:
921 return (VT_ERROR);
922 }
923 }
924 free(buf);
925 return (0);
926 }
927
928 /* make sure the user specified something reasonable */
929 static int
930 check_input(struct dk_gpt *vtoc)
931 {
932 int resv_part = -1;
933 int i, j;
934 diskaddr_t istart, jstart, isize, jsize, endsect;
935
936 /*
937 * Sanity-check the input (make sure no partitions overlap)
938 */
939 for (i = 0; i < vtoc->efi_nparts; i++) {
940 /* It can't be unassigned and have an actual size */
941 if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) &&
942 (vtoc->efi_parts[i].p_size != 0)) {
943 if (efi_debug) {
944 (void) fprintf(stderr, "partition %d is "
945 "\"unassigned\" but has a size of %llu",
946 i, vtoc->efi_parts[i].p_size);
947 }
948 return (VT_EINVAL);
949 }
950 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) {
951 if (uuid_is_null((uchar_t *)&vtoc->efi_parts[i].p_guid))
952 continue;
953 /* we have encountered an unknown uuid */
954 vtoc->efi_parts[i].p_tag = 0xff;
955 }
956 if (vtoc->efi_parts[i].p_tag == V_RESERVED) {
957 if (resv_part != -1) {
958 if (efi_debug) {
959 (void) fprintf(stderr, "found "
960 "duplicate reserved partition "
961 "at %d\n", i);
962 }
963 return (VT_EINVAL);
964 }
965 resv_part = i;
966 }
967 if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) ||
968 (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) {
969 if (efi_debug) {
970 (void) fprintf(stderr,
971 "Partition %d starts at %llu. ",
972 i,
973 vtoc->efi_parts[i].p_start);
974 (void) fprintf(stderr,
975 "It must be between %llu and %llu.\n",
976 vtoc->efi_first_u_lba,
977 vtoc->efi_last_u_lba);
978 }
979 return (VT_EINVAL);
980 }
981 if ((vtoc->efi_parts[i].p_start +
982 vtoc->efi_parts[i].p_size <
983 vtoc->efi_first_u_lba) ||
984 (vtoc->efi_parts[i].p_start +
985 vtoc->efi_parts[i].p_size >
986 vtoc->efi_last_u_lba + 1)) {
987 if (efi_debug) {
988 (void) fprintf(stderr,
989 "Partition %d ends at %llu. ",
990 i,
991 vtoc->efi_parts[i].p_start +
992 vtoc->efi_parts[i].p_size);
993 (void) fprintf(stderr,
994 "It must be between %llu and %llu.\n",
995 vtoc->efi_first_u_lba,
996 vtoc->efi_last_u_lba);
997 }
998 return (VT_EINVAL);
999 }
1000
1001 for (j = 0; j < vtoc->efi_nparts; j++) {
1002 isize = vtoc->efi_parts[i].p_size;
1003 jsize = vtoc->efi_parts[j].p_size;
1004 istart = vtoc->efi_parts[i].p_start;
1005 jstart = vtoc->efi_parts[j].p_start;
1006 if ((i != j) && (isize != 0) && (jsize != 0)) {
1007 endsect = jstart + jsize -1;
1008 if ((jstart <= istart) &&
1009 (istart <= endsect)) {
1010 if (efi_debug) {
1011 (void) fprintf(stderr,
1012 "Partition %d overlaps "
1013 "partition %d.", i, j);
1014 }
1015 return (VT_EINVAL);
1016 }
1017 }
1018 }
1019 }
1020 /* just a warning for now */
1021 if ((resv_part == -1) && efi_debug) {
1022 (void) fprintf(stderr,
1023 "no reserved partition found\n");
1024 }
1025 return (0);
1026 }
1027
1028 /*
1029 * add all the unallocated space to the current label
1030 */
1031 int
1032 efi_use_whole_disk(int fd)
1033 {
1034 struct dk_gpt *efi_label;
1035 int rval;
1036 int i;
1037 uint_t resv_index = 0, data_index = 0;
1038 diskaddr_t resv_start = 0, data_start = 0;
1039 diskaddr_t difference;
1040
1041 rval = efi_alloc_and_read(fd, &efi_label);
1042 if (rval < 0) {
1043 return (rval);
1044 }
1045
1046 /*
1047 * If alter_lba is 1, we are using the backup label.
1048 * Since we can locate the backup label by disk capacity,
1049 * there must be no unallocated space.
1050 */
1051 if ((efi_label->efi_altern_lba == 1) || (efi_label->efi_altern_lba
1052 >= efi_label->efi_last_lba)) {
1053 if (efi_debug) {
1054 (void) fprintf(stderr,
1055 "efi_use_whole_disk: requested space not found\n");
1056 }
1057 efi_free(efi_label);
1058 return (VT_ENOSPC);
1059 }
1060
1061 difference = efi_label->efi_last_lba - efi_label->efi_altern_lba;
1062
1063 /*
1064 * Find the last physically non-zero partition.
1065 * This is the reserved partition.
1066 */
1067 for (i = 0; i < efi_label->efi_nparts; i ++) {
1068 if (resv_start < efi_label->efi_parts[i].p_start) {
1069 resv_start = efi_label->efi_parts[i].p_start;
1070 resv_index = i;
1071 }
1072 }
1073
1074 /*
1075 * Find the last physically non-zero partition before that.
1076 * This is the data partition.
1077 */
1078 for (i = 0; i < resv_index; i ++) {
1079 if (data_start < efi_label->efi_parts[i].p_start) {
1080 data_start = efi_label->efi_parts[i].p_start;
1081 data_index = i;
1082 }
1083 }
1084
1085 /*
1086 * Move the reserved partition. There is currently no data in
1087 * here except fabricated devids (which get generated via
1088 * efi_write()). So there is no need to copy data.
1089 */
1090 efi_label->efi_parts[data_index].p_size += difference;
1091 efi_label->efi_parts[resv_index].p_start += difference;
1092 efi_label->efi_last_u_lba += difference;
1093
1094 rval = efi_write(fd, efi_label);
1095 if (rval < 0) {
1096 if (efi_debug) {
1097 (void) fprintf(stderr,
1098 "efi_use_whole_disk:fail to write label, rval=%d\n",
1099 rval);
1100 }
1101 efi_free(efi_label);
1102 return (rval);
1103 }
1104
1105 efi_free(efi_label);
1106 return (0);
1107 }
1108
1109
1110 /*
1111 * write EFI label and backup label
1112 */
1113 int
1114 efi_write(int fd, struct dk_gpt *vtoc)
1115 {
1116 dk_efi_t dk_ioc;
1117 efi_gpt_t *efi;
1118 efi_gpe_t *efi_parts;
1119 int i, j;
1120 struct dk_cinfo dki_info;
1121 int rval;
1122 int md_flag = 0;
1123 int nblocks;
1124 diskaddr_t lba_backup_gpt_hdr;
1125
1126 if ((rval = efi_get_info(fd, &dki_info)) != 0)
1127 return (rval);
1128
1129 /* check if we are dealing wih a metadevice */
1130 if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) &&
1131 (strncmp(dki_info.dki_dname, "md", 3) == 0)) {
1132 md_flag = 1;
1133 }
1134
1135 if (check_input(vtoc)) {
1136 /*
1137 * not valid; if it's a metadevice just pass it down
1138 * because SVM will do its own checking
1139 */
1140 if (md_flag == 0) {
1141 return (VT_EINVAL);
1142 }
1143 }
1144
1145 dk_ioc.dki_lba = 1;
1146 if (NBLOCKS(vtoc->efi_nparts, vtoc->efi_lbasize) < 34) {
1147 dk_ioc.dki_length = EFI_MIN_ARRAY_SIZE + vtoc->efi_lbasize;
1148 } else {
1149 dk_ioc.dki_length = NBLOCKS(vtoc->efi_nparts,
1150 vtoc->efi_lbasize) *
1151 vtoc->efi_lbasize;
1152 }
1153
1154 /*
1155 * the number of blocks occupied by GUID partition entry array
1156 */
1157 nblocks = dk_ioc.dki_length / vtoc->efi_lbasize - 1;
1158
1159 /*
1160 * Backup GPT header is located on the block after GUID
1161 * partition entry array. Here, we calculate the address
1162 * for backup GPT header.
1163 */
1164 lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks;
1165 if (posix_memalign((void **)&dk_ioc.dki_data,
1166 vtoc->efi_lbasize, dk_ioc.dki_length))
1167 return (VT_ERROR);
1168
1169 memset(dk_ioc.dki_data, 0, dk_ioc.dki_length);
1170 efi = dk_ioc.dki_data;
1171
1172 /* stuff user's input into EFI struct */
1173 efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
1174 efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */
1175 efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt) - LEN_EFI_PAD);
1176 efi->efi_gpt_Reserved1 = 0;
1177 efi->efi_gpt_MyLBA = LE_64(1ULL);
1178 efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr);
1179 efi->efi_gpt_FirstUsableLBA = LE_64(vtoc->efi_first_u_lba);
1180 efi->efi_gpt_LastUsableLBA = LE_64(vtoc->efi_last_u_lba);
1181 efi->efi_gpt_PartitionEntryLBA = LE_64(2ULL);
1182 efi->efi_gpt_NumberOfPartitionEntries = LE_32(vtoc->efi_nparts);
1183 efi->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (struct efi_gpe));
1184 UUID_LE_CONVERT(efi->efi_gpt_DiskGUID, vtoc->efi_disk_uguid);
1185
1186 /* LINTED -- always longlong aligned */
1187 efi_parts = (efi_gpe_t *)((char *)dk_ioc.dki_data + vtoc->efi_lbasize);
1188
1189 for (i = 0; i < vtoc->efi_nparts; i++) {
1190 for (j = 0;
1191 j < sizeof (conversion_array) /
1192 sizeof (struct uuid_to_ptag); j++) {
1193
1194 if (vtoc->efi_parts[i].p_tag == j) {
1195 UUID_LE_CONVERT(
1196 efi_parts[i].efi_gpe_PartitionTypeGUID,
1197 conversion_array[j].uuid);
1198 break;
1199 }
1200 }
1201
1202 if (j == sizeof (conversion_array) /
1203 sizeof (struct uuid_to_ptag)) {
1204 /*
1205 * If we didn't have a matching uuid match, bail here.
1206 * Don't write a label with unknown uuid.
1207 */
1208 if (efi_debug) {
1209 (void) fprintf(stderr,
1210 "Unknown uuid for p_tag %d\n",
1211 vtoc->efi_parts[i].p_tag);
1212 }
1213 return (VT_EINVAL);
1214 }
1215
1216 /* Zero's should be written for empty partitions */
1217 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED)
1218 continue;
1219
1220 efi_parts[i].efi_gpe_StartingLBA =
1221 LE_64(vtoc->efi_parts[i].p_start);
1222 efi_parts[i].efi_gpe_EndingLBA =
1223 LE_64(vtoc->efi_parts[i].p_start +
1224 vtoc->efi_parts[i].p_size - 1);
1225 efi_parts[i].efi_gpe_Attributes.PartitionAttrs =
1226 LE_16(vtoc->efi_parts[i].p_flag);
1227 for (j = 0; j < EFI_PART_NAME_LEN; j++) {
1228 efi_parts[i].efi_gpe_PartitionName[j] =
1229 LE_16((ushort_t)vtoc->efi_parts[i].p_name[j]);
1230 }
1231 if ((vtoc->efi_parts[i].p_tag != V_UNASSIGNED) &&
1232 uuid_is_null((uchar_t *)&vtoc->efi_parts[i].p_uguid)) {
1233 (void) uuid_generate((uchar_t *)
1234 &vtoc->efi_parts[i].p_uguid);
1235 }
1236 bcopy(&vtoc->efi_parts[i].p_uguid,
1237 &efi_parts[i].efi_gpe_UniquePartitionGUID,
1238 sizeof (uuid_t));
1239 }
1240 efi->efi_gpt_PartitionEntryArrayCRC32 =
1241 LE_32(efi_crc32((unsigned char *)efi_parts,
1242 vtoc->efi_nparts * (int)sizeof (struct efi_gpe)));
1243 efi->efi_gpt_HeaderCRC32 =
1244 LE_32(efi_crc32((unsigned char *)efi,
1245 LE_32(efi->efi_gpt_HeaderSize)));
1246
1247 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
1248 free(dk_ioc.dki_data);
1249 switch (errno) {
1250 case EIO:
1251 return (VT_EIO);
1252 case EINVAL:
1253 return (VT_EINVAL);
1254 default:
1255 return (VT_ERROR);
1256 }
1257 }
1258 /* if it's a metadevice we're done */
1259 if (md_flag) {
1260 free(dk_ioc.dki_data);
1261 return (0);
1262 }
1263
1264 /* write backup partition array */
1265 dk_ioc.dki_lba = vtoc->efi_last_u_lba + 1;
1266 dk_ioc.dki_length -= vtoc->efi_lbasize;
1267 /* LINTED */
1268 dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data +
1269 vtoc->efi_lbasize);
1270
1271 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
1272 /*
1273 * we wrote the primary label okay, so don't fail
1274 */
1275 if (efi_debug) {
1276 (void) fprintf(stderr,
1277 "write of backup partitions to block %llu "
1278 "failed, errno %d\n",
1279 vtoc->efi_last_u_lba + 1,
1280 errno);
1281 }
1282 }
1283 /*
1284 * now swap MyLBA and AlternateLBA fields and write backup
1285 * partition table header
1286 */
1287 dk_ioc.dki_lba = lba_backup_gpt_hdr;
1288 dk_ioc.dki_length = vtoc->efi_lbasize;
1289 /* LINTED */
1290 dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data -
1291 vtoc->efi_lbasize);
1292 efi->efi_gpt_AlternateLBA = LE_64(1ULL);
1293 efi->efi_gpt_MyLBA = LE_64(lba_backup_gpt_hdr);
1294 efi->efi_gpt_PartitionEntryLBA = LE_64(vtoc->efi_last_u_lba + 1);
1295 efi->efi_gpt_HeaderCRC32 = 0;
1296 efi->efi_gpt_HeaderCRC32 =
1297 LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data,
1298 LE_32(efi->efi_gpt_HeaderSize)));
1299
1300 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
1301 if (efi_debug) {
1302 (void) fprintf(stderr,
1303 "write of backup header to block %llu failed, "
1304 "errno %d\n",
1305 lba_backup_gpt_hdr,
1306 errno);
1307 }
1308 }
1309 /* write the PMBR */
1310 (void) write_pmbr(fd, vtoc);
1311 free(dk_ioc.dki_data);
1312
1313 return (0);
1314 }
1315
1316 void
1317 efi_free(struct dk_gpt *ptr)
1318 {
1319 free(ptr);
1320 }
1321
1322 /*
1323 * Input: File descriptor
1324 * Output: 1 if disk has an EFI label, or > 2TB with no VTOC or legacy MBR.
1325 * Otherwise 0.
1326 */
1327 int
1328 efi_type(int fd)
1329 {
1330 #if 0
1331 struct vtoc vtoc;
1332 struct extvtoc extvtoc;
1333
1334 if (ioctl(fd, DKIOCGEXTVTOC, &extvtoc) == -1) {
1335 if (errno == ENOTSUP)
1336 return (1);
1337 else if (errno == ENOTTY) {
1338 if (ioctl(fd, DKIOCGVTOC, &vtoc) == -1)
1339 if (errno == ENOTSUP)
1340 return (1);
1341 }
1342 }
1343 return (0);
1344 #else
1345 return (ENOSYS);
1346 #endif
1347 }
1348
1349 void
1350 efi_err_check(struct dk_gpt *vtoc)
1351 {
1352 int resv_part = -1;
1353 int i, j;
1354 diskaddr_t istart, jstart, isize, jsize, endsect;
1355 int overlap = 0;
1356
1357 /*
1358 * make sure no partitions overlap
1359 */
1360 for (i = 0; i < vtoc->efi_nparts; i++) {
1361 /* It can't be unassigned and have an actual size */
1362 if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) &&
1363 (vtoc->efi_parts[i].p_size != 0)) {
1364 (void) fprintf(stderr,
1365 "partition %d is \"unassigned\" but has a size "
1366 "of %llu\n", i, vtoc->efi_parts[i].p_size);
1367 }
1368 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) {
1369 continue;
1370 }
1371 if (vtoc->efi_parts[i].p_tag == V_RESERVED) {
1372 if (resv_part != -1) {
1373 (void) fprintf(stderr,
1374 "found duplicate reserved partition at "
1375 "%d\n", i);
1376 }
1377 resv_part = i;
1378 if (vtoc->efi_parts[i].p_size != EFI_MIN_RESV_SIZE)
1379 (void) fprintf(stderr,
1380 "Warning: reserved partition size must "
1381 "be %d sectors\n", EFI_MIN_RESV_SIZE);
1382 }
1383 if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) ||
1384 (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) {
1385 (void) fprintf(stderr,
1386 "Partition %d starts at %llu\n",
1387 i,
1388 vtoc->efi_parts[i].p_start);
1389 (void) fprintf(stderr,
1390 "It must be between %llu and %llu.\n",
1391 vtoc->efi_first_u_lba,
1392 vtoc->efi_last_u_lba);
1393 }
1394 if ((vtoc->efi_parts[i].p_start +
1395 vtoc->efi_parts[i].p_size <
1396 vtoc->efi_first_u_lba) ||
1397 (vtoc->efi_parts[i].p_start +
1398 vtoc->efi_parts[i].p_size >
1399 vtoc->efi_last_u_lba + 1)) {
1400 (void) fprintf(stderr,
1401 "Partition %d ends at %llu\n",
1402 i,
1403 vtoc->efi_parts[i].p_start +
1404 vtoc->efi_parts[i].p_size);
1405 (void) fprintf(stderr,
1406 "It must be between %llu and %llu.\n",
1407 vtoc->efi_first_u_lba,
1408 vtoc->efi_last_u_lba);
1409 }
1410
1411 for (j = 0; j < vtoc->efi_nparts; j++) {
1412 isize = vtoc->efi_parts[i].p_size;
1413 jsize = vtoc->efi_parts[j].p_size;
1414 istart = vtoc->efi_parts[i].p_start;
1415 jstart = vtoc->efi_parts[j].p_start;
1416 if ((i != j) && (isize != 0) && (jsize != 0)) {
1417 endsect = jstart + jsize -1;
1418 if ((jstart <= istart) &&
1419 (istart <= endsect)) {
1420 if (!overlap) {
1421 (void) fprintf(stderr,
1422 "label error: EFI Labels do not "
1423 "support overlapping partitions\n");
1424 }
1425 (void) fprintf(stderr,
1426 "Partition %d overlaps partition "
1427 "%d.\n", i, j);
1428 overlap = 1;
1429 }
1430 }
1431 }
1432 }
1433 /* make sure there is a reserved partition */
1434 if (resv_part == -1) {
1435 (void) fprintf(stderr,
1436 "no reserved partition found\n");
1437 }
1438 }
1439
1440 /*
1441 * We need to get information necessary to construct a *new* efi
1442 * label type
1443 */
1444 int
1445 efi_auto_sense(int fd, struct dk_gpt **vtoc)
1446 {
1447
1448 int i;
1449
1450 /*
1451 * Now build the default partition table
1452 */
1453 if (efi_alloc_and_init(fd, EFI_NUMPAR, vtoc) != 0) {
1454 if (efi_debug) {
1455 (void) fprintf(stderr, "efi_alloc_and_init failed.\n");
1456 }
1457 return (-1);
1458 }
1459
1460 for (i = 0; i < MIN((*vtoc)->efi_nparts, V_NUMPAR); i++) {
1461 (*vtoc)->efi_parts[i].p_tag = default_vtoc_map[i].p_tag;
1462 (*vtoc)->efi_parts[i].p_flag = default_vtoc_map[i].p_flag;
1463 (*vtoc)->efi_parts[i].p_start = 0;
1464 (*vtoc)->efi_parts[i].p_size = 0;
1465 }
1466 /*
1467 * Make constants first
1468 * and variable partitions later
1469 */
1470
1471 /* root partition - s0 128 MB */
1472 (*vtoc)->efi_parts[0].p_start = 34;
1473 (*vtoc)->efi_parts[0].p_size = 262144;
1474
1475 /* partition - s1 128 MB */
1476 (*vtoc)->efi_parts[1].p_start = 262178;
1477 (*vtoc)->efi_parts[1].p_size = 262144;
1478
1479 /* partition -s2 is NOT the Backup disk */
1480 (*vtoc)->efi_parts[2].p_tag = V_UNASSIGNED;
1481
1482 /* partition -s6 /usr partition - HOG */
1483 (*vtoc)->efi_parts[6].p_start = 524322;
1484 (*vtoc)->efi_parts[6].p_size = (*vtoc)->efi_last_u_lba - 524322
1485 - (1024 * 16);
1486
1487 /* efi reserved partition - s9 16K */
1488 (*vtoc)->efi_parts[8].p_start = (*vtoc)->efi_last_u_lba - (1024 * 16);
1489 (*vtoc)->efi_parts[8].p_size = (1024 * 16);
1490 (*vtoc)->efi_parts[8].p_tag = V_RESERVED;
1491 return (0);
1492 }