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