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