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 5342440ecSPrasad Singamsetty * Common Development and Distribution License (the "License"). 6342440ecSPrasad Singamsetty * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*23a1cceaSRoger A. Faulkner 227c478bd9Sstevel@tonic-gate /* 23*23a1cceaSRoger A. Faulkner * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * This file contains functions that operate on partition tables. 287c478bd9Sstevel@tonic-gate */ 29*23a1cceaSRoger A. Faulkner #include <string.h> 30*23a1cceaSRoger A. Faulkner #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include "global.h" 327c478bd9Sstevel@tonic-gate #include "partition.h" 337c478bd9Sstevel@tonic-gate #include "misc.h" 347c478bd9Sstevel@tonic-gate #include "menu_command.h" 357c478bd9Sstevel@tonic-gate #include "menu_partition.h" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* 397c478bd9Sstevel@tonic-gate * Default vtoc information for non-SVr4 partitions 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate struct dk_map2 default_vtoc_map[NDKMAP] = { 427c478bd9Sstevel@tonic-gate { V_ROOT, 0 }, /* a - 0 */ 437c478bd9Sstevel@tonic-gate { V_SWAP, V_UNMNT }, /* b - 1 */ 447c478bd9Sstevel@tonic-gate { V_BACKUP, V_UNMNT }, /* c - 2 */ 457c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* d - 3 */ 467c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* e - 4 */ 477c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* f - 5 */ 487c478bd9Sstevel@tonic-gate { V_USR, 0 }, /* g - 6 */ 497c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* h - 7 */ 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate #if defined(i386) 547c478bd9Sstevel@tonic-gate { V_BOOT, V_UNMNT }, /* i - 8 */ 557c478bd9Sstevel@tonic-gate { V_ALTSCTR, 0 }, /* j - 9 */ 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate #else 587c478bd9Sstevel@tonic-gate #error No VTOC format defined. 597c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* k - 10 */ 627c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* l - 11 */ 637c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* m - 12 */ 647c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* n - 13 */ 657c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* o - 14 */ 667c478bd9Sstevel@tonic-gate { V_UNASSIGNED, 0 }, /* p - 15 */ 677c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 687c478bd9Sstevel@tonic-gate }; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* 717c478bd9Sstevel@tonic-gate * This routine finds the last usable sector in the partition table. 727c478bd9Sstevel@tonic-gate * It skips the BACKUP partition. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate static uint64_t 757c478bd9Sstevel@tonic-gate maxofN(struct dk_gpt *map) 767c478bd9Sstevel@tonic-gate { 777c478bd9Sstevel@tonic-gate uint64_t max; 787c478bd9Sstevel@tonic-gate uint64_t sec_no[2], start[2], size[2]; 797c478bd9Sstevel@tonic-gate int i; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate for (i = 0; i < map->efi_nparts - 1; i++) { 827c478bd9Sstevel@tonic-gate start[0] = map->efi_parts[i].p_start; 837c478bd9Sstevel@tonic-gate size[0] = map->efi_parts[i].p_size; 847c478bd9Sstevel@tonic-gate sec_no[0] = start[0] + size[0]; 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate start[1] = map->efi_parts[i+1].p_start; 877c478bd9Sstevel@tonic-gate size[1] = map->efi_parts[i+1].p_size; 887c478bd9Sstevel@tonic-gate sec_no[1] = start[1] + size[1]; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate if (map->efi_parts[i].p_tag == V_BACKUP) { 917c478bd9Sstevel@tonic-gate sec_no[0] = 0; 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate if (map->efi_parts[i+1].p_tag == V_BACKUP) { 947c478bd9Sstevel@tonic-gate sec_no[1] = 0; 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate if (i == 0) { 977c478bd9Sstevel@tonic-gate max = sec_no[1]; 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate if (sec_no[0] > max) { 1007c478bd9Sstevel@tonic-gate max = sec_no[0]; 1017c478bd9Sstevel@tonic-gate } else { 1027c478bd9Sstevel@tonic-gate max = max; 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate if (max == 0) 1067c478bd9Sstevel@tonic-gate max = 34; 1077c478bd9Sstevel@tonic-gate return (max); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* 1117c478bd9Sstevel@tonic-gate * This routine allows the user to change the boundaries of the given 1127c478bd9Sstevel@tonic-gate * partition in the current partition map. 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate void 1157c478bd9Sstevel@tonic-gate change_partition(int num) 1167c478bd9Sstevel@tonic-gate { 117342440ecSPrasad Singamsetty uint_t i; 1187c478bd9Sstevel@tonic-gate uint64_t i64, j64; 119342440ecSPrasad Singamsetty uint_t j; 1207c478bd9Sstevel@tonic-gate int deflt; 1217c478bd9Sstevel@tonic-gate part_deflt_t p_deflt; 1227c478bd9Sstevel@tonic-gate u_ioparam_t ioparam; 1237c478bd9Sstevel@tonic-gate int tag; 1247c478bd9Sstevel@tonic-gate int flag; 1257c478bd9Sstevel@tonic-gate char msg[256]; 126342440ecSPrasad Singamsetty blkaddr32_t cyl_offset = 0; 1277c478bd9Sstevel@tonic-gate efi_deflt_t efi_deflt; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* 1307c478bd9Sstevel@tonic-gate * check if there exists a partition table for the disk. 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate if (cur_parts == NULL) { 1337c478bd9Sstevel@tonic-gate err_print("Current Disk has no partition table.\n"); 1347c478bd9Sstevel@tonic-gate return; 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 1387c478bd9Sstevel@tonic-gate if (num > cur_parts->etoc->efi_nparts - 1) { 1397c478bd9Sstevel@tonic-gate err_print("Invalid partition for EFI label\n"); 1407c478bd9Sstevel@tonic-gate return; 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate print_efi_partition(cur_parts->etoc, num, 1); 1437c478bd9Sstevel@tonic-gate fmt_print("\n"); 1447c478bd9Sstevel@tonic-gate /* 1457c478bd9Sstevel@tonic-gate * Prompt for p_tag and p_flag values for this partition 1467c478bd9Sstevel@tonic-gate */ 1477c478bd9Sstevel@tonic-gate deflt = cur_parts->etoc->efi_parts[num].p_tag; 1487c478bd9Sstevel@tonic-gate if (deflt == V_UNASSIGNED) { 1497c478bd9Sstevel@tonic-gate deflt = V_USR; 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition id tag"); 1527c478bd9Sstevel@tonic-gate ioparam.io_slist = ptag_choices; 1537c478bd9Sstevel@tonic-gate tag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate deflt = cur_parts->etoc->efi_parts[num].p_flag; 1567c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition permission flags"); 1577c478bd9Sstevel@tonic-gate ioparam.io_slist = pflag_choices; 1587c478bd9Sstevel@tonic-gate flag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 34; 1617c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = cur_parts->etoc->efi_last_u_lba; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate efi_deflt.start_sector = maxofN(cur_parts->etoc); 1647c478bd9Sstevel@tonic-gate if ((cur_parts->etoc->efi_parts[num].p_start != 0) && 1657c478bd9Sstevel@tonic-gate (cur_parts->etoc->efi_parts[num].p_size != 0)) { 1667c478bd9Sstevel@tonic-gate efi_deflt.start_sector = 1677c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_start; 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate efi_deflt.end_sector = ioparam.io_bounds.upper - 1707c478bd9Sstevel@tonic-gate efi_deflt.start_sector; 1717c478bd9Sstevel@tonic-gate i64 = input(FIO_INT64, "Enter new starting Sector", ':', &ioparam, 1727c478bd9Sstevel@tonic-gate (int *)&efi_deflt, DATA_INPUT); 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 1757c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = cur_parts->etoc->efi_last_u_lba; 1767c478bd9Sstevel@tonic-gate efi_deflt.end_sector = cur_parts->etoc->efi_parts[num].p_size; 1777c478bd9Sstevel@tonic-gate efi_deflt.start_sector = i64; 1787c478bd9Sstevel@tonic-gate j64 = input(FIO_EFI, "Enter partition size", ':', &ioparam, 1797c478bd9Sstevel@tonic-gate (int *)&efi_deflt, DATA_INPUT); 1807c478bd9Sstevel@tonic-gate if (j64 == 0) { 1817c478bd9Sstevel@tonic-gate tag = V_UNASSIGNED; 1827c478bd9Sstevel@tonic-gate i64 = 0; 1837c478bd9Sstevel@tonic-gate } else if ((j64 != 0) && (tag == V_UNASSIGNED)) { 1847c478bd9Sstevel@tonic-gate tag = V_USR; 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate if (cur_parts->pinfo_name != NULL) 1887c478bd9Sstevel@tonic-gate make_partition(); 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_tag = tag; 1917c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_flag = flag; 1927c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_start = i64; 1937c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[num].p_size = j64; 1947c478bd9Sstevel@tonic-gate /* 1957c478bd9Sstevel@tonic-gate * We are now done with EFI part, so return now 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate return; 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate /* 2007c478bd9Sstevel@tonic-gate * Print out the given partition so the user knows what he/she's 2017c478bd9Sstevel@tonic-gate * getting into. 2027c478bd9Sstevel@tonic-gate */ 2037c478bd9Sstevel@tonic-gate print_partition(cur_parts, num, 1); 2047c478bd9Sstevel@tonic-gate fmt_print("\n"); 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* 2077c478bd9Sstevel@tonic-gate * Prompt for p_tag and p_flag values for this partition. 2087c478bd9Sstevel@tonic-gate */ 2097c478bd9Sstevel@tonic-gate assert(cur_parts->vtoc.v_version == V_VERSION); 2107c478bd9Sstevel@tonic-gate deflt = cur_parts->vtoc.v_part[num].p_tag; 2117c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition id tag"); 2127c478bd9Sstevel@tonic-gate ioparam.io_slist = ptag_choices; 2137c478bd9Sstevel@tonic-gate tag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate deflt = cur_parts->vtoc.v_part[num].p_flag; 2167c478bd9Sstevel@tonic-gate (void) sprintf(msg, "Enter partition permission flags"); 2177c478bd9Sstevel@tonic-gate ioparam.io_slist = pflag_choices; 2187c478bd9Sstevel@tonic-gate flag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT); 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate /* 2217c478bd9Sstevel@tonic-gate * Ask for the new values. The old values are the defaults, and 2227c478bd9Sstevel@tonic-gate * strict bounds checking is done on the values given. 2237c478bd9Sstevel@tonic-gate */ 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate #if defined(i386) 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if (tag != V_UNASSIGNED && tag != V_BACKUP && tag != V_BOOT) { 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * Determine cyl offset for boot and alternate partitions. 2307c478bd9Sstevel@tonic-gate * Assuming that the alternate sectors partition (slice) 2317c478bd9Sstevel@tonic-gate * physical location immediately follows the boot 2327c478bd9Sstevel@tonic-gate * partition and partition sizes are expressed in multiples 2337c478bd9Sstevel@tonic-gate * of cylinder size. 2347c478bd9Sstevel@tonic-gate */ 2357c478bd9Sstevel@tonic-gate cyl_offset = cur_parts->pinfo_map[I_PARTITION].dkl_cylno + 1; 2367c478bd9Sstevel@tonic-gate if (tag != V_ALTSCTR) { 2377c478bd9Sstevel@tonic-gate if (cur_parts->pinfo_map[J_PARTITION].dkl_nblk != 0) { 2387c478bd9Sstevel@tonic-gate cyl_offset = 2397c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[J_PARTITION].dkl_cylno + 2407c478bd9Sstevel@tonic-gate ((cur_parts->pinfo_map[J_PARTITION].dkl_nblk + 2417c478bd9Sstevel@tonic-gate (spc()-1)) / spc()); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 2487c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = ncyl - 1; 2497c478bd9Sstevel@tonic-gate deflt = max(cur_parts->pinfo_map[num].dkl_cylno, 2507c478bd9Sstevel@tonic-gate cyl_offset); 251342440ecSPrasad Singamsetty i = (uint_t)input(FIO_INT, "Enter new starting cyl", ':', &ioparam, 2527c478bd9Sstevel@tonic-gate &deflt, DATA_INPUT); 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 2557c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = (ncyl - i) * spc(); 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* fill in defaults for the current partition */ 2587c478bd9Sstevel@tonic-gate p_deflt.start_cyl = i; 2597c478bd9Sstevel@tonic-gate p_deflt.deflt_size = 2607c478bd9Sstevel@tonic-gate min(cur_parts->pinfo_map[num].dkl_nblk, 2617c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper); 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate /* call input, passing p_deflt's address, typecast to (int *) */ 264342440ecSPrasad Singamsetty j = (uint_t)input(FIO_ECYL, "Enter partition size", ':', &ioparam, 2657c478bd9Sstevel@tonic-gate (int *)&p_deflt, DATA_INPUT); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * If the current partition has a size of zero change the 2697c478bd9Sstevel@tonic-gate * tag to Unassigned and the starting cylinder to zero 2707c478bd9Sstevel@tonic-gate */ 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate if (j == 0) { 2737c478bd9Sstevel@tonic-gate tag = V_UNASSIGNED; 2747c478bd9Sstevel@tonic-gate i = 0; 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate #if defined(i386) 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate if (i < cyl_offset && tag != V_UNASSIGNED && tag != V_BACKUP && 2817c478bd9Sstevel@tonic-gate tag != V_BOOT) { 2827c478bd9Sstevel@tonic-gate /* 2837c478bd9Sstevel@tonic-gate * This slice overlaps boot and/or alternates slice 2847c478bd9Sstevel@tonic-gate * Check if it's the boot or alternates slice and warn 2857c478bd9Sstevel@tonic-gate * accordingly 2867c478bd9Sstevel@tonic-gate */ 2877c478bd9Sstevel@tonic-gate if (i < cur_parts->pinfo_map[I_PARTITION].dkl_cylno + 1) { 2887c478bd9Sstevel@tonic-gate fmt_print("\nWarning: Partition overlaps boot "); 2897c478bd9Sstevel@tonic-gate fmt_print("partition. Specify different start cyl.\n"); 2907c478bd9Sstevel@tonic-gate return; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate /* 2937c478bd9Sstevel@tonic-gate * Cyl offset for alternates partition was calculated before 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate if (i < cyl_offset) { 2967c478bd9Sstevel@tonic-gate fmt_print("\nWarning: Partition overlaps alternates "); 2977c478bd9Sstevel@tonic-gate fmt_print("partition. Specify different start cyl.\n"); 2987c478bd9Sstevel@tonic-gate return; 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate /* 3057c478bd9Sstevel@tonic-gate * If user has entered a V_BACKUP tag then the partition 3067c478bd9Sstevel@tonic-gate * size should specify full disk capacity else 3077c478bd9Sstevel@tonic-gate * return an Error. 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate if (tag == V_BACKUP) { 310342440ecSPrasad Singamsetty uint_t fullsz; 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate fullsz = ncyl * nhead * nsect; 3137c478bd9Sstevel@tonic-gate if (fullsz != j) { 3147c478bd9Sstevel@tonic-gate /* 3157c478bd9Sstevel@tonic-gate * V_BACKUP Tag Partition != full disk capacity. 3167c478bd9Sstevel@tonic-gate * print useful messages. 3177c478bd9Sstevel@tonic-gate */ 3187c478bd9Sstevel@tonic-gate fmt_print("\nWarning: Partition with V_BACKUP tag should "); 3197c478bd9Sstevel@tonic-gate fmt_print("specify full disk capacity. \n"); 3207c478bd9Sstevel@tonic-gate return; 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate } 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* 3267c478bd9Sstevel@tonic-gate * If the current partition is named, we can't change it. 3277c478bd9Sstevel@tonic-gate * We create a new current partition map instead. 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate if (cur_parts->pinfo_name != NULL) 3307c478bd9Sstevel@tonic-gate make_partition(); 3317c478bd9Sstevel@tonic-gate /* 3327c478bd9Sstevel@tonic-gate * Change the values. 3337c478bd9Sstevel@tonic-gate */ 3347c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[num].dkl_cylno = i; 3357c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[num].dkl_nblk = j; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 3387c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_start = (daddr_t)(i * (nhead * nsect)); 3397c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_size = (long)j; 3407c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate /* 3437c478bd9Sstevel@tonic-gate * Install the p_tag and p_flag values for this partition 3447c478bd9Sstevel@tonic-gate */ 3457c478bd9Sstevel@tonic-gate assert(cur_parts->vtoc.v_version == V_VERSION); 3467c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_tag = (ushort_t)tag; 3477c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[num].p_flag = (ushort_t)flag; 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate /* 3527c478bd9Sstevel@tonic-gate * This routine picks to closest partition table which matches the 3537c478bd9Sstevel@tonic-gate * selected disk type. It is called each time the disk type is 3547c478bd9Sstevel@tonic-gate * changed. If no match is found, it uses the first element 3557c478bd9Sstevel@tonic-gate * of the partition table. If no table exists, a dummy is 3567c478bd9Sstevel@tonic-gate * created. 3577c478bd9Sstevel@tonic-gate */ 3587c478bd9Sstevel@tonic-gate int 3597c478bd9Sstevel@tonic-gate get_partition() 3607c478bd9Sstevel@tonic-gate { 3617c478bd9Sstevel@tonic-gate register struct partition_info *pptr; 3627c478bd9Sstevel@tonic-gate register struct partition_info *parts; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate /* 3657c478bd9Sstevel@tonic-gate * If there are no pre-defined maps for this disk type, it's 3667c478bd9Sstevel@tonic-gate * an error. 3677c478bd9Sstevel@tonic-gate */ 3687c478bd9Sstevel@tonic-gate parts = cur_dtype->dtype_plist; 3697c478bd9Sstevel@tonic-gate if (parts == NULL) { 3707c478bd9Sstevel@tonic-gate err_print("No defined partition tables.\n"); 3717c478bd9Sstevel@tonic-gate make_partition(); 3727c478bd9Sstevel@tonic-gate return (-1); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate /* 3757c478bd9Sstevel@tonic-gate * Loop through the pre-defined maps searching for one which match 3767c478bd9Sstevel@tonic-gate * disk type. If found copy it into unmamed partition. 3777c478bd9Sstevel@tonic-gate */ 3787c478bd9Sstevel@tonic-gate enter_critical(); 3797c478bd9Sstevel@tonic-gate for (pptr = parts; pptr != NULL; pptr = pptr->pinfo_next) { 3807c478bd9Sstevel@tonic-gate if (cur_dtype->dtype_asciilabel) { 3817c478bd9Sstevel@tonic-gate if (pptr->pinfo_name != NULL && strcmp(pptr->pinfo_name, 3827c478bd9Sstevel@tonic-gate cur_dtype->dtype_asciilabel) == 0) { 3837c478bd9Sstevel@tonic-gate /* 3847c478bd9Sstevel@tonic-gate * Set current partition and name it. 3857c478bd9Sstevel@tonic-gate */ 3867c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = pptr; 3877c478bd9Sstevel@tonic-gate cur_parts->pinfo_name = pptr->pinfo_name; 3887c478bd9Sstevel@tonic-gate exit_critical(); 3897c478bd9Sstevel@tonic-gate return (0); 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * If we couldn't find a match, take the first one. 3957c478bd9Sstevel@tonic-gate * Set current partition and name it. 3967c478bd9Sstevel@tonic-gate */ 3977c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = cur_dtype->dtype_plist; 3987c478bd9Sstevel@tonic-gate cur_parts->pinfo_name = parts->pinfo_name; 3997c478bd9Sstevel@tonic-gate exit_critical(); 4007c478bd9Sstevel@tonic-gate return (0); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * This routine creates a new partition map and sets it current. If there 4067c478bd9Sstevel@tonic-gate * was a current map, the new map starts out identical to it. Otherwise 4077c478bd9Sstevel@tonic-gate * the new map starts out all zeroes. 4087c478bd9Sstevel@tonic-gate */ 4097c478bd9Sstevel@tonic-gate void 4107c478bd9Sstevel@tonic-gate make_partition() 4117c478bd9Sstevel@tonic-gate { 4127c478bd9Sstevel@tonic-gate register struct partition_info *pptr, *parts; 4137c478bd9Sstevel@tonic-gate int i; 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate /* 4167c478bd9Sstevel@tonic-gate * Lock out interrupts so the lists don't get mangled. 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate enter_critical(); 4197c478bd9Sstevel@tonic-gate /* 4207c478bd9Sstevel@tonic-gate * Get space for for the new map and link it into the list 4217c478bd9Sstevel@tonic-gate * of maps for the current disk type. 4227c478bd9Sstevel@tonic-gate */ 4237c478bd9Sstevel@tonic-gate pptr = (struct partition_info *)zalloc(sizeof (struct partition_info)); 4247c478bd9Sstevel@tonic-gate parts = cur_dtype->dtype_plist; 4257c478bd9Sstevel@tonic-gate if (parts == NULL) { 4267c478bd9Sstevel@tonic-gate cur_dtype->dtype_plist = pptr; 4277c478bd9Sstevel@tonic-gate } else { 4287c478bd9Sstevel@tonic-gate while (parts->pinfo_next != NULL) { 4297c478bd9Sstevel@tonic-gate parts = parts->pinfo_next; 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate parts->pinfo_next = pptr; 4327c478bd9Sstevel@tonic-gate pptr->pinfo_next = NULL; 4337c478bd9Sstevel@tonic-gate } 4347c478bd9Sstevel@tonic-gate /* 4357c478bd9Sstevel@tonic-gate * If there was a current map, copy its values. 4367c478bd9Sstevel@tonic-gate */ 4377c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 4387c478bd9Sstevel@tonic-gate struct dk_gpt *map; 4397c478bd9Sstevel@tonic-gate int nparts; 4407c478bd9Sstevel@tonic-gate int size; 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate nparts = cur_parts->etoc->efi_nparts; 4437c478bd9Sstevel@tonic-gate size = sizeof (struct dk_part) * nparts + sizeof (struct dk_gpt); 4447c478bd9Sstevel@tonic-gate map = zalloc(size); 4457c478bd9Sstevel@tonic-gate (void) memcpy(map, cur_parts->etoc, size); 4467c478bd9Sstevel@tonic-gate pptr->etoc = map; 4477c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = pptr; 4487c478bd9Sstevel@tonic-gate exit_critical(); 4497c478bd9Sstevel@tonic-gate return; 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate if (cur_parts != NULL) { 4527c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 4537c478bd9Sstevel@tonic-gate pptr->pinfo_map[i] = cur_parts->pinfo_map[i]; 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate pptr->vtoc = cur_parts->vtoc; 4567c478bd9Sstevel@tonic-gate } else { 4577c478bd9Sstevel@tonic-gate /* 4587c478bd9Sstevel@tonic-gate * Otherwise set initial default vtoc values 4597c478bd9Sstevel@tonic-gate */ 4607c478bd9Sstevel@tonic-gate set_vtoc_defaults(pptr); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate /* 4647c478bd9Sstevel@tonic-gate * Make the new one current. 4657c478bd9Sstevel@tonic-gate */ 4667c478bd9Sstevel@tonic-gate cur_disk->disk_parts = cur_parts = pptr; 4677c478bd9Sstevel@tonic-gate exit_critical(); 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate /* 4727c478bd9Sstevel@tonic-gate * This routine deletes a partition map from the list of maps for 4737c478bd9Sstevel@tonic-gate * the given disk type. 4747c478bd9Sstevel@tonic-gate */ 4757c478bd9Sstevel@tonic-gate void 4767c478bd9Sstevel@tonic-gate delete_partition(struct partition_info *parts) 4777c478bd9Sstevel@tonic-gate { 4787c478bd9Sstevel@tonic-gate struct partition_info *pptr; 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate /* 4817c478bd9Sstevel@tonic-gate * If there isn't a current map, it's an error. 4827c478bd9Sstevel@tonic-gate */ 4837c478bd9Sstevel@tonic-gate if (cur_dtype->dtype_plist == NULL) { 4847c478bd9Sstevel@tonic-gate err_print("Error: unexpected null partition list.\n"); 4857c478bd9Sstevel@tonic-gate fullabort(); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate /* 4887c478bd9Sstevel@tonic-gate * Remove the map from the list. 4897c478bd9Sstevel@tonic-gate */ 4907c478bd9Sstevel@tonic-gate if (cur_dtype->dtype_plist == parts) 4917c478bd9Sstevel@tonic-gate cur_dtype->dtype_plist = parts->pinfo_next; 4927c478bd9Sstevel@tonic-gate else { 4937c478bd9Sstevel@tonic-gate for (pptr = cur_dtype->dtype_plist; pptr->pinfo_next != parts; 4947c478bd9Sstevel@tonic-gate pptr = pptr->pinfo_next) 4957c478bd9Sstevel@tonic-gate ; 4967c478bd9Sstevel@tonic-gate pptr->pinfo_next = parts->pinfo_next; 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate /* 4997c478bd9Sstevel@tonic-gate * Free the space it was using. 5007c478bd9Sstevel@tonic-gate */ 5017c478bd9Sstevel@tonic-gate destroy_data((char *)parts); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate /* 5067c478bd9Sstevel@tonic-gate * Set all partition vtoc fields to defaults 5077c478bd9Sstevel@tonic-gate */ 5087c478bd9Sstevel@tonic-gate void 5097c478bd9Sstevel@tonic-gate set_vtoc_defaults(struct partition_info *part) 5107c478bd9Sstevel@tonic-gate { 5117c478bd9Sstevel@tonic-gate int i; 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate bzero((caddr_t)&part->vtoc, sizeof (struct dk_vtoc)); 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate part->vtoc.v_version = V_VERSION; 5167c478bd9Sstevel@tonic-gate part->vtoc.v_nparts = NDKMAP; 5177c478bd9Sstevel@tonic-gate part->vtoc.v_sanity = VTOC_SANE; 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 5207c478bd9Sstevel@tonic-gate part->vtoc.v_part[i].p_tag = default_vtoc_map[i].p_tag; 5217c478bd9Sstevel@tonic-gate part->vtoc.v_part[i].p_flag = default_vtoc_map[i].p_flag; 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate } 524