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 1476 /* 1477 * If the pool has disappeared, remove it from the list and continue. 1478 */ 1479 if (zpool_refresh_stats(zhp) != 0) 1480 pool_list_remove(cb->cb_list, zhp); 1481 1482 return (0); 1483 } 1484 1485 /* 1486 * Callback to print out the iostats for the given pool. 1487 */ 1488 int 1489 print_iostat(zpool_handle_t *zhp, void *data) 1490 { 1491 iostat_cbdata_t *cb = data; 1492 nvlist_t *oldconfig, *newconfig; 1493 nvlist_t *oldnvroot, *newnvroot; 1494 1495 newconfig = zpool_get_config(zhp, &oldconfig); 1496 1497 if (cb->cb_iteration == 1) 1498 oldconfig = NULL; 1499 1500 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 1501 &newnvroot) == 0); 1502 1503 if (oldconfig == NULL) 1504 oldnvroot = NULL; 1505 else 1506 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 1507 &oldnvroot) == 0); 1508 1509 /* 1510 * Print out the statistics for the pool. 1511 */ 1512 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 1513 1514 if (cb->cb_verbose) 1515 print_iostat_separator(cb); 1516 1517 return (0); 1518 } 1519 1520 int 1521 get_namewidth(zpool_handle_t *zhp, void *data) 1522 { 1523 iostat_cbdata_t *cb = data; 1524 nvlist_t *config, *nvroot; 1525 1526 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 1527 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1528 &nvroot) == 0); 1529 if (!cb->cb_verbose) 1530 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 1531 else 1532 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0); 1533 } 1534 1535 /* 1536 * The width must fall into the range [10,38]. The upper limit is the 1537 * maximum we can have and still fit in 80 columns. 1538 */ 1539 if (cb->cb_namewidth < 10) 1540 cb->cb_namewidth = 10; 1541 if (cb->cb_namewidth > 38) 1542 cb->cb_namewidth = 38; 1543 1544 return (0); 1545 } 1546 1547 /* 1548 * zpool iostat [-v] [pool] ... [interval [count]] 1549 * 1550 * -v Display statistics for individual vdevs 1551 * 1552 * This command can be tricky because we want to be able to deal with pool 1553 * creation/destruction as well as vdev configuration changes. The bulk of this 1554 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 1555 * on pool_list_update() to detect the addition of new pools. Configuration 1556 * changes are all handled within libzfs. 1557 */ 1558 int 1559 zpool_do_iostat(int argc, char **argv) 1560 { 1561 int c; 1562 int ret; 1563 int npools; 1564 unsigned long interval = 0, count = 0; 1565 zpool_list_t *list; 1566 boolean_t verbose = B_FALSE; 1567 iostat_cbdata_t cb; 1568 1569 /* check options */ 1570 while ((c = getopt(argc, argv, "v")) != -1) { 1571 switch (c) { 1572 case 'v': 1573 verbose = B_TRUE; 1574 break; 1575 case '?': 1576 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1577 optopt); 1578 usage(B_FALSE); 1579 } 1580 } 1581 1582 argc -= optind; 1583 argv += optind; 1584 1585 /* 1586 * Determine if the last argument is an integer or a pool name 1587 */ 1588 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1589 char *end; 1590 1591 errno = 0; 1592 interval = strtoul(argv[argc - 1], &end, 10); 1593 1594 if (*end == '\0' && errno == 0) { 1595 if (interval == 0) { 1596 (void) fprintf(stderr, gettext("interval " 1597 "cannot be zero\n")); 1598 usage(B_FALSE); 1599 } 1600 1601 /* 1602 * Ignore the last parameter 1603 */ 1604 argc--; 1605 } else { 1606 /* 1607 * If this is not a valid number, just plow on. The 1608 * user will get a more informative error message later 1609 * on. 1610 */ 1611 interval = 0; 1612 } 1613 } 1614 1615 /* 1616 * If the last argument is also an integer, then we have both a count 1617 * and an integer. 1618 */ 1619 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1620 char *end; 1621 1622 errno = 0; 1623 count = interval; 1624 interval = strtoul(argv[argc - 1], &end, 10); 1625 1626 if (*end == '\0' && errno == 0) { 1627 if (interval == 0) { 1628 (void) fprintf(stderr, gettext("interval " 1629 "cannot be zero\n")); 1630 usage(B_FALSE); 1631 } 1632 1633 /* 1634 * Ignore the last parameter 1635 */ 1636 argc--; 1637 } else { 1638 interval = 0; 1639 } 1640 } 1641 1642 /* 1643 * Construct the list of all interesting pools. 1644 */ 1645 ret = 0; 1646 if ((list = pool_list_get(argc, argv, &ret)) == NULL) 1647 return (1); 1648 1649 if (pool_list_count(list) == 0 && argc != 0) { 1650 pool_list_free(list); 1651 return (1); 1652 } 1653 1654 if (pool_list_count(list) == 0 && interval == 0) { 1655 pool_list_free(list); 1656 (void) fprintf(stderr, gettext("no pools available\n")); 1657 return (1); 1658 } 1659 1660 /* 1661 * Enter the main iostat loop. 1662 */ 1663 cb.cb_list = list; 1664 cb.cb_verbose = verbose; 1665 cb.cb_iteration = 0; 1666 cb.cb_namewidth = 0; 1667 1668 for (;;) { 1669 pool_list_update(list); 1670 1671 if ((npools = pool_list_count(list)) == 0) 1672 break; 1673 1674 /* 1675 * Refresh all statistics. This is done as an explicit step 1676 * before calculating the maximum name width, so that any 1677 * configuration changes are properly accounted for. 1678 */ 1679 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 1680 1681 /* 1682 * Iterate over all pools to determine the maximum width 1683 * for the pool / device name column across all pools. 1684 */ 1685 cb.cb_namewidth = 0; 1686 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 1687 1688 /* 1689 * If it's the first time, or verbose mode, print the header. 1690 */ 1691 if (++cb.cb_iteration == 1 || verbose) 1692 print_iostat_header(&cb); 1693 1694 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 1695 1696 /* 1697 * If there's more than one pool, and we're not in verbose mode 1698 * (which prints a separator for us), then print a separator. 1699 */ 1700 if (npools > 1 && !verbose) 1701 print_iostat_separator(&cb); 1702 1703 if (verbose) 1704 (void) printf("\n"); 1705 1706 if (interval == 0) 1707 break; 1708 1709 if (count != 0 && --count == 0) 1710 break; 1711 1712 (void) sleep(interval); 1713 } 1714 1715 pool_list_free(list); 1716 1717 return (ret); 1718 } 1719 1720 typedef struct list_cbdata { 1721 boolean_t cb_scripted; 1722 boolean_t cb_first; 1723 int cb_fields[MAX_FIELDS]; 1724 int cb_fieldcount; 1725 } list_cbdata_t; 1726 1727 /* 1728 * Given a list of columns to display, output appropriate headers for each one. 1729 */ 1730 void 1731 print_header(int *fields, size_t count) 1732 { 1733 int i; 1734 column_def_t *col; 1735 const char *fmt; 1736 1737 for (i = 0; i < count; i++) { 1738 col = &column_table[fields[i]]; 1739 if (i != 0) 1740 (void) printf(" "); 1741 if (col->cd_justify == left_justify) 1742 fmt = "%-*s"; 1743 else 1744 fmt = "%*s"; 1745 1746 (void) printf(fmt, i == count - 1 ? strlen(col->cd_title) : 1747 col->cd_width, col->cd_title); 1748 } 1749 1750 (void) printf("\n"); 1751 } 1752 1753 int 1754 list_callback(zpool_handle_t *zhp, void *data) 1755 { 1756 list_cbdata_t *cbp = data; 1757 nvlist_t *config; 1758 int i; 1759 char buf[ZPOOL_MAXNAMELEN]; 1760 uint64_t total; 1761 uint64_t used; 1762 const char *fmt; 1763 column_def_t *col; 1764 1765 if (cbp->cb_first) { 1766 if (!cbp->cb_scripted) 1767 print_header(cbp->cb_fields, cbp->cb_fieldcount); 1768 cbp->cb_first = B_FALSE; 1769 } 1770 1771 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 1772 config = NULL; 1773 } else { 1774 config = zpool_get_config(zhp, NULL); 1775 total = zpool_get_space_total(zhp); 1776 used = zpool_get_space_used(zhp); 1777 } 1778 1779 for (i = 0; i < cbp->cb_fieldcount; i++) { 1780 if (i != 0) { 1781 if (cbp->cb_scripted) 1782 (void) printf("\t"); 1783 else 1784 (void) printf(" "); 1785 } 1786 1787 col = &column_table[cbp->cb_fields[i]]; 1788 1789 switch (cbp->cb_fields[i]) { 1790 case ZPOOL_FIELD_NAME: 1791 (void) strlcpy(buf, zpool_get_name(zhp), sizeof (buf)); 1792 break; 1793 1794 case ZPOOL_FIELD_SIZE: 1795 if (config == NULL) 1796 (void) strlcpy(buf, "-", sizeof (buf)); 1797 else 1798 zfs_nicenum(total, buf, sizeof (buf)); 1799 break; 1800 1801 case ZPOOL_FIELD_USED: 1802 if (config == NULL) 1803 (void) strlcpy(buf, "-", sizeof (buf)); 1804 else 1805 zfs_nicenum(used, buf, sizeof (buf)); 1806 break; 1807 1808 case ZPOOL_FIELD_AVAILABLE: 1809 if (config == NULL) 1810 (void) strlcpy(buf, "-", sizeof (buf)); 1811 else 1812 zfs_nicenum(total - used, buf, sizeof (buf)); 1813 break; 1814 1815 case ZPOOL_FIELD_CAPACITY: 1816 if (config == NULL) { 1817 (void) strlcpy(buf, "-", sizeof (buf)); 1818 } else { 1819 uint64_t capacity = (total == 0 ? 0 : 1820 (used * 100 / total)); 1821 (void) snprintf(buf, sizeof (buf), "%llu%%", 1822 capacity); 1823 } 1824 break; 1825 1826 case ZPOOL_FIELD_HEALTH: 1827 if (config == NULL) { 1828 (void) strlcpy(buf, "FAULTED", sizeof (buf)); 1829 } else { 1830 nvlist_t *nvroot; 1831 vdev_stat_t *vs; 1832 uint_t vsc; 1833 1834 verify(nvlist_lookup_nvlist(config, 1835 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); 1836 verify(nvlist_lookup_uint64_array(nvroot, 1837 ZPOOL_CONFIG_STATS, (uint64_t **)&vs, 1838 &vsc) == 0); 1839 (void) strlcpy(buf, state_to_name(vs), 1840 sizeof (buf)); 1841 } 1842 break; 1843 1844 case ZPOOL_FIELD_ROOT: 1845 if (config == NULL) 1846 (void) strlcpy(buf, "-", sizeof (buf)); 1847 else if (zpool_get_root(zhp, buf, sizeof (buf)) != 0) 1848 (void) strlcpy(buf, "-", sizeof (buf)); 1849 break; 1850 } 1851 1852 if (cbp->cb_scripted) 1853 (void) printf("%s", buf); 1854 else { 1855 if (col->cd_justify == left_justify) 1856 fmt = "%-*s"; 1857 else 1858 fmt = "%*s"; 1859 1860 (void) printf(fmt, i == cbp->cb_fieldcount - 1 ? 1861 strlen(buf) : col->cd_width, buf); 1862 } 1863 } 1864 1865 (void) printf("\n"); 1866 1867 return (0); 1868 } 1869 1870 /* 1871 * zpool list [-H] [-o field[,field]*] [pool] ... 1872 * 1873 * -H Scripted mode. Don't display headers, and separate fields by 1874 * a single tab. 1875 * -o List of fields to display. Defaults to all fields, or 1876 * "name,size,used,available,capacity,health,root" 1877 * 1878 * List all pools in the system, whether or not they're healthy. Output space 1879 * statistics for each one, as well as health status summary. 1880 */ 1881 int 1882 zpool_do_list(int argc, char **argv) 1883 { 1884 int c; 1885 int ret; 1886 list_cbdata_t cb = { 0 }; 1887 static char default_fields[] = 1888 "name,size,used,available,capacity,health,root"; 1889 char *fields = default_fields; 1890 char *value; 1891 1892 /* check options */ 1893 while ((c = getopt(argc, argv, ":Ho:")) != -1) { 1894 switch (c) { 1895 case 'H': 1896 cb.cb_scripted = B_TRUE; 1897 break; 1898 case 'o': 1899 fields = optarg; 1900 break; 1901 case ':': 1902 (void) fprintf(stderr, gettext("missing argument for " 1903 "'%c' option\n"), optopt); 1904 usage(B_FALSE); 1905 break; 1906 case '?': 1907 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1908 optopt); 1909 usage(B_FALSE); 1910 } 1911 } 1912 1913 argc -= optind; 1914 argv += optind; 1915 1916 while (*fields != '\0') { 1917 if (cb.cb_fieldcount == MAX_FIELDS) { 1918 (void) fprintf(stderr, gettext("too many " 1919 "properties given to -o option\n")); 1920 usage(B_FALSE); 1921 } 1922 1923 if ((cb.cb_fields[cb.cb_fieldcount] = getsubopt(&fields, 1924 column_subopts, &value)) == -1) { 1925 (void) fprintf(stderr, gettext("invalid property " 1926 "'%s'\n"), value); 1927 usage(B_FALSE); 1928 } 1929 1930 cb.cb_fieldcount++; 1931 } 1932 1933 1934 cb.cb_first = B_TRUE; 1935 1936 ret = for_each_pool(argc, argv, B_TRUE, list_callback, &cb); 1937 1938 if (argc == 0 && cb.cb_first) { 1939 (void) printf(gettext("no pools available\n")); 1940 return (0); 1941 } 1942 1943 return (ret); 1944 } 1945 1946 static nvlist_t * 1947 zpool_get_vdev_by_name(nvlist_t *nv, char *name) 1948 { 1949 nvlist_t **child; 1950 uint_t c, children; 1951 nvlist_t *match; 1952 char *path; 1953 1954 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1955 &child, &children) != 0) { 1956 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 1957 if (strncmp(name, "/dev/dsk/", 9) == 0) 1958 name += 9; 1959 if (strncmp(path, "/dev/dsk/", 9) == 0) 1960 path += 9; 1961 if (strcmp(name, path) == 0) 1962 return (nv); 1963 return (NULL); 1964 } 1965 1966 for (c = 0; c < children; c++) 1967 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL) 1968 return (match); 1969 1970 return (NULL); 1971 } 1972 1973 static int 1974 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 1975 { 1976 boolean_t force = B_FALSE; 1977 int c; 1978 nvlist_t *nvroot; 1979 char *poolname, *old_disk, *new_disk; 1980 zpool_handle_t *zhp; 1981 nvlist_t *config; 1982 int ret; 1983 1984 /* check options */ 1985 while ((c = getopt(argc, argv, "f")) != -1) { 1986 switch (c) { 1987 case 'f': 1988 force = B_TRUE; 1989 break; 1990 case '?': 1991 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1992 optopt); 1993 usage(B_FALSE); 1994 } 1995 } 1996 1997 argc -= optind; 1998 argv += optind; 1999 2000 /* get pool name and check number of arguments */ 2001 if (argc < 1) { 2002 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2003 usage(B_FALSE); 2004 } 2005 2006 poolname = argv[0]; 2007 2008 if (argc < 2) { 2009 (void) fprintf(stderr, 2010 gettext("missing <device> specification\n")); 2011 usage(B_FALSE); 2012 } 2013 2014 old_disk = argv[1]; 2015 2016 if (argc < 3) { 2017 if (!replacing) { 2018 (void) fprintf(stderr, 2019 gettext("missing <new_device> specification\n")); 2020 usage(B_FALSE); 2021 } 2022 new_disk = old_disk; 2023 argc -= 1; 2024 argv += 1; 2025 } else { 2026 new_disk = argv[2]; 2027 argc -= 2; 2028 argv += 2; 2029 } 2030 2031 if (argc > 1) { 2032 (void) fprintf(stderr, gettext("too many arguments\n")); 2033 usage(B_FALSE); 2034 } 2035 2036 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2037 return (1); 2038 2039 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 2040 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 2041 poolname); 2042 zpool_close(zhp); 2043 return (1); 2044 } 2045 2046 nvroot = make_root_vdev(config, force, B_FALSE, replacing, argc, argv); 2047 if (nvroot == NULL) { 2048 zpool_close(zhp); 2049 return (1); 2050 } 2051 2052 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 2053 2054 nvlist_free(nvroot); 2055 zpool_close(zhp); 2056 2057 return (ret); 2058 } 2059 2060 /* 2061 * zpool replace [-f] <pool> <device> <new_device> 2062 * 2063 * -f Force attach, even if <new_device> appears to be in use. 2064 * 2065 * Replace <device> with <new_device>. 2066 */ 2067 /* ARGSUSED */ 2068 int 2069 zpool_do_replace(int argc, char **argv) 2070 { 2071 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 2072 } 2073 2074 /* 2075 * zpool attach [-f] <pool> <device> <new_device> 2076 * 2077 * -f Force attach, even if <new_device> appears to be in use. 2078 * 2079 * Attach <new_device> to the mirror containing <device>. If <device> is not 2080 * part of a mirror, then <device> will be transformed into a mirror of 2081 * <device> and <new_device>. In either case, <new_device> will begin life 2082 * with a DTL of [0, now], and will immediately begin to resilver itself. 2083 */ 2084 int 2085 zpool_do_attach(int argc, char **argv) 2086 { 2087 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 2088 } 2089 2090 /* 2091 * zpool detach [-f] <pool> <device> 2092 * 2093 * -f Force detach of <device>, even if DTLs argue against it 2094 * (not supported yet) 2095 * 2096 * Detach a device from a mirror. The operation will be refused if <device> 2097 * is the last device in the mirror, or if the DTLs indicate that this device 2098 * has the only valid copy of some data. 2099 */ 2100 /* ARGSUSED */ 2101 int 2102 zpool_do_detach(int argc, char **argv) 2103 { 2104 int c; 2105 char *poolname, *path; 2106 zpool_handle_t *zhp; 2107 int ret; 2108 2109 /* check options */ 2110 while ((c = getopt(argc, argv, "f")) != -1) { 2111 switch (c) { 2112 case 'f': 2113 case '?': 2114 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2115 optopt); 2116 usage(B_FALSE); 2117 } 2118 } 2119 2120 argc -= optind; 2121 argv += optind; 2122 2123 /* get pool name and check number of arguments */ 2124 if (argc < 1) { 2125 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2126 usage(B_FALSE); 2127 } 2128 2129 if (argc < 2) { 2130 (void) fprintf(stderr, 2131 gettext("missing <device> specification\n")); 2132 usage(B_FALSE); 2133 } 2134 2135 poolname = argv[0]; 2136 path = argv[1]; 2137 2138 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2139 return (1); 2140 2141 ret = zpool_vdev_detach(zhp, path); 2142 2143 zpool_close(zhp); 2144 2145 return (ret); 2146 } 2147 2148 /* 2149 * zpool online <pool> <device> ... 2150 */ 2151 /* ARGSUSED */ 2152 int 2153 zpool_do_online(int argc, char **argv) 2154 { 2155 int c, i; 2156 char *poolname; 2157 zpool_handle_t *zhp; 2158 int ret = 0; 2159 2160 /* check options */ 2161 while ((c = getopt(argc, argv, "t")) != -1) { 2162 switch (c) { 2163 case 't': 2164 case '?': 2165 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2166 optopt); 2167 usage(B_FALSE); 2168 } 2169 } 2170 2171 argc -= optind; 2172 argv += optind; 2173 2174 /* get pool name and check number of arguments */ 2175 if (argc < 1) { 2176 (void) fprintf(stderr, gettext("missing pool name\n")); 2177 usage(B_FALSE); 2178 } 2179 if (argc < 2) { 2180 (void) fprintf(stderr, gettext("missing device name\n")); 2181 usage(B_FALSE); 2182 } 2183 2184 poolname = argv[0]; 2185 2186 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2187 return (1); 2188 2189 for (i = 1; i < argc; i++) 2190 if (zpool_vdev_online(zhp, argv[i]) == 0) 2191 (void) printf(gettext("Bringing device %s online\n"), 2192 argv[i]); 2193 else 2194 ret = 1; 2195 2196 zpool_close(zhp); 2197 2198 return (ret); 2199 } 2200 2201 /* 2202 * zpool offline [-ft] <pool> <device> ... 2203 * 2204 * -f Force the device into the offline state, even if doing 2205 * so would appear to compromise pool availability. 2206 * (not supported yet) 2207 * 2208 * -t Only take the device off-line temporarily. The offline 2209 * state will not be persistent across reboots. 2210 */ 2211 /* ARGSUSED */ 2212 int 2213 zpool_do_offline(int argc, char **argv) 2214 { 2215 int c, i; 2216 char *poolname; 2217 zpool_handle_t *zhp; 2218 int ret = 0; 2219 boolean_t istmp = B_FALSE; 2220 2221 /* check options */ 2222 while ((c = getopt(argc, argv, "ft")) != -1) { 2223 switch (c) { 2224 case 't': 2225 istmp = B_TRUE; 2226 break; 2227 case 'f': 2228 case '?': 2229 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2230 optopt); 2231 usage(B_FALSE); 2232 } 2233 } 2234 2235 argc -= optind; 2236 argv += optind; 2237 2238 /* get pool name and check number of arguments */ 2239 if (argc < 1) { 2240 (void) fprintf(stderr, gettext("missing pool name\n")); 2241 usage(B_FALSE); 2242 } 2243 if (argc < 2) { 2244 (void) fprintf(stderr, gettext("missing device name\n")); 2245 usage(B_FALSE); 2246 } 2247 2248 poolname = argv[0]; 2249 2250 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2251 return (1); 2252 2253 for (i = 1; i < argc; i++) 2254 if (zpool_vdev_offline(zhp, argv[i], istmp) == 0) 2255 (void) printf(gettext("Bringing device %s offline\n"), 2256 argv[i]); 2257 else 2258 ret = 1; 2259 2260 zpool_close(zhp); 2261 2262 return (ret); 2263 } 2264 2265 /* 2266 * zpool clear <pool> [device] 2267 * 2268 * Clear all errors associated with a pool or a particular device. 2269 */ 2270 int 2271 zpool_do_clear(int argc, char **argv) 2272 { 2273 int ret = 0; 2274 zpool_handle_t *zhp; 2275 char *pool, *device; 2276 2277 if (argc < 2) { 2278 (void) fprintf(stderr, gettext("missing pool name\n")); 2279 usage(B_FALSE); 2280 } 2281 2282 if (argc > 3) { 2283 (void) fprintf(stderr, gettext("too many arguments\n")); 2284 usage(B_FALSE); 2285 } 2286 2287 pool = argv[1]; 2288 device = argc == 3 ? argv[2] : NULL; 2289 2290 if ((zhp = zpool_open(g_zfs, pool)) == NULL) 2291 return (1); 2292 2293 if (zpool_clear(zhp, device) != 0) 2294 ret = 1; 2295 2296 zpool_close(zhp); 2297 2298 return (ret); 2299 } 2300 2301 typedef struct scrub_cbdata { 2302 int cb_type; 2303 } scrub_cbdata_t; 2304 2305 int 2306 scrub_callback(zpool_handle_t *zhp, void *data) 2307 { 2308 scrub_cbdata_t *cb = data; 2309 2310 /* 2311 * Ignore faulted pools. 2312 */ 2313 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 2314 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 2315 "currently unavailable\n"), zpool_get_name(zhp)); 2316 return (1); 2317 } 2318 2319 return (zpool_scrub(zhp, cb->cb_type) != 0); 2320 } 2321 2322 /* 2323 * zpool scrub [-s] <pool> ... 2324 * 2325 * -s Stop. Stops any in-progress scrub. 2326 */ 2327 int 2328 zpool_do_scrub(int argc, char **argv) 2329 { 2330 int c; 2331 scrub_cbdata_t cb; 2332 2333 cb.cb_type = POOL_SCRUB_EVERYTHING; 2334 2335 /* check options */ 2336 while ((c = getopt(argc, argv, "s")) != -1) { 2337 switch (c) { 2338 case 's': 2339 cb.cb_type = POOL_SCRUB_NONE; 2340 break; 2341 case '?': 2342 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2343 optopt); 2344 usage(B_FALSE); 2345 } 2346 } 2347 2348 argc -= optind; 2349 argv += optind; 2350 2351 if (argc < 1) { 2352 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2353 usage(B_FALSE); 2354 } 2355 2356 return (for_each_pool(argc, argv, B_TRUE, scrub_callback, &cb)); 2357 } 2358 2359 typedef struct status_cbdata { 2360 int cb_count; 2361 boolean_t cb_verbose; 2362 boolean_t cb_explain; 2363 boolean_t cb_first; 2364 } status_cbdata_t; 2365 2366 /* 2367 * Print out detailed scrub status. 2368 */ 2369 void 2370 print_scrub_status(nvlist_t *nvroot) 2371 { 2372 vdev_stat_t *vs; 2373 uint_t vsc; 2374 time_t start, end, now; 2375 double fraction_done; 2376 uint64_t examined, total, minutes_left; 2377 char *scrub_type; 2378 2379 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2380 (uint64_t **)&vs, &vsc) == 0); 2381 2382 /* 2383 * If there's never been a scrub, there's not much to say. 2384 */ 2385 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) { 2386 (void) printf(gettext("none requested\n")); 2387 return; 2388 } 2389 2390 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2391 "resilver" : "scrub"; 2392 2393 start = vs->vs_scrub_start; 2394 end = vs->vs_scrub_end; 2395 now = time(NULL); 2396 examined = vs->vs_scrub_examined; 2397 total = vs->vs_alloc; 2398 2399 if (end != 0) { 2400 (void) printf(gettext("%s %s with %llu errors on %s"), 2401 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2402 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2403 return; 2404 } 2405 2406 if (examined == 0) 2407 examined = 1; 2408 if (examined > total) 2409 total = examined; 2410 2411 fraction_done = (double)examined / total; 2412 minutes_left = (uint64_t)((now - start) * 2413 (1 - fraction_done) / fraction_done / 60); 2414 2415 (void) printf(gettext("%s in progress, %.2f%% done, %lluh%um to go\n"), 2416 scrub_type, 100 * fraction_done, 2417 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2418 } 2419 2420 typedef struct spare_cbdata { 2421 uint64_t cb_guid; 2422 zpool_handle_t *cb_zhp; 2423 } spare_cbdata_t; 2424 2425 static boolean_t 2426 find_vdev(nvlist_t *nv, uint64_t search) 2427 { 2428 uint64_t guid; 2429 nvlist_t **child; 2430 uint_t c, children; 2431 2432 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 2433 search == guid) 2434 return (B_TRUE); 2435 2436 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2437 &child, &children) == 0) { 2438 for (c = 0; c < children; c++) 2439 if (find_vdev(child[c], search)) 2440 return (B_TRUE); 2441 } 2442 2443 return (B_FALSE); 2444 } 2445 2446 static int 2447 find_spare(zpool_handle_t *zhp, void *data) 2448 { 2449 spare_cbdata_t *cbp = data; 2450 nvlist_t *config, *nvroot; 2451 2452 config = zpool_get_config(zhp, NULL); 2453 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2454 &nvroot) == 0); 2455 2456 if (find_vdev(nvroot, cbp->cb_guid)) { 2457 cbp->cb_zhp = zhp; 2458 return (1); 2459 } 2460 2461 zpool_close(zhp); 2462 return (0); 2463 } 2464 2465 /* 2466 * Print out configuration state as requested by status_callback. 2467 */ 2468 void 2469 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 2470 int namewidth, int depth, boolean_t isspare) 2471 { 2472 nvlist_t **child; 2473 uint_t c, children; 2474 vdev_stat_t *vs; 2475 char rbuf[6], wbuf[6], cbuf[6], repaired[7]; 2476 char *vname; 2477 uint64_t notpresent; 2478 spare_cbdata_t cb; 2479 const char *state; 2480 2481 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 2482 (uint64_t **)&vs, &c) == 0); 2483 2484 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2485 &child, &children) != 0) 2486 children = 0; 2487 2488 state = state_to_name(vs); 2489 if (isspare) { 2490 /* 2491 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 2492 * online drives. 2493 */ 2494 if (vs->vs_aux == VDEV_AUX_SPARED) 2495 state = "INUSE"; 2496 else if (vs->vs_state == VDEV_STATE_HEALTHY) 2497 state = "AVAIL"; 2498 } 2499 2500 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 2501 name, state); 2502 2503 if (!isspare) { 2504 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 2505 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 2506 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 2507 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 2508 } 2509 2510 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2511 ¬present) == 0) { 2512 char *path; 2513 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2514 (void) printf(" was %s", path); 2515 } else if (vs->vs_aux != 0) { 2516 (void) printf(" "); 2517 2518 switch (vs->vs_aux) { 2519 case VDEV_AUX_OPEN_FAILED: 2520 (void) printf(gettext("cannot open")); 2521 break; 2522 2523 case VDEV_AUX_BAD_GUID_SUM: 2524 (void) printf(gettext("missing device")); 2525 break; 2526 2527 case VDEV_AUX_NO_REPLICAS: 2528 (void) printf(gettext("insufficient replicas")); 2529 break; 2530 2531 case VDEV_AUX_VERSION_NEWER: 2532 (void) printf(gettext("newer version")); 2533 break; 2534 2535 case VDEV_AUX_SPARED: 2536 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2537 &cb.cb_guid) == 0); 2538 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 2539 if (strcmp(zpool_get_name(cb.cb_zhp), 2540 zpool_get_name(zhp)) == 0) 2541 (void) printf(gettext("currently in " 2542 "use")); 2543 else 2544 (void) printf(gettext("in use by " 2545 "pool '%s'"), 2546 zpool_get_name(cb.cb_zhp)); 2547 zpool_close(cb.cb_zhp); 2548 } else { 2549 (void) printf(gettext("currently in use")); 2550 } 2551 break; 2552 2553 default: 2554 (void) printf(gettext("corrupted data")); 2555 break; 2556 } 2557 } else if (vs->vs_scrub_repaired != 0 && children == 0) { 2558 /* 2559 * Report bytes resilvered/repaired on leaf devices. 2560 */ 2561 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired)); 2562 (void) printf(gettext(" %s %s"), repaired, 2563 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2564 "resilvered" : "repaired"); 2565 } 2566 2567 (void) printf("\n"); 2568 2569 for (c = 0; c < children; c++) { 2570 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 2571 print_status_config(zhp, vname, child[c], 2572 namewidth, depth + 2, isspare); 2573 free(vname); 2574 } 2575 } 2576 2577 static void 2578 print_error_log(zpool_handle_t *zhp) 2579 { 2580 nvlist_t **log; 2581 size_t nelem; 2582 size_t maxdsname = sizeof ("DATASET") - 1; 2583 size_t maxobjname = sizeof ("OBJECT") - 1; 2584 int i; 2585 nvlist_t *nv; 2586 size_t len; 2587 char *dsname, *objname, *range; 2588 2589 if (zpool_get_errlog(zhp, &log, &nelem) != 0) { 2590 (void) printf("errors: List of errors unavailable " 2591 "(insufficient privileges)\n"); 2592 return; 2593 } 2594 2595 for (i = 0; i < nelem; i++) { 2596 nv = log[i]; 2597 2598 verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET, 2599 &dsname) == 0); 2600 len = strlen(dsname); 2601 if (len > maxdsname) 2602 maxdsname = len; 2603 2604 verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT, 2605 &objname) == 0); 2606 len = strlen(objname); 2607 if (len > maxobjname) 2608 maxobjname = len; 2609 } 2610 2611 (void) printf("errors: The following persistent errors have been " 2612 "detected:\n\n"); 2613 (void) printf("%8s %-*s %-*s %s\n", "", maxdsname, "DATASET", 2614 maxobjname, "OBJECT", "RANGE"); 2615 2616 for (i = 0; i < nelem; i++) { 2617 nv = log[i]; 2618 2619 verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET, 2620 &dsname) == 0); 2621 verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT, 2622 &objname) == 0); 2623 verify(nvlist_lookup_string(nv, ZPOOL_ERR_RANGE, 2624 &range) == 0); 2625 2626 (void) printf("%8s %-*s %-*s %s\n", "", maxdsname, 2627 dsname, maxobjname, objname, range); 2628 } 2629 } 2630 2631 static void 2632 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2633 int namewidth) 2634 { 2635 uint_t i; 2636 char *name; 2637 2638 if (nspares == 0) 2639 return; 2640 2641 (void) printf(gettext("\tspares\n")); 2642 2643 for (i = 0; i < nspares; i++) { 2644 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2645 print_status_config(zhp, name, spares[i], 2646 namewidth, 2, B_TRUE); 2647 free(name); 2648 } 2649 } 2650 2651 /* 2652 * Display a summary of pool status. Displays a summary such as: 2653 * 2654 * pool: tank 2655 * status: DEGRADED 2656 * reason: One or more devices ... 2657 * see: http://www.sun.com/msg/ZFS-xxxx-01 2658 * config: 2659 * mirror DEGRADED 2660 * c1t0d0 OK 2661 * c2t0d0 UNAVAIL 2662 * 2663 * When given the '-v' option, we print out the complete config. If the '-e' 2664 * option is specified, then we print out error rate information as well. 2665 */ 2666 int 2667 status_callback(zpool_handle_t *zhp, void *data) 2668 { 2669 status_cbdata_t *cbp = data; 2670 nvlist_t *config, *nvroot; 2671 char *msgid; 2672 int reason; 2673 char *health; 2674 2675 config = zpool_get_config(zhp, NULL); 2676 reason = zpool_get_status(zhp, &msgid); 2677 2678 cbp->cb_count++; 2679 2680 /* 2681 * If we were given 'zpool status -x', only report those pools with 2682 * problems. 2683 */ 2684 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) 2685 return (0); 2686 2687 if (cbp->cb_first) 2688 cbp->cb_first = B_FALSE; 2689 else 2690 (void) printf("\n"); 2691 2692 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_HEALTH, 2693 &health) == 0); 2694 2695 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 2696 (void) printf(gettext(" state: %s\n"), health); 2697 2698 switch (reason) { 2699 case ZPOOL_STATUS_MISSING_DEV_R: 2700 (void) printf(gettext("status: One or more devices could not " 2701 "be opened. Sufficient replicas exist for\n\tthe pool to " 2702 "continue functioning in a degraded state.\n")); 2703 (void) printf(gettext("action: Attach the missing device and " 2704 "online it using 'zpool online'.\n")); 2705 break; 2706 2707 case ZPOOL_STATUS_MISSING_DEV_NR: 2708 (void) printf(gettext("status: One or more devices could not " 2709 "be opened. There are insufficient\n\treplicas for the " 2710 "pool to continue functioning.\n")); 2711 (void) printf(gettext("action: Attach the missing device and " 2712 "online it using 'zpool online'.\n")); 2713 break; 2714 2715 case ZPOOL_STATUS_CORRUPT_LABEL_R: 2716 (void) printf(gettext("status: One or more devices could not " 2717 "be used because the label is missing or\n\tinvalid. " 2718 "Sufficient replicas exist for the pool to continue\n\t" 2719 "functioning in a degraded state.\n")); 2720 (void) printf(gettext("action: Replace the device using " 2721 "'zpool replace'.\n")); 2722 break; 2723 2724 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 2725 (void) printf(gettext("status: One or more devices could not " 2726 "be used because the the label is missing \n\tor invalid. " 2727 "There are insufficient replicas for the pool to " 2728 "continue\n\tfunctioning.\n")); 2729 (void) printf(gettext("action: Destroy and re-create the pool " 2730 "from a backup source.\n")); 2731 break; 2732 2733 case ZPOOL_STATUS_FAILING_DEV: 2734 (void) printf(gettext("status: One or more devices has " 2735 "experienced an unrecoverable error. An\n\tattempt was " 2736 "made to correct the error. Applications are " 2737 "unaffected.\n")); 2738 (void) printf(gettext("action: Determine if the device needs " 2739 "to be replaced, and clear the errors\n\tusing " 2740 "'zpool clear' or replace the device with 'zpool " 2741 "replace'.\n")); 2742 break; 2743 2744 case ZPOOL_STATUS_OFFLINE_DEV: 2745 (void) printf(gettext("status: One or more devices has " 2746 "been taken offline by the adminstrator.\n\tSufficient " 2747 "replicas exist for the pool to continue functioning in " 2748 "a\n\tdegraded state.\n")); 2749 (void) printf(gettext("action: Online the device using " 2750 "'zpool online' or replace the device with\n\t'zpool " 2751 "replace'.\n")); 2752 break; 2753 2754 case ZPOOL_STATUS_RESILVERING: 2755 (void) printf(gettext("status: One or more devices is " 2756 "currently being resilvered. The pool will\n\tcontinue " 2757 "to function, possibly in a degraded state.\n")); 2758 (void) printf(gettext("action: Wait for the resilver to " 2759 "complete.\n")); 2760 break; 2761 2762 case ZPOOL_STATUS_CORRUPT_DATA: 2763 (void) printf(gettext("status: One or more devices has " 2764 "experienced an error resulting in data\n\tcorruption. " 2765 "Applications may be affected.\n")); 2766 (void) printf(gettext("action: Restore the file in question " 2767 "if possible. Otherwise restore the\n\tentire pool from " 2768 "backup.\n")); 2769 break; 2770 2771 case ZPOOL_STATUS_CORRUPT_POOL: 2772 (void) printf(gettext("status: The pool metadata is corrupted " 2773 "and the pool cannot be opened.\n")); 2774 (void) printf(gettext("action: Destroy and re-create the pool " 2775 "from a backup source.\n")); 2776 break; 2777 2778 case ZPOOL_STATUS_VERSION_OLDER: 2779 (void) printf(gettext("status: The pool is formatted using an " 2780 "older on-disk format. The pool can\n\tstill be used, but " 2781 "some features are unavailable.\n")); 2782 (void) printf(gettext("action: Upgrade the pool using 'zpool " 2783 "upgrade'. Once this is done, the\n\tpool will no longer " 2784 "be accessible on older software versions.\n")); 2785 break; 2786 2787 case ZPOOL_STATUS_VERSION_NEWER: 2788 (void) printf(gettext("status: The pool has been upgraded to a " 2789 "newer, incompatible on-disk version.\n\tThe pool cannot " 2790 "be accessed on this system.\n")); 2791 (void) printf(gettext("action: Access the pool from a system " 2792 "running more recent software, or\n\trestore the pool from " 2793 "backup.\n")); 2794 break; 2795 2796 default: 2797 /* 2798 * The remaining errors can't actually be generated, yet. 2799 */ 2800 assert(reason == ZPOOL_STATUS_OK); 2801 } 2802 2803 if (msgid != NULL) 2804 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 2805 msgid); 2806 2807 if (config != NULL) { 2808 int namewidth; 2809 uint64_t nerr; 2810 size_t realerr; 2811 nvlist_t **spares; 2812 uint_t nspares; 2813 2814 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2815 &nvroot) == 0); 2816 2817 (void) printf(gettext(" scrub: ")); 2818 print_scrub_status(nvroot); 2819 2820 namewidth = max_width(zhp, nvroot, 0, 0); 2821 if (namewidth < 10) 2822 namewidth = 10; 2823 2824 (void) printf(gettext("config:\n\n")); 2825 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 2826 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 2827 print_status_config(zhp, zpool_get_name(zhp), nvroot, 2828 namewidth, 0, B_FALSE); 2829 2830 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 2831 &spares, &nspares) == 0) 2832 print_spares(zhp, spares, nspares, namewidth); 2833 2834 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 2835 &nerr) == 0) { 2836 /* 2837 * If the approximate error count is small, get a 2838 * precise count by fetching the entire log and 2839 * uniquifying the results. 2840 */ 2841 if (nerr < 100 && !cbp->cb_verbose && 2842 zpool_get_errlog(zhp, NULL, &realerr) == 0) 2843 nerr = realerr; 2844 2845 (void) printf("\n"); 2846 2847 if (nerr == 0) 2848 (void) printf(gettext("errors: No known data " 2849 "errors\n")); 2850 else if (!cbp->cb_verbose) 2851 (void) printf(gettext("errors: %d data errors, " 2852 "use '-v' for a list\n"), nerr); 2853 else 2854 print_error_log(zhp); 2855 } 2856 } else { 2857 (void) printf(gettext("config: The configuration cannot be " 2858 "determined.\n")); 2859 } 2860 2861 return (0); 2862 } 2863 2864 /* 2865 * zpool status [-vx] [pool] ... 2866 * 2867 * -v Display complete error logs 2868 * -x Display only pools with potential problems 2869 * 2870 * Describes the health status of all pools or some subset. 2871 */ 2872 int 2873 zpool_do_status(int argc, char **argv) 2874 { 2875 int c; 2876 int ret; 2877 status_cbdata_t cb = { 0 }; 2878 2879 /* check options */ 2880 while ((c = getopt(argc, argv, "vx")) != -1) { 2881 switch (c) { 2882 case 'v': 2883 cb.cb_verbose = B_TRUE; 2884 break; 2885 case 'x': 2886 cb.cb_explain = B_TRUE; 2887 break; 2888 case '?': 2889 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2890 optopt); 2891 usage(B_FALSE); 2892 } 2893 } 2894 2895 argc -= optind; 2896 argv += optind; 2897 2898 cb.cb_first = B_TRUE; 2899 2900 ret = for_each_pool(argc, argv, B_TRUE, status_callback, &cb); 2901 2902 if (argc == 0 && cb.cb_count == 0) 2903 (void) printf(gettext("no pools available\n")); 2904 else if (cb.cb_explain && cb.cb_first) { 2905 if (argc == 0) { 2906 (void) printf(gettext("all pools are healthy\n")); 2907 } else { 2908 int i; 2909 for (i = 0; i < argc; i++) 2910 (void) printf(gettext("pool '%s' is healthy\n"), 2911 argv[i]); 2912 } 2913 } 2914 2915 return (ret); 2916 } 2917 2918 typedef struct upgrade_cbdata { 2919 int cb_all; 2920 int cb_first; 2921 int cb_newer; 2922 } upgrade_cbdata_t; 2923 2924 static int 2925 upgrade_cb(zpool_handle_t *zhp, void *arg) 2926 { 2927 upgrade_cbdata_t *cbp = arg; 2928 nvlist_t *config; 2929 uint64_t version; 2930 int ret = 0; 2931 2932 config = zpool_get_config(zhp, NULL); 2933 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 2934 &version) == 0); 2935 2936 if (!cbp->cb_newer && version < ZFS_VERSION) { 2937 if (!cbp->cb_all) { 2938 if (cbp->cb_first) { 2939 (void) printf(gettext("The following pools are " 2940 "out of date, and can be upgraded. After " 2941 "being\nupgraded, these pools will no " 2942 "longer be accessible by older software " 2943 "versions.\n\n")); 2944 (void) printf(gettext("VER POOL\n")); 2945 (void) printf(gettext("--- ------------\n")); 2946 cbp->cb_first = B_FALSE; 2947 } 2948 2949 (void) printf("%2llu %s\n", version, 2950 zpool_get_name(zhp)); 2951 } else { 2952 cbp->cb_first = B_FALSE; 2953 ret = zpool_upgrade(zhp); 2954 if (ret == 0) 2955 (void) printf(gettext("Successfully upgraded " 2956 "'%s'\n"), zpool_get_name(zhp)); 2957 } 2958 } else if (cbp->cb_newer && version > ZFS_VERSION) { 2959 assert(!cbp->cb_all); 2960 2961 if (cbp->cb_first) { 2962 (void) printf(gettext("The following pools are " 2963 "formatted using a newer software version and\n" 2964 "cannot be accessed on the current system.\n\n")); 2965 (void) printf(gettext("VER POOL\n")); 2966 (void) printf(gettext("--- ------------\n")); 2967 cbp->cb_first = B_FALSE; 2968 } 2969 2970 (void) printf("%2llu %s\n", version, 2971 zpool_get_name(zhp)); 2972 } 2973 2974 zpool_close(zhp); 2975 return (ret); 2976 } 2977 2978 /* ARGSUSED */ 2979 static int 2980 upgrade_one(zpool_handle_t *zhp, void *unused) 2981 { 2982 nvlist_t *config; 2983 uint64_t version; 2984 int ret; 2985 2986 config = zpool_get_config(zhp, NULL); 2987 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 2988 &version) == 0); 2989 2990 if (version == ZFS_VERSION) { 2991 (void) printf(gettext("Pool '%s' is already formatted " 2992 "using the current version.\n"), zpool_get_name(zhp)); 2993 return (0); 2994 } 2995 2996 ret = zpool_upgrade(zhp); 2997 if (ret == 0) 2998 (void) printf(gettext("Successfully upgraded '%s' " 2999 "from version %llu to version %llu\n"), zpool_get_name(zhp), 3000 (u_longlong_t)version, (u_longlong_t)ZFS_VERSION); 3001 3002 return (ret != 0); 3003 } 3004 3005 /* 3006 * zpool upgrade 3007 * zpool upgrade -v 3008 * zpool upgrade <-a | pool> 3009 * 3010 * With no arguments, display downrev'd ZFS pool available for upgrade. 3011 * Individual pools can be upgraded by specifying the pool, and '-a' will 3012 * upgrade all pools. 3013 */ 3014 int 3015 zpool_do_upgrade(int argc, char **argv) 3016 { 3017 int c; 3018 upgrade_cbdata_t cb = { 0 }; 3019 int ret = 0; 3020 boolean_t showversions = B_FALSE; 3021 3022 /* check options */ 3023 while ((c = getopt(argc, argv, "av")) != -1) { 3024 switch (c) { 3025 case 'a': 3026 cb.cb_all = B_TRUE; 3027 break; 3028 case 'v': 3029 showversions = B_TRUE; 3030 break; 3031 case '?': 3032 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3033 optopt); 3034 usage(B_FALSE); 3035 } 3036 } 3037 3038 argc -= optind; 3039 argv += optind; 3040 3041 if (showversions) { 3042 if (cb.cb_all || argc != 0) { 3043 (void) fprintf(stderr, gettext("-v option is " 3044 "incompatible with other arguments\n")); 3045 usage(B_FALSE); 3046 } 3047 } else if (cb.cb_all) { 3048 if (argc != 0) { 3049 (void) fprintf(stderr, gettext("-a option is " 3050 "incompatible with other arguments\n")); 3051 usage(B_FALSE); 3052 } 3053 } 3054 3055 (void) printf(gettext("This system is currently running ZFS version " 3056 "%llu.\n\n"), ZFS_VERSION); 3057 cb.cb_first = B_TRUE; 3058 if (showversions) { 3059 (void) printf(gettext("The following versions are " 3060 "suppored:\n\n")); 3061 (void) printf(gettext("VER DESCRIPTION\n")); 3062 (void) printf("--- -----------------------------------------" 3063 "---------------\n"); 3064 (void) printf(gettext(" 1 Initial ZFS version\n")); 3065 (void) printf(gettext(" 2 Ditto blocks " 3066 "(replicated metadata)\n")); 3067 (void) printf(gettext(" 3 Hot spares and double parity " 3068 "RAID-Z\n")); 3069 (void) printf(gettext("\nFor more information on a particular " 3070 "version, including supported releases, see:\n\n")); 3071 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3072 "version/N\n\n"); 3073 (void) printf(gettext("Where 'N' is the version number.\n")); 3074 } else if (argc == 0) { 3075 int notfound; 3076 3077 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3078 notfound = cb.cb_first; 3079 3080 if (!cb.cb_all && ret == 0) { 3081 if (!cb.cb_first) 3082 (void) printf("\n"); 3083 cb.cb_first = B_TRUE; 3084 cb.cb_newer = B_TRUE; 3085 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3086 if (!cb.cb_first) { 3087 notfound = B_FALSE; 3088 (void) printf("\n"); 3089 } 3090 } 3091 3092 if (ret == 0) { 3093 if (notfound) 3094 (void) printf(gettext("All pools are formatted " 3095 "using this version.\n")); 3096 else if (!cb.cb_all) 3097 (void) printf(gettext("Use 'zpool upgrade -v' " 3098 "for a list of available versions and " 3099 "their associated\nfeatures.\n")); 3100 } 3101 } else { 3102 ret = for_each_pool(argc, argv, B_FALSE, upgrade_one, NULL); 3103 } 3104 3105 return (ret); 3106 } 3107 3108 int 3109 main(int argc, char **argv) 3110 { 3111 int ret; 3112 int i; 3113 char *cmdname; 3114 3115 (void) setlocale(LC_ALL, ""); 3116 (void) textdomain(TEXT_DOMAIN); 3117 3118 if ((g_zfs = libzfs_init()) == NULL) { 3119 (void) fprintf(stderr, gettext("internal error: failed to " 3120 "initialize ZFS library")); 3121 return (1); 3122 } 3123 3124 libzfs_print_on_error(g_zfs, B_TRUE); 3125 3126 opterr = 0; 3127 3128 /* 3129 * Make sure the user has specified some command. 3130 */ 3131 if (argc < 2) { 3132 (void) fprintf(stderr, gettext("missing command\n")); 3133 usage(B_FALSE); 3134 } 3135 3136 cmdname = argv[1]; 3137 3138 /* 3139 * Special case '-?' 3140 */ 3141 if (strcmp(cmdname, "-?") == 0) 3142 usage(B_TRUE); 3143 3144 /* 3145 * Run the appropriate command. 3146 */ 3147 for (i = 0; i < NCOMMAND; i++) { 3148 if (command_table[i].name == NULL) 3149 continue; 3150 3151 if (strcmp(cmdname, command_table[i].name) == 0) { 3152 current_command = &command_table[i]; 3153 ret = command_table[i].func(argc - 1, argv + 1); 3154 break; 3155 } 3156 } 3157 3158 /* 3159 * 'freeze' is a vile debugging abomination, so we treat it as such. 3160 */ 3161 if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3162 char buf[16384]; 3163 int fd = open(ZFS_DEV, O_RDWR); 3164 (void) strcpy((void *)buf, argv[2]); 3165 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3166 } 3167 3168 if (i == NCOMMAND) { 3169 (void) fprintf(stderr, gettext("unrecognized " 3170 "command '%s'\n"), cmdname); 3171 usage(B_FALSE); 3172 } 3173 3174 libzfs_fini(g_zfs); 3175 3176 /* 3177 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3178 * for the purposes of running ::findleaks. 3179 */ 3180 if (getenv("ZFS_ABORT") != NULL) { 3181 (void) printf("dumping core by request\n"); 3182 abort(); 3183 } 3184 3185 return (ret); 3186 } 3187