xref: /onnv-gate/usr/src/cmd/format/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
57563SPrasad.Singamsetty@Sun.COM  * Common Development and Distribution License (the "License").
67563SPrasad.Singamsetty@Sun.COM  * 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 that operate on partition tables.
280Sstevel@tonic-gate  */
29*13093SRoger.Faulkner@Oracle.COM #include <string.h>
30*13093SRoger.Faulkner@Oracle.COM #include <stdlib.h>
310Sstevel@tonic-gate #include "global.h"
320Sstevel@tonic-gate #include "partition.h"
330Sstevel@tonic-gate #include "misc.h"
340Sstevel@tonic-gate #include "menu_command.h"
350Sstevel@tonic-gate #include "menu_partition.h"
360Sstevel@tonic-gate 
370Sstevel@tonic-gate 
380Sstevel@tonic-gate /*
390Sstevel@tonic-gate  * Default vtoc information for non-SVr4 partitions
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate struct dk_map2	default_vtoc_map[NDKMAP] = {
420Sstevel@tonic-gate 	{	V_ROOT,		0	},		/* a - 0 */
430Sstevel@tonic-gate 	{	V_SWAP,		V_UNMNT	},		/* b - 1 */
440Sstevel@tonic-gate 	{	V_BACKUP,	V_UNMNT	},		/* c - 2 */
450Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* d - 3 */
460Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* e - 4 */
470Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* f - 5 */
480Sstevel@tonic-gate 	{	V_USR,		0	},		/* g - 6 */
490Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* h - 7 */
500Sstevel@tonic-gate 
510Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
520Sstevel@tonic-gate 
530Sstevel@tonic-gate #if defined(i386)
540Sstevel@tonic-gate 	{	V_BOOT,		V_UNMNT	},		/* i - 8 */
550Sstevel@tonic-gate 	{	V_ALTSCTR,	0	},		/* j - 9 */
560Sstevel@tonic-gate 
570Sstevel@tonic-gate #else
580Sstevel@tonic-gate #error No VTOC format defined.
590Sstevel@tonic-gate #endif			/* defined(i386) */
600Sstevel@tonic-gate 
610Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* k - 10 */
620Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* l - 11 */
630Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* m - 12 */
640Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* n - 13 */
650Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* o - 14 */
660Sstevel@tonic-gate 	{	V_UNASSIGNED,	0	},		/* p - 15 */
670Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_16) */
680Sstevel@tonic-gate };
690Sstevel@tonic-gate 
700Sstevel@tonic-gate /*
710Sstevel@tonic-gate  * This routine finds the last usable sector in the partition table.
720Sstevel@tonic-gate  * It skips the BACKUP partition.
730Sstevel@tonic-gate  */
740Sstevel@tonic-gate static uint64_t
maxofN(struct dk_gpt * map)750Sstevel@tonic-gate maxofN(struct dk_gpt *map)
760Sstevel@tonic-gate {
770Sstevel@tonic-gate 	uint64_t	max;
780Sstevel@tonic-gate 	uint64_t	sec_no[2], start[2], size[2];
790Sstevel@tonic-gate 	int		i;
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	for (i = 0; i < map->efi_nparts - 1; i++) {
820Sstevel@tonic-gate 	    start[0] = map->efi_parts[i].p_start;
830Sstevel@tonic-gate 	    size[0] = map->efi_parts[i].p_size;
840Sstevel@tonic-gate 	    sec_no[0] = start[0] + size[0];
850Sstevel@tonic-gate 
860Sstevel@tonic-gate 	    start[1] = map->efi_parts[i+1].p_start;
870Sstevel@tonic-gate 	    size[1] = map->efi_parts[i+1].p_size;
880Sstevel@tonic-gate 	    sec_no[1] = start[1] + size[1];
890Sstevel@tonic-gate 
900Sstevel@tonic-gate 	    if (map->efi_parts[i].p_tag == V_BACKUP) {
910Sstevel@tonic-gate 		sec_no[0] = 0;
920Sstevel@tonic-gate 	    }
930Sstevel@tonic-gate 	    if (map->efi_parts[i+1].p_tag == V_BACKUP) {
940Sstevel@tonic-gate 		sec_no[1] = 0;
950Sstevel@tonic-gate 	    }
960Sstevel@tonic-gate 	    if (i == 0) {
970Sstevel@tonic-gate 		max = sec_no[1];
980Sstevel@tonic-gate 	    }
990Sstevel@tonic-gate 	    if (sec_no[0] > max) {
1000Sstevel@tonic-gate 		max = sec_no[0];
1010Sstevel@tonic-gate 	    } else {
1020Sstevel@tonic-gate 		max = max;
1030Sstevel@tonic-gate 	    }
1040Sstevel@tonic-gate 	}
1050Sstevel@tonic-gate 	if (max == 0)
1060Sstevel@tonic-gate 	    max = 34;
1070Sstevel@tonic-gate 	return (max);
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate /*
1110Sstevel@tonic-gate  * This routine allows the user to change the boundaries of the given
1120Sstevel@tonic-gate  * partition in the current partition map.
1130Sstevel@tonic-gate  */
1140Sstevel@tonic-gate void
change_partition(int num)1150Sstevel@tonic-gate change_partition(int num)
1160Sstevel@tonic-gate {
1177563SPrasad.Singamsetty@Sun.COM 	uint_t		i;
1180Sstevel@tonic-gate 	uint64_t	i64, j64;
1197563SPrasad.Singamsetty@Sun.COM 	uint_t		j;
1200Sstevel@tonic-gate 	int		deflt;
1210Sstevel@tonic-gate 	part_deflt_t	p_deflt;
1220Sstevel@tonic-gate 	u_ioparam_t	ioparam;
1230Sstevel@tonic-gate 	int		tag;
1240Sstevel@tonic-gate 	int		flag;
1250Sstevel@tonic-gate 	char		msg[256];
1267563SPrasad.Singamsetty@Sun.COM 	blkaddr32_t	cyl_offset = 0;
1270Sstevel@tonic-gate 	efi_deflt_t	efi_deflt;
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 	/*
1300Sstevel@tonic-gate 	 * check if there exists a partition table for the disk.
1310Sstevel@tonic-gate 	 */
1320Sstevel@tonic-gate 	if (cur_parts == NULL) {
1330Sstevel@tonic-gate 		err_print("Current Disk has no partition table.\n");
1340Sstevel@tonic-gate 		return;
1350Sstevel@tonic-gate 	}
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 	if (cur_label == L_TYPE_EFI) {
1380Sstevel@tonic-gate 	    if (num > cur_parts->etoc->efi_nparts - 1) {
1390Sstevel@tonic-gate 		err_print("Invalid partition for EFI label\n");
1400Sstevel@tonic-gate 		return;
1410Sstevel@tonic-gate 	    }
1420Sstevel@tonic-gate 	    print_efi_partition(cur_parts->etoc, num, 1);
1430Sstevel@tonic-gate 	    fmt_print("\n");
1440Sstevel@tonic-gate 		/*
1450Sstevel@tonic-gate 		 * Prompt for p_tag and p_flag values for this partition
1460Sstevel@tonic-gate 		 */
1470Sstevel@tonic-gate 	    deflt = cur_parts->etoc->efi_parts[num].p_tag;
1480Sstevel@tonic-gate 	    if (deflt == V_UNASSIGNED) {
1490Sstevel@tonic-gate 		deflt = V_USR;
1500Sstevel@tonic-gate 	    }
1510Sstevel@tonic-gate 	    (void) sprintf(msg, "Enter partition id tag");
1520Sstevel@tonic-gate 	    ioparam.io_slist = ptag_choices;
1530Sstevel@tonic-gate 	    tag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT);
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 	    deflt = cur_parts->etoc->efi_parts[num].p_flag;
1560Sstevel@tonic-gate 	    (void) sprintf(msg, "Enter partition permission flags");
1570Sstevel@tonic-gate 	    ioparam.io_slist = pflag_choices;
1580Sstevel@tonic-gate 	    flag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT);
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	    ioparam.io_bounds.lower = 34;
1610Sstevel@tonic-gate 	    ioparam.io_bounds.upper = cur_parts->etoc->efi_last_u_lba;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	    efi_deflt.start_sector = maxofN(cur_parts->etoc);
1640Sstevel@tonic-gate 	    if ((cur_parts->etoc->efi_parts[num].p_start != 0) &&
1650Sstevel@tonic-gate 		(cur_parts->etoc->efi_parts[num].p_size != 0)) {
1660Sstevel@tonic-gate 		    efi_deflt.start_sector =
1670Sstevel@tonic-gate 			cur_parts->etoc->efi_parts[num].p_start;
1680Sstevel@tonic-gate 	    }
1690Sstevel@tonic-gate 	    efi_deflt.end_sector = ioparam.io_bounds.upper -
1700Sstevel@tonic-gate 					efi_deflt.start_sector;
1710Sstevel@tonic-gate 	    i64 = input(FIO_INT64, "Enter new starting Sector", ':', &ioparam,
1720Sstevel@tonic-gate 		(int *)&efi_deflt, DATA_INPUT);
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	    ioparam.io_bounds.lower = 0;
1750Sstevel@tonic-gate 	    ioparam.io_bounds.upper = cur_parts->etoc->efi_last_u_lba;
1760Sstevel@tonic-gate 	    efi_deflt.end_sector = cur_parts->etoc->efi_parts[num].p_size;
1770Sstevel@tonic-gate 	    efi_deflt.start_sector = i64;
1780Sstevel@tonic-gate 	    j64 = input(FIO_EFI, "Enter partition size", ':', &ioparam,
1790Sstevel@tonic-gate 		(int *)&efi_deflt, DATA_INPUT);
1800Sstevel@tonic-gate 	    if (j64 == 0) {
1810Sstevel@tonic-gate 		tag = V_UNASSIGNED;
1820Sstevel@tonic-gate 		i64 = 0;
1830Sstevel@tonic-gate 	    } else if ((j64 != 0) && (tag == V_UNASSIGNED)) {
1840Sstevel@tonic-gate 		tag = V_USR;
1850Sstevel@tonic-gate 	    }
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	    if (cur_parts->pinfo_name != NULL)
1880Sstevel@tonic-gate 		make_partition();
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 	    cur_parts->etoc->efi_parts[num].p_tag = tag;
1910Sstevel@tonic-gate 	    cur_parts->etoc->efi_parts[num].p_flag = flag;
1920Sstevel@tonic-gate 	    cur_parts->etoc->efi_parts[num].p_start = i64;
1930Sstevel@tonic-gate 	    cur_parts->etoc->efi_parts[num].p_size = j64;
1940Sstevel@tonic-gate 	/*
1950Sstevel@tonic-gate 	 * We are now done with EFI part, so return now
1960Sstevel@tonic-gate 	 */
1970Sstevel@tonic-gate 	    return;
1980Sstevel@tonic-gate 	}
1990Sstevel@tonic-gate 	/*
2000Sstevel@tonic-gate 	 * Print out the given partition so the user knows what he/she's
2010Sstevel@tonic-gate 	 * getting into.
2020Sstevel@tonic-gate 	 */
2030Sstevel@tonic-gate 	print_partition(cur_parts, num, 1);
2040Sstevel@tonic-gate 	fmt_print("\n");
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	/*
2070Sstevel@tonic-gate 	 * Prompt for p_tag and p_flag values for this partition.
2080Sstevel@tonic-gate 	 */
2090Sstevel@tonic-gate 	assert(cur_parts->vtoc.v_version == V_VERSION);
2100Sstevel@tonic-gate 	deflt = cur_parts->vtoc.v_part[num].p_tag;
2110Sstevel@tonic-gate 	(void) sprintf(msg, "Enter partition id tag");
2120Sstevel@tonic-gate 	ioparam.io_slist = ptag_choices;
2130Sstevel@tonic-gate 	tag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT);
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 	deflt = cur_parts->vtoc.v_part[num].p_flag;
2160Sstevel@tonic-gate 	(void) sprintf(msg, "Enter partition permission flags");
2170Sstevel@tonic-gate 	ioparam.io_slist = pflag_choices;
2180Sstevel@tonic-gate 	flag = input(FIO_SLIST, msg, ':', &ioparam, &deflt, DATA_INPUT);
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate 	/*
2210Sstevel@tonic-gate 	 * Ask for the new values.  The old values are the defaults, and
2220Sstevel@tonic-gate 	 * strict bounds checking is done on the values given.
2230Sstevel@tonic-gate 	 */
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate #if defined(i386)
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	if (tag != V_UNASSIGNED && tag != V_BACKUP && tag != V_BOOT) {
2280Sstevel@tonic-gate 		/*
2290Sstevel@tonic-gate 		 * Determine cyl offset for boot and alternate partitions.
2300Sstevel@tonic-gate 		 * Assuming that the alternate sectors partition (slice)
2310Sstevel@tonic-gate 		 * physical location immediately follows the boot
2320Sstevel@tonic-gate 		 * partition and partition sizes are expressed in multiples
2330Sstevel@tonic-gate 		 * of cylinder size.
2340Sstevel@tonic-gate 		 */
2350Sstevel@tonic-gate 		cyl_offset = cur_parts->pinfo_map[I_PARTITION].dkl_cylno + 1;
2360Sstevel@tonic-gate 		if (tag != V_ALTSCTR) {
2370Sstevel@tonic-gate 			if (cur_parts->pinfo_map[J_PARTITION].dkl_nblk != 0) {
2380Sstevel@tonic-gate 				cyl_offset =
2390Sstevel@tonic-gate 				cur_parts->pinfo_map[J_PARTITION].dkl_cylno +
2400Sstevel@tonic-gate 				((cur_parts->pinfo_map[J_PARTITION].dkl_nblk +
2410Sstevel@tonic-gate 				(spc()-1)) / spc());
2420Sstevel@tonic-gate 			}
2430Sstevel@tonic-gate 		}
2440Sstevel@tonic-gate 	}
2450Sstevel@tonic-gate #endif	/* defined(i386) */
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 	ioparam.io_bounds.lower = 0;
2480Sstevel@tonic-gate 	ioparam.io_bounds.upper = ncyl - 1;
2490Sstevel@tonic-gate 	deflt = max(cur_parts->pinfo_map[num].dkl_cylno,
2500Sstevel@tonic-gate 		cyl_offset);
2517563SPrasad.Singamsetty@Sun.COM 	i = (uint_t)input(FIO_INT, "Enter new starting cyl", ':', &ioparam,
2520Sstevel@tonic-gate 	    &deflt, DATA_INPUT);
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	ioparam.io_bounds.lower = 0;
2550Sstevel@tonic-gate 	ioparam.io_bounds.upper = (ncyl - i) * spc();
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	/* fill in defaults for the current partition */
2580Sstevel@tonic-gate 	p_deflt.start_cyl = i;
2590Sstevel@tonic-gate 	p_deflt.deflt_size =
2600Sstevel@tonic-gate 		min(cur_parts->pinfo_map[num].dkl_nblk,
2610Sstevel@tonic-gate 		    ioparam.io_bounds.upper);
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	/* call input, passing p_deflt's address, typecast to (int *) */
2647563SPrasad.Singamsetty@Sun.COM 	j = (uint_t)input(FIO_ECYL, "Enter partition size", ':', &ioparam,
2650Sstevel@tonic-gate 	    (int *)&p_deflt, DATA_INPUT);
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 	/*
2680Sstevel@tonic-gate 	 * If the current partition has a size of zero change the
2690Sstevel@tonic-gate 	 * tag to Unassigned and the starting cylinder to zero
2700Sstevel@tonic-gate 	 */
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 	if (j == 0) {
2730Sstevel@tonic-gate 		tag = V_UNASSIGNED;
2740Sstevel@tonic-gate 		i = 0;
2750Sstevel@tonic-gate 	}
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate #if defined(i386)
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 	if (i < cyl_offset && tag != V_UNASSIGNED && tag != V_BACKUP &&
2810Sstevel@tonic-gate 	    tag != V_BOOT) {
2820Sstevel@tonic-gate 		/*
2830Sstevel@tonic-gate 		 * This slice overlaps boot and/or alternates slice
2840Sstevel@tonic-gate 		 * Check if it's the boot or alternates slice and warn
2850Sstevel@tonic-gate 		 * accordingly
2860Sstevel@tonic-gate 		 */
2870Sstevel@tonic-gate 		if (i < cur_parts->pinfo_map[I_PARTITION].dkl_cylno + 1) {
2880Sstevel@tonic-gate 			fmt_print("\nWarning: Partition overlaps boot ");
2890Sstevel@tonic-gate 			fmt_print("partition. Specify different start cyl.\n");
2900Sstevel@tonic-gate 			return;
2910Sstevel@tonic-gate 		}
2920Sstevel@tonic-gate 		/*
2930Sstevel@tonic-gate 		 * Cyl offset for alternates partition was calculated before
2940Sstevel@tonic-gate 		 */
2950Sstevel@tonic-gate 		if (i < cyl_offset) {
2960Sstevel@tonic-gate 			fmt_print("\nWarning: Partition overlaps alternates ");
2970Sstevel@tonic-gate 			fmt_print("partition. Specify different start cyl.\n");
2980Sstevel@tonic-gate 			return;
2990Sstevel@tonic-gate 		}
3000Sstevel@tonic-gate 	}
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate #endif	/* defined(i386) */
3030Sstevel@tonic-gate 
3040Sstevel@tonic-gate 	/*
3050Sstevel@tonic-gate 	 * If user has entered a V_BACKUP tag then the partition
3060Sstevel@tonic-gate 	 * size should specify full disk capacity else
3070Sstevel@tonic-gate 	 * return an Error.
3080Sstevel@tonic-gate 	 */
3090Sstevel@tonic-gate 	if (tag == V_BACKUP) {
3107563SPrasad.Singamsetty@Sun.COM 		uint_t fullsz;
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 		fullsz = ncyl * nhead * nsect;
3130Sstevel@tonic-gate 		if (fullsz != j) {
3140Sstevel@tonic-gate 		/*
3150Sstevel@tonic-gate 		 * V_BACKUP Tag Partition != full disk capacity.
3160Sstevel@tonic-gate 		 * print useful messages.
3170Sstevel@tonic-gate 		 */
3180Sstevel@tonic-gate 		fmt_print("\nWarning: Partition with V_BACKUP tag should ");
3190Sstevel@tonic-gate 		fmt_print("specify full disk capacity. \n");
3200Sstevel@tonic-gate 		return;
3210Sstevel@tonic-gate 		}
3220Sstevel@tonic-gate 	}
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate 	/*
3260Sstevel@tonic-gate 	 * If the current partition is named, we can't change it.
3270Sstevel@tonic-gate 	 * We create a new current partition map instead.
3280Sstevel@tonic-gate 	 */
3290Sstevel@tonic-gate 	if (cur_parts->pinfo_name != NULL)
3300Sstevel@tonic-gate 		make_partition();
3310Sstevel@tonic-gate 	/*
3320Sstevel@tonic-gate 	 * Change the values.
3330Sstevel@tonic-gate 	 */
3340Sstevel@tonic-gate 	cur_parts->pinfo_map[num].dkl_cylno = i;
3350Sstevel@tonic-gate 	cur_parts->pinfo_map[num].dkl_nblk = j;
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3380Sstevel@tonic-gate 	cur_parts->vtoc.v_part[num].p_start = (daddr_t)(i * (nhead * nsect));
3390Sstevel@tonic-gate 	cur_parts->vtoc.v_part[num].p_size = (long)j;
3400Sstevel@tonic-gate #endif	/* defined(_SUNOS_VTOC_16) */
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	/*
3430Sstevel@tonic-gate 	 * Install the p_tag and p_flag values for this partition
3440Sstevel@tonic-gate 	 */
3450Sstevel@tonic-gate 	assert(cur_parts->vtoc.v_version == V_VERSION);
3460Sstevel@tonic-gate 	cur_parts->vtoc.v_part[num].p_tag = (ushort_t)tag;
3470Sstevel@tonic-gate 	cur_parts->vtoc.v_part[num].p_flag = (ushort_t)flag;
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate /*
3520Sstevel@tonic-gate  * This routine picks to closest partition table which matches the
3530Sstevel@tonic-gate  * selected disk type.  It is called each time the disk type is
3540Sstevel@tonic-gate  * changed.  If no match is found, it uses the first element
3550Sstevel@tonic-gate  * of the partition table.  If no table exists, a dummy is
3560Sstevel@tonic-gate  * created.
3570Sstevel@tonic-gate  */
3580Sstevel@tonic-gate int
get_partition()3590Sstevel@tonic-gate get_partition()
3600Sstevel@tonic-gate {
3610Sstevel@tonic-gate 	register struct partition_info *pptr;
3620Sstevel@tonic-gate 	register struct partition_info *parts;
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	/*
3650Sstevel@tonic-gate 	 * If there are no pre-defined maps for this disk type, it's
3660Sstevel@tonic-gate 	 * an error.
3670Sstevel@tonic-gate 	 */
3680Sstevel@tonic-gate 	parts = cur_dtype->dtype_plist;
3690Sstevel@tonic-gate 	if (parts == NULL) {
3700Sstevel@tonic-gate 		err_print("No defined partition tables.\n");
3710Sstevel@tonic-gate 		make_partition();
3720Sstevel@tonic-gate 		return (-1);
3730Sstevel@tonic-gate 	}
3740Sstevel@tonic-gate 	/*
3750Sstevel@tonic-gate 	 * Loop through the pre-defined maps searching for one which match
3760Sstevel@tonic-gate 	 * disk type.  If found copy it into unmamed partition.
3770Sstevel@tonic-gate 	 */
3780Sstevel@tonic-gate 	enter_critical();
3790Sstevel@tonic-gate 	for (pptr = parts; pptr != NULL; pptr = pptr->pinfo_next) {
3800Sstevel@tonic-gate 	    if (cur_dtype->dtype_asciilabel) {
3810Sstevel@tonic-gate 		if (pptr->pinfo_name != NULL && strcmp(pptr->pinfo_name,
3820Sstevel@tonic-gate 				cur_dtype->dtype_asciilabel) == 0) {
3830Sstevel@tonic-gate 			/*
3840Sstevel@tonic-gate 			 * Set current partition and name it.
3850Sstevel@tonic-gate 			 */
3860Sstevel@tonic-gate 			cur_disk->disk_parts = cur_parts = pptr;
3870Sstevel@tonic-gate 			cur_parts->pinfo_name = pptr->pinfo_name;
3880Sstevel@tonic-gate 			exit_critical();
3890Sstevel@tonic-gate 			return (0);
3900Sstevel@tonic-gate 		}
3910Sstevel@tonic-gate 	    }
3920Sstevel@tonic-gate 	}
3930Sstevel@tonic-gate 	/*
3940Sstevel@tonic-gate 	 * If we couldn't find a match, take the first one.
3950Sstevel@tonic-gate 	 * Set current partition and name it.
3960Sstevel@tonic-gate 	 */
3970Sstevel@tonic-gate 	cur_disk->disk_parts = cur_parts = cur_dtype->dtype_plist;
3980Sstevel@tonic-gate 	cur_parts->pinfo_name = parts->pinfo_name;
3990Sstevel@tonic-gate 	exit_critical();
4000Sstevel@tonic-gate 	return (0);
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate /*
4050Sstevel@tonic-gate  * This routine creates a new partition map and sets it current.  If there
4060Sstevel@tonic-gate  * was a current map, the new map starts out identical to it.  Otherwise
4070Sstevel@tonic-gate  * the new map starts out all zeroes.
4080Sstevel@tonic-gate  */
4090Sstevel@tonic-gate void
make_partition()4100Sstevel@tonic-gate make_partition()
4110Sstevel@tonic-gate {
4120Sstevel@tonic-gate 	register struct partition_info *pptr, *parts;
4130Sstevel@tonic-gate 	int	i;
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 	/*
4160Sstevel@tonic-gate 	 * Lock out interrupts so the lists don't get mangled.
4170Sstevel@tonic-gate 	 */
4180Sstevel@tonic-gate 	enter_critical();
4190Sstevel@tonic-gate 	/*
4200Sstevel@tonic-gate 	 * Get space for for the new map and link it into the list
4210Sstevel@tonic-gate 	 * of maps for the current disk type.
4220Sstevel@tonic-gate 	 */
4230Sstevel@tonic-gate 	pptr = (struct partition_info *)zalloc(sizeof (struct partition_info));
4240Sstevel@tonic-gate 	parts = cur_dtype->dtype_plist;
4250Sstevel@tonic-gate 	if (parts == NULL) {
4260Sstevel@tonic-gate 		cur_dtype->dtype_plist = pptr;
4270Sstevel@tonic-gate 	} else {
4280Sstevel@tonic-gate 		while (parts->pinfo_next != NULL) {
4290Sstevel@tonic-gate 			parts = parts->pinfo_next;
4300Sstevel@tonic-gate 		}
4310Sstevel@tonic-gate 		parts->pinfo_next = pptr;
4320Sstevel@tonic-gate 		pptr->pinfo_next = NULL;
4330Sstevel@tonic-gate 	}
4340Sstevel@tonic-gate 	/*
4350Sstevel@tonic-gate 	 * If there was a current map, copy its values.
4360Sstevel@tonic-gate 	 */
4370Sstevel@tonic-gate 	if (cur_label == L_TYPE_EFI) {
4380Sstevel@tonic-gate 	    struct dk_gpt	*map;
4390Sstevel@tonic-gate 	    int			nparts;
4400Sstevel@tonic-gate 	    int			size;
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	    nparts = cur_parts->etoc->efi_nparts;
4430Sstevel@tonic-gate 	    size = sizeof (struct dk_part) * nparts + sizeof (struct dk_gpt);
4440Sstevel@tonic-gate 	    map = zalloc(size);
4450Sstevel@tonic-gate 	    (void) memcpy(map, cur_parts->etoc, size);
4460Sstevel@tonic-gate 	    pptr->etoc = map;
4470Sstevel@tonic-gate 	    cur_disk->disk_parts = cur_parts = pptr;
4480Sstevel@tonic-gate 	    exit_critical();
4490Sstevel@tonic-gate 	    return;
4500Sstevel@tonic-gate 	}
4510Sstevel@tonic-gate 	if (cur_parts != NULL) {
4520Sstevel@tonic-gate 		for (i = 0; i < NDKMAP; i++) {
4530Sstevel@tonic-gate 			pptr->pinfo_map[i] = cur_parts->pinfo_map[i];
4540Sstevel@tonic-gate 		}
4550Sstevel@tonic-gate 		pptr->vtoc = cur_parts->vtoc;
4560Sstevel@tonic-gate 	} else {
4570Sstevel@tonic-gate 		/*
4580Sstevel@tonic-gate 		 * Otherwise set initial default vtoc values
4590Sstevel@tonic-gate 		 */
4600Sstevel@tonic-gate 		set_vtoc_defaults(pptr);
4610Sstevel@tonic-gate 	}
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	/*
4640Sstevel@tonic-gate 	 * Make the new one current.
4650Sstevel@tonic-gate 	 */
4660Sstevel@tonic-gate 	cur_disk->disk_parts = cur_parts = pptr;
4670Sstevel@tonic-gate 	exit_critical();
4680Sstevel@tonic-gate }
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate /*
4720Sstevel@tonic-gate  * This routine deletes a partition map from the list of maps for
4730Sstevel@tonic-gate  * the given disk type.
4740Sstevel@tonic-gate  */
4750Sstevel@tonic-gate void
delete_partition(struct partition_info * parts)4760Sstevel@tonic-gate delete_partition(struct partition_info *parts)
4770Sstevel@tonic-gate {
4780Sstevel@tonic-gate 	struct	partition_info *pptr;
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 	/*
4810Sstevel@tonic-gate 	 * If there isn't a current map, it's an error.
4820Sstevel@tonic-gate 	 */
4830Sstevel@tonic-gate 	if (cur_dtype->dtype_plist == NULL) {
4840Sstevel@tonic-gate 		err_print("Error: unexpected null partition list.\n");
4850Sstevel@tonic-gate 		fullabort();
4860Sstevel@tonic-gate 	}
4870Sstevel@tonic-gate 	/*
4880Sstevel@tonic-gate 	 * Remove the map from the list.
4890Sstevel@tonic-gate 	 */
4900Sstevel@tonic-gate 	if (cur_dtype->dtype_plist == parts)
4910Sstevel@tonic-gate 		cur_dtype->dtype_plist = parts->pinfo_next;
4920Sstevel@tonic-gate 	else {
4930Sstevel@tonic-gate 		for (pptr = cur_dtype->dtype_plist; pptr->pinfo_next != parts;
4940Sstevel@tonic-gate 		    pptr = pptr->pinfo_next)
4950Sstevel@tonic-gate 			;
4960Sstevel@tonic-gate 		pptr->pinfo_next = parts->pinfo_next;
4970Sstevel@tonic-gate 	}
4980Sstevel@tonic-gate 	/*
4990Sstevel@tonic-gate 	 * Free the space it was using.
5000Sstevel@tonic-gate 	 */
5010Sstevel@tonic-gate 	destroy_data((char *)parts);
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate /*
5060Sstevel@tonic-gate  * Set all partition vtoc fields to defaults
5070Sstevel@tonic-gate  */
5080Sstevel@tonic-gate void
set_vtoc_defaults(struct partition_info * part)5090Sstevel@tonic-gate set_vtoc_defaults(struct partition_info *part)
5100Sstevel@tonic-gate {
5110Sstevel@tonic-gate 	int	i;
5120Sstevel@tonic-gate 
5130Sstevel@tonic-gate 	bzero((caddr_t)&part->vtoc, sizeof (struct dk_vtoc));
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 	part->vtoc.v_version = V_VERSION;
5160Sstevel@tonic-gate 	part->vtoc.v_nparts = NDKMAP;
5170Sstevel@tonic-gate 	part->vtoc.v_sanity = VTOC_SANE;
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
5200Sstevel@tonic-gate 		part->vtoc.v_part[i].p_tag = default_vtoc_map[i].p_tag;
5210Sstevel@tonic-gate 		part->vtoc.v_part[i].p_flag = default_vtoc_map[i].p_flag;
5220Sstevel@tonic-gate 	}
5230Sstevel@tonic-gate }
524