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