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