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