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
c_disk()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
c_type()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
c_partition()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
c_current()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
c_format()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
c_repair()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
c_show()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
c_label()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
c_analyze()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
c_defect()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
c_backup()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
c_verify_efi()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
c_verify()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
c_inquiry()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
c_volname()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