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