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