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