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