xref: /onnv-gate/usr/src/cmd/format/modify_partition.c (revision 13093:48f2dbca79a2)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55421Smishra  * Common Development and Distribution License (the "License").
65421Smishra  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*13093SRoger.Faulkner@Oracle.COM 
220Sstevel@tonic-gate /*
23*13093SRoger.Faulkner@Oracle.COM  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * This file contains functions to implement the partition menu commands.
280Sstevel@tonic-gate  */
29*13093SRoger.Faulkner@Oracle.COM #include <stdlib.h>
30*13093SRoger.Faulkner@Oracle.COM #include <string.h>
310Sstevel@tonic-gate #include "global.h"
320Sstevel@tonic-gate #include "partition.h"
330Sstevel@tonic-gate #include "menu_partition.h"
340Sstevel@tonic-gate #include "menu_command.h"
350Sstevel@tonic-gate #include "modify_partition.h"
36767Ssjelinek #include "checkdev.h"
370Sstevel@tonic-gate #include "misc.h"
380Sstevel@tonic-gate #include "label.h"
390Sstevel@tonic-gate #include "auto_sense.h"
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #ifdef __STDC__
420Sstevel@tonic-gate 
430Sstevel@tonic-gate /* Function prototypes for ANSI C Compilers */
440Sstevel@tonic-gate 
450Sstevel@tonic-gate static void	adj_cyl_offset(struct dk_map32 *map);
460Sstevel@tonic-gate static int	check_map(struct dk_map32 *map);
470Sstevel@tonic-gate static void	get_user_map(struct dk_map32 *map, int float_part);
480Sstevel@tonic-gate static void	get_user_map_efi(struct dk_gpt *map, int float_part);
490Sstevel@tonic-gate 
500Sstevel@tonic-gate #else	/* __STDC__ */
510Sstevel@tonic-gate 
520Sstevel@tonic-gate /* Function prototypes for non-ANSI C Compilers */
530Sstevel@tonic-gate 
540Sstevel@tonic-gate static void	adj_cyl_offset();
550Sstevel@tonic-gate static int	check_map();
560Sstevel@tonic-gate static void	get_user_map();
570Sstevel@tonic-gate static void	get_user_map_efi();
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #endif	/* __STDC__ */
600Sstevel@tonic-gate 
610Sstevel@tonic-gate static char *partn_list[] = { "0", "1", "2", "3", "4", "5", "6", "7", NULL };
620Sstevel@tonic-gate 
630Sstevel@tonic-gate static char *sel_list[] = { "0", "1", "2", "3", NULL };
640Sstevel@tonic-gate 
650Sstevel@tonic-gate #define	MBYTE	(1024*1024)
660Sstevel@tonic-gate 
670Sstevel@tonic-gate 
680Sstevel@tonic-gate /*
690Sstevel@tonic-gate  * Modify/Create a predefined partition table.
700Sstevel@tonic-gate  */
710Sstevel@tonic-gate int
p_modify()720Sstevel@tonic-gate p_modify()
730Sstevel@tonic-gate {
740Sstevel@tonic-gate 	struct	partition_info	tmp_pinfo[1];
750Sstevel@tonic-gate 	struct	dk_map32	*map = tmp_pinfo->pinfo_map;
760Sstevel@tonic-gate 	u_ioparam_t		ioparam;
770Sstevel@tonic-gate 	int			inpt_dflt = 0;
780Sstevel@tonic-gate 	int			free_hog = -1;
790Sstevel@tonic-gate 	int			i;
800Sstevel@tonic-gate 	char			tmpstr[80];
810Sstevel@tonic-gate 	char			tmpstr2[300];
820Sstevel@tonic-gate 	int			sel_type = 0;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	/*
850Sstevel@tonic-gate 	 * There must be a current disk type (and therefore a current disk).
860Sstevel@tonic-gate 	 */
870Sstevel@tonic-gate 	if (cur_dtype == NULL) {
880Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
890Sstevel@tonic-gate 		return (-1);
900Sstevel@tonic-gate 	}
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	/*
930Sstevel@tonic-gate 	 * check if there exists a partition table for the disk.
940Sstevel@tonic-gate 	 */
950Sstevel@tonic-gate 	if (cur_parts == NULL) {
960Sstevel@tonic-gate 		err_print("Current Disk has no partition table.\n");
970Sstevel@tonic-gate 		return (-1);
980Sstevel@tonic-gate 	}
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	/*
1020Sstevel@tonic-gate 	 * If the disk has mounted partitions, cannot modify
1030Sstevel@tonic-gate 	 */
1047563SPrasad.Singamsetty@Sun.COM 	if (checkmount((diskaddr_t)-1, (diskaddr_t)-1)) {
1050Sstevel@tonic-gate 		err_print(
1060Sstevel@tonic-gate "Cannot modify disk partitions while it has mounted partitions.\n\n");
1070Sstevel@tonic-gate 		return (-1);
1080Sstevel@tonic-gate 	}
1095421Smishra 
1100Sstevel@tonic-gate 	/*
1110Sstevel@tonic-gate 	 * If the disk has partitions currently being used for
1120Sstevel@tonic-gate 	 * swapping, cannot modify
1130Sstevel@tonic-gate 	 */
1147563SPrasad.Singamsetty@Sun.COM 	if (checkswap((diskaddr_t)-1, (diskaddr_t)-1)) {
1150Sstevel@tonic-gate 		err_print(
1160Sstevel@tonic-gate "Cannot modify disk partitions while it is \
1170Sstevel@tonic-gate currently being used for swapping.\n");
1180Sstevel@tonic-gate 		return (-1);
1190Sstevel@tonic-gate 	}
1205421Smishra 
1215421Smishra 	/*
1225421Smishra 	 * Check to see if any partitions used for svm, vxvm, ZFS zpool
1235421Smishra 	 * or live upgrade are on the disk.
1245421Smishra 	 */
1255421Smishra 	if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
1265421Smishra 	    (diskaddr_t)-1, 0, 0)) {
1275421Smishra 		err_print("Cannot modify disk partition when "
1285421Smishra 		    "partitions are in use as described.\n");
1295421Smishra 		return (-1);
1305421Smishra 	}
1315421Smishra 
1320Sstevel@tonic-gate 	/*
1330Sstevel@tonic-gate 	 * prompt user for a partition table base
1340Sstevel@tonic-gate 	 */
1350Sstevel@tonic-gate 	if (cur_parts->pinfo_name != NULL) {
1360Sstevel@tonic-gate 		(void) snprintf(tmpstr, sizeof (tmpstr),
1370Sstevel@tonic-gate 			"\t0. Current partition table (%s)",
1380Sstevel@tonic-gate 			cur_parts->pinfo_name);
1390Sstevel@tonic-gate 	} else {
1400Sstevel@tonic-gate 		(void) sprintf(tmpstr,
1410Sstevel@tonic-gate 			"\t0. Current partition table (unnamed)");
1420Sstevel@tonic-gate 	}
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate 	(void) snprintf(tmpstr2, sizeof (tmpstr2),
1450Sstevel@tonic-gate "Select partitioning base:\n%s\n"
1460Sstevel@tonic-gate "\t1. All Free Hog\n"
1470Sstevel@tonic-gate "Choose base (enter number) ",
1480Sstevel@tonic-gate 		tmpstr);
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	ioparam.io_charlist = sel_list;
1510Sstevel@tonic-gate 	sel_type = input(FIO_MSTR, tmpstr2, '?', &ioparam,
1520Sstevel@tonic-gate 		&sel_type, DATA_INPUT);
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	switch (cur_label) {
1550Sstevel@tonic-gate 	case L_TYPE_SOLARIS:
1560Sstevel@tonic-gate 	    if (sel_type == 0) {
1570Sstevel@tonic-gate 		/*
1580Sstevel@tonic-gate 		 * Check for invalid parameters but do
1590Sstevel@tonic-gate 		 * not modify the table.
1600Sstevel@tonic-gate 		 */
1610Sstevel@tonic-gate 		if (check_map(cur_parts->pinfo_map)) {
1620Sstevel@tonic-gate 			err_print("\
1630Sstevel@tonic-gate Warning: Fix, or select a different partition table.\n");
1640Sstevel@tonic-gate 			return (0);
1650Sstevel@tonic-gate 		}
1660Sstevel@tonic-gate 		/*
1670Sstevel@tonic-gate 		 * Create partition map from existing map
1680Sstevel@tonic-gate 		 */
1690Sstevel@tonic-gate 		tmp_pinfo->vtoc = cur_parts->vtoc;
1700Sstevel@tonic-gate 		for (i = 0; i < NDKMAP; i++) {
1710Sstevel@tonic-gate 			map[i].dkl_nblk = cur_parts->pinfo_map[i].dkl_nblk;
1720Sstevel@tonic-gate 			map[i].dkl_cylno = cur_parts->pinfo_map[i].dkl_cylno;
1730Sstevel@tonic-gate 		}
1740Sstevel@tonic-gate 	    } else {
1750Sstevel@tonic-gate 		/*
1760Sstevel@tonic-gate 		 * Make an empty partition map, with all the space
1770Sstevel@tonic-gate 		 * in the c partition.
1780Sstevel@tonic-gate 		 */
1790Sstevel@tonic-gate 		set_vtoc_defaults(tmp_pinfo);
1800Sstevel@tonic-gate 		for (i = 0; i < NDKMAP; i++) {
1810Sstevel@tonic-gate 			map[i].dkl_nblk = 0;
1820Sstevel@tonic-gate 			map[i].dkl_cylno = 0;
1830Sstevel@tonic-gate 		}
1840Sstevel@tonic-gate 		map[C_PARTITION].dkl_nblk = ncyl * spc();
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate #if defined(i386)
1870Sstevel@tonic-gate 		/*
1880Sstevel@tonic-gate 		 * Adjust for the boot and possibly alternates partitions
1890Sstevel@tonic-gate 		 */
1900Sstevel@tonic-gate 		map[I_PARTITION].dkl_nblk = spc();
1910Sstevel@tonic-gate 		map[I_PARTITION].dkl_cylno = 0;
1920Sstevel@tonic-gate 		if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) {
1930Sstevel@tonic-gate 			map[J_PARTITION].dkl_nblk = 2 * spc();
1940Sstevel@tonic-gate 			map[J_PARTITION].dkl_cylno = spc() / spc();
1950Sstevel@tonic-gate 		}
1960Sstevel@tonic-gate #endif			/* defined(i386) */
1970Sstevel@tonic-gate 	    }
1980Sstevel@tonic-gate 	    break;
1990Sstevel@tonic-gate 	case L_TYPE_EFI:
2000Sstevel@tonic-gate 	    if (sel_type == 1) {
2010Sstevel@tonic-gate 		for (i = 0; i < cur_parts->etoc->efi_nparts; i++) {
2020Sstevel@tonic-gate 		    cur_parts->etoc->efi_parts[i].p_start = 0;
2030Sstevel@tonic-gate 		    cur_parts->etoc->efi_parts[i].p_size = 0;
2040Sstevel@tonic-gate 		}
2050Sstevel@tonic-gate 	    }
2060Sstevel@tonic-gate 	    break;
2070Sstevel@tonic-gate 	}
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	fmt_print("\n");
2100Sstevel@tonic-gate 	if (cur_label == L_TYPE_SOLARIS) {
2110Sstevel@tonic-gate 	    print_map(tmp_pinfo);
2120Sstevel@tonic-gate 	} else {
2130Sstevel@tonic-gate 	    print_map(cur_parts);
2140Sstevel@tonic-gate 	}
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate 	ioparam.io_charlist = confirm_list;
2170Sstevel@tonic-gate 	if (input(FIO_MSTR,
2180Sstevel@tonic-gate "Do you wish to continue creating a new partition\ntable based on above table",
2190Sstevel@tonic-gate 			'?', &ioparam, &inpt_dflt, DATA_INPUT)) {
2200Sstevel@tonic-gate 		return (0);
2210Sstevel@tonic-gate 	}
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	/*
2240Sstevel@tonic-gate 	 * get Free Hog partition
2250Sstevel@tonic-gate 	 */
2260Sstevel@tonic-gate 	inpt_dflt = 1;
2270Sstevel@tonic-gate 	while ((free_hog < 0) && (cur_label == L_TYPE_SOLARIS)) {
2280Sstevel@tonic-gate 		free_hog = G_PARTITION;	/* default to g partition */
2290Sstevel@tonic-gate 		ioparam.io_charlist = partn_list;
2300Sstevel@tonic-gate 		free_hog = input(FIO_MSTR, "Free Hog partition", '?',
2310Sstevel@tonic-gate 			&ioparam, &free_hog, DATA_INPUT);
2320Sstevel@tonic-gate 		/* disallow c partition */
2330Sstevel@tonic-gate 		if (free_hog == C_PARTITION) {
2340Sstevel@tonic-gate 			fmt_print("'%c' cannot be the 'Free Hog' partition.\n",
2350Sstevel@tonic-gate 				C_PARTITION + PARTITION_BASE);
2360Sstevel@tonic-gate 			free_hog = -1;
2370Sstevel@tonic-gate 			continue;
2380Sstevel@tonic-gate 		}
2390Sstevel@tonic-gate 		/*
2400Sstevel@tonic-gate 		 * If user selected all float set the
2410Sstevel@tonic-gate 		 * float to be the whole disk.
2420Sstevel@tonic-gate 		 */
2430Sstevel@tonic-gate 		if (sel_type == 1) {
2440Sstevel@tonic-gate 			map[free_hog].dkl_nblk = map[C_PARTITION].dkl_nblk;
2450Sstevel@tonic-gate #if defined(i386)
2460Sstevel@tonic-gate 			map[free_hog].dkl_nblk -= map[I_PARTITION].dkl_nblk;
2470Sstevel@tonic-gate 			if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) {
2480Sstevel@tonic-gate 				map[free_hog].dkl_nblk -=
2490Sstevel@tonic-gate 					map[J_PARTITION].dkl_nblk;
2500Sstevel@tonic-gate 			}
2510Sstevel@tonic-gate #endif			/* defined(i386) */
2520Sstevel@tonic-gate 			break;
2530Sstevel@tonic-gate 		}
2540Sstevel@tonic-gate 		/*
2550Sstevel@tonic-gate 		 * Warn the user if there is no free space in
2560Sstevel@tonic-gate 		 * the float partition.
2570Sstevel@tonic-gate 		 */
2580Sstevel@tonic-gate 		if (map[free_hog].dkl_nblk == 0) {
2590Sstevel@tonic-gate 			err_print("\
2600Sstevel@tonic-gate Warning: No space available from Free Hog partition.\n");
2610Sstevel@tonic-gate 			ioparam.io_charlist = confirm_list;
2620Sstevel@tonic-gate 			if (input(FIO_MSTR, "Continue", '?',
2630Sstevel@tonic-gate 				&ioparam, &inpt_dflt, DATA_INPUT)) {
2640Sstevel@tonic-gate 				free_hog = -1;
2650Sstevel@tonic-gate 			}
2660Sstevel@tonic-gate 		}
2670Sstevel@tonic-gate 	}
2680Sstevel@tonic-gate 	inpt_dflt = 0;
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate 	if (cur_label == L_TYPE_EFI) {
2710Sstevel@tonic-gate 	    free_hog = G_PARTITION; /* default to g partition */
2720Sstevel@tonic-gate 	    ioparam.io_charlist = partn_list;
2730Sstevel@tonic-gate 	    free_hog = input(FIO_MSTR, "Free Hog partition", '?',
2740Sstevel@tonic-gate 		&ioparam, &free_hog, DATA_INPUT);
2750Sstevel@tonic-gate 	    /* disallow c partition */
2760Sstevel@tonic-gate 	    if (free_hog == C_PARTITION) {
2770Sstevel@tonic-gate 		fmt_print("'%c' cannot be the 'Free Hog' partition.\n",
2780Sstevel@tonic-gate 		    C_PARTITION + PARTITION_BASE);
2790Sstevel@tonic-gate 		return (-1);
2800Sstevel@tonic-gate 	    }
2810Sstevel@tonic-gate 	    get_user_map_efi(cur_parts->etoc, free_hog);
2820Sstevel@tonic-gate 	    print_map(cur_parts);
2830Sstevel@tonic-gate 	    if (check("Ready to label disk, continue")) {
2840Sstevel@tonic-gate 		return (-1);
2850Sstevel@tonic-gate 	    }
2860Sstevel@tonic-gate 	    fmt_print("\n");
2870Sstevel@tonic-gate 	    if (write_label()) {
2880Sstevel@tonic-gate 		err_print("Writing label failed\n");
2890Sstevel@tonic-gate 		return (-1);
2900Sstevel@tonic-gate 	    }
2910Sstevel@tonic-gate 	    return (0);
2920Sstevel@tonic-gate 	}
2930Sstevel@tonic-gate 	/*
2940Sstevel@tonic-gate 	 * get user modified partition table
2950Sstevel@tonic-gate 	 */
2960Sstevel@tonic-gate 	get_user_map(map, free_hog);
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate 	/*
2990Sstevel@tonic-gate 	 * Update cylno offsets
3000Sstevel@tonic-gate 	 */
3010Sstevel@tonic-gate 	adj_cyl_offset(map);
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate 	fmt_print("\n");
3040Sstevel@tonic-gate 	print_map(tmp_pinfo);
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	ioparam.io_charlist = confirm_list;
3070Sstevel@tonic-gate 	if (input(FIO_MSTR, "\
3080Sstevel@tonic-gate Okay to make this the current partition table", '?',
3090Sstevel@tonic-gate 		&ioparam, &inpt_dflt, DATA_INPUT)) {
3100Sstevel@tonic-gate 		return (0);
3110Sstevel@tonic-gate 	} else {
3120Sstevel@tonic-gate 		make_partition();
3130Sstevel@tonic-gate 		/*
3140Sstevel@tonic-gate 		 * Update new partition map
3150Sstevel@tonic-gate 		 */
3160Sstevel@tonic-gate 		for (i = 0; i < NDKMAP; i++) {
3170Sstevel@tonic-gate 			cur_parts->pinfo_map[i].dkl_nblk = map[i].dkl_nblk;
3180Sstevel@tonic-gate 			cur_parts->pinfo_map[i].dkl_cylno = map[i].dkl_cylno;
3190Sstevel@tonic-gate #ifdef i386
3200Sstevel@tonic-gate 			cur_parts->vtoc.v_part[i].p_start =
3210Sstevel@tonic-gate 				map[i].dkl_cylno * nhead * nsect;
3220Sstevel@tonic-gate 			cur_parts->vtoc.v_part[i].p_size =
3230Sstevel@tonic-gate 				map[i].dkl_nblk;
3240Sstevel@tonic-gate #endif
3250Sstevel@tonic-gate 		}
3260Sstevel@tonic-gate 		(void) p_name();
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate 		/*
3290Sstevel@tonic-gate 		 * Label the disk now
3300Sstevel@tonic-gate 		 */
3310Sstevel@tonic-gate 		if (check("Ready to label disk, continue")) {
3320Sstevel@tonic-gate 			return (-1);
3330Sstevel@tonic-gate 		}
3340Sstevel@tonic-gate 		fmt_print("\n");
3350Sstevel@tonic-gate 		if (write_label()) {
3360Sstevel@tonic-gate 			err_print("Writing label failed\n");
3370Sstevel@tonic-gate 			return (-1);
3380Sstevel@tonic-gate 		}
3390Sstevel@tonic-gate 		return (0);
3400Sstevel@tonic-gate 	}
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate /*
3460Sstevel@tonic-gate  * Adjust cylinder offsets
3470Sstevel@tonic-gate  */
3480Sstevel@tonic-gate static void
adj_cyl_offset(map)3490Sstevel@tonic-gate adj_cyl_offset(map)
3500Sstevel@tonic-gate 	struct	dk_map32 *map;
3510Sstevel@tonic-gate {
3520Sstevel@tonic-gate 	int	i;
3530Sstevel@tonic-gate 	int	cyloffset = 0;
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate 	/*
3570Sstevel@tonic-gate 	 * Update cylno offsets
3580Sstevel@tonic-gate 	 */
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3610Sstevel@tonic-gate 	/*
3620Sstevel@tonic-gate 	 * Correct cylinder allocation for having the boot and alternates
3630Sstevel@tonic-gate 	 * slice in the beginning of the disk
3640Sstevel@tonic-gate 	 */
3650Sstevel@tonic-gate 	for (i = NDKMAP/2; i < NDKMAP; i++) {
3660Sstevel@tonic-gate 		if (i != C_PARTITION && map[i].dkl_nblk) {
3670Sstevel@tonic-gate 			map[i].dkl_cylno = cyloffset;
3680Sstevel@tonic-gate 			cyloffset += (map[i].dkl_nblk + (spc()-1))/spc();
3690Sstevel@tonic-gate 		} else if (map[i].dkl_nblk == 0) {
3700Sstevel@tonic-gate 			map[i].dkl_cylno = 0;
3710Sstevel@tonic-gate 		}
3720Sstevel@tonic-gate 	}
3730Sstevel@tonic-gate 	for (i = 0; i < NDKMAP/2; i++) {
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate #else					/* !defined(_SUNOS_VTOC_16) */
3760Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
3770Sstevel@tonic-gate #endif					/* defined(_SUNOS_VTOC_16) */
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 		if (i != C_PARTITION && map[i].dkl_nblk) {
3800Sstevel@tonic-gate 			map[i].dkl_cylno = cyloffset;
3810Sstevel@tonic-gate 			cyloffset += (map[i].dkl_nblk + (spc()-1))/spc();
3820Sstevel@tonic-gate 		} else if (map[i].dkl_nblk == 0) {
3830Sstevel@tonic-gate 			map[i].dkl_cylno = 0;
3840Sstevel@tonic-gate 		}
3850Sstevel@tonic-gate 	}
3860Sstevel@tonic-gate }
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate /*
3900Sstevel@tonic-gate  * Check partition table
3910Sstevel@tonic-gate  */
3920Sstevel@tonic-gate static int
check_map(map)3930Sstevel@tonic-gate check_map(map)
3940Sstevel@tonic-gate 	struct	dk_map32 *map;
3950Sstevel@tonic-gate {
3967563SPrasad.Singamsetty@Sun.COM 	int		i;
3977563SPrasad.Singamsetty@Sun.COM 	int		cyloffset = 0;
3987563SPrasad.Singamsetty@Sun.COM 	blkaddr32_t	tot_blks = 0;
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate #ifdef i386
4010Sstevel@tonic-gate 	/*
4020Sstevel@tonic-gate 	 * On x86, we must account for the boot and alternates
4030Sstevel@tonic-gate 	 */
4040Sstevel@tonic-gate 	cyloffset = map[0].dkl_cylno;
4050Sstevel@tonic-gate 	tot_blks = map[0].dkl_nblk;
4060Sstevel@tonic-gate #endif
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 	/*
4090Sstevel@tonic-gate 	 * Do some checks for invalid parameters but do
4100Sstevel@tonic-gate 	 * not modify the table.
4110Sstevel@tonic-gate 	 */
4120Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
4137563SPrasad.Singamsetty@Sun.COM 		if (map[i].dkl_cylno > (blkaddr32_t)ncyl-1) {
4140Sstevel@tonic-gate 			err_print("\
4150Sstevel@tonic-gate Warning: Partition %c starting cylinder %d is out of range.\n",
4160Sstevel@tonic-gate 				(PARTITION_BASE+i), map[i].dkl_cylno);
4170Sstevel@tonic-gate 			return (-1);
4180Sstevel@tonic-gate 		}
4197563SPrasad.Singamsetty@Sun.COM 		if (map[i].dkl_nblk >
4207563SPrasad.Singamsetty@Sun.COM 			(blkaddr32_t)(ncyl - map[i].dkl_cylno) * spc()) {
4210Sstevel@tonic-gate 			err_print("\
4227563SPrasad.Singamsetty@Sun.COM Warning: Partition %c, specified # of blocks, %u, is out of range.\n",
4230Sstevel@tonic-gate 				(PARTITION_BASE+i), map[i].dkl_nblk);
4240Sstevel@tonic-gate 			return (-1);
4250Sstevel@tonic-gate 		}
4260Sstevel@tonic-gate 		if (i != C_PARTITION && map[i].dkl_nblk) {
4270Sstevel@tonic-gate #ifdef	i386
4280Sstevel@tonic-gate 			if (i == I_PARTITION || i == J_PARTITION)
4290Sstevel@tonic-gate 				continue;
4300Sstevel@tonic-gate #endif
4310Sstevel@tonic-gate 			if (map[i].dkl_cylno < cyloffset) {
4320Sstevel@tonic-gate 				err_print(
4330Sstevel@tonic-gate "Warning: Overlapping partition (%c) in table.\n", PARTITION_BASE+i);
4340Sstevel@tonic-gate 				return (-1);
4350Sstevel@tonic-gate 			} else if (map[i].dkl_cylno > cyloffset) {
4360Sstevel@tonic-gate 				err_print(
4370Sstevel@tonic-gate "Warning: Non-contiguous partition (%c) in table.\n", PARTITION_BASE+i);
4380Sstevel@tonic-gate 			}
4390Sstevel@tonic-gate 			cyloffset += (map[i].dkl_nblk + (spc()-1))/spc();
4400Sstevel@tonic-gate 			tot_blks = map[i].dkl_nblk;
4410Sstevel@tonic-gate 		}
4420Sstevel@tonic-gate 	}
4430Sstevel@tonic-gate 	if (tot_blks > map[C_PARTITION].dkl_nblk) {
4440Sstevel@tonic-gate 		err_print("\
4450Sstevel@tonic-gate Warning: Total blocks used is greater than number of blocks in '%c'\n\
4460Sstevel@tonic-gate \tpartition.\n", C_PARTITION + PARTITION_BASE);
4470Sstevel@tonic-gate 	return (-1);
4480Sstevel@tonic-gate 	}
4490Sstevel@tonic-gate 	return (0);
4500Sstevel@tonic-gate }
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate /*
4550Sstevel@tonic-gate  * get user defined partitions
4560Sstevel@tonic-gate  */
4570Sstevel@tonic-gate static void
get_user_map(map,float_part)4580Sstevel@tonic-gate get_user_map(map, float_part)
4590Sstevel@tonic-gate 	struct	dk_map32 *map;
4600Sstevel@tonic-gate 	int	float_part;
4610Sstevel@tonic-gate {
4620Sstevel@tonic-gate 	int		i;
4637563SPrasad.Singamsetty@Sun.COM 	blkaddr32_t	newsize;
4647563SPrasad.Singamsetty@Sun.COM 	blkaddr32_t	deflt;
4650Sstevel@tonic-gate 	char		tmpstr[80];
4660Sstevel@tonic-gate 	u_ioparam_t	ioparam;
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate 	/*
4690Sstevel@tonic-gate 	 * Get partition sizes
4700Sstevel@tonic-gate 	 */
4710Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
4720Sstevel@tonic-gate 		if (partn_list[i] == NULL)
4730Sstevel@tonic-gate 			break;
4740Sstevel@tonic-gate 		if ((i == C_PARTITION) || (i == float_part))
4750Sstevel@tonic-gate 			continue;
4760Sstevel@tonic-gate 		else {
4770Sstevel@tonic-gate 			ioparam.io_bounds.lower = 0;
4780Sstevel@tonic-gate 			ioparam.io_bounds.upper = map[i].dkl_nblk +
4790Sstevel@tonic-gate 				map[float_part].dkl_nblk;
4800Sstevel@tonic-gate 			deflt = map[i].dkl_nblk;
4810Sstevel@tonic-gate 			if (ioparam.io_bounds.upper == 0) {
4820Sstevel@tonic-gate 				err_print("\
4830Sstevel@tonic-gate Warning: no space available for '%s' from Free Hog partition\n",
4840Sstevel@tonic-gate 					partn_list[i]);
4850Sstevel@tonic-gate 				continue;
4860Sstevel@tonic-gate 			}
4870Sstevel@tonic-gate 			(void) snprintf(tmpstr, sizeof (tmpstr),
4880Sstevel@tonic-gate 				"Enter size of partition '%s' ",
4890Sstevel@tonic-gate 				partn_list[i]);
4907563SPrasad.Singamsetty@Sun.COM 			newsize = (blkaddr32_t)input(FIO_CYL, tmpstr, ':',
4917563SPrasad.Singamsetty@Sun.COM 				&ioparam, (int *)&deflt, DATA_INPUT);
4920Sstevel@tonic-gate 			map[float_part].dkl_nblk -= (newsize - map[i].dkl_nblk);
4930Sstevel@tonic-gate 			map[i].dkl_nblk = newsize;
4940Sstevel@tonic-gate 		}
4950Sstevel@tonic-gate 	}
4960Sstevel@tonic-gate }
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate static struct partition_info *
build_partition(tptr)4990Sstevel@tonic-gate build_partition(tptr)
5000Sstevel@tonic-gate struct disk_type *tptr;
5010Sstevel@tonic-gate {
5020Sstevel@tonic-gate 	struct partition_info	*part;
5030Sstevel@tonic-gate 	struct dk_label		*label;
5040Sstevel@tonic-gate 	int			i;
5050Sstevel@tonic-gate 
5060Sstevel@tonic-gate #ifdef DEBUG
5070Sstevel@tonic-gate 	fmt_print("Creating Default Partition for the disk \n");
5080Sstevel@tonic-gate #endif
5090Sstevel@tonic-gate 	/*
5100Sstevel@tonic-gate 	 * construct a label and pass it on to
5110Sstevel@tonic-gate 	 * build_default_partition() which builds the
5120Sstevel@tonic-gate 	 * default partition list.
5130Sstevel@tonic-gate 	 */
5140Sstevel@tonic-gate 	label = zalloc(sizeof (struct dk_label));
5150Sstevel@tonic-gate 	label->dkl_pcyl = tptr->dtype_pcyl;
5160Sstevel@tonic-gate 	label->dkl_ncyl = tptr->dtype_ncyl;
5170Sstevel@tonic-gate 	label->dkl_acyl = tptr->dtype_acyl;
5180Sstevel@tonic-gate 	label->dkl_nhead = tptr->dtype_nhead;
5190Sstevel@tonic-gate 	label->dkl_nsect = tptr->dtype_nsect;
5200Sstevel@tonic-gate 	label->dkl_apc = apc;
5210Sstevel@tonic-gate 	label->dkl_intrlv = 1;
5220Sstevel@tonic-gate 	label->dkl_rpm	= tptr->dtype_rpm;
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate 	if (!build_default_partition(label, cur_ctype->ctype_ctype))
5250Sstevel@tonic-gate 		return (NULL);
5260Sstevel@tonic-gate 
5270Sstevel@tonic-gate 	part = (struct partition_info *)
5280Sstevel@tonic-gate 		    zalloc(sizeof (struct partition_info));
5290Sstevel@tonic-gate 	part->pinfo_name = alloc_string(tptr->dtype_asciilabel);
5300Sstevel@tonic-gate 	/*
5310Sstevel@tonic-gate 	 * Fill in the partition info from the label
5320Sstevel@tonic-gate 	 */
5330Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
5340Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
5350Sstevel@tonic-gate 	    part->pinfo_map[i] = label->dkl_map[i];
5360Sstevel@tonic-gate #else
5370Sstevel@tonic-gate 	    part->pinfo_map[i].dkl_cylno =
5387563SPrasad.Singamsetty@Sun.COM 		label->dkl_vtoc.v_part[i].p_start /
5397563SPrasad.Singamsetty@Sun.COM 		(blkaddr32_t)(tptr->dtype_nhead * tptr->dtype_nsect - apc);
5400Sstevel@tonic-gate 	    part->pinfo_map[i].dkl_nblk =
5410Sstevel@tonic-gate 		label->dkl_vtoc.v_part[i].p_size;
5420Sstevel@tonic-gate #endif /* ifdefined(_SUNOS_VTOC_8) */
5430Sstevel@tonic-gate 	}
5440Sstevel@tonic-gate 	part->vtoc = label->dkl_vtoc;
5450Sstevel@tonic-gate 	return (part);
5460Sstevel@tonic-gate }
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate /*
5490Sstevel@tonic-gate  * build new partition table for given disk type
5500Sstevel@tonic-gate  */
5510Sstevel@tonic-gate static void
get_user_map_efi(map,float_part)5520Sstevel@tonic-gate get_user_map_efi(map, float_part)
5530Sstevel@tonic-gate 	struct dk_gpt *map;
5540Sstevel@tonic-gate 	int	float_part;
5550Sstevel@tonic-gate {
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 	int		i;
5580Sstevel@tonic-gate 	efi_deflt_t	efi_deflt;
5590Sstevel@tonic-gate 	u_ioparam_t	ioparam;
5600Sstevel@tonic-gate 	char		tmpstr[80];
5610Sstevel@tonic-gate 	uint64_t	i64;
5620Sstevel@tonic-gate 	uint64_t	start_lba = 34;
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate 	for (i = 0; i < map->efi_nparts - 1; i++) {
5650Sstevel@tonic-gate 		if (i == float_part)
5660Sstevel@tonic-gate 			continue;
5670Sstevel@tonic-gate 		else {
5680Sstevel@tonic-gate 			ioparam.io_bounds.lower = start_lba;
5690Sstevel@tonic-gate 			ioparam.io_bounds.upper = map->efi_last_u_lba;
5700Sstevel@tonic-gate 			efi_deflt.start_sector = ioparam.io_bounds.lower;
5710Sstevel@tonic-gate 			efi_deflt.end_sector = map->efi_parts[i].p_size;
5720Sstevel@tonic-gate 			(void) sprintf(tmpstr,
5730Sstevel@tonic-gate 			    "Enter size of partition %d ", i);
5740Sstevel@tonic-gate 			i64 = input(FIO_EFI, tmpstr, ':',
5750Sstevel@tonic-gate 			    &ioparam, (int *)&efi_deflt, DATA_INPUT);
5760Sstevel@tonic-gate 			if (i64 == 0) {
5770Sstevel@tonic-gate 			    map->efi_parts[i].p_tag = V_UNASSIGNED;
5780Sstevel@tonic-gate 			} else if ((i64 != 0) && (map->efi_parts[i].p_tag ==
5790Sstevel@tonic-gate 				V_UNASSIGNED)) {
5800Sstevel@tonic-gate 			    map->efi_parts[i].p_tag = V_USR;
5810Sstevel@tonic-gate 			}
5820Sstevel@tonic-gate 			if (i64 == 0) {
5830Sstevel@tonic-gate 			    map->efi_parts[i].p_start = 0;
5840Sstevel@tonic-gate 			} else {
5850Sstevel@tonic-gate 			    map->efi_parts[i].p_start = start_lba;
5860Sstevel@tonic-gate 			}
5870Sstevel@tonic-gate 			map->efi_parts[i].p_size = i64;
5880Sstevel@tonic-gate 			start_lba += i64;
5890Sstevel@tonic-gate 		}
5900Sstevel@tonic-gate 	}
5910Sstevel@tonic-gate 		map->efi_parts[float_part].p_start = start_lba;
5920Sstevel@tonic-gate 		map->efi_parts[float_part].p_size = map->efi_last_u_lba -
5930Sstevel@tonic-gate 			start_lba - (1024 * 16);
5940Sstevel@tonic-gate 		map->efi_parts[float_part].p_tag = V_USR;
5950Sstevel@tonic-gate 		if (map->efi_parts[float_part].p_size == UINT_MAX64) {
5960Sstevel@tonic-gate 			map->efi_parts[float_part].p_size = 0;
5970Sstevel@tonic-gate 			map->efi_parts[float_part].p_start = 0;
5980Sstevel@tonic-gate 			map->efi_parts[float_part].p_tag = V_UNASSIGNED;
5990Sstevel@tonic-gate 			fmt_print("Warning: No space left for HOG\n");
6000Sstevel@tonic-gate 		}
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 		for (i = 0; i < map->efi_nparts; i++) {
6030Sstevel@tonic-gate 		    if (map->efi_parts[i].p_tag == V_RESERVED) {
6040Sstevel@tonic-gate 			map->efi_parts[i].p_start = map->efi_last_u_lba -
6050Sstevel@tonic-gate 			    (1024 * 16);
6060Sstevel@tonic-gate 			map->efi_parts[i].p_size = (1024 * 16);
6070Sstevel@tonic-gate 			break;
6080Sstevel@tonic-gate 		    }
6090Sstevel@tonic-gate 		}
6100Sstevel@tonic-gate }
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 
6130Sstevel@tonic-gate void
new_partitiontable(tptr,oldtptr)6140Sstevel@tonic-gate new_partitiontable(tptr, oldtptr)
6150Sstevel@tonic-gate struct disk_type	*tptr, *oldtptr;
6160Sstevel@tonic-gate {
6170Sstevel@tonic-gate 	struct partition_info *part;
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate 	/*
6200Sstevel@tonic-gate 	 * check if disk geometry has changed , if so add new
6210Sstevel@tonic-gate 	 * partition table else copy the old partition table.(best guess).
6220Sstevel@tonic-gate 	 */
6230Sstevel@tonic-gate 	if ((oldtptr != NULL) &&
6240Sstevel@tonic-gate 		(tptr->dtype_ncyl ==  oldtptr->dtype_ncyl) &&
6250Sstevel@tonic-gate 		(tptr->dtype_nhead == oldtptr->dtype_nhead) &&
6260Sstevel@tonic-gate 		(tptr->dtype_nsect == oldtptr->dtype_nsect)) {
6270Sstevel@tonic-gate 
6280Sstevel@tonic-gate 	    part = (struct partition_info *)
6290Sstevel@tonic-gate 			zalloc(sizeof (struct partition_info));
6300Sstevel@tonic-gate 	    bcopy((char *)cur_parts, (char *)part,
6310Sstevel@tonic-gate 			sizeof (struct partition_info));
6320Sstevel@tonic-gate 	    part->pinfo_next = tptr->dtype_plist;
6330Sstevel@tonic-gate 	    tptr->dtype_plist = part;
6340Sstevel@tonic-gate 	} else {
6350Sstevel@tonic-gate 
6360Sstevel@tonic-gate #ifdef DEBUG
6370Sstevel@tonic-gate 		if (cur_parts != NULL) {
6380Sstevel@tonic-gate 			fmt_print("Warning: Partition Table is set");
6390Sstevel@tonic-gate 			fmt_print("to default partition table. \n");
6400Sstevel@tonic-gate 		}
6410Sstevel@tonic-gate #endif
6420Sstevel@tonic-gate 		if (tptr->dtype_plist == NULL) {
6430Sstevel@tonic-gate 			part = (struct partition_info *)build_partition(tptr);
6440Sstevel@tonic-gate 			if (part != NULL) {
6450Sstevel@tonic-gate 				part->pinfo_next = tptr->dtype_plist;
6460Sstevel@tonic-gate 				tptr->dtype_plist = part;
6470Sstevel@tonic-gate 			}
6480Sstevel@tonic-gate 		}
6490Sstevel@tonic-gate 	}
6500Sstevel@tonic-gate }
651