xref: /titanic_44/usr/src/cmd/format/menu_command.c (revision 9aa4340a44380b7c8ec138cd722e0c9bf086c266)
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
5698107ecSlh195018  * Common Development and Distribution License (the "License").
6698107ecSlh195018  * 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  */
217c478bd9Sstevel@tonic-gate /*
229ca9c420SSheng-Liang Eric Zhang  * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
2333f5ff17SMilan Jurik  * Copyright 2012 Milan Jurik. All rights reserved.
24e088753cSToomas Soome  * Copyright 2014 Toomas Soome <tsoome@me.com>
25*9aa4340aSHans Rosenfeld  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * This file contains functions that implement the command menu commands.
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include "global.h"
337c478bd9Sstevel@tonic-gate #include <time.h>
347c478bd9Sstevel@tonic-gate #include <sys/time.h>
357c478bd9Sstevel@tonic-gate #include <sys/resource.h>
367c478bd9Sstevel@tonic-gate #include <sys/wait.h>
377c478bd9Sstevel@tonic-gate #include <strings.h>
387c478bd9Sstevel@tonic-gate #include <signal.h>
397c478bd9Sstevel@tonic-gate #include <stdlib.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #if defined(sparc)
437c478bd9Sstevel@tonic-gate #include <sys/hdio.h>
447c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #include "main.h"
477c478bd9Sstevel@tonic-gate #include "analyze.h"
487c478bd9Sstevel@tonic-gate #include "menu.h"
497c478bd9Sstevel@tonic-gate #include "menu_command.h"
507c478bd9Sstevel@tonic-gate #include "menu_defect.h"
517c478bd9Sstevel@tonic-gate #include "menu_partition.h"
527c478bd9Sstevel@tonic-gate #include "param.h"
537c478bd9Sstevel@tonic-gate #include "misc.h"
547c478bd9Sstevel@tonic-gate #include "label.h"
557c478bd9Sstevel@tonic-gate #include "startup.h"
567c478bd9Sstevel@tonic-gate #include "partition.h"
577c478bd9Sstevel@tonic-gate #include "prompts.h"
583e1bd7a2Ssjelinek #include "checkdev.h"
597c478bd9Sstevel@tonic-gate #include "io.h"
607c478bd9Sstevel@tonic-gate #include "ctlr_scsi.h"
617c478bd9Sstevel@tonic-gate #include "auto_sense.h"
627c478bd9Sstevel@tonic-gate #include "modify_partition.h"
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate extern	struct menu_item menu_partition[];
667c478bd9Sstevel@tonic-gate extern	struct menu_item menu_analyze[];
677c478bd9Sstevel@tonic-gate extern	struct menu_item menu_defect[];
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * Choices for the p_tag vtoc field
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate slist_t	ptag_choices[] = {
737c478bd9Sstevel@tonic-gate 	{ "unassigned",	"",	V_UNASSIGNED	},
747c478bd9Sstevel@tonic-gate 	{ "boot",	"",	V_BOOT		},
757c478bd9Sstevel@tonic-gate 	{ "root",	"",	V_ROOT		},
767c478bd9Sstevel@tonic-gate 	{ "swap",	"",	V_SWAP		},
777c478bd9Sstevel@tonic-gate 	{ "usr",	"",	V_USR		},
787c478bd9Sstevel@tonic-gate 	{ "backup",	"",	V_BACKUP	},
797c478bd9Sstevel@tonic-gate 	{ "stand",	"",	V_STAND		},
807c478bd9Sstevel@tonic-gate 	{ "var",	"",	V_VAR		},
817c478bd9Sstevel@tonic-gate 	{ "home",	"",	V_HOME		},
827c478bd9Sstevel@tonic-gate 	{ "alternates",	"",	V_ALTSCTR	},
837c478bd9Sstevel@tonic-gate 	{ "reserved",	"",	V_RESERVED	},
84e088753cSToomas Soome 	{ "system",	"",	V_SYSTEM	},
85e088753cSToomas Soome 	{ "BIOS_boot",	"",	V_BIOS_BOOT	},
867c478bd9Sstevel@tonic-gate 	{ NULL }
877c478bd9Sstevel@tonic-gate };
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate /*
917c478bd9Sstevel@tonic-gate  * Choices for the p_flag vtoc field
927c478bd9Sstevel@tonic-gate  */
937c478bd9Sstevel@tonic-gate slist_t	pflag_choices[] = {
947c478bd9Sstevel@tonic-gate 	{ "wm",	"read-write, mountable",	0		},
957c478bd9Sstevel@tonic-gate 	{ "wu",	"read-write, unmountable",	V_UNMNT		},
967c478bd9Sstevel@tonic-gate 	{ "rm",	"read-only, mountable",		V_RONLY		},
977c478bd9Sstevel@tonic-gate 	{ "ru",	"read-only, unmountable",	V_RONLY|V_UNMNT	},
987c478bd9Sstevel@tonic-gate 	{ NULL }
997c478bd9Sstevel@tonic-gate };
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate /*
1037c478bd9Sstevel@tonic-gate  * This routine implements the 'disk' command.  It allows the user to
1047c478bd9Sstevel@tonic-gate  * select a disk to be current.  The list of choices is the list of
1057c478bd9Sstevel@tonic-gate  * disks that were found at startup time.
1067c478bd9Sstevel@tonic-gate  */
1077c478bd9Sstevel@tonic-gate int
c_disk()1087c478bd9Sstevel@tonic-gate c_disk()
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate 	struct disk_info	*disk;
1117c478bd9Sstevel@tonic-gate 	u_ioparam_t		ioparam;
1127c478bd9Sstevel@tonic-gate 	int			i;
1137c478bd9Sstevel@tonic-gate 	int			ndisks = 0;
1147c478bd9Sstevel@tonic-gate 	int			blind_select = 0;
1157c478bd9Sstevel@tonic-gate 	int			deflt;
1167c478bd9Sstevel@tonic-gate 	int			index;
1177c478bd9Sstevel@tonic-gate 	int			*defltptr = NULL;
1187c478bd9Sstevel@tonic-gate 	int			more = 0;
1197c478bd9Sstevel@tonic-gate 	int			more_quit = 0;
1207c478bd9Sstevel@tonic-gate 	int			one_line = 0;
1217c478bd9Sstevel@tonic-gate 	int			tty_lines;
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate /*
1247c478bd9Sstevel@tonic-gate  * This buffer holds the check() prompt that verifies we've got the right
1257c478bd9Sstevel@tonic-gate  * disk when performing a blind selection.  The size should be sufficient
1267c478bd9Sstevel@tonic-gate  * to hold the prompt string, plus 256 characters for the disk name -
1277c478bd9Sstevel@tonic-gate  * way more than should ever be necessary.  See the #define in misc.h.
1287c478bd9Sstevel@tonic-gate  */
1297c478bd9Sstevel@tonic-gate 	char			chk_buf[BLIND_SELECT_VER_PROMPT];
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	if (istokenpresent()) {
1327c478bd9Sstevel@tonic-gate 		/*
1337c478bd9Sstevel@tonic-gate 		 * disk number to be selected is already in the
1347c478bd9Sstevel@tonic-gate 		 * input stream .
1357c478bd9Sstevel@tonic-gate 		 */
1367c478bd9Sstevel@tonic-gate 		TOKEN token, cleantoken;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 		/*
1397c478bd9Sstevel@tonic-gate 		 * Get the disk number the user has given.
1407c478bd9Sstevel@tonic-gate 		 */
1417c478bd9Sstevel@tonic-gate 		i = 0;
1427c478bd9Sstevel@tonic-gate 		for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
1437c478bd9Sstevel@tonic-gate 			i++;
1447c478bd9Sstevel@tonic-gate 		}
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.lower = 0;
1477c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.upper = i - 1;
1487c478bd9Sstevel@tonic-gate 		(void) gettoken(token);
1497c478bd9Sstevel@tonic-gate 		clean_token(cleantoken, token);
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 		/*
1527c478bd9Sstevel@tonic-gate 		 * Convert the token into an integer.
1537c478bd9Sstevel@tonic-gate 		 */
154342440ecSPrasad Singamsetty 		if (geti(cleantoken, &index, (int *)NULL))
1557c478bd9Sstevel@tonic-gate 			return (0);
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 		/*
1587c478bd9Sstevel@tonic-gate 		 * Check to be sure it is within the legal bounds.
1597c478bd9Sstevel@tonic-gate 		 */
1607c478bd9Sstevel@tonic-gate 		if ((index < 0) || (index >= i)) {
1617c478bd9Sstevel@tonic-gate 			err_print("`%d' is out of range.\n", index);
1627c478bd9Sstevel@tonic-gate 			return (0);
1637c478bd9Sstevel@tonic-gate 		}
1647c478bd9Sstevel@tonic-gate 		goto checkdisk;
1657c478bd9Sstevel@tonic-gate 	}
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	fmt_print("\n\nAVAILABLE DISK SELECTIONS:\n");
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	i = 0;
1707c478bd9Sstevel@tonic-gate 	if ((option_f == (char *)NULL) && isatty(0) == 1 && isatty(1) == 1) {
1717c478bd9Sstevel@tonic-gate 		/*
1727c478bd9Sstevel@tonic-gate 		 * We have a real terminal for std input and output, enable
1737c478bd9Sstevel@tonic-gate 		 * more style of output for disk selection list.
1747c478bd9Sstevel@tonic-gate 		 */
1757c478bd9Sstevel@tonic-gate 		more = 1;
1767c478bd9Sstevel@tonic-gate 		tty_lines = get_tty_lines();
1777c478bd9Sstevel@tonic-gate 		enter_critical();
1787c478bd9Sstevel@tonic-gate 		echo_off();
1797c478bd9Sstevel@tonic-gate 		charmode_on();
1807c478bd9Sstevel@tonic-gate 		exit_critical();
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	/*
1847c478bd9Sstevel@tonic-gate 	 * Loop through the list of found disks.
1857c478bd9Sstevel@tonic-gate 	 */
1867c478bd9Sstevel@tonic-gate 	for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
1877c478bd9Sstevel@tonic-gate 		/*
1887c478bd9Sstevel@tonic-gate 		 * If using more output, account 2 lines for each disk.
1897c478bd9Sstevel@tonic-gate 		 */
1907c478bd9Sstevel@tonic-gate 		if (more && !more_quit && i && (one_line ||
1917c478bd9Sstevel@tonic-gate 		    ((2 * i + 1) % (tty_lines - 2) <= 1))) {
1927c478bd9Sstevel@tonic-gate 			int	c;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 			/*
1957c478bd9Sstevel@tonic-gate 			 * Get the next character.
1967c478bd9Sstevel@tonic-gate 			 */
1977c478bd9Sstevel@tonic-gate 			fmt_print("- hit space for more or s to select - ");
1987c478bd9Sstevel@tonic-gate 			c = getchar();
1997c478bd9Sstevel@tonic-gate 			fmt_print("\015");
2007c478bd9Sstevel@tonic-gate 			one_line = 0;
2017c478bd9Sstevel@tonic-gate 			/*
2027c478bd9Sstevel@tonic-gate 			 * Handle display one line command
2037c478bd9Sstevel@tonic-gate 			 * (return key)
2047c478bd9Sstevel@tonic-gate 			 */
2057c478bd9Sstevel@tonic-gate 			if (c == '\012') {
2067c478bd9Sstevel@tonic-gate 				one_line++;
2077c478bd9Sstevel@tonic-gate 			}
2087c478bd9Sstevel@tonic-gate 			/* Handle Quit command */
2097c478bd9Sstevel@tonic-gate 			if (c == 'q') {
2107c478bd9Sstevel@tonic-gate 				fmt_print(
2117c478bd9Sstevel@tonic-gate 				"                       \015");
2127c478bd9Sstevel@tonic-gate 				more_quit++;
2137c478bd9Sstevel@tonic-gate 			}
2147c478bd9Sstevel@tonic-gate 			/* Handle ^D command */
2157c478bd9Sstevel@tonic-gate 			if (c == '\004')
2167c478bd9Sstevel@tonic-gate 				fullabort();
2177c478bd9Sstevel@tonic-gate 			/* or get on with the show */
2187c478bd9Sstevel@tonic-gate 			if (c == 's' || c == 'S') {
2197c478bd9Sstevel@tonic-gate 				fmt_print("%80s\n", " ");
2207c478bd9Sstevel@tonic-gate 				break;
2217c478bd9Sstevel@tonic-gate 			}
2227c478bd9Sstevel@tonic-gate 		}
2237c478bd9Sstevel@tonic-gate 		/*
2247c478bd9Sstevel@tonic-gate 		 * If this is the current disk, mark it as
2257c478bd9Sstevel@tonic-gate 		 * the default.
2267c478bd9Sstevel@tonic-gate 		 */
2277c478bd9Sstevel@tonic-gate 		if (cur_disk == disk) {
2287c478bd9Sstevel@tonic-gate 			deflt = i;
2297c478bd9Sstevel@tonic-gate 			defltptr = &deflt;
2307c478bd9Sstevel@tonic-gate 		}
2317c478bd9Sstevel@tonic-gate 		if (!more || !more_quit)
2327c478bd9Sstevel@tonic-gate 			pr_diskline(disk, i);
2337c478bd9Sstevel@tonic-gate 		i++;
2347c478bd9Sstevel@tonic-gate 	}
2357c478bd9Sstevel@tonic-gate 	if (more) {
2367c478bd9Sstevel@tonic-gate 		enter_critical();
2377c478bd9Sstevel@tonic-gate 		charmode_off();
2387c478bd9Sstevel@tonic-gate 		echo_on();
2397c478bd9Sstevel@tonic-gate 		exit_critical();
2407c478bd9Sstevel@tonic-gate 	}
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	/*
2437c478bd9Sstevel@tonic-gate 	 * Determine total number of disks, and ask the user which disk he
2447c478bd9Sstevel@tonic-gate 	 * would like to make current.
2457c478bd9Sstevel@tonic-gate 	 */
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
2487c478bd9Sstevel@tonic-gate 		ndisks++;
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	ioparam.io_bounds.lower = 0;
2527c478bd9Sstevel@tonic-gate 	ioparam.io_bounds.upper = ndisks - 1;
2537c478bd9Sstevel@tonic-gate 	index = input(FIO_INT, "Specify disk (enter its number)", ':',
2547c478bd9Sstevel@tonic-gate 	    &ioparam, defltptr, DATA_INPUT);
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	if (index >= i) {
2577c478bd9Sstevel@tonic-gate 		blind_select = 1;
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	/*
2617c478bd9Sstevel@tonic-gate 	 * Find the disk chosen.  Search through controllers/disks
2627c478bd9Sstevel@tonic-gate 	 * in the same original order, so we match what the user
2637c478bd9Sstevel@tonic-gate 	 * chose.
2647c478bd9Sstevel@tonic-gate 	 */
2657c478bd9Sstevel@tonic-gate checkdisk:
2667c478bd9Sstevel@tonic-gate 	i = 0;
2677c478bd9Sstevel@tonic-gate 	for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
2687c478bd9Sstevel@tonic-gate 		if (i == index)
2697c478bd9Sstevel@tonic-gate 			goto found;
2707c478bd9Sstevel@tonic-gate 		i++;
2717c478bd9Sstevel@tonic-gate 	}
2727c478bd9Sstevel@tonic-gate 	/*
2737c478bd9Sstevel@tonic-gate 	 * Should never happen.
2747c478bd9Sstevel@tonic-gate 	 */
2757c478bd9Sstevel@tonic-gate 	impossible("no disk found");
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate found:
2787c478bd9Sstevel@tonic-gate 	if (blind_select) {
2797c478bd9Sstevel@tonic-gate 		(void) snprintf(chk_buf, sizeof (chk_buf),
2807c478bd9Sstevel@tonic-gate "Disk %s selected - is this the desired disk? ", disk->disk_name);
2817c478bd9Sstevel@tonic-gate 		if (check(chk_buf)) {
2827c478bd9Sstevel@tonic-gate 			return (-1);
2837c478bd9Sstevel@tonic-gate 		}
2847c478bd9Sstevel@tonic-gate 	}
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	/*
2877c478bd9Sstevel@tonic-gate 	 * Update the state.  We lock out interrupts so the state can't
2887c478bd9Sstevel@tonic-gate 	 * get half-updated.
2897c478bd9Sstevel@tonic-gate 	 */
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 	enter_critical();
2927c478bd9Sstevel@tonic-gate 	init_globals(disk);
2937c478bd9Sstevel@tonic-gate 	exit_critical();
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	/*
2967c478bd9Sstevel@tonic-gate 	 * If type unknown and interactive, ask user to specify type.
2977c478bd9Sstevel@tonic-gate 	 * Also, set partition table (best guess) too.
2987c478bd9Sstevel@tonic-gate 	 */
2997c478bd9Sstevel@tonic-gate 	if (!option_f && ncyl == 0 && nhead == 0 && nsect == 0 &&
3007c478bd9Sstevel@tonic-gate 	    (disk->label_type != L_TYPE_EFI)) {
3017c478bd9Sstevel@tonic-gate 		(void) c_type();
3027c478bd9Sstevel@tonic-gate 	}
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	/*
3057c478bd9Sstevel@tonic-gate 	 * Get the Solaris Fdisk Partition information
3067c478bd9Sstevel@tonic-gate 	 */
3077c478bd9Sstevel@tonic-gate 	if (nhead != 0 && nsect != 0)
3087c478bd9Sstevel@tonic-gate 		(void) copy_solaris_part(&cur_disk->fdisk_part);
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	if ((cur_disk->label_type == L_TYPE_EFI) &&
3117c478bd9Sstevel@tonic-gate 	    (cur_disk->disk_parts->etoc->efi_flags &
3127c478bd9Sstevel@tonic-gate 	    EFI_GPT_PRIMARY_CORRUPT)) {
3137c478bd9Sstevel@tonic-gate 		err_print("Reading the primary EFI GPT label ");
3147c478bd9Sstevel@tonic-gate 		err_print("failed.  Using backup label.\n");
3157c478bd9Sstevel@tonic-gate 		err_print("Use the 'backup' command to restore ");
3167c478bd9Sstevel@tonic-gate 		err_print("the primary label.\n");
3177c478bd9Sstevel@tonic-gate 	}
3189daef70dSbo zhou - Sun Microsystems - Beijing China 
3199daef70dSbo zhou - Sun Microsystems - Beijing China #if defined(_SUNOS_VTOC_16)
3209daef70dSbo zhou - Sun Microsystems - Beijing China 	/*
3219daef70dSbo zhou - Sun Microsystems - Beijing China 	 * If there is no fdisk solaris partition.
3229daef70dSbo zhou - Sun Microsystems - Beijing China 	 */
3239daef70dSbo zhou - Sun Microsystems - Beijing China 	if (cur_disk->fdisk_part.numsect == 0) {
3249daef70dSbo zhou - Sun Microsystems - Beijing China 		err_print("No Solaris fdisk partition found.\n");
3259daef70dSbo zhou - Sun Microsystems - Beijing China 		goto exit;
3269daef70dSbo zhou - Sun Microsystems - Beijing China 	}
3279daef70dSbo zhou - Sun Microsystems - Beijing China #endif /* defined(_SUNOS_VTOC_16) */
3289daef70dSbo zhou - Sun Microsystems - Beijing China 
3297c478bd9Sstevel@tonic-gate 	/*
3307c478bd9Sstevel@tonic-gate 	 * If the label of the disk is marked dirty,
3317c478bd9Sstevel@tonic-gate 	 * see if they'd like to label the disk now.
3327c478bd9Sstevel@tonic-gate 	 */
3337c478bd9Sstevel@tonic-gate 	if (cur_disk->disk_flags & DSK_LABEL_DIRTY) {
3347c478bd9Sstevel@tonic-gate 		if (check("Disk not labeled.  Label it now") == 0) {
3357c478bd9Sstevel@tonic-gate 			if (write_label()) {
3367c478bd9Sstevel@tonic-gate 				err_print("Write label failed\n");
3377c478bd9Sstevel@tonic-gate 			} else {
3387c478bd9Sstevel@tonic-gate 				cur_disk->disk_flags &= ~DSK_LABEL_DIRTY;
3397c478bd9Sstevel@tonic-gate 			}
3407c478bd9Sstevel@tonic-gate 		}
3417c478bd9Sstevel@tonic-gate 	}
34260b0c6ebSbo zhou - Sun Microsystems - Beijing China exit:
3437c478bd9Sstevel@tonic-gate 	return (0);
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate /*
3477c478bd9Sstevel@tonic-gate  * This routine implements the 'type' command.  It allows the user to
3487c478bd9Sstevel@tonic-gate  * specify the type of the current disk.  It should be necessary only
3497c478bd9Sstevel@tonic-gate  * if the disk was not labelled or was somehow labelled incorrectly.
3507c478bd9Sstevel@tonic-gate  * The list of legal types for the disk comes from information that was
3517c478bd9Sstevel@tonic-gate  * in the data file.
3527c478bd9Sstevel@tonic-gate  */
3537c478bd9Sstevel@tonic-gate int
c_type()3547c478bd9Sstevel@tonic-gate c_type()
3557c478bd9Sstevel@tonic-gate {
3567c478bd9Sstevel@tonic-gate 	struct disk_type	*type, *tptr, *oldtype;
3577c478bd9Sstevel@tonic-gate 	u_ioparam_t		ioparam;
3587c478bd9Sstevel@tonic-gate 	int			i, index, deflt, *defltptr = NULL;
3597c478bd9Sstevel@tonic-gate 	struct disk_type	disk_type;
3607c478bd9Sstevel@tonic-gate 	struct disk_type	*d = &disk_type;
3617c478bd9Sstevel@tonic-gate 	int			first_disk;
3627c478bd9Sstevel@tonic-gate 	int			auto_conf_choice;
3637c478bd9Sstevel@tonic-gate 	int			other_choice;
3647c478bd9Sstevel@tonic-gate 	struct dk_label		label;
3657c478bd9Sstevel@tonic-gate 	struct efi_info		efi_info;
3667c478bd9Sstevel@tonic-gate 	uint64_t		maxLBA;
3677c478bd9Sstevel@tonic-gate 	char			volname[LEN_DKL_VVOL];
3687c478bd9Sstevel@tonic-gate 	int			volinit = 0;
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	/*
3717c478bd9Sstevel@tonic-gate 	 * There must be a current disk.
3727c478bd9Sstevel@tonic-gate 	 */
3737c478bd9Sstevel@tonic-gate 	if (cur_disk == NULL) {
3747c478bd9Sstevel@tonic-gate 		err_print("Current Disk is not set.\n");
3757c478bd9Sstevel@tonic-gate 		return (-1);
3767c478bd9Sstevel@tonic-gate 	}
3777c478bd9Sstevel@tonic-gate 	oldtype = cur_disk->disk_type;
3787c478bd9Sstevel@tonic-gate 	type = cur_ctype->ctype_dlist;
3797c478bd9Sstevel@tonic-gate 	/*
3807c478bd9Sstevel@tonic-gate 	 * Print out the list of choices.
3817c478bd9Sstevel@tonic-gate 	 */
3827c478bd9Sstevel@tonic-gate 	fmt_print("\n\nAVAILABLE DRIVE TYPES:\n");
3837c478bd9Sstevel@tonic-gate 	first_disk = 0;
3847c478bd9Sstevel@tonic-gate 	if (cur_ctype->ctype_ctype == DKC_SCSI_CCS) {
3857c478bd9Sstevel@tonic-gate 		auto_conf_choice = 0;
3867c478bd9Sstevel@tonic-gate 		fmt_print("        %d. Auto configure\n", first_disk++);
3877c478bd9Sstevel@tonic-gate 	} else {
3887c478bd9Sstevel@tonic-gate 		auto_conf_choice = -1;
3897c478bd9Sstevel@tonic-gate 	}
39065908c77Syu, larry liu - Sun Microsystems - Beijing China 
3917c478bd9Sstevel@tonic-gate 	i = first_disk;
3927c478bd9Sstevel@tonic-gate 	for (tptr = type; tptr != NULL; tptr = tptr->dtype_next) {
3937c478bd9Sstevel@tonic-gate 		/*
3947c478bd9Sstevel@tonic-gate 		 * If we pass the current type, mark it to be the default.
3957c478bd9Sstevel@tonic-gate 		 */
3967c478bd9Sstevel@tonic-gate 		if (cur_dtype == tptr) {
3977c478bd9Sstevel@tonic-gate 			deflt = i;
3987c478bd9Sstevel@tonic-gate 			defltptr = &deflt;
3997c478bd9Sstevel@tonic-gate 		}
4007c478bd9Sstevel@tonic-gate 		if (cur_disk->label_type == L_TYPE_EFI) {
4017c478bd9Sstevel@tonic-gate 			continue;
4027c478bd9Sstevel@tonic-gate 		}
4037c478bd9Sstevel@tonic-gate 		if (tptr->dtype_asciilabel)
40465908c77Syu, larry liu - Sun Microsystems - Beijing China 			fmt_print("        %d. %s\n", i++,
40565908c77Syu, larry liu - Sun Microsystems - Beijing China 			    tptr->dtype_asciilabel);
4067c478bd9Sstevel@tonic-gate 	}
4077c478bd9Sstevel@tonic-gate 	other_choice = i;
4087c478bd9Sstevel@tonic-gate 	fmt_print("        %d. other\n", i);
4097c478bd9Sstevel@tonic-gate 	ioparam.io_bounds.lower = 0;
4107c478bd9Sstevel@tonic-gate 	ioparam.io_bounds.upper = i;
4117c478bd9Sstevel@tonic-gate 	/*
4127c478bd9Sstevel@tonic-gate 	 * Ask the user which type the disk is.
4137c478bd9Sstevel@tonic-gate 	 */
4147c478bd9Sstevel@tonic-gate 	index = input(FIO_INT, "Specify disk type (enter its number)", ':',
4157c478bd9Sstevel@tonic-gate 	    &ioparam, defltptr, DATA_INPUT);
4167c478bd9Sstevel@tonic-gate 	/*
4177c478bd9Sstevel@tonic-gate 	 * Find the type s/he chose.
4187c478bd9Sstevel@tonic-gate 	 */
4197c478bd9Sstevel@tonic-gate 	if (index == auto_conf_choice) {
4207c478bd9Sstevel@tonic-gate 		float			scaled;
421342440ecSPrasad Singamsetty 		diskaddr_t		nblks;
4227c478bd9Sstevel@tonic-gate 		int			nparts;
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 		/*
4257c478bd9Sstevel@tonic-gate 		 * User chose "auto configure".
4267c478bd9Sstevel@tonic-gate 		 */
4277c478bd9Sstevel@tonic-gate 		(void) strcpy(x86_devname, cur_disk->disk_name);
4287c478bd9Sstevel@tonic-gate 		switch (cur_disk->label_type) {
4297c478bd9Sstevel@tonic-gate 		case L_TYPE_SOLARIS:
4307c478bd9Sstevel@tonic-gate 			if ((tptr = auto_sense(cur_file, 1, &label)) == NULL) {
4317c478bd9Sstevel@tonic-gate 				err_print("Auto configure failed\n");
4327c478bd9Sstevel@tonic-gate 				return (-1);
4337c478bd9Sstevel@tonic-gate 			}
4347c478bd9Sstevel@tonic-gate 			fmt_print("%s: configured with capacity of ",
4357c478bd9Sstevel@tonic-gate 			    cur_disk->disk_name);
43665908c77Syu, larry liu - Sun Microsystems - Beijing China 			nblks = (diskaddr_t)tptr->dtype_ncyl *
43765908c77Syu, larry liu - Sun Microsystems - Beijing China 			    tptr->dtype_nhead * tptr->dtype_nsect;
4387c478bd9Sstevel@tonic-gate 			scaled = bn2mb(nblks);
4397c478bd9Sstevel@tonic-gate 			if (scaled > 1024.0) {
4407c478bd9Sstevel@tonic-gate 				fmt_print("%1.2fGB\n", scaled/1024.0);
4417c478bd9Sstevel@tonic-gate 			} else {
4427c478bd9Sstevel@tonic-gate 				fmt_print("%1.2fMB\n", scaled);
4437c478bd9Sstevel@tonic-gate 			}
4447c478bd9Sstevel@tonic-gate 			fmt_print("<%s cyl %d alt %d hd %d sec %d>\n",
4457c478bd9Sstevel@tonic-gate 			    tptr->dtype_asciilabel, tptr->dtype_ncyl,
4467c478bd9Sstevel@tonic-gate 			    tptr->dtype_acyl, tptr->dtype_nhead,
4477c478bd9Sstevel@tonic-gate 			    tptr->dtype_nsect);
4487c478bd9Sstevel@tonic-gate 			break;
4497c478bd9Sstevel@tonic-gate 		case L_TYPE_EFI:
45065908c77Syu, larry liu - Sun Microsystems - Beijing China 			if ((tptr = auto_efi_sense(cur_file, &efi_info))
45165908c77Syu, larry liu - Sun Microsystems - Beijing China 			    == NULL) {
4527c478bd9Sstevel@tonic-gate 				err_print("Auto configure failed\n");
4537c478bd9Sstevel@tonic-gate 				return (-1);
4547c478bd9Sstevel@tonic-gate 			}
4557c478bd9Sstevel@tonic-gate 			fmt_print("%s: configured with capacity of ",
4567c478bd9Sstevel@tonic-gate 			    cur_disk->disk_name);
4577c478bd9Sstevel@tonic-gate 			scaled = bn2mb(efi_info.capacity);
4587c478bd9Sstevel@tonic-gate 			if (scaled > 1024.0) {
4597c478bd9Sstevel@tonic-gate 				fmt_print("%1.2fGB\n", scaled/1024.0);
4607c478bd9Sstevel@tonic-gate 			} else {
4617c478bd9Sstevel@tonic-gate 				fmt_print("%1.2fMB\n", scaled);
4627c478bd9Sstevel@tonic-gate 			}
46365908c77Syu, larry liu - Sun Microsystems - Beijing China 			cur_blksz = efi_info.e_parts->efi_lbasize;
4647c478bd9Sstevel@tonic-gate 			print_efi_string(efi_info.vendor, efi_info.product,
4657c478bd9Sstevel@tonic-gate 			    efi_info.revision, efi_info.capacity);
4667c478bd9Sstevel@tonic-gate 			fmt_print("\n");
4677c478bd9Sstevel@tonic-gate 			for (nparts = 0; nparts < cur_parts->etoc->efi_nparts;
4687c478bd9Sstevel@tonic-gate 			    nparts++) {
4697c478bd9Sstevel@tonic-gate 				if (cur_parts->etoc->efi_parts[nparts].p_tag ==
4707c478bd9Sstevel@tonic-gate 				    V_RESERVED) {
47165908c77Syu, larry liu - Sun Microsystems - Beijing China 					if (cur_parts->etoc->efi_parts[nparts].
47265908c77Syu, larry liu - Sun Microsystems - Beijing China 					    p_name) {
4737c478bd9Sstevel@tonic-gate 						(void) strcpy(volname,
47465908c77Syu, larry liu - Sun Microsystems - Beijing China 						    cur_parts->etoc->efi_parts
47565908c77Syu, larry liu - Sun Microsystems - Beijing China 						    [nparts].p_name);
4767c478bd9Sstevel@tonic-gate 						volinit = 1;
4777c478bd9Sstevel@tonic-gate 					}
4787c478bd9Sstevel@tonic-gate 					break;
4797c478bd9Sstevel@tonic-gate 				}
4807c478bd9Sstevel@tonic-gate 			}
4817c478bd9Sstevel@tonic-gate 			enter_critical();
4825fadadd1SNikko He 			if (delete_disk_type(cur_disk->disk_type) != 0) {
4835fadadd1SNikko He 				fmt_print("Autoconfiguration failed.\n");
4845fadadd1SNikko He 				return (-1);
4855fadadd1SNikko He 			}
4867c478bd9Sstevel@tonic-gate 			cur_disk->disk_type = tptr;
4877c478bd9Sstevel@tonic-gate 			cur_disk->disk_parts = tptr->dtype_plist;
4887c478bd9Sstevel@tonic-gate 			init_globals(cur_disk);
4897c478bd9Sstevel@tonic-gate 			exit_critical();
4907c478bd9Sstevel@tonic-gate 			if (volinit) {
49165908c77Syu, larry liu - Sun Microsystems - Beijing China 				for (nparts = 0; nparts <
49265908c77Syu, larry liu - Sun Microsystems - Beijing China 				    cur_parts->etoc->efi_nparts; nparts++) {
4937c478bd9Sstevel@tonic-gate 				if (cur_parts->etoc->efi_parts[nparts].p_tag ==
4947c478bd9Sstevel@tonic-gate 				    V_RESERVED) {
4957c478bd9Sstevel@tonic-gate 				(void) strcpy(
4967c478bd9Sstevel@tonic-gate 				    cur_parts->etoc->efi_parts[nparts].p_name,
4977c478bd9Sstevel@tonic-gate 				    volname);
4987c478bd9Sstevel@tonic-gate 				(void) strlcpy(cur_disk->v_volume, volname,
4997c478bd9Sstevel@tonic-gate 				    LEN_DKL_VVOL);
5007c478bd9Sstevel@tonic-gate 				break;
5017c478bd9Sstevel@tonic-gate 				}
5027c478bd9Sstevel@tonic-gate 				}
5037c478bd9Sstevel@tonic-gate 			}
5047c478bd9Sstevel@tonic-gate 			return (0);
5057c478bd9Sstevel@tonic-gate 		default:
5067c478bd9Sstevel@tonic-gate 			/* Should never happen */
5077c478bd9Sstevel@tonic-gate 			return (-1);
5087c478bd9Sstevel@tonic-gate 		}
5097c478bd9Sstevel@tonic-gate 	} else if ((index == other_choice) && (cur_label == L_TYPE_SOLARIS)) {
5107c478bd9Sstevel@tonic-gate 		/*
5117c478bd9Sstevel@tonic-gate 		 * User chose "other".
5127c478bd9Sstevel@tonic-gate 		 * Get the standard information on the new type.
5137c478bd9Sstevel@tonic-gate 		 * Put all information in a tmp structure, in
5147c478bd9Sstevel@tonic-gate 		 * case user aborts.
5157c478bd9Sstevel@tonic-gate 		 */
5167c478bd9Sstevel@tonic-gate 		bzero((char *)d, sizeof (struct disk_type));
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 		d->dtype_ncyl = get_ncyl();
5197c478bd9Sstevel@tonic-gate 		d->dtype_acyl = get_acyl(d->dtype_ncyl);
5207c478bd9Sstevel@tonic-gate 		d->dtype_pcyl = get_pcyl(d->dtype_ncyl, d->dtype_acyl);
5217c478bd9Sstevel@tonic-gate 		d->dtype_nhead = get_nhead();
5227c478bd9Sstevel@tonic-gate 		d->dtype_phead = get_phead(d->dtype_nhead, &d->dtype_options);
5237c478bd9Sstevel@tonic-gate 		d->dtype_nsect = get_nsect();
5247c478bd9Sstevel@tonic-gate 		d->dtype_psect = get_psect(&d->dtype_options);
5257c478bd9Sstevel@tonic-gate 		d->dtype_bpt = get_bpt(d->dtype_nsect, &d->dtype_options);
5267c478bd9Sstevel@tonic-gate 		d->dtype_rpm = get_rpm();
5277c478bd9Sstevel@tonic-gate 		d->dtype_fmt_time = get_fmt_time(&d->dtype_options);
5287c478bd9Sstevel@tonic-gate 		d->dtype_cyl_skew = get_cyl_skew(&d->dtype_options);
5297c478bd9Sstevel@tonic-gate 		d->dtype_trk_skew = get_trk_skew(&d->dtype_options);
5307c478bd9Sstevel@tonic-gate 		d->dtype_trks_zone = get_trks_zone(&d->dtype_options);
5317c478bd9Sstevel@tonic-gate 		d->dtype_atrks = get_atrks(&d->dtype_options);
5327c478bd9Sstevel@tonic-gate 		d->dtype_asect = get_asect(&d->dtype_options);
5337c478bd9Sstevel@tonic-gate 		d->dtype_cache = get_cache(&d->dtype_options);
5347c478bd9Sstevel@tonic-gate 		d->dtype_threshold = get_threshold(&d->dtype_options);
5357c478bd9Sstevel@tonic-gate 		d->dtype_prefetch_min = get_min_prefetch(&d->dtype_options);
5367c478bd9Sstevel@tonic-gate 		d->dtype_prefetch_max = get_max_prefetch(d->dtype_prefetch_min,
5377c478bd9Sstevel@tonic-gate 		    &d->dtype_options);
5387c478bd9Sstevel@tonic-gate 		d->dtype_bps = get_bps();
5397c478bd9Sstevel@tonic-gate #if defined(sparc)
5407c478bd9Sstevel@tonic-gate 		d->dtype_dr_type = 0;
5417c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 		d->dtype_asciilabel = get_asciilabel();
5447c478bd9Sstevel@tonic-gate 		/*
5457c478bd9Sstevel@tonic-gate 		 * Add the new type to the list of possible types for
5467c478bd9Sstevel@tonic-gate 		 * this controller.  We lock out interrupts so the lists
5477c478bd9Sstevel@tonic-gate 		 * can't get munged.  We put off actually allocating the
5487c478bd9Sstevel@tonic-gate 		 * structure till here in case the user wanted to
5497c478bd9Sstevel@tonic-gate 		 * interrupt while still inputting information.
5507c478bd9Sstevel@tonic-gate 		 */
5517c478bd9Sstevel@tonic-gate 		enter_critical();
5527c478bd9Sstevel@tonic-gate 		tptr = (struct disk_type *)zalloc(sizeof (struct disk_type));
5537c478bd9Sstevel@tonic-gate 		if (type == NULL)
5547c478bd9Sstevel@tonic-gate 			cur_ctype->ctype_dlist = tptr;
5557c478bd9Sstevel@tonic-gate 		else {
5567c478bd9Sstevel@tonic-gate 			while (type->dtype_next != NULL)
5577c478bd9Sstevel@tonic-gate 				type = type->dtype_next;
5587c478bd9Sstevel@tonic-gate 			type->dtype_next = tptr;
5597c478bd9Sstevel@tonic-gate 		}
5607c478bd9Sstevel@tonic-gate 		bcopy((char *)d, (char *)tptr, sizeof (disk_type));
5617c478bd9Sstevel@tonic-gate 		tptr->dtype_next = NULL;
5627c478bd9Sstevel@tonic-gate 		/*
5637c478bd9Sstevel@tonic-gate 		 * the new disk type does not have any defined
5647c478bd9Sstevel@tonic-gate 		 * partition table . Hence copy the current partition
5657c478bd9Sstevel@tonic-gate 		 * table if possible else create a default
5667c478bd9Sstevel@tonic-gate 		 * paritition table.
5677c478bd9Sstevel@tonic-gate 		 */
5687c478bd9Sstevel@tonic-gate 		new_partitiontable(tptr, oldtype);
5697c478bd9Sstevel@tonic-gate 	} else if ((index == other_choice) && (cur_label == L_TYPE_EFI)) {
5707c478bd9Sstevel@tonic-gate 		maxLBA = get_mlba();
5717c478bd9Sstevel@tonic-gate 		cur_parts->etoc->efi_last_lba = maxLBA;
5727c478bd9Sstevel@tonic-gate 		cur_parts->etoc->efi_last_u_lba = maxLBA - 34;
5737c478bd9Sstevel@tonic-gate 		for (i = 0; i < cur_parts->etoc->efi_nparts; i++) {
5747c478bd9Sstevel@tonic-gate 			cur_parts->etoc->efi_parts[i].p_start = 0;
5757c478bd9Sstevel@tonic-gate 			cur_parts->etoc->efi_parts[i].p_size = 0;
5767c478bd9Sstevel@tonic-gate 			cur_parts->etoc->efi_parts[i].p_tag = V_UNASSIGNED;
5777c478bd9Sstevel@tonic-gate 		}
5787c478bd9Sstevel@tonic-gate 		cur_parts->etoc->efi_parts[8].p_start =
5797c478bd9Sstevel@tonic-gate 		    maxLBA - 34 - (1024 * 16);
5807c478bd9Sstevel@tonic-gate 		cur_parts->etoc->efi_parts[8].p_size = (1024 * 16);
5817c478bd9Sstevel@tonic-gate 		cur_parts->etoc->efi_parts[8].p_tag = V_RESERVED;
5827c478bd9Sstevel@tonic-gate 		if (write_label()) {
5837c478bd9Sstevel@tonic-gate 			err_print("Write label failed\n");
5847c478bd9Sstevel@tonic-gate 		} else {
5857c478bd9Sstevel@tonic-gate 			cur_disk->disk_flags &= ~DSK_LABEL_DIRTY;
5867c478bd9Sstevel@tonic-gate 		}
5877c478bd9Sstevel@tonic-gate 		return (0);
5887c478bd9Sstevel@tonic-gate 	} else {
5897c478bd9Sstevel@tonic-gate 		/*
5907c478bd9Sstevel@tonic-gate 		 * User picked an existing disk type.
5917c478bd9Sstevel@tonic-gate 		 */
5927c478bd9Sstevel@tonic-gate 		i = first_disk;
5937c478bd9Sstevel@tonic-gate 		tptr = type;
5947c478bd9Sstevel@tonic-gate 		while (i < index) {
5957c478bd9Sstevel@tonic-gate 			if (tptr->dtype_asciilabel) {
5967c478bd9Sstevel@tonic-gate 				i++;
5977c478bd9Sstevel@tonic-gate 			}
5987c478bd9Sstevel@tonic-gate 			tptr = tptr->dtype_next;
5997c478bd9Sstevel@tonic-gate 		}
6007c478bd9Sstevel@tonic-gate 		if ((tptr->dtype_asciilabel == NULL) &&
6017c478bd9Sstevel@tonic-gate 		    (tptr->dtype_next != NULL)) {
6027c478bd9Sstevel@tonic-gate 			while (tptr->dtype_asciilabel == NULL) {
6037c478bd9Sstevel@tonic-gate 				tptr = tptr->dtype_next;
6047c478bd9Sstevel@tonic-gate 			}
6057c478bd9Sstevel@tonic-gate 		}
6067c478bd9Sstevel@tonic-gate 	}
6077c478bd9Sstevel@tonic-gate 	/*
6087c478bd9Sstevel@tonic-gate 	 * Check for mounted file systems in the format zone.
6097c478bd9Sstevel@tonic-gate 	 * One potential problem with this would be that check()
6107c478bd9Sstevel@tonic-gate 	 * always returns 'yes' when running out of a file.  However,
6117c478bd9Sstevel@tonic-gate 	 * it is actually ok because we don't let the program get
6127c478bd9Sstevel@tonic-gate 	 * started if there are mounted file systems and we are
6137c478bd9Sstevel@tonic-gate 	 * running from a file.
6147c478bd9Sstevel@tonic-gate 	 */
6157c478bd9Sstevel@tonic-gate 	if ((tptr != oldtype) &&
616342440ecSPrasad Singamsetty 	    checkmount((diskaddr_t)-1, (diskaddr_t)-1)) {
6177c478bd9Sstevel@tonic-gate 		err_print(
61865908c77Syu, larry liu - Sun Microsystems - Beijing China 		    "Cannot set disk type while it has mounted "
61965908c77Syu, larry liu - Sun Microsystems - Beijing China 		    "partitions.\n\n");
6207c478bd9Sstevel@tonic-gate 		return (-1);
6217c478bd9Sstevel@tonic-gate 	}
6227c478bd9Sstevel@tonic-gate 	/*
6237c478bd9Sstevel@tonic-gate 	 * check for partitions being used for swapping in format zone
6247c478bd9Sstevel@tonic-gate 	 */
6257c478bd9Sstevel@tonic-gate 	if ((tptr != oldtype) &&
626342440ecSPrasad Singamsetty 	    checkswap((diskaddr_t)-1, (diskaddr_t)-1)) {
62765908c77Syu, larry liu - Sun Microsystems - Beijing China 		err_print("Cannot set disk type while its partition are "
62865908c77Syu, larry liu - Sun Microsystems - Beijing China 		"currently being used for swapping.\n");
6297c478bd9Sstevel@tonic-gate 		return (-1);
6307c478bd9Sstevel@tonic-gate 	}
6313e1bd7a2Ssjelinek 
6323e1bd7a2Ssjelinek 	/*
6333e1bd7a2Ssjelinek 	 * Check for partitions being used in SVM, VxVM or LU devices
6343e1bd7a2Ssjelinek 	 */
6353e1bd7a2Ssjelinek 
6363e1bd7a2Ssjelinek 	if ((tptr != oldtype) &&
6373e1bd7a2Ssjelinek 	    checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
6383e1bd7a2Ssjelinek 	    (diskaddr_t)-1, 0, 0)) {
6393e1bd7a2Ssjelinek 		err_print("Cannot set disk type while its "
6403e1bd7a2Ssjelinek 		    "partitions are currently in use.\n");
6413e1bd7a2Ssjelinek 		return (-1);
6423e1bd7a2Ssjelinek 	}
6437c478bd9Sstevel@tonic-gate 	/*
6447c478bd9Sstevel@tonic-gate 	 * If the type selected is different from the previous type,
6457c478bd9Sstevel@tonic-gate 	 * mark the disk as not labelled and reload the current
6467c478bd9Sstevel@tonic-gate 	 * partition info.  This is not essential but probably the
6477c478bd9Sstevel@tonic-gate 	 * right thing to do, since the size of the disk has probably
6487c478bd9Sstevel@tonic-gate 	 * changed.
6497c478bd9Sstevel@tonic-gate 	 */
6507c478bd9Sstevel@tonic-gate 	enter_critical();
6517c478bd9Sstevel@tonic-gate 	if (tptr != oldtype) {
6527c478bd9Sstevel@tonic-gate 		cur_disk->disk_type = tptr;
6537c478bd9Sstevel@tonic-gate 		cur_disk->disk_parts = NULL;
6547c478bd9Sstevel@tonic-gate 		cur_disk->disk_flags &= ~DSK_LABEL;
6557c478bd9Sstevel@tonic-gate 	}
6567c478bd9Sstevel@tonic-gate 	/*
6577c478bd9Sstevel@tonic-gate 	 * Initialize the state of the current disk.
6587c478bd9Sstevel@tonic-gate 	 */
6597c478bd9Sstevel@tonic-gate 	init_globals(cur_disk);
6607c478bd9Sstevel@tonic-gate 	(void) get_partition();
6617c478bd9Sstevel@tonic-gate 	exit_critical();
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	/*
6647c478bd9Sstevel@tonic-gate 	 * If the label of the disk is marked dirty,
6657c478bd9Sstevel@tonic-gate 	 * see if they'd like to label the disk now.
6667c478bd9Sstevel@tonic-gate 	 */
6677c478bd9Sstevel@tonic-gate 	if (cur_disk->disk_flags & DSK_LABEL_DIRTY) {
6687c478bd9Sstevel@tonic-gate 		if (check("Disk not labeled.  Label it now") == 0) {
6697c478bd9Sstevel@tonic-gate 			if (write_label()) {
6707c478bd9Sstevel@tonic-gate 				err_print("Write label failed\n");
6717c478bd9Sstevel@tonic-gate 			} else {
6727c478bd9Sstevel@tonic-gate 				cur_disk->disk_flags &= ~DSK_LABEL_DIRTY;
6737c478bd9Sstevel@tonic-gate 			}
6747c478bd9Sstevel@tonic-gate 		}
6757c478bd9Sstevel@tonic-gate 	}
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 	return (0);
6787c478bd9Sstevel@tonic-gate }
6797c478bd9Sstevel@tonic-gate 
6807c478bd9Sstevel@tonic-gate /*
6817c478bd9Sstevel@tonic-gate  * This routine implements the 'partition' command.  It simply runs
6827c478bd9Sstevel@tonic-gate  * the partition menu.
6837c478bd9Sstevel@tonic-gate  */
6847c478bd9Sstevel@tonic-gate int
c_partition()6857c478bd9Sstevel@tonic-gate c_partition()
6867c478bd9Sstevel@tonic-gate {
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	/*
6897c478bd9Sstevel@tonic-gate 	 * There must be a current disk type and a current disk
6907c478bd9Sstevel@tonic-gate 	 */
6917c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
6927c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
6937c478bd9Sstevel@tonic-gate 		return (-1);
6947c478bd9Sstevel@tonic-gate 	}
6957c478bd9Sstevel@tonic-gate 	/*
6967c478bd9Sstevel@tonic-gate 	 * Check for a valid fdisk table entry for Solaris
6977c478bd9Sstevel@tonic-gate 	 */
6987c478bd9Sstevel@tonic-gate 	if (!good_fdisk()) {
6997c478bd9Sstevel@tonic-gate 		return (-1);
7007c478bd9Sstevel@tonic-gate 	}
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate 	cur_menu++;
7037c478bd9Sstevel@tonic-gate 	last_menu = cur_menu;
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate #ifdef	not
7067c478bd9Sstevel@tonic-gate 	/*
7077c478bd9Sstevel@tonic-gate 	 * If there is no current partition table, make one.  This is
7087c478bd9Sstevel@tonic-gate 	 * so the commands within the menu never have to check for
7097c478bd9Sstevel@tonic-gate 	 * a non-existent table.
7107c478bd9Sstevel@tonic-gate 	 */
7117c478bd9Sstevel@tonic-gate 	if (cur_parts == NULL)
7127c478bd9Sstevel@tonic-gate 		err_print("making partition.\n");
7137c478bd9Sstevel@tonic-gate 		make_partition();
7147c478bd9Sstevel@tonic-gate #endif	/* not */
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 	/*
7177c478bd9Sstevel@tonic-gate 	 * Run the menu.
7187c478bd9Sstevel@tonic-gate 	 */
7197c478bd9Sstevel@tonic-gate 	run_menu(menu_partition, "PARTITION", "partition", 0);
7207c478bd9Sstevel@tonic-gate 	cur_menu--;
7217c478bd9Sstevel@tonic-gate 	return (0);
7227c478bd9Sstevel@tonic-gate }
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate /*
7257c478bd9Sstevel@tonic-gate  * This routine implements the 'current' command.  It describes the
7267c478bd9Sstevel@tonic-gate  * current disk.
7277c478bd9Sstevel@tonic-gate  */
7287c478bd9Sstevel@tonic-gate int
c_current()7297c478bd9Sstevel@tonic-gate c_current()
7307c478bd9Sstevel@tonic-gate {
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate 	/*
7337c478bd9Sstevel@tonic-gate 	 * If there is no current disk, say so.  Note that this is
7347c478bd9Sstevel@tonic-gate 	 * not an error since it is a legitimate response to the inquiry.
7357c478bd9Sstevel@tonic-gate 	 */
7367c478bd9Sstevel@tonic-gate 	if (cur_disk == NULL) {
7377c478bd9Sstevel@tonic-gate 		fmt_print("No Current Disk.\n");
7387c478bd9Sstevel@tonic-gate 		return (0);
7397c478bd9Sstevel@tonic-gate 	}
7407c478bd9Sstevel@tonic-gate 	/*
7417c478bd9Sstevel@tonic-gate 	 * Print out the info we have on the current disk.
7427c478bd9Sstevel@tonic-gate 	 */
7437c478bd9Sstevel@tonic-gate 	fmt_print("Current Disk = %s", cur_disk->disk_name);
7447c478bd9Sstevel@tonic-gate 	if (chk_volname(cur_disk)) {
7457c478bd9Sstevel@tonic-gate 		fmt_print(": ");
7467c478bd9Sstevel@tonic-gate 		print_volname(cur_disk);
7477c478bd9Sstevel@tonic-gate 	}
7487c478bd9Sstevel@tonic-gate 	fmt_print("\n");
7497c478bd9Sstevel@tonic-gate 	if (cur_disk->devfs_name != NULL) {
7507c478bd9Sstevel@tonic-gate 		if (cur_dtype == NULL) {
7517c478bd9Sstevel@tonic-gate 			fmt_print("<type unknown>\n");
7527c478bd9Sstevel@tonic-gate 		} else if (cur_label == L_TYPE_SOLARIS) {
7537c478bd9Sstevel@tonic-gate 			fmt_print("<%s cyl %d alt %d hd %d sec %d>\n",
7547c478bd9Sstevel@tonic-gate 			    cur_dtype->dtype_asciilabel, ncyl,
7557c478bd9Sstevel@tonic-gate 			    acyl, nhead, nsect);
7567c478bd9Sstevel@tonic-gate 		} else if (cur_label == L_TYPE_EFI) {
7577c478bd9Sstevel@tonic-gate 			print_efi_string(cur_dtype->vendor,
7587c478bd9Sstevel@tonic-gate 			    cur_dtype->product, cur_dtype->revision,
7597c478bd9Sstevel@tonic-gate 			    cur_dtype->capacity);
7607c478bd9Sstevel@tonic-gate 			fmt_print("\n");
7617c478bd9Sstevel@tonic-gate 		}
7627c478bd9Sstevel@tonic-gate 		fmt_print("%s\n", cur_disk->devfs_name);
7637c478bd9Sstevel@tonic-gate 	} else {
7647c478bd9Sstevel@tonic-gate 		fmt_print("%s%d: <", cur_ctlr->ctlr_dname,
7657c478bd9Sstevel@tonic-gate 		    cur_disk->disk_dkinfo.dki_unit);
7667c478bd9Sstevel@tonic-gate 		if (cur_dtype == NULL) {
7677c478bd9Sstevel@tonic-gate 			fmt_print("type unknown");
7687c478bd9Sstevel@tonic-gate 		} else if (cur_label == L_TYPE_SOLARIS) {
7697c478bd9Sstevel@tonic-gate 			fmt_print("%s cyl %d alt %d hd %d sec %d",
7707c478bd9Sstevel@tonic-gate 			    cur_dtype->dtype_asciilabel, ncyl,
7717c478bd9Sstevel@tonic-gate 			    acyl, nhead, nsect);
7727c478bd9Sstevel@tonic-gate 		} else if (cur_label == L_TYPE_EFI) {
7737c478bd9Sstevel@tonic-gate 			print_efi_string(cur_dtype->vendor,
7747c478bd9Sstevel@tonic-gate 			    cur_dtype->product, cur_dtype->revision,
7757c478bd9Sstevel@tonic-gate 			    cur_dtype->capacity);
7767c478bd9Sstevel@tonic-gate 			fmt_print("\n");
7777c478bd9Sstevel@tonic-gate 		}
7787c478bd9Sstevel@tonic-gate 		fmt_print(">\n");
7797c478bd9Sstevel@tonic-gate 	}
7807c478bd9Sstevel@tonic-gate 	fmt_print("\n");
7817c478bd9Sstevel@tonic-gate 	return (0);
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate /*
7847c478bd9Sstevel@tonic-gate  * This routine implements the 'format' command.  It allows the user
7857c478bd9Sstevel@tonic-gate  * to format and verify any portion of the disk.
7867c478bd9Sstevel@tonic-gate  */
7877c478bd9Sstevel@tonic-gate int
c_format()7887c478bd9Sstevel@tonic-gate c_format()
7897c478bd9Sstevel@tonic-gate {
7907c478bd9Sstevel@tonic-gate 	diskaddr_t		start, end;
7917c478bd9Sstevel@tonic-gate 	time_t			clock;
7927c478bd9Sstevel@tonic-gate 	int			format_time, format_tracks, format_cyls;
7937c478bd9Sstevel@tonic-gate 	int			format_interval;
794342440ecSPrasad Singamsetty 	diskaddr_t		deflt;
795342440ecSPrasad Singamsetty 	int			status;
7967c478bd9Sstevel@tonic-gate 	u_ioparam_t		ioparam;
7979ca9c420SSheng-Liang Eric Zhang 	struct scsi_inquiry	*inq;
7989ca9c420SSheng-Liang Eric Zhang 	char	rawbuf[MAX_MODE_SENSE_SIZE];
7999ca9c420SSheng-Liang Eric Zhang 	struct scsi_capacity_16	capacity;
8009ca9c420SSheng-Liang Eric Zhang 	struct vpd_hdr	*vpdhdr;
8019ca9c420SSheng-Liang Eric Zhang 	uint8_t	protect;
8029ca9c420SSheng-Liang Eric Zhang 	uint8_t	pagecode;
8039ca9c420SSheng-Liang Eric Zhang 	uint8_t	spt;
8049ca9c420SSheng-Liang Eric Zhang 	uint8_t	p_type;
8059ca9c420SSheng-Liang Eric Zhang 	uint8_t	prot_flag[NUM_PROT_TYPE] = {1, 0, 0, 0};
8069ca9c420SSheng-Liang Eric Zhang 	int	i;
8079ca9c420SSheng-Liang Eric Zhang 	char	*prot_descriptor[NUM_PROT_TYPE] = {
8089ca9c420SSheng-Liang Eric Zhang 	    "Protection Information is disabled.",
8099ca9c420SSheng-Liang Eric Zhang 	    "Protection Information is enabled.",
8109ca9c420SSheng-Liang Eric Zhang 	    "Protection Information is enabled.",
8119ca9c420SSheng-Liang Eric Zhang 	    "Protection Information is enabled.", };
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate 	/*
8147c478bd9Sstevel@tonic-gate 	 * There must be a current disk type and a current disk
8157c478bd9Sstevel@tonic-gate 	 */
8167c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
8177c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
8187c478bd9Sstevel@tonic-gate 		return (-1);
8197c478bd9Sstevel@tonic-gate 	}
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	/*
8227c478bd9Sstevel@tonic-gate 	 * There must be a format routine in cur_ops structure to have
8237c478bd9Sstevel@tonic-gate 	 *  this routine work.
8247c478bd9Sstevel@tonic-gate 	 */
8257c478bd9Sstevel@tonic-gate 	if (cur_ops->op_format == NULL) {
8267c478bd9Sstevel@tonic-gate 		err_print(
8277c478bd9Sstevel@tonic-gate "Cannot format this drive. Please use your Manufacturer supplied formatting "
8287c478bd9Sstevel@tonic-gate "utility.\n");
8297c478bd9Sstevel@tonic-gate 		return (-1);
8307c478bd9Sstevel@tonic-gate 	}
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	/*
8337c478bd9Sstevel@tonic-gate 	 * There must be a current defect list.  Except for
8347c478bd9Sstevel@tonic-gate 	 * unformatted SCSI disks.  For them the defect list
8357c478bd9Sstevel@tonic-gate 	 * can only be retrieved after formatting the disk.
8367c478bd9Sstevel@tonic-gate 	 */
8377c478bd9Sstevel@tonic-gate 	if ((cur_ctype->ctype_flags & CF_SCSI) && !EMBEDDED_SCSI &&
8387c478bd9Sstevel@tonic-gate 	    (cur_ctype->ctype_flags & CF_DEFECTS) &&
8397c478bd9Sstevel@tonic-gate 	    ! (cur_flags & DISK_FORMATTED)) {
8407c478bd9Sstevel@tonic-gate 		cur_list.flags |= LIST_RELOAD;
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate 	} else if (cur_list.list == NULL && !EMBEDDED_SCSI) {
8437c478bd9Sstevel@tonic-gate 		err_print("Current Defect List must be initialized.\n");
8447c478bd9Sstevel@tonic-gate 		return (-1);
8457c478bd9Sstevel@tonic-gate 	}
8467c478bd9Sstevel@tonic-gate 	/*
8477c478bd9Sstevel@tonic-gate 	 * Ask for the bounds of the format.  We always use the whole
8487c478bd9Sstevel@tonic-gate 	 * disk as the default, since that is the most likely case.
8497c478bd9Sstevel@tonic-gate 	 * Note, for disks which must be formatted accross the whole disk,
8507c478bd9Sstevel@tonic-gate 	 * don't bother the user.
8517c478bd9Sstevel@tonic-gate 	 */
8527c478bd9Sstevel@tonic-gate 	ioparam.io_bounds.lower = start = 0;
8537c478bd9Sstevel@tonic-gate 	if (cur_label == L_TYPE_SOLARIS) {
8547c478bd9Sstevel@tonic-gate 		if (cur_ctype->ctype_flags & CF_SCSI) {
8557c478bd9Sstevel@tonic-gate 			ioparam.io_bounds.upper = end = datasects() - 1;
8567c478bd9Sstevel@tonic-gate 		} else {
8577c478bd9Sstevel@tonic-gate 			ioparam.io_bounds.upper = end = physsects() - 1;
8587c478bd9Sstevel@tonic-gate 		}
8597c478bd9Sstevel@tonic-gate 	} else {
8607c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.upper = end = cur_parts->etoc->efi_last_lba;
8617c478bd9Sstevel@tonic-gate 	}
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate 	if (! (cur_ctlr->ctlr_flags & DKI_FMTVOL)) {
8647c478bd9Sstevel@tonic-gate 		deflt = ioparam.io_bounds.lower;
8657c478bd9Sstevel@tonic-gate 		start = input(FIO_BN,
8667c478bd9Sstevel@tonic-gate 		    "Enter starting block number", ':',
867342440ecSPrasad Singamsetty 		    &ioparam, (int *)&deflt, DATA_INPUT);
8687c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.lower = start;
8697c478bd9Sstevel@tonic-gate 		deflt = ioparam.io_bounds.upper;
8707c478bd9Sstevel@tonic-gate 		end = input(FIO_BN,
8717c478bd9Sstevel@tonic-gate 		    "Enter ending block number", ':',
872342440ecSPrasad Singamsetty 		    &ioparam, (int *)&deflt, DATA_INPUT);
8737c478bd9Sstevel@tonic-gate 	}
8747c478bd9Sstevel@tonic-gate 	/*
8757c478bd9Sstevel@tonic-gate 	 * Some disks can format tracks.  Make sure the whole track is
8767c478bd9Sstevel@tonic-gate 	 * specified for them.
8777c478bd9Sstevel@tonic-gate 	 */
8787c478bd9Sstevel@tonic-gate 	if (cur_ctlr->ctlr_flags & DKI_FMTTRK) {
8797c478bd9Sstevel@tonic-gate 		if (bn2s(start) != 0 ||
8807c478bd9Sstevel@tonic-gate 		    bn2s(end) != sectors(bn2h(end)) - 1) {
8817c478bd9Sstevel@tonic-gate 			err_print("Controller requires formatting of ");
8827c478bd9Sstevel@tonic-gate 			err_print("entire tracks.\n");
8837c478bd9Sstevel@tonic-gate 			return (-1);
8847c478bd9Sstevel@tonic-gate 		}
8857c478bd9Sstevel@tonic-gate 	}
8867c478bd9Sstevel@tonic-gate 	/*
8877c478bd9Sstevel@tonic-gate 	 * Check for mounted file systems in the format zone, and if we
8887c478bd9Sstevel@tonic-gate 	 * find any, make sure they are really serious.  One potential
8897c478bd9Sstevel@tonic-gate 	 * problem with this would be that check() always returns 'yes'
8907c478bd9Sstevel@tonic-gate 	 * when running out of a file.  However, it is actually ok
8917c478bd9Sstevel@tonic-gate 	 * because we don't let the program get started if there are
8927c478bd9Sstevel@tonic-gate 	 * mounted file systems and we are running from a file.
8937c478bd9Sstevel@tonic-gate 	 */
8947c478bd9Sstevel@tonic-gate 	if (checkmount(start, end)) {
8957c478bd9Sstevel@tonic-gate 		err_print(
8967c478bd9Sstevel@tonic-gate 		"Cannot format disk while it has mounted partitions.\n\n");
8977c478bd9Sstevel@tonic-gate 		return (-1);
8987c478bd9Sstevel@tonic-gate 	}
8997c478bd9Sstevel@tonic-gate 	/*
9007c478bd9Sstevel@tonic-gate 	 * check for partitions being used for swapping in format zone
9017c478bd9Sstevel@tonic-gate 	 */
9027c478bd9Sstevel@tonic-gate 	if (checkswap(start, end)) {
9037c478bd9Sstevel@tonic-gate 		err_print("Cannot format disk while its partition are \
9047c478bd9Sstevel@tonic-gate currently being used for swapping.\n");
9057c478bd9Sstevel@tonic-gate 		return (-1);
9067c478bd9Sstevel@tonic-gate 	}
9073e1bd7a2Ssjelinek 	/*
9083e1bd7a2Ssjelinek 	 * Check for partitions being used in SVM, VxVM or LU devices
9093e1bd7a2Ssjelinek 	 * in this format zone
9103e1bd7a2Ssjelinek 	 */
9113e1bd7a2Ssjelinek 	if (checkdevinuse(cur_disk->disk_name, start, end, 0, 0)) {
9123e1bd7a2Ssjelinek 		err_print("Cannot format disk while its partitions "
9133e1bd7a2Ssjelinek 		    "are currently in use.\n");
9143e1bd7a2Ssjelinek 		return (-1);
9153e1bd7a2Ssjelinek 	}
9163e1bd7a2Ssjelinek 
91765908c77Syu, larry liu - Sun Microsystems - Beijing China 	if (cur_disk->disk_lbasize != DEV_BSIZE) {
91865908c77Syu, larry liu - Sun Microsystems - Beijing China 		fmt_print("Current disk sector size is %d Byte, format\n"
91965908c77Syu, larry liu - Sun Microsystems - Beijing China 		    "will change the sector size to 512 Byte. ",
92065908c77Syu, larry liu - Sun Microsystems - Beijing China 		    cur_disk->disk_lbasize);
92165908c77Syu, larry liu - Sun Microsystems - Beijing China 		if (check("Continue")) {
92265908c77Syu, larry liu - Sun Microsystems - Beijing China 			return (-1);
92365908c77Syu, larry liu - Sun Microsystems - Beijing China 		}
92465908c77Syu, larry liu - Sun Microsystems - Beijing China 	}
92565908c77Syu, larry liu - Sun Microsystems - Beijing China 
9269ca9c420SSheng-Liang Eric Zhang 	/*
9279ca9c420SSheng-Liang Eric Zhang 	 * set the default protection type
9289ca9c420SSheng-Liang Eric Zhang 	 */
9299ca9c420SSheng-Liang Eric Zhang 	prot_type = PROT_TYPE_0;
9309ca9c420SSheng-Liang Eric Zhang 
9319ca9c420SSheng-Liang Eric Zhang 	/*
9329ca9c420SSheng-Liang Eric Zhang 	 * Check if the protect information of this disk is enabled
9339ca9c420SSheng-Liang Eric Zhang 	 */
9349ca9c420SSheng-Liang Eric Zhang 	if (uscsi_inquiry(cur_file, rawbuf, sizeof (rawbuf))) {
9359ca9c420SSheng-Liang Eric Zhang 		err_print("Inquiry failed\n");
9369ca9c420SSheng-Liang Eric Zhang 		return (-1);
9379ca9c420SSheng-Liang Eric Zhang 	}
9389ca9c420SSheng-Liang Eric Zhang 	inq = (struct scsi_inquiry *)rawbuf;
9399ca9c420SSheng-Liang Eric Zhang 	protect = inq->inq_protect;
9409ca9c420SSheng-Liang Eric Zhang 	if (protect == 0) {
9419ca9c420SSheng-Liang Eric Zhang 		fmt_print("The protection information is not enabled\n");
9429ca9c420SSheng-Liang Eric Zhang 		fmt_print(
9439ca9c420SSheng-Liang Eric Zhang 		    "The disk will be formatted with protection type 0\n");
9449ca9c420SSheng-Liang Eric Zhang 	} else {
9459ca9c420SSheng-Liang Eric Zhang 		(void) memset(rawbuf, 0, MAX_MODE_SENSE_SIZE);
9469ca9c420SSheng-Liang Eric Zhang 		if (uscsi_inquiry_page_86h(cur_file, rawbuf, sizeof (rawbuf))) {
9479ca9c420SSheng-Liang Eric Zhang 			err_print("Inquiry with page 86h failed\n");
9489ca9c420SSheng-Liang Eric Zhang 			return (-1);
9499ca9c420SSheng-Liang Eric Zhang 		}
9509ca9c420SSheng-Liang Eric Zhang 		vpdhdr = (struct vpd_hdr *)rawbuf;
9519ca9c420SSheng-Liang Eric Zhang 		pagecode = vpdhdr->page_code;
9529ca9c420SSheng-Liang Eric Zhang 		if (pagecode != 0x86) {
9539ca9c420SSheng-Liang Eric Zhang 			err_print("Inquiry with page 86h failed\n");
9549ca9c420SSheng-Liang Eric Zhang 			return (-1);
9559ca9c420SSheng-Liang Eric Zhang 		}
9569ca9c420SSheng-Liang Eric Zhang 		spt = (rawbuf[4] << 2) >> 5;
9579ca9c420SSheng-Liang Eric Zhang 		fmt_print("This disk can support protection types:\n");
9589ca9c420SSheng-Liang Eric Zhang 
9599ca9c420SSheng-Liang Eric Zhang 		switch (spt) {
9609ca9c420SSheng-Liang Eric Zhang 		case 0:
9619ca9c420SSheng-Liang Eric Zhang 			prot_flag[1] = 1;
9629ca9c420SSheng-Liang Eric Zhang 			break;
9639ca9c420SSheng-Liang Eric Zhang 		case 1:
9649ca9c420SSheng-Liang Eric Zhang 			prot_flag[1] = 1;
9659ca9c420SSheng-Liang Eric Zhang 			prot_flag[2] = 1;
9669ca9c420SSheng-Liang Eric Zhang 			break;
9679ca9c420SSheng-Liang Eric Zhang 		case 2:
9689ca9c420SSheng-Liang Eric Zhang 			prot_flag[2] = 1;
9699ca9c420SSheng-Liang Eric Zhang 			break;
9709ca9c420SSheng-Liang Eric Zhang 		case 3:
9719ca9c420SSheng-Liang Eric Zhang 			prot_flag[1] = 1;
9729ca9c420SSheng-Liang Eric Zhang 			prot_flag[3] = 1;
9739ca9c420SSheng-Liang Eric Zhang 			break;
9749ca9c420SSheng-Liang Eric Zhang 		case 4:
9759ca9c420SSheng-Liang Eric Zhang 			prot_flag[3] = 1;
9769ca9c420SSheng-Liang Eric Zhang 			break;
9779ca9c420SSheng-Liang Eric Zhang 		case 5:
9789ca9c420SSheng-Liang Eric Zhang 			prot_flag[2] = 1;
9799ca9c420SSheng-Liang Eric Zhang 			prot_flag[3] = 1;
9809ca9c420SSheng-Liang Eric Zhang 			break;
9819ca9c420SSheng-Liang Eric Zhang 		case 7:
9829ca9c420SSheng-Liang Eric Zhang 			prot_flag[1] = 1;
9839ca9c420SSheng-Liang Eric Zhang 			prot_flag[2] = 1;
9849ca9c420SSheng-Liang Eric Zhang 			prot_flag[3] = 1;
9859ca9c420SSheng-Liang Eric Zhang 			break;
9869ca9c420SSheng-Liang Eric Zhang 		default:
9879ca9c420SSheng-Liang Eric Zhang 			err_print(
9889ca9c420SSheng-Liang Eric Zhang 			    "Invalid supported protection types\n");
9899ca9c420SSheng-Liang Eric Zhang 			return (-1);
9909ca9c420SSheng-Liang Eric Zhang 		}
9919ca9c420SSheng-Liang Eric Zhang 		for (i = 0; i < NUM_PROT_TYPE; i++) {
9929ca9c420SSheng-Liang Eric Zhang 			if (prot_flag[i] == 1) {
9939ca9c420SSheng-Liang Eric Zhang 				fmt_print("[%d] TYPE_%d : ", i, i);
9949ca9c420SSheng-Liang Eric Zhang 				fmt_print("%s\n", prot_descriptor[i]);
9959ca9c420SSheng-Liang Eric Zhang 			}
9969ca9c420SSheng-Liang Eric Zhang 		}
9979ca9c420SSheng-Liang Eric Zhang 
9989ca9c420SSheng-Liang Eric Zhang 		/*
9999ca9c420SSheng-Liang Eric Zhang 		 * Get the current protection type
10009ca9c420SSheng-Liang Eric Zhang 		 */
10019ca9c420SSheng-Liang Eric Zhang 		if (uscsi_read_capacity_16(cur_file, &capacity)) {
10029ca9c420SSheng-Liang Eric Zhang 			err_print("Read capacity_16 failed\n");
10039ca9c420SSheng-Liang Eric Zhang 			return (-1);
10049ca9c420SSheng-Liang Eric Zhang 		}
10059ca9c420SSheng-Liang Eric Zhang 		p_type = get_cur_protection_type(&capacity);
10069ca9c420SSheng-Liang Eric Zhang 		fmt_print("\nThe disk is currently formatted with TYPE_%d.\n",
10079ca9c420SSheng-Liang Eric Zhang 		    p_type);
10089ca9c420SSheng-Liang Eric Zhang 
10099ca9c420SSheng-Liang Eric Zhang 		/*
10109ca9c420SSheng-Liang Eric Zhang 		 * Ask user what protection type to use
10119ca9c420SSheng-Liang Eric Zhang 		 */
10129ca9c420SSheng-Liang Eric Zhang 		ioparam.io_bounds.lower = PROT_TYPE_0;
10139ca9c420SSheng-Liang Eric Zhang 		ioparam.io_bounds.upper = PROT_TYPE_3;
10149ca9c420SSheng-Liang Eric Zhang 		prot_type = input(FIO_INT, "Specify the New Protection Type",
10159ca9c420SSheng-Liang Eric Zhang 		    ':', &ioparam, NULL, DATA_INPUT);
10169ca9c420SSheng-Liang Eric Zhang 		/*
10179ca9c420SSheng-Liang Eric Zhang 		 * if get a unsupported protection type, then use the
10189ca9c420SSheng-Liang Eric Zhang 		 * current type: p_type.
10199ca9c420SSheng-Liang Eric Zhang 		 */
10209ca9c420SSheng-Liang Eric Zhang 		if (prot_flag[prot_type] == 0) {
10219ca9c420SSheng-Liang Eric Zhang 			fmt_print("Unsupported protection type.\n");
10229ca9c420SSheng-Liang Eric Zhang 			prot_type = p_type;
10239ca9c420SSheng-Liang Eric Zhang 		}
10249ca9c420SSheng-Liang Eric Zhang 		fmt_print("The disk will be formatted to type %d\n", prot_type);
10259ca9c420SSheng-Liang Eric Zhang 	}
10269ca9c420SSheng-Liang Eric Zhang 
10277c478bd9Sstevel@tonic-gate 	if (SCSI && (format_time = scsi_format_time()) > 0) {
10287c478bd9Sstevel@tonic-gate 		fmt_print(
102965908c77Syu, larry liu - Sun Microsystems - Beijing China 		    "\nReady to format.  Formatting cannot be interrupted\n"
10307c478bd9Sstevel@tonic-gate 		    "and takes %d minutes (estimated). ", format_time);
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate 	} else if (cur_dtype->dtype_options & SUP_FMTTIME) {
10337c478bd9Sstevel@tonic-gate 		/*
10347c478bd9Sstevel@tonic-gate 		 * Formatting time is (2 * time of 1 spin * number of
10357c478bd9Sstevel@tonic-gate 		 * tracks) + (step rate * number of cylinders) rounded
10367c478bd9Sstevel@tonic-gate 		 * up to the nearest minute.  Note, a 10% fudge factor
10377c478bd9Sstevel@tonic-gate 		 * is thrown in for insurance.
10387c478bd9Sstevel@tonic-gate 		 */
10397c478bd9Sstevel@tonic-gate 		if (cur_dtype->dtype_fmt_time == 0)
10407c478bd9Sstevel@tonic-gate 			cur_dtype->dtype_fmt_time = 2;
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 		format_tracks = ((end-start) / cur_dtype->dtype_nsect) + 1;
10437c478bd9Sstevel@tonic-gate 		format_cyls = format_tracks / cur_dtype->dtype_nhead;
10447c478bd9Sstevel@tonic-gate 		format_tracks = format_tracks * cur_dtype->dtype_fmt_time;
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 		/*
10477c478bd9Sstevel@tonic-gate 		 * ms.
10487c478bd9Sstevel@tonic-gate 		 */
10497c478bd9Sstevel@tonic-gate 		format_time = ((60000 / cur_dtype->dtype_rpm) +1) *
10507c478bd9Sstevel@tonic-gate 		    format_tracks + format_cyls * 7;
10517c478bd9Sstevel@tonic-gate 		/*
10527c478bd9Sstevel@tonic-gate 		 * 20% done tick (sec)
10537c478bd9Sstevel@tonic-gate 		 */
10547c478bd9Sstevel@tonic-gate 		format_interval = format_time / 5000;
10557c478bd9Sstevel@tonic-gate 		/*
10567c478bd9Sstevel@tonic-gate 		 * min.
10577c478bd9Sstevel@tonic-gate 		 */
10587c478bd9Sstevel@tonic-gate 		format_time = (format_time + 59999) / 60000;
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 		/*
10617c478bd9Sstevel@tonic-gate 		 * Check format time values and make adjustments
10627c478bd9Sstevel@tonic-gate 		 * to prevent sleeping too long (forever?) or
10637c478bd9Sstevel@tonic-gate 		 * too short.
10647c478bd9Sstevel@tonic-gate 		 */
10657c478bd9Sstevel@tonic-gate 		if (format_time <= 1) {
10667c478bd9Sstevel@tonic-gate 			/*
10677c478bd9Sstevel@tonic-gate 			 * Format time is less than 1 min..
10687c478bd9Sstevel@tonic-gate 			 */
10697c478bd9Sstevel@tonic-gate 			format_time = 1;
10707c478bd9Sstevel@tonic-gate 		}
10717c478bd9Sstevel@tonic-gate 
10727c478bd9Sstevel@tonic-gate 		if (format_interval < 11) {
10737c478bd9Sstevel@tonic-gate 			/* Format time is less than 1 minute. */
10747c478bd9Sstevel@tonic-gate 			if (format_interval < 2)
10757c478bd9Sstevel@tonic-gate 				format_interval = 2;	/* failsafe */
10767c478bd9Sstevel@tonic-gate 			format_interval = 10;
10777c478bd9Sstevel@tonic-gate 		} else {
10787c478bd9Sstevel@tonic-gate 			/* Format time is greater than 1 minute. */
10797c478bd9Sstevel@tonic-gate 			format_interval -= 10;
10807c478bd9Sstevel@tonic-gate 		}
10817c478bd9Sstevel@tonic-gate 
10827c478bd9Sstevel@tonic-gate 		fmt_print(
10837c478bd9Sstevel@tonic-gate 		    "Ready to format.  Formatting cannot be interrupted\n"
10847c478bd9Sstevel@tonic-gate 		    "and takes %d minutes (estimated). ", format_time);
10857c478bd9Sstevel@tonic-gate 	} else {
10867c478bd9Sstevel@tonic-gate 		fmt_print(
10877c478bd9Sstevel@tonic-gate 		    "Ready to format.  Formatting cannot be interrupted.\n");
10887c478bd9Sstevel@tonic-gate 	}
10897c478bd9Sstevel@tonic-gate 	if (check("Continue")) {
10907c478bd9Sstevel@tonic-gate 		return (-1);
10917c478bd9Sstevel@tonic-gate 	}
10927c478bd9Sstevel@tonic-gate 
10937c478bd9Sstevel@tonic-gate 	/*
10947c478bd9Sstevel@tonic-gate 	 * Print the time so that the user will know when format started.
10957c478bd9Sstevel@tonic-gate 	 * Lock out interrupts.  This could be a problem, since it could
10967c478bd9Sstevel@tonic-gate 	 * cause the user to sit for quite awhile with no control, but we
10977c478bd9Sstevel@tonic-gate 	 * don't have any other good way of keeping his gun from going off.
10987c478bd9Sstevel@tonic-gate 	 */
10997c478bd9Sstevel@tonic-gate 	clock = time((time_t *)0);
11007c478bd9Sstevel@tonic-gate 	fmt_print("Beginning format. The current time is %s\n",
11017c478bd9Sstevel@tonic-gate 	    ctime(&clock));
11027c478bd9Sstevel@tonic-gate 	enter_critical();
11037c478bd9Sstevel@tonic-gate 	/*
11047c478bd9Sstevel@tonic-gate 	 * Mark the defect list dirty so it will be rewritten when we are
11057c478bd9Sstevel@tonic-gate 	 * done.  It is possible to qualify this so it doesn't always
11067c478bd9Sstevel@tonic-gate 	 * get rewritten, but it's not worth the trouble.
11077c478bd9Sstevel@tonic-gate 	 * Note: no defect lists for embedded scsi drives.
11087c478bd9Sstevel@tonic-gate 	 */
11097c478bd9Sstevel@tonic-gate 	if (!EMBEDDED_SCSI) {
11107c478bd9Sstevel@tonic-gate 		cur_list.flags |= LIST_DIRTY;
11117c478bd9Sstevel@tonic-gate 	}
11127c478bd9Sstevel@tonic-gate 	/*
11137c478bd9Sstevel@tonic-gate 	 * If we are formatting over any of the labels, mark the label
11147c478bd9Sstevel@tonic-gate 	 * dirty so it will be rewritten.
11157c478bd9Sstevel@tonic-gate 	 */
11167c478bd9Sstevel@tonic-gate 	if (cur_disk->label_type == L_TYPE_SOLARIS) {
11177c478bd9Sstevel@tonic-gate 		if (start < totalsects() && end >= datasects()) {
11187c478bd9Sstevel@tonic-gate 			if (cur_disk->disk_flags & DSK_LABEL)
11197c478bd9Sstevel@tonic-gate 				cur_flags |= LABEL_DIRTY;
11207c478bd9Sstevel@tonic-gate 		}
11217c478bd9Sstevel@tonic-gate 	} else if (cur_disk->label_type == L_TYPE_EFI) {
11227c478bd9Sstevel@tonic-gate 		if (start < 34) {
11237c478bd9Sstevel@tonic-gate 			if (cur_disk->disk_flags & DSK_LABEL)
11247c478bd9Sstevel@tonic-gate 				cur_flags |= LABEL_DIRTY;
11257c478bd9Sstevel@tonic-gate 		}
11267c478bd9Sstevel@tonic-gate 	}
11277c478bd9Sstevel@tonic-gate 	if (start == 0) {
11287c478bd9Sstevel@tonic-gate 		cur_flags |= LABEL_DIRTY;
11297c478bd9Sstevel@tonic-gate 	}
11307c478bd9Sstevel@tonic-gate 	/*
11317c478bd9Sstevel@tonic-gate 	 * Do the format. bugid 1009138 removed the use of fork to
11327c478bd9Sstevel@tonic-gate 	 * background the format and print a tick.
11337c478bd9Sstevel@tonic-gate 	 */
11347c478bd9Sstevel@tonic-gate 
11357c478bd9Sstevel@tonic-gate 	status = (*cur_ops->op_format)(start, end, &cur_list);
11367c478bd9Sstevel@tonic-gate 	if (status) {
11377c478bd9Sstevel@tonic-gate 		exit_critical();
11387c478bd9Sstevel@tonic-gate 		err_print("failed\n");
11397c478bd9Sstevel@tonic-gate 		return (-1);
11407c478bd9Sstevel@tonic-gate 	}
11417c478bd9Sstevel@tonic-gate 	fmt_print("done\n");
11427c478bd9Sstevel@tonic-gate 	if (option_msg && diag_msg) {
11437c478bd9Sstevel@tonic-gate 		clock = time((time_t *)0);
11447c478bd9Sstevel@tonic-gate 		fmt_print("The current time is %s\n", ctime(&clock));
11457c478bd9Sstevel@tonic-gate 	}
11467c478bd9Sstevel@tonic-gate 	cur_flags |= DISK_FORMATTED;
11477c478bd9Sstevel@tonic-gate 	/*
11487c478bd9Sstevel@tonic-gate 	 * If the defect list or label is dirty, write them out again.
11497c478bd9Sstevel@tonic-gate 	 * Note, for SCSI we have to wait til now to load defect list
11507c478bd9Sstevel@tonic-gate 	 * since we can't access it until after formatting a virgin disk.
11517c478bd9Sstevel@tonic-gate 	 */
11527c478bd9Sstevel@tonic-gate 	/* enter_critical(); */
11537c478bd9Sstevel@tonic-gate 	if (cur_list.flags & LIST_RELOAD) {
11547c478bd9Sstevel@tonic-gate 		assert(!EMBEDDED_SCSI);
11557c478bd9Sstevel@tonic-gate 		if (*cur_ops->op_ex_man == NULL ||
11567c478bd9Sstevel@tonic-gate 		    (*cur_ops->op_ex_man)(&cur_list)) {
11577c478bd9Sstevel@tonic-gate 			err_print("Warning: unable to reload defect list\n");
11587c478bd9Sstevel@tonic-gate 			cur_list.flags &= ~LIST_DIRTY;
11597c478bd9Sstevel@tonic-gate 			return (-1);
11607c478bd9Sstevel@tonic-gate 		}
11617c478bd9Sstevel@tonic-gate 		cur_list.flags |= LIST_DIRTY;
11627c478bd9Sstevel@tonic-gate 	}
11637c478bd9Sstevel@tonic-gate 
11647c478bd9Sstevel@tonic-gate 	if (cur_list.flags & LIST_DIRTY) {
11657c478bd9Sstevel@tonic-gate 		assert(!EMBEDDED_SCSI);
11667c478bd9Sstevel@tonic-gate 		write_deflist(&cur_list);
11677c478bd9Sstevel@tonic-gate 		cur_list.flags = 0;
11687c478bd9Sstevel@tonic-gate 	}
11697c478bd9Sstevel@tonic-gate 	if (cur_flags & LABEL_DIRTY) {
11707c478bd9Sstevel@tonic-gate 		(void) write_label();
11717c478bd9Sstevel@tonic-gate 		cur_flags &= ~LABEL_DIRTY;
11727c478bd9Sstevel@tonic-gate 	}
11737c478bd9Sstevel@tonic-gate 	/*
11747c478bd9Sstevel@tonic-gate 	 * Come up for air, since the verify step does not need to
11757c478bd9Sstevel@tonic-gate 	 * be atomic (it does it's own lockouts when necessary).
11767c478bd9Sstevel@tonic-gate 	 */
11777c478bd9Sstevel@tonic-gate 	exit_critical();
11787c478bd9Sstevel@tonic-gate 	/*
11797c478bd9Sstevel@tonic-gate 	 * If we are supposed to verify, we do the 'write' test over
11807c478bd9Sstevel@tonic-gate 	 * the format zone.  The rest of the analysis parameters are
11817c478bd9Sstevel@tonic-gate 	 * left the way they were.
11827c478bd9Sstevel@tonic-gate 	 */
11837c478bd9Sstevel@tonic-gate 	if (scan_auto) {
11847c478bd9Sstevel@tonic-gate 		scan_entire = 0;
11857c478bd9Sstevel@tonic-gate 		scan_lower = start;
11867c478bd9Sstevel@tonic-gate 		scan_upper = end;
11877c478bd9Sstevel@tonic-gate 		fmt_print("\nVerifying media...");
11887c478bd9Sstevel@tonic-gate 		status = do_scan(SCAN_PATTERN, F_SILENT);
11897c478bd9Sstevel@tonic-gate 	}
11907c478bd9Sstevel@tonic-gate 	/*
11917c478bd9Sstevel@tonic-gate 	 * If the defect list or label is dirty, write them out again.
11927c478bd9Sstevel@tonic-gate 	 */
11937c478bd9Sstevel@tonic-gate 	if (cur_list.flags & LIST_DIRTY) {
11947c478bd9Sstevel@tonic-gate 		assert(!EMBEDDED_SCSI);
11957c478bd9Sstevel@tonic-gate 		cur_list.flags = 0;
11967c478bd9Sstevel@tonic-gate 		write_deflist(&cur_list);
11977c478bd9Sstevel@tonic-gate 	}
11987c478bd9Sstevel@tonic-gate 	if (cur_flags & LABEL_DIRTY) {
11997c478bd9Sstevel@tonic-gate 		cur_flags &= ~LABEL_DIRTY;
12007c478bd9Sstevel@tonic-gate 		(void) write_label();
12017c478bd9Sstevel@tonic-gate 	}
12027c478bd9Sstevel@tonic-gate 	return (status);
12037c478bd9Sstevel@tonic-gate }
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate /*
12067c478bd9Sstevel@tonic-gate  * This routine implements the 'repair' command.  It allows the user
12077c478bd9Sstevel@tonic-gate  * to reallocate sectors on the disk that have gone bad.
12087c478bd9Sstevel@tonic-gate  */
12097c478bd9Sstevel@tonic-gate int
c_repair()12107c478bd9Sstevel@tonic-gate c_repair()
12117c478bd9Sstevel@tonic-gate {
12127c478bd9Sstevel@tonic-gate 	diskaddr_t	bn;
12137c478bd9Sstevel@tonic-gate 	int		status;
12147c478bd9Sstevel@tonic-gate 	u_ioparam_t	ioparam;
121565908c77Syu, larry liu - Sun Microsystems - Beijing China 	char		*buf;
12167c478bd9Sstevel@tonic-gate 	int		buf_is_good;
12177c478bd9Sstevel@tonic-gate 	int		block_has_error;
12187c478bd9Sstevel@tonic-gate 	int		i;
12197c478bd9Sstevel@tonic-gate 
12207c478bd9Sstevel@tonic-gate 	/*
12217c478bd9Sstevel@tonic-gate 	 * There must be a current disk type (and therefore a current disk).
12227c478bd9Sstevel@tonic-gate 	 */
12237c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
12247c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
12257c478bd9Sstevel@tonic-gate 		return (-1);
12267c478bd9Sstevel@tonic-gate 	}
12277c478bd9Sstevel@tonic-gate 	/*
12287c478bd9Sstevel@tonic-gate 	 * The current disk must be formatted for repair to work.
12297c478bd9Sstevel@tonic-gate 	 */
12307c478bd9Sstevel@tonic-gate 	if (!(cur_flags & DISK_FORMATTED)) {
12317c478bd9Sstevel@tonic-gate 		err_print("Current Disk is unformatted.\n");
12327c478bd9Sstevel@tonic-gate 		return (-1);
12337c478bd9Sstevel@tonic-gate 	}
12347c478bd9Sstevel@tonic-gate 	/*
12357c478bd9Sstevel@tonic-gate 	 * Check for a valid fdisk table entry for Solaris
12367c478bd9Sstevel@tonic-gate 	 */
12377c478bd9Sstevel@tonic-gate 	if (!good_fdisk()) {
12387c478bd9Sstevel@tonic-gate 		return (-1);
12397c478bd9Sstevel@tonic-gate 	}
12407c478bd9Sstevel@tonic-gate 	/*
12417c478bd9Sstevel@tonic-gate 	 * Repair is an optional command for controllers, so it may
12427c478bd9Sstevel@tonic-gate 	 * not be supported.
12437c478bd9Sstevel@tonic-gate 	 */
12447c478bd9Sstevel@tonic-gate 	if (cur_ops->op_repair == NULL) {
12457c478bd9Sstevel@tonic-gate 		err_print("Controller does not support repairing.\n");
12467c478bd9Sstevel@tonic-gate 		err_print("or disk supports automatic defect management.\n");
12477c478bd9Sstevel@tonic-gate 		return (-1);
12487c478bd9Sstevel@tonic-gate 	}
12497c478bd9Sstevel@tonic-gate 	/*
12507c478bd9Sstevel@tonic-gate 	 * There must be a defect list for non-embedded scsi devices,
12517c478bd9Sstevel@tonic-gate 	 * since we will add to it.
12527c478bd9Sstevel@tonic-gate 	 */
12537c478bd9Sstevel@tonic-gate 	if (!EMBEDDED_SCSI && cur_list.list == NULL) {
12547c478bd9Sstevel@tonic-gate 		err_print("Current Defect List must be initialized.\n");
12557c478bd9Sstevel@tonic-gate 		return (-1);
12567c478bd9Sstevel@tonic-gate 	}
12577c478bd9Sstevel@tonic-gate 	/*
12587c478bd9Sstevel@tonic-gate 	 * Ask the user which sector has gone bad.
12597c478bd9Sstevel@tonic-gate 	 */
12607c478bd9Sstevel@tonic-gate 	ioparam.io_bounds.lower = 0;
12617c478bd9Sstevel@tonic-gate 	if (cur_disk->label_type == L_TYPE_SOLARIS) {
12627c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.upper = physsects() - 1;
12637c478bd9Sstevel@tonic-gate 	} else {
12647c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba;
12657c478bd9Sstevel@tonic-gate 	}
12667c478bd9Sstevel@tonic-gate 	bn = input(FIO_BN,
12677c478bd9Sstevel@tonic-gate 	    "Enter absolute block number of defect", ':',
12687c478bd9Sstevel@tonic-gate 	    &ioparam, (int *)NULL, DATA_INPUT);
12697c478bd9Sstevel@tonic-gate 	/*
12707c478bd9Sstevel@tonic-gate 	 * Check to see if there is a mounted file system over the
12717c478bd9Sstevel@tonic-gate 	 * specified sector.  If there is, make sure the user is
12727c478bd9Sstevel@tonic-gate 	 * really serious.
12737c478bd9Sstevel@tonic-gate 	 */
12747c478bd9Sstevel@tonic-gate 	if (checkmount(bn, bn)) {
12757c478bd9Sstevel@tonic-gate 		if (check("Repair is in a mounted partition, continue"))
12767c478bd9Sstevel@tonic-gate 			return (-1);
12777c478bd9Sstevel@tonic-gate 	}
12787c478bd9Sstevel@tonic-gate 	/*
12797c478bd9Sstevel@tonic-gate 	 * check for partitions being used for swapping in format zone
12807c478bd9Sstevel@tonic-gate 	 */
12817c478bd9Sstevel@tonic-gate 	if (checkswap(bn, bn)) {
12827c478bd9Sstevel@tonic-gate 		if (check("Repair is in a partition which is currently \
12837c478bd9Sstevel@tonic-gate being used for swapping.\ncontinue"))
12847c478bd9Sstevel@tonic-gate 		return (-1);
12857c478bd9Sstevel@tonic-gate 	}
12867c478bd9Sstevel@tonic-gate 
12873e1bd7a2Ssjelinek 	if (checkdevinuse(cur_disk->disk_name, bn, bn, 0, 0)) {
12883e1bd7a2Ssjelinek 		if (check("Repair is in a partition which is currently "
12893e1bd7a2Ssjelinek 		    "in use.\ncontinue"))
12903e1bd7a2Ssjelinek 			return (-1);
12913e1bd7a2Ssjelinek 	}
12923e1bd7a2Ssjelinek 
129365908c77Syu, larry liu - Sun Microsystems - Beijing China 	buf = zalloc((cur_disk->disk_lbasize == 0) ?
129465908c77Syu, larry liu - Sun Microsystems - Beijing China 	    SECSIZE : cur_disk->disk_lbasize);
129565908c77Syu, larry liu - Sun Microsystems - Beijing China 
12967c478bd9Sstevel@tonic-gate 	/*
12977c478bd9Sstevel@tonic-gate 	 * Try to read the sector before repairing it.  If we can
12987c478bd9Sstevel@tonic-gate 	 * get good data out of it, we can write that data back
12997c478bd9Sstevel@tonic-gate 	 * after the repair.  If the sector looks ok, ask the
13007c478bd9Sstevel@tonic-gate 	 * user to confirm the repair, since it doesn't appear
13017c478bd9Sstevel@tonic-gate 	 * necessary.  Try reading the block several times to
13027c478bd9Sstevel@tonic-gate 	 * see if we can read it consistently.
13037c478bd9Sstevel@tonic-gate 	 *
13047c478bd9Sstevel@tonic-gate 	 * First, let's see if the block appears to have problems...
13057c478bd9Sstevel@tonic-gate 	 */
13067c478bd9Sstevel@tonic-gate 	block_has_error = 1;
13077c478bd9Sstevel@tonic-gate 	for (i = 0; i < 5; i++) {
13087c478bd9Sstevel@tonic-gate 		status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, bn,
13097c478bd9Sstevel@tonic-gate 		    1, buf, (F_SILENT | F_ALLERRS), NULL);
13107c478bd9Sstevel@tonic-gate 		if (status)
13117c478bd9Sstevel@tonic-gate 			break;		/* one of the tries failed */
13127c478bd9Sstevel@tonic-gate 	}
13137c478bd9Sstevel@tonic-gate 	if (status == 0) {
13147c478bd9Sstevel@tonic-gate 		block_has_error = 0;
13157c478bd9Sstevel@tonic-gate 		if (check("\
13167c478bd9Sstevel@tonic-gate This block doesn't appear to be bad.  Repair it anyway")) {
131765908c77Syu, larry liu - Sun Microsystems - Beijing China 			free(buf);
13187c478bd9Sstevel@tonic-gate 			return (0);
13197c478bd9Sstevel@tonic-gate 		}
13207c478bd9Sstevel@tonic-gate 	}
13217c478bd9Sstevel@tonic-gate 	/*
13227c478bd9Sstevel@tonic-gate 	 * Last chance...
13237c478bd9Sstevel@tonic-gate 	 */
13247c478bd9Sstevel@tonic-gate 	if (check("Ready to repair defect, continue")) {
132565908c77Syu, larry liu - Sun Microsystems - Beijing China 		free(buf);
13267c478bd9Sstevel@tonic-gate 		return (-1);
13277c478bd9Sstevel@tonic-gate 	}
13287c478bd9Sstevel@tonic-gate 	/*
13297c478bd9Sstevel@tonic-gate 	 * We're committed to repairing it.  Try to get any good
13307c478bd9Sstevel@tonic-gate 	 * data out of the block if possible.  Note that we do
13317c478bd9Sstevel@tonic-gate 	 * not set the F_ALLERRS flag.
13327c478bd9Sstevel@tonic-gate 	 */
13337c478bd9Sstevel@tonic-gate 	buf_is_good = 0;
13347c478bd9Sstevel@tonic-gate 	for (i = 0; i < 5; i++) {
13357c478bd9Sstevel@tonic-gate 		status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, bn,
13367c478bd9Sstevel@tonic-gate 		    1, buf, F_SILENT, NULL);
13377c478bd9Sstevel@tonic-gate 		if (status == 0) {
13387c478bd9Sstevel@tonic-gate 			buf_is_good = 1;
13397c478bd9Sstevel@tonic-gate 			break;
13407c478bd9Sstevel@tonic-gate 		}
13417c478bd9Sstevel@tonic-gate 	}
13427c478bd9Sstevel@tonic-gate 	/*
13437c478bd9Sstevel@tonic-gate 	 * Lock out interrupts so the disk can't get out of sync with
13447c478bd9Sstevel@tonic-gate 	 * the defect list.
13457c478bd9Sstevel@tonic-gate 	 */
13467c478bd9Sstevel@tonic-gate 	enter_critical();
13477c478bd9Sstevel@tonic-gate 
13487c478bd9Sstevel@tonic-gate 	fmt_print("Repairing ");
13497c478bd9Sstevel@tonic-gate 	if (block_has_error) {
13507c478bd9Sstevel@tonic-gate 		fmt_print("%s error on ", buf_is_good ? "soft" : "hard");
13517c478bd9Sstevel@tonic-gate 	}
13527c478bd9Sstevel@tonic-gate 	fmt_print("block %llu (", bn);
13537c478bd9Sstevel@tonic-gate 	pr_dblock(fmt_print, bn);
13547c478bd9Sstevel@tonic-gate 	fmt_print(")...");
13557c478bd9Sstevel@tonic-gate 	/*
13567c478bd9Sstevel@tonic-gate 	 * Do the repair.
13577c478bd9Sstevel@tonic-gate 	 */
13587c478bd9Sstevel@tonic-gate 	status = (*cur_ops->op_repair)(bn, F_NORMAL);
13597c478bd9Sstevel@tonic-gate 	if (status) {
13607c478bd9Sstevel@tonic-gate 		fmt_print("failed.\n\n");
13617c478bd9Sstevel@tonic-gate 	} else {
13627c478bd9Sstevel@tonic-gate 		/*
13637c478bd9Sstevel@tonic-gate 		 * The repair worked.  Write the old data to the new
13647c478bd9Sstevel@tonic-gate 		 * block if we were able to read it, otherwise
13657c478bd9Sstevel@tonic-gate 		 * zero out the new block.  If it looks like the
13667c478bd9Sstevel@tonic-gate 		 * new block is bad, let the user know that, too.
13677c478bd9Sstevel@tonic-gate 		 * Should we attempt auto-repair in this case?
13687c478bd9Sstevel@tonic-gate 		 */
13697c478bd9Sstevel@tonic-gate 		fmt_print("ok.\n");
13707c478bd9Sstevel@tonic-gate 		if (!buf_is_good) {
137165908c77Syu, larry liu - Sun Microsystems - Beijing China 			bzero(buf, cur_disk->disk_lbasize);
13727c478bd9Sstevel@tonic-gate 		}
13737c478bd9Sstevel@tonic-gate 		status = (*cur_ops->op_rdwr)(DIR_WRITE, cur_file, bn,
13747c478bd9Sstevel@tonic-gate 		    1, buf, (F_SILENT | F_ALLERRS), NULL);
13757c478bd9Sstevel@tonic-gate 		if (status == 0) {
13767c478bd9Sstevel@tonic-gate 			status = (*cur_ops->op_rdwr)(DIR_READ, cur_file,
13777c478bd9Sstevel@tonic-gate 			    bn, 1, buf, (F_SILENT | F_ALLERRS), NULL);
13787c478bd9Sstevel@tonic-gate 		}
13797c478bd9Sstevel@tonic-gate 		if (status) {
13807c478bd9Sstevel@tonic-gate 			fmt_print("The new block %llu (", bn);
13817c478bd9Sstevel@tonic-gate 			pr_dblock(fmt_print, bn);
13827c478bd9Sstevel@tonic-gate 			fmt_print(") also appears defective.\n");
13837c478bd9Sstevel@tonic-gate 		}
13847c478bd9Sstevel@tonic-gate 		fmt_print("\n");
13857c478bd9Sstevel@tonic-gate 		/*
13867c478bd9Sstevel@tonic-gate 		 * Add the bad sector to the defect list, write out
13877c478bd9Sstevel@tonic-gate 		 * the defect list, and kill off the working list so
13887c478bd9Sstevel@tonic-gate 		 * it will get synced up with the current defect list
13897c478bd9Sstevel@tonic-gate 		 * next time we need it.
13907c478bd9Sstevel@tonic-gate 		 *
13917c478bd9Sstevel@tonic-gate 		 * For embedded scsi, we don't require a defect list.
13927c478bd9Sstevel@tonic-gate 		 * However, if we have one, add the defect if the
13937c478bd9Sstevel@tonic-gate 		 * list includes the grown list.  If not, kill it
13947c478bd9Sstevel@tonic-gate 		 * to force a resync if we need the list later.
13957c478bd9Sstevel@tonic-gate 		 */
13967c478bd9Sstevel@tonic-gate 		if (EMBEDDED_SCSI) {
13977c478bd9Sstevel@tonic-gate 			if (cur_list.list != NULL) {
13987c478bd9Sstevel@tonic-gate 				if (cur_list.flags & LIST_PGLIST) {
13997c478bd9Sstevel@tonic-gate 					add_ldef(bn, &cur_list);
14007c478bd9Sstevel@tonic-gate 				} else {
14017c478bd9Sstevel@tonic-gate 					kill_deflist(&cur_list);
14027c478bd9Sstevel@tonic-gate 				}
14037c478bd9Sstevel@tonic-gate 			}
14047c478bd9Sstevel@tonic-gate 		} else if (cur_ctype->ctype_flags & CF_WLIST) {
14057c478bd9Sstevel@tonic-gate 			kill_deflist(&cur_list);
14067c478bd9Sstevel@tonic-gate 			if (*cur_ops->op_ex_cur != NULL) {
14077c478bd9Sstevel@tonic-gate 				(*cur_ops->op_ex_cur)(&cur_list);
14087c478bd9Sstevel@tonic-gate 				fmt_print("Current list updated\n");
14097c478bd9Sstevel@tonic-gate 			}
14107c478bd9Sstevel@tonic-gate 		} else {
14117c478bd9Sstevel@tonic-gate 			add_ldef(bn, &cur_list);
14127c478bd9Sstevel@tonic-gate 			write_deflist(&cur_list);
14137c478bd9Sstevel@tonic-gate 		}
14147c478bd9Sstevel@tonic-gate 		kill_deflist(&work_list);
14157c478bd9Sstevel@tonic-gate 	}
14167c478bd9Sstevel@tonic-gate 	exit_critical();
141765908c77Syu, larry liu - Sun Microsystems - Beijing China 	free(buf);
141865908c77Syu, larry liu - Sun Microsystems - Beijing China 
14197c478bd9Sstevel@tonic-gate 	/*
14207c478bd9Sstevel@tonic-gate 	 * Return status.
14217c478bd9Sstevel@tonic-gate 	 */
14227c478bd9Sstevel@tonic-gate 	return (status);
14237c478bd9Sstevel@tonic-gate }
14247c478bd9Sstevel@tonic-gate 
14257c478bd9Sstevel@tonic-gate /*
14267c478bd9Sstevel@tonic-gate  * This routine implements the 'show' command.  It translates a disk
14277c478bd9Sstevel@tonic-gate  * block given in any format into decimal, hexadecimal, and
14287c478bd9Sstevel@tonic-gate  * cylinder/head/sector format.
14297c478bd9Sstevel@tonic-gate  */
14307c478bd9Sstevel@tonic-gate int
c_show()14317c478bd9Sstevel@tonic-gate c_show()
14327c478bd9Sstevel@tonic-gate {
14337c478bd9Sstevel@tonic-gate 	u_ioparam_t	ioparam;
1434342440ecSPrasad Singamsetty 	diskaddr_t	bn;
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate 	/*
14377c478bd9Sstevel@tonic-gate 	 * There must be a current disk type, so we will know the geometry.
14387c478bd9Sstevel@tonic-gate 	 */
14397c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
14407c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
14417c478bd9Sstevel@tonic-gate 		return (-1);
14427c478bd9Sstevel@tonic-gate 	}
14437c478bd9Sstevel@tonic-gate 	/*
14447c478bd9Sstevel@tonic-gate 	 * Ask the user for a disk block.
14457c478bd9Sstevel@tonic-gate 	 */
14467c478bd9Sstevel@tonic-gate 	ioparam.io_bounds.lower = 0;
14477c478bd9Sstevel@tonic-gate 	if (cur_disk->label_type == L_TYPE_SOLARIS) {
14487c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.upper = physsects() - 1;
14497c478bd9Sstevel@tonic-gate 	} else {
14507c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba;
14517c478bd9Sstevel@tonic-gate 	}
1452342440ecSPrasad Singamsetty 	bn = input(FIO_BN, "Enter a disk block", ':',
14537c478bd9Sstevel@tonic-gate 	    &ioparam, (int *)NULL, DATA_INPUT);
14547c478bd9Sstevel@tonic-gate 	/*
14557c478bd9Sstevel@tonic-gate 	 * Echo it back.
14567c478bd9Sstevel@tonic-gate 	 */
1457342440ecSPrasad Singamsetty 	fmt_print("Disk block = %lld = 0x%llx = (", bn, bn);
14587c478bd9Sstevel@tonic-gate 	pr_dblock(fmt_print, bn);
14597c478bd9Sstevel@tonic-gate 	fmt_print(")\n\n");
14607c478bd9Sstevel@tonic-gate 	return (0);
14617c478bd9Sstevel@tonic-gate }
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate /*
14647c478bd9Sstevel@tonic-gate  * This routine implements the 'label' command.  It writes the
14657c478bd9Sstevel@tonic-gate  * primary and backup labels onto the current disk.
14667c478bd9Sstevel@tonic-gate  */
14677c478bd9Sstevel@tonic-gate int
c_label()14687c478bd9Sstevel@tonic-gate c_label()
14697c478bd9Sstevel@tonic-gate {
14707c478bd9Sstevel@tonic-gate 	int			status;
14717c478bd9Sstevel@tonic-gate 	int			deflt, *defltptr = NULL;
14727c478bd9Sstevel@tonic-gate 
14737c478bd9Sstevel@tonic-gate 	/*
14747c478bd9Sstevel@tonic-gate 	 * There must be a current disk type (and therefore a current disk).
14757c478bd9Sstevel@tonic-gate 	 */
14767c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
14777c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
14787c478bd9Sstevel@tonic-gate 		return (-1);
14797c478bd9Sstevel@tonic-gate 	}
14807c478bd9Sstevel@tonic-gate 	/*
14817c478bd9Sstevel@tonic-gate 	 * The current disk must be formatted to label it.
14827c478bd9Sstevel@tonic-gate 	 */
14837c478bd9Sstevel@tonic-gate 	if (!(cur_flags & DISK_FORMATTED)) {
14847c478bd9Sstevel@tonic-gate 		err_print("Current Disk is unformatted.\n");
14857c478bd9Sstevel@tonic-gate 		return (-1);
14867c478bd9Sstevel@tonic-gate 	}
14877c478bd9Sstevel@tonic-gate 	/*
14887c478bd9Sstevel@tonic-gate 	 * Check for a valid fdisk table entry for Solaris
14897c478bd9Sstevel@tonic-gate 	 */
14907c478bd9Sstevel@tonic-gate 	if (!good_fdisk()) {
14917c478bd9Sstevel@tonic-gate 		return (-1);
14927c478bd9Sstevel@tonic-gate 	}
14937c478bd9Sstevel@tonic-gate 	/*
14947c478bd9Sstevel@tonic-gate 	 * Check to see if there are any mounted file systems anywhere
14957c478bd9Sstevel@tonic-gate 	 * on the current disk.  If so, refuse to label the disk, but
14967c478bd9Sstevel@tonic-gate 	 * only if the partitions would change for the mounted partitions.
14977c478bd9Sstevel@tonic-gate 	 *
14987c478bd9Sstevel@tonic-gate 	 */
1499342440ecSPrasad Singamsetty 	if (checkmount((diskaddr_t)-1, (diskaddr_t)-1)) {
15007c478bd9Sstevel@tonic-gate 		/* Bleagh, too descriptive */
15017c478bd9Sstevel@tonic-gate 		if (check_label_with_mount()) {
15027c478bd9Sstevel@tonic-gate 			err_print("Cannot label disk while it has "
15037c478bd9Sstevel@tonic-gate 			    "mounted partitions.\n\n");
15047c478bd9Sstevel@tonic-gate 			return (-1);
15057c478bd9Sstevel@tonic-gate 		}
15067c478bd9Sstevel@tonic-gate 	}
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 	/*
15097c478bd9Sstevel@tonic-gate 	 * check to see if there any partitions being used for swapping
15107c478bd9Sstevel@tonic-gate 	 * on the current disk.  If so, refuse to label the disk, but
15117c478bd9Sstevel@tonic-gate 	 * only if the partitions would change for the mounted partitions.
15127c478bd9Sstevel@tonic-gate 	 */
1513342440ecSPrasad Singamsetty 	if (checkswap((diskaddr_t)-1, (diskaddr_t)-1)) {
15147c478bd9Sstevel@tonic-gate 		if (check_label_with_swap()) {
15157c478bd9Sstevel@tonic-gate 			err_print("Cannot label disk while its "
15167c478bd9Sstevel@tonic-gate 			    "partitions are currently being used for "
15177c478bd9Sstevel@tonic-gate 			    "swapping.\n");
15187c478bd9Sstevel@tonic-gate 			return (-1);
15197c478bd9Sstevel@tonic-gate 		}
15207c478bd9Sstevel@tonic-gate 	}
15217c478bd9Sstevel@tonic-gate 
15223e1bd7a2Ssjelinek 	/*
15233e1bd7a2Ssjelinek 	 * Check to see if any partitions used for svm, vxvm or live upgrade
15243e1bd7a2Ssjelinek 	 * are on the disk. If so, refuse to label the disk, but only
15253e1bd7a2Ssjelinek 	 * if we are trying to shrink a partition in use.
15263e1bd7a2Ssjelinek 	 */
15273e1bd7a2Ssjelinek 	if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
15283e1bd7a2Ssjelinek 	    (diskaddr_t)-1, 0, 1)) {
15293e1bd7a2Ssjelinek 		err_print("Cannot label disk when "
15303e1bd7a2Ssjelinek 		    "partitions are in use as described.\n");
15313e1bd7a2Ssjelinek 		return (-1);
15323e1bd7a2Ssjelinek 	}
15337c478bd9Sstevel@tonic-gate 
15347c478bd9Sstevel@tonic-gate 	/*
15357c478bd9Sstevel@tonic-gate 	 * If there is not a current partition map, warn the user we
15367c478bd9Sstevel@tonic-gate 	 * are going to use the default.  The default is the first
15377c478bd9Sstevel@tonic-gate 	 * partition map we encountered in the data file.  If there is
15387c478bd9Sstevel@tonic-gate 	 * no default we give up.
15397c478bd9Sstevel@tonic-gate 	 */
15407c478bd9Sstevel@tonic-gate 	if (cur_parts == NULL) {
15417c478bd9Sstevel@tonic-gate 		fmt_print("Current Partition Table is not set, "
15427c478bd9Sstevel@tonic-gate 		    "using default.\n");
15437c478bd9Sstevel@tonic-gate 		cur_disk->disk_parts = cur_parts = cur_dtype->dtype_plist;
15447c478bd9Sstevel@tonic-gate 		if (cur_parts == NULL) {
15457c478bd9Sstevel@tonic-gate 			err_print("No default available, cannot label.\n");
15467c478bd9Sstevel@tonic-gate 			return (-1);
15477c478bd9Sstevel@tonic-gate 		}
15487c478bd9Sstevel@tonic-gate 	}
15497c478bd9Sstevel@tonic-gate 	/*
15507c478bd9Sstevel@tonic-gate 	 * If expert (-e) mode, then ask user if they wish
15517c478bd9Sstevel@tonic-gate 	 * to change the current solaris label into an EFI one
15527c478bd9Sstevel@tonic-gate 	 */
15537c478bd9Sstevel@tonic-gate 	if (expert_mode) {
15547c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
15557c478bd9Sstevel@tonic-gate 		int 		i;
15567c478bd9Sstevel@tonic-gate #endif
15577c478bd9Sstevel@tonic-gate 		int 		choice;
15587c478bd9Sstevel@tonic-gate 		u_ioparam_t		ioparam;
1559342440ecSPrasad Singamsetty 		struct extvtoc	vtoc;
15607c478bd9Sstevel@tonic-gate 		struct dk_label	label;
15617c478bd9Sstevel@tonic-gate 		struct dk_gpt	*vtoc64;
15627c478bd9Sstevel@tonic-gate 		struct efi_info	efinfo;
15637c478bd9Sstevel@tonic-gate 		struct disk_type	*dptr;
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate 		/* Ask user what label to use */
15667c478bd9Sstevel@tonic-gate 		fmt_print("[0] SMI Label\n");
15677c478bd9Sstevel@tonic-gate 		fmt_print("[1] EFI Label\n");
15687c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.lower = 0;
15697c478bd9Sstevel@tonic-gate 		ioparam.io_bounds.upper = 1;
15709ef03c05SAlexander Eremin 		if ((cur_label == L_TYPE_SOLARIS) &&
15719ef03c05SAlexander Eremin 		    (cur_disk->fdisk_part.systid != EFI_PMBR))
15729ef03c05SAlexander Eremin 			deflt = L_TYPE_SOLARIS;
15737c478bd9Sstevel@tonic-gate 		else
15749ef03c05SAlexander Eremin 			deflt = L_TYPE_EFI;
15757c478bd9Sstevel@tonic-gate 		defltptr = &deflt;
15767c478bd9Sstevel@tonic-gate 		choice = input(FIO_INT, "Specify Label type", ':',
15777c478bd9Sstevel@tonic-gate 		    &ioparam, defltptr, DATA_INPUT);
15789ef03c05SAlexander Eremin 		if ((choice == L_TYPE_SOLARIS) &&
15799ef03c05SAlexander Eremin 		    (cur_label == L_TYPE_SOLARIS) &&
15809ef03c05SAlexander Eremin 		    (cur_disk->fdisk_part.systid != EFI_PMBR)) {
15817c478bd9Sstevel@tonic-gate 			goto expert_end;
15829ef03c05SAlexander Eremin 		} else if ((choice == L_TYPE_EFI) &&
15839ef03c05SAlexander Eremin 		    (cur_label == L_TYPE_EFI)) {
15847c478bd9Sstevel@tonic-gate 			goto expert_end;
15857c478bd9Sstevel@tonic-gate 		}
15867c478bd9Sstevel@tonic-gate 		switch (choice) {
15879ef03c05SAlexander Eremin 		case L_TYPE_SOLARIS:
15887c478bd9Sstevel@tonic-gate 		/*
15897c478bd9Sstevel@tonic-gate 		 * EFI label to SMI label
15907c478bd9Sstevel@tonic-gate 		 */
15917c478bd9Sstevel@tonic-gate 		if (cur_dtype->capacity > INFINITY) {
159265908c77Syu, larry liu - Sun Microsystems - Beijing China 			fmt_print("Warning: SMI labels only support up to "
159365908c77Syu, larry liu - Sun Microsystems - Beijing China 			    "2 TB.\n");
15947c478bd9Sstevel@tonic-gate 		}
15957c478bd9Sstevel@tonic-gate 
1596342440ecSPrasad Singamsetty 		if (cur_disk->fdisk_part.systid == EFI_PMBR) {
159765908c77Syu, larry liu - Sun Microsystems - Beijing China 			fmt_print("Warning: This disk has an EFI label. "
159865908c77Syu, larry liu - Sun Microsystems - Beijing China 			    "Changing to SMI label will erase all\n"
159965908c77Syu, larry liu - Sun Microsystems - Beijing China 			    "current partitions.\n");
16003ccda647Slclee 			if (check("Continue"))
16013ccda647Slclee 			return (-1);
1602342440ecSPrasad Singamsetty #if defined(_FIRMWARE_NEEDS_FDISK)
1603895142e0Syl194034 			fmt_print("You must use fdisk to delete the current "
1604895142e0Syl194034 			    "EFI partition and create a new\n"
1605895142e0Syl194034 			    "Solaris partition before you can convert the "
1606895142e0Syl194034 			    "label.\n");
1607895142e0Syl194034 			return (-1);
1608342440ecSPrasad Singamsetty #endif
1609895142e0Syl194034 		}
1610895142e0Syl194034 
1611342440ecSPrasad Singamsetty #if defined(_FIRMWARE_NEEDS_FDISK)
1612342440ecSPrasad Singamsetty 		if (!(((cur_disk->fdisk_part.systid != SUNIXOS) ||
1613342440ecSPrasad Singamsetty 		    (cur_disk->fdisk_part.systid != SUNIXOS2)) &&
1614342440ecSPrasad Singamsetty 		    (cur_disk->fdisk_part.numsect > 0))) {
1615342440ecSPrasad Singamsetty 			fmt_print("You must use fdisk to create a Solaris "
1616342440ecSPrasad Singamsetty 			    "partition before you can convert the label.\n");
1617342440ecSPrasad Singamsetty 			return (-1);
1618342440ecSPrasad Singamsetty 		}
1619342440ecSPrasad Singamsetty #endif
1620342440ecSPrasad Singamsetty 
1621342440ecSPrasad Singamsetty 		(void) memset((char *)&label, 0, sizeof (struct dk_label));
1622342440ecSPrasad Singamsetty 
1623e17fd3dcSshidokht 		(void) strcpy(x86_devname, cur_disk->disk_name);
16243ccda647Slclee 		if (cur_ctype->ctype_ctype == DKC_DIRECT)
16253ccda647Slclee 			dptr = auto_direct_get_geom_label(cur_file,  &label);
16263ccda647Slclee 		else
16273ccda647Slclee 			dptr = auto_sense(cur_file, 1, &label);
16287c478bd9Sstevel@tonic-gate 		if (dptr == NULL) {
16297c478bd9Sstevel@tonic-gate 			fmt_print("Autoconfiguration failed.\n");
16307c478bd9Sstevel@tonic-gate 			return (-1);
16317c478bd9Sstevel@tonic-gate 		}
16327c478bd9Sstevel@tonic-gate 
16333ccda647Slclee 		pcyl = label.dkl_pcyl;
16343ccda647Slclee 		ncyl = label.dkl_ncyl;
16353ccda647Slclee 		acyl = label.dkl_acyl;
16363ccda647Slclee 		nhead = label.dkl_nhead;
16373ccda647Slclee 		nsect = label.dkl_nsect;
16383ccda647Slclee 
1639698107ecSlh195018 		if (delete_disk_type(cur_disk->disk_type) == 0) {
16407c478bd9Sstevel@tonic-gate 			cur_label = L_TYPE_SOLARIS;
16417c478bd9Sstevel@tonic-gate 			cur_disk->label_type = L_TYPE_SOLARIS;
16427c478bd9Sstevel@tonic-gate 			cur_disk->disk_type = dptr;
16437c478bd9Sstevel@tonic-gate 			cur_disk->disk_parts = dptr->dtype_plist;
16447c478bd9Sstevel@tonic-gate 			cur_dtype = dptr;
16457c478bd9Sstevel@tonic-gate 			cur_parts = dptr->dtype_plist;
16463ccda647Slclee 
16473ccda647Slclee 			if (status = write_label())
16483ccda647Slclee 				err_print("Label failed.\n");
1649698107ecSlh195018 			else
1650698107ecSlh195018 				cur_disk->disk_flags &= ~DSK_LABEL_DIRTY;
1651698107ecSlh195018 
16523ccda647Slclee 			return (status);
1653698107ecSlh195018 		} else {
1654698107ecSlh195018 			err_print("Label failed.\n");
1655698107ecSlh195018 			return (-1);
1656698107ecSlh195018 		}
16573ccda647Slclee 
16583ccda647Slclee 
16599ef03c05SAlexander Eremin 		case L_TYPE_EFI:
16607c478bd9Sstevel@tonic-gate 		/*
16617c478bd9Sstevel@tonic-gate 		 * SMI label to EFI label
16627c478bd9Sstevel@tonic-gate 		 */
16633ccda647Slclee 
16649ef03c05SAlexander Eremin 		if ((cur_disk->fdisk_part.systid == SUNIXOS) ||
16659ef03c05SAlexander Eremin 		    (cur_disk->fdisk_part.systid == SUNIXOS2)) {
16669ef03c05SAlexander Eremin 			fmt_print("Warning: This disk has an SMI label. "
16679ef03c05SAlexander Eremin 			    "Changing to EFI label will erase all\ncurrent "
16689ef03c05SAlexander Eremin 			    "partitions.\n");
16697c478bd9Sstevel@tonic-gate 			if (check("Continue")) {
16707c478bd9Sstevel@tonic-gate 				return (-1);
16717c478bd9Sstevel@tonic-gate 			}
16729ef03c05SAlexander Eremin 		}
16737c478bd9Sstevel@tonic-gate 
1674*9aa4340aSHans Rosenfeld 		if (get_disk_info(cur_file, &efinfo, cur_disk) != 0) {
16757c478bd9Sstevel@tonic-gate 			return (-1);
16767c478bd9Sstevel@tonic-gate 		}
16777c478bd9Sstevel@tonic-gate 		(void) memset((char *)&label, 0, sizeof (struct dk_label));
16787c478bd9Sstevel@tonic-gate 		label.dkl_pcyl = pcyl;
16797c478bd9Sstevel@tonic-gate 		label.dkl_ncyl = ncyl;
16807c478bd9Sstevel@tonic-gate 		label.dkl_acyl = acyl;
16817c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
16827c478bd9Sstevel@tonic-gate 		label.dkl_bcyl = bcyl;
16837c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOC_VTOC_16) */
16847c478bd9Sstevel@tonic-gate 		label.dkl_nhead = nhead;
16857c478bd9Sstevel@tonic-gate 		label.dkl_nsect = nsect;
16867c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
16877c478bd9Sstevel@tonic-gate 		for (i = 0; i < NDKMAP; i++) {
16887c478bd9Sstevel@tonic-gate 			label.dkl_map[i] = cur_parts->pinfo_map[i];
16897c478bd9Sstevel@tonic-gate 		}
16907c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
16917c478bd9Sstevel@tonic-gate 		label.dkl_magic = DKL_MAGIC;
16927c478bd9Sstevel@tonic-gate 		label.dkl_vtoc = cur_parts->vtoc;
16937c478bd9Sstevel@tonic-gate 		if (label_to_vtoc(&vtoc, &label) == -1) {
16947c478bd9Sstevel@tonic-gate 			return (-1);
16957c478bd9Sstevel@tonic-gate 		}
16960d9ffb6aSgz161490 		if (SMI_vtoc_to_EFI(cur_file, &vtoc64) == -1) {
16977c478bd9Sstevel@tonic-gate 			return (-1);
16987c478bd9Sstevel@tonic-gate 		}
16997c478bd9Sstevel@tonic-gate 		if (efi_write(cur_file, vtoc64) != 0) {
17007c478bd9Sstevel@tonic-gate 			err_check(vtoc64);
17017c478bd9Sstevel@tonic-gate 			err_print("Warning: error writing EFI.\n");
17027c478bd9Sstevel@tonic-gate 			return (-1);
1703698107ecSlh195018 		} else {
1704698107ecSlh195018 			cur_disk->disk_flags &= ~DSK_LABEL_DIRTY;
17057c478bd9Sstevel@tonic-gate 		}
17067c478bd9Sstevel@tonic-gate 		/*
17077c478bd9Sstevel@tonic-gate 		 * copy over the EFI vtoc onto the SMI vtoc and return
17087c478bd9Sstevel@tonic-gate 		 * okay.
17097c478bd9Sstevel@tonic-gate 		 */
1710698107ecSlh195018 		dptr = auto_efi_sense(cur_file, &efinfo);
1711698107ecSlh195018 		if (dptr == NULL) {
1712698107ecSlh195018 			fmt_print("Autoconfiguration failed.\n");
1713698107ecSlh195018 			return (-1);
1714698107ecSlh195018 		}
1715698107ecSlh195018 
17167c478bd9Sstevel@tonic-gate 		cur_label = L_TYPE_EFI;
17177c478bd9Sstevel@tonic-gate 		cur_disk->label_type = L_TYPE_EFI;
1718698107ecSlh195018 		cur_disk->disk_type = dptr;
1719698107ecSlh195018 		cur_disk->disk_parts = dptr->dtype_plist;
1720698107ecSlh195018 		cur_dtype = dptr;
1721698107ecSlh195018 		cur_parts = dptr->dtype_plist;
1722698107ecSlh195018 		cur_parts->etoc = vtoc64;
1723698107ecSlh195018 
1724052b6e8aSbg159949 		ncyl = pcyl = nsect = psect = acyl = phead = 0;
17257c478bd9Sstevel@tonic-gate 
1726698107ecSlh195018 		/*
1727698107ecSlh195018 		 * Get the Solais Fdisk Partition information.
1728698107ecSlh195018 		 */
1729698107ecSlh195018 		(void) copy_solaris_part(&cur_disk->fdisk_part);
1730698107ecSlh195018 
17317c478bd9Sstevel@tonic-gate 		return (0);
17327c478bd9Sstevel@tonic-gate 		}
17337c478bd9Sstevel@tonic-gate 	}
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate expert_end:
17367c478bd9Sstevel@tonic-gate 	/*
17377c478bd9Sstevel@tonic-gate 	 * Make sure the user is serious.
17387c478bd9Sstevel@tonic-gate 	 */
17397c478bd9Sstevel@tonic-gate 	if (check("Ready to label disk, continue")) {
17407c478bd9Sstevel@tonic-gate 		return (-1);
17417c478bd9Sstevel@tonic-gate 	}
17427c478bd9Sstevel@tonic-gate 	/*
17437c478bd9Sstevel@tonic-gate 	 * Write the labels out (this will also notify unix) and
17447c478bd9Sstevel@tonic-gate 	 * return status.
17457c478bd9Sstevel@tonic-gate 	 */
17467c478bd9Sstevel@tonic-gate 	fmt_print("\n");
17477c478bd9Sstevel@tonic-gate 	if (status = write_label())
17487c478bd9Sstevel@tonic-gate 		err_print("Label failed.\n");
17497c478bd9Sstevel@tonic-gate 	return (status);
17507c478bd9Sstevel@tonic-gate }
17517c478bd9Sstevel@tonic-gate 
17527c478bd9Sstevel@tonic-gate /*
17537c478bd9Sstevel@tonic-gate  * This routine implements the 'analyze' command.  It simply runs
17547c478bd9Sstevel@tonic-gate  * the analyze menu.
17557c478bd9Sstevel@tonic-gate  */
17567c478bd9Sstevel@tonic-gate int
c_analyze()17577c478bd9Sstevel@tonic-gate c_analyze()
17587c478bd9Sstevel@tonic-gate {
17597c478bd9Sstevel@tonic-gate 
17607c478bd9Sstevel@tonic-gate 	/*
17617c478bd9Sstevel@tonic-gate 	 * There must be a current disk type (and therefor a current disk).
17627c478bd9Sstevel@tonic-gate 	 */
17637c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
17647c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
17657c478bd9Sstevel@tonic-gate 		return (-1);
17667c478bd9Sstevel@tonic-gate 	}
17677c478bd9Sstevel@tonic-gate 	cur_menu++;
17687c478bd9Sstevel@tonic-gate 	last_menu = cur_menu;
17697c478bd9Sstevel@tonic-gate 
17707c478bd9Sstevel@tonic-gate 	/*
17717c478bd9Sstevel@tonic-gate 	 * Run the menu.
17727c478bd9Sstevel@tonic-gate 	 */
17737c478bd9Sstevel@tonic-gate 	run_menu(menu_analyze, "ANALYZE", "analyze", 0);
17747c478bd9Sstevel@tonic-gate 	cur_menu--;
17757c478bd9Sstevel@tonic-gate 	return (0);
17767c478bd9Sstevel@tonic-gate }
17777c478bd9Sstevel@tonic-gate 
17787c478bd9Sstevel@tonic-gate /*
17797c478bd9Sstevel@tonic-gate  * This routine implements the 'defect' command.  It simply runs
17807c478bd9Sstevel@tonic-gate  * the defect menu.
17817c478bd9Sstevel@tonic-gate  */
17827c478bd9Sstevel@tonic-gate int
c_defect()17837c478bd9Sstevel@tonic-gate c_defect()
17847c478bd9Sstevel@tonic-gate {
17857c478bd9Sstevel@tonic-gate 	int	i;
17867c478bd9Sstevel@tonic-gate 
17877c478bd9Sstevel@tonic-gate 	/*
17887c478bd9Sstevel@tonic-gate 	 * There must be a current disk type (and therefor a current disk).
17897c478bd9Sstevel@tonic-gate 	 */
17907c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
17917c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
17927c478bd9Sstevel@tonic-gate 		return (-1);
17937c478bd9Sstevel@tonic-gate 	}
17947c478bd9Sstevel@tonic-gate 
17957c478bd9Sstevel@tonic-gate 	/*
17967c478bd9Sstevel@tonic-gate 	 * Check for the defect management and list management ops and
17977c478bd9Sstevel@tonic-gate 	 * display appropriate message.
17987c478bd9Sstevel@tonic-gate 	 */
17997c478bd9Sstevel@tonic-gate 	if ((cur_ops->op_ex_man == NULL) && (cur_ops->op_ex_cur == NULL) &&
18007c478bd9Sstevel@tonic-gate 	    (cur_ops->op_create == NULL) && (cur_ops->op_wr_cur == NULL)) {
18017c478bd9Sstevel@tonic-gate 		err_print("Controller does not support defect management\n");
18027c478bd9Sstevel@tonic-gate 		err_print("or disk supports automatic defect management.\n");
18037c478bd9Sstevel@tonic-gate 		return (-1);
18047c478bd9Sstevel@tonic-gate 	}
18057c478bd9Sstevel@tonic-gate 	cur_menu++;
18067c478bd9Sstevel@tonic-gate 	last_menu = cur_menu;
18077c478bd9Sstevel@tonic-gate 
18087c478bd9Sstevel@tonic-gate 	/*
18097c478bd9Sstevel@tonic-gate 	 * Lock out interrupt while we manipulate the defect lists.
18107c478bd9Sstevel@tonic-gate 	 */
18117c478bd9Sstevel@tonic-gate 	enter_critical();
18127c478bd9Sstevel@tonic-gate 	/*
18137c478bd9Sstevel@tonic-gate 	 * If the working list is null but there is a current list,
18147c478bd9Sstevel@tonic-gate 	 * update the working list to be a copy of the current list.
18157c478bd9Sstevel@tonic-gate 	 */
18167c478bd9Sstevel@tonic-gate 	if ((work_list.list == NULL) && (cur_list.list != NULL)) {
18177c478bd9Sstevel@tonic-gate 		work_list.header = cur_list.header;
18187c478bd9Sstevel@tonic-gate 		work_list.list = (struct defect_entry *)zalloc(
181965908c77Syu, larry liu - Sun Microsystems - Beijing China 		    deflist_size(cur_blksz, work_list.header.count) *
182065908c77Syu, larry liu - Sun Microsystems - Beijing China 		    cur_blksz);
18217c478bd9Sstevel@tonic-gate 		for (i = 0; i < work_list.header.count; i++)
18227c478bd9Sstevel@tonic-gate 			*(work_list.list + i) = *(cur_list.list + i);
18237c478bd9Sstevel@tonic-gate 		work_list.flags = cur_list.flags & LIST_PGLIST;
18247c478bd9Sstevel@tonic-gate 	}
18257c478bd9Sstevel@tonic-gate 	exit_critical();
18267c478bd9Sstevel@tonic-gate 	/*
18277c478bd9Sstevel@tonic-gate 	 * Run the menu.
18287c478bd9Sstevel@tonic-gate 	 */
18297c478bd9Sstevel@tonic-gate 	run_menu(menu_defect, "DEFECT", "defect", 0);
18307c478bd9Sstevel@tonic-gate 	cur_menu--;
18317c478bd9Sstevel@tonic-gate 
18327c478bd9Sstevel@tonic-gate 	/*
18337c478bd9Sstevel@tonic-gate 	 * If the user has modified the working list but not committed
18347c478bd9Sstevel@tonic-gate 	 * it, warn him that he is probably making a mistake.
18357c478bd9Sstevel@tonic-gate 	 */
18367c478bd9Sstevel@tonic-gate 	if (work_list.flags & LIST_DIRTY) {
18377c478bd9Sstevel@tonic-gate 		if (!EMBEDDED_SCSI) {
18387c478bd9Sstevel@tonic-gate 			err_print(
18397c478bd9Sstevel@tonic-gate 		"Warning: working defect list modified; but not committed.\n");
18407c478bd9Sstevel@tonic-gate 			if (!check(
18417c478bd9Sstevel@tonic-gate 		"Do you wish to commit changes to current defect list"))
18427c478bd9Sstevel@tonic-gate 			(void) do_commit();
18437c478bd9Sstevel@tonic-gate 		}
18447c478bd9Sstevel@tonic-gate 	}
18457c478bd9Sstevel@tonic-gate 	return (0);
18467c478bd9Sstevel@tonic-gate }
18477c478bd9Sstevel@tonic-gate 
18487c478bd9Sstevel@tonic-gate /*
18497c478bd9Sstevel@tonic-gate  * This routine implements the 'backup' command.  It allows the user
18507c478bd9Sstevel@tonic-gate  * to search for backup labels on the current disk.  This is useful
18517c478bd9Sstevel@tonic-gate  * if the primary label was lost and the user wishes to recover the
18527c478bd9Sstevel@tonic-gate  * partition information for the disk. The disk is relabeled and
18537c478bd9Sstevel@tonic-gate  * the current defect list is written out if a backup label is found.
18547c478bd9Sstevel@tonic-gate  */
18557c478bd9Sstevel@tonic-gate int
c_backup()18567c478bd9Sstevel@tonic-gate c_backup()
18577c478bd9Sstevel@tonic-gate {
18587c478bd9Sstevel@tonic-gate 	struct	dk_label label;
18597c478bd9Sstevel@tonic-gate 	struct	disk_type *dtype;
18607c478bd9Sstevel@tonic-gate 	struct	partition_info *parts, *plist;
1861342440ecSPrasad Singamsetty 	diskaddr_t	bn;
18627c478bd9Sstevel@tonic-gate 	int	sec, head, i;
186365908c77Syu, larry liu - Sun Microsystems - Beijing China 	char	*buf;
18647c478bd9Sstevel@tonic-gate 
18657c478bd9Sstevel@tonic-gate 	/*
18667c478bd9Sstevel@tonic-gate 	 * There must be a current disk type (and therefore a current disk).
18677c478bd9Sstevel@tonic-gate 	 */
18687c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
18697c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
18707c478bd9Sstevel@tonic-gate 		return (-1);
18717c478bd9Sstevel@tonic-gate 	}
18727c478bd9Sstevel@tonic-gate 	/*
18737c478bd9Sstevel@tonic-gate 	 * The disk must be formatted to read backup labels.
18747c478bd9Sstevel@tonic-gate 	 */
18757c478bd9Sstevel@tonic-gate 	if (!(cur_flags & DISK_FORMATTED)) {
18767c478bd9Sstevel@tonic-gate 		err_print("Current Disk is unformatted.\n");
18777c478bd9Sstevel@tonic-gate 		return (-1);
18787c478bd9Sstevel@tonic-gate 	}
18797c478bd9Sstevel@tonic-gate 	/*
18807c478bd9Sstevel@tonic-gate 	 * Check for a valid fdisk table entry for Solaris
18817c478bd9Sstevel@tonic-gate 	 */
18827c478bd9Sstevel@tonic-gate 	if (!good_fdisk()) {
18837c478bd9Sstevel@tonic-gate 		return (-1);
18847c478bd9Sstevel@tonic-gate 	}
18857c478bd9Sstevel@tonic-gate 	/*
18867c478bd9Sstevel@tonic-gate 	 * If we found a primary label on this disk, make sure
18877c478bd9Sstevel@tonic-gate 	 * the user is serious.
18887c478bd9Sstevel@tonic-gate 	 */
18897c478bd9Sstevel@tonic-gate 	if (cur_disk->label_type == L_TYPE_EFI) {
18907c478bd9Sstevel@tonic-gate 		if (((cur_disk->disk_parts->etoc->efi_flags &
18917c478bd9Sstevel@tonic-gate 		    EFI_GPT_PRIMARY_CORRUPT) == 0) &&
18927c478bd9Sstevel@tonic-gate 		    check("Disk has a primary label, still continue"))
18937c478bd9Sstevel@tonic-gate 			return (-1);
18947c478bd9Sstevel@tonic-gate 		fmt_print("Restoring primary label.\n");
18957c478bd9Sstevel@tonic-gate 		if (write_label()) {
18967c478bd9Sstevel@tonic-gate 			err_print("Failed\n");
18977c478bd9Sstevel@tonic-gate 			return (-1);
18987c478bd9Sstevel@tonic-gate 		}
18997c478bd9Sstevel@tonic-gate 		return (0);
19007c478bd9Sstevel@tonic-gate 	} else if (((cur_disk->disk_flags & (DSK_LABEL | DSK_LABEL_DIRTY)) ==
19017c478bd9Sstevel@tonic-gate 	    DSK_LABEL) &&
19027c478bd9Sstevel@tonic-gate 	    (check("Disk has a primary label, still continue"))) {
19037c478bd9Sstevel@tonic-gate 		return (-1);
19047c478bd9Sstevel@tonic-gate 	}
190565908c77Syu, larry liu - Sun Microsystems - Beijing China 
190665908c77Syu, larry liu - Sun Microsystems - Beijing China 	buf = zalloc(cur_blksz);
19077c478bd9Sstevel@tonic-gate 	fmt_print("Searching for backup labels...");
19087c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
190965908c77Syu, larry liu - Sun Microsystems - Beijing China 
19107c478bd9Sstevel@tonic-gate 	/*
19117c478bd9Sstevel@tonic-gate 	 * Some disks have the backup labels in a strange place.
19127c478bd9Sstevel@tonic-gate 	 */
19137c478bd9Sstevel@tonic-gate 	if (cur_ctype->ctype_flags & CF_BLABEL)
19147c478bd9Sstevel@tonic-gate 		head = 2;
19157c478bd9Sstevel@tonic-gate 	else
19167c478bd9Sstevel@tonic-gate 		head = nhead - 1;
19177c478bd9Sstevel@tonic-gate 	/*
19187c478bd9Sstevel@tonic-gate 	 * Loop through each copy of the backup label.
19197c478bd9Sstevel@tonic-gate 	 */
19207c478bd9Sstevel@tonic-gate 	for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect));
19217c478bd9Sstevel@tonic-gate 	    sec += 2) {
19227c478bd9Sstevel@tonic-gate 		bn = chs2bn(ncyl + acyl - 1, head, sec) + solaris_offset;
19237c478bd9Sstevel@tonic-gate 		/*
19247c478bd9Sstevel@tonic-gate 		 * Attempt to read it.
19257c478bd9Sstevel@tonic-gate 		 */
1926342440ecSPrasad Singamsetty 		if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, bn,
192765908c77Syu, larry liu - Sun Microsystems - Beijing China 		    1, buf, F_NORMAL, NULL)) {
19287c478bd9Sstevel@tonic-gate 			continue;
19297c478bd9Sstevel@tonic-gate 		}
193065908c77Syu, larry liu - Sun Microsystems - Beijing China 
193165908c77Syu, larry liu - Sun Microsystems - Beijing China 		(void *) memcpy((char *)&label, buf, sizeof (struct dk_label));
193265908c77Syu, larry liu - Sun Microsystems - Beijing China 
19337c478bd9Sstevel@tonic-gate 		/*
19347c478bd9Sstevel@tonic-gate 		 * Verify that it is a reasonable label.
19357c478bd9Sstevel@tonic-gate 		 */
19367c478bd9Sstevel@tonic-gate 		if (!checklabel(&label))
19377c478bd9Sstevel@tonic-gate 			continue;
19387c478bd9Sstevel@tonic-gate 		if (trim_id(label.dkl_asciilabel))
19397c478bd9Sstevel@tonic-gate 			continue;
19407c478bd9Sstevel@tonic-gate 		/*
19417c478bd9Sstevel@tonic-gate 		 * Lock out interrupts while we manipulate lists.
19427c478bd9Sstevel@tonic-gate 		 */
19437c478bd9Sstevel@tonic-gate 		enter_critical();
19447c478bd9Sstevel@tonic-gate 		fmt_print("found.\n");
19457c478bd9Sstevel@tonic-gate 		/*
19467c478bd9Sstevel@tonic-gate 		 * Find out which disk type the backup label claims.
19477c478bd9Sstevel@tonic-gate 		 */
19487c478bd9Sstevel@tonic-gate 		for (dtype = cur_ctype->ctype_dlist; dtype != NULL;
19497c478bd9Sstevel@tonic-gate 		    dtype = dtype->dtype_next)
19507c478bd9Sstevel@tonic-gate 			if (dtype_match(&label, dtype))
19517c478bd9Sstevel@tonic-gate 				break;
19527c478bd9Sstevel@tonic-gate 		/*
19537c478bd9Sstevel@tonic-gate 		 * If it disagrees with our current type, something
19547c478bd9Sstevel@tonic-gate 		 * real bad is happening.
19557c478bd9Sstevel@tonic-gate 		 */
19567c478bd9Sstevel@tonic-gate 		if (dtype != cur_dtype) {
19577c478bd9Sstevel@tonic-gate 			if (dtype == NULL) {
19587c478bd9Sstevel@tonic-gate 				fmt_print("\
19597c478bd9Sstevel@tonic-gate Unknown disk type in backup label\n");
19607c478bd9Sstevel@tonic-gate 				exit_critical();
196165908c77Syu, larry liu - Sun Microsystems - Beijing China 				free(buf);
19627c478bd9Sstevel@tonic-gate 				return (-1);
19637c478bd9Sstevel@tonic-gate 			}
19647c478bd9Sstevel@tonic-gate 			fmt_print("Backup label claims different type:\n");
19657c478bd9Sstevel@tonic-gate 			fmt_print("    <%s cyl %d alt %d hd %d sec %d>\n",
19667c478bd9Sstevel@tonic-gate 			    label.dkl_asciilabel, label.dkl_ncyl,
19677c478bd9Sstevel@tonic-gate 			    label.dkl_acyl, label.dkl_nhead,
19687c478bd9Sstevel@tonic-gate 			    label.dkl_nsect);
19697c478bd9Sstevel@tonic-gate 			if (check("Continue")) {
19707c478bd9Sstevel@tonic-gate 				exit_critical();
197165908c77Syu, larry liu - Sun Microsystems - Beijing China 				free(buf);
19727c478bd9Sstevel@tonic-gate 				return (-1);
19737c478bd9Sstevel@tonic-gate 			}
19747c478bd9Sstevel@tonic-gate 			cur_dtype = dtype;
19757c478bd9Sstevel@tonic-gate 		}
19767c478bd9Sstevel@tonic-gate 		/*
19777c478bd9Sstevel@tonic-gate 		 * Try to match the partition map with a known map.
19787c478bd9Sstevel@tonic-gate 		 */
19797c478bd9Sstevel@tonic-gate 		for (parts = dtype->dtype_plist; parts != NULL;
19807c478bd9Sstevel@tonic-gate 		    parts = parts->pinfo_next)
19817c478bd9Sstevel@tonic-gate 			if (parts_match(&label, parts))
19827c478bd9Sstevel@tonic-gate 				break;
19837c478bd9Sstevel@tonic-gate 		/*
19847c478bd9Sstevel@tonic-gate 		 * If we couldn't match it, allocate space for a new one,
19857c478bd9Sstevel@tonic-gate 		 * fill in the info, and add it to the list.  The name
19867c478bd9Sstevel@tonic-gate 		 * for the new map is derived from the disk name.
19877c478bd9Sstevel@tonic-gate 		 */
19887c478bd9Sstevel@tonic-gate 		if (parts == NULL) {
19897c478bd9Sstevel@tonic-gate 			parts = (struct partition_info *)
19907c478bd9Sstevel@tonic-gate 			    zalloc(sizeof (struct partition_info));
19917c478bd9Sstevel@tonic-gate 			plist = dtype->dtype_plist;
19927c478bd9Sstevel@tonic-gate 			if (plist == NULL)
19937c478bd9Sstevel@tonic-gate 				dtype->dtype_plist = parts;
19947c478bd9Sstevel@tonic-gate 			else {
19957c478bd9Sstevel@tonic-gate 				while (plist->pinfo_next != NULL)
19967c478bd9Sstevel@tonic-gate 					plist = plist->pinfo_next;
19977c478bd9Sstevel@tonic-gate 				plist->pinfo_next = parts;
19987c478bd9Sstevel@tonic-gate 			}
19997c478bd9Sstevel@tonic-gate 			parts->pinfo_name = alloc_string("original");
20007c478bd9Sstevel@tonic-gate 			for (i = 0; i < NDKMAP; i++)
20017c478bd9Sstevel@tonic-gate 
20027c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
20037c478bd9Sstevel@tonic-gate 				parts->pinfo_map[i] = label.dkl_map[i];
20047c478bd9Sstevel@tonic-gate 
20057c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
20067c478bd9Sstevel@tonic-gate 				parts->pinfo_map[i].dkl_cylno  =
20077c478bd9Sstevel@tonic-gate 				    label.dkl_vtoc.v_part[i].p_start / spc();
20087c478bd9Sstevel@tonic-gate 				parts->pinfo_map[i].dkl_nblk =
20097c478bd9Sstevel@tonic-gate 				    label.dkl_vtoc.v_part[i].p_size;
20107c478bd9Sstevel@tonic-gate #else
20117c478bd9Sstevel@tonic-gate #error No VTOC layout defined.
20127c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
20137c478bd9Sstevel@tonic-gate 			parts->vtoc = label.dkl_vtoc;
20147c478bd9Sstevel@tonic-gate 		}
20157c478bd9Sstevel@tonic-gate 		/*
20167c478bd9Sstevel@tonic-gate 		 * We now have a partition map.  Make it the current map.
20177c478bd9Sstevel@tonic-gate 		 */
20187c478bd9Sstevel@tonic-gate 		cur_disk->disk_parts = cur_parts = parts;
20197c478bd9Sstevel@tonic-gate 		exit_critical();
20207c478bd9Sstevel@tonic-gate 		/*
20217c478bd9Sstevel@tonic-gate 		 * Rewrite the labels and defect lists, as appropriate.
20227c478bd9Sstevel@tonic-gate 		 */
20237c478bd9Sstevel@tonic-gate 		if (EMBEDDED_SCSI) {
20247c478bd9Sstevel@tonic-gate 			fmt_print("Restoring primary label.\n");
202565908c77Syu, larry liu - Sun Microsystems - Beijing China 			if (write_label()) {
202665908c77Syu, larry liu - Sun Microsystems - Beijing China 				free(buf);
20277c478bd9Sstevel@tonic-gate 				return (-1);
202865908c77Syu, larry liu - Sun Microsystems - Beijing China 			}
20297c478bd9Sstevel@tonic-gate 		} else {
20307c478bd9Sstevel@tonic-gate 			fmt_print("Restoring primary label and defect list.\n");
203165908c77Syu, larry liu - Sun Microsystems - Beijing China 			if (write_label()) {
203265908c77Syu, larry liu - Sun Microsystems - Beijing China 				free(buf);
20337c478bd9Sstevel@tonic-gate 				return (-1);
203465908c77Syu, larry liu - Sun Microsystems - Beijing China 			}
20357c478bd9Sstevel@tonic-gate 			if (cur_list.list != NULL)
20367c478bd9Sstevel@tonic-gate 				write_deflist(&cur_list);
20377c478bd9Sstevel@tonic-gate 		}
20387c478bd9Sstevel@tonic-gate 		fmt_print("\n");
203965908c77Syu, larry liu - Sun Microsystems - Beijing China 		free(buf);
20407c478bd9Sstevel@tonic-gate 		return (0);
20417c478bd9Sstevel@tonic-gate 	}
20427c478bd9Sstevel@tonic-gate 	/*
20437c478bd9Sstevel@tonic-gate 	 * If we didn't find any backup labels, say so.
20447c478bd9Sstevel@tonic-gate 	 */
20457c478bd9Sstevel@tonic-gate 	fmt_print("not found.\n\n");
204665908c77Syu, larry liu - Sun Microsystems - Beijing China 	free(buf);
20477c478bd9Sstevel@tonic-gate 	return (0);
20487c478bd9Sstevel@tonic-gate }
20497c478bd9Sstevel@tonic-gate 
20507c478bd9Sstevel@tonic-gate /*
20517c478bd9Sstevel@tonic-gate  * This routine is called by c_verify() for an EFI labeled disk
20527c478bd9Sstevel@tonic-gate  */
20537c478bd9Sstevel@tonic-gate static int
c_verify_efi()20547c478bd9Sstevel@tonic-gate c_verify_efi()
20557c478bd9Sstevel@tonic-gate {
20567c478bd9Sstevel@tonic-gate 	struct efi_info efi_info;
20577c478bd9Sstevel@tonic-gate 	struct	partition_info	tmp_pinfo;
20587c478bd9Sstevel@tonic-gate 	int status;
20597c478bd9Sstevel@tonic-gate 
2060*9aa4340aSHans Rosenfeld 	status = read_efi_label(cur_file, &efi_info, cur_disk);
20617c478bd9Sstevel@tonic-gate 	if (status != 0) {
20627c478bd9Sstevel@tonic-gate 		err_print("Warning: Could not read label.\n");
20637c478bd9Sstevel@tonic-gate 		return (-1);
20647c478bd9Sstevel@tonic-gate 	}
20657c478bd9Sstevel@tonic-gate 	if (cur_parts->etoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) {
20667c478bd9Sstevel@tonic-gate 		err_print("Reading the primary EFI GPT label ");
20677c478bd9Sstevel@tonic-gate 		err_print("failed.  Using backup label.\n");
20687c478bd9Sstevel@tonic-gate 		err_print("Use the 'backup' command to restore ");
20697c478bd9Sstevel@tonic-gate 		err_print("the primary label.\n");
20707c478bd9Sstevel@tonic-gate 	}
20717c478bd9Sstevel@tonic-gate 	tmp_pinfo.etoc = efi_info.e_parts;
20727c478bd9Sstevel@tonic-gate 	fmt_print("\n");
20737c478bd9Sstevel@tonic-gate 	if (cur_parts->etoc->efi_parts[8].p_name) {
20747c478bd9Sstevel@tonic-gate 		fmt_print("Volume name = <%8s>\n",
20757c478bd9Sstevel@tonic-gate 		    cur_parts->etoc->efi_parts[8].p_name);
20767c478bd9Sstevel@tonic-gate 	} else {
20777c478bd9Sstevel@tonic-gate 		fmt_print("Volume name = <        >\n");
20787c478bd9Sstevel@tonic-gate 	}
20797c478bd9Sstevel@tonic-gate 	fmt_print("ascii name  = ");
20807c478bd9Sstevel@tonic-gate 	print_efi_string(efi_info.vendor, efi_info.product,
20817c478bd9Sstevel@tonic-gate 	    efi_info.revision, efi_info.capacity);
20827c478bd9Sstevel@tonic-gate 	fmt_print("\n");
20837c478bd9Sstevel@tonic-gate 
208465908c77Syu, larry liu - Sun Microsystems - Beijing China 	fmt_print("bytes/sector	=  %d\n", cur_blksz);
20857c478bd9Sstevel@tonic-gate 	fmt_print("sectors = %llu\n", cur_parts->etoc->efi_last_lba);
20867c478bd9Sstevel@tonic-gate 	fmt_print("accessible sectors = %llu\n",
20877c478bd9Sstevel@tonic-gate 	    cur_parts->etoc->efi_last_u_lba);
20887c478bd9Sstevel@tonic-gate 
20897c478bd9Sstevel@tonic-gate 	print_map(&tmp_pinfo);
2090*9aa4340aSHans Rosenfeld 
2091*9aa4340aSHans Rosenfeld 	free(efi_info.vendor);
2092*9aa4340aSHans Rosenfeld 	free(efi_info.product);
2093*9aa4340aSHans Rosenfeld 	free(efi_info.revision);
20947c478bd9Sstevel@tonic-gate 	return (0);
20957c478bd9Sstevel@tonic-gate }
20967c478bd9Sstevel@tonic-gate 
20977c478bd9Sstevel@tonic-gate /*
20987c478bd9Sstevel@tonic-gate  * This routine implements the 'verify' command.  It allows the user
20997c478bd9Sstevel@tonic-gate  * to read the labels on the current disk.
21007c478bd9Sstevel@tonic-gate  */
21017c478bd9Sstevel@tonic-gate int
c_verify()21027c478bd9Sstevel@tonic-gate c_verify()
21037c478bd9Sstevel@tonic-gate {
21047c478bd9Sstevel@tonic-gate 	struct	dk_label p_label, b_label, *label;
21057c478bd9Sstevel@tonic-gate 	struct	partition_info tmp_pinfo;
2106342440ecSPrasad Singamsetty 	diskaddr_t	bn;
21077c478bd9Sstevel@tonic-gate 	int	sec, head, i, status;
21087c478bd9Sstevel@tonic-gate 	int	p_label_bad = 0;
21097c478bd9Sstevel@tonic-gate 	int	b_label_bad = 0;
21107c478bd9Sstevel@tonic-gate 	int	p_label_found = 0;
21117c478bd9Sstevel@tonic-gate 	int	b_label_found = 0;
21127c478bd9Sstevel@tonic-gate 	char	id_str[128];
211365908c77Syu, larry liu - Sun Microsystems - Beijing China 	char	*buf;
21147c478bd9Sstevel@tonic-gate 
21157c478bd9Sstevel@tonic-gate 	/*
21167c478bd9Sstevel@tonic-gate 	 * There must be a current disk type (and therefore a current disk).
21177c478bd9Sstevel@tonic-gate 	 */
21187c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
21197c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
21207c478bd9Sstevel@tonic-gate 		return (-1);
21217c478bd9Sstevel@tonic-gate 	}
21227c478bd9Sstevel@tonic-gate 	/*
21237c478bd9Sstevel@tonic-gate 	 * The disk must be formatted to read labels.
21247c478bd9Sstevel@tonic-gate 	 */
21257c478bd9Sstevel@tonic-gate 	if (!(cur_flags & DISK_FORMATTED)) {
21267c478bd9Sstevel@tonic-gate 		err_print("Current Disk is unformatted.\n");
21277c478bd9Sstevel@tonic-gate 		return (-1);
21287c478bd9Sstevel@tonic-gate 	}
21297c478bd9Sstevel@tonic-gate 	/*
21307c478bd9Sstevel@tonic-gate 	 * Check for a valid fdisk table entry for Solaris
21317c478bd9Sstevel@tonic-gate 	 */
21327c478bd9Sstevel@tonic-gate 	if (!good_fdisk()) {
21337c478bd9Sstevel@tonic-gate 		return (-1);
21347c478bd9Sstevel@tonic-gate 	}
21357c478bd9Sstevel@tonic-gate 	/*
21367c478bd9Sstevel@tonic-gate 	 * Branch off here if the disk is EFI labelled.
21377c478bd9Sstevel@tonic-gate 	 */
21387c478bd9Sstevel@tonic-gate 	if (cur_label == L_TYPE_EFI) {
21397c478bd9Sstevel@tonic-gate 		return (c_verify_efi());
21407c478bd9Sstevel@tonic-gate 	}
21417c478bd9Sstevel@tonic-gate 	/*
21427c478bd9Sstevel@tonic-gate 	 * Attempt to read the primary label.
21437c478bd9Sstevel@tonic-gate 	 */
21447c478bd9Sstevel@tonic-gate 	status = read_label(cur_file, &p_label);
21457c478bd9Sstevel@tonic-gate 	if (status == -1) {
21467c478bd9Sstevel@tonic-gate 		err_print("Warning: Could not read primary label.\n");
21477c478bd9Sstevel@tonic-gate 		p_label_bad = 1;
21487c478bd9Sstevel@tonic-gate 	} else {
21497c478bd9Sstevel@tonic-gate 		/*
21507c478bd9Sstevel@tonic-gate 		 * Verify that it is a reasonable label.
21517c478bd9Sstevel@tonic-gate 		 */
21527c478bd9Sstevel@tonic-gate 		/*
21537c478bd9Sstevel@tonic-gate 		 * Save complete ascii string for printing later.
21547c478bd9Sstevel@tonic-gate 		 */
21557c478bd9Sstevel@tonic-gate 		(void) strncpy(id_str, p_label.dkl_asciilabel, 128);
21567c478bd9Sstevel@tonic-gate 
21577c478bd9Sstevel@tonic-gate 		if ((!checklabel((struct dk_label *)&p_label)) ||
21587c478bd9Sstevel@tonic-gate 		    (trim_id(p_label.dkl_asciilabel))) {
21597c478bd9Sstevel@tonic-gate 			err_print("\
21607c478bd9Sstevel@tonic-gate Warning: Primary label appears to be corrupt.\n");
21617c478bd9Sstevel@tonic-gate 			p_label_bad = 1;
21627c478bd9Sstevel@tonic-gate 		} else {
21637c478bd9Sstevel@tonic-gate 			p_label_found = 1;
21647c478bd9Sstevel@tonic-gate 			/*
21657c478bd9Sstevel@tonic-gate 			 * Make sure it matches current label
21667c478bd9Sstevel@tonic-gate 			 */
21677c478bd9Sstevel@tonic-gate 			if ((!dtype_match(&p_label, cur_dtype)) ||
21687c478bd9Sstevel@tonic-gate 			    (!parts_match(&p_label, cur_parts))) {
21697c478bd9Sstevel@tonic-gate 				err_print("\
21707c478bd9Sstevel@tonic-gate Warning: Primary label on disk appears to be different from\ncurrent label.\n");
21717c478bd9Sstevel@tonic-gate 				p_label_bad = 1;
21727c478bd9Sstevel@tonic-gate 			}
21737c478bd9Sstevel@tonic-gate 		}
21747c478bd9Sstevel@tonic-gate 	}
21757c478bd9Sstevel@tonic-gate 
21767c478bd9Sstevel@tonic-gate 	/*
21777c478bd9Sstevel@tonic-gate 	 * Read backup labels.
21787c478bd9Sstevel@tonic-gate 	 * Some disks have the backup labels in a strange place.
21797c478bd9Sstevel@tonic-gate 	 */
21807c478bd9Sstevel@tonic-gate 	if (cur_ctype->ctype_flags & CF_BLABEL)
21817c478bd9Sstevel@tonic-gate 		head = 2;
21827c478bd9Sstevel@tonic-gate 	else
21837c478bd9Sstevel@tonic-gate 		head = nhead - 1;
218465908c77Syu, larry liu - Sun Microsystems - Beijing China 
218565908c77Syu, larry liu - Sun Microsystems - Beijing China 	buf = zalloc(cur_blksz);
21867c478bd9Sstevel@tonic-gate 	/*
21877c478bd9Sstevel@tonic-gate 	 * Loop through each copy of the backup label.
21887c478bd9Sstevel@tonic-gate 	 */
21897c478bd9Sstevel@tonic-gate 	for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect));
21907c478bd9Sstevel@tonic-gate 	    sec += 2) {
21917c478bd9Sstevel@tonic-gate 		bn = chs2bn(ncyl + acyl - 1, head, sec) + solaris_offset;
21927c478bd9Sstevel@tonic-gate 		/*
21937c478bd9Sstevel@tonic-gate 		 * Attempt to read it.
21947c478bd9Sstevel@tonic-gate 		 */
2195342440ecSPrasad Singamsetty 		if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, bn,
219665908c77Syu, larry liu - Sun Microsystems - Beijing China 		    1, buf, F_NORMAL, NULL))
21977c478bd9Sstevel@tonic-gate 			continue;
219865908c77Syu, larry liu - Sun Microsystems - Beijing China 
219965908c77Syu, larry liu - Sun Microsystems - Beijing China 		(void *) memcpy((char *)&b_label, buf,
220065908c77Syu, larry liu - Sun Microsystems - Beijing China 		    sizeof (struct dk_label));
220165908c77Syu, larry liu - Sun Microsystems - Beijing China 
22027c478bd9Sstevel@tonic-gate 		/*
22037c478bd9Sstevel@tonic-gate 		 * Verify that it is a reasonable label.
22047c478bd9Sstevel@tonic-gate 		 */
22057c478bd9Sstevel@tonic-gate 		if (!checklabel(&b_label))
22067c478bd9Sstevel@tonic-gate 			continue;
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 		/*
22097c478bd9Sstevel@tonic-gate 		 * Save complete label only if no primary label exists
22107c478bd9Sstevel@tonic-gate 		 */
22117c478bd9Sstevel@tonic-gate 		if (!p_label_found)
22127c478bd9Sstevel@tonic-gate 			(void) strncpy(id_str, b_label.dkl_asciilabel, 128);
22137c478bd9Sstevel@tonic-gate 
22147c478bd9Sstevel@tonic-gate 		if (trim_id(b_label.dkl_asciilabel))
22157c478bd9Sstevel@tonic-gate 			continue;
22167c478bd9Sstevel@tonic-gate 		b_label_found = 1;
22177c478bd9Sstevel@tonic-gate 		/*
22187c478bd9Sstevel@tonic-gate 		 * Compare against primary label
22197c478bd9Sstevel@tonic-gate 		 */
22207c478bd9Sstevel@tonic-gate 		if (p_label_found) {
22217c478bd9Sstevel@tonic-gate 			if ((strcmp(b_label.dkl_asciilabel,
22227c478bd9Sstevel@tonic-gate 			    p_label.dkl_asciilabel) != 0) ||
22237c478bd9Sstevel@tonic-gate 			    (b_label.dkl_ncyl != p_label.dkl_ncyl) ||
22247c478bd9Sstevel@tonic-gate 			    (b_label.dkl_acyl != p_label.dkl_acyl) ||
22257c478bd9Sstevel@tonic-gate 			    (b_label.dkl_nhead != p_label.dkl_nhead) ||
22267c478bd9Sstevel@tonic-gate 			    (b_label.dkl_nsect != p_label.dkl_nsect)) {
22277c478bd9Sstevel@tonic-gate 				b_label_bad = 1;
22287c478bd9Sstevel@tonic-gate 			} else {
22297c478bd9Sstevel@tonic-gate 				for (i = 0; i < NDKMAP; i++) {
22307c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
22317c478bd9Sstevel@tonic-gate 					if ((b_label.dkl_map[i].dkl_cylno !=
22327c478bd9Sstevel@tonic-gate 					    p_label.dkl_map[i].dkl_cylno) ||
22337c478bd9Sstevel@tonic-gate 					    (b_label.dkl_map[i].dkl_nblk !=
22347c478bd9Sstevel@tonic-gate 					    p_label.dkl_map[i].dkl_nblk)) {
22357c478bd9Sstevel@tonic-gate 						b_label_bad = 1;
22367c478bd9Sstevel@tonic-gate 						break;
22377c478bd9Sstevel@tonic-gate 					}
22387c478bd9Sstevel@tonic-gate 
22397c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
22407c478bd9Sstevel@tonic-gate 					if ((b_label.dkl_vtoc.v_part[i].p_tag !=
22417c478bd9Sstevel@tonic-gate 					    p_label.dkl_vtoc.v_part[i].p_tag) ||
224265908c77Syu, larry liu - Sun Microsystems - Beijing China 					    (b_label.dkl_vtoc.v_part[i].p_flag
224365908c77Syu, larry liu - Sun Microsystems - Beijing China 					    != p_label.dkl_vtoc.v_part[i].
224465908c77Syu, larry liu - Sun Microsystems - Beijing China 					    p_flag) ||
224565908c77Syu, larry liu - Sun Microsystems - Beijing China 					    (b_label.dkl_vtoc.v_part[i].p_start
224665908c77Syu, larry liu - Sun Microsystems - Beijing China 					    != p_label.dkl_vtoc.v_part[i].
224765908c77Syu, larry liu - Sun Microsystems - Beijing China 					    p_start) ||
224865908c77Syu, larry liu - Sun Microsystems - Beijing China 					    (b_label.dkl_vtoc.v_part[i].p_size
224965908c77Syu, larry liu - Sun Microsystems - Beijing China 					    != p_label.dkl_vtoc.v_part[i].
225065908c77Syu, larry liu - Sun Microsystems - Beijing China 					    p_size)) {
22517c478bd9Sstevel@tonic-gate 						b_label_bad = 1;
22527c478bd9Sstevel@tonic-gate 						break;
22537c478bd9Sstevel@tonic-gate 					}
22547c478bd9Sstevel@tonic-gate #else
22557c478bd9Sstevel@tonic-gate #error No VTOC layout defined.
22567c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
22577c478bd9Sstevel@tonic-gate 				}
22587c478bd9Sstevel@tonic-gate 			}
22597c478bd9Sstevel@tonic-gate 		}
22607c478bd9Sstevel@tonic-gate 		if (b_label_bad)
22617c478bd9Sstevel@tonic-gate 			err_print(
22627c478bd9Sstevel@tonic-gate "Warning: Primary and backup labels do not match.\n");
22637c478bd9Sstevel@tonic-gate 		break;
22647c478bd9Sstevel@tonic-gate 	}
22657c478bd9Sstevel@tonic-gate 	/*
22667c478bd9Sstevel@tonic-gate 	 * If we didn't find any backup labels, say so.
22677c478bd9Sstevel@tonic-gate 	 */
22687c478bd9Sstevel@tonic-gate 	if (!b_label_found)
22697c478bd9Sstevel@tonic-gate 		err_print("Warning: Could not read backup labels.\n");
22707c478bd9Sstevel@tonic-gate 
22717c478bd9Sstevel@tonic-gate 	if ((!b_label_found) || (p_label_bad) || (b_label_bad))
22727c478bd9Sstevel@tonic-gate 		err_print("\n\
22737c478bd9Sstevel@tonic-gate Warning: Check the current partitioning and 'label' the disk or use the\n\
22747c478bd9Sstevel@tonic-gate \t 'backup' command.\n");
22757c478bd9Sstevel@tonic-gate 
22767c478bd9Sstevel@tonic-gate 	/*
22777c478bd9Sstevel@tonic-gate 	 * Print label information.
22787c478bd9Sstevel@tonic-gate 	 */
22797c478bd9Sstevel@tonic-gate 	if (p_label_found) {
22807c478bd9Sstevel@tonic-gate 		fmt_print("\nPrimary label contents:\n");
22817c478bd9Sstevel@tonic-gate 		label = &p_label;
22827c478bd9Sstevel@tonic-gate 	} else if (b_label_found) {
22837c478bd9Sstevel@tonic-gate 		fmt_print("\nBackup label contents:\n");
22847c478bd9Sstevel@tonic-gate 		label = &b_label;
22857c478bd9Sstevel@tonic-gate 	} else {
228665908c77Syu, larry liu - Sun Microsystems - Beijing China 		free(buf);
22877c478bd9Sstevel@tonic-gate 		return (0);
22887c478bd9Sstevel@tonic-gate 	}
22897c478bd9Sstevel@tonic-gate 
22907c478bd9Sstevel@tonic-gate 	/*
22917c478bd9Sstevel@tonic-gate 	 * Must put info into partition_info struct for
22927c478bd9Sstevel@tonic-gate 	 * for print routine.
22937c478bd9Sstevel@tonic-gate 	 */
22947c478bd9Sstevel@tonic-gate 	bzero(&tmp_pinfo, sizeof (struct partition_info));
22957c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
22967c478bd9Sstevel@tonic-gate 
22977c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
22987c478bd9Sstevel@tonic-gate 		tmp_pinfo.pinfo_map[i] = label->dkl_map[i];
22997c478bd9Sstevel@tonic-gate 
23007c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
23017c478bd9Sstevel@tonic-gate 		tmp_pinfo.pinfo_map[i].dkl_cylno =
23027c478bd9Sstevel@tonic-gate 		    label->dkl_vtoc.v_part[i].p_start / spc();
23037c478bd9Sstevel@tonic-gate 		tmp_pinfo.pinfo_map[i].dkl_nblk =
23047c478bd9Sstevel@tonic-gate 		    label->dkl_vtoc.v_part[i].p_size;
23057c478bd9Sstevel@tonic-gate #else
23067c478bd9Sstevel@tonic-gate #error No VTOC layout defined.
23077c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
23087c478bd9Sstevel@tonic-gate 	}
23097c478bd9Sstevel@tonic-gate 	tmp_pinfo.vtoc = label->dkl_vtoc;
23107c478bd9Sstevel@tonic-gate 
23117c478bd9Sstevel@tonic-gate 	fmt_print("\n");
23127c478bd9Sstevel@tonic-gate 	fmt_print("Volume name = <%8s>\n", label->dkl_vtoc.v_volume);
23137c478bd9Sstevel@tonic-gate 	fmt_print("ascii name  = <%s>\n", id_str);
23147c478bd9Sstevel@tonic-gate 	fmt_print("pcyl        = %4d\n", label->dkl_pcyl);
23157c478bd9Sstevel@tonic-gate 	fmt_print("ncyl        = %4d\n", label->dkl_ncyl);
23167c478bd9Sstevel@tonic-gate 	fmt_print("acyl        = %4d\n", label->dkl_acyl);
23177c478bd9Sstevel@tonic-gate 
23187c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
23197c478bd9Sstevel@tonic-gate 	fmt_print("bcyl        = %4d\n", label->dkl_bcyl);
23207c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */
23217c478bd9Sstevel@tonic-gate 
23227c478bd9Sstevel@tonic-gate 	fmt_print("nhead       = %4d\n", label->dkl_nhead);
23237c478bd9Sstevel@tonic-gate 	fmt_print("nsect       = %4d\n", label->dkl_nsect);
23247c478bd9Sstevel@tonic-gate 
23257c478bd9Sstevel@tonic-gate 	print_map(&tmp_pinfo);
232665908c77Syu, larry liu - Sun Microsystems - Beijing China 	free(buf);
23277c478bd9Sstevel@tonic-gate 	return (0);
23287c478bd9Sstevel@tonic-gate }
23297c478bd9Sstevel@tonic-gate 
23307c478bd9Sstevel@tonic-gate 
23317c478bd9Sstevel@tonic-gate /*
23327c478bd9Sstevel@tonic-gate  * This command implements the inquiry command, for embedded SCSI
23337c478bd9Sstevel@tonic-gate  * disks only, which issues a SCSI inquiry command, and
23347c478bd9Sstevel@tonic-gate  * displays the resulting vendor, product id and revision level.
23357c478bd9Sstevel@tonic-gate  */
23367c478bd9Sstevel@tonic-gate int
c_inquiry()23377c478bd9Sstevel@tonic-gate c_inquiry()
23387c478bd9Sstevel@tonic-gate {
23397c478bd9Sstevel@tonic-gate 	char			inqbuf[255];
23407c478bd9Sstevel@tonic-gate 	struct scsi_inquiry	*inq;
23417c478bd9Sstevel@tonic-gate 
23427c478bd9Sstevel@tonic-gate 	assert(SCSI);
23437c478bd9Sstevel@tonic-gate 
23447c478bd9Sstevel@tonic-gate 	inq = (struct scsi_inquiry *)inqbuf;
23457c478bd9Sstevel@tonic-gate 
23467c478bd9Sstevel@tonic-gate 	if (uscsi_inquiry(cur_file, inqbuf, sizeof (inqbuf))) {
23477c478bd9Sstevel@tonic-gate 		err_print("Failed\n");
23487c478bd9Sstevel@tonic-gate 		return (-1);
23497c478bd9Sstevel@tonic-gate 	} else {
23507c478bd9Sstevel@tonic-gate 		fmt_print("Vendor:   ");
23517c478bd9Sstevel@tonic-gate 		print_buf(inq->inq_vid, sizeof (inq->inq_vid));
23527c478bd9Sstevel@tonic-gate 		fmt_print("\nProduct:  ");
23537c478bd9Sstevel@tonic-gate 		print_buf(inq->inq_pid, sizeof (inq->inq_pid));
23547c478bd9Sstevel@tonic-gate 		fmt_print("\nRevision: ");
23557c478bd9Sstevel@tonic-gate 		print_buf(inq->inq_revision, sizeof (inq->inq_revision));
23567c478bd9Sstevel@tonic-gate 		fmt_print("\n");
23577c478bd9Sstevel@tonic-gate 	}
23587c478bd9Sstevel@tonic-gate 
23597c478bd9Sstevel@tonic-gate 	return (0);
23607c478bd9Sstevel@tonic-gate }
23617c478bd9Sstevel@tonic-gate 
23627c478bd9Sstevel@tonic-gate 
23637c478bd9Sstevel@tonic-gate /*
23647c478bd9Sstevel@tonic-gate  * This routine allows the user to set the 8-character
23657c478bd9Sstevel@tonic-gate  * volume name in the vtoc.  It then writes both the
23667c478bd9Sstevel@tonic-gate  * primary and backup labels onto the current disk.
23677c478bd9Sstevel@tonic-gate  */
23687c478bd9Sstevel@tonic-gate int
c_volname()23697c478bd9Sstevel@tonic-gate c_volname()
23707c478bd9Sstevel@tonic-gate {
23717c478bd9Sstevel@tonic-gate 	int	 status;
23727c478bd9Sstevel@tonic-gate 	char	*prompt;
23737c478bd9Sstevel@tonic-gate 	union {
23747c478bd9Sstevel@tonic-gate 		int	xfoo;
23757c478bd9Sstevel@tonic-gate 		char	defvolname[LEN_DKL_VVOL+1];
23767c478bd9Sstevel@tonic-gate 	} x;
23777c478bd9Sstevel@tonic-gate 	char    s1[MAXPATHLEN], nclean[MAXPATHLEN];
23787c478bd9Sstevel@tonic-gate 	char	*volname;
23797c478bd9Sstevel@tonic-gate 
23807c478bd9Sstevel@tonic-gate 
23817c478bd9Sstevel@tonic-gate 	/*
23827c478bd9Sstevel@tonic-gate 	 * There must be a current disk type (and therefore a current disk).
23837c478bd9Sstevel@tonic-gate 	 */
23847c478bd9Sstevel@tonic-gate 	if (cur_dtype == NULL) {
23857c478bd9Sstevel@tonic-gate 		err_print("Current Disk Type is not set.\n");
23867c478bd9Sstevel@tonic-gate 		return (-1);
23877c478bd9Sstevel@tonic-gate 	}
23887c478bd9Sstevel@tonic-gate 	/*
23897c478bd9Sstevel@tonic-gate 	 * The current disk must be formatted to label it.
23907c478bd9Sstevel@tonic-gate 	 */
23917c478bd9Sstevel@tonic-gate 	if (!(cur_flags & DISK_FORMATTED)) {
23927c478bd9Sstevel@tonic-gate 		err_print("Current Disk is unformatted.\n");
23937c478bd9Sstevel@tonic-gate 		return (-1);
23947c478bd9Sstevel@tonic-gate 	}
23957c478bd9Sstevel@tonic-gate 	/*
23967c478bd9Sstevel@tonic-gate 	 * Check for a valid fdisk table entry for Solaris
23977c478bd9Sstevel@tonic-gate 	 */
23987c478bd9Sstevel@tonic-gate 	if (!good_fdisk()) {
23997c478bd9Sstevel@tonic-gate 		return (-1);
24007c478bd9Sstevel@tonic-gate 	}
24017c478bd9Sstevel@tonic-gate 	/*
24027c478bd9Sstevel@tonic-gate 	 * The current disk must be formatted to label it.
24037c478bd9Sstevel@tonic-gate 	 */
24047c478bd9Sstevel@tonic-gate 	if (cur_parts == NULL) {
24057c478bd9Sstevel@tonic-gate 	err_print(
24067c478bd9Sstevel@tonic-gate "Please select a partition map for the disk first.\n");
24077c478bd9Sstevel@tonic-gate 	return (-1);
24087c478bd9Sstevel@tonic-gate 	}
2409c92a0838Smishra 
24107c478bd9Sstevel@tonic-gate 	/*
24117c478bd9Sstevel@tonic-gate 	 * Check to see if there are any mounted file systems anywhere
24127c478bd9Sstevel@tonic-gate 	 * on the current disk.  If so, refuse to label the disk, but
24137c478bd9Sstevel@tonic-gate 	 * only if the partitions would change for the mounted partitions.
24147c478bd9Sstevel@tonic-gate 	 *
24157c478bd9Sstevel@tonic-gate 	 */
2416342440ecSPrasad Singamsetty 	if (checkmount((diskaddr_t)-1, (diskaddr_t)-1)) {
24177c478bd9Sstevel@tonic-gate 		/* Bleagh, too descriptive */
24187c478bd9Sstevel@tonic-gate 		if (check_label_with_mount()) {
24197c478bd9Sstevel@tonic-gate 			err_print(
24207c478bd9Sstevel@tonic-gate "Cannot label disk while it has mounted partitions.\n\n");
24217c478bd9Sstevel@tonic-gate 			return (-1);
24227c478bd9Sstevel@tonic-gate 		}
24237c478bd9Sstevel@tonic-gate 	}
2424c92a0838Smishra 
24257c478bd9Sstevel@tonic-gate 	/*
24267c478bd9Sstevel@tonic-gate 	 * Check to see if there are partitions being used for swapping
24277c478bd9Sstevel@tonic-gate 	 * on the current disk.  If so, refuse to label the disk, but
24287c478bd9Sstevel@tonic-gate 	 * only if the partitions would change for the swap partitions.
24297c478bd9Sstevel@tonic-gate 	 *
24307c478bd9Sstevel@tonic-gate 	 */
2431342440ecSPrasad Singamsetty 	if (checkswap((diskaddr_t)-1, (diskaddr_t)-1)) {
24327c478bd9Sstevel@tonic-gate 		/* Bleagh, too descriptive */
24337c478bd9Sstevel@tonic-gate 		if (check_label_with_swap()) {
24347c478bd9Sstevel@tonic-gate 			err_print(
24357c478bd9Sstevel@tonic-gate "Cannot label disk while its partitions are currently \
24367c478bd9Sstevel@tonic-gate being used for swapping.\n\n");
24377c478bd9Sstevel@tonic-gate 			return (-1);
24387c478bd9Sstevel@tonic-gate 		}
24397c478bd9Sstevel@tonic-gate 	}
2440c92a0838Smishra 
2441c92a0838Smishra 	/*
2442c92a0838Smishra 	 * Check to see if any partitions used for svm, vxvm, ZFS zpool
2443c92a0838Smishra 	 * or live upgrade are on the disk. If so, refuse to label the
2444c92a0838Smishra 	 * disk, but only if we are trying to shrink a partition in
2445c92a0838Smishra 	 * use.
2446c92a0838Smishra 	 */
2447c92a0838Smishra 	if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
2448c92a0838Smishra 	    (diskaddr_t)-1, 0, 1)) {
2449c92a0838Smishra 		err_print("Cannot label disk while its partitions "
2450c92a0838Smishra 		    "are in use as described.\n");
2451c92a0838Smishra 		return (-1);
2452c92a0838Smishra 	}
2453c92a0838Smishra 
24547c478bd9Sstevel@tonic-gate 	/*
24557c478bd9Sstevel@tonic-gate 	 * Prompt for the disk volume name.
24567c478bd9Sstevel@tonic-gate 	 */
24577c478bd9Sstevel@tonic-gate 	prompt = "Enter 8-character volume name (remember quotes)";
24587c478bd9Sstevel@tonic-gate 	bzero(x.defvolname, LEN_DKL_VVOL+1);
24597c478bd9Sstevel@tonic-gate 	bcopy(cur_disk->v_volume, x.defvolname, LEN_DKL_VVOL);
24607c478bd9Sstevel@tonic-gate 	/*
24617c478bd9Sstevel@tonic-gate 	 *  Get the input using "get_inputline" since
24627c478bd9Sstevel@tonic-gate 	 *  input would never return null string.
24637c478bd9Sstevel@tonic-gate 	 */
24647c478bd9Sstevel@tonic-gate 	fmt_print("%s[\"%s\"]:", prompt, x.defvolname);
24657c478bd9Sstevel@tonic-gate 
24667c478bd9Sstevel@tonic-gate 	/*
24677c478bd9Sstevel@tonic-gate 	 * Get input from the user.
24687c478bd9Sstevel@tonic-gate 	 */
24697c478bd9Sstevel@tonic-gate 	get_inputline(nclean, MAXPATHLEN);
24707c478bd9Sstevel@tonic-gate 	clean_token(s1, nclean);
24717c478bd9Sstevel@tonic-gate 	/*
24727c478bd9Sstevel@tonic-gate 	 * check for return.
24737c478bd9Sstevel@tonic-gate 	 */
24747c478bd9Sstevel@tonic-gate 	if (s1[0] == 0) {
24757c478bd9Sstevel@tonic-gate 		volname = x.defvolname;
24767c478bd9Sstevel@tonic-gate 	} else {
24777c478bd9Sstevel@tonic-gate 		/*
24787c478bd9Sstevel@tonic-gate 		 * remove the " mark from volname.
24797c478bd9Sstevel@tonic-gate 		 */
24807c478bd9Sstevel@tonic-gate 		if (s1[0] == '"') {
24817c478bd9Sstevel@tonic-gate 			int i = 1;
24827c478bd9Sstevel@tonic-gate 			volname = &s1[1];
24837c478bd9Sstevel@tonic-gate 			while (s1[i] != '"' && s1[i] != '\0')
24847c478bd9Sstevel@tonic-gate 				i++;
24857c478bd9Sstevel@tonic-gate 			s1[i] = '\0';
24867c478bd9Sstevel@tonic-gate 			clean_token(nclean, volname);
24877c478bd9Sstevel@tonic-gate 			volname = nclean;
24887c478bd9Sstevel@tonic-gate 		} else {
24897c478bd9Sstevel@tonic-gate 			(void) sscanf(&s1[0], "%1024s", nclean);
24907c478bd9Sstevel@tonic-gate 			volname = nclean;
24917c478bd9Sstevel@tonic-gate 		};
24927c478bd9Sstevel@tonic-gate 	}
24937c478bd9Sstevel@tonic-gate 	/*
24947c478bd9Sstevel@tonic-gate 	 * Make sure the user is serious.
24957c478bd9Sstevel@tonic-gate 	 */
24967c478bd9Sstevel@tonic-gate 	if (check("Ready to label disk, continue")) {
24977c478bd9Sstevel@tonic-gate 		fmt_print("\n");
24987c478bd9Sstevel@tonic-gate 		return (-1);
24997c478bd9Sstevel@tonic-gate 	}
25007c478bd9Sstevel@tonic-gate 	/*
25017c478bd9Sstevel@tonic-gate 	 * Use the volume name chosen above
25027c478bd9Sstevel@tonic-gate 	 */
25037c478bd9Sstevel@tonic-gate 	bzero(cur_disk->v_volume, LEN_DKL_VVOL);
25047c478bd9Sstevel@tonic-gate 	bcopy(volname, cur_disk->v_volume, min((int)strlen(volname),
25057c478bd9Sstevel@tonic-gate 	    LEN_DKL_VVOL));
25067c478bd9Sstevel@tonic-gate 	if (cur_label == L_TYPE_EFI) {
25077c478bd9Sstevel@tonic-gate 		bzero(cur_parts->etoc->efi_parts[8].p_name, LEN_DKL_VVOL);
25087c478bd9Sstevel@tonic-gate 		bcopy(volname, cur_parts->etoc->efi_parts[8].p_name,
25097c478bd9Sstevel@tonic-gate 		    LEN_DKL_VVOL);
25107c478bd9Sstevel@tonic-gate 	}
25117c478bd9Sstevel@tonic-gate 	/*
25127c478bd9Sstevel@tonic-gate 	 * Write the labels out (this will also notify unix) and
25137c478bd9Sstevel@tonic-gate 	 * return status.
25147c478bd9Sstevel@tonic-gate 	 */
25157c478bd9Sstevel@tonic-gate 	fmt_print("\n");
25167c478bd9Sstevel@tonic-gate 	if (status = write_label())
25177c478bd9Sstevel@tonic-gate 		err_print("Label failed.\n");
25187c478bd9Sstevel@tonic-gate 	return (status);
25197c478bd9Sstevel@tonic-gate }
2520