1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2012 Milan Jurik. All rights reserved. 24 * Copyright 2014 Toomas Soome <tsoome@me.com> 25 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 26 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com> 27 * Copyright (c) 2016 by Delphix. All rights reserved. 28 */ 29 30 /* 31 * This file contains functions that implement the command menu commands. 32 */ 33 34 #include "global.h" 35 #include <time.h> 36 #include <sys/time.h> 37 #include <sys/resource.h> 38 #include <sys/wait.h> 39 #include <strings.h> 40 #include <signal.h> 41 #include <stdlib.h> 42 #include <string.h> 43 44 #if defined(sparc) 45 #include <sys/hdio.h> 46 #endif /* defined(sparc) */ 47 48 #include "main.h" 49 #include "analyze.h" 50 #include "menu.h" 51 #include "menu_command.h" 52 #include "menu_defect.h" 53 #include "menu_partition.h" 54 #include "param.h" 55 #include "misc.h" 56 #include "label.h" 57 #include "startup.h" 58 #include "partition.h" 59 #include "prompts.h" 60 #include "checkdev.h" 61 #include "io.h" 62 #include "ctlr_scsi.h" 63 #include "auto_sense.h" 64 #include "modify_partition.h" 65 66 67 extern struct menu_item menu_partition[]; 68 extern struct menu_item menu_analyze[]; 69 extern struct menu_item menu_defect[]; 70 int prot_type; 71 72 /* 73 * Choices for the p_tag vtoc field 74 */ 75 slist_t ptag_choices[] = { 76 { "unassigned", "", V_UNASSIGNED }, 77 { "boot", "", V_BOOT }, 78 { "root", "", V_ROOT }, 79 { "swap", "", V_SWAP }, 80 { "usr", "", V_USR }, 81 { "backup", "", V_BACKUP }, 82 { "stand", "", V_STAND }, 83 { "var", "", V_VAR }, 84 { "home", "", V_HOME }, 85 { "alternates", "", V_ALTSCTR }, 86 { "reserved", "", V_RESERVED }, 87 { "system", "", V_SYSTEM }, 88 { "BIOS_boot", "", V_BIOS_BOOT }, 89 { "FreeBSD boot", "", V_FREEBSD_BOOT }, 90 { "FreeBSD swap", "", V_FREEBSD_SWAP }, 91 { "FreeBSD UFS", "", V_FREEBSD_UFS }, 92 { "FreeBSD ZFS", "", V_FREEBSD_ZFS }, 93 94 { NULL } 95 }; 96 97 98 /* 99 * Choices for the p_flag vtoc field 100 */ 101 slist_t pflag_choices[] = { 102 { "wm", "read-write, mountable", 0 }, 103 { "wu", "read-write, unmountable", V_UNMNT }, 104 { "rm", "read-only, mountable", V_RONLY }, 105 { "ru", "read-only, unmountable", V_RONLY|V_UNMNT }, 106 { NULL } 107 }; 108 109 110 /* 111 * This routine implements the 'disk' command. It allows the user to 112 * select a disk to be current. The list of choices is the list of 113 * disks that were found at startup time. 114 */ 115 int 116 c_disk(void) 117 { 118 struct disk_info *disk; 119 u_ioparam_t ioparam; 120 int i; 121 int ndisks = 0; 122 int blind_select = 0; 123 int deflt; 124 int index; 125 int *defltptr = NULL; 126 int more = 0; 127 int more_quit = 0; 128 int one_line = 0; 129 int tty_lines; 130 131 /* 132 * This buffer holds the check() prompt that verifies we've got the right 133 * disk when performing a blind selection. The size should be sufficient 134 * to hold the prompt string, plus 256 characters for the disk name - 135 * way more than should ever be necessary. See the #define in misc.h. 136 */ 137 char chk_buf[BLIND_SELECT_VER_PROMPT]; 138 139 if (istokenpresent()) { 140 /* 141 * disk number to be selected is already in the 142 * input stream . 143 */ 144 TOKEN token, cleantoken; 145 146 /* 147 * Get the disk number the user has given. 148 */ 149 i = 0; 150 for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 151 i++; 152 } 153 154 ioparam.io_bounds.lower = 0; 155 ioparam.io_bounds.upper = i - 1; 156 (void) gettoken(token); 157 clean_token(cleantoken, token); 158 159 /* 160 * Convert the token into an integer. 161 */ 162 if (geti(cleantoken, &index, NULL)) 163 return (0); 164 165 /* 166 * Check to be sure it is within the legal bounds. 167 */ 168 if ((index < 0) || (index >= i)) { 169 err_print("`%d' is out of range.\n", index); 170 return (0); 171 } 172 goto checkdisk; 173 } 174 175 fmt_print("\n\nAVAILABLE DISK SELECTIONS:\n"); 176 177 i = 0; 178 if ((option_f == NULL) && isatty(0) == 1 && isatty(1) == 1) { 179 /* 180 * We have a real terminal for std input and output, enable 181 * more style of output for disk selection list. 182 */ 183 more = 1; 184 tty_lines = get_tty_lines(); 185 enter_critical(); 186 echo_off(); 187 charmode_on(); 188 exit_critical(); 189 } 190 191 /* 192 * Loop through the list of found disks. 193 */ 194 for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 195 /* 196 * If using more output, account 2 lines for each disk. 197 */ 198 if (more && !more_quit && i && (one_line || 199 ((2 * i + 1) % (tty_lines - 2) <= 1))) { 200 int c; 201 202 /* 203 * Get the next character. 204 */ 205 fmt_print("- hit space for more or s to select - "); 206 c = getchar(); 207 fmt_print("\015"); 208 one_line = 0; 209 /* 210 * Handle display one line command 211 * (return key) 212 */ 213 if (c == '\012') { 214 one_line++; 215 } 216 /* Handle Quit command */ 217 if (c == 'q') { 218 fmt_print( 219 " \015"); 220 more_quit++; 221 } 222 /* Handle ^D command */ 223 if (c == '\004') 224 fullabort(); 225 /* or get on with the show */ 226 if (c == 's' || c == 'S') { 227 fmt_print("%80s\n", " "); 228 break; 229 } 230 } 231 /* 232 * If this is the current disk, mark it as 233 * the default. 234 */ 235 if (cur_disk == disk) { 236 deflt = i; 237 defltptr = &deflt; 238 } 239 if (!more || !more_quit) 240 pr_diskline(disk, i); 241 i++; 242 } 243 if (more) { 244 enter_critical(); 245 charmode_off(); 246 echo_on(); 247 exit_critical(); 248 } 249 250 /* 251 * Determine total number of disks, and ask the user which disk they 252 * would like to make current. 253 */ 254 255 for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 256 ndisks++; 257 } 258 259 ioparam.io_bounds.lower = 0; 260 ioparam.io_bounds.upper = ndisks - 1; 261 index = input(FIO_INT, "Specify disk (enter its number)", ':', 262 &ioparam, defltptr, DATA_INPUT); 263 264 if (index >= i) { 265 blind_select = 1; 266 } 267 268 /* 269 * Find the disk chosen. Search through controllers/disks 270 * in the same original order, so we match what the user 271 * chose. 272 */ 273 checkdisk: 274 i = 0; 275 for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 276 if (i == index) 277 goto found; 278 i++; 279 } 280 /* 281 * Should never happen. 282 */ 283 impossible("no disk found"); 284 285 found: 286 if (blind_select) { 287 (void) snprintf(chk_buf, sizeof (chk_buf), 288 "Disk %s selected - is this the desired disk? ", disk->disk_name); 289 if (check(chk_buf)) { 290 return (-1); 291 } 292 } 293 294 /* 295 * Update the state. We lock out interrupts so the state can't 296 * get half-updated. 297 */ 298 299 enter_critical(); 300 init_globals(disk); 301 exit_critical(); 302 303 /* 304 * If type unknown and interactive, ask user to specify type. 305 * Also, set partition table (best guess) too. 306 */ 307 if (!option_f && ncyl == 0 && nhead == 0 && nsect == 0 && 308 (disk->label_type != L_TYPE_EFI)) { 309 (void) c_type(); 310 } 311 312 /* 313 * Get the Solaris Fdisk Partition information 314 */ 315 if (nhead != 0 && nsect != 0) 316 (void) copy_solaris_part(&cur_disk->fdisk_part); 317 318 if ((cur_disk->label_type == L_TYPE_EFI) && 319 (cur_disk->disk_parts->etoc->efi_flags & 320 EFI_GPT_PRIMARY_CORRUPT)) { 321 err_print("Reading the primary EFI GPT label "); 322 err_print("failed. Using backup label.\n"); 323 err_print("Use the 'backup' command to restore "); 324 err_print("the primary label.\n"); 325 } 326 327 #if defined(_SUNOS_VTOC_16) 328 /* 329 * If there is no fdisk solaris partition. 330 */ 331 if (cur_disk->fdisk_part.numsect == 0) { 332 err_print("No Solaris fdisk partition found.\n"); 333 goto exit; 334 } 335 #endif /* defined(_SUNOS_VTOC_16) */ 336 337 /* 338 * If the label of the disk is marked dirty, 339 * see if they'd like to label the disk now. 340 */ 341 if (cur_disk->disk_flags & DSK_LABEL_DIRTY) { 342 if (check("Disk not labeled. Label it now") == 0) { 343 if (write_label()) { 344 err_print("Write label failed\n"); 345 } else { 346 cur_disk->disk_flags &= ~DSK_LABEL_DIRTY; 347 } 348 } 349 } 350 exit: 351 return (0); 352 } 353 354 /* 355 * This routine implements the 'type' command. It allows the user to 356 * specify the type of the current disk. It should be necessary only 357 * if the disk was not labelled or was somehow labelled incorrectly. 358 * The list of legal types for the disk comes from information that was 359 * in the data file. 360 */ 361 int 362 c_type(void) 363 { 364 struct disk_type *type, *tptr, *oldtype; 365 u_ioparam_t ioparam; 366 int i, index, deflt, *defltptr = NULL; 367 struct disk_type disk_type; 368 struct disk_type *d = &disk_type; 369 int first_disk; 370 int auto_conf_choice; 371 int other_choice; 372 struct dk_label label; 373 struct efi_info efi_info; 374 uint64_t maxLBA; 375 char volname[LEN_DKL_VVOL]; 376 int volinit = 0; 377 378 /* 379 * There must be a current disk. 380 */ 381 if (cur_disk == NULL) { 382 err_print("Current Disk is not set.\n"); 383 return (-1); 384 } 385 oldtype = cur_disk->disk_type; 386 type = cur_ctype->ctype_dlist; 387 /* 388 * Print out the list of choices. 389 */ 390 fmt_print("\n\nAVAILABLE DRIVE TYPES:\n"); 391 first_disk = 0; 392 if (cur_ctype->ctype_ctype == DKC_SCSI_CCS) { 393 auto_conf_choice = 0; 394 fmt_print(" %d. Auto configure\n", first_disk++); 395 } else { 396 auto_conf_choice = -1; 397 } 398 399 i = first_disk; 400 for (tptr = type; tptr != NULL; tptr = tptr->dtype_next) { 401 /* 402 * If we pass the current type, mark it to be the default. 403 */ 404 if (cur_dtype == tptr) { 405 deflt = i; 406 defltptr = &deflt; 407 } 408 if (cur_disk->label_type == L_TYPE_EFI) { 409 continue; 410 } 411 if (tptr->dtype_asciilabel) 412 fmt_print(" %d. %s\n", i++, 413 tptr->dtype_asciilabel); 414 } 415 other_choice = i; 416 fmt_print(" %d. other\n", i); 417 ioparam.io_bounds.lower = 0; 418 ioparam.io_bounds.upper = i; 419 /* 420 * Ask the user which type the disk is. 421 */ 422 index = input(FIO_INT, "Specify disk type (enter its number)", ':', 423 &ioparam, defltptr, DATA_INPUT); 424 /* 425 * Find the type they chose. 426 */ 427 if (index == auto_conf_choice) { 428 float scaled; 429 diskaddr_t nblks; 430 int nparts; 431 432 /* 433 * User chose "auto configure". 434 */ 435 (void) strcpy(x86_devname, cur_disk->disk_name); 436 switch (cur_disk->label_type) { 437 case L_TYPE_SOLARIS: 438 if ((tptr = auto_sense(cur_file, 1, &label)) == NULL) { 439 err_print("Auto configure failed\n"); 440 return (-1); 441 } 442 fmt_print("%s: configured with capacity of ", 443 cur_disk->disk_name); 444 nblks = (diskaddr_t)tptr->dtype_ncyl * 445 tptr->dtype_nhead * tptr->dtype_nsect; 446 scaled = bn2mb(nblks); 447 if (scaled > 1024.0) { 448 fmt_print("%1.2fGB\n", scaled/1024.0); 449 } else { 450 fmt_print("%1.2fMB\n", scaled); 451 } 452 fmt_print("<%s cyl %d alt %d hd %d sec %d>\n", 453 tptr->dtype_asciilabel, tptr->dtype_ncyl, 454 tptr->dtype_acyl, tptr->dtype_nhead, 455 tptr->dtype_nsect); 456 break; 457 case L_TYPE_EFI: 458 if ((tptr = auto_efi_sense(cur_file, &efi_info)) 459 == NULL) { 460 err_print("Auto configure failed\n"); 461 return (-1); 462 } 463 fmt_print("%s: configured with capacity of ", 464 cur_disk->disk_name); 465 scaled = bn2mb(efi_info.capacity); 466 if (scaled > 1024.0) { 467 fmt_print("%1.2fGB\n", scaled/1024.0); 468 } else { 469 fmt_print("%1.2fMB\n", scaled); 470 } 471 cur_blksz = efi_info.e_parts->efi_lbasize; 472 print_efi_string(efi_info.vendor, efi_info.product, 473 efi_info.revision, efi_info.capacity); 474 fmt_print("\n"); 475 for (nparts = 0; nparts < cur_parts->etoc->efi_nparts; 476 nparts++) { 477 if (cur_parts->etoc->efi_parts[nparts].p_tag == 478 V_RESERVED) { 479 (void) strcpy(volname, 480 cur_parts->etoc->efi_parts 481 [nparts].p_name); 482 volinit = 1; 483 break; 484 } 485 } 486 enter_critical(); 487 if (delete_disk_type(cur_disk->disk_type) != 0) { 488 fmt_print("Autoconfiguration failed.\n"); 489 return (-1); 490 } 491 cur_disk->disk_type = tptr; 492 cur_disk->disk_parts = tptr->dtype_plist; 493 init_globals(cur_disk); 494 exit_critical(); 495 if (volinit) { 496 for (nparts = 0; nparts < 497 cur_parts->etoc->efi_nparts; nparts++) { 498 if (cur_parts->etoc->efi_parts[nparts].p_tag == 499 V_RESERVED) { 500 (void) strcpy( 501 cur_parts->etoc->efi_parts[nparts].p_name, 502 volname); 503 (void) strlcpy(cur_disk->v_volume, volname, 504 LEN_DKL_VVOL); 505 break; 506 } 507 } 508 } 509 return (0); 510 default: 511 /* Should never happen */ 512 return (-1); 513 } 514 } else if ((index == other_choice) && (cur_label == L_TYPE_SOLARIS)) { 515 /* 516 * User chose "other". 517 * Get the standard information on the new type. 518 * Put all information in a tmp structure, in 519 * case user aborts. 520 */ 521 bzero((char *)d, sizeof (struct disk_type)); 522 523 d->dtype_ncyl = get_ncyl(); 524 d->dtype_acyl = get_acyl(d->dtype_ncyl); 525 d->dtype_pcyl = get_pcyl(d->dtype_ncyl, d->dtype_acyl); 526 d->dtype_nhead = get_nhead(); 527 d->dtype_phead = get_phead(d->dtype_nhead, &d->dtype_options); 528 d->dtype_nsect = get_nsect(); 529 d->dtype_psect = get_psect(&d->dtype_options); 530 d->dtype_bpt = get_bpt(d->dtype_nsect, &d->dtype_options); 531 d->dtype_rpm = get_rpm(); 532 d->dtype_fmt_time = get_fmt_time(&d->dtype_options); 533 d->dtype_cyl_skew = get_cyl_skew(&d->dtype_options); 534 d->dtype_trk_skew = get_trk_skew(&d->dtype_options); 535 d->dtype_trks_zone = get_trks_zone(&d->dtype_options); 536 d->dtype_atrks = get_atrks(&d->dtype_options); 537 d->dtype_asect = get_asect(&d->dtype_options); 538 d->dtype_cache = get_cache(&d->dtype_options); 539 d->dtype_threshold = get_threshold(&d->dtype_options); 540 d->dtype_prefetch_min = get_min_prefetch(&d->dtype_options); 541 d->dtype_prefetch_max = get_max_prefetch(d->dtype_prefetch_min, 542 &d->dtype_options); 543 d->dtype_bps = get_bps(); 544 #if defined(sparc) 545 d->dtype_dr_type = 0; 546 #endif /* defined(sparc) */ 547 548 d->dtype_asciilabel = get_asciilabel(); 549 /* 550 * Add the new type to the list of possible types for 551 * this controller. We lock out interrupts so the lists 552 * can't get munged. We put off actually allocating the 553 * structure till here in case the user wanted to 554 * interrupt while still inputting information. 555 */ 556 enter_critical(); 557 tptr = (struct disk_type *)zalloc(sizeof (struct disk_type)); 558 if (type == NULL) 559 cur_ctype->ctype_dlist = tptr; 560 else { 561 while (type->dtype_next != NULL) 562 type = type->dtype_next; 563 type->dtype_next = tptr; 564 } 565 bcopy((char *)d, (char *)tptr, sizeof (disk_type)); 566 tptr->dtype_next = NULL; 567 /* 568 * the new disk type does not have any defined 569 * partition table . Hence copy the current partition 570 * table if possible else create a default 571 * paritition table. 572 */ 573 new_partitiontable(tptr, oldtype); 574 } else if ((index == other_choice) && (cur_label == L_TYPE_EFI)) { 575 uint64_t start_lba = cur_parts->etoc->efi_first_u_lba; 576 uint64_t reserved; 577 578 reserved = efi_reserved_sectors(cur_parts->etoc); 579 maxLBA = get_mlba(); 580 cur_parts->etoc->efi_last_lba = maxLBA; 581 cur_parts->etoc->efi_last_u_lba = maxLBA - start_lba; 582 for (i = 0; i < cur_parts->etoc->efi_nparts; i++) { 583 cur_parts->etoc->efi_parts[i].p_start = 0; 584 cur_parts->etoc->efi_parts[i].p_size = 0; 585 cur_parts->etoc->efi_parts[i].p_tag = V_UNASSIGNED; 586 } 587 cur_parts->etoc->efi_parts[8].p_start = 588 maxLBA - start_lba - reserved; 589 cur_parts->etoc->efi_parts[8].p_size = reserved; 590 cur_parts->etoc->efi_parts[8].p_tag = V_RESERVED; 591 if (write_label()) { 592 err_print("Write label failed\n"); 593 } else { 594 cur_disk->disk_flags &= ~DSK_LABEL_DIRTY; 595 } 596 return (0); 597 } else { 598 /* 599 * User picked an existing disk type. 600 */ 601 i = first_disk; 602 tptr = type; 603 while (i < index) { 604 if (tptr->dtype_asciilabel) { 605 i++; 606 } 607 tptr = tptr->dtype_next; 608 } 609 if ((tptr->dtype_asciilabel == NULL) && 610 (tptr->dtype_next != NULL)) { 611 while (tptr->dtype_asciilabel == NULL) { 612 tptr = tptr->dtype_next; 613 } 614 } 615 } 616 /* 617 * Check for mounted file systems in the format zone. 618 * One potential problem with this would be that check() 619 * always returns 'yes' when running out of a file. However, 620 * it is actually ok because we don't let the program get 621 * started if there are mounted file systems and we are 622 * running from a file. 623 */ 624 if ((tptr != oldtype) && 625 checkmount((diskaddr_t)-1, (diskaddr_t)-1)) { 626 err_print( 627 "Cannot set disk type while it has mounted " 628 "partitions.\n\n"); 629 return (-1); 630 } 631 /* 632 * check for partitions being used for swapping in format zone 633 */ 634 if ((tptr != oldtype) && 635 checkswap((diskaddr_t)-1, (diskaddr_t)-1)) { 636 err_print("Cannot set disk type while its partition are " 637 "currently being used for swapping.\n"); 638 return (-1); 639 } 640 641 /* 642 * Check for partitions being used in SVM, VxVM or LU devices 643 */ 644 645 if ((tptr != oldtype) && 646 checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, 647 (diskaddr_t)-1, 0, 0)) { 648 err_print("Cannot set disk type while its " 649 "partitions are currently in use.\n"); 650 return (-1); 651 } 652 /* 653 * If the type selected is different from the previous type, 654 * mark the disk as not labelled and reload the current 655 * partition info. This is not essential but probably the 656 * right thing to do, since the size of the disk has probably 657 * changed. 658 */ 659 enter_critical(); 660 if (tptr != oldtype) { 661 cur_disk->disk_type = tptr; 662 cur_disk->disk_parts = NULL; 663 cur_disk->disk_flags &= ~DSK_LABEL; 664 } 665 /* 666 * Initialize the state of the current disk. 667 */ 668 init_globals(cur_disk); 669 (void) get_partition(); 670 exit_critical(); 671 672 /* 673 * If the label of the disk is marked dirty, 674 * see if they'd like to label the disk now. 675 */ 676 if (cur_disk->disk_flags & DSK_LABEL_DIRTY) { 677 if (check("Disk not labeled. Label it now") == 0) { 678 if (write_label()) { 679 err_print("Write label failed\n"); 680 } else { 681 cur_disk->disk_flags &= ~DSK_LABEL_DIRTY; 682 } 683 } 684 } 685 686 return (0); 687 } 688 689 /* 690 * This routine implements the 'partition' command. It simply runs 691 * the partition menu. 692 */ 693 int 694 c_partition(void) 695 { 696 697 /* 698 * There must be a current disk type and a current disk 699 */ 700 if (cur_dtype == NULL) { 701 err_print("Current Disk Type is not set.\n"); 702 return (-1); 703 } 704 /* 705 * Check for a valid fdisk table entry for Solaris 706 */ 707 if (!good_fdisk()) { 708 return (-1); 709 } 710 711 cur_menu++; 712 last_menu = cur_menu; 713 714 #ifdef not 715 /* 716 * If there is no current partition table, make one. This is 717 * so the commands within the menu never have to check for 718 * a non-existent table. 719 */ 720 if (cur_parts == NULL) 721 err_print("making partition.\n"); 722 make_partition(); 723 #endif /* not */ 724 725 /* 726 * Run the menu. 727 */ 728 run_menu(menu_partition, "PARTITION", "partition", 0); 729 cur_menu--; 730 return (0); 731 } 732 733 /* 734 * This routine implements the 'current' command. It describes the 735 * current disk. 736 */ 737 int 738 c_current(void) 739 { 740 741 /* 742 * If there is no current disk, say so. Note that this is 743 * not an error since it is a legitimate response to the inquiry. 744 */ 745 if (cur_disk == NULL) { 746 fmt_print("No Current Disk.\n"); 747 return (0); 748 } 749 /* 750 * Print out the info we have on the current disk. 751 */ 752 fmt_print("Current Disk = %s", cur_disk->disk_name); 753 if (chk_volname(cur_disk)) { 754 fmt_print(": "); 755 print_volname(cur_disk); 756 } 757 fmt_print("\n"); 758 if (cur_disk->devfs_name != NULL) { 759 if (cur_dtype == NULL) { 760 fmt_print("<type unknown>\n"); 761 } else if (cur_label == L_TYPE_SOLARIS) { 762 fmt_print("<%s cyl %d alt %d hd %d sec %d>\n", 763 cur_dtype->dtype_asciilabel, ncyl, 764 acyl, nhead, nsect); 765 } else if (cur_label == L_TYPE_EFI) { 766 print_efi_string(cur_dtype->vendor, 767 cur_dtype->product, cur_dtype->revision, 768 cur_dtype->capacity); 769 fmt_print("\n"); 770 } 771 fmt_print("%s\n", cur_disk->devfs_name); 772 } else { 773 fmt_print("%s%d: <", cur_ctlr->ctlr_dname, 774 cur_disk->disk_dkinfo.dki_unit); 775 if (cur_dtype == NULL) { 776 fmt_print("type unknown"); 777 } else if (cur_label == L_TYPE_SOLARIS) { 778 fmt_print("%s cyl %d alt %d hd %d sec %d", 779 cur_dtype->dtype_asciilabel, ncyl, 780 acyl, nhead, nsect); 781 } else if (cur_label == L_TYPE_EFI) { 782 print_efi_string(cur_dtype->vendor, 783 cur_dtype->product, cur_dtype->revision, 784 cur_dtype->capacity); 785 fmt_print("\n"); 786 } 787 fmt_print(">\n"); 788 } 789 fmt_print("\n"); 790 return (0); 791 } 792 /* 793 * This routine implements the 'format' command. It allows the user 794 * to format and verify any portion of the disk. 795 */ 796 int 797 c_format(void) 798 { 799 diskaddr_t start, end; 800 time_t clock; 801 int format_time, format_tracks, format_cyls; 802 int format_interval; 803 diskaddr_t deflt; 804 int status; 805 u_ioparam_t ioparam; 806 struct scsi_inquiry *inq; 807 char rawbuf[MAX_MODE_SENSE_SIZE]; 808 struct scsi_capacity_16 capacity; 809 struct vpd_hdr *vpdhdr; 810 uint8_t protect; 811 uint8_t pagecode; 812 uint8_t spt; 813 uint8_t p_type; 814 uint8_t prot_flag[NUM_PROT_TYPE] = {1, 0, 0, 0}; 815 int i; 816 char *prot_descriptor[NUM_PROT_TYPE] = { 817 "Protection Information is disabled.", 818 "Protection Information is enabled.", 819 "Protection Information is enabled.", 820 "Protection Information is enabled.", }; 821 822 /* 823 * There must be a current disk type and a current disk 824 */ 825 if (cur_dtype == NULL) { 826 err_print("Current Disk Type is not set.\n"); 827 return (-1); 828 } 829 830 /* 831 * There must be a format routine in cur_ops structure to have 832 * this routine work. 833 */ 834 if (cur_ops->op_format == NULL) { 835 err_print( 836 "Cannot format this drive. Please use your Manufacturer supplied formatting " 837 "utility.\n"); 838 return (-1); 839 } 840 841 /* 842 * There must be a current defect list. Except for 843 * unformatted SCSI disks. For them the defect list 844 * can only be retrieved after formatting the disk. 845 */ 846 if ((cur_ctype->ctype_flags & CF_SCSI) && !EMBEDDED_SCSI && 847 (cur_ctype->ctype_flags & CF_DEFECTS) && 848 ! (cur_flags & DISK_FORMATTED)) { 849 cur_list.flags |= LIST_RELOAD; 850 851 } else if (cur_list.list == NULL && !EMBEDDED_SCSI) { 852 err_print("Current Defect List must be initialized.\n"); 853 return (-1); 854 } 855 /* 856 * Ask for the bounds of the format. We always use the whole 857 * disk as the default, since that is the most likely case. 858 * Note, for disks which must be formatted accross the whole disk, 859 * don't bother the user. 860 */ 861 ioparam.io_bounds.lower = start = 0; 862 if (cur_label == L_TYPE_SOLARIS) { 863 if (cur_ctype->ctype_flags & CF_SCSI) { 864 ioparam.io_bounds.upper = end = datasects() - 1; 865 } else { 866 ioparam.io_bounds.upper = end = physsects() - 1; 867 } 868 } else { 869 ioparam.io_bounds.upper = end = cur_parts->etoc->efi_last_lba; 870 } 871 872 if (! (cur_ctlr->ctlr_flags & DKI_FMTVOL)) { 873 deflt = ioparam.io_bounds.lower; 874 start = input(FIO_BN, 875 "Enter starting block number", ':', 876 &ioparam, (int *)&deflt, DATA_INPUT); 877 ioparam.io_bounds.lower = start; 878 deflt = ioparam.io_bounds.upper; 879 end = input(FIO_BN, 880 "Enter ending block number", ':', 881 &ioparam, (int *)&deflt, DATA_INPUT); 882 } 883 /* 884 * Some disks can format tracks. Make sure the whole track is 885 * specified for them. 886 */ 887 if (cur_ctlr->ctlr_flags & DKI_FMTTRK) { 888 if (bn2s(start) != 0 || 889 bn2s(end) != sectors(bn2h(end)) - 1) { 890 err_print("Controller requires formatting of "); 891 err_print("entire tracks.\n"); 892 return (-1); 893 } 894 } 895 /* 896 * Check for mounted file systems in the format zone, and if we 897 * find any, make sure they are really serious. One potential 898 * problem with this would be that check() always returns 'yes' 899 * when running out of a file. However, it is actually ok 900 * because we don't let the program get started if there are 901 * mounted file systems and we are running from a file. 902 */ 903 if (checkmount(start, end)) { 904 err_print( 905 "Cannot format disk while it has mounted partitions.\n\n"); 906 return (-1); 907 } 908 /* 909 * check for partitions being used for swapping in format zone 910 */ 911 if (checkswap(start, end)) { 912 err_print("Cannot format disk while its partition are \ 913 currently being used for swapping.\n"); 914 return (-1); 915 } 916 /* 917 * Check for partitions being used in SVM, VxVM or LU devices 918 * in this format zone 919 */ 920 if (checkdevinuse(cur_disk->disk_name, start, end, 0, 0)) { 921 err_print("Cannot format disk while its partitions " 922 "are currently in use.\n"); 923 return (-1); 924 } 925 926 if (cur_disk->disk_lbasize != DEV_BSIZE) { 927 fmt_print("Current disk sector size is %d Byte, format\n" 928 "will change the sector size to 512 Byte. ", 929 cur_disk->disk_lbasize); 930 if (check("Continue")) { 931 return (-1); 932 } 933 } 934 935 /* 936 * set the default protection type 937 */ 938 prot_type = PROT_TYPE_0; 939 940 /* 941 * Check if the protect information of this disk is enabled 942 */ 943 if (uscsi_inquiry(cur_file, rawbuf, sizeof (rawbuf))) { 944 err_print("Inquiry failed\n"); 945 return (-1); 946 } 947 inq = (struct scsi_inquiry *)rawbuf; 948 protect = inq->inq_protect; 949 if (protect == 0) { 950 fmt_print("The protection information is not enabled\n"); 951 fmt_print( 952 "The disk will be formatted with protection type 0\n"); 953 } else { 954 (void) memset(rawbuf, 0, MAX_MODE_SENSE_SIZE); 955 if (uscsi_inquiry_page_86h(cur_file, rawbuf, sizeof (rawbuf))) { 956 err_print("Inquiry with page 86h failed\n"); 957 return (-1); 958 } 959 vpdhdr = (struct vpd_hdr *)rawbuf; 960 pagecode = vpdhdr->page_code; 961 if (pagecode != 0x86) { 962 err_print("Inquiry with page 86h failed\n"); 963 return (-1); 964 } 965 spt = (rawbuf[4] << 2) >> 5; 966 fmt_print("This disk can support protection types:\n"); 967 968 switch (spt) { 969 case 0: 970 prot_flag[1] = 1; 971 break; 972 case 1: 973 prot_flag[1] = 1; 974 prot_flag[2] = 1; 975 break; 976 case 2: 977 prot_flag[2] = 1; 978 break; 979 case 3: 980 prot_flag[1] = 1; 981 prot_flag[3] = 1; 982 break; 983 case 4: 984 prot_flag[3] = 1; 985 break; 986 case 5: 987 prot_flag[2] = 1; 988 prot_flag[3] = 1; 989 break; 990 case 7: 991 prot_flag[1] = 1; 992 prot_flag[2] = 1; 993 prot_flag[3] = 1; 994 break; 995 default: 996 err_print( 997 "Invalid supported protection types\n"); 998 return (-1); 999 } 1000 for (i = 0; i < NUM_PROT_TYPE; i++) { 1001 if (prot_flag[i] == 1) { 1002 fmt_print("[%d] TYPE_%d : ", i, i); 1003 fmt_print("%s\n", prot_descriptor[i]); 1004 } 1005 } 1006 1007 /* 1008 * Get the current protection type 1009 */ 1010 if (uscsi_read_capacity_16(cur_file, &capacity)) { 1011 err_print("Read capacity_16 failed\n"); 1012 return (-1); 1013 } 1014 p_type = get_cur_protection_type(&capacity); 1015 fmt_print("\nThe disk is currently formatted with TYPE_%d.\n", 1016 p_type); 1017 1018 /* 1019 * Ask user what protection type to use 1020 */ 1021 ioparam.io_bounds.lower = PROT_TYPE_0; 1022 ioparam.io_bounds.upper = PROT_TYPE_3; 1023 prot_type = input(FIO_INT, "Specify the New Protection Type", 1024 ':', &ioparam, NULL, DATA_INPUT); 1025 /* 1026 * if get a unsupported protection type, then use the 1027 * current type: p_type. 1028 */ 1029 if (prot_flag[prot_type] == 0) { 1030 fmt_print("Unsupported protection type.\n"); 1031 prot_type = p_type; 1032 } 1033 fmt_print("The disk will be formatted to type %d\n", prot_type); 1034 } 1035 1036 if (SCSI && (format_time = scsi_format_time()) > 0) { 1037 fmt_print( 1038 "\nReady to format. Formatting cannot be interrupted\n" 1039 "and takes %d minutes (estimated). ", format_time); 1040 1041 } else if (cur_dtype->dtype_options & SUP_FMTTIME) { 1042 /* 1043 * Formatting time is (2 * time of 1 spin * number of 1044 * tracks) + (step rate * number of cylinders) rounded 1045 * up to the nearest minute. Note, a 10% fudge factor 1046 * is thrown in for insurance. 1047 */ 1048 if (cur_dtype->dtype_fmt_time == 0) 1049 cur_dtype->dtype_fmt_time = 2; 1050 1051 format_tracks = ((end-start) / cur_dtype->dtype_nsect) + 1; 1052 format_cyls = format_tracks / cur_dtype->dtype_nhead; 1053 format_tracks = format_tracks * cur_dtype->dtype_fmt_time; 1054 1055 /* 1056 * ms. 1057 */ 1058 format_time = ((60000 / cur_dtype->dtype_rpm) +1) * 1059 format_tracks + format_cyls * 7; 1060 /* 1061 * 20% done tick (sec) 1062 */ 1063 format_interval = format_time / 5000; 1064 /* 1065 * min. 1066 */ 1067 format_time = (format_time + 59999) / 60000; 1068 1069 /* 1070 * Check format time values and make adjustments 1071 * to prevent sleeping too long (forever?) or 1072 * too short. 1073 */ 1074 if (format_time <= 1) { 1075 /* 1076 * Format time is less than 1 min.. 1077 */ 1078 format_time = 1; 1079 } 1080 1081 if (format_interval < 11) { 1082 /* Format time is less than 1 minute. */ 1083 if (format_interval < 2) 1084 format_interval = 2; /* failsafe */ 1085 format_interval = 10; 1086 } else { 1087 /* Format time is greater than 1 minute. */ 1088 format_interval -= 10; 1089 } 1090 1091 fmt_print( 1092 "Ready to format. Formatting cannot be interrupted\n" 1093 "and takes %d minutes (estimated). ", format_time); 1094 } else { 1095 fmt_print( 1096 "Ready to format. Formatting cannot be interrupted.\n"); 1097 } 1098 if (check("Continue")) { 1099 return (-1); 1100 } 1101 1102 /* 1103 * Print the time so that the user will know when format started. 1104 * Lock out interrupts. This could be a problem, since it could 1105 * cause the user to sit for quite awhile with no control, but we 1106 * don't have any other good way of keeping their gun from going off. 1107 */ 1108 clock = time(NULL); 1109 fmt_print("Beginning format. The current time is %s\n", 1110 ctime(&clock)); 1111 enter_critical(); 1112 /* 1113 * Mark the defect list dirty so it will be rewritten when we are 1114 * done. It is possible to qualify this so it doesn't always 1115 * get rewritten, but it's not worth the trouble. 1116 * Note: no defect lists for embedded scsi drives. 1117 */ 1118 if (!EMBEDDED_SCSI) { 1119 cur_list.flags |= LIST_DIRTY; 1120 } 1121 /* 1122 * If we are formatting over any of the labels, mark the label 1123 * dirty so it will be rewritten. 1124 */ 1125 if (cur_disk->label_type == L_TYPE_SOLARIS) { 1126 if (start < totalsects() && end >= datasects()) { 1127 if (cur_disk->disk_flags & DSK_LABEL) 1128 cur_flags |= LABEL_DIRTY; 1129 } 1130 } else if (cur_disk->label_type == L_TYPE_EFI) { 1131 if (start < cur_parts->etoc->efi_first_u_lba) { 1132 if (cur_disk->disk_flags & DSK_LABEL) 1133 cur_flags |= LABEL_DIRTY; 1134 } 1135 } 1136 if (start == 0) { 1137 cur_flags |= LABEL_DIRTY; 1138 } 1139 /* 1140 * Do the format. bugid 1009138 removed the use of fork to 1141 * background the format and print a tick. 1142 */ 1143 1144 status = (*cur_ops->op_format)(start, end, &cur_list); 1145 if (status) { 1146 exit_critical(); 1147 err_print("failed\n"); 1148 return (-1); 1149 } 1150 fmt_print("done\n"); 1151 if (option_msg && diag_msg) { 1152 clock = time((time_t *)0); 1153 fmt_print("The current time is %s\n", ctime(&clock)); 1154 } 1155 cur_flags |= DISK_FORMATTED; 1156 /* 1157 * If the defect list or label is dirty, write them out again. 1158 * Note, for SCSI we have to wait til now to load defect list 1159 * since we can't access it until after formatting a virgin disk. 1160 */ 1161 /* enter_critical(); */ 1162 if (cur_list.flags & LIST_RELOAD) { 1163 assert(!EMBEDDED_SCSI); 1164 if (*cur_ops->op_ex_man == NULL || 1165 (*cur_ops->op_ex_man)(&cur_list)) { 1166 err_print("Warning: unable to reload defect list\n"); 1167 cur_list.flags &= ~LIST_DIRTY; 1168 return (-1); 1169 } 1170 cur_list.flags |= LIST_DIRTY; 1171 } 1172 1173 if (cur_list.flags & LIST_DIRTY) { 1174 assert(!EMBEDDED_SCSI); 1175 write_deflist(&cur_list); 1176 cur_list.flags = 0; 1177 } 1178 if (cur_flags & LABEL_DIRTY) { 1179 (void) write_label(); 1180 cur_flags &= ~LABEL_DIRTY; 1181 } 1182 /* 1183 * Come up for air, since the verify step does not need to 1184 * be atomic (it does it's own lockouts when necessary). 1185 */ 1186 exit_critical(); 1187 /* 1188 * If we are supposed to verify, we do the 'write' test over 1189 * the format zone. The rest of the analysis parameters are 1190 * left the way they were. 1191 */ 1192 if (scan_auto) { 1193 scan_entire = 0; 1194 scan_lower = start; 1195 scan_upper = end; 1196 fmt_print("\nVerifying media..."); 1197 status = do_scan(SCAN_PATTERN, F_SILENT); 1198 } 1199 /* 1200 * If the defect list or label is dirty, write them out again. 1201 */ 1202 if (cur_list.flags & LIST_DIRTY) { 1203 assert(!EMBEDDED_SCSI); 1204 cur_list.flags = 0; 1205 write_deflist(&cur_list); 1206 } 1207 if (cur_flags & LABEL_DIRTY) { 1208 cur_flags &= ~LABEL_DIRTY; 1209 (void) write_label(); 1210 } 1211 return (status); 1212 } 1213 1214 /* 1215 * This routine implements the 'repair' command. It allows the user 1216 * to reallocate sectors on the disk that have gone bad. 1217 */ 1218 int 1219 c_repair(void) 1220 { 1221 diskaddr_t bn; 1222 int status; 1223 u_ioparam_t ioparam; 1224 char *buf; 1225 int buf_is_good; 1226 int block_has_error; 1227 int i; 1228 1229 /* 1230 * There must be a current disk type (and therefore a current disk). 1231 */ 1232 if (cur_dtype == NULL) { 1233 err_print("Current Disk Type is not set.\n"); 1234 return (-1); 1235 } 1236 /* 1237 * The current disk must be formatted for repair to work. 1238 */ 1239 if (!(cur_flags & DISK_FORMATTED)) { 1240 err_print("Current Disk is unformatted.\n"); 1241 return (-1); 1242 } 1243 /* 1244 * Check for a valid fdisk table entry for Solaris 1245 */ 1246 if (!good_fdisk()) { 1247 return (-1); 1248 } 1249 /* 1250 * Repair is an optional command for controllers, so it may 1251 * not be supported. 1252 */ 1253 if (cur_ops->op_repair == NULL) { 1254 err_print("Controller does not support repairing.\n"); 1255 err_print("or disk supports automatic defect management.\n"); 1256 return (-1); 1257 } 1258 /* 1259 * There must be a defect list for non-embedded scsi devices, 1260 * since we will add to it. 1261 */ 1262 if (!EMBEDDED_SCSI && cur_list.list == NULL) { 1263 err_print("Current Defect List must be initialized.\n"); 1264 return (-1); 1265 } 1266 /* 1267 * Ask the user which sector has gone bad. 1268 */ 1269 ioparam.io_bounds.lower = 0; 1270 if (cur_disk->label_type == L_TYPE_SOLARIS) { 1271 ioparam.io_bounds.upper = physsects() - 1; 1272 } else { 1273 ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba; 1274 } 1275 bn = input(FIO_BN, 1276 "Enter absolute block number of defect", ':', 1277 &ioparam, NULL, DATA_INPUT); 1278 /* 1279 * Check to see if there is a mounted file system over the 1280 * specified sector. If there is, make sure the user is 1281 * really serious. 1282 */ 1283 if (checkmount(bn, bn)) { 1284 if (check("Repair is in a mounted partition, continue")) 1285 return (-1); 1286 } 1287 /* 1288 * check for partitions being used for swapping in format zone 1289 */ 1290 if (checkswap(bn, bn)) { 1291 if (check("Repair is in a partition which is currently \ 1292 being used for swapping.\ncontinue")) 1293 return (-1); 1294 } 1295 1296 if (checkdevinuse(cur_disk->disk_name, bn, bn, 0, 0)) { 1297 if (check("Repair is in a partition which is currently " 1298 "in use.\ncontinue")) 1299 return (-1); 1300 } 1301 1302 buf = zalloc((cur_disk->disk_lbasize == 0) ? 1303 SECSIZE : cur_disk->disk_lbasize); 1304 1305 /* 1306 * Try to read the sector before repairing it. If we can 1307 * get good data out of it, we can write that data back 1308 * after the repair. If the sector looks ok, ask the 1309 * user to confirm the repair, since it doesn't appear 1310 * necessary. Try reading the block several times to 1311 * see if we can read it consistently. 1312 * 1313 * First, let's see if the block appears to have problems... 1314 */ 1315 block_has_error = 1; 1316 for (i = 0; i < 5; i++) { 1317 status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, 1318 1, buf, (F_SILENT | F_ALLERRS), NULL); 1319 if (status) 1320 break; /* one of the tries failed */ 1321 } 1322 if (status == 0) { 1323 block_has_error = 0; 1324 if (check("\ 1325 This block doesn't appear to be bad. Repair it anyway")) { 1326 free(buf); 1327 return (0); 1328 } 1329 } 1330 /* 1331 * Last chance... 1332 */ 1333 if (check("Ready to repair defect, continue")) { 1334 free(buf); 1335 return (-1); 1336 } 1337 /* 1338 * We're committed to repairing it. Try to get any good 1339 * data out of the block if possible. Note that we do 1340 * not set the F_ALLERRS flag. 1341 */ 1342 buf_is_good = 0; 1343 for (i = 0; i < 5; i++) { 1344 status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, 1345 1, buf, F_SILENT, NULL); 1346 if (status == 0) { 1347 buf_is_good = 1; 1348 break; 1349 } 1350 } 1351 /* 1352 * Lock out interrupts so the disk can't get out of sync with 1353 * the defect list. 1354 */ 1355 enter_critical(); 1356 1357 fmt_print("Repairing "); 1358 if (block_has_error) { 1359 fmt_print("%s error on ", buf_is_good ? "soft" : "hard"); 1360 } 1361 fmt_print("block %llu (", bn); 1362 pr_dblock(fmt_print, bn); 1363 fmt_print(")..."); 1364 /* 1365 * Do the repair. 1366 */ 1367 status = (*cur_ops->op_repair)(bn, F_NORMAL); 1368 if (status) { 1369 fmt_print("failed.\n\n"); 1370 } else { 1371 /* 1372 * The repair worked. Write the old data to the new 1373 * block if we were able to read it, otherwise 1374 * zero out the new block. If it looks like the 1375 * new block is bad, let the user know that, too. 1376 * Should we attempt auto-repair in this case? 1377 */ 1378 fmt_print("ok.\n"); 1379 if (!buf_is_good) { 1380 bzero(buf, cur_disk->disk_lbasize); 1381 } 1382 status = (*cur_ops->op_rdwr)(DIR_WRITE, cur_file, bn, 1383 1, buf, (F_SILENT | F_ALLERRS), NULL); 1384 if (status == 0) { 1385 status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, 1386 bn, 1, buf, (F_SILENT | F_ALLERRS), NULL); 1387 } 1388 if (status) { 1389 fmt_print("The new block %llu (", bn); 1390 pr_dblock(fmt_print, bn); 1391 fmt_print(") also appears defective.\n"); 1392 } 1393 fmt_print("\n"); 1394 /* 1395 * Add the bad sector to the defect list, write out 1396 * the defect list, and kill off the working list so 1397 * it will get synced up with the current defect list 1398 * next time we need it. 1399 * 1400 * For embedded scsi, we don't require a defect list. 1401 * However, if we have one, add the defect if the 1402 * list includes the grown list. If not, kill it 1403 * to force a resync if we need the list later. 1404 */ 1405 if (EMBEDDED_SCSI) { 1406 if (cur_list.list != NULL) { 1407 if (cur_list.flags & LIST_PGLIST) { 1408 add_ldef(bn, &cur_list); 1409 } else { 1410 kill_deflist(&cur_list); 1411 } 1412 } 1413 } else if (cur_ctype->ctype_flags & CF_WLIST) { 1414 kill_deflist(&cur_list); 1415 if (*cur_ops->op_ex_cur != NULL) { 1416 (*cur_ops->op_ex_cur)(&cur_list); 1417 fmt_print("Current list updated\n"); 1418 } 1419 } else { 1420 add_ldef(bn, &cur_list); 1421 write_deflist(&cur_list); 1422 } 1423 kill_deflist(&work_list); 1424 } 1425 exit_critical(); 1426 free(buf); 1427 1428 /* 1429 * Return status. 1430 */ 1431 return (status); 1432 } 1433 1434 /* 1435 * This routine implements the 'show' command. It translates a disk 1436 * block given in any format into decimal, hexadecimal, and 1437 * cylinder/head/sector format. 1438 */ 1439 int 1440 c_show(void) 1441 { 1442 u_ioparam_t ioparam; 1443 diskaddr_t bn; 1444 1445 /* 1446 * There must be a current disk type, so we will know the geometry. 1447 */ 1448 if (cur_dtype == NULL) { 1449 err_print("Current Disk Type is not set.\n"); 1450 return (-1); 1451 } 1452 /* 1453 * Ask the user for a disk block. 1454 */ 1455 ioparam.io_bounds.lower = 0; 1456 if (cur_disk->label_type == L_TYPE_SOLARIS) { 1457 ioparam.io_bounds.upper = physsects() - 1; 1458 } else { 1459 ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba; 1460 } 1461 bn = input(FIO_BN, "Enter a disk block", ':', 1462 &ioparam, NULL, DATA_INPUT); 1463 /* 1464 * Echo it back. 1465 */ 1466 fmt_print("Disk block = %lld = 0x%llx = (", bn, bn); 1467 pr_dblock(fmt_print, bn); 1468 fmt_print(")\n\n"); 1469 return (0); 1470 } 1471 1472 /* 1473 * This routine implements the 'label' command. It writes the 1474 * primary and backup labels onto the current disk. 1475 */ 1476 int 1477 c_label(void) 1478 { 1479 int status; 1480 int deflt, *defltptr = NULL; 1481 1482 /* 1483 * There must be a current disk type (and therefore a current disk). 1484 */ 1485 if (cur_dtype == NULL) { 1486 err_print("Current Disk Type is not set.\n"); 1487 return (-1); 1488 } 1489 /* 1490 * The current disk must be formatted to label it. 1491 */ 1492 if (!(cur_flags & DISK_FORMATTED)) { 1493 err_print("Current Disk is unformatted.\n"); 1494 return (-1); 1495 } 1496 /* 1497 * Check for a valid fdisk table entry for Solaris 1498 */ 1499 if (!good_fdisk()) { 1500 return (-1); 1501 } 1502 /* 1503 * Check to see if there are any mounted file systems anywhere 1504 * on the current disk. If so, refuse to label the disk, but 1505 * only if the partitions would change for the mounted partitions. 1506 * 1507 */ 1508 if (checkmount((diskaddr_t)-1, (diskaddr_t)-1)) { 1509 /* Bleagh, too descriptive */ 1510 if (check_label_with_mount()) { 1511 err_print("Cannot label disk while it has " 1512 "mounted partitions.\n\n"); 1513 return (-1); 1514 } 1515 } 1516 1517 /* 1518 * check to see if there any partitions being used for swapping 1519 * on the current disk. If so, refuse to label the disk, but 1520 * only if the partitions would change for the mounted partitions. 1521 */ 1522 if (checkswap((diskaddr_t)-1, (diskaddr_t)-1)) { 1523 if (check_label_with_swap()) { 1524 err_print("Cannot label disk while its " 1525 "partitions are currently being used for " 1526 "swapping.\n"); 1527 return (-1); 1528 } 1529 } 1530 1531 /* 1532 * Check to see if any partitions used for svm, vxvm or live upgrade 1533 * are on the disk. If so, refuse to label the disk, but only 1534 * if we are trying to shrink a partition in use. 1535 */ 1536 if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, 1537 (diskaddr_t)-1, 0, 1)) { 1538 err_print("Cannot label disk when " 1539 "partitions are in use as described.\n"); 1540 return (-1); 1541 } 1542 1543 /* 1544 * If there is not a current partition map, warn the user we 1545 * are going to use the default. The default is the first 1546 * partition map we encountered in the data file. If there is 1547 * no default we give up. 1548 */ 1549 if (cur_parts == NULL) { 1550 fmt_print("Current Partition Table is not set, " 1551 "using default.\n"); 1552 cur_disk->disk_parts = cur_parts = cur_dtype->dtype_plist; 1553 if (cur_parts == NULL) { 1554 err_print("No default available, cannot label.\n"); 1555 return (-1); 1556 } 1557 } 1558 /* 1559 * If expert (-e) mode, then ask user if they wish 1560 * to change the current solaris label into an EFI one 1561 */ 1562 if (expert_mode) { 1563 #if defined(_SUNOS_VTOC_8) 1564 int i; 1565 #endif 1566 int choice; 1567 u_ioparam_t ioparam; 1568 struct extvtoc vtoc; 1569 struct dk_label label; 1570 struct dk_gpt *vtoc64; 1571 struct efi_info efinfo; 1572 struct disk_type *dptr; 1573 1574 /* Ask user what label to use */ 1575 fmt_print("[0] SMI Label\n"); 1576 fmt_print("[1] EFI Label\n"); 1577 ioparam.io_bounds.lower = 0; 1578 ioparam.io_bounds.upper = 1; 1579 if ((cur_label == L_TYPE_SOLARIS) && 1580 (cur_disk->fdisk_part.systid != EFI_PMBR)) 1581 deflt = L_TYPE_SOLARIS; 1582 else 1583 deflt = L_TYPE_EFI; 1584 defltptr = &deflt; 1585 choice = input(FIO_INT, "Specify Label type", ':', 1586 &ioparam, defltptr, DATA_INPUT); 1587 if ((choice == L_TYPE_SOLARIS) && 1588 (cur_label == L_TYPE_SOLARIS) && 1589 (cur_disk->fdisk_part.systid != EFI_PMBR)) { 1590 goto expert_end; 1591 } else if ((choice == L_TYPE_EFI) && 1592 (cur_label == L_TYPE_EFI)) { 1593 goto expert_end; 1594 } 1595 switch (choice) { 1596 case L_TYPE_SOLARIS: 1597 /* 1598 * EFI label to SMI label 1599 */ 1600 if (cur_dtype->capacity > INFINITY) { 1601 fmt_print("Warning: SMI labels only support up to " 1602 "2 TB.\n"); 1603 } 1604 1605 if (cur_disk->fdisk_part.systid == EFI_PMBR) { 1606 fmt_print("Warning: This disk has an EFI label. " 1607 "Changing to SMI label will erase all\n" 1608 "current partitions.\n"); 1609 if (check("Continue")) 1610 return (-1); 1611 #if defined(_FIRMWARE_NEEDS_FDISK) 1612 fmt_print("You must use fdisk to delete the current " 1613 "EFI partition and create a new\n" 1614 "Solaris partition before you can convert the " 1615 "label.\n"); 1616 return (-1); 1617 #endif 1618 } 1619 1620 #if defined(_FIRMWARE_NEEDS_FDISK) 1621 if (!(((cur_disk->fdisk_part.systid != SUNIXOS) || 1622 (cur_disk->fdisk_part.systid != SUNIXOS2)) && 1623 (cur_disk->fdisk_part.numsect > 0))) { 1624 fmt_print("You must use fdisk to create a Solaris " 1625 "partition before you can convert the label.\n"); 1626 return (-1); 1627 } 1628 #endif 1629 1630 (void) memset((char *)&label, 0, sizeof (struct dk_label)); 1631 1632 (void) strcpy(x86_devname, cur_disk->disk_name); 1633 if (cur_ctype->ctype_ctype == DKC_DIRECT || 1634 cur_ctype->ctype_ctype == DKC_BLKDEV) 1635 dptr = auto_direct_get_geom_label(cur_file, &label); 1636 else 1637 dptr = auto_sense(cur_file, 1, &label); 1638 if (dptr == NULL) { 1639 fmt_print("Autoconfiguration failed.\n"); 1640 return (-1); 1641 } 1642 1643 pcyl = label.dkl_pcyl; 1644 ncyl = label.dkl_ncyl; 1645 acyl = label.dkl_acyl; 1646 nhead = label.dkl_nhead; 1647 nsect = label.dkl_nsect; 1648 1649 if (delete_disk_type(cur_disk->disk_type) == 0) { 1650 cur_label = L_TYPE_SOLARIS; 1651 cur_disk->label_type = L_TYPE_SOLARIS; 1652 cur_disk->disk_type = dptr; 1653 cur_disk->disk_parts = dptr->dtype_plist; 1654 cur_dtype = dptr; 1655 cur_parts = dptr->dtype_plist; 1656 1657 if (status = write_label()) 1658 err_print("Label failed.\n"); 1659 else 1660 cur_disk->disk_flags &= ~DSK_LABEL_DIRTY; 1661 1662 return (status); 1663 } else { 1664 err_print("Label failed.\n"); 1665 return (-1); 1666 } 1667 1668 1669 case L_TYPE_EFI: 1670 /* 1671 * SMI label to EFI label 1672 */ 1673 1674 if ((cur_disk->fdisk_part.systid == SUNIXOS) || 1675 (cur_disk->fdisk_part.systid == SUNIXOS2)) { 1676 fmt_print("Warning: This disk has an SMI label. " 1677 "Changing to EFI label will erase all\ncurrent " 1678 "partitions.\n"); 1679 if (check("Continue")) { 1680 return (-1); 1681 } 1682 } 1683 1684 if (get_disk_info(cur_file, &efinfo, cur_disk) != 0) { 1685 return (-1); 1686 } 1687 (void) memset((char *)&label, 0, sizeof (struct dk_label)); 1688 label.dkl_pcyl = pcyl; 1689 label.dkl_ncyl = ncyl; 1690 label.dkl_acyl = acyl; 1691 #if defined(_SUNOS_VTOC_16) 1692 label.dkl_bcyl = bcyl; 1693 #endif /* defined(_SUNOC_VTOC_16) */ 1694 label.dkl_nhead = nhead; 1695 label.dkl_nsect = nsect; 1696 #if defined(_SUNOS_VTOC_8) 1697 for (i = 0; i < NDKMAP; i++) { 1698 label.dkl_map[i] = cur_parts->pinfo_map[i]; 1699 } 1700 #endif /* defined(_SUNOS_VTOC_8) */ 1701 label.dkl_magic = DKL_MAGIC; 1702 label.dkl_vtoc = cur_parts->vtoc; 1703 if (label_to_vtoc(&vtoc, &label) == -1) { 1704 return (-1); 1705 } 1706 if (SMI_vtoc_to_EFI(cur_file, &vtoc64) == -1) { 1707 return (-1); 1708 } 1709 if (efi_write(cur_file, vtoc64) != 0) { 1710 efi_err_check(vtoc64); 1711 err_print("Warning: error writing EFI.\n"); 1712 return (-1); 1713 } else { 1714 cur_disk->disk_flags &= ~DSK_LABEL_DIRTY; 1715 } 1716 /* 1717 * copy over the EFI vtoc onto the SMI vtoc and return 1718 * okay. 1719 */ 1720 dptr = auto_efi_sense(cur_file, &efinfo); 1721 if (dptr == NULL) { 1722 fmt_print("Autoconfiguration failed.\n"); 1723 return (-1); 1724 } 1725 1726 cur_label = L_TYPE_EFI; 1727 cur_disk->label_type = L_TYPE_EFI; 1728 cur_disk->disk_type = dptr; 1729 cur_disk->disk_parts = dptr->dtype_plist; 1730 cur_dtype = dptr; 1731 cur_parts = dptr->dtype_plist; 1732 cur_parts->etoc = vtoc64; 1733 1734 ncyl = pcyl = nsect = psect = acyl = phead = 0; 1735 1736 /* 1737 * Get the Solais Fdisk Partition information. 1738 */ 1739 (void) copy_solaris_part(&cur_disk->fdisk_part); 1740 1741 return (0); 1742 } 1743 } 1744 1745 expert_end: 1746 /* 1747 * Make sure the user is serious. 1748 */ 1749 if (check("Ready to label disk, continue")) { 1750 return (-1); 1751 } 1752 /* 1753 * Write the labels out (this will also notify unix) and 1754 * return status. 1755 */ 1756 fmt_print("\n"); 1757 if (status = write_label()) 1758 err_print("Label failed.\n"); 1759 return (status); 1760 } 1761 1762 /* 1763 * This routine implements the 'analyze' command. It simply runs 1764 * the analyze menu. 1765 */ 1766 int 1767 c_analyze(void) 1768 { 1769 1770 /* 1771 * There must be a current disk type (and therefor a current disk). 1772 */ 1773 if (cur_dtype == NULL) { 1774 err_print("Current Disk Type is not set.\n"); 1775 return (-1); 1776 } 1777 cur_menu++; 1778 last_menu = cur_menu; 1779 1780 /* 1781 * Run the menu. 1782 */ 1783 run_menu(menu_analyze, "ANALYZE", "analyze", 0); 1784 cur_menu--; 1785 return (0); 1786 } 1787 1788 /* 1789 * This routine implements the 'defect' command. It simply runs 1790 * the defect menu. 1791 */ 1792 int 1793 c_defect(void) 1794 { 1795 int i; 1796 1797 /* 1798 * There must be a current disk type (and therefor a current disk). 1799 */ 1800 if (cur_dtype == NULL) { 1801 err_print("Current Disk Type is not set.\n"); 1802 return (-1); 1803 } 1804 1805 /* 1806 * Check for the defect management and list management ops and 1807 * display appropriate message. 1808 */ 1809 if ((cur_ops->op_ex_man == NULL) && (cur_ops->op_ex_cur == NULL) && 1810 (cur_ops->op_create == NULL) && (cur_ops->op_wr_cur == NULL)) { 1811 err_print("Controller does not support defect management\n"); 1812 err_print("or disk supports automatic defect management.\n"); 1813 return (-1); 1814 } 1815 cur_menu++; 1816 last_menu = cur_menu; 1817 1818 /* 1819 * Lock out interrupt while we manipulate the defect lists. 1820 */ 1821 enter_critical(); 1822 /* 1823 * If the working list is null but there is a current list, 1824 * update the working list to be a copy of the current list. 1825 */ 1826 if ((work_list.list == NULL) && (cur_list.list != NULL)) { 1827 work_list.header = cur_list.header; 1828 work_list.list = (struct defect_entry *)zalloc( 1829 deflist_size(cur_blksz, work_list.header.count) * 1830 cur_blksz); 1831 for (i = 0; i < work_list.header.count; i++) 1832 *(work_list.list + i) = *(cur_list.list + i); 1833 work_list.flags = cur_list.flags & LIST_PGLIST; 1834 } 1835 exit_critical(); 1836 /* 1837 * Run the menu. 1838 */ 1839 run_menu(menu_defect, "DEFECT", "defect", 0); 1840 cur_menu--; 1841 1842 /* 1843 * If the user has modified the working list but not committed 1844 * it, warn them that they are probably making a mistake. 1845 */ 1846 if (work_list.flags & LIST_DIRTY) { 1847 if (!EMBEDDED_SCSI) { 1848 err_print( 1849 "Warning: working defect list modified; but not committed.\n"); 1850 if (!check( 1851 "Do you wish to commit changes to current defect list")) 1852 (void) do_commit(); 1853 } 1854 } 1855 return (0); 1856 } 1857 1858 /* 1859 * This routine implements the 'backup' command. It allows the user 1860 * to search for backup labels on the current disk. This is useful 1861 * if the primary label was lost and the user wishes to recover the 1862 * partition information for the disk. The disk is relabeled and 1863 * the current defect list is written out if a backup label is found. 1864 */ 1865 int 1866 c_backup(void) 1867 { 1868 struct dk_label label; 1869 struct disk_type *dtype; 1870 struct partition_info *parts, *plist; 1871 diskaddr_t bn; 1872 int sec, head, i; 1873 char *buf; 1874 1875 /* 1876 * There must be a current disk type (and therefore a current disk). 1877 */ 1878 if (cur_dtype == NULL) { 1879 err_print("Current Disk Type is not set.\n"); 1880 return (-1); 1881 } 1882 /* 1883 * The disk must be formatted to read backup labels. 1884 */ 1885 if (!(cur_flags & DISK_FORMATTED)) { 1886 err_print("Current Disk is unformatted.\n"); 1887 return (-1); 1888 } 1889 /* 1890 * Check for a valid fdisk table entry for Solaris 1891 */ 1892 if (!good_fdisk()) { 1893 return (-1); 1894 } 1895 /* 1896 * If we found a primary label on this disk, make sure 1897 * the user is serious. 1898 */ 1899 if (cur_disk->label_type == L_TYPE_EFI) { 1900 if (((cur_disk->disk_parts->etoc->efi_flags & 1901 EFI_GPT_PRIMARY_CORRUPT) == 0) && 1902 check("Disk has a primary label, still continue")) 1903 return (-1); 1904 fmt_print("Restoring primary label.\n"); 1905 if (write_label()) { 1906 err_print("Failed\n"); 1907 return (-1); 1908 } 1909 return (0); 1910 } else if (((cur_disk->disk_flags & (DSK_LABEL | DSK_LABEL_DIRTY)) == 1911 DSK_LABEL) && 1912 (check("Disk has a primary label, still continue"))) { 1913 return (-1); 1914 } 1915 1916 buf = zalloc(cur_blksz); 1917 fmt_print("Searching for backup labels..."); 1918 (void) fflush(stdout); 1919 1920 /* 1921 * Some disks have the backup labels in a strange place. 1922 */ 1923 if (cur_ctype->ctype_flags & CF_BLABEL) 1924 head = 2; 1925 else 1926 head = nhead - 1; 1927 /* 1928 * Loop through each copy of the backup label. 1929 */ 1930 for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect)); 1931 sec += 2) { 1932 bn = chs2bn(ncyl + acyl - 1, head, sec) + solaris_offset; 1933 /* 1934 * Attempt to read it. 1935 */ 1936 if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, 1937 1, buf, F_NORMAL, NULL)) { 1938 continue; 1939 } 1940 1941 (void) memcpy((char *)&label, buf, sizeof (struct dk_label)); 1942 1943 /* 1944 * Verify that it is a reasonable label. 1945 */ 1946 if (!checklabel(&label)) 1947 continue; 1948 if (trim_id(label.dkl_asciilabel)) 1949 continue; 1950 /* 1951 * Lock out interrupts while we manipulate lists. 1952 */ 1953 enter_critical(); 1954 fmt_print("found.\n"); 1955 /* 1956 * Find out which disk type the backup label claims. 1957 */ 1958 for (dtype = cur_ctype->ctype_dlist; dtype != NULL; 1959 dtype = dtype->dtype_next) 1960 if (dtype_match(&label, dtype)) 1961 break; 1962 /* 1963 * If it disagrees with our current type, something 1964 * real bad is happening. 1965 */ 1966 if (dtype != cur_dtype) { 1967 if (dtype == NULL) { 1968 fmt_print("\ 1969 Unknown disk type in backup label\n"); 1970 exit_critical(); 1971 free(buf); 1972 return (-1); 1973 } 1974 fmt_print("Backup label claims different type:\n"); 1975 fmt_print(" <%s cyl %d alt %d hd %d sec %d>\n", 1976 label.dkl_asciilabel, label.dkl_ncyl, 1977 label.dkl_acyl, label.dkl_nhead, 1978 label.dkl_nsect); 1979 if (check("Continue")) { 1980 exit_critical(); 1981 free(buf); 1982 return (-1); 1983 } 1984 cur_dtype = dtype; 1985 } 1986 /* 1987 * Try to match the partition map with a known map. 1988 */ 1989 for (parts = dtype->dtype_plist; parts != NULL; 1990 parts = parts->pinfo_next) 1991 if (parts_match(&label, parts)) 1992 break; 1993 /* 1994 * If we couldn't match it, allocate space for a new one, 1995 * fill in the info, and add it to the list. The name 1996 * for the new map is derived from the disk name. 1997 */ 1998 if (parts == NULL) { 1999 parts = (struct partition_info *) 2000 zalloc(sizeof (struct partition_info)); 2001 plist = dtype->dtype_plist; 2002 if (plist == NULL) 2003 dtype->dtype_plist = parts; 2004 else { 2005 while (plist->pinfo_next != NULL) 2006 plist = plist->pinfo_next; 2007 plist->pinfo_next = parts; 2008 } 2009 parts->pinfo_name = alloc_string("original"); 2010 for (i = 0; i < NDKMAP; i++) { 2011 2012 #if defined(_SUNOS_VTOC_8) 2013 parts->pinfo_map[i] = label.dkl_map[i]; 2014 2015 #elif defined(_SUNOS_VTOC_16) 2016 parts->pinfo_map[i].dkl_cylno = 2017 label.dkl_vtoc.v_part[i].p_start / spc(); 2018 parts->pinfo_map[i].dkl_nblk = 2019 label.dkl_vtoc.v_part[i].p_size; 2020 #else 2021 #error No VTOC layout defined. 2022 #endif /* defined(_SUNOS_VTOC_8) */ 2023 } 2024 parts->vtoc = label.dkl_vtoc; 2025 } 2026 /* 2027 * We now have a partition map. Make it the current map. 2028 */ 2029 cur_disk->disk_parts = cur_parts = parts; 2030 exit_critical(); 2031 /* 2032 * Rewrite the labels and defect lists, as appropriate. 2033 */ 2034 if (EMBEDDED_SCSI) { 2035 fmt_print("Restoring primary label.\n"); 2036 if (write_label()) { 2037 free(buf); 2038 return (-1); 2039 } 2040 } else { 2041 fmt_print("Restoring primary label and defect list.\n"); 2042 if (write_label()) { 2043 free(buf); 2044 return (-1); 2045 } 2046 if (cur_list.list != NULL) 2047 write_deflist(&cur_list); 2048 } 2049 fmt_print("\n"); 2050 free(buf); 2051 return (0); 2052 } 2053 /* 2054 * If we didn't find any backup labels, say so. 2055 */ 2056 fmt_print("not found.\n\n"); 2057 free(buf); 2058 return (0); 2059 } 2060 2061 /* 2062 * This routine is called by c_verify() for an EFI labeled disk 2063 */ 2064 static int 2065 c_verify_efi(void) 2066 { 2067 struct efi_info efi_info; 2068 struct partition_info tmp_pinfo; 2069 int status; 2070 2071 status = read_efi_label(cur_file, &efi_info, cur_disk); 2072 if (status != 0) { 2073 err_print("Warning: Could not read label.\n"); 2074 return (-1); 2075 } 2076 if (cur_parts->etoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) { 2077 err_print("Reading the primary EFI GPT label "); 2078 err_print("failed. Using backup label.\n"); 2079 err_print("Use the 'backup' command to restore "); 2080 err_print("the primary label.\n"); 2081 } 2082 tmp_pinfo.etoc = efi_info.e_parts; 2083 fmt_print("\n"); 2084 fmt_print("Volume name = <%8s>\n", 2085 cur_parts->etoc->efi_parts[8].p_name); 2086 fmt_print("ascii name = "); 2087 print_efi_string(efi_info.vendor, efi_info.product, 2088 efi_info.revision, efi_info.capacity); 2089 fmt_print("\n"); 2090 2091 fmt_print("bytes/sector = %d\n", cur_blksz); 2092 fmt_print("sectors = %llu\n", cur_parts->etoc->efi_last_lba + 1); 2093 fmt_print("accessible sectors = %llu\n", 2094 cur_parts->etoc->efi_last_u_lba - 2095 cur_parts->etoc->efi_first_u_lba - 2096 efi_reserved_sectors(cur_parts->etoc) + 1); 2097 fmt_print("first usable sector = %llu\n", 2098 cur_parts->etoc->efi_first_u_lba); 2099 fmt_print("last usable sector = %llu\n", 2100 cur_parts->etoc->efi_last_u_lba); 2101 2102 print_map(&tmp_pinfo); 2103 2104 free(efi_info.vendor); 2105 free(efi_info.product); 2106 free(efi_info.revision); 2107 return (0); 2108 } 2109 2110 /* 2111 * This routine implements the 'verify' command. It allows the user 2112 * to read the labels on the current disk. 2113 */ 2114 int 2115 c_verify(void) 2116 { 2117 struct dk_label p_label, b_label, *label; 2118 struct partition_info tmp_pinfo; 2119 diskaddr_t bn; 2120 int sec, head, i, status; 2121 int p_label_bad = 0; 2122 int b_label_bad = 0; 2123 int p_label_found = 0; 2124 int b_label_found = 0; 2125 char id_str[128]; 2126 char *buf; 2127 2128 /* 2129 * There must be a current disk type (and therefore a current disk). 2130 */ 2131 if (cur_dtype == NULL) { 2132 err_print("Current Disk Type is not set.\n"); 2133 return (-1); 2134 } 2135 /* 2136 * The disk must be formatted to read labels. 2137 */ 2138 if (!(cur_flags & DISK_FORMATTED)) { 2139 err_print("Current Disk is unformatted.\n"); 2140 return (-1); 2141 } 2142 /* 2143 * Check for a valid fdisk table entry for Solaris 2144 */ 2145 if (!good_fdisk()) { 2146 return (-1); 2147 } 2148 /* 2149 * Branch off here if the disk is EFI labelled. 2150 */ 2151 if (cur_label == L_TYPE_EFI) { 2152 return (c_verify_efi()); 2153 } 2154 /* 2155 * Attempt to read the primary label. 2156 */ 2157 status = read_label(cur_file, &p_label); 2158 if (status == -1) { 2159 err_print("Warning: Could not read primary label.\n"); 2160 p_label_bad = 1; 2161 } else { 2162 /* 2163 * Verify that it is a reasonable label. 2164 */ 2165 /* 2166 * Save complete ascii string for printing later. 2167 */ 2168 (void) strncpy(id_str, p_label.dkl_asciilabel, 128); 2169 2170 if ((!checklabel((struct dk_label *)&p_label)) || 2171 (trim_id(p_label.dkl_asciilabel))) { 2172 err_print("\ 2173 Warning: Primary label appears to be corrupt.\n"); 2174 p_label_bad = 1; 2175 } else { 2176 p_label_found = 1; 2177 /* 2178 * Make sure it matches current label 2179 */ 2180 if ((!dtype_match(&p_label, cur_dtype)) || 2181 (!parts_match(&p_label, cur_parts))) { 2182 err_print("\ 2183 Warning: Primary label on disk appears to be different from\ncurrent label.\n"); 2184 p_label_bad = 1; 2185 } 2186 } 2187 } 2188 2189 /* 2190 * Read backup labels. 2191 * Some disks have the backup labels in a strange place. 2192 */ 2193 if (cur_ctype->ctype_flags & CF_BLABEL) 2194 head = 2; 2195 else 2196 head = nhead - 1; 2197 2198 buf = zalloc(cur_blksz); 2199 /* 2200 * Loop through each copy of the backup label. 2201 */ 2202 for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect)); 2203 sec += 2) { 2204 bn = chs2bn(ncyl + acyl - 1, head, sec) + solaris_offset; 2205 /* 2206 * Attempt to read it. 2207 */ 2208 if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, 2209 1, buf, F_NORMAL, NULL)) 2210 continue; 2211 2212 (void) memcpy((char *)&b_label, buf, 2213 sizeof (struct dk_label)); 2214 2215 /* 2216 * Verify that it is a reasonable label. 2217 */ 2218 if (!checklabel(&b_label)) 2219 continue; 2220 2221 /* 2222 * Save complete label only if no primary label exists 2223 */ 2224 if (!p_label_found) 2225 (void) strncpy(id_str, b_label.dkl_asciilabel, 128); 2226 2227 if (trim_id(b_label.dkl_asciilabel)) 2228 continue; 2229 b_label_found = 1; 2230 /* 2231 * Compare against primary label 2232 */ 2233 if (p_label_found) { 2234 if ((strcmp(b_label.dkl_asciilabel, 2235 p_label.dkl_asciilabel) != 0) || 2236 (b_label.dkl_ncyl != p_label.dkl_ncyl) || 2237 (b_label.dkl_acyl != p_label.dkl_acyl) || 2238 (b_label.dkl_nhead != p_label.dkl_nhead) || 2239 (b_label.dkl_nsect != p_label.dkl_nsect)) { 2240 b_label_bad = 1; 2241 } else { 2242 for (i = 0; i < NDKMAP; i++) { 2243 #if defined(_SUNOS_VTOC_8) 2244 if ((b_label.dkl_map[i].dkl_cylno != 2245 p_label.dkl_map[i].dkl_cylno) || 2246 (b_label.dkl_map[i].dkl_nblk != 2247 p_label.dkl_map[i].dkl_nblk)) { 2248 b_label_bad = 1; 2249 break; 2250 } 2251 2252 #elif defined(_SUNOS_VTOC_16) 2253 if ((b_label.dkl_vtoc.v_part[i].p_tag != 2254 p_label.dkl_vtoc.v_part[i].p_tag) || 2255 (b_label.dkl_vtoc.v_part[i].p_flag 2256 != p_label.dkl_vtoc.v_part[i]. 2257 p_flag) || 2258 (b_label.dkl_vtoc.v_part[i].p_start 2259 != p_label.dkl_vtoc.v_part[i]. 2260 p_start) || 2261 (b_label.dkl_vtoc.v_part[i].p_size 2262 != p_label.dkl_vtoc.v_part[i]. 2263 p_size)) { 2264 b_label_bad = 1; 2265 break; 2266 } 2267 #else 2268 #error No VTOC layout defined. 2269 #endif /* defined(_SUNOS_VTOC_8) */ 2270 } 2271 } 2272 } 2273 if (b_label_bad) 2274 err_print( 2275 "Warning: Primary and backup labels do not match.\n"); 2276 break; 2277 } 2278 /* 2279 * If we didn't find any backup labels, say so. 2280 */ 2281 if (!b_label_found) 2282 err_print("Warning: Could not read backup labels.\n"); 2283 2284 if ((!b_label_found) || (p_label_bad) || (b_label_bad)) 2285 err_print("\n\ 2286 Warning: Check the current partitioning and 'label' the disk or use the\n\ 2287 \t 'backup' command.\n"); 2288 2289 /* 2290 * Print label information. 2291 */ 2292 if (p_label_found) { 2293 fmt_print("\nPrimary label contents:\n"); 2294 label = &p_label; 2295 } else if (b_label_found) { 2296 fmt_print("\nBackup label contents:\n"); 2297 label = &b_label; 2298 } else { 2299 free(buf); 2300 return (0); 2301 } 2302 2303 /* 2304 * Must put info into partition_info struct for 2305 * for print routine. 2306 */ 2307 bzero(&tmp_pinfo, sizeof (struct partition_info)); 2308 for (i = 0; i < NDKMAP; i++) { 2309 2310 #if defined(_SUNOS_VTOC_8) 2311 tmp_pinfo.pinfo_map[i] = label->dkl_map[i]; 2312 2313 #elif defined(_SUNOS_VTOC_16) 2314 tmp_pinfo.pinfo_map[i].dkl_cylno = 2315 label->dkl_vtoc.v_part[i].p_start / spc(); 2316 tmp_pinfo.pinfo_map[i].dkl_nblk = 2317 label->dkl_vtoc.v_part[i].p_size; 2318 #else 2319 #error No VTOC layout defined. 2320 #endif /* defined(_SUNOS_VTOC_8) */ 2321 } 2322 tmp_pinfo.vtoc = label->dkl_vtoc; 2323 2324 fmt_print("\n"); 2325 fmt_print("Volume name = <%8s>\n", label->dkl_vtoc.v_volume); 2326 fmt_print("ascii name = <%s>\n", id_str); 2327 fmt_print("pcyl = %4d\n", label->dkl_pcyl); 2328 fmt_print("ncyl = %4d\n", label->dkl_ncyl); 2329 fmt_print("acyl = %4d\n", label->dkl_acyl); 2330 2331 #if defined(_SUNOS_VTOC_16) 2332 fmt_print("bcyl = %4d\n", label->dkl_bcyl); 2333 #endif /* defined(_SUNOS_VTOC_16) */ 2334 2335 fmt_print("nhead = %4d\n", label->dkl_nhead); 2336 fmt_print("nsect = %4d\n", label->dkl_nsect); 2337 2338 print_map(&tmp_pinfo); 2339 free(buf); 2340 return (0); 2341 } 2342 2343 2344 /* 2345 * This command implements the inquiry command, for embedded SCSI 2346 * disks only, which issues a SCSI inquiry command, and 2347 * displays the resulting vendor, product id and revision level. 2348 */ 2349 int 2350 c_inquiry(void) 2351 { 2352 char inqbuf[255]; 2353 struct scsi_inquiry *inq; 2354 2355 assert(SCSI); 2356 2357 inq = (struct scsi_inquiry *)inqbuf; 2358 2359 if (uscsi_inquiry(cur_file, inqbuf, sizeof (inqbuf))) { 2360 err_print("Failed\n"); 2361 return (-1); 2362 } else { 2363 fmt_print("Vendor: "); 2364 print_buf(inq->inq_vid, sizeof (inq->inq_vid)); 2365 fmt_print("\nProduct: "); 2366 print_buf(inq->inq_pid, sizeof (inq->inq_pid)); 2367 fmt_print("\nRevision: "); 2368 print_buf(inq->inq_revision, sizeof (inq->inq_revision)); 2369 fmt_print("\n"); 2370 } 2371 2372 return (0); 2373 } 2374 2375 2376 /* 2377 * This routine allows the user to set the 8-character 2378 * volume name in the vtoc. It then writes both the 2379 * primary and backup labels onto the current disk. 2380 */ 2381 int 2382 c_volname(void) 2383 { 2384 int status; 2385 char *prompt; 2386 union { 2387 int xfoo; 2388 char defvolname[LEN_DKL_VVOL+1]; 2389 } x; 2390 char s1[MAXPATHLEN], nclean[MAXPATHLEN]; 2391 char *volname; 2392 2393 2394 /* 2395 * There must be a current disk type (and therefore a current disk). 2396 */ 2397 if (cur_dtype == NULL) { 2398 err_print("Current Disk Type is not set.\n"); 2399 return (-1); 2400 } 2401 /* 2402 * The current disk must be formatted to label it. 2403 */ 2404 if (!(cur_flags & DISK_FORMATTED)) { 2405 err_print("Current Disk is unformatted.\n"); 2406 return (-1); 2407 } 2408 /* 2409 * Check for a valid fdisk table entry for Solaris 2410 */ 2411 if (!good_fdisk()) { 2412 return (-1); 2413 } 2414 /* 2415 * The current disk must be formatted to label it. 2416 */ 2417 if (cur_parts == NULL) { 2418 err_print( 2419 "Please select a partition map for the disk first.\n"); 2420 return (-1); 2421 } 2422 2423 /* 2424 * Check to see if there are any mounted file systems anywhere 2425 * on the current disk. If so, refuse to label the disk, but 2426 * only if the partitions would change for the mounted partitions. 2427 * 2428 */ 2429 if (checkmount((diskaddr_t)-1, (diskaddr_t)-1)) { 2430 /* Bleagh, too descriptive */ 2431 if (check_label_with_mount()) { 2432 err_print( 2433 "Cannot label disk while it has mounted partitions.\n\n"); 2434 return (-1); 2435 } 2436 } 2437 2438 /* 2439 * Check to see if there are partitions being used for swapping 2440 * on the current disk. If so, refuse to label the disk, but 2441 * only if the partitions would change for the swap partitions. 2442 * 2443 */ 2444 if (checkswap((diskaddr_t)-1, (diskaddr_t)-1)) { 2445 /* Bleagh, too descriptive */ 2446 if (check_label_with_swap()) { 2447 err_print( 2448 "Cannot label disk while its partitions are currently \ 2449 being used for swapping.\n\n"); 2450 return (-1); 2451 } 2452 } 2453 2454 /* 2455 * Check to see if any partitions used for svm, vxvm, ZFS zpool 2456 * or live upgrade are on the disk. If so, refuse to label the 2457 * disk, but only if we are trying to shrink a partition in 2458 * use. 2459 */ 2460 if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, 2461 (diskaddr_t)-1, 0, 1)) { 2462 err_print("Cannot label disk while its partitions " 2463 "are in use as described.\n"); 2464 return (-1); 2465 } 2466 2467 /* 2468 * Prompt for the disk volume name. 2469 */ 2470 prompt = "Enter 8-character volume name (remember quotes)"; 2471 bzero(x.defvolname, LEN_DKL_VVOL+1); 2472 bcopy(cur_disk->v_volume, x.defvolname, LEN_DKL_VVOL); 2473 /* 2474 * Get the input using "get_inputline" since 2475 * input would never return null string. 2476 */ 2477 fmt_print("%s[\"%s\"]:", prompt, x.defvolname); 2478 2479 /* 2480 * Get input from the user. 2481 */ 2482 get_inputline(nclean, MAXPATHLEN); 2483 clean_token(s1, nclean); 2484 /* 2485 * check for return. 2486 */ 2487 if (s1[0] == 0) { 2488 volname = x.defvolname; 2489 } else { 2490 /* 2491 * remove the " mark from volname. 2492 */ 2493 if (s1[0] == '"') { 2494 int i = 1; 2495 volname = &s1[1]; 2496 while (s1[i] != '"' && s1[i] != '\0') 2497 i++; 2498 s1[i] = '\0'; 2499 clean_token(nclean, volname); 2500 volname = nclean; 2501 } else { 2502 (void) sscanf(&s1[0], "%1024s", nclean); 2503 volname = nclean; 2504 }; 2505 } 2506 /* 2507 * Make sure the user is serious. 2508 */ 2509 if (check("Ready to label disk, continue")) { 2510 fmt_print("\n"); 2511 return (-1); 2512 } 2513 /* 2514 * Use the volume name chosen above 2515 */ 2516 bzero(cur_disk->v_volume, LEN_DKL_VVOL); 2517 bcopy(volname, cur_disk->v_volume, min((int)strlen(volname), 2518 LEN_DKL_VVOL)); 2519 if (cur_label == L_TYPE_EFI) { 2520 bzero(cur_parts->etoc->efi_parts[8].p_name, LEN_DKL_VVOL); 2521 bcopy(volname, cur_parts->etoc->efi_parts[8].p_name, 2522 LEN_DKL_VVOL); 2523 } 2524 /* 2525 * Write the labels out (this will also notify unix) and 2526 * return status. 2527 */ 2528 fmt_print("\n"); 2529 if (status = write_label()) 2530 err_print("Label failed.\n"); 2531 return (status); 2532 } 2533