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