17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * This file contains the code relating to label manipulation. 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include "global.h" 347c478bd9Sstevel@tonic-gate #include "label.h" 357c478bd9Sstevel@tonic-gate #include "misc.h" 367c478bd9Sstevel@tonic-gate #include "main.h" 377c478bd9Sstevel@tonic-gate #include "partition.h" 387c478bd9Sstevel@tonic-gate #include "ctlr_scsi.h" 397c478bd9Sstevel@tonic-gate #include <string.h> 407c478bd9Sstevel@tonic-gate #include <stdlib.h> 417c478bd9Sstevel@tonic-gate #include <memory.h> 427c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h> 437c478bd9Sstevel@tonic-gate #include <sys/efi_partition.h> 447c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 457c478bd9Sstevel@tonic-gate #include <sys/uuid.h> 467c478bd9Sstevel@tonic-gate #include <errno.h> 47*3ccda647Slclee #include <devid.h> 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #if defined(_FIRMWARE_NEEDS_FDISK) 507c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 517c478bd9Sstevel@tonic-gate #include "menu_fdisk.h" 527c478bd9Sstevel@tonic-gate #endif /* defined(_FIRMWARE_NEEDS_FDISK) */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #ifndef WD_NODE 557c478bd9Sstevel@tonic-gate #define WD_NODE 7 567c478bd9Sstevel@tonic-gate #endif 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #ifdef __STDC__ 597c478bd9Sstevel@tonic-gate /* 607c478bd9Sstevel@tonic-gate * Prototypes for ANSI C compilers 617c478bd9Sstevel@tonic-gate */ 627c478bd9Sstevel@tonic-gate static int do_geometry_sanity_check(void); 637c478bd9Sstevel@tonic-gate static int vtoc_to_label(struct dk_label *label, struct vtoc *vtoc, 647c478bd9Sstevel@tonic-gate struct dk_geom *geom); 657c478bd9Sstevel@tonic-gate extern int read_vtoc(int, struct vtoc *); 667c478bd9Sstevel@tonic-gate extern int write_vtoc(int, struct vtoc *); 677c478bd9Sstevel@tonic-gate static int vtoc64_to_label(struct efi_info *, struct dk_gpt *); 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate /* 727c478bd9Sstevel@tonic-gate * Prototypes for non-ANSI C compilers 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate static int do_geometry_sanity_check(); 757c478bd9Sstevel@tonic-gate static int vtoc_to_label(); 767c478bd9Sstevel@tonic-gate extern int read_vtoc(); 777c478bd9Sstevel@tonic-gate extern int write_vtoc(); 787c478bd9Sstevel@tonic-gate static int vtoc64_to_label(); 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* 837c478bd9Sstevel@tonic-gate * This routine checks the given label to see if it is valid. 847c478bd9Sstevel@tonic-gate */ 857c478bd9Sstevel@tonic-gate int 867c478bd9Sstevel@tonic-gate checklabel(label) 877c478bd9Sstevel@tonic-gate register struct dk_label *label; 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate /* 917c478bd9Sstevel@tonic-gate * Check the magic number. 927c478bd9Sstevel@tonic-gate */ 937c478bd9Sstevel@tonic-gate if (label->dkl_magic != DKL_MAGIC) 947c478bd9Sstevel@tonic-gate return (0); 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * Check the checksum. 977c478bd9Sstevel@tonic-gate */ 987c478bd9Sstevel@tonic-gate if (checksum(label, CK_CHECKSUM) != 0) 997c478bd9Sstevel@tonic-gate return (0); 1007c478bd9Sstevel@tonic-gate return (1); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* 1047c478bd9Sstevel@tonic-gate * This routine checks or calculates the label checksum, depending on 1057c478bd9Sstevel@tonic-gate * the mode it is called in. 1067c478bd9Sstevel@tonic-gate */ 1077c478bd9Sstevel@tonic-gate int 1087c478bd9Sstevel@tonic-gate checksum(label, mode) 1097c478bd9Sstevel@tonic-gate struct dk_label *label; 1107c478bd9Sstevel@tonic-gate int mode; 1117c478bd9Sstevel@tonic-gate { 1127c478bd9Sstevel@tonic-gate register short *sp, sum = 0; 1137c478bd9Sstevel@tonic-gate register short count = (sizeof (struct dk_label)) / (sizeof (short)); 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate /* 1167c478bd9Sstevel@tonic-gate * If we are generating a checksum, don't include the checksum 1177c478bd9Sstevel@tonic-gate * in the rolling xor. 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate if (mode == CK_MAKESUM) 1207c478bd9Sstevel@tonic-gate count -= 1; 1217c478bd9Sstevel@tonic-gate sp = (short *)label; 1227c478bd9Sstevel@tonic-gate /* 1237c478bd9Sstevel@tonic-gate * Take the xor of all the half-words in the label. 1247c478bd9Sstevel@tonic-gate */ 1257c478bd9Sstevel@tonic-gate while (count--) { 1267c478bd9Sstevel@tonic-gate sum ^= *sp++; 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * If we are checking the checksum, the total will be zero for 1307c478bd9Sstevel@tonic-gate * a correct checksum, so we can just return the sum. 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate if (mode == CK_CHECKSUM) 1337c478bd9Sstevel@tonic-gate return (sum); 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * If we are generating the checksum, fill it in. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate else { 1387c478bd9Sstevel@tonic-gate label->dkl_cksum = sum; 1397c478bd9Sstevel@tonic-gate return (0); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate /* 1447c478bd9Sstevel@tonic-gate * This routine is used to extract the id string from the string stored 1457c478bd9Sstevel@tonic-gate * in a disk label. The problem is that the string in the label has 1467c478bd9Sstevel@tonic-gate * the physical characteristics of the drive appended to it. The approach 1477c478bd9Sstevel@tonic-gate * is to find the beginning of the physical attributes portion of the string 1487c478bd9Sstevel@tonic-gate * and truncate it there. 1497c478bd9Sstevel@tonic-gate */ 1507c478bd9Sstevel@tonic-gate int 1517c478bd9Sstevel@tonic-gate trim_id(id) 1527c478bd9Sstevel@tonic-gate char *id; 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate register char *c; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate /* 1577c478bd9Sstevel@tonic-gate * Start at the end of the string. When we match the word ' cyl', 1587c478bd9Sstevel@tonic-gate * we are at the beginning of the attributes. 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate for (c = id + strlen(id); c >= id; c--) { 1617c478bd9Sstevel@tonic-gate if (strncmp(c, " cyl", strlen(" cyl")) == 0) { 1627c478bd9Sstevel@tonic-gate /* 1637c478bd9Sstevel@tonic-gate * Remove any white space. 1647c478bd9Sstevel@tonic-gate */ 1657c478bd9Sstevel@tonic-gate for (; (((*(c - 1) == ' ') || (*(c - 1) == '\t')) && 1667c478bd9Sstevel@tonic-gate (c >= id)); c--); 1677c478bd9Sstevel@tonic-gate break; 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * If we ran off the beginning of the string, something is wrong. 1727c478bd9Sstevel@tonic-gate */ 1737c478bd9Sstevel@tonic-gate if (c < id) 1747c478bd9Sstevel@tonic-gate return (-1); 1757c478bd9Sstevel@tonic-gate /* 1767c478bd9Sstevel@tonic-gate * Truncate the string. 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate *c = '\0'; 1797c478bd9Sstevel@tonic-gate return (0); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate /* 1837c478bd9Sstevel@tonic-gate * This routine is used by write_label() to do a quick sanity check on the 1847c478bd9Sstevel@tonic-gate * supplied geometry. This is not a thorough check. 1857c478bd9Sstevel@tonic-gate * 1867c478bd9Sstevel@tonic-gate * The SCSI READ_CAPACITY command is used here to get the capacity of the 1877c478bd9Sstevel@tonic-gate * disk. But, the available area to store data on a disk is usually less 1887c478bd9Sstevel@tonic-gate * than this. So, if the specified geometry evaluates to a value which falls 1897c478bd9Sstevel@tonic-gate * in this margin, then such illegal geometries can slip through the cracks. 1907c478bd9Sstevel@tonic-gate */ 1917c478bd9Sstevel@tonic-gate static int 1927c478bd9Sstevel@tonic-gate do_geometry_sanity_check() 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate struct scsi_capacity_16 capacity; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate if (uscsi_read_capacity(cur_file, &capacity)) { 1977c478bd9Sstevel@tonic-gate err_print("Warning: Unable to get capacity." 1987c478bd9Sstevel@tonic-gate " Cannot check geometry\n"); 1997c478bd9Sstevel@tonic-gate return (0); /* Just ignore this problem */ 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate if (capacity.sc_capacity < ncyl * nhead * nsect) { 2037c478bd9Sstevel@tonic-gate err_print("\nWarning: Current geometry overshoots " 2047c478bd9Sstevel@tonic-gate "actual geometry of disk\n\n"); 2057c478bd9Sstevel@tonic-gate if (check("Continue labelling disk") != 0) 2067c478bd9Sstevel@tonic-gate return (-1); 2077c478bd9Sstevel@tonic-gate return (0); /* Just ignore this problem */ 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate return (0); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 2147c478bd9Sstevel@tonic-gate * expand the internal 32-bit SMI VTOC into the 64-bit EFI version 2157c478bd9Sstevel@tonic-gate * for writing it out to the disk 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate int 2187c478bd9Sstevel@tonic-gate SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc, struct vtoc *old_vtoc) 2197c478bd9Sstevel@tonic-gate { 2207c478bd9Sstevel@tonic-gate int i, j; 2217c478bd9Sstevel@tonic-gate int vtoc_part_count = 0; 2227c478bd9Sstevel@tonic-gate int highest_assigned_part = 0; 2237c478bd9Sstevel@tonic-gate int last_par = 0; 2247c478bd9Sstevel@tonic-gate int compact = 0; 2257c478bd9Sstevel@tonic-gate struct dk_gpt *vtoc; 2267c478bd9Sstevel@tonic-gate struct vtoc old_vtoc_copy; 2277c478bd9Sstevel@tonic-gate diskaddr_t start, size; 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate if (efi_alloc_and_init(fd, EFI_NUMPAR, new_vtoc) != 0) { 2307c478bd9Sstevel@tonic-gate err_print("SMI vtoc to EFI failed\n"); 2317c478bd9Sstevel@tonic-gate return (-1); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate vtoc = *new_vtoc; 2347c478bd9Sstevel@tonic-gate old_vtoc_copy = *old_vtoc; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * Prepare old VTOC table for transfer by ensuring the 2387c478bd9Sstevel@tonic-gate * tags are set correctly. Also collect information 2397c478bd9Sstevel@tonic-gate * about the old VTOC table including the number of 2407c478bd9Sstevel@tonic-gate * valid VTOC partitions and the highest VTOC partition 2417c478bd9Sstevel@tonic-gate * in use. An EFI label provides fewer partitions, so 2427c478bd9Sstevel@tonic-gate * it is possible that the VTOC partitions cannot all be 2437c478bd9Sstevel@tonic-gate * transferred. 2447c478bd9Sstevel@tonic-gate */ 2457c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++) { 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * we may be carrying around old tags from the 2487c478bd9Sstevel@tonic-gate * default partition table. If the partition 2497c478bd9Sstevel@tonic-gate * is really unassigned, set the tag correctly 2507c478bd9Sstevel@tonic-gate */ 2517c478bd9Sstevel@tonic-gate if ((old_vtoc->v_part[i].p_start == 0) && 2527c478bd9Sstevel@tonic-gate (old_vtoc->v_part[i].p_size == 0)) 2537c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_tag = V_UNASSIGNED; 2547c478bd9Sstevel@tonic-gate /* 2557c478bd9Sstevel@tonic-gate * Likewise, if the partition is not empty, don't 2567c478bd9Sstevel@tonic-gate * write it out as "unassigned." 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate if ((old_vtoc->v_part[i].p_size != 0) && 2597c478bd9Sstevel@tonic-gate (old_vtoc->v_part[i].p_tag == V_UNASSIGNED)) 2607c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_tag = V_ROOT; 2617c478bd9Sstevel@tonic-gate if (old_vtoc->v_part[i].p_tag != V_BACKUP && 2627c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_tag != V_UNASSIGNED && 2637c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_start < vtoc->efi_first_u_lba) { 2647c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_start = vtoc->efi_first_u_lba; 2657c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_size -= vtoc->efi_first_u_lba; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if (old_vtoc->v_part[i].p_tag == V_BACKUP || 2697c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_tag == V_BOOT) { 2707c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_tag = V_UNASSIGNED; 2717c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_start = 2727c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_size = 0; 2737c478bd9Sstevel@tonic-gate last_par = i; 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate if ((i == WD_NODE) && (old_vtoc->v_part[i].p_tag != 2767c478bd9Sstevel@tonic-gate V_UNASSIGNED)) { 2777c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_tag = V_UNASSIGNED; 2787c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_start = 0; 2797c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_size = 0; 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate if (old_vtoc->v_part[i].p_tag != V_UNASSIGNED) { 2837c478bd9Sstevel@tonic-gate /* Update count of valid VTOC partitions */ 2847c478bd9Sstevel@tonic-gate vtoc_part_count++; 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* Note the highest valid VTOC slice */ 2877c478bd9Sstevel@tonic-gate highest_assigned_part = i; 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate if (vtoc_part_count > vtoc->efi_nparts - 1) { 2917c478bd9Sstevel@tonic-gate /* Too many partitions to convert the VTOC label */ 2927c478bd9Sstevel@tonic-gate err_print("There are %d defined VTOC ", vtoc_part_count); 2937c478bd9Sstevel@tonic-gate err_print("partitions and an EFI label\n"); 2947c478bd9Sstevel@tonic-gate err_print("can only accept %d.\n", vtoc->efi_nparts - 1); 2957c478bd9Sstevel@tonic-gate if (check("Continue anyway") != 0) { 2967c478bd9Sstevel@tonic-gate /* If no, restore VTOC and return an error */ 2977c478bd9Sstevel@tonic-gate *old_vtoc = old_vtoc_copy; 2987c478bd9Sstevel@tonic-gate efi_free(vtoc); 2997c478bd9Sstevel@tonic-gate return (-1); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate if (highest_assigned_part > vtoc->efi_nparts - 2) { 3047c478bd9Sstevel@tonic-gate /* 3057c478bd9Sstevel@tonic-gate * Partition indexes cannot be transferred directly since 3067c478bd9Sstevel@tonic-gate * the highest valid VTOC index is higher than the highest 3077c478bd9Sstevel@tonic-gate * available EFI partition. Ask the user if it is OK to 3087c478bd9Sstevel@tonic-gate * move the partitions to available slots 3097c478bd9Sstevel@tonic-gate */ 3107c478bd9Sstevel@tonic-gate err_print("VTOC partition %d is defined ", 3117c478bd9Sstevel@tonic-gate highest_assigned_part); 3127c478bd9Sstevel@tonic-gate err_print("and the highest available EFI\n"); 3137c478bd9Sstevel@tonic-gate err_print("partition is %d. The partitions\n", 3147c478bd9Sstevel@tonic-gate vtoc->efi_nparts - 2); 3157c478bd9Sstevel@tonic-gate err_print("will fit if they are re-numbered\n"); 3167c478bd9Sstevel@tonic-gate if (check("OK to renumber") != 0) { 3177c478bd9Sstevel@tonic-gate /* If no, restore VTOC and return an error */ 3187c478bd9Sstevel@tonic-gate *old_vtoc = old_vtoc_copy; 3197c478bd9Sstevel@tonic-gate efi_free(vtoc); 3207c478bd9Sstevel@tonic-gate return (-1); 3217c478bd9Sstevel@tonic-gate } else { 3227c478bd9Sstevel@tonic-gate compact = 1; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * Now copy the VTOC partitions, remapping the indices if 3287c478bd9Sstevel@tonic-gate * necessary. 3297c478bd9Sstevel@tonic-gate */ 3307c478bd9Sstevel@tonic-gate j = 0; 3317c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++) { 3327c478bd9Sstevel@tonic-gate if (old_vtoc->v_part[i].p_tag != V_UNASSIGNED) { 3337c478bd9Sstevel@tonic-gate /* Copy partition info */ 3347c478bd9Sstevel@tonic-gate vtoc->efi_parts[j].p_tag = old_vtoc->v_part[i].p_tag; 3357c478bd9Sstevel@tonic-gate vtoc->efi_parts[j].p_flag = old_vtoc->v_part[i].p_flag; 3367c478bd9Sstevel@tonic-gate vtoc->efi_parts[j].p_start = 3377c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_start; 3387c478bd9Sstevel@tonic-gate vtoc->efi_parts[j].p_size = 3397c478bd9Sstevel@tonic-gate old_vtoc->v_part[i].p_size; 3407c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[j].p_size != 0) 3417c478bd9Sstevel@tonic-gate last_par = j; 3427c478bd9Sstevel@tonic-gate j++; /* Increment EFI index */ 3437c478bd9Sstevel@tonic-gate } else { 3447c478bd9Sstevel@tonic-gate if (!compact) { 3457c478bd9Sstevel@tonic-gate j++; /* Increment EFI index */ 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate start = vtoc->efi_parts[last_par].p_start; 3517c478bd9Sstevel@tonic-gate size = vtoc->efi_parts[last_par].p_size; 3527c478bd9Sstevel@tonic-gate if ((start + size) > (vtoc->efi_last_u_lba - EFI_MIN_RESV_SIZE)) { 3537c478bd9Sstevel@tonic-gate size = (start + size) - (vtoc->efi_last_u_lba - 3547c478bd9Sstevel@tonic-gate EFI_MIN_RESV_SIZE); 3557c478bd9Sstevel@tonic-gate vtoc->efi_parts[last_par].p_size -= size; 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate vtoc->efi_parts[vtoc->efi_nparts - 1].p_tag = V_RESERVED; 3587c478bd9Sstevel@tonic-gate vtoc->efi_parts[vtoc->efi_nparts - 1].p_start = 3597c478bd9Sstevel@tonic-gate vtoc->efi_last_u_lba - EFI_MIN_RESV_SIZE; 3607c478bd9Sstevel@tonic-gate vtoc->efi_parts[vtoc->efi_nparts - 1].p_size = EFI_MIN_RESV_SIZE; 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate return (0); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate /* 3677c478bd9Sstevel@tonic-gate * This routine constructs and writes a label on the disk. It writes both 3687c478bd9Sstevel@tonic-gate * the primary and backup labels. It assumes that there is a current 3697c478bd9Sstevel@tonic-gate * partition map already defined. It also notifies the SunOS kernel of 3707c478bd9Sstevel@tonic-gate * the label and partition information it has written on the disk. 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate int 3737c478bd9Sstevel@tonic-gate write_label() 3747c478bd9Sstevel@tonic-gate { 3757c478bd9Sstevel@tonic-gate int error = 0, head, sec; 3767c478bd9Sstevel@tonic-gate struct dk_label label; 3777c478bd9Sstevel@tonic-gate struct dk_label new_label; 3787c478bd9Sstevel@tonic-gate struct vtoc vtoc; 3797c478bd9Sstevel@tonic-gate struct dk_geom geom; 3807c478bd9Sstevel@tonic-gate struct dk_gpt *vtoc64; 3817c478bd9Sstevel@tonic-gate int nbackups; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 3847c478bd9Sstevel@tonic-gate int i; 3857c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate /* 3887c478bd9Sstevel@tonic-gate * If EFI label, then write it out to disk 3897c478bd9Sstevel@tonic-gate */ 3907c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 3917c478bd9Sstevel@tonic-gate enter_critical(); 3927c478bd9Sstevel@tonic-gate vtoc64 = cur_parts->etoc; 3937c478bd9Sstevel@tonic-gate err_check(vtoc64); 3947c478bd9Sstevel@tonic-gate if (efi_write(cur_file, vtoc64) != 0) { 3957c478bd9Sstevel@tonic-gate err_print("Warning: error writing EFI.\n"); 3967c478bd9Sstevel@tonic-gate error = -1; 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate cur_disk->disk_flags |= DSK_LABEL; 4007c478bd9Sstevel@tonic-gate exit_critical(); 4017c478bd9Sstevel@tonic-gate return (error); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * Fill in a label structure with the geometry information. 4067c478bd9Sstevel@tonic-gate */ 4077c478bd9Sstevel@tonic-gate (void) memset((char *)&label, 0, sizeof (struct dk_label)); 4087c478bd9Sstevel@tonic-gate (void) memset((char *)&new_label, 0, sizeof (struct dk_label)); 4097c478bd9Sstevel@tonic-gate label.dkl_pcyl = pcyl; 4107c478bd9Sstevel@tonic-gate label.dkl_ncyl = ncyl; 4117c478bd9Sstevel@tonic-gate label.dkl_acyl = acyl; 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 4147c478bd9Sstevel@tonic-gate label.dkl_bcyl = bcyl; 4157c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOC_VTOC_16) */ 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate label.dkl_nhead = nhead; 4187c478bd9Sstevel@tonic-gate label.dkl_nsect = nsect; 4197c478bd9Sstevel@tonic-gate label.dkl_apc = apc; 4207c478bd9Sstevel@tonic-gate label.dkl_intrlv = 1; 4217c478bd9Sstevel@tonic-gate label.dkl_rpm = cur_dtype->dtype_rpm; 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 4247c478bd9Sstevel@tonic-gate /* 4257c478bd9Sstevel@tonic-gate * Also fill in the current partition information. 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 4287c478bd9Sstevel@tonic-gate label.dkl_map[i] = cur_parts->pinfo_map[i]; 4297c478bd9Sstevel@tonic-gate } 4307c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate label.dkl_magic = DKL_MAGIC; 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /* 4357c478bd9Sstevel@tonic-gate * Fill in the vtoc information 4367c478bd9Sstevel@tonic-gate */ 4377c478bd9Sstevel@tonic-gate label.dkl_vtoc = cur_parts->vtoc; 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate /* 4407c478bd9Sstevel@tonic-gate * Use the current label 4417c478bd9Sstevel@tonic-gate */ 4427c478bd9Sstevel@tonic-gate bcopy(cur_disk->v_volume, label.dkl_vtoc.v_volume, LEN_DKL_VVOL); 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate /* 4457c478bd9Sstevel@tonic-gate * Put asciilabel in; on x86 it's in the vtoc, not the label. 4467c478bd9Sstevel@tonic-gate */ 4477c478bd9Sstevel@tonic-gate (void) snprintf(label.dkl_asciilabel, sizeof (label.dkl_asciilabel), 4487c478bd9Sstevel@tonic-gate "%s cyl %d alt %d hd %d sec %d", 4497c478bd9Sstevel@tonic-gate cur_dtype->dtype_asciilabel, ncyl, acyl, nhead, nsect); 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 4527c478bd9Sstevel@tonic-gate /* 4537c478bd9Sstevel@tonic-gate * Also add in v_sectorsz, as the driver will. Everyone 4547c478bd9Sstevel@tonic-gate * else is assuming DEV_BSIZE, so we do the same. 4557c478bd9Sstevel@tonic-gate */ 4567c478bd9Sstevel@tonic-gate label.dkl_vtoc.v_sectorsz = DEV_BSIZE; 4577c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate /* 4607c478bd9Sstevel@tonic-gate * Generate the correct checksum. 4617c478bd9Sstevel@tonic-gate */ 4627c478bd9Sstevel@tonic-gate (void) checksum(&label, CK_MAKESUM); 4637c478bd9Sstevel@tonic-gate /* 4647c478bd9Sstevel@tonic-gate * Convert the label into a vtoc 4657c478bd9Sstevel@tonic-gate */ 4667c478bd9Sstevel@tonic-gate if (label_to_vtoc(&vtoc, &label) == -1) { 4677c478bd9Sstevel@tonic-gate return (-1); 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate /* 4707c478bd9Sstevel@tonic-gate * Fill in the geometry info. This is critical that 4717c478bd9Sstevel@tonic-gate * we do this before writing the vtoc. 4727c478bd9Sstevel@tonic-gate */ 4737c478bd9Sstevel@tonic-gate bzero((caddr_t)&geom, sizeof (struct dk_geom)); 4747c478bd9Sstevel@tonic-gate geom.dkg_ncyl = ncyl; 4757c478bd9Sstevel@tonic-gate geom.dkg_acyl = acyl; 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 4787c478bd9Sstevel@tonic-gate geom.dkg_bcyl = bcyl; 4797c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate geom.dkg_nhead = nhead; 4827c478bd9Sstevel@tonic-gate geom.dkg_nsect = nsect; 4837c478bd9Sstevel@tonic-gate geom.dkg_intrlv = 1; 4847c478bd9Sstevel@tonic-gate geom.dkg_apc = apc; 4857c478bd9Sstevel@tonic-gate geom.dkg_rpm = cur_dtype->dtype_rpm; 4867c478bd9Sstevel@tonic-gate geom.dkg_pcyl = pcyl; 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate /* 4897c478bd9Sstevel@tonic-gate * Make a quick check to see that the geometry is being 4907c478bd9Sstevel@tonic-gate * written now is not way off from the actual capacity 4917c478bd9Sstevel@tonic-gate * of the disk. This is only an appoximate check and 4927c478bd9Sstevel@tonic-gate * is only for SCSI disks. 4937c478bd9Sstevel@tonic-gate */ 4947c478bd9Sstevel@tonic-gate if (SCSI && do_geometry_sanity_check() != 0) { 4957c478bd9Sstevel@tonic-gate return (-1); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate /* 4997c478bd9Sstevel@tonic-gate * Lock out interrupts so we do things in sync. 5007c478bd9Sstevel@tonic-gate */ 5017c478bd9Sstevel@tonic-gate enter_critical(); 5027c478bd9Sstevel@tonic-gate /* 5037c478bd9Sstevel@tonic-gate * Do the ioctl to tell the kernel the geometry. 5047c478bd9Sstevel@tonic-gate */ 5057c478bd9Sstevel@tonic-gate if (ioctl(cur_file, DKIOCSGEOM, &geom) == -1) { 5067c478bd9Sstevel@tonic-gate err_print("Warning: error setting drive geometry.\n"); 5077c478bd9Sstevel@tonic-gate error = -1; 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate /* 5107c478bd9Sstevel@tonic-gate * Write the vtoc. At the time of this writing, our 5117c478bd9Sstevel@tonic-gate * drivers convert the vtoc back to a label, and 5127c478bd9Sstevel@tonic-gate * then write both the primary and backup labels. 5137c478bd9Sstevel@tonic-gate * This is not a requirement, however, as we 5147c478bd9Sstevel@tonic-gate * always use an ioctl to read the vtoc from the 5157c478bd9Sstevel@tonic-gate * driver, so it can do as it likes. 5167c478bd9Sstevel@tonic-gate */ 5177c478bd9Sstevel@tonic-gate if (write_vtoc(cur_file, &vtoc) != 0) { 5187c478bd9Sstevel@tonic-gate err_print("Warning: error writing VTOC.\n"); 5197c478bd9Sstevel@tonic-gate error = -1; 5207c478bd9Sstevel@tonic-gate } 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate /* 5237c478bd9Sstevel@tonic-gate * Calculate where the backup labels went. They are always on 5247c478bd9Sstevel@tonic-gate * the last alternate cylinder, but some older drives put them 5257c478bd9Sstevel@tonic-gate * on head 2 instead of the last head. They are always on the 5267c478bd9Sstevel@tonic-gate * first 5 odd sectors of the appropriate track. 5277c478bd9Sstevel@tonic-gate */ 5287c478bd9Sstevel@tonic-gate if (cur_ctype->ctype_flags & CF_BLABEL) 5297c478bd9Sstevel@tonic-gate head = 2; 5307c478bd9Sstevel@tonic-gate else 5317c478bd9Sstevel@tonic-gate head = nhead - 1; 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * Read and verify the backup labels. 5347c478bd9Sstevel@tonic-gate */ 5357c478bd9Sstevel@tonic-gate nbackups = 0; 5367c478bd9Sstevel@tonic-gate for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect)); 5377c478bd9Sstevel@tonic-gate sec += 2) { 5387c478bd9Sstevel@tonic-gate if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, (diskaddr_t) 5397c478bd9Sstevel@tonic-gate ((chs2bn(ncyl + acyl - 1, head, sec)) + solaris_offset), 5407c478bd9Sstevel@tonic-gate 1, (caddr_t)&new_label, F_NORMAL, NULL)) { 5417c478bd9Sstevel@tonic-gate err_print("Warning: error reading backup label.\n"); 5427c478bd9Sstevel@tonic-gate error = -1; 5437c478bd9Sstevel@tonic-gate } else { 5447c478bd9Sstevel@tonic-gate if (bcmp((char *)&label, (char *)&new_label, 5457c478bd9Sstevel@tonic-gate sizeof (struct dk_label)) == 0) { 5467c478bd9Sstevel@tonic-gate nbackups++; 5477c478bd9Sstevel@tonic-gate } 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate if (nbackups != BAD_LISTCNT) { 5517c478bd9Sstevel@tonic-gate err_print("Warning: %s\n", nbackups == 0 ? 5527c478bd9Sstevel@tonic-gate "no backup labels" : 5537c478bd9Sstevel@tonic-gate "some backup labels incorrect"); 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate /* 5567c478bd9Sstevel@tonic-gate * Mark the current disk as labelled and notify the kernel of what 5577c478bd9Sstevel@tonic-gate * has happened. 5587c478bd9Sstevel@tonic-gate */ 5597c478bd9Sstevel@tonic-gate cur_disk->disk_flags |= DSK_LABEL; 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate exit_critical(); 5627c478bd9Sstevel@tonic-gate return (error); 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate /* 5677c478bd9Sstevel@tonic-gate * Read the label from the disk. 5687c478bd9Sstevel@tonic-gate * Do this via the read_vtoc() library routine, then convert it to a label. 5697c478bd9Sstevel@tonic-gate * We also need a DKIOCGGEOM ioctl to get the disk's geometry. 5707c478bd9Sstevel@tonic-gate */ 5717c478bd9Sstevel@tonic-gate int 5727c478bd9Sstevel@tonic-gate read_label(int fd, struct dk_label *label) 5737c478bd9Sstevel@tonic-gate { 5747c478bd9Sstevel@tonic-gate struct vtoc vtoc; 5757c478bd9Sstevel@tonic-gate struct dk_geom geom; 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate if (read_vtoc(fd, &vtoc) < 0 || ioctl(fd, DKIOCGGEOM, &geom) == -1) { 5787c478bd9Sstevel@tonic-gate return (-1); 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate return (vtoc_to_label(label, &vtoc, &geom)); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 583*3ccda647Slclee int 584*3ccda647Slclee get_disk_info_from_devid(int fd, struct efi_info *label) 585*3ccda647Slclee { 586*3ccda647Slclee ddi_devid_t devid; 587*3ccda647Slclee char *s; 588*3ccda647Slclee int n; 589*3ccda647Slclee char *vid, *pid; 590*3ccda647Slclee int nvid, npid; 591*3ccda647Slclee struct dk_minfo minf; 592*3ccda647Slclee struct dk_cinfo dkinfo; 593*3ccda647Slclee 594*3ccda647Slclee 595*3ccda647Slclee if (devid_get(fd, &devid)) { 596*3ccda647Slclee if (option_msg && diag_msg) 597*3ccda647Slclee err_print("devid_get failed\n"); 598*3ccda647Slclee return (-1); 599*3ccda647Slclee } 600*3ccda647Slclee 601*3ccda647Slclee n = devid_sizeof(devid); 602*3ccda647Slclee s = (char *)devid; 603*3ccda647Slclee 604*3ccda647Slclee if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { 605*3ccda647Slclee if (option_msg && diag_msg) 606*3ccda647Slclee err_print("DKIOCINFO failed\n"); 607*3ccda647Slclee return (-1); 608*3ccda647Slclee } 609*3ccda647Slclee 610*3ccda647Slclee if (dkinfo.dki_ctype != DKC_DIRECT) 611*3ccda647Slclee return (-1); 612*3ccda647Slclee 613*3ccda647Slclee vid = s+12; 614*3ccda647Slclee if (!(pid = strchr(vid, '='))) 615*3ccda647Slclee return (-1); 616*3ccda647Slclee nvid = pid - vid; 617*3ccda647Slclee pid += 1; 618*3ccda647Slclee npid = n - nvid - 13; 619*3ccda647Slclee 620*3ccda647Slclee if (nvid > 9) 621*3ccda647Slclee nvid = 9; 622*3ccda647Slclee if (npid > 17) { 623*3ccda647Slclee pid = pid + npid - 17; 624*3ccda647Slclee npid = 17; 625*3ccda647Slclee } 626*3ccda647Slclee 627*3ccda647Slclee if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == -1) { 628*3ccda647Slclee devid_free(devid); 629*3ccda647Slclee return (-1); 630*3ccda647Slclee } 631*3ccda647Slclee 632*3ccda647Slclee (void) strlcpy(label->vendor, vid, nvid); 633*3ccda647Slclee (void) strlcpy(label->product, pid, npid); 634*3ccda647Slclee (void) strlcpy(label->revision, "0001", 5); 635*3ccda647Slclee label->capacity = minf.dki_capacity * minf.dki_lbsize / 512; 636*3ccda647Slclee 637*3ccda647Slclee devid_free(devid); 638*3ccda647Slclee return (0); 639*3ccda647Slclee } 640*3ccda647Slclee 6417c478bd9Sstevel@tonic-gate /* 6427c478bd9Sstevel@tonic-gate * Issue uscsi_inquiry and read_capacity commands to 6437c478bd9Sstevel@tonic-gate * retrieve the disk's Vendor, Product, Revision and 6447c478bd9Sstevel@tonic-gate * Capacity information. 6457c478bd9Sstevel@tonic-gate */ 6467c478bd9Sstevel@tonic-gate int 6477c478bd9Sstevel@tonic-gate get_disk_info(int fd, struct efi_info *label) 6487c478bd9Sstevel@tonic-gate { 6497c478bd9Sstevel@tonic-gate struct scsi_inquiry inquiry; 6507c478bd9Sstevel@tonic-gate struct scsi_capacity_16 capacity; 6517c478bd9Sstevel@tonic-gate 652*3ccda647Slclee if (!get_disk_info_from_devid(fd, label)) 653*3ccda647Slclee return (0); 654*3ccda647Slclee 6557c478bd9Sstevel@tonic-gate if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry))) { 6567c478bd9Sstevel@tonic-gate err_print("Inquiry failed on %d\n", fd); 6577c478bd9Sstevel@tonic-gate return (-1); 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate if (uscsi_read_capacity(fd, &capacity)) { 6607c478bd9Sstevel@tonic-gate err_print("Read Capacity failed for %d\n", fd); 6617c478bd9Sstevel@tonic-gate return (-1); 6627c478bd9Sstevel@tonic-gate } 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate (void) strlcpy(label->vendor, inquiry.inq_vid, 9); 6657c478bd9Sstevel@tonic-gate (void) strlcpy(label->product, inquiry.inq_pid, 17); 6667c478bd9Sstevel@tonic-gate (void) strlcpy(label->revision, inquiry.inq_revision, 5); 6677c478bd9Sstevel@tonic-gate label->capacity = capacity.sc_capacity; 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate /* Since we are counting from zero, add 1 to capacity */ 6707c478bd9Sstevel@tonic-gate label->capacity++; 6717c478bd9Sstevel@tonic-gate return (0); 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate int 6757c478bd9Sstevel@tonic-gate read_efi_label(int fd, struct efi_info *label) 6767c478bd9Sstevel@tonic-gate { 6777c478bd9Sstevel@tonic-gate struct dk_gpt *vtoc64; 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate /* This could fail if there is no label already */ 6807c478bd9Sstevel@tonic-gate if (efi_alloc_and_read(fd, &vtoc64) < 0) { 6817c478bd9Sstevel@tonic-gate return (-1); 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate if (vtoc64_to_label(label, vtoc64) != 0) { 6847c478bd9Sstevel@tonic-gate err_print("vtoc64_to_label failed\n"); 6857c478bd9Sstevel@tonic-gate return (-1); 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate efi_free(vtoc64); 6887c478bd9Sstevel@tonic-gate if (get_disk_info(fd, label) != 0) { 6897c478bd9Sstevel@tonic-gate return (-1); 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate return (0); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate /* 6967c478bd9Sstevel@tonic-gate * We've read a 64-bit label which has no geometry information. Use 6977c478bd9Sstevel@tonic-gate * some heuristics to fake up a geometry that would match the disk in 6987c478bd9Sstevel@tonic-gate * order to make the rest of format(1M) happy. 6997c478bd9Sstevel@tonic-gate */ 7007c478bd9Sstevel@tonic-gate static int 7017c478bd9Sstevel@tonic-gate vtoc64_to_label(struct efi_info *label, struct dk_gpt *vtoc) 7027c478bd9Sstevel@tonic-gate { 7037c478bd9Sstevel@tonic-gate int i, nparts = 0; 7047c478bd9Sstevel@tonic-gate struct dk_gpt *lmap; 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate (void) memset((char *)label, 0, sizeof (struct efi_info)); 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate /* XXX do a sanity check here for nparts */ 7097c478bd9Sstevel@tonic-gate nparts = vtoc->efi_nparts; 7107c478bd9Sstevel@tonic-gate lmap = (struct dk_gpt *) calloc(1, (sizeof (struct dk_part) * 7117c478bd9Sstevel@tonic-gate nparts) + sizeof (struct dk_gpt)); 7127c478bd9Sstevel@tonic-gate if (lmap == NULL) { 7137c478bd9Sstevel@tonic-gate err_print("vtoc64_to_label: unable to allocate lmap\n"); 7147c478bd9Sstevel@tonic-gate fullabort(); 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate label->e_parts = lmap; 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate /* 7197c478bd9Sstevel@tonic-gate * Copy necessary portions 7207c478bd9Sstevel@tonic-gate * XXX Maybe we can use memcpy() ?? 7217c478bd9Sstevel@tonic-gate */ 7227c478bd9Sstevel@tonic-gate lmap->efi_version = vtoc->efi_version; 7237c478bd9Sstevel@tonic-gate lmap->efi_nparts = vtoc->efi_nparts; 7247c478bd9Sstevel@tonic-gate lmap->efi_part_size = vtoc->efi_part_size; 7257c478bd9Sstevel@tonic-gate lmap->efi_lbasize = vtoc->efi_lbasize; 7267c478bd9Sstevel@tonic-gate lmap->efi_last_lba = vtoc->efi_last_lba; 7277c478bd9Sstevel@tonic-gate lmap->efi_first_u_lba = vtoc->efi_first_u_lba; 7287c478bd9Sstevel@tonic-gate lmap->efi_last_u_lba = vtoc->efi_last_u_lba; 7297c478bd9Sstevel@tonic-gate lmap->efi_flags = vtoc->efi_flags; 7307c478bd9Sstevel@tonic-gate (void) memcpy((uchar_t *)&lmap->efi_disk_uguid, 7317c478bd9Sstevel@tonic-gate (uchar_t *)&vtoc->efi_disk_uguid, sizeof (struct uuid)); 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate for (i = 0; i < nparts; i++) { 7347c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_tag = vtoc->efi_parts[i].p_tag; 7357c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_flag = vtoc->efi_parts[i].p_flag; 7367c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_start = vtoc->efi_parts[i].p_start; 7377c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_size = vtoc->efi_parts[i].p_size; 7387c478bd9Sstevel@tonic-gate (void) memcpy((uchar_t *)&lmap->efi_parts[i].p_uguid, 7397c478bd9Sstevel@tonic-gate (uchar_t *)&vtoc->efi_parts[i].p_uguid, 7407c478bd9Sstevel@tonic-gate sizeof (struct uuid)); 7417c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_tag == V_RESERVED) { 7427c478bd9Sstevel@tonic-gate bcopy(vtoc->efi_parts[i].p_name, 7437c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_name, LEN_DKL_VVOL); 7447c478bd9Sstevel@tonic-gate } 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate return (0); 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate /* 7507c478bd9Sstevel@tonic-gate * Convert vtoc/geom to label. 7517c478bd9Sstevel@tonic-gate */ 7527c478bd9Sstevel@tonic-gate static int 7537c478bd9Sstevel@tonic-gate vtoc_to_label(struct dk_label *label, struct vtoc *vtoc, struct dk_geom *geom) 7547c478bd9Sstevel@tonic-gate { 7557c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 7567c478bd9Sstevel@tonic-gate struct dk_map32 *lmap; 7577c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 7587c478bd9Sstevel@tonic-gate struct dkl_partition *lmap; 7597c478bd9Sstevel@tonic-gate #else 7607c478bd9Sstevel@tonic-gate #error No VTOC format defined. 7617c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate struct partition *vpart; 7647c478bd9Sstevel@tonic-gate long nblks; 7657c478bd9Sstevel@tonic-gate int i; 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate (void) memset((char *)label, 0, sizeof (struct dk_label)); 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate /* 7707c478bd9Sstevel@tonic-gate * Sanity-check the vtoc 7717c478bd9Sstevel@tonic-gate */ 7727c478bd9Sstevel@tonic-gate if (vtoc->v_sanity != VTOC_SANE || vtoc->v_sectorsz != DEV_BSIZE || 7737c478bd9Sstevel@tonic-gate vtoc->v_nparts != V_NUMPAR) { 7747c478bd9Sstevel@tonic-gate return (-1); 7757c478bd9Sstevel@tonic-gate } 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate /* 7787c478bd9Sstevel@tonic-gate * Sanity check of geometry 7797c478bd9Sstevel@tonic-gate */ 7807c478bd9Sstevel@tonic-gate if (geom->dkg_ncyl == 0 || geom->dkg_nhead == 0 || 7817c478bd9Sstevel@tonic-gate geom->dkg_nsect == 0) { 7827c478bd9Sstevel@tonic-gate return (-1); 7837c478bd9Sstevel@tonic-gate } 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate label->dkl_magic = DKL_MAGIC; 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate /* 7887c478bd9Sstevel@tonic-gate * Copy necessary portions of the geometry information 7897c478bd9Sstevel@tonic-gate */ 7907c478bd9Sstevel@tonic-gate label->dkl_rpm = geom->dkg_rpm; 7917c478bd9Sstevel@tonic-gate label->dkl_pcyl = geom->dkg_pcyl; 7927c478bd9Sstevel@tonic-gate label->dkl_apc = geom->dkg_apc; 7937c478bd9Sstevel@tonic-gate label->dkl_intrlv = geom->dkg_intrlv; 7947c478bd9Sstevel@tonic-gate label->dkl_ncyl = geom->dkg_ncyl; 7957c478bd9Sstevel@tonic-gate label->dkl_acyl = geom->dkg_acyl; 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 7987c478bd9Sstevel@tonic-gate label->dkl_bcyl = geom->dkg_bcyl; 7997c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate label->dkl_nhead = geom->dkg_nhead; 8027c478bd9Sstevel@tonic-gate label->dkl_nsect = geom->dkg_nsect; 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 8057c478bd9Sstevel@tonic-gate label->dkl_obs1 = geom->dkg_obs1; 8067c478bd9Sstevel@tonic-gate label->dkl_obs2 = geom->dkg_obs2; 8077c478bd9Sstevel@tonic-gate label->dkl_obs3 = geom->dkg_obs3; 8087c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate label->dkl_write_reinstruct = geom->dkg_write_reinstruct; 8117c478bd9Sstevel@tonic-gate label->dkl_read_reinstruct = geom->dkg_read_reinstruct; 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate /* 8147c478bd9Sstevel@tonic-gate * Copy vtoc structure fields into the disk label dk_vtoc 8157c478bd9Sstevel@tonic-gate */ 8167c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_sanity = vtoc->v_sanity; 8177c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_nparts = vtoc->v_nparts; 8187c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_version = vtoc->v_version; 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate (void) memcpy(label->dkl_vtoc.v_volume, vtoc->v_volume, 8217c478bd9Sstevel@tonic-gate LEN_DKL_VVOL); 8227c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++) { 8237c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_tag = vtoc->v_part[i].p_tag; 8247c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_flag = vtoc->v_part[i].p_flag; 8257c478bd9Sstevel@tonic-gate } 8267c478bd9Sstevel@tonic-gate (void) memcpy((char *)label->dkl_vtoc.v_bootinfo, 8277c478bd9Sstevel@tonic-gate (char *)vtoc->v_bootinfo, sizeof (vtoc->v_bootinfo)); 8287c478bd9Sstevel@tonic-gate (void) memcpy((char *)label->dkl_vtoc.v_reserved, 8297c478bd9Sstevel@tonic-gate (char *)vtoc->v_reserved, sizeof (vtoc->v_reserved)); 8307c478bd9Sstevel@tonic-gate (void) memcpy((char *)label->dkl_vtoc.v_timestamp, 8317c478bd9Sstevel@tonic-gate (char *)vtoc->timestamp, sizeof (vtoc->timestamp)); 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate (void) memcpy(label->dkl_asciilabel, vtoc->v_asciilabel, 8347c478bd9Sstevel@tonic-gate LEN_DKL_ASCII); 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate /* 8377c478bd9Sstevel@tonic-gate * Note the conversion from starting sector number 8387c478bd9Sstevel@tonic-gate * to starting cylinder number. 8397c478bd9Sstevel@tonic-gate * Return error if division results in a remainder. 8407c478bd9Sstevel@tonic-gate */ 8417c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 8427c478bd9Sstevel@tonic-gate lmap = label->dkl_map; 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 8457c478bd9Sstevel@tonic-gate lmap = label->dkl_vtoc.v_part; 8467c478bd9Sstevel@tonic-gate #else 8477c478bd9Sstevel@tonic-gate #error No VTOC format defined. 8487c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate vpart = vtoc->v_part; 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate nblks = (int)label->dkl_nsect * (int)label->dkl_nhead; 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++, lmap++, vpart++) { 8557c478bd9Sstevel@tonic-gate if ((vpart->p_start % nblks) != 0 || 8567c478bd9Sstevel@tonic-gate (vpart->p_size % nblks) != 0) { 8577c478bd9Sstevel@tonic-gate return (-1); 8587c478bd9Sstevel@tonic-gate } 8597c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 8607c478bd9Sstevel@tonic-gate lmap->dkl_cylno = vpart->p_start / nblks; 8617c478bd9Sstevel@tonic-gate lmap->dkl_nblk = vpart->p_size; 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 8647c478bd9Sstevel@tonic-gate lmap->p_start = vpart->p_start; 8657c478bd9Sstevel@tonic-gate lmap->p_size = vpart->p_size; 8667c478bd9Sstevel@tonic-gate #else 8677c478bd9Sstevel@tonic-gate #error No VTOC format defined. 8687c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 8697c478bd9Sstevel@tonic-gate } 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate /* 8727c478bd9Sstevel@tonic-gate * Finally, make a checksum 8737c478bd9Sstevel@tonic-gate */ 8747c478bd9Sstevel@tonic-gate (void) checksum(label, CK_MAKESUM); 8757c478bd9Sstevel@tonic-gate 8767c478bd9Sstevel@tonic-gate return (0); 8777c478bd9Sstevel@tonic-gate } 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate 8817c478bd9Sstevel@tonic-gate /* 8827c478bd9Sstevel@tonic-gate * Extract a vtoc structure out of a valid label 8837c478bd9Sstevel@tonic-gate */ 8847c478bd9Sstevel@tonic-gate int 8857c478bd9Sstevel@tonic-gate label_to_vtoc(struct vtoc *vtoc, struct dk_label *label) 8867c478bd9Sstevel@tonic-gate { 8877c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 8887c478bd9Sstevel@tonic-gate struct dk_map2 *lpart; 8897c478bd9Sstevel@tonic-gate struct dk_map32 *lmap; 8907c478bd9Sstevel@tonic-gate long nblks; 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 8937c478bd9Sstevel@tonic-gate struct dkl_partition *lpart; 8947c478bd9Sstevel@tonic-gate #else 8957c478bd9Sstevel@tonic-gate #error No VTOC format defined. 8967c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate struct partition *vpart; 8997c478bd9Sstevel@tonic-gate int i; 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate (void) memset((char *)vtoc, 0, sizeof (struct vtoc)); 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate switch (label->dkl_vtoc.v_version) { 9047c478bd9Sstevel@tonic-gate case 0: 9057c478bd9Sstevel@tonic-gate /* 9067c478bd9Sstevel@tonic-gate * No valid vtoc information in the label. 9077c478bd9Sstevel@tonic-gate * Construct default p_flags and p_tags. 9087c478bd9Sstevel@tonic-gate */ 9097c478bd9Sstevel@tonic-gate vpart = vtoc->v_part; 9107c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++, vpart++) { 9117c478bd9Sstevel@tonic-gate vpart->p_tag = default_vtoc_map[i].p_tag; 9127c478bd9Sstevel@tonic-gate vpart->p_flag = default_vtoc_map[i].p_flag; 9137c478bd9Sstevel@tonic-gate } 9147c478bd9Sstevel@tonic-gate break; 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate case V_VERSION: 9177c478bd9Sstevel@tonic-gate vpart = vtoc->v_part; 9187c478bd9Sstevel@tonic-gate lpart = label->dkl_vtoc.v_part; 9197c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++, vpart++, lpart++) { 9207c478bd9Sstevel@tonic-gate vpart->p_tag = lpart->p_tag; 9217c478bd9Sstevel@tonic-gate vpart->p_flag = lpart->p_flag; 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 9247c478bd9Sstevel@tonic-gate vpart->p_start = lpart->p_start; 9257c478bd9Sstevel@tonic-gate vpart->p_size = lpart->p_size; 9267c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 9277c478bd9Sstevel@tonic-gate } 9287c478bd9Sstevel@tonic-gate (void) memcpy(vtoc->v_volume, label->dkl_vtoc.v_volume, 9297c478bd9Sstevel@tonic-gate LEN_DKL_VVOL); 9307c478bd9Sstevel@tonic-gate (void) memcpy((char *)vtoc->v_bootinfo, 9317c478bd9Sstevel@tonic-gate (char *)label->dkl_vtoc.v_bootinfo, 9327c478bd9Sstevel@tonic-gate sizeof (vtoc->v_bootinfo)); 9337c478bd9Sstevel@tonic-gate (void) memcpy((char *)vtoc->v_reserved, 9347c478bd9Sstevel@tonic-gate (char *)label->dkl_vtoc.v_reserved, 9357c478bd9Sstevel@tonic-gate sizeof (vtoc->v_reserved)); 9367c478bd9Sstevel@tonic-gate (void) memcpy((char *)vtoc->timestamp, 9377c478bd9Sstevel@tonic-gate (char *)label->dkl_vtoc.v_timestamp, 9387c478bd9Sstevel@tonic-gate sizeof (vtoc->timestamp)); 9397c478bd9Sstevel@tonic-gate break; 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate default: 9427c478bd9Sstevel@tonic-gate return (-1); 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate /* 9467c478bd9Sstevel@tonic-gate * XXX - this looks wrong to me.... 9477c478bd9Sstevel@tonic-gate * why are these values hardwired, rather than returned from 9487c478bd9Sstevel@tonic-gate * the real disk label? 9497c478bd9Sstevel@tonic-gate */ 9507c478bd9Sstevel@tonic-gate vtoc->v_sanity = VTOC_SANE; 9517c478bd9Sstevel@tonic-gate vtoc->v_version = V_VERSION; 9527c478bd9Sstevel@tonic-gate vtoc->v_sectorsz = DEV_BSIZE; 9537c478bd9Sstevel@tonic-gate vtoc->v_nparts = V_NUMPAR; 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate (void) memcpy(vtoc->v_asciilabel, label->dkl_asciilabel, 9567c478bd9Sstevel@tonic-gate LEN_DKL_ASCII); 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 9597c478bd9Sstevel@tonic-gate /* 9607c478bd9Sstevel@tonic-gate * Convert partitioning information. 9617c478bd9Sstevel@tonic-gate * Note the conversion from starting cylinder number 9627c478bd9Sstevel@tonic-gate * to starting sector number. 9637c478bd9Sstevel@tonic-gate */ 9647c478bd9Sstevel@tonic-gate lmap = label->dkl_map; 9657c478bd9Sstevel@tonic-gate vpart = vtoc->v_part; 9667c478bd9Sstevel@tonic-gate nblks = label->dkl_nsect * label->dkl_nhead; 9677c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++, vpart++, lmap++) { 9687c478bd9Sstevel@tonic-gate vpart->p_start = lmap->dkl_cylno * nblks; 9697c478bd9Sstevel@tonic-gate vpart->p_size = lmap->dkl_nblk; 9707c478bd9Sstevel@tonic-gate } 9717c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate return (0); 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate /* 9777c478bd9Sstevel@tonic-gate * Input: File descriptor 9787c478bd9Sstevel@tonic-gate * Output: 1 if disk is >1TB OR has an EFI label, 0 otherwise. 9797c478bd9Sstevel@tonic-gate */ 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate int 9827c478bd9Sstevel@tonic-gate is_efi_type(int fd) 9837c478bd9Sstevel@tonic-gate { 9847c478bd9Sstevel@tonic-gate struct vtoc vtoc; 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGVTOC, &vtoc) == -1) { 9877c478bd9Sstevel@tonic-gate if (errno == ENOTSUP) { 9887c478bd9Sstevel@tonic-gate return (1); 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate } 9917c478bd9Sstevel@tonic-gate return (0); 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate /* make sure the user specified something reasonable */ 9957c478bd9Sstevel@tonic-gate void 9967c478bd9Sstevel@tonic-gate err_check(struct dk_gpt *vtoc) 9977c478bd9Sstevel@tonic-gate { 9987c478bd9Sstevel@tonic-gate int resv_part = -1; 9997c478bd9Sstevel@tonic-gate int i, j; 10007c478bd9Sstevel@tonic-gate diskaddr_t istart, jstart, isize, jsize, endsect; 10017c478bd9Sstevel@tonic-gate int overlap = 0; 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate /* 10047c478bd9Sstevel@tonic-gate * make sure no partitions overlap 10057c478bd9Sstevel@tonic-gate */ 10067c478bd9Sstevel@tonic-gate for (i = 0; i < vtoc->efi_nparts; i++) { 10077c478bd9Sstevel@tonic-gate /* It can't be unassigned and have an actual size */ 10087c478bd9Sstevel@tonic-gate if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) && 10097c478bd9Sstevel@tonic-gate (vtoc->efi_parts[i].p_size != 0)) { 10107c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10117c478bd9Sstevel@tonic-gate "partition %d is \"unassigned\" but has a size of %llu\n", i, 10127c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size); 10137c478bd9Sstevel@tonic-gate } 10147c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) { 10157c478bd9Sstevel@tonic-gate continue; 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_tag == V_RESERVED) { 10187c478bd9Sstevel@tonic-gate if (resv_part != -1) { 10197c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10207c478bd9Sstevel@tonic-gate "found duplicate reserved partition at %d\n", 10217c478bd9Sstevel@tonic-gate i); 10227c478bd9Sstevel@tonic-gate } 10237c478bd9Sstevel@tonic-gate resv_part = i; 10247c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_size != EFI_MIN_RESV_SIZE) 10257c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10267c478bd9Sstevel@tonic-gate "Warning: reserved partition size must be %d sectors\n", 10277c478bd9Sstevel@tonic-gate EFI_MIN_RESV_SIZE); 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) || 10307c478bd9Sstevel@tonic-gate (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) { 10317c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10327c478bd9Sstevel@tonic-gate "Partition %d starts at %llu\n", 10337c478bd9Sstevel@tonic-gate i, 10347c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_start); 10357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10367c478bd9Sstevel@tonic-gate "It must be between %llu and %llu.\n", 10377c478bd9Sstevel@tonic-gate vtoc->efi_first_u_lba, 10387c478bd9Sstevel@tonic-gate vtoc->efi_last_u_lba); 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate if ((vtoc->efi_parts[i].p_start + 10417c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size < 10427c478bd9Sstevel@tonic-gate vtoc->efi_first_u_lba) || 10437c478bd9Sstevel@tonic-gate (vtoc->efi_parts[i].p_start + 10447c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size > 10457c478bd9Sstevel@tonic-gate vtoc->efi_last_u_lba + 1)) { 10467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10477c478bd9Sstevel@tonic-gate "Partition %d ends at %llu\n", 10487c478bd9Sstevel@tonic-gate i, 10497c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_start + 10507c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size); 10517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10527c478bd9Sstevel@tonic-gate "It must be between %llu and %llu.\n", 10537c478bd9Sstevel@tonic-gate vtoc->efi_first_u_lba, 10547c478bd9Sstevel@tonic-gate vtoc->efi_last_u_lba); 10557c478bd9Sstevel@tonic-gate } 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate for (j = 0; j < vtoc->efi_nparts; j++) { 10587c478bd9Sstevel@tonic-gate isize = vtoc->efi_parts[i].p_size; 10597c478bd9Sstevel@tonic-gate jsize = vtoc->efi_parts[j].p_size; 10607c478bd9Sstevel@tonic-gate istart = vtoc->efi_parts[i].p_start; 10617c478bd9Sstevel@tonic-gate jstart = vtoc->efi_parts[j].p_start; 10627c478bd9Sstevel@tonic-gate if ((i != j) && (isize != 0) && (jsize != 0)) { 10637c478bd9Sstevel@tonic-gate endsect = jstart + jsize -1; 10647c478bd9Sstevel@tonic-gate if ((jstart <= istart) && 10657c478bd9Sstevel@tonic-gate (istart <= endsect)) { 10667c478bd9Sstevel@tonic-gate if (!overlap) { 10677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10687c478bd9Sstevel@tonic-gate "label error: EFI Labels do not support overlapping partitions\n"); 10697c478bd9Sstevel@tonic-gate } 10707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10717c478bd9Sstevel@tonic-gate "Partition %d overlaps partition %d.\n", i, j); 10727c478bd9Sstevel@tonic-gate overlap = 1; 10737c478bd9Sstevel@tonic-gate } 10747c478bd9Sstevel@tonic-gate } 10757c478bd9Sstevel@tonic-gate } 10767c478bd9Sstevel@tonic-gate } 10777c478bd9Sstevel@tonic-gate /* make sure there is a reserved partition */ 10787c478bd9Sstevel@tonic-gate if (resv_part == -1) { 10797c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10807c478bd9Sstevel@tonic-gate "no reserved partition found\n"); 10817c478bd9Sstevel@tonic-gate } 10827c478bd9Sstevel@tonic-gate } 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate #ifdef FOR_DEBUGGING_ONLY 10857c478bd9Sstevel@tonic-gate int 10867c478bd9Sstevel@tonic-gate dump_label(label) 10877c478bd9Sstevel@tonic-gate struct dk_label *label; 10887c478bd9Sstevel@tonic-gate { 10897c478bd9Sstevel@tonic-gate int i; 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate fmt_print("%s\n", label->dkl_asciilabel); 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate fmt_print("version: %d\n", label->dkl_vtoc.v_version); 10947c478bd9Sstevel@tonic-gate fmt_print("volume: "); 10957c478bd9Sstevel@tonic-gate for (i = 0; i < LEN_DKL_VVOL; i++) { 10967c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_volume[i] == 0) 10977c478bd9Sstevel@tonic-gate break; 10987c478bd9Sstevel@tonic-gate fmt_print("%c", label->dkl_vtoc.v_volume[i]); 10997c478bd9Sstevel@tonic-gate } 11007c478bd9Sstevel@tonic-gate fmt_print("\n"); 11017c478bd9Sstevel@tonic-gate fmt_print("v_nparts: %d\n", label->dkl_vtoc.v_nparts); 11027c478bd9Sstevel@tonic-gate fmt_print("v_sanity: %lx\n", label->dkl_vtoc.v_sanity); 11037c478bd9Sstevel@tonic-gate 11047c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 11057c478bd9Sstevel@tonic-gate fmt_print("rpm: %d\n", label->dkl_rpm); 11067c478bd9Sstevel@tonic-gate fmt_print("pcyl: %d\n", label->dkl_pcyl); 11077c478bd9Sstevel@tonic-gate fmt_print("apc: %d\n", label->dkl_apc); 11087c478bd9Sstevel@tonic-gate fmt_print("obs1: %d\n", label->dkl_obs1); 11097c478bd9Sstevel@tonic-gate fmt_print("obs2: %d\n", label->dkl_obs2); 11107c478bd9Sstevel@tonic-gate fmt_print("intrlv: %d\n", label->dkl_intrlv); 11117c478bd9Sstevel@tonic-gate fmt_print("ncyl: %d\n", label->dkl_ncyl); 11127c478bd9Sstevel@tonic-gate fmt_print("acyl: %d\n", label->dkl_acyl); 11137c478bd9Sstevel@tonic-gate fmt_print("nhead: %d\n", label->dkl_nhead); 11147c478bd9Sstevel@tonic-gate fmt_print("nsect: %d\n", label->dkl_nsect); 11157c478bd9Sstevel@tonic-gate fmt_print("obs3: %d\n", label->dkl_obs3); 11167c478bd9Sstevel@tonic-gate fmt_print("obs4: %d\n", label->dkl_obs4); 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 11197c478bd9Sstevel@tonic-gate fmt_print("rpm: %d\n", label->dkl_rpm); 11207c478bd9Sstevel@tonic-gate fmt_print("pcyl: %d\n", label->dkl_pcyl); 11217c478bd9Sstevel@tonic-gate fmt_print("apc: %d\n", label->dkl_apc); 11227c478bd9Sstevel@tonic-gate fmt_print("intrlv: %d\n", label->dkl_intrlv); 11237c478bd9Sstevel@tonic-gate fmt_print("ncyl: %d\n", label->dkl_ncyl); 11247c478bd9Sstevel@tonic-gate fmt_print("acyl: %d\n", label->dkl_acyl); 11257c478bd9Sstevel@tonic-gate fmt_print("nhead: %d\n", label->dkl_nhead); 11267c478bd9Sstevel@tonic-gate fmt_print("nsect: %d\n", label->dkl_nsect); 11277c478bd9Sstevel@tonic-gate fmt_print("bcyl: %d\n", label->dkl_bcyl); 11287c478bd9Sstevel@tonic-gate fmt_print("skew: %d\n", label->dkl_skew); 11297c478bd9Sstevel@tonic-gate #else 11307c478bd9Sstevel@tonic-gate #error No VTOC format defined. 11317c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 11327c478bd9Sstevel@tonic-gate fmt_print("magic: %0x\n", label->dkl_magic); 11337c478bd9Sstevel@tonic-gate fmt_print("cksum: %0x\n", label->dkl_cksum); 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 11387c478bd9Sstevel@tonic-gate fmt_print("%c: cyl=%d, blocks=%d", i+'a', 11397c478bd9Sstevel@tonic-gate label->dkl_map[i].dkl_cylno, 11407c478bd9Sstevel@tonic-gate label->dkl_map[i].dkl_nblk); 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 11437c478bd9Sstevel@tonic-gate fmt_print("%c: start=%d, blocks=%d", i+'a', 11447c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_start, 11457c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_size); 11467c478bd9Sstevel@tonic-gate #else 11477c478bd9Sstevel@tonic-gate #error No VTOC format defined. 11487c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate fmt_print(", tag=%d, flag=%d", 11517c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_tag, 11527c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_flag); 11537c478bd9Sstevel@tonic-gate fmt_print("\n"); 11547c478bd9Sstevel@tonic-gate } 11557c478bd9Sstevel@tonic-gate 11567c478bd9Sstevel@tonic-gate fmt_print("read_reinstruct: %d\n", label->dkl_read_reinstruct); 11577c478bd9Sstevel@tonic-gate fmt_print("write_reinstruct: %d\n", label->dkl_write_reinstruct); 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate fmt_print("bootinfo: "); 11607c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 11617c478bd9Sstevel@tonic-gate fmt_print("0x%x ", label->dkl_vtoc.v_bootinfo[i]); 11627c478bd9Sstevel@tonic-gate } 11637c478bd9Sstevel@tonic-gate fmt_print("\n"); 11647c478bd9Sstevel@tonic-gate 11657c478bd9Sstevel@tonic-gate fmt_print("reserved: "); 11667c478bd9Sstevel@tonic-gate for (i = 0; i < 10; i++) { 11677c478bd9Sstevel@tonic-gate if ((i % 4) == 3) 11687c478bd9Sstevel@tonic-gate fmt_print("\n"); 11697c478bd9Sstevel@tonic-gate fmt_print("0x%x ", label->dkl_vtoc.v_reserved[i]); 11707c478bd9Sstevel@tonic-gate } 11717c478bd9Sstevel@tonic-gate fmt_print("\n"); 11727c478bd9Sstevel@tonic-gate 11737c478bd9Sstevel@tonic-gate fmt_print("timestamp:\n"); 11747c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 11757c478bd9Sstevel@tonic-gate if ((i % 4) == 3) 11767c478bd9Sstevel@tonic-gate fmt_print("\n"); 11777c478bd9Sstevel@tonic-gate fmt_print("0x%x ", label->dkl_vtoc.v_timestamp[i]); 11787c478bd9Sstevel@tonic-gate } 11797c478bd9Sstevel@tonic-gate fmt_print("\n"); 11807c478bd9Sstevel@tonic-gate 11817c478bd9Sstevel@tonic-gate fmt_print("pad:\n"); 11827c478bd9Sstevel@tonic-gate dump("", label->dkl_pad, LEN_DKL_PAD, HEX_ONLY); 11837c478bd9Sstevel@tonic-gate 11847c478bd9Sstevel@tonic-gate fmt_print("\n\n"); 11857c478bd9Sstevel@tonic-gate } 11867c478bd9Sstevel@tonic-gate #endif /* FOR_DEBUGGING_ONLY */ 1187