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