1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 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 #include <assert.h> 30 #include <ctype.h> 31 #include <dirent.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <libgen.h> 35 #include <libintl.h> 36 #include <libuutil.h> 37 #include <locale.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <strings.h> 42 #include <unistd.h> 43 #include <priv.h> 44 45 #include <sys/stat.h> 46 47 #include <libzfs.h> 48 49 #include "zpool_util.h" 50 51 static int zpool_do_create(int, char **); 52 static int zpool_do_destroy(int, char **); 53 54 static int zpool_do_add(int, char **); 55 static int zpool_do_remove(int, char **); 56 57 static int zpool_do_list(int, char **); 58 static int zpool_do_iostat(int, char **); 59 static int zpool_do_status(int, char **); 60 61 static int zpool_do_online(int, char **); 62 static int zpool_do_offline(int, char **); 63 static int zpool_do_clear(int, char **); 64 65 static int zpool_do_attach(int, char **); 66 static int zpool_do_detach(int, char **); 67 static int zpool_do_replace(int, char **); 68 69 static int zpool_do_scrub(int, char **); 70 71 static int zpool_do_import(int, char **); 72 static int zpool_do_export(int, char **); 73 74 static int zpool_do_upgrade(int, char **); 75 76 /* 77 * These libumem hooks provide a reasonable set of defaults for the allocator's 78 * debugging facilities. 79 */ 80 const char * 81 _umem_debug_init(void) 82 { 83 return ("default,verbose"); /* $UMEM_DEBUG setting */ 84 } 85 86 const char * 87 _umem_logging_init(void) 88 { 89 return ("fail,contents"); /* $UMEM_LOGGING setting */ 90 } 91 92 typedef enum { 93 HELP_ADD, 94 HELP_ATTACH, 95 HELP_CLEAR, 96 HELP_CREATE, 97 HELP_DESTROY, 98 HELP_DETACH, 99 HELP_EXPORT, 100 HELP_IMPORT, 101 HELP_IOSTAT, 102 HELP_LIST, 103 HELP_OFFLINE, 104 HELP_ONLINE, 105 HELP_REPLACE, 106 HELP_REMOVE, 107 HELP_SCRUB, 108 HELP_STATUS, 109 HELP_UPGRADE 110 } zpool_help_t; 111 112 113 typedef struct zpool_command { 114 const char *name; 115 int (*func)(int, char **); 116 zpool_help_t usage; 117 } zpool_command_t; 118 119 /* 120 * Master command table. Each ZFS command has a name, associated function, and 121 * usage message. The usage messages need to be internationalized, so we have 122 * to have a function to return the usage message based on a command index. 123 * 124 * These commands are organized according to how they are displayed in the usage 125 * message. An empty command (one with a NULL name) indicates an empty line in 126 * the generic usage message. 127 */ 128 static zpool_command_t command_table[] = { 129 { "create", zpool_do_create, HELP_CREATE }, 130 { "destroy", zpool_do_destroy, HELP_DESTROY }, 131 { NULL }, 132 { "add", zpool_do_add, HELP_ADD }, 133 { "remove", zpool_do_remove, HELP_REMOVE }, 134 { NULL }, 135 { "list", zpool_do_list, HELP_LIST }, 136 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 137 { "status", zpool_do_status, HELP_STATUS }, 138 { NULL }, 139 { "online", zpool_do_online, HELP_ONLINE }, 140 { "offline", zpool_do_offline, HELP_OFFLINE }, 141 { "clear", zpool_do_clear, HELP_CLEAR }, 142 { NULL }, 143 { "attach", zpool_do_attach, HELP_ATTACH }, 144 { "detach", zpool_do_detach, HELP_DETACH }, 145 { "replace", zpool_do_replace, HELP_REPLACE }, 146 { NULL }, 147 { "scrub", zpool_do_scrub, HELP_SCRUB }, 148 { NULL }, 149 { "import", zpool_do_import, HELP_IMPORT }, 150 { "export", zpool_do_export, HELP_EXPORT }, 151 { "upgrade", zpool_do_upgrade, HELP_UPGRADE } 152 }; 153 154 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) 155 156 zpool_command_t *current_command; 157 158 static const char * 159 get_usage(zpool_help_t idx) { 160 switch (idx) { 161 case HELP_ADD: 162 return (gettext("\tadd [-fn] <pool> <vdev> ...\n")); 163 case HELP_ATTACH: 164 return (gettext("\tattach [-f] <pool> <device> " 165 "<new_device>\n")); 166 case HELP_CLEAR: 167 return (gettext("\tclear <pool> [device]\n")); 168 case HELP_CREATE: 169 return (gettext("\tcreate [-fn] [-R root] [-m mountpoint] " 170 "<pool> <vdev> ...\n")); 171 case HELP_DESTROY: 172 return (gettext("\tdestroy [-f] <pool>\n")); 173 case HELP_DETACH: 174 return (gettext("\tdetach <pool> <device>\n")); 175 case HELP_EXPORT: 176 return (gettext("\texport [-f] <pool> ...\n")); 177 case HELP_IMPORT: 178 return (gettext("\timport [-d dir] [-D]\n" 179 "\timport [-d dir] [-D] [-f] [-o opts] [-R root] -a\n" 180 "\timport [-d dir] [-D] [-f] [-o opts] [-R root ]" 181 " <pool | id> [newpool]\n")); 182 case HELP_IOSTAT: 183 return (gettext("\tiostat [-v] [pool] ... [interval " 184 "[count]]\n")); 185 case HELP_LIST: 186 return (gettext("\tlist [-H] [-o field[,field]*] " 187 "[pool] ...\n")); 188 case HELP_OFFLINE: 189 return (gettext("\toffline [-t] <pool> <device> ...\n")); 190 case HELP_ONLINE: 191 return (gettext("\tonline <pool> <device> ...\n")); 192 case HELP_REPLACE: 193 return (gettext("\treplace [-f] <pool> <device> " 194 "[new_device]\n")); 195 case HELP_REMOVE: 196 return (gettext("\tremove <pool> <device>\n")); 197 case HELP_SCRUB: 198 return (gettext("\tscrub [-s] <pool> ...\n")); 199 case HELP_STATUS: 200 return (gettext("\tstatus [-vx] [pool] ...\n")); 201 case HELP_UPGRADE: 202 return (gettext("\tupgrade\n" 203 "\tupgrade -v\n" 204 "\tupgrade <-a | pool>\n")); 205 } 206 207 abort(); 208 /* NOTREACHED */ 209 } 210 211 /* 212 * Fields available for 'zpool list'. 213 */ 214 typedef enum { 215 ZPOOL_FIELD_NAME, 216 ZPOOL_FIELD_SIZE, 217 ZPOOL_FIELD_USED, 218 ZPOOL_FIELD_AVAILABLE, 219 ZPOOL_FIELD_CAPACITY, 220 ZPOOL_FIELD_HEALTH, 221 ZPOOL_FIELD_ROOT 222 } zpool_field_t; 223 224 #define MAX_FIELDS 10 225 226 typedef struct column_def { 227 const char *cd_title; 228 size_t cd_width; 229 enum { 230 left_justify, 231 right_justify 232 } cd_justify; 233 } column_def_t; 234 235 static column_def_t column_table[] = { 236 { "NAME", 20, left_justify }, 237 { "SIZE", 6, right_justify }, 238 { "USED", 6, right_justify }, 239 { "AVAIL", 6, right_justify }, 240 { "CAP", 5, right_justify }, 241 { "HEALTH", 9, left_justify }, 242 { "ALTROOT", 15, left_justify } 243 }; 244 245 static char *column_subopts[] = { 246 "name", 247 "size", 248 "used", 249 "available", 250 "capacity", 251 "health", 252 "root", 253 NULL 254 }; 255 256 /* 257 * Display usage message. If we're inside a command, display only the usage for 258 * that command. Otherwise, iterate over the entire command table and display 259 * a complete usage message. 260 */ 261 void 262 usage(boolean_t requested) 263 { 264 int i; 265 FILE *fp = requested ? stdout : stderr; 266 267 if (current_command == NULL) { 268 int i; 269 270 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 271 (void) fprintf(fp, 272 gettext("where 'command' is one of the following:\n\n")); 273 274 for (i = 0; i < NCOMMAND; i++) { 275 if (command_table[i].name == NULL) 276 (void) fprintf(fp, "\n"); 277 else 278 (void) fprintf(fp, "%s", 279 get_usage(command_table[i].usage)); 280 } 281 } else { 282 (void) fprintf(fp, gettext("usage:\n")); 283 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 284 285 if (strcmp(current_command->name, "list") == 0) { 286 (void) fprintf(fp, gettext("\nwhere 'field' is one " 287 "of the following:\n\n")); 288 289 for (i = 0; column_subopts[i] != NULL; i++) 290 (void) fprintf(fp, "\t%s\n", column_subopts[i]); 291 } 292 } 293 294 /* 295 * See comments at end of main(). 296 */ 297 if (getenv("ZFS_ABORT") != NULL) { 298 (void) printf("dumping core by request\n"); 299 abort(); 300 } 301 302 exit(requested ? 0 : 2); 303 } 304 305 const char * 306 state_to_name(vdev_stat_t *vs) 307 { 308 switch (vs->vs_state) { 309 case VDEV_STATE_CLOSED: 310 case VDEV_STATE_CANT_OPEN: 311 if (vs->vs_aux == VDEV_AUX_CORRUPT_DATA) 312 return (gettext("FAULTED")); 313 else 314 return (gettext("UNAVAIL")); 315 case VDEV_STATE_OFFLINE: 316 return (gettext("OFFLINE")); 317 case VDEV_STATE_DEGRADED: 318 return (gettext("DEGRADED")); 319 case VDEV_STATE_HEALTHY: 320 return (gettext("ONLINE")); 321 } 322 323 return (gettext("UNKNOWN")); 324 } 325 326 void 327 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent) 328 { 329 nvlist_t **child; 330 uint_t c, children; 331 char *vname; 332 333 if (name != NULL) 334 (void) printf("\t%*s%s\n", indent, "", name); 335 336 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 337 &child, &children) != 0) 338 return; 339 340 for (c = 0; c < children; c++) { 341 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 342 print_vdev_tree(zhp, vname, child[c], indent + 2); 343 free(vname); 344 } 345 } 346 347 /* 348 * zpool add [-fn] <pool> <vdev> ... 349 * 350 * -f Force addition of devices, even if they appear in use 351 * -n Do not add the devices, but display the resulting layout if 352 * they were to be added. 353 * 354 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 355 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to 356 * libzfs. 357 */ 358 int 359 zpool_do_add(int argc, char **argv) 360 { 361 boolean_t force = B_FALSE; 362 boolean_t dryrun = B_FALSE; 363 int c; 364 nvlist_t *nvroot; 365 char *poolname; 366 int ret; 367 zpool_handle_t *zhp; 368 nvlist_t *config; 369 370 /* check options */ 371 while ((c = getopt(argc, argv, "fn")) != -1) { 372 switch (c) { 373 case 'f': 374 force = B_TRUE; 375 break; 376 case 'n': 377 dryrun = B_TRUE; 378 break; 379 case '?': 380 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 381 optopt); 382 usage(B_FALSE); 383 } 384 } 385 386 argc -= optind; 387 argv += optind; 388 389 /* get pool name and check number of arguments */ 390 if (argc < 1) { 391 (void) fprintf(stderr, gettext("missing pool name argument\n")); 392 usage(B_FALSE); 393 } 394 if (argc < 2) { 395 (void) fprintf(stderr, gettext("missing vdev specification\n")); 396 usage(B_FALSE); 397 } 398 399 poolname = argv[0]; 400 401 argc--; 402 argv++; 403 404 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 405 return (1); 406 407 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 408 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 409 poolname); 410 zpool_close(zhp); 411 return (1); 412 } 413 414 /* pass off to get_vdev_spec for processing */ 415 nvroot = make_root_vdev(config, force, !force, B_FALSE, argc, argv); 416 if (nvroot == NULL) { 417 zpool_close(zhp); 418 return (1); 419 } 420 421 if (dryrun) { 422 nvlist_t *poolnvroot; 423 424 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 425 &poolnvroot) == 0); 426 427 (void) printf(gettext("would update '%s' to the following " 428 "configuration:\n"), zpool_get_name(zhp)); 429 430 print_vdev_tree(zhp, poolname, poolnvroot, 0); 431 print_vdev_tree(zhp, NULL, nvroot, 0); 432 433 ret = 0; 434 } else { 435 ret = (zpool_add(zhp, nvroot) != 0); 436 } 437 438 nvlist_free(nvroot); 439 zpool_close(zhp); 440 441 return (ret); 442 } 443 444 /* 445 * zpool remove <pool> <vdev> 446 * 447 * Removes the given vdev from the pool. Currently, this only supports removing 448 * spares from the pool. Eventually, we'll want to support removing leaf vdevs 449 * (as an alias for 'detach') as well as toplevel vdevs. 450 */ 451 int 452 zpool_do_remove(int argc, char **argv) 453 { 454 char *poolname; 455 int ret; 456 zpool_handle_t *zhp; 457 458 argc--; 459 argv++; 460 461 /* get pool name and check number of arguments */ 462 if (argc < 1) { 463 (void) fprintf(stderr, gettext("missing pool name argument\n")); 464 usage(B_FALSE); 465 } 466 if (argc < 2) { 467 (void) fprintf(stderr, gettext("missing device\n")); 468 usage(B_FALSE); 469 } 470 471 poolname = argv[0]; 472 473 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 474 return (1); 475 476 ret = (zpool_vdev_remove(zhp, argv[1]) != 0); 477 478 return (ret); 479 } 480 481 /* 482 * zpool create [-fn] [-R root] [-m mountpoint] <pool> <dev> ... 483 * 484 * -f Force creation, even if devices appear in use 485 * -n Do not create the pool, but display the resulting layout if it 486 * were to be created. 487 * -R Create a pool under an alternate root 488 * -m Set default mountpoint for the root dataset. By default it's 489 * '/<pool>' 490 * 491 * Creates the the named pool according to the given vdev specification. The 492 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once 493 * we get the nvlist back from get_vdev_spec(), we either print out the contents 494 * (if '-n' was specified), or pass it to libzfs to do the creation. 495 */ 496 int 497 zpool_do_create(int argc, char **argv) 498 { 499 boolean_t force = B_FALSE; 500 boolean_t dryrun = B_FALSE; 501 int c; 502 nvlist_t *nvroot; 503 char *poolname; 504 int ret; 505 char *altroot = NULL; 506 char *mountpoint = NULL; 507 nvlist_t **child; 508 uint_t children; 509 510 /* check options */ 511 while ((c = getopt(argc, argv, ":fnR:m:")) != -1) { 512 switch (c) { 513 case 'f': 514 force = B_TRUE; 515 break; 516 case 'n': 517 dryrun = B_TRUE; 518 break; 519 case 'R': 520 altroot = optarg; 521 break; 522 case 'm': 523 mountpoint = optarg; 524 break; 525 case ':': 526 (void) fprintf(stderr, gettext("missing argument for " 527 "'%c' option\n"), optopt); 528 usage(B_FALSE); 529 break; 530 case '?': 531 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 532 optopt); 533 usage(B_FALSE); 534 } 535 } 536 537 argc -= optind; 538 argv += optind; 539 540 /* get pool name and check number of arguments */ 541 if (argc < 1) { 542 (void) fprintf(stderr, gettext("missing pool name argument\n")); 543 usage(B_FALSE); 544 } 545 if (argc < 2) { 546 (void) fprintf(stderr, gettext("missing vdev specification\n")); 547 usage(B_FALSE); 548 } 549 550 poolname = argv[0]; 551 552 /* 553 * As a special case, check for use of '/' in the name, and direct the 554 * user to use 'zfs create' instead. 555 */ 556 if (strchr(poolname, '/') != NULL) { 557 (void) fprintf(stderr, gettext("cannot create '%s': invalid " 558 "character '/' in pool name\n"), poolname); 559 (void) fprintf(stderr, gettext("use 'zfs create' to " 560 "create a dataset\n")); 561 return (1); 562 } 563 564 /* pass off to get_vdev_spec for bulk processing */ 565 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1, 566 argv + 1); 567 if (nvroot == NULL) 568 return (1); 569 570 /* make_root_vdev() allows 0 toplevel children if there are spares */ 571 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 572 &child, &children) == 0); 573 if (children == 0) { 574 (void) fprintf(stderr, gettext("invalid vdev " 575 "specification: at least one toplevel vdev must be " 576 "specified\n")); 577 return (1); 578 } 579 580 581 if (altroot != NULL && altroot[0] != '/') { 582 (void) fprintf(stderr, gettext("invalid alternate root '%s': " 583 "must be an absolute path\n"), altroot); 584 nvlist_free(nvroot); 585 return (1); 586 } 587 588 /* 589 * Check the validity of the mountpoint and direct the user to use the 590 * '-m' mountpoint option if it looks like its in use. 591 */ 592 if (mountpoint == NULL || 593 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && 594 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { 595 char buf[MAXPATHLEN]; 596 struct stat64 statbuf; 597 598 if (mountpoint && mountpoint[0] != '/') { 599 (void) fprintf(stderr, gettext("invalid mountpoint " 600 "'%s': must be an absolute path, 'legacy', or " 601 "'none'\n"), mountpoint); 602 nvlist_free(nvroot); 603 return (1); 604 } 605 606 if (mountpoint == NULL) { 607 if (altroot != NULL) 608 (void) snprintf(buf, sizeof (buf), "%s/%s", 609 altroot, poolname); 610 else 611 (void) snprintf(buf, sizeof (buf), "/%s", 612 poolname); 613 } else { 614 if (altroot != NULL) 615 (void) snprintf(buf, sizeof (buf), "%s%s", 616 altroot, mountpoint); 617 else 618 (void) snprintf(buf, sizeof (buf), "%s", 619 mountpoint); 620 } 621 622 if (stat64(buf, &statbuf) == 0 && 623 statbuf.st_nlink != 2) { 624 if (mountpoint == NULL) 625 (void) fprintf(stderr, gettext("default " 626 "mountpoint '%s' exists and is not " 627 "empty\n"), buf); 628 else 629 (void) fprintf(stderr, gettext("mountpoint " 630 "'%s' exists and is not empty\n"), buf); 631 (void) fprintf(stderr, gettext("use '-m' " 632 "option to provide a different default\n")); 633 nvlist_free(nvroot); 634 return (1); 635 } 636 } 637 638 639 if (dryrun) { 640 /* 641 * For a dry run invocation, print out a basic message and run 642 * through all the vdevs in the list and print out in an 643 * appropriate hierarchy. 644 */ 645 (void) printf(gettext("would create '%s' with the " 646 "following layout:\n\n"), poolname); 647 648 print_vdev_tree(NULL, poolname, nvroot, 0); 649 650 ret = 0; 651 } else { 652 ret = 1; 653 /* 654 * Hand off to libzfs. 655 */ 656 if (zpool_create(g_zfs, poolname, nvroot, altroot) == 0) { 657 zfs_handle_t *pool = zfs_open(g_zfs, poolname, 658 ZFS_TYPE_FILESYSTEM); 659 if (pool != NULL) { 660 if (mountpoint != NULL) 661 verify(zfs_prop_set(pool, 662 zfs_prop_to_name( 663 ZFS_PROP_MOUNTPOINT), 664 mountpoint) == 0); 665 if (zfs_mount(pool, NULL, 0) == 0) 666 ret = zfs_share(pool); 667 zfs_close(pool); 668 } 669 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { 670 (void) fprintf(stderr, gettext("pool name may have " 671 "been omitted\n")); 672 } 673 } 674 675 nvlist_free(nvroot); 676 677 return (ret); 678 } 679 680 /* 681 * zpool destroy <pool> 682 * 683 * -f Forcefully unmount any datasets 684 * 685 * Destroy the given pool. Automatically unmounts any datasets in the pool. 686 */ 687 int 688 zpool_do_destroy(int argc, char **argv) 689 { 690 boolean_t force = B_FALSE; 691 int c; 692 char *pool; 693 zpool_handle_t *zhp; 694 int ret; 695 696 /* check options */ 697 while ((c = getopt(argc, argv, "f")) != -1) { 698 switch (c) { 699 case 'f': 700 force = B_TRUE; 701 break; 702 case '?': 703 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 704 optopt); 705 usage(B_FALSE); 706 } 707 } 708 709 argc -= optind; 710 argv += optind; 711 712 /* check arguments */ 713 if (argc < 1) { 714 (void) fprintf(stderr, gettext("missing pool argument\n")); 715 usage(B_FALSE); 716 } 717 if (argc > 1) { 718 (void) fprintf(stderr, gettext("too many arguments\n")); 719 usage(B_FALSE); 720 } 721 722 pool = argv[0]; 723 724 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 725 /* 726 * As a special case, check for use of '/' in the name, and 727 * direct the user to use 'zfs destroy' instead. 728 */ 729 if (strchr(pool, '/') != NULL) 730 (void) fprintf(stderr, gettext("use 'zfs destroy' to " 731 "destroy a dataset\n")); 732 return (1); 733 } 734 735 if (zpool_unmount_datasets(zhp, force) != 0) { 736 (void) fprintf(stderr, gettext("could not destroy '%s': " 737 "could not unmount datasets\n"), zpool_get_name(zhp)); 738 return (1); 739 } 740 741 ret = (zpool_destroy(zhp) != 0); 742 743 zpool_close(zhp); 744 745 return (ret); 746 } 747 748 /* 749 * zpool export [-f] <pool> ... 750 * 751 * -f Forcefully unmount datasets 752 * 753 * Export the the given pools. By default, the command will attempt to cleanly 754 * unmount any active datasets within the pool. If the '-f' flag is specified, 755 * then the datasets will be forcefully unmounted. 756 */ 757 int 758 zpool_do_export(int argc, char **argv) 759 { 760 boolean_t force = B_FALSE; 761 int c; 762 zpool_handle_t *zhp; 763 int ret; 764 int i; 765 766 /* check options */ 767 while ((c = getopt(argc, argv, "f")) != -1) { 768 switch (c) { 769 case 'f': 770 force = B_TRUE; 771 break; 772 case '?': 773 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 774 optopt); 775 usage(B_FALSE); 776 } 777 } 778 779 argc -= optind; 780 argv += optind; 781 782 /* check arguments */ 783 if (argc < 1) { 784 (void) fprintf(stderr, gettext("missing pool argument\n")); 785 usage(B_FALSE); 786 } 787 788 ret = 0; 789 for (i = 0; i < argc; i++) { 790 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) { 791 ret = 1; 792 continue; 793 } 794 795 if (zpool_unmount_datasets(zhp, force) != 0) { 796 ret = 1; 797 zpool_close(zhp); 798 continue; 799 } 800 801 if (zpool_export(zhp) != 0) 802 ret = 1; 803 804 zpool_close(zhp); 805 } 806 807 return (ret); 808 } 809 810 /* 811 * Given a vdev configuration, determine the maximum width needed for the device 812 * name column. 813 */ 814 static int 815 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max) 816 { 817 char *name = zpool_vdev_name(g_zfs, zhp, nv); 818 nvlist_t **child; 819 uint_t c, children; 820 int ret; 821 822 if (strlen(name) + depth > max) 823 max = strlen(name) + depth; 824 825 free(name); 826 827 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 828 &child, &children) == 0) { 829 for (c = 0; c < children; c++) 830 if ((ret = max_width(zhp, child[c], depth + 2, 831 max)) > max) 832 max = ret; 833 } 834 835 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 836 &child, &children) == 0) { 837 for (c = 0; c < children; c++) 838 if ((ret = max_width(zhp, child[c], depth + 2, 839 max)) > max) 840 max = ret; 841 } 842 843 844 return (max); 845 } 846 847 848 /* 849 * Print the configuration of an exported pool. Iterate over all vdevs in the 850 * pool, printing out the name and status for each one. 851 */ 852 void 853 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth) 854 { 855 nvlist_t **child; 856 uint_t c, children; 857 vdev_stat_t *vs; 858 char *type, *vname; 859 860 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 861 if (strcmp(type, VDEV_TYPE_MISSING) == 0) 862 return; 863 864 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 865 (uint64_t **)&vs, &c) == 0); 866 867 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name); 868 869 if (vs->vs_aux != 0) { 870 (void) printf(" %-8s ", state_to_name(vs)); 871 872 switch (vs->vs_aux) { 873 case VDEV_AUX_OPEN_FAILED: 874 (void) printf(gettext("cannot open")); 875 break; 876 877 case VDEV_AUX_BAD_GUID_SUM: 878 (void) printf(gettext("missing device")); 879 break; 880 881 case VDEV_AUX_NO_REPLICAS: 882 (void) printf(gettext("insufficient replicas")); 883 break; 884 885 case VDEV_AUX_VERSION_NEWER: 886 (void) printf(gettext("newer version")); 887 break; 888 889 default: 890 (void) printf(gettext("corrupted data")); 891 break; 892 } 893 } else { 894 (void) printf(" %s", state_to_name(vs)); 895 } 896 (void) printf("\n"); 897 898 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 899 &child, &children) != 0) 900 return; 901 902 for (c = 0; c < children; c++) { 903 vname = zpool_vdev_name(g_zfs, NULL, child[c]); 904 print_import_config(vname, child[c], 905 namewidth, depth + 2); 906 free(vname); 907 } 908 909 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 910 &child, &children) != 0) 911 return; 912 913 (void) printf(gettext("\tspares\n")); 914 for (c = 0; c < children; c++) { 915 vname = zpool_vdev_name(g_zfs, NULL, child[c]); 916 (void) printf("\t %s\n", vname); 917 free(vname); 918 } 919 } 920 921 /* 922 * Display the status for the given pool. 923 */ 924 static void 925 show_import(nvlist_t *config) 926 { 927 uint64_t pool_state; 928 vdev_stat_t *vs; 929 char *name; 930 uint64_t guid; 931 char *msgid; 932 nvlist_t *nvroot; 933 int reason; 934 char *health; 935 uint_t vsc; 936 int namewidth; 937 938 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 939 &name) == 0); 940 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 941 &guid) == 0); 942 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 943 &pool_state) == 0); 944 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_HEALTH, 945 &health) == 0); 946 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 947 &nvroot) == 0); 948 949 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 950 (uint64_t **)&vs, &vsc) == 0); 951 952 reason = zpool_import_status(config, &msgid); 953 954 (void) printf(" pool: %s\n", name); 955 (void) printf(" id: %llu\n", guid); 956 (void) printf(" state: %s", health); 957 if (pool_state == POOL_STATE_DESTROYED) 958 (void) printf(" (DESTROYED)"); 959 (void) printf("\n"); 960 961 switch (reason) { 962 case ZPOOL_STATUS_MISSING_DEV_R: 963 case ZPOOL_STATUS_MISSING_DEV_NR: 964 case ZPOOL_STATUS_BAD_GUID_SUM: 965 (void) printf(gettext("status: One or more devices are missing " 966 "from the system.\n")); 967 break; 968 969 case ZPOOL_STATUS_CORRUPT_LABEL_R: 970 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 971 (void) printf(gettext("status: One or more devices contains " 972 "corrupted data.\n")); 973 break; 974 975 case ZPOOL_STATUS_CORRUPT_DATA: 976 (void) printf(gettext("status: The pool data is corrupted.\n")); 977 break; 978 979 case ZPOOL_STATUS_OFFLINE_DEV: 980 (void) printf(gettext("status: One or more devices " 981 "are offlined.\n")); 982 break; 983 984 case ZPOOL_STATUS_CORRUPT_POOL: 985 (void) printf(gettext("status: The pool metadata is " 986 "corrupted.\n")); 987 break; 988 989 case ZPOOL_STATUS_VERSION_OLDER: 990 (void) printf(gettext("status: The pool is formatted using an " 991 "older on-disk version.\n")); 992 break; 993 994 case ZPOOL_STATUS_VERSION_NEWER: 995 (void) printf(gettext("status: The pool is formatted using an " 996 "incompatible version.\n")); 997 break; 998 999 default: 1000 /* 1001 * No other status can be seen when importing pools. 1002 */ 1003 assert(reason == ZPOOL_STATUS_OK); 1004 } 1005 1006 /* 1007 * Print out an action according to the overall state of the pool. 1008 */ 1009 if (strcmp(health, gettext("ONLINE")) == 0) { 1010 if (reason == ZPOOL_STATUS_VERSION_OLDER) 1011 (void) printf(gettext("action: The pool can be " 1012 "imported using its name or numeric identifier, " 1013 "though\n\tsome features will not be available " 1014 "without an explicit 'zpool upgrade'.\n")); 1015 else 1016 (void) printf(gettext("action: The pool can be " 1017 "imported using its name or numeric " 1018 "identifier.\n")); 1019 } else if (strcmp(health, gettext("DEGRADED")) == 0) { 1020 (void) printf(gettext("action: The pool can be imported " 1021 "despite missing or damaged devices. The\n\tfault " 1022 "tolerance of the pool may be compromised if imported.\n")); 1023 } else { 1024 switch (reason) { 1025 case ZPOOL_STATUS_VERSION_NEWER: 1026 (void) printf(gettext("action: The pool cannot be " 1027 "imported. Access the pool on a system running " 1028 "newer\n\tsoftware, or recreate the pool from " 1029 "backup.\n")); 1030 break; 1031 case ZPOOL_STATUS_MISSING_DEV_R: 1032 case ZPOOL_STATUS_MISSING_DEV_NR: 1033 case ZPOOL_STATUS_BAD_GUID_SUM: 1034 (void) printf(gettext("action: The pool cannot be " 1035 "imported. Attach the missing\n\tdevices and try " 1036 "again.\n")); 1037 break; 1038 default: 1039 (void) printf(gettext("action: The pool cannot be " 1040 "imported due to damaged devices or data.\n")); 1041 } 1042 } 1043 1044 if (strcmp(health, gettext("FAULTED")) != 0) { 1045 if (pool_state == POOL_STATE_DESTROYED) 1046 (void) printf(gettext("\tThe pool was destroyed, " 1047 "but can be imported using the '-Df' flags.\n")); 1048 else if (pool_state != POOL_STATE_EXPORTED) 1049 (void) printf(gettext("\tThe pool may be active on " 1050 "on another system, but can be imported using\n\t" 1051 "the '-f' flag.\n")); 1052 } 1053 1054 if (msgid != NULL) 1055 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 1056 msgid); 1057 1058 (void) printf(gettext("config:\n\n")); 1059 1060 namewidth = max_width(NULL, nvroot, 0, 0); 1061 if (namewidth < 10) 1062 namewidth = 10; 1063 print_import_config(name, nvroot, namewidth, 0); 1064 1065 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) { 1066 (void) printf("\n\tAdditional devices are known to " 1067 "be part of this pool, though their\n\texact " 1068 "configuration cannot be determined.\n"); 1069 } 1070 } 1071 1072 /* 1073 * Perform the import for the given configuration. This passes the heavy 1074 * lifting off to zpool_import(), and then mounts the datasets contained within 1075 * the pool. 1076 */ 1077 static int 1078 do_import(nvlist_t *config, const char *newname, const char *mntopts, 1079 const char *altroot, int force) 1080 { 1081 zpool_handle_t *zhp; 1082 char *name; 1083 uint64_t state; 1084 uint64_t version; 1085 1086 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1087 &name) == 0); 1088 1089 verify(nvlist_lookup_uint64(config, 1090 ZPOOL_CONFIG_POOL_STATE, &state) == 0); 1091 verify(nvlist_lookup_uint64(config, 1092 ZPOOL_CONFIG_VERSION, &version) == 0); 1093 if (version > ZFS_VERSION) { 1094 (void) fprintf(stderr, gettext("cannot import '%s': pool " 1095 "is formatted using a newer ZFS version\n"), name); 1096 return (1); 1097 } else if (state != POOL_STATE_EXPORTED && !force) { 1098 (void) fprintf(stderr, gettext("cannot import '%s': pool " 1099 "may be in use from other system\n"), name); 1100 (void) fprintf(stderr, gettext("use '-f' to import anyway\n")); 1101 return (1); 1102 } 1103 1104 if (zpool_import(g_zfs, config, newname, altroot) != 0) 1105 return (1); 1106 1107 if (newname != NULL) 1108 name = (char *)newname; 1109 1110 verify((zhp = zpool_open(g_zfs, name)) != NULL); 1111 1112 if (zpool_mount_datasets(zhp, mntopts, 0) != 0) { 1113 zpool_close(zhp); 1114 return (1); 1115 } 1116 1117 zpool_close(zhp); 1118 return (0); 1119 } 1120 1121 /* 1122 * zpool import [-d dir] [-D] 1123 * import [-R root] [-D] [-d dir] [-f] -a 1124 * import [-R root] [-D] [-d dir] [-f] <pool | id> [newpool] 1125 * 1126 * -d Scan in a specific directory, other than /dev/dsk. More than 1127 * one directory can be specified using multiple '-d' options. 1128 * 1129 * -D Scan for previously destroyed pools or import all or only 1130 * specified destroyed pools. 1131 * 1132 * -R Temporarily import the pool, with all mountpoints relative to 1133 * the given root. The pool will remain exported when the machine 1134 * is rebooted. 1135 * 1136 * -f Force import, even if it appears that the pool is active. 1137 * 1138 * -a Import all pools found. 1139 * 1140 * The import command scans for pools to import, and import pools based on pool 1141 * name and GUID. The pool can also be renamed as part of the import process. 1142 */ 1143 int 1144 zpool_do_import(int argc, char **argv) 1145 { 1146 char **searchdirs = NULL; 1147 int nsearch = 0; 1148 int c; 1149 int err; 1150 nvlist_t *pools; 1151 boolean_t do_all = B_FALSE; 1152 boolean_t do_destroyed = B_FALSE; 1153 char *altroot = NULL; 1154 char *mntopts = NULL; 1155 boolean_t do_force = B_FALSE; 1156 nvpair_t *elem; 1157 nvlist_t *config; 1158 uint64_t searchguid; 1159 char *searchname; 1160 nvlist_t *found_config; 1161 boolean_t first; 1162 uint64_t pool_state; 1163 1164 /* check options */ 1165 while ((c = getopt(argc, argv, ":Dfd:R:ao:")) != -1) { 1166 switch (c) { 1167 case 'a': 1168 do_all = B_TRUE; 1169 break; 1170 case 'd': 1171 if (searchdirs == NULL) { 1172 searchdirs = safe_malloc(sizeof (char *)); 1173 } else { 1174 char **tmp = safe_malloc((nsearch + 1) * 1175 sizeof (char *)); 1176 bcopy(searchdirs, tmp, nsearch * 1177 sizeof (char *)); 1178 free(searchdirs); 1179 searchdirs = tmp; 1180 } 1181 searchdirs[nsearch++] = optarg; 1182 break; 1183 case 'D': 1184 do_destroyed = B_TRUE; 1185 break; 1186 case 'f': 1187 do_force = B_TRUE; 1188 break; 1189 case 'o': 1190 mntopts = optarg; 1191 break; 1192 case 'R': 1193 altroot = optarg; 1194 break; 1195 case ':': 1196 (void) fprintf(stderr, gettext("missing argument for " 1197 "'%c' option\n"), optopt); 1198 usage(B_FALSE); 1199 break; 1200 case '?': 1201 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1202 optopt); 1203 usage(B_FALSE); 1204 } 1205 } 1206 1207 argc -= optind; 1208 argv += optind; 1209 1210 if (searchdirs == NULL) { 1211 searchdirs = safe_malloc(sizeof (char *)); 1212 searchdirs[0] = "/dev/dsk"; 1213 nsearch = 1; 1214 } 1215 1216 /* check argument count */ 1217 if (do_all) { 1218 if (argc != 0) { 1219 (void) fprintf(stderr, gettext("too many arguments\n")); 1220 usage(B_FALSE); 1221 } 1222 } else { 1223 if (argc > 2) { 1224 (void) fprintf(stderr, gettext("too many arguments\n")); 1225 usage(B_FALSE); 1226 } 1227 1228 /* 1229 * Check for the SYS_CONFIG privilege. We do this explicitly 1230 * here because otherwise any attempt to discover pools will 1231 * silently fail. 1232 */ 1233 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 1234 (void) fprintf(stderr, gettext("cannot " 1235 "discover pools: permission denied\n")); 1236 free(searchdirs); 1237 return (1); 1238 } 1239 } 1240 1241 if ((pools = zpool_find_import(g_zfs, nsearch, searchdirs)) == NULL) { 1242 free(searchdirs); 1243 return (1); 1244 } 1245 1246 /* 1247 * We now have a list of all available pools in the given directories. 1248 * Depending on the arguments given, we do one of the following: 1249 * 1250 * <none> Iterate through all pools and display information about 1251 * each one. 1252 * 1253 * -a Iterate through all pools and try to import each one. 1254 * 1255 * <id> Find the pool that corresponds to the given GUID/pool 1256 * name and import that one. 1257 * 1258 * -D Above options applies only to destroyed pools. 1259 */ 1260 if (argc != 0) { 1261 char *endptr; 1262 1263 errno = 0; 1264 searchguid = strtoull(argv[0], &endptr, 10); 1265 if (errno != 0 || *endptr != '\0') 1266 searchname = argv[0]; 1267 else 1268 searchname = NULL; 1269 found_config = NULL; 1270 } 1271 1272 err = 0; 1273 elem = NULL; 1274 first = B_TRUE; 1275 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 1276 1277 verify(nvpair_value_nvlist(elem, &config) == 0); 1278 1279 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1280 &pool_state) == 0); 1281 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 1282 continue; 1283 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 1284 continue; 1285 1286 if (argc == 0) { 1287 if (first) 1288 first = B_FALSE; 1289 else if (!do_all) 1290 (void) printf("\n"); 1291 1292 if (do_all) 1293 err |= do_import(config, NULL, mntopts, 1294 altroot, do_force); 1295 else 1296 show_import(config); 1297 } else if (searchname != NULL) { 1298 char *name; 1299 1300 /* 1301 * We are searching for a pool based on name. 1302 */ 1303 verify(nvlist_lookup_string(config, 1304 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 1305 1306 if (strcmp(name, searchname) == 0) { 1307 if (found_config != NULL) { 1308 (void) fprintf(stderr, gettext( 1309 "cannot import '%s': more than " 1310 "one matching pool\n"), searchname); 1311 (void) fprintf(stderr, gettext( 1312 "import by numeric ID instead\n")); 1313 err = B_TRUE; 1314 } 1315 found_config = config; 1316 } 1317 } else { 1318 uint64_t guid; 1319 1320 /* 1321 * Search for a pool by guid. 1322 */ 1323 verify(nvlist_lookup_uint64(config, 1324 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 1325 1326 if (guid == searchguid) 1327 found_config = config; 1328 } 1329 } 1330 1331 /* 1332 * If we were searching for a specific pool, verify that we found a 1333 * pool, and then do the import. 1334 */ 1335 if (argc != 0 && err == 0) { 1336 if (found_config == NULL) { 1337 (void) fprintf(stderr, gettext("cannot import '%s': " 1338 "no such pool available\n"), argv[0]); 1339 err = B_TRUE; 1340 } else { 1341 err |= do_import(found_config, argc == 1 ? NULL : 1342 argv[1], mntopts, altroot, do_force); 1343 } 1344 } 1345 1346 /* 1347 * If we were just looking for pools, report an error if none were 1348 * found. 1349 */ 1350 if (argc == 0 && first) 1351 (void) fprintf(stderr, 1352 gettext("no pools available to import\n")); 1353 1354 nvlist_free(pools); 1355 free(searchdirs); 1356 1357 return (err ? 1 : 0); 1358 } 1359 1360 typedef struct iostat_cbdata { 1361 zpool_list_t *cb_list; 1362 int cb_verbose; 1363 int cb_iteration; 1364 int cb_namewidth; 1365 } iostat_cbdata_t; 1366 1367 static void 1368 print_iostat_separator(iostat_cbdata_t *cb) 1369 { 1370 int i = 0; 1371 1372 for (i = 0; i < cb->cb_namewidth; i++) 1373 (void) printf("-"); 1374 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 1375 } 1376 1377 static void 1378 print_iostat_header(iostat_cbdata_t *cb) 1379 { 1380 (void) printf("%*s capacity operations bandwidth\n", 1381 cb->cb_namewidth, ""); 1382 (void) printf("%-*s used avail read write read write\n", 1383 cb->cb_namewidth, "pool"); 1384 print_iostat_separator(cb); 1385 } 1386 1387 /* 1388 * Display a single statistic. 1389 */ 1390 void 1391 print_one_stat(uint64_t value) 1392 { 1393 char buf[64]; 1394 1395 zfs_nicenum(value, buf, sizeof (buf)); 1396 (void) printf(" %5s", buf); 1397 } 1398 1399 /* 1400 * Print out all the statistics for the given vdev. This can either be the 1401 * toplevel configuration, or called recursively. If 'name' is NULL, then this 1402 * is a verbose output, and we don't want to display the toplevel pool stats. 1403 */ 1404 void 1405 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 1406 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 1407 { 1408 nvlist_t **oldchild, **newchild; 1409 uint_t c, children; 1410 vdev_stat_t *oldvs, *newvs; 1411 vdev_stat_t zerovs = { 0 }; 1412 uint64_t tdelta; 1413 double scale; 1414 char *vname; 1415 1416 if (oldnv != NULL) { 1417 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS, 1418 (uint64_t **)&oldvs, &c) == 0); 1419 } else { 1420 oldvs = &zerovs; 1421 } 1422 1423 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS, 1424 (uint64_t **)&newvs, &c) == 0); 1425 1426 if (strlen(name) + depth > cb->cb_namewidth) 1427 (void) printf("%*s%s", depth, "", name); 1428 else 1429 (void) printf("%*s%s%*s", depth, "", name, 1430 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 1431 1432 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 1433 1434 if (tdelta == 0) 1435 scale = 1.0; 1436 else 1437 scale = (double)NANOSEC / tdelta; 1438 1439 /* only toplevel vdevs have capacity stats */ 1440 if (newvs->vs_space == 0) { 1441 (void) printf(" - -"); 1442 } else { 1443 print_one_stat(newvs->vs_alloc); 1444 print_one_stat(newvs->vs_space - newvs->vs_alloc); 1445 } 1446 1447 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 1448 oldvs->vs_ops[ZIO_TYPE_READ]))); 1449 1450 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 1451 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 1452 1453 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 1454 oldvs->vs_bytes[ZIO_TYPE_READ]))); 1455 1456 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 1457 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 1458 1459 (void) printf("\n"); 1460 1461 if (!cb->cb_verbose) 1462 return; 1463 1464 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 1465 &newchild, &children) != 0) 1466 return; 1467 1468 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 1469 &oldchild, &c) != 0) 1470 return; 1471 1472 for (c = 0; c < children; c++) { 1473 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]); 1474 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 1475 newchild[c], cb, depth + 2); 1476 free(vname); 1477 } 1478 } 1479 1480 static int 1481 refresh_iostat(zpool_handle_t *zhp, void *data) 1482 { 1483 iostat_cbdata_t *cb = data; 1484 boolean_t missing; 1485 1486 /* 1487 * If the pool has disappeared, remove it from the list and continue. 1488 */ 1489 if (zpool_refresh_stats(zhp, &missing) != 0) 1490 return (-1); 1491 1492 if (missing) 1493 pool_list_remove(cb->cb_list, zhp); 1494 1495 return (0); 1496 } 1497 1498 /* 1499 * Callback to print out the iostats for the given pool. 1500 */ 1501 int 1502 print_iostat(zpool_handle_t *zhp, void *data) 1503 { 1504 iostat_cbdata_t *cb = data; 1505 nvlist_t *oldconfig, *newconfig; 1506 nvlist_t *oldnvroot, *newnvroot; 1507 1508 newconfig = zpool_get_config(zhp, &oldconfig); 1509 1510 if (cb->cb_iteration == 1) 1511 oldconfig = NULL; 1512 1513 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 1514 &newnvroot) == 0); 1515 1516 if (oldconfig == NULL) 1517 oldnvroot = NULL; 1518 else 1519 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 1520 &oldnvroot) == 0); 1521 1522 /* 1523 * Print out the statistics for the pool. 1524 */ 1525 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 1526 1527 if (cb->cb_verbose) 1528 print_iostat_separator(cb); 1529 1530 return (0); 1531 } 1532 1533 int 1534 get_namewidth(zpool_handle_t *zhp, void *data) 1535 { 1536 iostat_cbdata_t *cb = data; 1537 nvlist_t *config, *nvroot; 1538 1539 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 1540 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1541 &nvroot) == 0); 1542 if (!cb->cb_verbose) 1543 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 1544 else 1545 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0); 1546 } 1547 1548 /* 1549 * The width must fall into the range [10,38]. The upper limit is the 1550 * maximum we can have and still fit in 80 columns. 1551 */ 1552 if (cb->cb_namewidth < 10) 1553 cb->cb_namewidth = 10; 1554 if (cb->cb_namewidth > 38) 1555 cb->cb_namewidth = 38; 1556 1557 return (0); 1558 } 1559 1560 /* 1561 * zpool iostat [-v] [pool] ... [interval [count]] 1562 * 1563 * -v Display statistics for individual vdevs 1564 * 1565 * This command can be tricky because we want to be able to deal with pool 1566 * creation/destruction as well as vdev configuration changes. The bulk of this 1567 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 1568 * on pool_list_update() to detect the addition of new pools. Configuration 1569 * changes are all handled within libzfs. 1570 */ 1571 int 1572 zpool_do_iostat(int argc, char **argv) 1573 { 1574 int c; 1575 int ret; 1576 int npools; 1577 unsigned long interval = 0, count = 0; 1578 zpool_list_t *list; 1579 boolean_t verbose = B_FALSE; 1580 iostat_cbdata_t cb; 1581 1582 /* check options */ 1583 while ((c = getopt(argc, argv, "v")) != -1) { 1584 switch (c) { 1585 case 'v': 1586 verbose = B_TRUE; 1587 break; 1588 case '?': 1589 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1590 optopt); 1591 usage(B_FALSE); 1592 } 1593 } 1594 1595 argc -= optind; 1596 argv += optind; 1597 1598 /* 1599 * Determine if the last argument is an integer or a pool name 1600 */ 1601 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1602 char *end; 1603 1604 errno = 0; 1605 interval = strtoul(argv[argc - 1], &end, 10); 1606 1607 if (*end == '\0' && errno == 0) { 1608 if (interval == 0) { 1609 (void) fprintf(stderr, gettext("interval " 1610 "cannot be zero\n")); 1611 usage(B_FALSE); 1612 } 1613 1614 /* 1615 * Ignore the last parameter 1616 */ 1617 argc--; 1618 } else { 1619 /* 1620 * If this is not a valid number, just plow on. The 1621 * user will get a more informative error message later 1622 * on. 1623 */ 1624 interval = 0; 1625 } 1626 } 1627 1628 /* 1629 * If the last argument is also an integer, then we have both a count 1630 * and an integer. 1631 */ 1632 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1633 char *end; 1634 1635 errno = 0; 1636 count = interval; 1637 interval = strtoul(argv[argc - 1], &end, 10); 1638 1639 if (*end == '\0' && errno == 0) { 1640 if (interval == 0) { 1641 (void) fprintf(stderr, gettext("interval " 1642 "cannot be zero\n")); 1643 usage(B_FALSE); 1644 } 1645 1646 /* 1647 * Ignore the last parameter 1648 */ 1649 argc--; 1650 } else { 1651 interval = 0; 1652 } 1653 } 1654 1655 /* 1656 * Construct the list of all interesting pools. 1657 */ 1658 ret = 0; 1659 if ((list = pool_list_get(argc, argv, &ret)) == NULL) 1660 return (1); 1661 1662 if (pool_list_count(list) == 0 && argc != 0) { 1663 pool_list_free(list); 1664 return (1); 1665 } 1666 1667 if (pool_list_count(list) == 0 && interval == 0) { 1668 pool_list_free(list); 1669 (void) fprintf(stderr, gettext("no pools available\n")); 1670 return (1); 1671 } 1672 1673 /* 1674 * Enter the main iostat loop. 1675 */ 1676 cb.cb_list = list; 1677 cb.cb_verbose = verbose; 1678 cb.cb_iteration = 0; 1679 cb.cb_namewidth = 0; 1680 1681 for (;;) { 1682 pool_list_update(list); 1683 1684 if ((npools = pool_list_count(list)) == 0) 1685 break; 1686 1687 /* 1688 * Refresh all statistics. This is done as an explicit step 1689 * before calculating the maximum name width, so that any 1690 * configuration changes are properly accounted for. 1691 */ 1692 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 1693 1694 /* 1695 * Iterate over all pools to determine the maximum width 1696 * for the pool / device name column across all pools. 1697 */ 1698 cb.cb_namewidth = 0; 1699 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 1700 1701 /* 1702 * If it's the first time, or verbose mode, print the header. 1703 */ 1704 if (++cb.cb_iteration == 1 || verbose) 1705 print_iostat_header(&cb); 1706 1707 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 1708 1709 /* 1710 * If there's more than one pool, and we're not in verbose mode 1711 * (which prints a separator for us), then print a separator. 1712 */ 1713 if (npools > 1 && !verbose) 1714 print_iostat_separator(&cb); 1715 1716 if (verbose) 1717 (void) printf("\n"); 1718 1719 if (interval == 0) 1720 break; 1721 1722 if (count != 0 && --count == 0) 1723 break; 1724 1725 (void) sleep(interval); 1726 } 1727 1728 pool_list_free(list); 1729 1730 return (ret); 1731 } 1732 1733 typedef struct list_cbdata { 1734 boolean_t cb_scripted; 1735 boolean_t cb_first; 1736 int cb_fields[MAX_FIELDS]; 1737 int cb_fieldcount; 1738 } list_cbdata_t; 1739 1740 /* 1741 * Given a list of columns to display, output appropriate headers for each one. 1742 */ 1743 void 1744 print_header(int *fields, size_t count) 1745 { 1746 int i; 1747 column_def_t *col; 1748 const char *fmt; 1749 1750 for (i = 0; i < count; i++) { 1751 col = &column_table[fields[i]]; 1752 if (i != 0) 1753 (void) printf(" "); 1754 if (col->cd_justify == left_justify) 1755 fmt = "%-*s"; 1756 else 1757 fmt = "%*s"; 1758 1759 (void) printf(fmt, i == count - 1 ? strlen(col->cd_title) : 1760 col->cd_width, col->cd_title); 1761 } 1762 1763 (void) printf("\n"); 1764 } 1765 1766 int 1767 list_callback(zpool_handle_t *zhp, void *data) 1768 { 1769 list_cbdata_t *cbp = data; 1770 nvlist_t *config; 1771 int i; 1772 char buf[ZPOOL_MAXNAMELEN]; 1773 uint64_t total; 1774 uint64_t used; 1775 const char *fmt; 1776 column_def_t *col; 1777 1778 if (cbp->cb_first) { 1779 if (!cbp->cb_scripted) 1780 print_header(cbp->cb_fields, cbp->cb_fieldcount); 1781 cbp->cb_first = B_FALSE; 1782 } 1783 1784 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 1785 config = NULL; 1786 } else { 1787 config = zpool_get_config(zhp, NULL); 1788 total = zpool_get_space_total(zhp); 1789 used = zpool_get_space_used(zhp); 1790 } 1791 1792 for (i = 0; i < cbp->cb_fieldcount; i++) { 1793 if (i != 0) { 1794 if (cbp->cb_scripted) 1795 (void) printf("\t"); 1796 else 1797 (void) printf(" "); 1798 } 1799 1800 col = &column_table[cbp->cb_fields[i]]; 1801 1802 switch (cbp->cb_fields[i]) { 1803 case ZPOOL_FIELD_NAME: 1804 (void) strlcpy(buf, zpool_get_name(zhp), sizeof (buf)); 1805 break; 1806 1807 case ZPOOL_FIELD_SIZE: 1808 if (config == NULL) 1809 (void) strlcpy(buf, "-", sizeof (buf)); 1810 else 1811 zfs_nicenum(total, buf, sizeof (buf)); 1812 break; 1813 1814 case ZPOOL_FIELD_USED: 1815 if (config == NULL) 1816 (void) strlcpy(buf, "-", sizeof (buf)); 1817 else 1818 zfs_nicenum(used, buf, sizeof (buf)); 1819 break; 1820 1821 case ZPOOL_FIELD_AVAILABLE: 1822 if (config == NULL) 1823 (void) strlcpy(buf, "-", sizeof (buf)); 1824 else 1825 zfs_nicenum(total - used, buf, sizeof (buf)); 1826 break; 1827 1828 case ZPOOL_FIELD_CAPACITY: 1829 if (config == NULL) { 1830 (void) strlcpy(buf, "-", sizeof (buf)); 1831 } else { 1832 uint64_t capacity = (total == 0 ? 0 : 1833 (used * 100 / total)); 1834 (void) snprintf(buf, sizeof (buf), "%llu%%", 1835 capacity); 1836 } 1837 break; 1838 1839 case ZPOOL_FIELD_HEALTH: 1840 if (config == NULL) { 1841 (void) strlcpy(buf, "FAULTED", sizeof (buf)); 1842 } else { 1843 nvlist_t *nvroot; 1844 vdev_stat_t *vs; 1845 uint_t vsc; 1846 1847 verify(nvlist_lookup_nvlist(config, 1848 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); 1849 verify(nvlist_lookup_uint64_array(nvroot, 1850 ZPOOL_CONFIG_STATS, (uint64_t **)&vs, 1851 &vsc) == 0); 1852 (void) strlcpy(buf, state_to_name(vs), 1853 sizeof (buf)); 1854 } 1855 break; 1856 1857 case ZPOOL_FIELD_ROOT: 1858 if (config == NULL) 1859 (void) strlcpy(buf, "-", sizeof (buf)); 1860 else if (zpool_get_root(zhp, buf, sizeof (buf)) != 0) 1861 (void) strlcpy(buf, "-", sizeof (buf)); 1862 break; 1863 } 1864 1865 if (cbp->cb_scripted) 1866 (void) printf("%s", buf); 1867 else { 1868 if (col->cd_justify == left_justify) 1869 fmt = "%-*s"; 1870 else 1871 fmt = "%*s"; 1872 1873 (void) printf(fmt, i == cbp->cb_fieldcount - 1 ? 1874 strlen(buf) : col->cd_width, buf); 1875 } 1876 } 1877 1878 (void) printf("\n"); 1879 1880 return (0); 1881 } 1882 1883 /* 1884 * zpool list [-H] [-o field[,field]*] [pool] ... 1885 * 1886 * -H Scripted mode. Don't display headers, and separate fields by 1887 * a single tab. 1888 * -o List of fields to display. Defaults to all fields, or 1889 * "name,size,used,available,capacity,health,root" 1890 * 1891 * List all pools in the system, whether or not they're healthy. Output space 1892 * statistics for each one, as well as health status summary. 1893 */ 1894 int 1895 zpool_do_list(int argc, char **argv) 1896 { 1897 int c; 1898 int ret; 1899 list_cbdata_t cb = { 0 }; 1900 static char default_fields[] = 1901 "name,size,used,available,capacity,health,root"; 1902 char *fields = default_fields; 1903 char *value; 1904 1905 /* check options */ 1906 while ((c = getopt(argc, argv, ":Ho:")) != -1) { 1907 switch (c) { 1908 case 'H': 1909 cb.cb_scripted = B_TRUE; 1910 break; 1911 case 'o': 1912 fields = optarg; 1913 break; 1914 case ':': 1915 (void) fprintf(stderr, gettext("missing argument for " 1916 "'%c' option\n"), optopt); 1917 usage(B_FALSE); 1918 break; 1919 case '?': 1920 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1921 optopt); 1922 usage(B_FALSE); 1923 } 1924 } 1925 1926 argc -= optind; 1927 argv += optind; 1928 1929 while (*fields != '\0') { 1930 if (cb.cb_fieldcount == MAX_FIELDS) { 1931 (void) fprintf(stderr, gettext("too many " 1932 "properties given to -o option\n")); 1933 usage(B_FALSE); 1934 } 1935 1936 if ((cb.cb_fields[cb.cb_fieldcount] = getsubopt(&fields, 1937 column_subopts, &value)) == -1) { 1938 (void) fprintf(stderr, gettext("invalid property " 1939 "'%s'\n"), value); 1940 usage(B_FALSE); 1941 } 1942 1943 cb.cb_fieldcount++; 1944 } 1945 1946 1947 cb.cb_first = B_TRUE; 1948 1949 ret = for_each_pool(argc, argv, B_TRUE, list_callback, &cb); 1950 1951 if (argc == 0 && cb.cb_first) { 1952 (void) printf(gettext("no pools available\n")); 1953 return (0); 1954 } 1955 1956 return (ret); 1957 } 1958 1959 static nvlist_t * 1960 zpool_get_vdev_by_name(nvlist_t *nv, char *name) 1961 { 1962 nvlist_t **child; 1963 uint_t c, children; 1964 nvlist_t *match; 1965 char *path; 1966 1967 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1968 &child, &children) != 0) { 1969 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 1970 if (strncmp(name, "/dev/dsk/", 9) == 0) 1971 name += 9; 1972 if (strncmp(path, "/dev/dsk/", 9) == 0) 1973 path += 9; 1974 if (strcmp(name, path) == 0) 1975 return (nv); 1976 return (NULL); 1977 } 1978 1979 for (c = 0; c < children; c++) 1980 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL) 1981 return (match); 1982 1983 return (NULL); 1984 } 1985 1986 static int 1987 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 1988 { 1989 boolean_t force = B_FALSE; 1990 int c; 1991 nvlist_t *nvroot; 1992 char *poolname, *old_disk, *new_disk; 1993 zpool_handle_t *zhp; 1994 nvlist_t *config; 1995 int ret; 1996 1997 /* check options */ 1998 while ((c = getopt(argc, argv, "f")) != -1) { 1999 switch (c) { 2000 case 'f': 2001 force = B_TRUE; 2002 break; 2003 case '?': 2004 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2005 optopt); 2006 usage(B_FALSE); 2007 } 2008 } 2009 2010 argc -= optind; 2011 argv += optind; 2012 2013 /* get pool name and check number of arguments */ 2014 if (argc < 1) { 2015 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2016 usage(B_FALSE); 2017 } 2018 2019 poolname = argv[0]; 2020 2021 if (argc < 2) { 2022 (void) fprintf(stderr, 2023 gettext("missing <device> specification\n")); 2024 usage(B_FALSE); 2025 } 2026 2027 old_disk = argv[1]; 2028 2029 if (argc < 3) { 2030 if (!replacing) { 2031 (void) fprintf(stderr, 2032 gettext("missing <new_device> specification\n")); 2033 usage(B_FALSE); 2034 } 2035 new_disk = old_disk; 2036 argc -= 1; 2037 argv += 1; 2038 } else { 2039 new_disk = argv[2]; 2040 argc -= 2; 2041 argv += 2; 2042 } 2043 2044 if (argc > 1) { 2045 (void) fprintf(stderr, gettext("too many arguments\n")); 2046 usage(B_FALSE); 2047 } 2048 2049 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2050 return (1); 2051 2052 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 2053 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 2054 poolname); 2055 zpool_close(zhp); 2056 return (1); 2057 } 2058 2059 nvroot = make_root_vdev(config, force, B_FALSE, replacing, argc, argv); 2060 if (nvroot == NULL) { 2061 zpool_close(zhp); 2062 return (1); 2063 } 2064 2065 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 2066 2067 nvlist_free(nvroot); 2068 zpool_close(zhp); 2069 2070 return (ret); 2071 } 2072 2073 /* 2074 * zpool replace [-f] <pool> <device> <new_device> 2075 * 2076 * -f Force attach, even if <new_device> appears to be in use. 2077 * 2078 * Replace <device> with <new_device>. 2079 */ 2080 /* ARGSUSED */ 2081 int 2082 zpool_do_replace(int argc, char **argv) 2083 { 2084 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 2085 } 2086 2087 /* 2088 * zpool attach [-f] <pool> <device> <new_device> 2089 * 2090 * -f Force attach, even if <new_device> appears to be in use. 2091 * 2092 * Attach <new_device> to the mirror containing <device>. If <device> is not 2093 * part of a mirror, then <device> will be transformed into a mirror of 2094 * <device> and <new_device>. In either case, <new_device> will begin life 2095 * with a DTL of [0, now], and will immediately begin to resilver itself. 2096 */ 2097 int 2098 zpool_do_attach(int argc, char **argv) 2099 { 2100 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 2101 } 2102 2103 /* 2104 * zpool detach [-f] <pool> <device> 2105 * 2106 * -f Force detach of <device>, even if DTLs argue against it 2107 * (not supported yet) 2108 * 2109 * Detach a device from a mirror. The operation will be refused if <device> 2110 * is the last device in the mirror, or if the DTLs indicate that this device 2111 * has the only valid copy of some data. 2112 */ 2113 /* ARGSUSED */ 2114 int 2115 zpool_do_detach(int argc, char **argv) 2116 { 2117 int c; 2118 char *poolname, *path; 2119 zpool_handle_t *zhp; 2120 int ret; 2121 2122 /* check options */ 2123 while ((c = getopt(argc, argv, "f")) != -1) { 2124 switch (c) { 2125 case 'f': 2126 case '?': 2127 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2128 optopt); 2129 usage(B_FALSE); 2130 } 2131 } 2132 2133 argc -= optind; 2134 argv += optind; 2135 2136 /* get pool name and check number of arguments */ 2137 if (argc < 1) { 2138 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2139 usage(B_FALSE); 2140 } 2141 2142 if (argc < 2) { 2143 (void) fprintf(stderr, 2144 gettext("missing <device> specification\n")); 2145 usage(B_FALSE); 2146 } 2147 2148 poolname = argv[0]; 2149 path = argv[1]; 2150 2151 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2152 return (1); 2153 2154 ret = zpool_vdev_detach(zhp, path); 2155 2156 zpool_close(zhp); 2157 2158 return (ret); 2159 } 2160 2161 /* 2162 * zpool online <pool> <device> ... 2163 */ 2164 /* ARGSUSED */ 2165 int 2166 zpool_do_online(int argc, char **argv) 2167 { 2168 int c, i; 2169 char *poolname; 2170 zpool_handle_t *zhp; 2171 int ret = 0; 2172 2173 /* check options */ 2174 while ((c = getopt(argc, argv, "t")) != -1) { 2175 switch (c) { 2176 case 't': 2177 case '?': 2178 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2179 optopt); 2180 usage(B_FALSE); 2181 } 2182 } 2183 2184 argc -= optind; 2185 argv += optind; 2186 2187 /* get pool name and check number of arguments */ 2188 if (argc < 1) { 2189 (void) fprintf(stderr, gettext("missing pool name\n")); 2190 usage(B_FALSE); 2191 } 2192 if (argc < 2) { 2193 (void) fprintf(stderr, gettext("missing device name\n")); 2194 usage(B_FALSE); 2195 } 2196 2197 poolname = argv[0]; 2198 2199 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2200 return (1); 2201 2202 for (i = 1; i < argc; i++) 2203 if (zpool_vdev_online(zhp, argv[i]) == 0) 2204 (void) printf(gettext("Bringing device %s online\n"), 2205 argv[i]); 2206 else 2207 ret = 1; 2208 2209 zpool_close(zhp); 2210 2211 return (ret); 2212 } 2213 2214 /* 2215 * zpool offline [-ft] <pool> <device> ... 2216 * 2217 * -f Force the device into the offline state, even if doing 2218 * so would appear to compromise pool availability. 2219 * (not supported yet) 2220 * 2221 * -t Only take the device off-line temporarily. The offline 2222 * state will not be persistent across reboots. 2223 */ 2224 /* ARGSUSED */ 2225 int 2226 zpool_do_offline(int argc, char **argv) 2227 { 2228 int c, i; 2229 char *poolname; 2230 zpool_handle_t *zhp; 2231 int ret = 0; 2232 boolean_t istmp = B_FALSE; 2233 2234 /* check options */ 2235 while ((c = getopt(argc, argv, "ft")) != -1) { 2236 switch (c) { 2237 case 't': 2238 istmp = B_TRUE; 2239 break; 2240 case 'f': 2241 case '?': 2242 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2243 optopt); 2244 usage(B_FALSE); 2245 } 2246 } 2247 2248 argc -= optind; 2249 argv += optind; 2250 2251 /* get pool name and check number of arguments */ 2252 if (argc < 1) { 2253 (void) fprintf(stderr, gettext("missing pool name\n")); 2254 usage(B_FALSE); 2255 } 2256 if (argc < 2) { 2257 (void) fprintf(stderr, gettext("missing device name\n")); 2258 usage(B_FALSE); 2259 } 2260 2261 poolname = argv[0]; 2262 2263 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2264 return (1); 2265 2266 for (i = 1; i < argc; i++) 2267 if (zpool_vdev_offline(zhp, argv[i], istmp) == 0) 2268 (void) printf(gettext("Bringing device %s offline\n"), 2269 argv[i]); 2270 else 2271 ret = 1; 2272 2273 zpool_close(zhp); 2274 2275 return (ret); 2276 } 2277 2278 /* 2279 * zpool clear <pool> [device] 2280 * 2281 * Clear all errors associated with a pool or a particular device. 2282 */ 2283 int 2284 zpool_do_clear(int argc, char **argv) 2285 { 2286 int ret = 0; 2287 zpool_handle_t *zhp; 2288 char *pool, *device; 2289 2290 if (argc < 2) { 2291 (void) fprintf(stderr, gettext("missing pool name\n")); 2292 usage(B_FALSE); 2293 } 2294 2295 if (argc > 3) { 2296 (void) fprintf(stderr, gettext("too many arguments\n")); 2297 usage(B_FALSE); 2298 } 2299 2300 pool = argv[1]; 2301 device = argc == 3 ? argv[2] : NULL; 2302 2303 if ((zhp = zpool_open(g_zfs, pool)) == NULL) 2304 return (1); 2305 2306 if (zpool_clear(zhp, device) != 0) 2307 ret = 1; 2308 2309 zpool_close(zhp); 2310 2311 return (ret); 2312 } 2313 2314 typedef struct scrub_cbdata { 2315 int cb_type; 2316 } scrub_cbdata_t; 2317 2318 int 2319 scrub_callback(zpool_handle_t *zhp, void *data) 2320 { 2321 scrub_cbdata_t *cb = data; 2322 2323 /* 2324 * Ignore faulted pools. 2325 */ 2326 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 2327 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 2328 "currently unavailable\n"), zpool_get_name(zhp)); 2329 return (1); 2330 } 2331 2332 return (zpool_scrub(zhp, cb->cb_type) != 0); 2333 } 2334 2335 /* 2336 * zpool scrub [-s] <pool> ... 2337 * 2338 * -s Stop. Stops any in-progress scrub. 2339 */ 2340 int 2341 zpool_do_scrub(int argc, char **argv) 2342 { 2343 int c; 2344 scrub_cbdata_t cb; 2345 2346 cb.cb_type = POOL_SCRUB_EVERYTHING; 2347 2348 /* check options */ 2349 while ((c = getopt(argc, argv, "s")) != -1) { 2350 switch (c) { 2351 case 's': 2352 cb.cb_type = POOL_SCRUB_NONE; 2353 break; 2354 case '?': 2355 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2356 optopt); 2357 usage(B_FALSE); 2358 } 2359 } 2360 2361 argc -= optind; 2362 argv += optind; 2363 2364 if (argc < 1) { 2365 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2366 usage(B_FALSE); 2367 } 2368 2369 return (for_each_pool(argc, argv, B_TRUE, scrub_callback, &cb)); 2370 } 2371 2372 typedef struct status_cbdata { 2373 int cb_count; 2374 boolean_t cb_allpools; 2375 boolean_t cb_verbose; 2376 boolean_t cb_explain; 2377 boolean_t cb_first; 2378 } status_cbdata_t; 2379 2380 /* 2381 * Print out detailed scrub status. 2382 */ 2383 void 2384 print_scrub_status(nvlist_t *nvroot) 2385 { 2386 vdev_stat_t *vs; 2387 uint_t vsc; 2388 time_t start, end, now; 2389 double fraction_done; 2390 uint64_t examined, total, minutes_left; 2391 char *scrub_type; 2392 2393 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2394 (uint64_t **)&vs, &vsc) == 0); 2395 2396 /* 2397 * If there's never been a scrub, there's not much to say. 2398 */ 2399 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) { 2400 (void) printf(gettext("none requested\n")); 2401 return; 2402 } 2403 2404 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2405 "resilver" : "scrub"; 2406 2407 start = vs->vs_scrub_start; 2408 end = vs->vs_scrub_end; 2409 now = time(NULL); 2410 examined = vs->vs_scrub_examined; 2411 total = vs->vs_alloc; 2412 2413 if (end != 0) { 2414 (void) printf(gettext("%s %s with %llu errors on %s"), 2415 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2416 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2417 return; 2418 } 2419 2420 if (examined == 0) 2421 examined = 1; 2422 if (examined > total) 2423 total = examined; 2424 2425 fraction_done = (double)examined / total; 2426 minutes_left = (uint64_t)((now - start) * 2427 (1 - fraction_done) / fraction_done / 60); 2428 2429 (void) printf(gettext("%s in progress, %.2f%% done, %lluh%um to go\n"), 2430 scrub_type, 100 * fraction_done, 2431 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2432 } 2433 2434 typedef struct spare_cbdata { 2435 uint64_t cb_guid; 2436 zpool_handle_t *cb_zhp; 2437 } spare_cbdata_t; 2438 2439 static boolean_t 2440 find_vdev(nvlist_t *nv, uint64_t search) 2441 { 2442 uint64_t guid; 2443 nvlist_t **child; 2444 uint_t c, children; 2445 2446 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 2447 search == guid) 2448 return (B_TRUE); 2449 2450 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2451 &child, &children) == 0) { 2452 for (c = 0; c < children; c++) 2453 if (find_vdev(child[c], search)) 2454 return (B_TRUE); 2455 } 2456 2457 return (B_FALSE); 2458 } 2459 2460 static int 2461 find_spare(zpool_handle_t *zhp, void *data) 2462 { 2463 spare_cbdata_t *cbp = data; 2464 nvlist_t *config, *nvroot; 2465 2466 config = zpool_get_config(zhp, NULL); 2467 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2468 &nvroot) == 0); 2469 2470 if (find_vdev(nvroot, cbp->cb_guid)) { 2471 cbp->cb_zhp = zhp; 2472 return (1); 2473 } 2474 2475 zpool_close(zhp); 2476 return (0); 2477 } 2478 2479 /* 2480 * Print out configuration state as requested by status_callback. 2481 */ 2482 void 2483 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 2484 int namewidth, int depth, boolean_t isspare) 2485 { 2486 nvlist_t **child; 2487 uint_t c, children; 2488 vdev_stat_t *vs; 2489 char rbuf[6], wbuf[6], cbuf[6], repaired[7]; 2490 char *vname; 2491 uint64_t notpresent; 2492 spare_cbdata_t cb; 2493 const char *state; 2494 2495 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 2496 (uint64_t **)&vs, &c) == 0); 2497 2498 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2499 &child, &children) != 0) 2500 children = 0; 2501 2502 state = state_to_name(vs); 2503 if (isspare) { 2504 /* 2505 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 2506 * online drives. 2507 */ 2508 if (vs->vs_aux == VDEV_AUX_SPARED) 2509 state = "INUSE"; 2510 else if (vs->vs_state == VDEV_STATE_HEALTHY) 2511 state = "AVAIL"; 2512 } 2513 2514 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 2515 name, state); 2516 2517 if (!isspare) { 2518 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 2519 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 2520 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 2521 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 2522 } 2523 2524 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2525 ¬present) == 0) { 2526 char *path; 2527 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2528 (void) printf(" was %s", path); 2529 } else if (vs->vs_aux != 0) { 2530 (void) printf(" "); 2531 2532 switch (vs->vs_aux) { 2533 case VDEV_AUX_OPEN_FAILED: 2534 (void) printf(gettext("cannot open")); 2535 break; 2536 2537 case VDEV_AUX_BAD_GUID_SUM: 2538 (void) printf(gettext("missing device")); 2539 break; 2540 2541 case VDEV_AUX_NO_REPLICAS: 2542 (void) printf(gettext("insufficient replicas")); 2543 break; 2544 2545 case VDEV_AUX_VERSION_NEWER: 2546 (void) printf(gettext("newer version")); 2547 break; 2548 2549 case VDEV_AUX_SPARED: 2550 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2551 &cb.cb_guid) == 0); 2552 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 2553 if (strcmp(zpool_get_name(cb.cb_zhp), 2554 zpool_get_name(zhp)) == 0) 2555 (void) printf(gettext("currently in " 2556 "use")); 2557 else 2558 (void) printf(gettext("in use by " 2559 "pool '%s'"), 2560 zpool_get_name(cb.cb_zhp)); 2561 zpool_close(cb.cb_zhp); 2562 } else { 2563 (void) printf(gettext("currently in use")); 2564 } 2565 break; 2566 2567 default: 2568 (void) printf(gettext("corrupted data")); 2569 break; 2570 } 2571 } else if (vs->vs_scrub_repaired != 0 && children == 0) { 2572 /* 2573 * Report bytes resilvered/repaired on leaf devices. 2574 */ 2575 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired)); 2576 (void) printf(gettext(" %s %s"), repaired, 2577 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2578 "resilvered" : "repaired"); 2579 } 2580 2581 (void) printf("\n"); 2582 2583 for (c = 0; c < children; c++) { 2584 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 2585 print_status_config(zhp, vname, child[c], 2586 namewidth, depth + 2, isspare); 2587 free(vname); 2588 } 2589 } 2590 2591 static void 2592 print_error_log(zpool_handle_t *zhp) 2593 { 2594 nvlist_t **log; 2595 size_t nelem; 2596 size_t maxdsname = sizeof ("DATASET") - 1; 2597 size_t maxobjname = sizeof ("OBJECT") - 1; 2598 int i; 2599 nvlist_t *nv; 2600 size_t len; 2601 char *dsname, *objname, *range; 2602 2603 if (zpool_get_errlog(zhp, &log, &nelem) != 0) { 2604 (void) printf("errors: List of errors unavailable " 2605 "(insufficient privileges)\n"); 2606 return; 2607 } 2608 2609 for (i = 0; i < nelem; i++) { 2610 nv = log[i]; 2611 2612 verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET, 2613 &dsname) == 0); 2614 len = strlen(dsname); 2615 if (len > maxdsname) 2616 maxdsname = len; 2617 2618 verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT, 2619 &objname) == 0); 2620 len = strlen(objname); 2621 if (len > maxobjname) 2622 maxobjname = len; 2623 } 2624 2625 (void) printf("errors: The following persistent errors have been " 2626 "detected:\n\n"); 2627 (void) printf("%8s %-*s %-*s %s\n", "", maxdsname, "DATASET", 2628 maxobjname, "OBJECT", "RANGE"); 2629 2630 for (i = 0; i < nelem; i++) { 2631 nv = log[i]; 2632 2633 verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET, 2634 &dsname) == 0); 2635 verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT, 2636 &objname) == 0); 2637 verify(nvlist_lookup_string(nv, ZPOOL_ERR_RANGE, 2638 &range) == 0); 2639 2640 (void) printf("%8s %-*s %-*s %s\n", "", maxdsname, 2641 dsname, maxobjname, objname, range); 2642 } 2643 } 2644 2645 static void 2646 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2647 int namewidth) 2648 { 2649 uint_t i; 2650 char *name; 2651 2652 if (nspares == 0) 2653 return; 2654 2655 (void) printf(gettext("\tspares\n")); 2656 2657 for (i = 0; i < nspares; i++) { 2658 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2659 print_status_config(zhp, name, spares[i], 2660 namewidth, 2, B_TRUE); 2661 free(name); 2662 } 2663 } 2664 2665 /* 2666 * Display a summary of pool status. Displays a summary such as: 2667 * 2668 * pool: tank 2669 * status: DEGRADED 2670 * reason: One or more devices ... 2671 * see: http://www.sun.com/msg/ZFS-xxxx-01 2672 * config: 2673 * mirror DEGRADED 2674 * c1t0d0 OK 2675 * c2t0d0 UNAVAIL 2676 * 2677 * When given the '-v' option, we print out the complete config. If the '-e' 2678 * option is specified, then we print out error rate information as well. 2679 */ 2680 int 2681 status_callback(zpool_handle_t *zhp, void *data) 2682 { 2683 status_cbdata_t *cbp = data; 2684 nvlist_t *config, *nvroot; 2685 char *msgid; 2686 int reason; 2687 char *health; 2688 2689 config = zpool_get_config(zhp, NULL); 2690 reason = zpool_get_status(zhp, &msgid); 2691 2692 cbp->cb_count++; 2693 2694 /* 2695 * If we were given 'zpool status -x', only report those pools with 2696 * problems. 2697 */ 2698 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) { 2699 if (!cbp->cb_allpools) { 2700 (void) printf(gettext("pool '%s' is healthy\n"), 2701 zpool_get_name(zhp)); 2702 if (cbp->cb_first) 2703 cbp->cb_first = B_FALSE; 2704 } 2705 return (0); 2706 } 2707 2708 if (cbp->cb_first) 2709 cbp->cb_first = B_FALSE; 2710 else 2711 (void) printf("\n"); 2712 2713 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_HEALTH, 2714 &health) == 0); 2715 2716 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 2717 (void) printf(gettext(" state: %s\n"), health); 2718 2719 switch (reason) { 2720 case ZPOOL_STATUS_MISSING_DEV_R: 2721 (void) printf(gettext("status: One or more devices could not " 2722 "be opened. Sufficient replicas exist for\n\tthe pool to " 2723 "continue functioning in a degraded state.\n")); 2724 (void) printf(gettext("action: Attach the missing device and " 2725 "online it using 'zpool online'.\n")); 2726 break; 2727 2728 case ZPOOL_STATUS_MISSING_DEV_NR: 2729 (void) printf(gettext("status: One or more devices could not " 2730 "be opened. There are insufficient\n\treplicas for the " 2731 "pool to continue functioning.\n")); 2732 (void) printf(gettext("action: Attach the missing device and " 2733 "online it using 'zpool online'.\n")); 2734 break; 2735 2736 case ZPOOL_STATUS_CORRUPT_LABEL_R: 2737 (void) printf(gettext("status: One or more devices could not " 2738 "be used because the label is missing or\n\tinvalid. " 2739 "Sufficient replicas exist for the pool to continue\n\t" 2740 "functioning in a degraded state.\n")); 2741 (void) printf(gettext("action: Replace the device using " 2742 "'zpool replace'.\n")); 2743 break; 2744 2745 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 2746 (void) printf(gettext("status: One or more devices could not " 2747 "be used because the the label is missing \n\tor invalid. " 2748 "There are insufficient replicas for the pool to " 2749 "continue\n\tfunctioning.\n")); 2750 (void) printf(gettext("action: Destroy and re-create the pool " 2751 "from a backup source.\n")); 2752 break; 2753 2754 case ZPOOL_STATUS_FAILING_DEV: 2755 (void) printf(gettext("status: One or more devices has " 2756 "experienced an unrecoverable error. An\n\tattempt was " 2757 "made to correct the error. Applications are " 2758 "unaffected.\n")); 2759 (void) printf(gettext("action: Determine if the device needs " 2760 "to be replaced, and clear the errors\n\tusing " 2761 "'zpool clear' or replace the device with 'zpool " 2762 "replace'.\n")); 2763 break; 2764 2765 case ZPOOL_STATUS_OFFLINE_DEV: 2766 (void) printf(gettext("status: One or more devices has " 2767 "been taken offline by the adminstrator.\n\tSufficient " 2768 "replicas exist for the pool to continue functioning in " 2769 "a\n\tdegraded state.\n")); 2770 (void) printf(gettext("action: Online the device using " 2771 "'zpool online' or replace the device with\n\t'zpool " 2772 "replace'.\n")); 2773 break; 2774 2775 case ZPOOL_STATUS_RESILVERING: 2776 (void) printf(gettext("status: One or more devices is " 2777 "currently being resilvered. The pool will\n\tcontinue " 2778 "to function, possibly in a degraded state.\n")); 2779 (void) printf(gettext("action: Wait for the resilver to " 2780 "complete.\n")); 2781 break; 2782 2783 case ZPOOL_STATUS_CORRUPT_DATA: 2784 (void) printf(gettext("status: One or more devices has " 2785 "experienced an error resulting in data\n\tcorruption. " 2786 "Applications may be affected.\n")); 2787 (void) printf(gettext("action: Restore the file in question " 2788 "if possible. Otherwise restore the\n\tentire pool from " 2789 "backup.\n")); 2790 break; 2791 2792 case ZPOOL_STATUS_CORRUPT_POOL: 2793 (void) printf(gettext("status: The pool metadata is corrupted " 2794 "and the pool cannot be opened.\n")); 2795 (void) printf(gettext("action: Destroy and re-create the pool " 2796 "from a backup source.\n")); 2797 break; 2798 2799 case ZPOOL_STATUS_VERSION_OLDER: 2800 (void) printf(gettext("status: The pool is formatted using an " 2801 "older on-disk format. The pool can\n\tstill be used, but " 2802 "some features are unavailable.\n")); 2803 (void) printf(gettext("action: Upgrade the pool using 'zpool " 2804 "upgrade'. Once this is done, the\n\tpool will no longer " 2805 "be accessible on older software versions.\n")); 2806 break; 2807 2808 case ZPOOL_STATUS_VERSION_NEWER: 2809 (void) printf(gettext("status: The pool has been upgraded to a " 2810 "newer, incompatible on-disk version.\n\tThe pool cannot " 2811 "be accessed on this system.\n")); 2812 (void) printf(gettext("action: Access the pool from a system " 2813 "running more recent software, or\n\trestore the pool from " 2814 "backup.\n")); 2815 break; 2816 2817 default: 2818 /* 2819 * The remaining errors can't actually be generated, yet. 2820 */ 2821 assert(reason == ZPOOL_STATUS_OK); 2822 } 2823 2824 if (msgid != NULL) 2825 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 2826 msgid); 2827 2828 if (config != NULL) { 2829 int namewidth; 2830 uint64_t nerr; 2831 size_t realerr; 2832 nvlist_t **spares; 2833 uint_t nspares; 2834 2835 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2836 &nvroot) == 0); 2837 2838 (void) printf(gettext(" scrub: ")); 2839 print_scrub_status(nvroot); 2840 2841 namewidth = max_width(zhp, nvroot, 0, 0); 2842 if (namewidth < 10) 2843 namewidth = 10; 2844 2845 (void) printf(gettext("config:\n\n")); 2846 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 2847 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 2848 print_status_config(zhp, zpool_get_name(zhp), nvroot, 2849 namewidth, 0, B_FALSE); 2850 2851 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 2852 &spares, &nspares) == 0) 2853 print_spares(zhp, spares, nspares, namewidth); 2854 2855 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 2856 &nerr) == 0) { 2857 /* 2858 * If the approximate error count is small, get a 2859 * precise count by fetching the entire log and 2860 * uniquifying the results. 2861 */ 2862 if (nerr < 100 && !cbp->cb_verbose && 2863 zpool_get_errlog(zhp, NULL, &realerr) == 0) 2864 nerr = realerr; 2865 2866 (void) printf("\n"); 2867 2868 if (nerr == 0) 2869 (void) printf(gettext("errors: No known data " 2870 "errors\n")); 2871 else if (!cbp->cb_verbose) 2872 (void) printf(gettext("errors: %llu data " 2873 "errors, use '-v' for a list\n"), nerr); 2874 else 2875 print_error_log(zhp); 2876 } 2877 } else { 2878 (void) printf(gettext("config: The configuration cannot be " 2879 "determined.\n")); 2880 } 2881 2882 return (0); 2883 } 2884 2885 /* 2886 * zpool status [-vx] [pool] ... 2887 * 2888 * -v Display complete error logs 2889 * -x Display only pools with potential problems 2890 * 2891 * Describes the health status of all pools or some subset. 2892 */ 2893 int 2894 zpool_do_status(int argc, char **argv) 2895 { 2896 int c; 2897 int ret; 2898 status_cbdata_t cb = { 0 }; 2899 2900 /* check options */ 2901 while ((c = getopt(argc, argv, "vx")) != -1) { 2902 switch (c) { 2903 case 'v': 2904 cb.cb_verbose = B_TRUE; 2905 break; 2906 case 'x': 2907 cb.cb_explain = B_TRUE; 2908 break; 2909 case '?': 2910 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2911 optopt); 2912 usage(B_FALSE); 2913 } 2914 } 2915 2916 argc -= optind; 2917 argv += optind; 2918 2919 cb.cb_first = B_TRUE; 2920 2921 if (argc == 0) 2922 cb.cb_allpools = B_TRUE; 2923 2924 ret = for_each_pool(argc, argv, B_TRUE, status_callback, &cb); 2925 2926 if (argc == 0 && cb.cb_count == 0) 2927 (void) printf(gettext("no pools available\n")); 2928 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 2929 (void) printf(gettext("all pools are healthy\n")); 2930 2931 return (ret); 2932 } 2933 2934 typedef struct upgrade_cbdata { 2935 int cb_all; 2936 int cb_first; 2937 int cb_newer; 2938 } upgrade_cbdata_t; 2939 2940 static int 2941 upgrade_cb(zpool_handle_t *zhp, void *arg) 2942 { 2943 upgrade_cbdata_t *cbp = arg; 2944 nvlist_t *config; 2945 uint64_t version; 2946 int ret = 0; 2947 2948 config = zpool_get_config(zhp, NULL); 2949 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 2950 &version) == 0); 2951 2952 if (!cbp->cb_newer && version < ZFS_VERSION) { 2953 if (!cbp->cb_all) { 2954 if (cbp->cb_first) { 2955 (void) printf(gettext("The following pools are " 2956 "out of date, and can be upgraded. After " 2957 "being\nupgraded, these pools will no " 2958 "longer be accessible by older software " 2959 "versions.\n\n")); 2960 (void) printf(gettext("VER POOL\n")); 2961 (void) printf(gettext("--- ------------\n")); 2962 cbp->cb_first = B_FALSE; 2963 } 2964 2965 (void) printf("%2llu %s\n", version, 2966 zpool_get_name(zhp)); 2967 } else { 2968 cbp->cb_first = B_FALSE; 2969 ret = zpool_upgrade(zhp); 2970 if (ret == 0) 2971 (void) printf(gettext("Successfully upgraded " 2972 "'%s'\n"), zpool_get_name(zhp)); 2973 } 2974 } else if (cbp->cb_newer && version > ZFS_VERSION) { 2975 assert(!cbp->cb_all); 2976 2977 if (cbp->cb_first) { 2978 (void) printf(gettext("The following pools are " 2979 "formatted using a newer software version and\n" 2980 "cannot be accessed on the current system.\n\n")); 2981 (void) printf(gettext("VER POOL\n")); 2982 (void) printf(gettext("--- ------------\n")); 2983 cbp->cb_first = B_FALSE; 2984 } 2985 2986 (void) printf("%2llu %s\n", version, 2987 zpool_get_name(zhp)); 2988 } 2989 2990 zpool_close(zhp); 2991 return (ret); 2992 } 2993 2994 /* ARGSUSED */ 2995 static int 2996 upgrade_one(zpool_handle_t *zhp, void *unused) 2997 { 2998 nvlist_t *config; 2999 uint64_t version; 3000 int ret; 3001 3002 config = zpool_get_config(zhp, NULL); 3003 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3004 &version) == 0); 3005 3006 if (version == ZFS_VERSION) { 3007 (void) printf(gettext("Pool '%s' is already formatted " 3008 "using the current version.\n"), zpool_get_name(zhp)); 3009 return (0); 3010 } 3011 3012 ret = zpool_upgrade(zhp); 3013 if (ret == 0) 3014 (void) printf(gettext("Successfully upgraded '%s' " 3015 "from version %llu to version %llu\n"), zpool_get_name(zhp), 3016 (u_longlong_t)version, (u_longlong_t)ZFS_VERSION); 3017 3018 return (ret != 0); 3019 } 3020 3021 /* 3022 * zpool upgrade 3023 * zpool upgrade -v 3024 * zpool upgrade <-a | pool> 3025 * 3026 * With no arguments, display downrev'd ZFS pool available for upgrade. 3027 * Individual pools can be upgraded by specifying the pool, and '-a' will 3028 * upgrade all pools. 3029 */ 3030 int 3031 zpool_do_upgrade(int argc, char **argv) 3032 { 3033 int c; 3034 upgrade_cbdata_t cb = { 0 }; 3035 int ret = 0; 3036 boolean_t showversions = B_FALSE; 3037 3038 /* check options */ 3039 while ((c = getopt(argc, argv, "av")) != -1) { 3040 switch (c) { 3041 case 'a': 3042 cb.cb_all = B_TRUE; 3043 break; 3044 case 'v': 3045 showversions = B_TRUE; 3046 break; 3047 case '?': 3048 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3049 optopt); 3050 usage(B_FALSE); 3051 } 3052 } 3053 3054 argc -= optind; 3055 argv += optind; 3056 3057 if (showversions) { 3058 if (cb.cb_all || argc != 0) { 3059 (void) fprintf(stderr, gettext("-v option is " 3060 "incompatible with other arguments\n")); 3061 usage(B_FALSE); 3062 } 3063 } else if (cb.cb_all) { 3064 if (argc != 0) { 3065 (void) fprintf(stderr, gettext("-a option is " 3066 "incompatible with other arguments\n")); 3067 usage(B_FALSE); 3068 } 3069 } 3070 3071 (void) printf(gettext("This system is currently running ZFS version " 3072 "%llu.\n\n"), ZFS_VERSION); 3073 cb.cb_first = B_TRUE; 3074 if (showversions) { 3075 (void) printf(gettext("The following versions are " 3076 "suppored:\n\n")); 3077 (void) printf(gettext("VER DESCRIPTION\n")); 3078 (void) printf("--- -----------------------------------------" 3079 "---------------\n"); 3080 (void) printf(gettext(" 1 Initial ZFS version\n")); 3081 (void) printf(gettext(" 2 Ditto blocks " 3082 "(replicated metadata)\n")); 3083 (void) printf(gettext(" 3 Hot spares and double parity " 3084 "RAID-Z\n")); 3085 (void) printf(gettext("\nFor more information on a particular " 3086 "version, including supported releases, see:\n\n")); 3087 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3088 "version/N\n\n"); 3089 (void) printf(gettext("Where 'N' is the version number.\n")); 3090 } else if (argc == 0) { 3091 int notfound; 3092 3093 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3094 notfound = cb.cb_first; 3095 3096 if (!cb.cb_all && ret == 0) { 3097 if (!cb.cb_first) 3098 (void) printf("\n"); 3099 cb.cb_first = B_TRUE; 3100 cb.cb_newer = B_TRUE; 3101 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3102 if (!cb.cb_first) { 3103 notfound = B_FALSE; 3104 (void) printf("\n"); 3105 } 3106 } 3107 3108 if (ret == 0) { 3109 if (notfound) 3110 (void) printf(gettext("All pools are formatted " 3111 "using this version.\n")); 3112 else if (!cb.cb_all) 3113 (void) printf(gettext("Use 'zpool upgrade -v' " 3114 "for a list of available versions and " 3115 "their associated\nfeatures.\n")); 3116 } 3117 } else { 3118 ret = for_each_pool(argc, argv, B_FALSE, upgrade_one, NULL); 3119 } 3120 3121 return (ret); 3122 } 3123 3124 int 3125 main(int argc, char **argv) 3126 { 3127 int ret; 3128 int i; 3129 char *cmdname; 3130 3131 (void) setlocale(LC_ALL, ""); 3132 (void) textdomain(TEXT_DOMAIN); 3133 3134 if ((g_zfs = libzfs_init()) == NULL) { 3135 (void) fprintf(stderr, gettext("internal error: failed to " 3136 "initialize ZFS library\n")); 3137 return (1); 3138 } 3139 3140 libzfs_print_on_error(g_zfs, B_TRUE); 3141 3142 opterr = 0; 3143 3144 /* 3145 * Make sure the user has specified some command. 3146 */ 3147 if (argc < 2) { 3148 (void) fprintf(stderr, gettext("missing command\n")); 3149 usage(B_FALSE); 3150 } 3151 3152 cmdname = argv[1]; 3153 3154 /* 3155 * Special case '-?' 3156 */ 3157 if (strcmp(cmdname, "-?") == 0) 3158 usage(B_TRUE); 3159 3160 /* 3161 * Run the appropriate command. 3162 */ 3163 for (i = 0; i < NCOMMAND; i++) { 3164 if (command_table[i].name == NULL) 3165 continue; 3166 3167 if (strcmp(cmdname, command_table[i].name) == 0) { 3168 current_command = &command_table[i]; 3169 ret = command_table[i].func(argc - 1, argv + 1); 3170 break; 3171 } 3172 } 3173 3174 /* 3175 * 'freeze' is a vile debugging abomination, so we treat it as such. 3176 */ 3177 if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3178 char buf[16384]; 3179 int fd = open(ZFS_DEV, O_RDWR); 3180 (void) strcpy((void *)buf, argv[2]); 3181 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3182 } 3183 3184 if (i == NCOMMAND) { 3185 (void) fprintf(stderr, gettext("unrecognized " 3186 "command '%s'\n"), cmdname); 3187 usage(B_FALSE); 3188 } 3189 3190 libzfs_fini(g_zfs); 3191 3192 /* 3193 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3194 * for the purposes of running ::findleaks. 3195 */ 3196 if (getenv("ZFS_ABORT") != NULL) { 3197 (void) printf("dumping core by request\n"); 3198 abort(); 3199 } 3200 3201 return (ret); 3202 } 3203