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