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