1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * This file contains functions to implement the partition menu commands. 31*0Sstevel@tonic-gate */ 32*0Sstevel@tonic-gate #include "global.h" 33*0Sstevel@tonic-gate #include "partition.h" 34*0Sstevel@tonic-gate #include "menu_partition.h" 35*0Sstevel@tonic-gate #include "menu_command.h" 36*0Sstevel@tonic-gate #include "modify_partition.h" 37*0Sstevel@tonic-gate #include "checkmount.h" 38*0Sstevel@tonic-gate #include "misc.h" 39*0Sstevel@tonic-gate #include "label.h" 40*0Sstevel@tonic-gate #include "auto_sense.h" 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate #include <stdlib.h> 43*0Sstevel@tonic-gate #include <string.h> 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate #ifdef __STDC__ 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate /* Function prototypes for ANSI C Compilers */ 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate static void adj_cyl_offset(struct dk_map32 *map); 50*0Sstevel@tonic-gate static int check_map(struct dk_map32 *map); 51*0Sstevel@tonic-gate static void get_user_map(struct dk_map32 *map, int float_part); 52*0Sstevel@tonic-gate static void get_user_map_efi(struct dk_gpt *map, int float_part); 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate #else /* __STDC__ */ 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate /* Function prototypes for non-ANSI C Compilers */ 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate static void adj_cyl_offset(); 59*0Sstevel@tonic-gate static int check_map(); 60*0Sstevel@tonic-gate static void get_user_map(); 61*0Sstevel@tonic-gate static void get_user_map_efi(); 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate #endif /* __STDC__ */ 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate static char *partn_list[] = { "0", "1", "2", "3", "4", "5", "6", "7", NULL }; 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate static char *sel_list[] = { "0", "1", "2", "3", NULL }; 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate #define MBYTE (1024*1024) 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate /* 73*0Sstevel@tonic-gate * Modify/Create a predefined partition table. 74*0Sstevel@tonic-gate */ 75*0Sstevel@tonic-gate int 76*0Sstevel@tonic-gate p_modify() 77*0Sstevel@tonic-gate { 78*0Sstevel@tonic-gate struct partition_info tmp_pinfo[1]; 79*0Sstevel@tonic-gate struct dk_map32 *map = tmp_pinfo->pinfo_map; 80*0Sstevel@tonic-gate u_ioparam_t ioparam; 81*0Sstevel@tonic-gate int inpt_dflt = 0; 82*0Sstevel@tonic-gate int free_hog = -1; 83*0Sstevel@tonic-gate int i; 84*0Sstevel@tonic-gate char tmpstr[80]; 85*0Sstevel@tonic-gate char tmpstr2[300]; 86*0Sstevel@tonic-gate int sel_type = 0; 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate /* 89*0Sstevel@tonic-gate * There must be a current disk type (and therefore a current disk). 90*0Sstevel@tonic-gate */ 91*0Sstevel@tonic-gate if (cur_dtype == NULL) { 92*0Sstevel@tonic-gate err_print("Current Disk Type is not set.\n"); 93*0Sstevel@tonic-gate return (-1); 94*0Sstevel@tonic-gate } 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate /* 97*0Sstevel@tonic-gate * check if there exists a partition table for the disk. 98*0Sstevel@tonic-gate */ 99*0Sstevel@tonic-gate if (cur_parts == NULL) { 100*0Sstevel@tonic-gate err_print("Current Disk has no partition table.\n"); 101*0Sstevel@tonic-gate return (-1); 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate /* 106*0Sstevel@tonic-gate * If the disk has mounted partitions, cannot modify 107*0Sstevel@tonic-gate */ 108*0Sstevel@tonic-gate if (checkmount((daddr_t)-1, (daddr_t)-1)) { 109*0Sstevel@tonic-gate err_print( 110*0Sstevel@tonic-gate "Cannot modify disk partitions while it has mounted partitions.\n\n"); 111*0Sstevel@tonic-gate return (-1); 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate /* 114*0Sstevel@tonic-gate * If the disk has partitions currently being used for 115*0Sstevel@tonic-gate * swapping, cannot modify 116*0Sstevel@tonic-gate */ 117*0Sstevel@tonic-gate if (checkswap((daddr_t)-1, (daddr_t)-1)) { 118*0Sstevel@tonic-gate err_print( 119*0Sstevel@tonic-gate "Cannot modify disk partitions while it is \ 120*0Sstevel@tonic-gate currently being used for swapping.\n"); 121*0Sstevel@tonic-gate return (-1); 122*0Sstevel@tonic-gate } 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * prompt user for a partition table base 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate if (cur_parts->pinfo_name != NULL) { 127*0Sstevel@tonic-gate (void) snprintf(tmpstr, sizeof (tmpstr), 128*0Sstevel@tonic-gate "\t0. Current partition table (%s)", 129*0Sstevel@tonic-gate cur_parts->pinfo_name); 130*0Sstevel@tonic-gate } else { 131*0Sstevel@tonic-gate (void) sprintf(tmpstr, 132*0Sstevel@tonic-gate "\t0. Current partition table (unnamed)"); 133*0Sstevel@tonic-gate } 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate (void) snprintf(tmpstr2, sizeof (tmpstr2), 136*0Sstevel@tonic-gate "Select partitioning base:\n%s\n" 137*0Sstevel@tonic-gate "\t1. All Free Hog\n" 138*0Sstevel@tonic-gate "Choose base (enter number) ", 139*0Sstevel@tonic-gate tmpstr); 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate ioparam.io_charlist = sel_list; 142*0Sstevel@tonic-gate sel_type = input(FIO_MSTR, tmpstr2, '?', &ioparam, 143*0Sstevel@tonic-gate &sel_type, DATA_INPUT); 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate switch (cur_label) { 146*0Sstevel@tonic-gate case L_TYPE_SOLARIS: 147*0Sstevel@tonic-gate if (sel_type == 0) { 148*0Sstevel@tonic-gate /* 149*0Sstevel@tonic-gate * Check for invalid parameters but do 150*0Sstevel@tonic-gate * not modify the table. 151*0Sstevel@tonic-gate */ 152*0Sstevel@tonic-gate if (check_map(cur_parts->pinfo_map)) { 153*0Sstevel@tonic-gate err_print("\ 154*0Sstevel@tonic-gate Warning: Fix, or select a different partition table.\n"); 155*0Sstevel@tonic-gate return (0); 156*0Sstevel@tonic-gate } 157*0Sstevel@tonic-gate /* 158*0Sstevel@tonic-gate * Create partition map from existing map 159*0Sstevel@tonic-gate */ 160*0Sstevel@tonic-gate tmp_pinfo->vtoc = cur_parts->vtoc; 161*0Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 162*0Sstevel@tonic-gate map[i].dkl_nblk = cur_parts->pinfo_map[i].dkl_nblk; 163*0Sstevel@tonic-gate map[i].dkl_cylno = cur_parts->pinfo_map[i].dkl_cylno; 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate } else { 166*0Sstevel@tonic-gate /* 167*0Sstevel@tonic-gate * Make an empty partition map, with all the space 168*0Sstevel@tonic-gate * in the c partition. 169*0Sstevel@tonic-gate */ 170*0Sstevel@tonic-gate set_vtoc_defaults(tmp_pinfo); 171*0Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 172*0Sstevel@tonic-gate map[i].dkl_nblk = 0; 173*0Sstevel@tonic-gate map[i].dkl_cylno = 0; 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate map[C_PARTITION].dkl_nblk = ncyl * spc(); 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate #if defined(i386) 178*0Sstevel@tonic-gate /* 179*0Sstevel@tonic-gate * Adjust for the boot and possibly alternates partitions 180*0Sstevel@tonic-gate */ 181*0Sstevel@tonic-gate map[I_PARTITION].dkl_nblk = spc(); 182*0Sstevel@tonic-gate map[I_PARTITION].dkl_cylno = 0; 183*0Sstevel@tonic-gate if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) { 184*0Sstevel@tonic-gate map[J_PARTITION].dkl_nblk = 2 * spc(); 185*0Sstevel@tonic-gate map[J_PARTITION].dkl_cylno = spc() / spc(); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate #endif /* defined(i386) */ 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate break; 190*0Sstevel@tonic-gate case L_TYPE_EFI: 191*0Sstevel@tonic-gate if (sel_type == 1) { 192*0Sstevel@tonic-gate for (i = 0; i < cur_parts->etoc->efi_nparts; i++) { 193*0Sstevel@tonic-gate cur_parts->etoc->efi_parts[i].p_start = 0; 194*0Sstevel@tonic-gate cur_parts->etoc->efi_parts[i].p_size = 0; 195*0Sstevel@tonic-gate } 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate break; 198*0Sstevel@tonic-gate } 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate fmt_print("\n"); 201*0Sstevel@tonic-gate if (cur_label == L_TYPE_SOLARIS) { 202*0Sstevel@tonic-gate print_map(tmp_pinfo); 203*0Sstevel@tonic-gate } else { 204*0Sstevel@tonic-gate print_map(cur_parts); 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate ioparam.io_charlist = confirm_list; 208*0Sstevel@tonic-gate if (input(FIO_MSTR, 209*0Sstevel@tonic-gate "Do you wish to continue creating a new partition\ntable based on above table", 210*0Sstevel@tonic-gate '?', &ioparam, &inpt_dflt, DATA_INPUT)) { 211*0Sstevel@tonic-gate return (0); 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate /* 215*0Sstevel@tonic-gate * get Free Hog partition 216*0Sstevel@tonic-gate */ 217*0Sstevel@tonic-gate inpt_dflt = 1; 218*0Sstevel@tonic-gate while ((free_hog < 0) && (cur_label == L_TYPE_SOLARIS)) { 219*0Sstevel@tonic-gate free_hog = G_PARTITION; /* default to g partition */ 220*0Sstevel@tonic-gate ioparam.io_charlist = partn_list; 221*0Sstevel@tonic-gate free_hog = input(FIO_MSTR, "Free Hog partition", '?', 222*0Sstevel@tonic-gate &ioparam, &free_hog, DATA_INPUT); 223*0Sstevel@tonic-gate /* disallow c partition */ 224*0Sstevel@tonic-gate if (free_hog == C_PARTITION) { 225*0Sstevel@tonic-gate fmt_print("'%c' cannot be the 'Free Hog' partition.\n", 226*0Sstevel@tonic-gate C_PARTITION + PARTITION_BASE); 227*0Sstevel@tonic-gate free_hog = -1; 228*0Sstevel@tonic-gate continue; 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate /* 231*0Sstevel@tonic-gate * If user selected all float set the 232*0Sstevel@tonic-gate * float to be the whole disk. 233*0Sstevel@tonic-gate */ 234*0Sstevel@tonic-gate if (sel_type == 1) { 235*0Sstevel@tonic-gate map[free_hog].dkl_nblk = map[C_PARTITION].dkl_nblk; 236*0Sstevel@tonic-gate #if defined(i386) 237*0Sstevel@tonic-gate map[free_hog].dkl_nblk -= map[I_PARTITION].dkl_nblk; 238*0Sstevel@tonic-gate if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) { 239*0Sstevel@tonic-gate map[free_hog].dkl_nblk -= 240*0Sstevel@tonic-gate map[J_PARTITION].dkl_nblk; 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate #endif /* defined(i386) */ 243*0Sstevel@tonic-gate break; 244*0Sstevel@tonic-gate } 245*0Sstevel@tonic-gate /* 246*0Sstevel@tonic-gate * Warn the user if there is no free space in 247*0Sstevel@tonic-gate * the float partition. 248*0Sstevel@tonic-gate */ 249*0Sstevel@tonic-gate if (map[free_hog].dkl_nblk == 0) { 250*0Sstevel@tonic-gate err_print("\ 251*0Sstevel@tonic-gate Warning: No space available from Free Hog partition.\n"); 252*0Sstevel@tonic-gate ioparam.io_charlist = confirm_list; 253*0Sstevel@tonic-gate if (input(FIO_MSTR, "Continue", '?', 254*0Sstevel@tonic-gate &ioparam, &inpt_dflt, DATA_INPUT)) { 255*0Sstevel@tonic-gate free_hog = -1; 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate inpt_dflt = 0; 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 262*0Sstevel@tonic-gate free_hog = G_PARTITION; /* default to g partition */ 263*0Sstevel@tonic-gate ioparam.io_charlist = partn_list; 264*0Sstevel@tonic-gate free_hog = input(FIO_MSTR, "Free Hog partition", '?', 265*0Sstevel@tonic-gate &ioparam, &free_hog, DATA_INPUT); 266*0Sstevel@tonic-gate /* disallow c partition */ 267*0Sstevel@tonic-gate if (free_hog == C_PARTITION) { 268*0Sstevel@tonic-gate fmt_print("'%c' cannot be the 'Free Hog' partition.\n", 269*0Sstevel@tonic-gate C_PARTITION + PARTITION_BASE); 270*0Sstevel@tonic-gate return (-1); 271*0Sstevel@tonic-gate } 272*0Sstevel@tonic-gate get_user_map_efi(cur_parts->etoc, free_hog); 273*0Sstevel@tonic-gate print_map(cur_parts); 274*0Sstevel@tonic-gate if (check("Ready to label disk, continue")) { 275*0Sstevel@tonic-gate return (-1); 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate fmt_print("\n"); 278*0Sstevel@tonic-gate if (write_label()) { 279*0Sstevel@tonic-gate err_print("Writing label failed\n"); 280*0Sstevel@tonic-gate return (-1); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate return (0); 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate /* 285*0Sstevel@tonic-gate * get user modified partition table 286*0Sstevel@tonic-gate */ 287*0Sstevel@tonic-gate get_user_map(map, free_hog); 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate /* 290*0Sstevel@tonic-gate * Update cylno offsets 291*0Sstevel@tonic-gate */ 292*0Sstevel@tonic-gate adj_cyl_offset(map); 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate fmt_print("\n"); 295*0Sstevel@tonic-gate print_map(tmp_pinfo); 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate ioparam.io_charlist = confirm_list; 298*0Sstevel@tonic-gate if (input(FIO_MSTR, "\ 299*0Sstevel@tonic-gate Okay to make this the current partition table", '?', 300*0Sstevel@tonic-gate &ioparam, &inpt_dflt, DATA_INPUT)) { 301*0Sstevel@tonic-gate return (0); 302*0Sstevel@tonic-gate } else { 303*0Sstevel@tonic-gate make_partition(); 304*0Sstevel@tonic-gate /* 305*0Sstevel@tonic-gate * Update new partition map 306*0Sstevel@tonic-gate */ 307*0Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 308*0Sstevel@tonic-gate cur_parts->pinfo_map[i].dkl_nblk = map[i].dkl_nblk; 309*0Sstevel@tonic-gate cur_parts->pinfo_map[i].dkl_cylno = map[i].dkl_cylno; 310*0Sstevel@tonic-gate #ifdef i386 311*0Sstevel@tonic-gate cur_parts->vtoc.v_part[i].p_start = 312*0Sstevel@tonic-gate map[i].dkl_cylno * nhead * nsect; 313*0Sstevel@tonic-gate cur_parts->vtoc.v_part[i].p_size = 314*0Sstevel@tonic-gate map[i].dkl_nblk; 315*0Sstevel@tonic-gate #endif 316*0Sstevel@tonic-gate } 317*0Sstevel@tonic-gate (void) p_name(); 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate /* 320*0Sstevel@tonic-gate * Label the disk now 321*0Sstevel@tonic-gate */ 322*0Sstevel@tonic-gate if (check("Ready to label disk, continue")) { 323*0Sstevel@tonic-gate return (-1); 324*0Sstevel@tonic-gate } 325*0Sstevel@tonic-gate fmt_print("\n"); 326*0Sstevel@tonic-gate if (write_label()) { 327*0Sstevel@tonic-gate err_print("Writing label failed\n"); 328*0Sstevel@tonic-gate return (-1); 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate return (0); 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate } 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate /* 337*0Sstevel@tonic-gate * Adjust cylinder offsets 338*0Sstevel@tonic-gate */ 339*0Sstevel@tonic-gate static void 340*0Sstevel@tonic-gate adj_cyl_offset(map) 341*0Sstevel@tonic-gate struct dk_map32 *map; 342*0Sstevel@tonic-gate { 343*0Sstevel@tonic-gate int i; 344*0Sstevel@tonic-gate int cyloffset = 0; 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate /* 348*0Sstevel@tonic-gate * Update cylno offsets 349*0Sstevel@tonic-gate */ 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 352*0Sstevel@tonic-gate /* 353*0Sstevel@tonic-gate * Correct cylinder allocation for having the boot and alternates 354*0Sstevel@tonic-gate * slice in the beginning of the disk 355*0Sstevel@tonic-gate */ 356*0Sstevel@tonic-gate for (i = NDKMAP/2; i < NDKMAP; i++) { 357*0Sstevel@tonic-gate if (i != C_PARTITION && map[i].dkl_nblk) { 358*0Sstevel@tonic-gate map[i].dkl_cylno = cyloffset; 359*0Sstevel@tonic-gate cyloffset += (map[i].dkl_nblk + (spc()-1))/spc(); 360*0Sstevel@tonic-gate } else if (map[i].dkl_nblk == 0) { 361*0Sstevel@tonic-gate map[i].dkl_cylno = 0; 362*0Sstevel@tonic-gate } 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate for (i = 0; i < NDKMAP/2; i++) { 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate #else /* !defined(_SUNOS_VTOC_16) */ 367*0Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 368*0Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate if (i != C_PARTITION && map[i].dkl_nblk) { 371*0Sstevel@tonic-gate map[i].dkl_cylno = cyloffset; 372*0Sstevel@tonic-gate cyloffset += (map[i].dkl_nblk + (spc()-1))/spc(); 373*0Sstevel@tonic-gate } else if (map[i].dkl_nblk == 0) { 374*0Sstevel@tonic-gate map[i].dkl_cylno = 0; 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate } 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate /* 381*0Sstevel@tonic-gate * Check partition table 382*0Sstevel@tonic-gate */ 383*0Sstevel@tonic-gate static int 384*0Sstevel@tonic-gate check_map(map) 385*0Sstevel@tonic-gate struct dk_map32 *map; 386*0Sstevel@tonic-gate { 387*0Sstevel@tonic-gate int i; 388*0Sstevel@tonic-gate int cyloffset = 0; 389*0Sstevel@tonic-gate int tot_blks = 0; 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate #ifdef i386 392*0Sstevel@tonic-gate /* 393*0Sstevel@tonic-gate * On x86, we must account for the boot and alternates 394*0Sstevel@tonic-gate */ 395*0Sstevel@tonic-gate cyloffset = map[0].dkl_cylno; 396*0Sstevel@tonic-gate tot_blks = map[0].dkl_nblk; 397*0Sstevel@tonic-gate #endif 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate /* 400*0Sstevel@tonic-gate * Do some checks for invalid parameters but do 401*0Sstevel@tonic-gate * not modify the table. 402*0Sstevel@tonic-gate */ 403*0Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 404*0Sstevel@tonic-gate if (map[i].dkl_cylno < 0 || 405*0Sstevel@tonic-gate map[i].dkl_cylno > (daddr_t)ncyl-1) { 406*0Sstevel@tonic-gate err_print("\ 407*0Sstevel@tonic-gate Warning: Partition %c starting cylinder %d is out of range.\n", 408*0Sstevel@tonic-gate (PARTITION_BASE+i), map[i].dkl_cylno); 409*0Sstevel@tonic-gate return (-1); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate if (map[i].dkl_nblk < 0 || map[i].dkl_nblk > (daddr_t)(ncyl - 412*0Sstevel@tonic-gate map[i].dkl_cylno) * spc()) { 413*0Sstevel@tonic-gate err_print("\ 414*0Sstevel@tonic-gate Warning: Partition %c, specified # of blocks, %d, is out of range.\n", 415*0Sstevel@tonic-gate (PARTITION_BASE+i), map[i].dkl_nblk); 416*0Sstevel@tonic-gate return (-1); 417*0Sstevel@tonic-gate } 418*0Sstevel@tonic-gate if (i != C_PARTITION && map[i].dkl_nblk) { 419*0Sstevel@tonic-gate #ifdef i386 420*0Sstevel@tonic-gate if (i == I_PARTITION || i == J_PARTITION) 421*0Sstevel@tonic-gate continue; 422*0Sstevel@tonic-gate #endif 423*0Sstevel@tonic-gate if (map[i].dkl_cylno < cyloffset) { 424*0Sstevel@tonic-gate err_print( 425*0Sstevel@tonic-gate "Warning: Overlapping partition (%c) in table.\n", PARTITION_BASE+i); 426*0Sstevel@tonic-gate return (-1); 427*0Sstevel@tonic-gate } else if (map[i].dkl_cylno > cyloffset) { 428*0Sstevel@tonic-gate err_print( 429*0Sstevel@tonic-gate "Warning: Non-contiguous partition (%c) in table.\n", PARTITION_BASE+i); 430*0Sstevel@tonic-gate } 431*0Sstevel@tonic-gate cyloffset += (map[i].dkl_nblk + (spc()-1))/spc(); 432*0Sstevel@tonic-gate tot_blks = map[i].dkl_nblk; 433*0Sstevel@tonic-gate } 434*0Sstevel@tonic-gate } 435*0Sstevel@tonic-gate if (tot_blks > map[C_PARTITION].dkl_nblk) { 436*0Sstevel@tonic-gate err_print("\ 437*0Sstevel@tonic-gate Warning: Total blocks used is greater than number of blocks in '%c'\n\ 438*0Sstevel@tonic-gate \tpartition.\n", C_PARTITION + PARTITION_BASE); 439*0Sstevel@tonic-gate return (-1); 440*0Sstevel@tonic-gate } 441*0Sstevel@tonic-gate return (0); 442*0Sstevel@tonic-gate } 443*0Sstevel@tonic-gate 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate /* 447*0Sstevel@tonic-gate * get user defined partitions 448*0Sstevel@tonic-gate */ 449*0Sstevel@tonic-gate static void 450*0Sstevel@tonic-gate get_user_map(map, float_part) 451*0Sstevel@tonic-gate struct dk_map32 *map; 452*0Sstevel@tonic-gate int float_part; 453*0Sstevel@tonic-gate { 454*0Sstevel@tonic-gate int i; 455*0Sstevel@tonic-gate int newsize; 456*0Sstevel@tonic-gate int deflt; 457*0Sstevel@tonic-gate char tmpstr[80]; 458*0Sstevel@tonic-gate u_ioparam_t ioparam; 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate /* 461*0Sstevel@tonic-gate * Get partition sizes 462*0Sstevel@tonic-gate */ 463*0Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 464*0Sstevel@tonic-gate if (partn_list[i] == NULL) 465*0Sstevel@tonic-gate break; 466*0Sstevel@tonic-gate if ((i == C_PARTITION) || (i == float_part)) 467*0Sstevel@tonic-gate continue; 468*0Sstevel@tonic-gate else { 469*0Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 470*0Sstevel@tonic-gate ioparam.io_bounds.upper = map[i].dkl_nblk + 471*0Sstevel@tonic-gate map[float_part].dkl_nblk; 472*0Sstevel@tonic-gate deflt = map[i].dkl_nblk; 473*0Sstevel@tonic-gate if (ioparam.io_bounds.upper == 0) { 474*0Sstevel@tonic-gate err_print("\ 475*0Sstevel@tonic-gate Warning: no space available for '%s' from Free Hog partition\n", 476*0Sstevel@tonic-gate partn_list[i]); 477*0Sstevel@tonic-gate continue; 478*0Sstevel@tonic-gate } 479*0Sstevel@tonic-gate (void) snprintf(tmpstr, sizeof (tmpstr), 480*0Sstevel@tonic-gate "Enter size of partition '%s' ", 481*0Sstevel@tonic-gate partn_list[i]); 482*0Sstevel@tonic-gate newsize = input(FIO_CYL, tmpstr, ':', 483*0Sstevel@tonic-gate &ioparam, &deflt, DATA_INPUT); 484*0Sstevel@tonic-gate map[float_part].dkl_nblk -= (newsize - map[i].dkl_nblk); 485*0Sstevel@tonic-gate map[i].dkl_nblk = newsize; 486*0Sstevel@tonic-gate } 487*0Sstevel@tonic-gate } 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate static struct partition_info * 491*0Sstevel@tonic-gate build_partition(tptr) 492*0Sstevel@tonic-gate struct disk_type *tptr; 493*0Sstevel@tonic-gate { 494*0Sstevel@tonic-gate struct partition_info *part; 495*0Sstevel@tonic-gate struct dk_label *label; 496*0Sstevel@tonic-gate int i; 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate #ifdef DEBUG 499*0Sstevel@tonic-gate fmt_print("Creating Default Partition for the disk \n"); 500*0Sstevel@tonic-gate #endif 501*0Sstevel@tonic-gate /* 502*0Sstevel@tonic-gate * construct a label and pass it on to 503*0Sstevel@tonic-gate * build_default_partition() which builds the 504*0Sstevel@tonic-gate * default partition list. 505*0Sstevel@tonic-gate */ 506*0Sstevel@tonic-gate label = zalloc(sizeof (struct dk_label)); 507*0Sstevel@tonic-gate label->dkl_pcyl = tptr->dtype_pcyl; 508*0Sstevel@tonic-gate label->dkl_ncyl = tptr->dtype_ncyl; 509*0Sstevel@tonic-gate label->dkl_acyl = tptr->dtype_acyl; 510*0Sstevel@tonic-gate label->dkl_nhead = tptr->dtype_nhead; 511*0Sstevel@tonic-gate label->dkl_nsect = tptr->dtype_nsect; 512*0Sstevel@tonic-gate label->dkl_apc = apc; 513*0Sstevel@tonic-gate label->dkl_intrlv = 1; 514*0Sstevel@tonic-gate label->dkl_rpm = tptr->dtype_rpm; 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate if (!build_default_partition(label, cur_ctype->ctype_ctype)) 517*0Sstevel@tonic-gate return (NULL); 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate part = (struct partition_info *) 520*0Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 521*0Sstevel@tonic-gate part->pinfo_name = alloc_string(tptr->dtype_asciilabel); 522*0Sstevel@tonic-gate /* 523*0Sstevel@tonic-gate * Fill in the partition info from the label 524*0Sstevel@tonic-gate */ 525*0Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 526*0Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 527*0Sstevel@tonic-gate part->pinfo_map[i] = label->dkl_map[i]; 528*0Sstevel@tonic-gate #else 529*0Sstevel@tonic-gate part->pinfo_map[i].dkl_cylno = 530*0Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_start / 531*0Sstevel@tonic-gate ((int)(tptr->dtype_nhead * tptr->dtype_nsect - apc)); 532*0Sstevel@tonic-gate part->pinfo_map[i].dkl_nblk = 533*0Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_size; 534*0Sstevel@tonic-gate #endif /* ifdefined(_SUNOS_VTOC_8) */ 535*0Sstevel@tonic-gate } 536*0Sstevel@tonic-gate part->vtoc = label->dkl_vtoc; 537*0Sstevel@tonic-gate return (part); 538*0Sstevel@tonic-gate } 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate /* 541*0Sstevel@tonic-gate * build new partition table for given disk type 542*0Sstevel@tonic-gate */ 543*0Sstevel@tonic-gate static void 544*0Sstevel@tonic-gate get_user_map_efi(map, float_part) 545*0Sstevel@tonic-gate struct dk_gpt *map; 546*0Sstevel@tonic-gate int float_part; 547*0Sstevel@tonic-gate { 548*0Sstevel@tonic-gate 549*0Sstevel@tonic-gate int i; 550*0Sstevel@tonic-gate efi_deflt_t efi_deflt; 551*0Sstevel@tonic-gate u_ioparam_t ioparam; 552*0Sstevel@tonic-gate char tmpstr[80]; 553*0Sstevel@tonic-gate uint64_t i64; 554*0Sstevel@tonic-gate uint64_t start_lba = 34; 555*0Sstevel@tonic-gate 556*0Sstevel@tonic-gate for (i = 0; i < map->efi_nparts - 1; i++) { 557*0Sstevel@tonic-gate if (i == float_part) 558*0Sstevel@tonic-gate continue; 559*0Sstevel@tonic-gate else { 560*0Sstevel@tonic-gate ioparam.io_bounds.lower = start_lba; 561*0Sstevel@tonic-gate ioparam.io_bounds.upper = map->efi_last_u_lba; 562*0Sstevel@tonic-gate efi_deflt.start_sector = ioparam.io_bounds.lower; 563*0Sstevel@tonic-gate efi_deflt.end_sector = map->efi_parts[i].p_size; 564*0Sstevel@tonic-gate (void) sprintf(tmpstr, 565*0Sstevel@tonic-gate "Enter size of partition %d ", i); 566*0Sstevel@tonic-gate i64 = input(FIO_EFI, tmpstr, ':', 567*0Sstevel@tonic-gate &ioparam, (int *)&efi_deflt, DATA_INPUT); 568*0Sstevel@tonic-gate if (i64 == 0) { 569*0Sstevel@tonic-gate map->efi_parts[i].p_tag = V_UNASSIGNED; 570*0Sstevel@tonic-gate } else if ((i64 != 0) && (map->efi_parts[i].p_tag == 571*0Sstevel@tonic-gate V_UNASSIGNED)) { 572*0Sstevel@tonic-gate map->efi_parts[i].p_tag = V_USR; 573*0Sstevel@tonic-gate } 574*0Sstevel@tonic-gate if (i64 == 0) { 575*0Sstevel@tonic-gate map->efi_parts[i].p_start = 0; 576*0Sstevel@tonic-gate } else { 577*0Sstevel@tonic-gate map->efi_parts[i].p_start = start_lba; 578*0Sstevel@tonic-gate } 579*0Sstevel@tonic-gate map->efi_parts[i].p_size = i64; 580*0Sstevel@tonic-gate start_lba += i64; 581*0Sstevel@tonic-gate } 582*0Sstevel@tonic-gate } 583*0Sstevel@tonic-gate map->efi_parts[float_part].p_start = start_lba; 584*0Sstevel@tonic-gate map->efi_parts[float_part].p_size = map->efi_last_u_lba - 585*0Sstevel@tonic-gate start_lba - (1024 * 16); 586*0Sstevel@tonic-gate map->efi_parts[float_part].p_tag = V_USR; 587*0Sstevel@tonic-gate if (map->efi_parts[float_part].p_size == UINT_MAX64) { 588*0Sstevel@tonic-gate map->efi_parts[float_part].p_size = 0; 589*0Sstevel@tonic-gate map->efi_parts[float_part].p_start = 0; 590*0Sstevel@tonic-gate map->efi_parts[float_part].p_tag = V_UNASSIGNED; 591*0Sstevel@tonic-gate fmt_print("Warning: No space left for HOG\n"); 592*0Sstevel@tonic-gate } 593*0Sstevel@tonic-gate 594*0Sstevel@tonic-gate for (i = 0; i < map->efi_nparts; i++) { 595*0Sstevel@tonic-gate if (map->efi_parts[i].p_tag == V_RESERVED) { 596*0Sstevel@tonic-gate map->efi_parts[i].p_start = map->efi_last_u_lba - 597*0Sstevel@tonic-gate (1024 * 16); 598*0Sstevel@tonic-gate map->efi_parts[i].p_size = (1024 * 16); 599*0Sstevel@tonic-gate break; 600*0Sstevel@tonic-gate } 601*0Sstevel@tonic-gate } 602*0Sstevel@tonic-gate } 603*0Sstevel@tonic-gate 604*0Sstevel@tonic-gate 605*0Sstevel@tonic-gate void 606*0Sstevel@tonic-gate new_partitiontable(tptr, oldtptr) 607*0Sstevel@tonic-gate struct disk_type *tptr, *oldtptr; 608*0Sstevel@tonic-gate { 609*0Sstevel@tonic-gate struct partition_info *part; 610*0Sstevel@tonic-gate 611*0Sstevel@tonic-gate /* 612*0Sstevel@tonic-gate * check if disk geometry has changed , if so add new 613*0Sstevel@tonic-gate * partition table else copy the old partition table.(best guess). 614*0Sstevel@tonic-gate */ 615*0Sstevel@tonic-gate if ((oldtptr != NULL) && 616*0Sstevel@tonic-gate (tptr->dtype_ncyl == oldtptr->dtype_ncyl) && 617*0Sstevel@tonic-gate (tptr->dtype_nhead == oldtptr->dtype_nhead) && 618*0Sstevel@tonic-gate (tptr->dtype_nsect == oldtptr->dtype_nsect)) { 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate part = (struct partition_info *) 621*0Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 622*0Sstevel@tonic-gate bcopy((char *)cur_parts, (char *)part, 623*0Sstevel@tonic-gate sizeof (struct partition_info)); 624*0Sstevel@tonic-gate part->pinfo_next = tptr->dtype_plist; 625*0Sstevel@tonic-gate tptr->dtype_plist = part; 626*0Sstevel@tonic-gate } else { 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gate #ifdef DEBUG 629*0Sstevel@tonic-gate if (cur_parts != NULL) { 630*0Sstevel@tonic-gate fmt_print("Warning: Partition Table is set"); 631*0Sstevel@tonic-gate fmt_print("to default partition table. \n"); 632*0Sstevel@tonic-gate } 633*0Sstevel@tonic-gate #endif 634*0Sstevel@tonic-gate if (tptr->dtype_plist == NULL) { 635*0Sstevel@tonic-gate part = (struct partition_info *)build_partition(tptr); 636*0Sstevel@tonic-gate if (part != NULL) { 637*0Sstevel@tonic-gate part->pinfo_next = tptr->dtype_plist; 638*0Sstevel@tonic-gate tptr->dtype_plist = part; 639*0Sstevel@tonic-gate } 640*0Sstevel@tonic-gate } 641*0Sstevel@tonic-gate } 642*0Sstevel@tonic-gate } 643