1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * This file contains functions that operate on partition tables. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate #include "global.h" 33*7c478bd9Sstevel@tonic-gate #include "partition.h" 34*7c478bd9Sstevel@tonic-gate #include "misc.h" 35*7c478bd9Sstevel@tonic-gate #include "menu_command.h" 36*7c478bd9Sstevel@tonic-gate #include "menu_partition.h" 37*7c478bd9Sstevel@tonic-gate #include <string.h> 38*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* 42*7c478bd9Sstevel@tonic-gate * Default vtoc information for non-SVr4 partitions 43*7c478bd9Sstevel@tonic-gate */ 44*7c478bd9Sstevel@tonic-gate struct dk_map2 default_vtoc_map[NDKMAP] = { 45*7c478bd9Sstevel@tonic-gate { V_ROOT, 0 }, /* a - 0 */ 46*7c478bd9Sstevel@tonic-gate { V_SWAP, V_UNMNT }, /* b - 1 */ 47*7c478bd9Sstevel@tonic-gate { V_BACKUP, V_UNMNT }, /* c - 2 */ 48*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* d - 3 */ 49*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* e - 4 */ 50*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* f - 5 */ 51*7c478bd9Sstevel@tonic-gate { V_USR, 0 }, /* g - 6 */ 52*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* h - 7 */ 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #if defined(i386) 57*7c478bd9Sstevel@tonic-gate { V_BOOT, V_UNMNT }, /* i - 8 */ 58*7c478bd9Sstevel@tonic-gate { V_ALTSCTR, 0 }, /* j - 9 */ 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #else 61*7c478bd9Sstevel@tonic-gate #error No VTOC format defined. 62*7c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* k - 10 */ 65*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* l - 11 */ 66*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* m - 12 */ 67*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* n - 13 */ 68*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* o - 14 */ 69*7c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* p - 15 */ 70*7c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 71*7c478bd9Sstevel@tonic-gate }; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * This routine finds the last usable sector in the partition table. 75*7c478bd9Sstevel@tonic-gate * It skips the BACKUP partition. 76*7c478bd9Sstevel@tonic-gate */ 77*7c478bd9Sstevel@tonic-gate static uint64_t 78*7c478bd9Sstevel@tonic-gate maxofN(struct dk_gpt *map) 79*7c478bd9Sstevel@tonic-gate { 80*7c478bd9Sstevel@tonic-gate uint64_t max; 81*7c478bd9Sstevel@tonic-gate uint64_t sec_no[2], start[2], size[2]; 82*7c478bd9Sstevel@tonic-gate int i; 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate for (i = 0; i < map->efi_nparts - 1; i++) { 85*7c478bd9Sstevel@tonic-gate start[0] = map->efi_parts[i].p_start; 86*7c478bd9Sstevel@tonic-gate size[0] = map->efi_parts[i].p_size; 87*7c478bd9Sstevel@tonic-gate sec_no[0] = start[0] + size[0]; 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate start[1] = map->efi_parts[i+1].p_start; 90*7c478bd9Sstevel@tonic-gate size[1] = map->efi_parts[i+1].p_size; 91*7c478bd9Sstevel@tonic-gate sec_no[1] = start[1] + size[1]; 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate if (map->efi_parts[i].p_tag == V_BACKUP) { 94*7c478bd9Sstevel@tonic-gate sec_no[0] = 0; 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate if (map->efi_parts[i+1].p_tag == V_BACKUP) { 97*7c478bd9Sstevel@tonic-gate sec_no[1] = 0; 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate if (i == 0) { 100*7c478bd9Sstevel@tonic-gate max = sec_no[1]; 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate if (sec_no[0] > max) { 103*7c478bd9Sstevel@tonic-gate max = sec_no[0]; 104*7c478bd9Sstevel@tonic-gate } else { 105*7c478bd9Sstevel@tonic-gate max = max; 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate } 108*7c478bd9Sstevel@tonic-gate if (max == 0) 109*7c478bd9Sstevel@tonic-gate max = 34; 110*7c478bd9Sstevel@tonic-gate return (max); 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate /* 114*7c478bd9Sstevel@tonic-gate * This routine allows the user to change the boundaries of the given 115*7c478bd9Sstevel@tonic-gate * partition in the current partition map. 116*7c478bd9Sstevel@tonic-gate */ 117*7c478bd9Sstevel@tonic-gate void 118*7c478bd9Sstevel@tonic-gate change_partition(int num) 119*7c478bd9Sstevel@tonic-gate { 120*7c478bd9Sstevel@tonic-gate int i; 121*7c478bd9Sstevel@tonic-gate uint64_t i64, j64; 122*7c478bd9Sstevel@tonic-gate int j; 123*7c478bd9Sstevel@tonic-gate int deflt; 124*7c478bd9Sstevel@tonic-gate part_deflt_t p_deflt; 125*7c478bd9Sstevel@tonic-gate u_ioparam_t ioparam; 126*7c478bd9Sstevel@tonic-gate int tag; 127*7c478bd9Sstevel@tonic-gate int flag; 128*7c478bd9Sstevel@tonic-gate char msg[256]; 129*7c478bd9Sstevel@tonic-gate long cyl_offset = 0; 130*7c478bd9Sstevel@tonic-gate efi_deflt_t efi_deflt; 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate /* 133*7c478bd9Sstevel@tonic-gate * check if there exists a partition table for the disk. 134*7c478bd9Sstevel@tonic-gate */ 135*7c478bd9Sstevel@tonic-gate if (cur_parts == NULL) { 136*7c478bd9Sstevel@tonic-gate err_print("Current Disk has no partition table.\n"); 137*7c478bd9Sstevel@tonic-gate return; 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 141*7c478bd9Sstevel@tonic-gate if (num > cur_parts->etoc->efi_nparts - 1) { 142*7c478bd9Sstevel@tonic-gate err_print("Invalid partition for EFI label\n"); 143*7c478bd9Sstevel@tonic-gate return; 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate print_efi_partition(cur_parts->etoc, num, 1); 146*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 147*7c478bd9Sstevel@tonic-gate /* 148*7c478bd9Sstevel@tonic-gate * Prompt for p_tag and p_flag values for this partition 149*7c478bd9Sstevel@tonic-gate */ 150*7c478bd9Sstevel@tonic-gate deflt = cur_parts->etoc->efi_parts[num].p_tag; 151*7c478bd9Sstevel@tonic-gate if (deflt == V_UNASSIGNED) { 152*7c478bd9Sstevel@tonic-gate deflt = V_USR; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition id tag"); 155*7c478bd9Sstevel@tonic-gate ioparam.io_slist = ptag_choices; 156*7c478bd9Sstevel@tonic-gate tag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate deflt = cur_parts->etoc->efi_parts[num].p_flag; 159*7c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition permission flags"); 160*7c478bd9Sstevel@tonic-gate ioparam.io_slist = pflag_choices; 161*7c478bd9Sstevel@tonic-gate flag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 34; 164*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = cur_parts->etoc->efi_last_u_lba; 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate efi_deflt.start_sector = maxofN(cur_parts->etoc); 167*7c478bd9Sstevel@tonic-gate if ((cur_parts->etoc->efi_parts[num].p_start != 0) && 168*7c478bd9Sstevel@tonic-gate (cur_parts->etoc->efi_parts[num].p_size != 0)) { 169*7c478bd9Sstevel@tonic-gate efi_deflt.start_sector = 170*7c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_start; 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate efi_deflt.end_sector = ioparam.io_bounds.upper - 173*7c478bd9Sstevel@tonic-gate efi_deflt.start_sector; 174*7c478bd9Sstevel@tonic-gate i64 = input(FIO_INT64, "Enter new starting Sector", ':', &ioparam, 175*7c478bd9Sstevel@tonic-gate (int *)&efi_deflt, DATA_INPUT); 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 178*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = cur_parts->etoc->efi_last_u_lba; 179*7c478bd9Sstevel@tonic-gate efi_deflt.end_sector = cur_parts->etoc->efi_parts[num].p_size; 180*7c478bd9Sstevel@tonic-gate efi_deflt.start_sector = i64; 181*7c478bd9Sstevel@tonic-gate j64 = input(FIO_EFI, "Enter partition size", ':', &ioparam, 182*7c478bd9Sstevel@tonic-gate (int *)&efi_deflt, DATA_INPUT); 183*7c478bd9Sstevel@tonic-gate if (j64 == 0) { 184*7c478bd9Sstevel@tonic-gate tag = V_UNASSIGNED; 185*7c478bd9Sstevel@tonic-gate i64 = 0; 186*7c478bd9Sstevel@tonic-gate } else if ((j64 != 0) && (tag == V_UNASSIGNED)) { 187*7c478bd9Sstevel@tonic-gate tag = V_USR; 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate if (cur_parts->pinfo_name != NULL) 191*7c478bd9Sstevel@tonic-gate make_partition(); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_tag = tag; 194*7c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_flag = flag; 195*7c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_start = i64; 196*7c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_size = j64; 197*7c478bd9Sstevel@tonic-gate /* 198*7c478bd9Sstevel@tonic-gate * We are now done with EFI part, so return now 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate return; 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate /* 203*7c478bd9Sstevel@tonic-gate * Print out the given partition so the user knows what he/she's 204*7c478bd9Sstevel@tonic-gate * getting into. 205*7c478bd9Sstevel@tonic-gate */ 206*7c478bd9Sstevel@tonic-gate print_partition(cur_parts, num, 1); 207*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate /* 210*7c478bd9Sstevel@tonic-gate * Prompt for p_tag and p_flag values for this partition. 211*7c478bd9Sstevel@tonic-gate */ 212*7c478bd9Sstevel@tonic-gate assert(cur_parts->vtoc.v_version == V_VERSION); 213*7c478bd9Sstevel@tonic-gate deflt = cur_parts->vtoc.v_part[num].p_tag; 214*7c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition id tag"); 215*7c478bd9Sstevel@tonic-gate ioparam.io_slist = ptag_choices; 216*7c478bd9Sstevel@tonic-gate tag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate deflt = cur_parts->vtoc.v_part[num].p_flag; 219*7c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition permission flags"); 220*7c478bd9Sstevel@tonic-gate ioparam.io_slist = pflag_choices; 221*7c478bd9Sstevel@tonic-gate flag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* 224*7c478bd9Sstevel@tonic-gate * Ask for the new values. The old values are the defaults, and 225*7c478bd9Sstevel@tonic-gate * strict bounds checking is done on the values given. 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate #if defined(i386) 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate if (tag != V_UNASSIGNED && tag != V_BACKUP && tag != V_BOOT) { 231*7c478bd9Sstevel@tonic-gate /* 232*7c478bd9Sstevel@tonic-gate * Determine cyl offset for boot and alternate partitions. 233*7c478bd9Sstevel@tonic-gate * Assuming that the alternate sectors partition (slice) 234*7c478bd9Sstevel@tonic-gate * physical location immediately follows the boot 235*7c478bd9Sstevel@tonic-gate * partition and partition sizes are expressed in multiples 236*7c478bd9Sstevel@tonic-gate * of cylinder size. 237*7c478bd9Sstevel@tonic-gate */ 238*7c478bd9Sstevel@tonic-gate cyl_offset = cur_parts->pinfo_map[I_PARTITION].dkl_cylno + 1; 239*7c478bd9Sstevel@tonic-gate if (tag != V_ALTSCTR) { 240*7c478bd9Sstevel@tonic-gate if (cur_parts->pinfo_map[J_PARTITION].dkl_nblk != 0) { 241*7c478bd9Sstevel@tonic-gate cyl_offset = 242*7c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[J_PARTITION].dkl_cylno + 243*7c478bd9Sstevel@tonic-gate ((cur_parts->pinfo_map[J_PARTITION].dkl_nblk + 244*7c478bd9Sstevel@tonic-gate (spc()-1)) / spc()); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 251*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = ncyl - 1; 252*7c478bd9Sstevel@tonic-gate deflt = max(cur_parts->pinfo_map[num].dkl_cylno, 253*7c478bd9Sstevel@tonic-gate cyl_offset); 254*7c478bd9Sstevel@tonic-gate i = input(FIO_INT, "Enter new starting cyl", ':', &ioparam, 255*7c478bd9Sstevel@tonic-gate &deflt, DATA_INPUT); 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 258*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = (ncyl - i) * spc(); 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate /* fill in defaults for the current partition */ 261*7c478bd9Sstevel@tonic-gate p_deflt.start_cyl = i; 262*7c478bd9Sstevel@tonic-gate p_deflt.deflt_size = 263*7c478bd9Sstevel@tonic-gate min(cur_parts->pinfo_map[num].dkl_nblk, 264*7c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper); 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate /* call input, passing p_deflt's address, typecast to (int *) */ 267*7c478bd9Sstevel@tonic-gate j = input(FIO_ECYL, "Enter partition size", ':', &ioparam, 268*7c478bd9Sstevel@tonic-gate (int *)&p_deflt, DATA_INPUT); 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate /* 271*7c478bd9Sstevel@tonic-gate * If the current partition has a size of zero change the 272*7c478bd9Sstevel@tonic-gate * tag to Unassigned and the starting cylinder to zero 273*7c478bd9Sstevel@tonic-gate */ 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate if (j == 0) { 276*7c478bd9Sstevel@tonic-gate tag = V_UNASSIGNED; 277*7c478bd9Sstevel@tonic-gate i = 0; 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate #if defined(i386) 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate if (i < cyl_offset && tag != V_UNASSIGNED && tag != V_BACKUP && 284*7c478bd9Sstevel@tonic-gate tag != V_BOOT) { 285*7c478bd9Sstevel@tonic-gate /* 286*7c478bd9Sstevel@tonic-gate * This slice overlaps boot and/or alternates slice 287*7c478bd9Sstevel@tonic-gate * Check if it's the boot or alternates slice and warn 288*7c478bd9Sstevel@tonic-gate * accordingly 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate if (i < cur_parts->pinfo_map[I_PARTITION].dkl_cylno + 1) { 291*7c478bd9Sstevel@tonic-gate fmt_print("\nWarning: Partition overlaps boot "); 292*7c478bd9Sstevel@tonic-gate fmt_print("partition. Specify different start cyl.\n"); 293*7c478bd9Sstevel@tonic-gate return; 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate /* 296*7c478bd9Sstevel@tonic-gate * Cyl offset for alternates partition was calculated before 297*7c478bd9Sstevel@tonic-gate */ 298*7c478bd9Sstevel@tonic-gate if (i < cyl_offset) { 299*7c478bd9Sstevel@tonic-gate fmt_print("\nWarning: Partition overlaps alternates "); 300*7c478bd9Sstevel@tonic-gate fmt_print("partition. Specify different start cyl.\n"); 301*7c478bd9Sstevel@tonic-gate return; 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* 308*7c478bd9Sstevel@tonic-gate * If user has entered a V_BACKUP tag then the partition 309*7c478bd9Sstevel@tonic-gate * size should specify full disk capacity else 310*7c478bd9Sstevel@tonic-gate * return an Error. 311*7c478bd9Sstevel@tonic-gate */ 312*7c478bd9Sstevel@tonic-gate if (tag == V_BACKUP) { 313*7c478bd9Sstevel@tonic-gate int fullsz; 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate fullsz = ncyl * nhead * nsect; 316*7c478bd9Sstevel@tonic-gate if (fullsz != j) { 317*7c478bd9Sstevel@tonic-gate /* 318*7c478bd9Sstevel@tonic-gate * V_BACKUP Tag Partition != full disk capacity. 319*7c478bd9Sstevel@tonic-gate * print useful messages. 320*7c478bd9Sstevel@tonic-gate */ 321*7c478bd9Sstevel@tonic-gate fmt_print("\nWarning: Partition with V_BACKUP tag should "); 322*7c478bd9Sstevel@tonic-gate fmt_print("specify full disk capacity. \n"); 323*7c478bd9Sstevel@tonic-gate return; 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate /* 329*7c478bd9Sstevel@tonic-gate * If the current partition is named, we can't change it. 330*7c478bd9Sstevel@tonic-gate * We create a new current partition map instead. 331*7c478bd9Sstevel@tonic-gate */ 332*7c478bd9Sstevel@tonic-gate if (cur_parts->pinfo_name != NULL) 333*7c478bd9Sstevel@tonic-gate make_partition(); 334*7c478bd9Sstevel@tonic-gate /* 335*7c478bd9Sstevel@tonic-gate * Change the values. 336*7c478bd9Sstevel@tonic-gate */ 337*7c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[num].dkl_cylno = i; 338*7c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[num].dkl_nblk = j; 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 341*7c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_start = (daddr_t)(i * (nhead * nsect)); 342*7c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_size = (long)j; 343*7c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate /* 346*7c478bd9Sstevel@tonic-gate * Install the p_tag and p_flag values for this partition 347*7c478bd9Sstevel@tonic-gate */ 348*7c478bd9Sstevel@tonic-gate assert(cur_parts->vtoc.v_version == V_VERSION); 349*7c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_tag = (ushort_t)tag; 350*7c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_flag = (ushort_t)flag; 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate /* 355*7c478bd9Sstevel@tonic-gate * This routine picks to closest partition table which matches the 356*7c478bd9Sstevel@tonic-gate * selected disk type. It is called each time the disk type is 357*7c478bd9Sstevel@tonic-gate * changed. If no match is found, it uses the first element 358*7c478bd9Sstevel@tonic-gate * of the partition table. If no table exists, a dummy is 359*7c478bd9Sstevel@tonic-gate * created. 360*7c478bd9Sstevel@tonic-gate */ 361*7c478bd9Sstevel@tonic-gate int 362*7c478bd9Sstevel@tonic-gate get_partition() 363*7c478bd9Sstevel@tonic-gate { 364*7c478bd9Sstevel@tonic-gate register struct partition_info *pptr; 365*7c478bd9Sstevel@tonic-gate register struct partition_info *parts; 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate /* 368*7c478bd9Sstevel@tonic-gate * If there are no pre-defined maps for this disk type, it's 369*7c478bd9Sstevel@tonic-gate * an error. 370*7c478bd9Sstevel@tonic-gate */ 371*7c478bd9Sstevel@tonic-gate parts = cur_dtype->dtype_plist; 372*7c478bd9Sstevel@tonic-gate if (parts == NULL) { 373*7c478bd9Sstevel@tonic-gate err_print("No defined partition tables.\n"); 374*7c478bd9Sstevel@tonic-gate make_partition(); 375*7c478bd9Sstevel@tonic-gate return (-1); 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate /* 378*7c478bd9Sstevel@tonic-gate * Loop through the pre-defined maps searching for one which match 379*7c478bd9Sstevel@tonic-gate * disk type. If found copy it into unmamed partition. 380*7c478bd9Sstevel@tonic-gate */ 381*7c478bd9Sstevel@tonic-gate enter_critical(); 382*7c478bd9Sstevel@tonic-gate for (pptr = parts; pptr != NULL; pptr = pptr->pinfo_next) { 383*7c478bd9Sstevel@tonic-gate if (cur_dtype->dtype_asciilabel) { 384*7c478bd9Sstevel@tonic-gate if (pptr->pinfo_name != NULL && strcmp(pptr->pinfo_name, 385*7c478bd9Sstevel@tonic-gate cur_dtype->dtype_asciilabel) == 0) { 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * Set current partition and name it. 388*7c478bd9Sstevel@tonic-gate */ 389*7c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = pptr; 390*7c478bd9Sstevel@tonic-gate cur_parts->pinfo_name = pptr->pinfo_name; 391*7c478bd9Sstevel@tonic-gate exit_critical(); 392*7c478bd9Sstevel@tonic-gate return (0); 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate } 396*7c478bd9Sstevel@tonic-gate /* 397*7c478bd9Sstevel@tonic-gate * If we couldn't find a match, take the first one. 398*7c478bd9Sstevel@tonic-gate * Set current partition and name it. 399*7c478bd9Sstevel@tonic-gate */ 400*7c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = cur_dtype->dtype_plist; 401*7c478bd9Sstevel@tonic-gate cur_parts->pinfo_name = parts->pinfo_name; 402*7c478bd9Sstevel@tonic-gate exit_critical(); 403*7c478bd9Sstevel@tonic-gate return (0); 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate /* 408*7c478bd9Sstevel@tonic-gate * This routine creates a new partition map and sets it current. If there 409*7c478bd9Sstevel@tonic-gate * was a current map, the new map starts out identical to it. Otherwise 410*7c478bd9Sstevel@tonic-gate * the new map starts out all zeroes. 411*7c478bd9Sstevel@tonic-gate */ 412*7c478bd9Sstevel@tonic-gate void 413*7c478bd9Sstevel@tonic-gate make_partition() 414*7c478bd9Sstevel@tonic-gate { 415*7c478bd9Sstevel@tonic-gate register struct partition_info *pptr, *parts; 416*7c478bd9Sstevel@tonic-gate int i; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate /* 419*7c478bd9Sstevel@tonic-gate * Lock out interrupts so the lists don't get mangled. 420*7c478bd9Sstevel@tonic-gate */ 421*7c478bd9Sstevel@tonic-gate enter_critical(); 422*7c478bd9Sstevel@tonic-gate /* 423*7c478bd9Sstevel@tonic-gate * Get space for for the new map and link it into the list 424*7c478bd9Sstevel@tonic-gate * of maps for the current disk type. 425*7c478bd9Sstevel@tonic-gate */ 426*7c478bd9Sstevel@tonic-gate pptr = (struct partition_info *)zalloc(sizeof (struct partition_info)); 427*7c478bd9Sstevel@tonic-gate parts = cur_dtype->dtype_plist; 428*7c478bd9Sstevel@tonic-gate if (parts == NULL) { 429*7c478bd9Sstevel@tonic-gate cur_dtype->dtype_plist = pptr; 430*7c478bd9Sstevel@tonic-gate } else { 431*7c478bd9Sstevel@tonic-gate while (parts->pinfo_next != NULL) { 432*7c478bd9Sstevel@tonic-gate parts = parts->pinfo_next; 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate parts->pinfo_next = pptr; 435*7c478bd9Sstevel@tonic-gate pptr->pinfo_next = NULL; 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate /* 438*7c478bd9Sstevel@tonic-gate * If there was a current map, copy its values. 439*7c478bd9Sstevel@tonic-gate */ 440*7c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 441*7c478bd9Sstevel@tonic-gate struct dk_gpt *map; 442*7c478bd9Sstevel@tonic-gate int nparts; 443*7c478bd9Sstevel@tonic-gate int size; 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate nparts = cur_parts->etoc->efi_nparts; 446*7c478bd9Sstevel@tonic-gate size = sizeof (struct dk_part) * nparts + sizeof (struct dk_gpt); 447*7c478bd9Sstevel@tonic-gate map = zalloc(size); 448*7c478bd9Sstevel@tonic-gate (void) memcpy(map, cur_parts->etoc, size); 449*7c478bd9Sstevel@tonic-gate pptr->etoc = map; 450*7c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = pptr; 451*7c478bd9Sstevel@tonic-gate exit_critical(); 452*7c478bd9Sstevel@tonic-gate return; 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate if (cur_parts != NULL) { 455*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 456*7c478bd9Sstevel@tonic-gate pptr->pinfo_map[i] = cur_parts->pinfo_map[i]; 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate pptr->vtoc = cur_parts->vtoc; 459*7c478bd9Sstevel@tonic-gate } else { 460*7c478bd9Sstevel@tonic-gate /* 461*7c478bd9Sstevel@tonic-gate * Otherwise set initial default vtoc values 462*7c478bd9Sstevel@tonic-gate */ 463*7c478bd9Sstevel@tonic-gate set_vtoc_defaults(pptr); 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate /* 467*7c478bd9Sstevel@tonic-gate * Make the new one current. 468*7c478bd9Sstevel@tonic-gate */ 469*7c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = pptr; 470*7c478bd9Sstevel@tonic-gate exit_critical(); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate /* 475*7c478bd9Sstevel@tonic-gate * This routine deletes a partition map from the list of maps for 476*7c478bd9Sstevel@tonic-gate * the given disk type. 477*7c478bd9Sstevel@tonic-gate */ 478*7c478bd9Sstevel@tonic-gate void 479*7c478bd9Sstevel@tonic-gate delete_partition(struct partition_info *parts) 480*7c478bd9Sstevel@tonic-gate { 481*7c478bd9Sstevel@tonic-gate struct partition_info *pptr; 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate /* 484*7c478bd9Sstevel@tonic-gate * If there isn't a current map, it's an error. 485*7c478bd9Sstevel@tonic-gate */ 486*7c478bd9Sstevel@tonic-gate if (cur_dtype->dtype_plist == NULL) { 487*7c478bd9Sstevel@tonic-gate err_print("Error: unexpected null partition list.\n"); 488*7c478bd9Sstevel@tonic-gate fullabort(); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate /* 491*7c478bd9Sstevel@tonic-gate * Remove the map from the list. 492*7c478bd9Sstevel@tonic-gate */ 493*7c478bd9Sstevel@tonic-gate if (cur_dtype->dtype_plist == parts) 494*7c478bd9Sstevel@tonic-gate cur_dtype->dtype_plist = parts->pinfo_next; 495*7c478bd9Sstevel@tonic-gate else { 496*7c478bd9Sstevel@tonic-gate for (pptr = cur_dtype->dtype_plist; pptr->pinfo_next != parts; 497*7c478bd9Sstevel@tonic-gate pptr = pptr->pinfo_next) 498*7c478bd9Sstevel@tonic-gate ; 499*7c478bd9Sstevel@tonic-gate pptr->pinfo_next = parts->pinfo_next; 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate /* 502*7c478bd9Sstevel@tonic-gate * Free the space it was using. 503*7c478bd9Sstevel@tonic-gate */ 504*7c478bd9Sstevel@tonic-gate destroy_data((char *)parts); 505*7c478bd9Sstevel@tonic-gate } 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate /* 509*7c478bd9Sstevel@tonic-gate * Set all partition vtoc fields to defaults 510*7c478bd9Sstevel@tonic-gate */ 511*7c478bd9Sstevel@tonic-gate void 512*7c478bd9Sstevel@tonic-gate set_vtoc_defaults(struct partition_info *part) 513*7c478bd9Sstevel@tonic-gate { 514*7c478bd9Sstevel@tonic-gate int i; 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate bzero((caddr_t)&part->vtoc, sizeof (struct dk_vtoc)); 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate part->vtoc.v_version = V_VERSION; 519*7c478bd9Sstevel@tonic-gate part->vtoc.v_nparts = NDKMAP; 520*7c478bd9Sstevel@tonic-gate part->vtoc.v_sanity = VTOC_SANE; 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 523*7c478bd9Sstevel@tonic-gate part->vtoc.v_part[i].p_tag = default_vtoc_map[i].p_tag; 524*7c478bd9Sstevel@tonic-gate part->vtoc.v_part[i].p_flag = default_vtoc_map[i].p_flag; 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate } 527