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