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