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 5c92a0838Smishra * Common Development and Distribution License (the "License"). 6c92a0838Smishra * 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 to implement the partition menu commands. 287c478bd9Sstevel@tonic-gate */ 29*23a1cceaSRoger A. Faulkner #include <stdlib.h> 30*23a1cceaSRoger A. Faulkner #include <string.h> 317c478bd9Sstevel@tonic-gate #include "global.h" 327c478bd9Sstevel@tonic-gate #include "partition.h" 337c478bd9Sstevel@tonic-gate #include "menu_partition.h" 347c478bd9Sstevel@tonic-gate #include "menu_command.h" 357c478bd9Sstevel@tonic-gate #include "modify_partition.h" 363e1bd7a2Ssjelinek #include "checkdev.h" 377c478bd9Sstevel@tonic-gate #include "misc.h" 387c478bd9Sstevel@tonic-gate #include "label.h" 397c478bd9Sstevel@tonic-gate #include "auto_sense.h" 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #ifdef __STDC__ 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* Function prototypes for ANSI C Compilers */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate static void adj_cyl_offset(struct dk_map32 *map); 467c478bd9Sstevel@tonic-gate static int check_map(struct dk_map32 *map); 477c478bd9Sstevel@tonic-gate static void get_user_map(struct dk_map32 *map, int float_part); 487c478bd9Sstevel@tonic-gate static void get_user_map_efi(struct dk_gpt *map, int float_part); 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* Function prototypes for non-ANSI C Compilers */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate static void adj_cyl_offset(); 557c478bd9Sstevel@tonic-gate static int check_map(); 567c478bd9Sstevel@tonic-gate static void get_user_map(); 577c478bd9Sstevel@tonic-gate static void get_user_map_efi(); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static char *partn_list[] = { "0", "1", "2", "3", "4", "5", "6", "7", NULL }; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate static char *sel_list[] = { "0", "1", "2", "3", NULL }; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #define MBYTE (1024*1024) 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * Modify/Create a predefined partition table. 707c478bd9Sstevel@tonic-gate */ 717c478bd9Sstevel@tonic-gate int 727c478bd9Sstevel@tonic-gate p_modify() 737c478bd9Sstevel@tonic-gate { 747c478bd9Sstevel@tonic-gate struct partition_info tmp_pinfo[1]; 757c478bd9Sstevel@tonic-gate struct dk_map32 *map = tmp_pinfo->pinfo_map; 767c478bd9Sstevel@tonic-gate u_ioparam_t ioparam; 777c478bd9Sstevel@tonic-gate int inpt_dflt = 0; 787c478bd9Sstevel@tonic-gate int free_hog = -1; 797c478bd9Sstevel@tonic-gate int i; 807c478bd9Sstevel@tonic-gate char tmpstr[80]; 817c478bd9Sstevel@tonic-gate char tmpstr2[300]; 827c478bd9Sstevel@tonic-gate int sel_type = 0; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * There must be a current disk type (and therefore a current disk). 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate if (cur_dtype == NULL) { 887c478bd9Sstevel@tonic-gate err_print("Current Disk Type is not set.\n"); 897c478bd9Sstevel@tonic-gate return (-1); 907c478bd9Sstevel@tonic-gate } 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate /* 937c478bd9Sstevel@tonic-gate * check if there exists a partition table for the disk. 947c478bd9Sstevel@tonic-gate */ 957c478bd9Sstevel@tonic-gate if (cur_parts == NULL) { 967c478bd9Sstevel@tonic-gate err_print("Current Disk has no partition table.\n"); 977c478bd9Sstevel@tonic-gate return (-1); 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /* 1027c478bd9Sstevel@tonic-gate * If the disk has mounted partitions, cannot modify 1037c478bd9Sstevel@tonic-gate */ 104342440ecSPrasad Singamsetty if (checkmount((diskaddr_t)-1, (diskaddr_t)-1)) { 1057c478bd9Sstevel@tonic-gate err_print( 1067c478bd9Sstevel@tonic-gate "Cannot modify disk partitions while it has mounted partitions.\n\n"); 1077c478bd9Sstevel@tonic-gate return (-1); 1087c478bd9Sstevel@tonic-gate } 109c92a0838Smishra 1107c478bd9Sstevel@tonic-gate /* 1117c478bd9Sstevel@tonic-gate * If the disk has partitions currently being used for 1127c478bd9Sstevel@tonic-gate * swapping, cannot modify 1137c478bd9Sstevel@tonic-gate */ 114342440ecSPrasad Singamsetty if (checkswap((diskaddr_t)-1, (diskaddr_t)-1)) { 1157c478bd9Sstevel@tonic-gate err_print( 1167c478bd9Sstevel@tonic-gate "Cannot modify disk partitions while it is \ 1177c478bd9Sstevel@tonic-gate currently being used for swapping.\n"); 1187c478bd9Sstevel@tonic-gate return (-1); 1197c478bd9Sstevel@tonic-gate } 120c92a0838Smishra 121c92a0838Smishra /* 122c92a0838Smishra * Check to see if any partitions used for svm, vxvm, ZFS zpool 123c92a0838Smishra * or live upgrade are on the disk. 124c92a0838Smishra */ 125c92a0838Smishra if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, 126c92a0838Smishra (diskaddr_t)-1, 0, 0)) { 127c92a0838Smishra err_print("Cannot modify disk partition when " 128c92a0838Smishra "partitions are in use as described.\n"); 129c92a0838Smishra return (-1); 130c92a0838Smishra } 131c92a0838Smishra 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * prompt user for a partition table base 1347c478bd9Sstevel@tonic-gate */ 1357c478bd9Sstevel@tonic-gate if (cur_parts->pinfo_name != NULL) { 1367c478bd9Sstevel@tonic-gate (void) snprintf(tmpstr, sizeof (tmpstr), 1377c478bd9Sstevel@tonic-gate "\t0. Current partition table (%s)", 1387c478bd9Sstevel@tonic-gate cur_parts->pinfo_name); 1397c478bd9Sstevel@tonic-gate } else { 1407c478bd9Sstevel@tonic-gate (void) sprintf(tmpstr, 1417c478bd9Sstevel@tonic-gate "\t0. Current partition table (unnamed)"); 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate (void) snprintf(tmpstr2, sizeof (tmpstr2), 1457c478bd9Sstevel@tonic-gate "Select partitioning base:\n%s\n" 1467c478bd9Sstevel@tonic-gate "\t1. All Free Hog\n" 1477c478bd9Sstevel@tonic-gate "Choose base (enter number) ", 1487c478bd9Sstevel@tonic-gate tmpstr); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate ioparam.io_charlist = sel_list; 1517c478bd9Sstevel@tonic-gate sel_type = input(FIO_MSTR, tmpstr2, '?', &ioparam, 1527c478bd9Sstevel@tonic-gate &sel_type, DATA_INPUT); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate switch (cur_label) { 1557c478bd9Sstevel@tonic-gate case L_TYPE_SOLARIS: 1567c478bd9Sstevel@tonic-gate if (sel_type == 0) { 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * Check for invalid parameters but do 1597c478bd9Sstevel@tonic-gate * not modify the table. 1607c478bd9Sstevel@tonic-gate */ 1617c478bd9Sstevel@tonic-gate if (check_map(cur_parts->pinfo_map)) { 1627c478bd9Sstevel@tonic-gate err_print("\ 1637c478bd9Sstevel@tonic-gate Warning: Fix, or select a different partition table.\n"); 1647c478bd9Sstevel@tonic-gate return (0); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * Create partition map from existing map 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate tmp_pinfo->vtoc = cur_parts->vtoc; 1707c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 1717c478bd9Sstevel@tonic-gate map[i].dkl_nblk = cur_parts->pinfo_map[i].dkl_nblk; 1727c478bd9Sstevel@tonic-gate map[i].dkl_cylno = cur_parts->pinfo_map[i].dkl_cylno; 1737c478bd9Sstevel@tonic-gate } 1747c478bd9Sstevel@tonic-gate } else { 1757c478bd9Sstevel@tonic-gate /* 1767c478bd9Sstevel@tonic-gate * Make an empty partition map, with all the space 1777c478bd9Sstevel@tonic-gate * in the c partition. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate set_vtoc_defaults(tmp_pinfo); 1807c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 1817c478bd9Sstevel@tonic-gate map[i].dkl_nblk = 0; 1827c478bd9Sstevel@tonic-gate map[i].dkl_cylno = 0; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate map[C_PARTITION].dkl_nblk = ncyl * spc(); 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate #if defined(i386) 1877c478bd9Sstevel@tonic-gate /* 1887c478bd9Sstevel@tonic-gate * Adjust for the boot and possibly alternates partitions 1897c478bd9Sstevel@tonic-gate */ 1907c478bd9Sstevel@tonic-gate map[I_PARTITION].dkl_nblk = spc(); 1917c478bd9Sstevel@tonic-gate map[I_PARTITION].dkl_cylno = 0; 1927c478bd9Sstevel@tonic-gate if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) { 1937c478bd9Sstevel@tonic-gate map[J_PARTITION].dkl_nblk = 2 * spc(); 1947c478bd9Sstevel@tonic-gate map[J_PARTITION].dkl_cylno = spc() / spc(); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate break; 1997c478bd9Sstevel@tonic-gate case L_TYPE_EFI: 2007c478bd9Sstevel@tonic-gate if (sel_type == 1) { 2017c478bd9Sstevel@tonic-gate for (i = 0; i < cur_parts->etoc->efi_nparts; i++) { 2027c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[i].p_start = 0; 2037c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_parts[i].p_size = 0; 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate break; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate fmt_print("\n"); 2107c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_SOLARIS) { 2117c478bd9Sstevel@tonic-gate print_map(tmp_pinfo); 2127c478bd9Sstevel@tonic-gate } else { 2137c478bd9Sstevel@tonic-gate print_map(cur_parts); 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate ioparam.io_charlist = confirm_list; 2177c478bd9Sstevel@tonic-gate if (input(FIO_MSTR, 2187c478bd9Sstevel@tonic-gate "Do you wish to continue creating a new partition\ntable based on above table", 2197c478bd9Sstevel@tonic-gate '?', &ioparam, &inpt_dflt, DATA_INPUT)) { 2207c478bd9Sstevel@tonic-gate return (0); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate /* 2247c478bd9Sstevel@tonic-gate * get Free Hog partition 2257c478bd9Sstevel@tonic-gate */ 2267c478bd9Sstevel@tonic-gate inpt_dflt = 1; 2277c478bd9Sstevel@tonic-gate while ((free_hog < 0) && (cur_label == L_TYPE_SOLARIS)) { 2287c478bd9Sstevel@tonic-gate free_hog = G_PARTITION; /* default to g partition */ 2297c478bd9Sstevel@tonic-gate ioparam.io_charlist = partn_list; 2307c478bd9Sstevel@tonic-gate free_hog = input(FIO_MSTR, "Free Hog partition", '?', 2317c478bd9Sstevel@tonic-gate &ioparam, &free_hog, DATA_INPUT); 2327c478bd9Sstevel@tonic-gate /* disallow c partition */ 2337c478bd9Sstevel@tonic-gate if (free_hog == C_PARTITION) { 2347c478bd9Sstevel@tonic-gate fmt_print("'%c' cannot be the 'Free Hog' partition.\n", 2357c478bd9Sstevel@tonic-gate C_PARTITION + PARTITION_BASE); 2367c478bd9Sstevel@tonic-gate free_hog = -1; 2377c478bd9Sstevel@tonic-gate continue; 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate /* 2407c478bd9Sstevel@tonic-gate * If user selected all float set the 2417c478bd9Sstevel@tonic-gate * float to be the whole disk. 2427c478bd9Sstevel@tonic-gate */ 2437c478bd9Sstevel@tonic-gate if (sel_type == 1) { 2447c478bd9Sstevel@tonic-gate map[free_hog].dkl_nblk = map[C_PARTITION].dkl_nblk; 2457c478bd9Sstevel@tonic-gate #if defined(i386) 2467c478bd9Sstevel@tonic-gate map[free_hog].dkl_nblk -= map[I_PARTITION].dkl_nblk; 2477c478bd9Sstevel@tonic-gate if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) { 2487c478bd9Sstevel@tonic-gate map[free_hog].dkl_nblk -= 2497c478bd9Sstevel@tonic-gate map[J_PARTITION].dkl_nblk; 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 2527c478bd9Sstevel@tonic-gate break; 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate /* 2557c478bd9Sstevel@tonic-gate * Warn the user if there is no free space in 2567c478bd9Sstevel@tonic-gate * the float partition. 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate if (map[free_hog].dkl_nblk == 0) { 2597c478bd9Sstevel@tonic-gate err_print("\ 2607c478bd9Sstevel@tonic-gate Warning: No space available from Free Hog partition.\n"); 2617c478bd9Sstevel@tonic-gate ioparam.io_charlist = confirm_list; 2627c478bd9Sstevel@tonic-gate if (input(FIO_MSTR, "Continue", '?', 2637c478bd9Sstevel@tonic-gate &ioparam, &inpt_dflt, DATA_INPUT)) { 2647c478bd9Sstevel@tonic-gate free_hog = -1; 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate inpt_dflt = 0; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 2717c478bd9Sstevel@tonic-gate free_hog = G_PARTITION; /* default to g partition */ 2727c478bd9Sstevel@tonic-gate ioparam.io_charlist = partn_list; 2737c478bd9Sstevel@tonic-gate free_hog = input(FIO_MSTR, "Free Hog partition", '?', 2747c478bd9Sstevel@tonic-gate &ioparam, &free_hog, DATA_INPUT); 2757c478bd9Sstevel@tonic-gate /* disallow c partition */ 2767c478bd9Sstevel@tonic-gate if (free_hog == C_PARTITION) { 2777c478bd9Sstevel@tonic-gate fmt_print("'%c' cannot be the 'Free Hog' partition.\n", 2787c478bd9Sstevel@tonic-gate C_PARTITION + PARTITION_BASE); 2797c478bd9Sstevel@tonic-gate return (-1); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate get_user_map_efi(cur_parts->etoc, free_hog); 2827c478bd9Sstevel@tonic-gate print_map(cur_parts); 2837c478bd9Sstevel@tonic-gate if (check("Ready to label disk, continue")) { 2847c478bd9Sstevel@tonic-gate return (-1); 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate fmt_print("\n"); 2877c478bd9Sstevel@tonic-gate if (write_label()) { 2887c478bd9Sstevel@tonic-gate err_print("Writing label failed\n"); 2897c478bd9Sstevel@tonic-gate return (-1); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate return (0); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate /* 2947c478bd9Sstevel@tonic-gate * get user modified partition table 2957c478bd9Sstevel@tonic-gate */ 2967c478bd9Sstevel@tonic-gate get_user_map(map, free_hog); 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* 2997c478bd9Sstevel@tonic-gate * Update cylno offsets 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate adj_cyl_offset(map); 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate fmt_print("\n"); 3047c478bd9Sstevel@tonic-gate print_map(tmp_pinfo); 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate ioparam.io_charlist = confirm_list; 3077c478bd9Sstevel@tonic-gate if (input(FIO_MSTR, "\ 3087c478bd9Sstevel@tonic-gate Okay to make this the current partition table", '?', 3097c478bd9Sstevel@tonic-gate &ioparam, &inpt_dflt, DATA_INPUT)) { 3107c478bd9Sstevel@tonic-gate return (0); 3117c478bd9Sstevel@tonic-gate } else { 3127c478bd9Sstevel@tonic-gate make_partition(); 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * Update new partition map 3157c478bd9Sstevel@tonic-gate */ 3167c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 3177c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[i].dkl_nblk = map[i].dkl_nblk; 3187c478bd9Sstevel@tonic-gate cur_parts->pinfo_map[i].dkl_cylno = map[i].dkl_cylno; 3197c478bd9Sstevel@tonic-gate #ifdef i386 3207c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[i].p_start = 3217c478bd9Sstevel@tonic-gate map[i].dkl_cylno * nhead * nsect; 3227c478bd9Sstevel@tonic-gate cur_parts->vtoc.v_part[i].p_size = 3237c478bd9Sstevel@tonic-gate map[i].dkl_nblk; 3247c478bd9Sstevel@tonic-gate #endif 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate (void) p_name(); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * Label the disk now 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate if (check("Ready to label disk, continue")) { 3327c478bd9Sstevel@tonic-gate return (-1); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate fmt_print("\n"); 3357c478bd9Sstevel@tonic-gate if (write_label()) { 3367c478bd9Sstevel@tonic-gate err_print("Writing label failed\n"); 3377c478bd9Sstevel@tonic-gate return (-1); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate return (0); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate /* 3467c478bd9Sstevel@tonic-gate * Adjust cylinder offsets 3477c478bd9Sstevel@tonic-gate */ 3487c478bd9Sstevel@tonic-gate static void 3497c478bd9Sstevel@tonic-gate adj_cyl_offset(map) 3507c478bd9Sstevel@tonic-gate struct dk_map32 *map; 3517c478bd9Sstevel@tonic-gate { 3527c478bd9Sstevel@tonic-gate int i; 3537c478bd9Sstevel@tonic-gate int cyloffset = 0; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate /* 3577c478bd9Sstevel@tonic-gate * Update cylno offsets 3587c478bd9Sstevel@tonic-gate */ 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 3617c478bd9Sstevel@tonic-gate /* 3627c478bd9Sstevel@tonic-gate * Correct cylinder allocation for having the boot and alternates 3637c478bd9Sstevel@tonic-gate * slice in the beginning of the disk 3647c478bd9Sstevel@tonic-gate */ 3657c478bd9Sstevel@tonic-gate for (i = NDKMAP/2; i < NDKMAP; i++) { 3667c478bd9Sstevel@tonic-gate if (i != C_PARTITION && map[i].dkl_nblk) { 3677c478bd9Sstevel@tonic-gate map[i].dkl_cylno = cyloffset; 3687c478bd9Sstevel@tonic-gate cyloffset += (map[i].dkl_nblk + (spc()-1))/spc(); 3697c478bd9Sstevel@tonic-gate } else if (map[i].dkl_nblk == 0) { 3707c478bd9Sstevel@tonic-gate map[i].dkl_cylno = 0; 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP/2; i++) { 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate #else /* !defined(_SUNOS_VTOC_16) */ 3767c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 3777c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate if (i != C_PARTITION && map[i].dkl_nblk) { 3807c478bd9Sstevel@tonic-gate map[i].dkl_cylno = cyloffset; 3817c478bd9Sstevel@tonic-gate cyloffset += (map[i].dkl_nblk + (spc()-1))/spc(); 3827c478bd9Sstevel@tonic-gate } else if (map[i].dkl_nblk == 0) { 3837c478bd9Sstevel@tonic-gate map[i].dkl_cylno = 0; 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* 3907c478bd9Sstevel@tonic-gate * Check partition table 3917c478bd9Sstevel@tonic-gate */ 3927c478bd9Sstevel@tonic-gate static int 3937c478bd9Sstevel@tonic-gate check_map(map) 3947c478bd9Sstevel@tonic-gate struct dk_map32 *map; 3957c478bd9Sstevel@tonic-gate { 3967c478bd9Sstevel@tonic-gate int i; 3977c478bd9Sstevel@tonic-gate int cyloffset = 0; 398342440ecSPrasad Singamsetty blkaddr32_t tot_blks = 0; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate #ifdef i386 4017c478bd9Sstevel@tonic-gate /* 4027c478bd9Sstevel@tonic-gate * On x86, we must account for the boot and alternates 4037c478bd9Sstevel@tonic-gate */ 4047c478bd9Sstevel@tonic-gate cyloffset = map[0].dkl_cylno; 4057c478bd9Sstevel@tonic-gate tot_blks = map[0].dkl_nblk; 4067c478bd9Sstevel@tonic-gate #endif 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate /* 4097c478bd9Sstevel@tonic-gate * Do some checks for invalid parameters but do 4107c478bd9Sstevel@tonic-gate * not modify the table. 4117c478bd9Sstevel@tonic-gate */ 4127c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 413342440ecSPrasad Singamsetty if (map[i].dkl_cylno > (blkaddr32_t)ncyl-1) { 4147c478bd9Sstevel@tonic-gate err_print("\ 4157c478bd9Sstevel@tonic-gate Warning: Partition %c starting cylinder %d is out of range.\n", 4167c478bd9Sstevel@tonic-gate (PARTITION_BASE+i), map[i].dkl_cylno); 4177c478bd9Sstevel@tonic-gate return (-1); 4187c478bd9Sstevel@tonic-gate } 419342440ecSPrasad Singamsetty if (map[i].dkl_nblk > 420342440ecSPrasad Singamsetty (blkaddr32_t)(ncyl - map[i].dkl_cylno) * spc()) { 4217c478bd9Sstevel@tonic-gate err_print("\ 422342440ecSPrasad Singamsetty Warning: Partition %c, specified # of blocks, %u, is out of range.\n", 4237c478bd9Sstevel@tonic-gate (PARTITION_BASE+i), map[i].dkl_nblk); 4247c478bd9Sstevel@tonic-gate return (-1); 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate if (i != C_PARTITION && map[i].dkl_nblk) { 4277c478bd9Sstevel@tonic-gate #ifdef i386 4287c478bd9Sstevel@tonic-gate if (i == I_PARTITION || i == J_PARTITION) 4297c478bd9Sstevel@tonic-gate continue; 4307c478bd9Sstevel@tonic-gate #endif 4317c478bd9Sstevel@tonic-gate if (map[i].dkl_cylno < cyloffset) { 4327c478bd9Sstevel@tonic-gate err_print( 4337c478bd9Sstevel@tonic-gate "Warning: Overlapping partition (%c) in table.\n", PARTITION_BASE+i); 4347c478bd9Sstevel@tonic-gate return (-1); 4357c478bd9Sstevel@tonic-gate } else if (map[i].dkl_cylno > cyloffset) { 4367c478bd9Sstevel@tonic-gate err_print( 4377c478bd9Sstevel@tonic-gate "Warning: Non-contiguous partition (%c) in table.\n", PARTITION_BASE+i); 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate cyloffset += (map[i].dkl_nblk + (spc()-1))/spc(); 4407c478bd9Sstevel@tonic-gate tot_blks = map[i].dkl_nblk; 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate if (tot_blks > map[C_PARTITION].dkl_nblk) { 4447c478bd9Sstevel@tonic-gate err_print("\ 4457c478bd9Sstevel@tonic-gate Warning: Total blocks used is greater than number of blocks in '%c'\n\ 4467c478bd9Sstevel@tonic-gate \tpartition.\n", C_PARTITION + PARTITION_BASE); 4477c478bd9Sstevel@tonic-gate return (-1); 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate return (0); 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate /* 4557c478bd9Sstevel@tonic-gate * get user defined partitions 4567c478bd9Sstevel@tonic-gate */ 4577c478bd9Sstevel@tonic-gate static void 4587c478bd9Sstevel@tonic-gate get_user_map(map, float_part) 4597c478bd9Sstevel@tonic-gate struct dk_map32 *map; 4607c478bd9Sstevel@tonic-gate int float_part; 4617c478bd9Sstevel@tonic-gate { 4627c478bd9Sstevel@tonic-gate int i; 463342440ecSPrasad Singamsetty blkaddr32_t newsize; 464342440ecSPrasad Singamsetty blkaddr32_t deflt; 4657c478bd9Sstevel@tonic-gate char tmpstr[80]; 4667c478bd9Sstevel@tonic-gate u_ioparam_t ioparam; 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate /* 4697c478bd9Sstevel@tonic-gate * Get partition sizes 4707c478bd9Sstevel@tonic-gate */ 4717c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 4727c478bd9Sstevel@tonic-gate if (partn_list[i] == NULL) 4737c478bd9Sstevel@tonic-gate break; 4747c478bd9Sstevel@tonic-gate if ((i == C_PARTITION) || (i == float_part)) 4757c478bd9Sstevel@tonic-gate continue; 4767c478bd9Sstevel@tonic-gate else { 4777c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = 0; 4787c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = map[i].dkl_nblk + 4797c478bd9Sstevel@tonic-gate map[float_part].dkl_nblk; 4807c478bd9Sstevel@tonic-gate deflt = map[i].dkl_nblk; 4817c478bd9Sstevel@tonic-gate if (ioparam.io_bounds.upper == 0) { 4827c478bd9Sstevel@tonic-gate err_print("\ 4837c478bd9Sstevel@tonic-gate Warning: no space available for '%s' from Free Hog partition\n", 4847c478bd9Sstevel@tonic-gate partn_list[i]); 4857c478bd9Sstevel@tonic-gate continue; 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate (void) snprintf(tmpstr, sizeof (tmpstr), 4887c478bd9Sstevel@tonic-gate "Enter size of partition '%s' ", 4897c478bd9Sstevel@tonic-gate partn_list[i]); 490342440ecSPrasad Singamsetty newsize = (blkaddr32_t)input(FIO_CYL, tmpstr, ':', 491342440ecSPrasad Singamsetty &ioparam, (int *)&deflt, DATA_INPUT); 4927c478bd9Sstevel@tonic-gate map[float_part].dkl_nblk -= (newsize - map[i].dkl_nblk); 4937c478bd9Sstevel@tonic-gate map[i].dkl_nblk = newsize; 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate static struct partition_info * 4997c478bd9Sstevel@tonic-gate build_partition(tptr) 5007c478bd9Sstevel@tonic-gate struct disk_type *tptr; 5017c478bd9Sstevel@tonic-gate { 5027c478bd9Sstevel@tonic-gate struct partition_info *part; 5037c478bd9Sstevel@tonic-gate struct dk_label *label; 5047c478bd9Sstevel@tonic-gate int i; 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate #ifdef DEBUG 5077c478bd9Sstevel@tonic-gate fmt_print("Creating Default Partition for the disk \n"); 5087c478bd9Sstevel@tonic-gate #endif 5097c478bd9Sstevel@tonic-gate /* 5107c478bd9Sstevel@tonic-gate * construct a label and pass it on to 5117c478bd9Sstevel@tonic-gate * build_default_partition() which builds the 5127c478bd9Sstevel@tonic-gate * default partition list. 5137c478bd9Sstevel@tonic-gate */ 5147c478bd9Sstevel@tonic-gate label = zalloc(sizeof (struct dk_label)); 5157c478bd9Sstevel@tonic-gate label->dkl_pcyl = tptr->dtype_pcyl; 5167c478bd9Sstevel@tonic-gate label->dkl_ncyl = tptr->dtype_ncyl; 5177c478bd9Sstevel@tonic-gate label->dkl_acyl = tptr->dtype_acyl; 5187c478bd9Sstevel@tonic-gate label->dkl_nhead = tptr->dtype_nhead; 5197c478bd9Sstevel@tonic-gate label->dkl_nsect = tptr->dtype_nsect; 5207c478bd9Sstevel@tonic-gate label->dkl_apc = apc; 5217c478bd9Sstevel@tonic-gate label->dkl_intrlv = 1; 5227c478bd9Sstevel@tonic-gate label->dkl_rpm = tptr->dtype_rpm; 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate if (!build_default_partition(label, cur_ctype->ctype_ctype)) 5257c478bd9Sstevel@tonic-gate return (NULL); 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate part = (struct partition_info *) 5287c478bd9Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 5297c478bd9Sstevel@tonic-gate part->pinfo_name = alloc_string(tptr->dtype_asciilabel); 5307c478bd9Sstevel@tonic-gate /* 5317c478bd9Sstevel@tonic-gate * Fill in the partition info from the label 5327c478bd9Sstevel@tonic-gate */ 5337c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 5347c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 5357c478bd9Sstevel@tonic-gate part->pinfo_map[i] = label->dkl_map[i]; 5367c478bd9Sstevel@tonic-gate #else 5377c478bd9Sstevel@tonic-gate part->pinfo_map[i].dkl_cylno = 5387c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_start / 539342440ecSPrasad Singamsetty (blkaddr32_t)(tptr->dtype_nhead * tptr->dtype_nsect - apc); 5407c478bd9Sstevel@tonic-gate part->pinfo_map[i].dkl_nblk = 5417c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_size; 5427c478bd9Sstevel@tonic-gate #endif /* ifdefined(_SUNOS_VTOC_8) */ 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate part->vtoc = label->dkl_vtoc; 5457c478bd9Sstevel@tonic-gate return (part); 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate /* 5497c478bd9Sstevel@tonic-gate * build new partition table for given disk type 5507c478bd9Sstevel@tonic-gate */ 5517c478bd9Sstevel@tonic-gate static void 5527c478bd9Sstevel@tonic-gate get_user_map_efi(map, float_part) 5537c478bd9Sstevel@tonic-gate struct dk_gpt *map; 5547c478bd9Sstevel@tonic-gate int float_part; 5557c478bd9Sstevel@tonic-gate { 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate int i; 5587c478bd9Sstevel@tonic-gate efi_deflt_t efi_deflt; 5597c478bd9Sstevel@tonic-gate u_ioparam_t ioparam; 5607c478bd9Sstevel@tonic-gate char tmpstr[80]; 5617c478bd9Sstevel@tonic-gate uint64_t i64; 5627c478bd9Sstevel@tonic-gate uint64_t start_lba = 34; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate for (i = 0; i < map->efi_nparts - 1; i++) { 5657c478bd9Sstevel@tonic-gate if (i == float_part) 5667c478bd9Sstevel@tonic-gate continue; 5677c478bd9Sstevel@tonic-gate else { 5687c478bd9Sstevel@tonic-gate ioparam.io_bounds.lower = start_lba; 5697c478bd9Sstevel@tonic-gate ioparam.io_bounds.upper = map->efi_last_u_lba; 5707c478bd9Sstevel@tonic-gate efi_deflt.start_sector = ioparam.io_bounds.lower; 5717c478bd9Sstevel@tonic-gate efi_deflt.end_sector = map->efi_parts[i].p_size; 5727c478bd9Sstevel@tonic-gate (void) sprintf(tmpstr, 5737c478bd9Sstevel@tonic-gate "Enter size of partition %d ", i); 5747c478bd9Sstevel@tonic-gate i64 = input(FIO_EFI, tmpstr, ':', 5757c478bd9Sstevel@tonic-gate &ioparam, (int *)&efi_deflt, DATA_INPUT); 5767c478bd9Sstevel@tonic-gate if (i64 == 0) { 5777c478bd9Sstevel@tonic-gate map->efi_parts[i].p_tag = V_UNASSIGNED; 5787c478bd9Sstevel@tonic-gate } else if ((i64 != 0) && (map->efi_parts[i].p_tag == 5797c478bd9Sstevel@tonic-gate V_UNASSIGNED)) { 5807c478bd9Sstevel@tonic-gate map->efi_parts[i].p_tag = V_USR; 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate if (i64 == 0) { 5837c478bd9Sstevel@tonic-gate map->efi_parts[i].p_start = 0; 5847c478bd9Sstevel@tonic-gate } else { 5857c478bd9Sstevel@tonic-gate map->efi_parts[i].p_start = start_lba; 5867c478bd9Sstevel@tonic-gate } 5877c478bd9Sstevel@tonic-gate map->efi_parts[i].p_size = i64; 5887c478bd9Sstevel@tonic-gate start_lba += i64; 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate } 5917c478bd9Sstevel@tonic-gate map->efi_parts[float_part].p_start = start_lba; 5927c478bd9Sstevel@tonic-gate map->efi_parts[float_part].p_size = map->efi_last_u_lba - 5937c478bd9Sstevel@tonic-gate start_lba - (1024 * 16); 5947c478bd9Sstevel@tonic-gate map->efi_parts[float_part].p_tag = V_USR; 5957c478bd9Sstevel@tonic-gate if (map->efi_parts[float_part].p_size == UINT_MAX64) { 5967c478bd9Sstevel@tonic-gate map->efi_parts[float_part].p_size = 0; 5977c478bd9Sstevel@tonic-gate map->efi_parts[float_part].p_start = 0; 5987c478bd9Sstevel@tonic-gate map->efi_parts[float_part].p_tag = V_UNASSIGNED; 5997c478bd9Sstevel@tonic-gate fmt_print("Warning: No space left for HOG\n"); 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate for (i = 0; i < map->efi_nparts; i++) { 6037c478bd9Sstevel@tonic-gate if (map->efi_parts[i].p_tag == V_RESERVED) { 6047c478bd9Sstevel@tonic-gate map->efi_parts[i].p_start = map->efi_last_u_lba - 6057c478bd9Sstevel@tonic-gate (1024 * 16); 6067c478bd9Sstevel@tonic-gate map->efi_parts[i].p_size = (1024 * 16); 6077c478bd9Sstevel@tonic-gate break; 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate void 6147c478bd9Sstevel@tonic-gate new_partitiontable(tptr, oldtptr) 6157c478bd9Sstevel@tonic-gate struct disk_type *tptr, *oldtptr; 6167c478bd9Sstevel@tonic-gate { 6177c478bd9Sstevel@tonic-gate struct partition_info *part; 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate /* 6207c478bd9Sstevel@tonic-gate * check if disk geometry has changed , if so add new 6217c478bd9Sstevel@tonic-gate * partition table else copy the old partition table.(best guess). 6227c478bd9Sstevel@tonic-gate */ 6237c478bd9Sstevel@tonic-gate if ((oldtptr != NULL) && 6247c478bd9Sstevel@tonic-gate (tptr->dtype_ncyl == oldtptr->dtype_ncyl) && 6257c478bd9Sstevel@tonic-gate (tptr->dtype_nhead == oldtptr->dtype_nhead) && 6267c478bd9Sstevel@tonic-gate (tptr->dtype_nsect == oldtptr->dtype_nsect)) { 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate part = (struct partition_info *) 6297c478bd9Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 6307c478bd9Sstevel@tonic-gate bcopy((char *)cur_parts, (char *)part, 6317c478bd9Sstevel@tonic-gate sizeof (struct partition_info)); 6327c478bd9Sstevel@tonic-gate part->pinfo_next = tptr->dtype_plist; 6337c478bd9Sstevel@tonic-gate tptr->dtype_plist = part; 6347c478bd9Sstevel@tonic-gate } else { 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate #ifdef DEBUG 6377c478bd9Sstevel@tonic-gate if (cur_parts != NULL) { 6387c478bd9Sstevel@tonic-gate fmt_print("Warning: Partition Table is set"); 6397c478bd9Sstevel@tonic-gate fmt_print("to default partition table. \n"); 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate #endif 6427c478bd9Sstevel@tonic-gate if (tptr->dtype_plist == NULL) { 6437c478bd9Sstevel@tonic-gate part = (struct partition_info *)build_partition(tptr); 6447c478bd9Sstevel@tonic-gate if (part != NULL) { 6457c478bd9Sstevel@tonic-gate part->pinfo_next = tptr->dtype_plist; 6467c478bd9Sstevel@tonic-gate tptr->dtype_plist = part; 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate } 651