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