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 if (cur_ctype->ctype_ctype == DKC_DIRECT) 1457 dptr = auto_direct_get_geom_label(cur_file, &label); 1458 else 1459 dptr = auto_sense(cur_file, 1, &label); 1460 if (dptr == NULL) { 1461 fmt_print("Autoconfiguration failed.\n"); 1462 return (-1); 1463 } 1464 1465 if (cur_disk->fdisk_part.systid == EFI_PMBR) { 1466 fmt_print("You must use fdisk to delete the current " 1467 "EFI partition and create a new\n" 1468 "Solaris partition before you can convert the " 1469 "label.\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 cur_label = L_TYPE_SOLARIS; 1480 cur_disk->label_type = L_TYPE_SOLARIS; 1481 free(cur_parts->etoc); 1482 free(cur_parts); 1483 dptr->dtype_next = cur_dtype->dtype_next; 1484 free(cur_disk->disk_type); 1485 cur_disk->disk_type = dptr; 1486 cur_disk->disk_parts = dptr->dtype_plist; 1487 cur_dtype = dptr; 1488 cur_parts = dptr->dtype_plist; 1489 dptr->dtype_next = NULL; 1490 1491 if (status = write_label()) 1492 err_print("Label failed.\n"); 1493 return (status); 1494 1495 1496 case 1: 1497 /* 1498 * SMI label to EFI label 1499 */ 1500 1501 1502 fmt_print("Warning: This disk has an SMI label. Changing to " 1503 "EFI label will erase all\ncurrent partitions.\n"); 1504 1505 if (check("Continue")) { 1506 return (-1); 1507 } 1508 1509 if (get_disk_info(cur_file, &efinfo) != 0) { 1510 return (-1); 1511 } 1512 (void) memset((char *)&label, 0, sizeof (struct dk_label)); 1513 label.dkl_pcyl = pcyl; 1514 label.dkl_ncyl = ncyl; 1515 label.dkl_acyl = acyl; 1516 #if defined(_SUNOS_VTOC_16) 1517 label.dkl_bcyl = bcyl; 1518 #endif /* defined(_SUNOC_VTOC_16) */ 1519 label.dkl_nhead = nhead; 1520 label.dkl_nsect = nsect; 1521 #if defined(_SUNOS_VTOC_8) 1522 for (i = 0; i < NDKMAP; i++) { 1523 label.dkl_map[i] = cur_parts->pinfo_map[i]; 1524 } 1525 #endif /* defined(_SUNOS_VTOC_8) */ 1526 label.dkl_magic = DKL_MAGIC; 1527 label.dkl_vtoc = cur_parts->vtoc; 1528 if (label_to_vtoc(&vtoc, &label) == -1) { 1529 return (-1); 1530 } 1531 if (SMI_vtoc_to_EFI(cur_file, &vtoc64, &vtoc) == -1) { 1532 return (-1); 1533 } 1534 if (efi_write(cur_file, vtoc64) != 0) { 1535 err_check(vtoc64); 1536 err_print("Warning: error writing EFI.\n"); 1537 return (-1); 1538 } 1539 /* 1540 * copy over the EFI vtoc onto the SMI vtoc and return 1541 * okay. 1542 */ 1543 cur_parts->etoc = vtoc64; 1544 cur_label = L_TYPE_EFI; 1545 cur_disk->label_type = L_TYPE_EFI; 1546 (void) strlcpy(cur_dtype->vendor, efinfo.vendor, 9); 1547 (void) strlcpy(cur_dtype->product, efinfo.product, 17); 1548 (void) strlcpy(cur_dtype->revision, efinfo.revision, 5); 1549 cur_dtype->capacity = efinfo.capacity; 1550 free(cur_dtype->dtype_asciilabel); 1551 ncyl = pcyl = nsect = psect = acyl = phead = 0; 1552 1553 return (0); 1554 } 1555 } 1556 1557 expert_end: 1558 /* 1559 * Make sure the user is serious. 1560 */ 1561 if (check("Ready to label disk, continue")) { 1562 return (-1); 1563 } 1564 /* 1565 * Write the labels out (this will also notify unix) and 1566 * return status. 1567 */ 1568 fmt_print("\n"); 1569 if (status = write_label()) 1570 err_print("Label failed.\n"); 1571 return (status); 1572 } 1573 1574 /* 1575 * This routine implements the 'analyze' command. It simply runs 1576 * the analyze menu. 1577 */ 1578 int 1579 c_analyze() 1580 { 1581 1582 /* 1583 * There must be a current disk type (and therefor a current disk). 1584 */ 1585 if (cur_dtype == NULL) { 1586 err_print("Current Disk Type is not set.\n"); 1587 return (-1); 1588 } 1589 cur_menu++; 1590 last_menu = cur_menu; 1591 1592 /* 1593 * Run the menu. 1594 */ 1595 run_menu(menu_analyze, "ANALYZE", "analyze", 0); 1596 cur_menu--; 1597 return (0); 1598 } 1599 1600 /* 1601 * This routine implements the 'defect' command. It simply runs 1602 * the defect menu. 1603 */ 1604 int 1605 c_defect() 1606 { 1607 int i; 1608 1609 /* 1610 * There must be a current disk type (and therefor a current disk). 1611 */ 1612 if (cur_dtype == NULL) { 1613 err_print("Current Disk Type is not set.\n"); 1614 return (-1); 1615 } 1616 1617 /* 1618 * Check for the defect management and list management ops and 1619 * display appropriate message. 1620 */ 1621 if ((cur_ops->op_ex_man == NULL) && (cur_ops->op_ex_cur == NULL) && 1622 (cur_ops->op_create == NULL) && (cur_ops->op_wr_cur == NULL)) { 1623 err_print("Controller does not support defect management\n"); 1624 err_print("or disk supports automatic defect management.\n"); 1625 return (-1); 1626 } 1627 cur_menu++; 1628 last_menu = cur_menu; 1629 1630 /* 1631 * Lock out interrupt while we manipulate the defect lists. 1632 */ 1633 enter_critical(); 1634 /* 1635 * If the working list is null but there is a current list, 1636 * update the working list to be a copy of the current list. 1637 */ 1638 if ((work_list.list == NULL) && (cur_list.list != NULL)) { 1639 work_list.header = cur_list.header; 1640 work_list.list = (struct defect_entry *)zalloc( 1641 LISTSIZE(work_list.header.count) * SECSIZE); 1642 for (i = 0; i < work_list.header.count; i++) 1643 *(work_list.list + i) = *(cur_list.list + i); 1644 work_list.flags = cur_list.flags & LIST_PGLIST; 1645 } 1646 exit_critical(); 1647 /* 1648 * Run the menu. 1649 */ 1650 run_menu(menu_defect, "DEFECT", "defect", 0); 1651 cur_menu--; 1652 1653 /* 1654 * If the user has modified the working list but not committed 1655 * it, warn him that he is probably making a mistake. 1656 */ 1657 if (work_list.flags & LIST_DIRTY) { 1658 if (!EMBEDDED_SCSI) { 1659 err_print( 1660 "Warning: working defect list modified; but not committed.\n"); 1661 if (!check( 1662 "Do you wish to commit changes to current defect list")) 1663 (void) do_commit(); 1664 } 1665 } 1666 return (0); 1667 } 1668 1669 /* 1670 * This routine implements the 'backup' command. It allows the user 1671 * to search for backup labels on the current disk. This is useful 1672 * if the primary label was lost and the user wishes to recover the 1673 * partition information for the disk. The disk is relabeled and 1674 * the current defect list is written out if a backup label is found. 1675 */ 1676 int 1677 c_backup() 1678 { 1679 struct dk_label label; 1680 struct disk_type *dtype; 1681 struct partition_info *parts, *plist; 1682 daddr_t bn; 1683 int sec, head, i; 1684 1685 /* 1686 * There must be a current disk type (and therefore a current disk). 1687 */ 1688 if (cur_dtype == NULL) { 1689 err_print("Current Disk Type is not set.\n"); 1690 return (-1); 1691 } 1692 /* 1693 * The disk must be formatted to read backup labels. 1694 */ 1695 if (!(cur_flags & DISK_FORMATTED)) { 1696 err_print("Current Disk is unformatted.\n"); 1697 return (-1); 1698 } 1699 /* 1700 * Check for a valid fdisk table entry for Solaris 1701 */ 1702 if (!good_fdisk()) { 1703 err_print("Please run fdisk first.\n"); 1704 return (-1); 1705 } 1706 /* 1707 * If we found a primary label on this disk, make sure 1708 * the user is serious. 1709 */ 1710 if (cur_disk->label_type == L_TYPE_EFI) { 1711 if (((cur_disk->disk_parts->etoc->efi_flags & 1712 EFI_GPT_PRIMARY_CORRUPT) == 0) && 1713 check("Disk has a primary label, still continue")) 1714 return (-1); 1715 fmt_print("Restoring primary label.\n"); 1716 if (write_label()) { 1717 err_print("Failed\n"); 1718 return (-1); 1719 } 1720 return (0); 1721 } else if (((cur_disk->disk_flags & (DSK_LABEL | DSK_LABEL_DIRTY)) == 1722 DSK_LABEL) && 1723 (check("Disk has a primary label, still continue"))) { 1724 return (-1); 1725 } 1726 fmt_print("Searching for backup labels..."); 1727 (void) fflush(stdout); 1728 /* 1729 * Some disks have the backup labels in a strange place. 1730 */ 1731 if (cur_ctype->ctype_flags & CF_BLABEL) 1732 head = 2; 1733 else 1734 head = nhead - 1; 1735 /* 1736 * Loop through each copy of the backup label. 1737 */ 1738 for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect)); 1739 sec += 2) { 1740 bn = chs2bn(ncyl + acyl - 1, head, sec) + solaris_offset; 1741 /* 1742 * Attempt to read it. 1743 */ 1744 if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, (diskaddr_t)bn, 1745 1, (char *)&label, F_NORMAL, NULL)) { 1746 continue; 1747 } 1748 /* 1749 * Verify that it is a reasonable label. 1750 */ 1751 if (!checklabel(&label)) 1752 continue; 1753 if (trim_id(label.dkl_asciilabel)) 1754 continue; 1755 /* 1756 * Lock out interrupts while we manipulate lists. 1757 */ 1758 enter_critical(); 1759 fmt_print("found.\n"); 1760 /* 1761 * Find out which disk type the backup label claims. 1762 */ 1763 for (dtype = cur_ctype->ctype_dlist; dtype != NULL; 1764 dtype = dtype->dtype_next) 1765 if (dtype_match(&label, dtype)) 1766 break; 1767 /* 1768 * If it disagrees with our current type, something 1769 * real bad is happening. 1770 */ 1771 if (dtype != cur_dtype) { 1772 if (dtype == NULL) { 1773 fmt_print("\ 1774 Unknown disk type in backup label\n"); 1775 exit_critical(); 1776 return (-1); 1777 } 1778 fmt_print("Backup label claims different type:\n"); 1779 fmt_print(" <%s cyl %d alt %d hd %d sec %d>\n", 1780 label.dkl_asciilabel, label.dkl_ncyl, 1781 label.dkl_acyl, label.dkl_nhead, 1782 label.dkl_nsect); 1783 if (check("Continue")) { 1784 exit_critical(); 1785 return (-1); 1786 } 1787 cur_dtype = dtype; 1788 } 1789 /* 1790 * Try to match the partition map with a known map. 1791 */ 1792 for (parts = dtype->dtype_plist; parts != NULL; 1793 parts = parts->pinfo_next) 1794 if (parts_match(&label, parts)) 1795 break; 1796 /* 1797 * If we couldn't match it, allocate space for a new one, 1798 * fill in the info, and add it to the list. The name 1799 * for the new map is derived from the disk name. 1800 */ 1801 if (parts == NULL) { 1802 parts = (struct partition_info *) 1803 zalloc(sizeof (struct partition_info)); 1804 plist = dtype->dtype_plist; 1805 if (plist == NULL) 1806 dtype->dtype_plist = parts; 1807 else { 1808 while (plist->pinfo_next != NULL) 1809 plist = plist->pinfo_next; 1810 plist->pinfo_next = parts; 1811 } 1812 parts->pinfo_name = alloc_string("original"); 1813 for (i = 0; i < NDKMAP; i++) 1814 1815 #if defined(_SUNOS_VTOC_8) 1816 parts->pinfo_map[i] = label.dkl_map[i]; 1817 1818 #elif defined(_SUNOS_VTOC_16) 1819 parts->pinfo_map[i].dkl_cylno = 1820 label.dkl_vtoc.v_part[i].p_start / spc(); 1821 parts->pinfo_map[i].dkl_nblk = 1822 label.dkl_vtoc.v_part[i].p_size; 1823 #else 1824 #error No VTOC layout defined. 1825 #endif /* defined(_SUNOS_VTOC_8) */ 1826 parts->vtoc = label.dkl_vtoc; 1827 } 1828 /* 1829 * We now have a partition map. Make it the current map. 1830 */ 1831 cur_disk->disk_parts = cur_parts = parts; 1832 exit_critical(); 1833 /* 1834 * Rewrite the labels and defect lists, as appropriate. 1835 */ 1836 if (EMBEDDED_SCSI) { 1837 fmt_print("Restoring primary label.\n"); 1838 if (write_label()) 1839 return (-1); 1840 } else { 1841 fmt_print("Restoring primary label and defect list.\n"); 1842 if (write_label()) 1843 return (-1); 1844 if (cur_list.list != NULL) 1845 write_deflist(&cur_list); 1846 } 1847 fmt_print("\n"); 1848 return (0); 1849 } 1850 /* 1851 * If we didn't find any backup labels, say so. 1852 */ 1853 fmt_print("not found.\n\n"); 1854 return (0); 1855 } 1856 1857 /* 1858 * This routine is called by c_verify() for an EFI labeled disk 1859 */ 1860 static int 1861 c_verify_efi() 1862 { 1863 struct efi_info efi_info; 1864 struct partition_info tmp_pinfo; 1865 int status; 1866 1867 status = read_efi_label(cur_file, &efi_info); 1868 if (status != 0) { 1869 err_print("Warning: Could not read label.\n"); 1870 return (-1); 1871 } 1872 if (cur_parts->etoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) { 1873 err_print("Reading the primary EFI GPT label "); 1874 err_print("failed. Using backup label.\n"); 1875 err_print("Use the 'backup' command to restore "); 1876 err_print("the primary label.\n"); 1877 } 1878 tmp_pinfo.etoc = efi_info.e_parts; 1879 fmt_print("\n"); 1880 if (cur_parts->etoc->efi_parts[8].p_name) { 1881 fmt_print("Volume name = <%8s>\n", 1882 cur_parts->etoc->efi_parts[8].p_name); 1883 } else { 1884 fmt_print("Volume name = < >\n"); 1885 } 1886 fmt_print("ascii name = "); 1887 print_efi_string(efi_info.vendor, efi_info.product, 1888 efi_info.revision, efi_info.capacity); 1889 fmt_print("\n"); 1890 1891 fmt_print("bytes/sector = %d\n", DEV_BSIZE); 1892 fmt_print("sectors = %llu\n", cur_parts->etoc->efi_last_lba); 1893 fmt_print("accessible sectors = %llu\n", 1894 cur_parts->etoc->efi_last_u_lba); 1895 1896 print_map(&tmp_pinfo); 1897 return (0); 1898 } 1899 1900 /* 1901 * This routine implements the 'verify' command. It allows the user 1902 * to read the labels on the current disk. 1903 */ 1904 int 1905 c_verify() 1906 { 1907 struct dk_label p_label, b_label, *label; 1908 struct partition_info tmp_pinfo; 1909 daddr_t bn; 1910 int sec, head, i, status; 1911 int p_label_bad = 0; 1912 int b_label_bad = 0; 1913 int p_label_found = 0; 1914 int b_label_found = 0; 1915 char id_str[128]; 1916 1917 /* 1918 * There must be a current disk type (and therefore a current disk). 1919 */ 1920 if (cur_dtype == NULL) { 1921 err_print("Current Disk Type is not set.\n"); 1922 return (-1); 1923 } 1924 /* 1925 * The disk must be formatted to read labels. 1926 */ 1927 if (!(cur_flags & DISK_FORMATTED)) { 1928 err_print("Current Disk is unformatted.\n"); 1929 return (-1); 1930 } 1931 /* 1932 * Check for a valid fdisk table entry for Solaris 1933 */ 1934 if (!good_fdisk()) { 1935 err_print("Please run fdisk first.\n"); 1936 return (-1); 1937 } 1938 /* 1939 * Branch off here if the disk is EFI labelled. 1940 */ 1941 if (cur_label == L_TYPE_EFI) { 1942 return (c_verify_efi()); 1943 } 1944 /* 1945 * Attempt to read the primary label. 1946 */ 1947 status = read_label(cur_file, &p_label); 1948 if (status == -1) { 1949 err_print("Warning: Could not read primary label.\n"); 1950 p_label_bad = 1; 1951 } else { 1952 /* 1953 * Verify that it is a reasonable label. 1954 */ 1955 /* 1956 * Save complete ascii string for printing later. 1957 */ 1958 (void) strncpy(id_str, p_label.dkl_asciilabel, 128); 1959 1960 if ((!checklabel((struct dk_label *)&p_label)) || 1961 (trim_id(p_label.dkl_asciilabel))) { 1962 err_print("\ 1963 Warning: Primary label appears to be corrupt.\n"); 1964 p_label_bad = 1; 1965 } else { 1966 p_label_found = 1; 1967 /* 1968 * Make sure it matches current label 1969 */ 1970 if ((!dtype_match(&p_label, cur_dtype)) || 1971 (!parts_match(&p_label, cur_parts))) { 1972 err_print("\ 1973 Warning: Primary label on disk appears to be different from\ncurrent label.\n"); 1974 p_label_bad = 1; 1975 } 1976 } 1977 } 1978 1979 /* 1980 * Read backup labels. 1981 * Some disks have the backup labels in a strange place. 1982 */ 1983 if (cur_ctype->ctype_flags & CF_BLABEL) 1984 head = 2; 1985 else 1986 head = nhead - 1; 1987 /* 1988 * Loop through each copy of the backup label. 1989 */ 1990 for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect)); 1991 sec += 2) { 1992 bn = chs2bn(ncyl + acyl - 1, head, sec) + solaris_offset; 1993 /* 1994 * Attempt to read it. 1995 */ 1996 if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, (diskaddr_t)bn, 1997 1, (char *)&b_label, F_NORMAL, NULL)) 1998 continue; 1999 /* 2000 * Verify that it is a reasonable label. 2001 */ 2002 if (!checklabel(&b_label)) 2003 continue; 2004 2005 /* 2006 * Save complete label only if no primary label exists 2007 */ 2008 if (!p_label_found) 2009 (void) strncpy(id_str, b_label.dkl_asciilabel, 128); 2010 2011 if (trim_id(b_label.dkl_asciilabel)) 2012 continue; 2013 b_label_found = 1; 2014 /* 2015 * Compare against primary label 2016 */ 2017 if (p_label_found) { 2018 if ((strcmp(b_label.dkl_asciilabel, 2019 p_label.dkl_asciilabel) != 0) || 2020 (b_label.dkl_ncyl != p_label.dkl_ncyl) || 2021 (b_label.dkl_acyl != p_label.dkl_acyl) || 2022 (b_label.dkl_nhead != p_label.dkl_nhead) || 2023 (b_label.dkl_nsect != p_label.dkl_nsect)) { 2024 b_label_bad = 1; 2025 } else { 2026 for (i = 0; i < NDKMAP; i++) { 2027 #if defined(_SUNOS_VTOC_8) 2028 if ((b_label.dkl_map[i].dkl_cylno != 2029 p_label.dkl_map[i].dkl_cylno) || 2030 (b_label.dkl_map[i].dkl_nblk != 2031 p_label.dkl_map[i].dkl_nblk)) { 2032 b_label_bad = 1; 2033 break; 2034 } 2035 2036 #elif defined(_SUNOS_VTOC_16) 2037 if ((b_label.dkl_vtoc.v_part[i].p_tag != 2038 p_label.dkl_vtoc.v_part[i].p_tag) || 2039 (b_label.dkl_vtoc.v_part[i].p_flag != 2040 p_label.dkl_vtoc.v_part[i].p_flag) || 2041 (b_label.dkl_vtoc.v_part[i].p_start != 2042 p_label.dkl_vtoc.v_part[i].p_start) || 2043 (b_label.dkl_vtoc.v_part[i].p_size != 2044 p_label.dkl_vtoc.v_part[i].p_size)) { 2045 b_label_bad = 1; 2046 break; 2047 } 2048 #else 2049 #error No VTOC layout defined. 2050 #endif /* defined(_SUNOS_VTOC_8) */ 2051 } 2052 } 2053 } 2054 if (b_label_bad) 2055 err_print( 2056 "Warning: Primary and backup labels do not match.\n"); 2057 break; 2058 } 2059 /* 2060 * If we didn't find any backup labels, say so. 2061 */ 2062 if (!b_label_found) 2063 err_print("Warning: Could not read backup labels.\n"); 2064 2065 if ((!b_label_found) || (p_label_bad) || (b_label_bad)) 2066 err_print("\n\ 2067 Warning: Check the current partitioning and 'label' the disk or use the\n\ 2068 \t 'backup' command.\n"); 2069 2070 /* 2071 * Print label information. 2072 */ 2073 if (p_label_found) { 2074 fmt_print("\nPrimary label contents:\n"); 2075 label = &p_label; 2076 } else if (b_label_found) { 2077 fmt_print("\nBackup label contents:\n"); 2078 label = &b_label; 2079 } else { 2080 return (0); 2081 } 2082 2083 /* 2084 * Must put info into partition_info struct for 2085 * for print routine. 2086 */ 2087 bzero(&tmp_pinfo, sizeof (struct partition_info)); 2088 for (i = 0; i < NDKMAP; i++) { 2089 2090 #if defined(_SUNOS_VTOC_8) 2091 tmp_pinfo.pinfo_map[i] = label->dkl_map[i]; 2092 2093 #elif defined(_SUNOS_VTOC_16) 2094 tmp_pinfo.pinfo_map[i].dkl_cylno = 2095 label->dkl_vtoc.v_part[i].p_start / spc(); 2096 tmp_pinfo.pinfo_map[i].dkl_nblk = 2097 label->dkl_vtoc.v_part[i].p_size; 2098 #else 2099 #error No VTOC layout defined. 2100 #endif /* defined(_SUNOS_VTOC_8) */ 2101 } 2102 tmp_pinfo.vtoc = label->dkl_vtoc; 2103 2104 fmt_print("\n"); 2105 fmt_print("Volume name = <%8s>\n", label->dkl_vtoc.v_volume); 2106 fmt_print("ascii name = <%s>\n", id_str); 2107 fmt_print("pcyl = %4d\n", label->dkl_pcyl); 2108 fmt_print("ncyl = %4d\n", label->dkl_ncyl); 2109 fmt_print("acyl = %4d\n", label->dkl_acyl); 2110 2111 #if defined(_SUNOS_VTOC_16) 2112 fmt_print("bcyl = %4d\n", label->dkl_bcyl); 2113 #endif /* defined(_SUNOS_VTOC_16) */ 2114 2115 fmt_print("nhead = %4d\n", label->dkl_nhead); 2116 fmt_print("nsect = %4d\n", label->dkl_nsect); 2117 2118 print_map(&tmp_pinfo); 2119 return (0); 2120 } 2121 2122 2123 /* 2124 * This command implements the inquiry command, for embedded SCSI 2125 * disks only, which issues a SCSI inquiry command, and 2126 * displays the resulting vendor, product id and revision level. 2127 */ 2128 int 2129 c_inquiry() 2130 { 2131 char inqbuf[255]; 2132 struct scsi_inquiry *inq; 2133 2134 assert(SCSI); 2135 2136 inq = (struct scsi_inquiry *)inqbuf; 2137 2138 if (uscsi_inquiry(cur_file, inqbuf, sizeof (inqbuf))) { 2139 err_print("Failed\n"); 2140 return (-1); 2141 } else { 2142 fmt_print("Vendor: "); 2143 print_buf(inq->inq_vid, sizeof (inq->inq_vid)); 2144 fmt_print("\nProduct: "); 2145 print_buf(inq->inq_pid, sizeof (inq->inq_pid)); 2146 fmt_print("\nRevision: "); 2147 print_buf(inq->inq_revision, sizeof (inq->inq_revision)); 2148 fmt_print("\n"); 2149 } 2150 2151 return (0); 2152 } 2153 2154 2155 /* 2156 * This routine allows the user to set the 8-character 2157 * volume name in the vtoc. It then writes both the 2158 * primary and backup labels onto the current disk. 2159 */ 2160 int 2161 c_volname() 2162 { 2163 int status; 2164 char *prompt; 2165 union { 2166 int xfoo; 2167 char defvolname[LEN_DKL_VVOL+1]; 2168 } x; 2169 char s1[MAXPATHLEN], nclean[MAXPATHLEN]; 2170 char *volname; 2171 2172 2173 /* 2174 * There must be a current disk type (and therefore a current disk). 2175 */ 2176 if (cur_dtype == NULL) { 2177 err_print("Current Disk Type is not set.\n"); 2178 return (-1); 2179 } 2180 /* 2181 * The current disk must be formatted to label it. 2182 */ 2183 if (!(cur_flags & DISK_FORMATTED)) { 2184 err_print("Current Disk is unformatted.\n"); 2185 return (-1); 2186 } 2187 /* 2188 * Check for a valid fdisk table entry for Solaris 2189 */ 2190 if (!good_fdisk()) { 2191 err_print("Please run fdisk first.\n"); 2192 return (-1); 2193 } 2194 /* 2195 * The current disk must be formatted to label it. 2196 */ 2197 if (cur_parts == NULL) { 2198 err_print( 2199 "Please select a partition map for the disk first.\n"); 2200 return (-1); 2201 } 2202 /* 2203 * Check to see if there are any mounted file systems anywhere 2204 * on the current disk. If so, refuse to label the disk, but 2205 * only if the partitions would change for the mounted partitions. 2206 * 2207 */ 2208 if (checkmount((daddr_t)-1, (daddr_t)-1)) { 2209 /* Bleagh, too descriptive */ 2210 if (check_label_with_mount()) { 2211 err_print( 2212 "Cannot label disk while it has mounted partitions.\n\n"); 2213 return (-1); 2214 } 2215 } 2216 /* 2217 * Check to see if there are partitions being used for swapping 2218 * on the current disk. If so, refuse to label the disk, but 2219 * only if the partitions would change for the swap partitions. 2220 * 2221 */ 2222 if (checkswap((daddr_t)-1, (daddr_t)-1)) { 2223 /* Bleagh, too descriptive */ 2224 if (check_label_with_swap()) { 2225 err_print( 2226 "Cannot label disk while its partitions are currently \ 2227 being used for swapping.\n\n"); 2228 return (-1); 2229 } 2230 } 2231 /* 2232 * Prompt for the disk volume name. 2233 */ 2234 prompt = "Enter 8-character volume name (remember quotes)"; 2235 bzero(x.defvolname, LEN_DKL_VVOL+1); 2236 bcopy(cur_disk->v_volume, x.defvolname, LEN_DKL_VVOL); 2237 /* 2238 * Get the input using "get_inputline" since 2239 * input would never return null string. 2240 */ 2241 fmt_print("%s[\"%s\"]:", prompt, x.defvolname); 2242 2243 /* 2244 * Get input from the user. 2245 */ 2246 get_inputline(nclean, MAXPATHLEN); 2247 clean_token(s1, nclean); 2248 /* 2249 * check for return. 2250 */ 2251 if (s1[0] == 0) { 2252 volname = x.defvolname; 2253 } else { 2254 /* 2255 * remove the " mark from volname. 2256 */ 2257 if (s1[0] == '"') { 2258 int i = 1; 2259 volname = &s1[1]; 2260 while (s1[i] != '"' && s1[i] != '\0') 2261 i++; 2262 s1[i] = '\0'; 2263 clean_token(nclean, volname); 2264 volname = nclean; 2265 } else { 2266 (void) sscanf(&s1[0], "%1024s", nclean); 2267 volname = nclean; 2268 }; 2269 } 2270 /* 2271 * Make sure the user is serious. 2272 */ 2273 if (check("Ready to label disk, continue")) { 2274 fmt_print("\n"); 2275 return (-1); 2276 } 2277 /* 2278 * Use the volume name chosen above 2279 */ 2280 bzero(cur_disk->v_volume, LEN_DKL_VVOL); 2281 bcopy(volname, cur_disk->v_volume, min((int)strlen(volname), 2282 LEN_DKL_VVOL)); 2283 if (cur_label == L_TYPE_EFI) { 2284 bzero(cur_parts->etoc->efi_parts[8].p_name, LEN_DKL_VVOL); 2285 bcopy(volname, cur_parts->etoc->efi_parts[8].p_name, 2286 LEN_DKL_VVOL); 2287 } 2288 /* 2289 * Write the labels out (this will also notify unix) and 2290 * return status. 2291 */ 2292 fmt_print("\n"); 2293 if (status = write_label()) 2294 err_print("Label failed.\n"); 2295 return (status); 2296 } 2297