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