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(zhp, 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 int ret; 2129 int log_argc; 2130 char **log_argv; 2131 2132 /* check options */ 2133 while ((c = getopt(argc, argv, "f")) != -1) { 2134 switch (c) { 2135 case 'f': 2136 force = B_TRUE; 2137 break; 2138 case '?': 2139 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2140 optopt); 2141 usage(B_FALSE); 2142 } 2143 } 2144 2145 log_argc = argc; 2146 log_argv = argv; 2147 argc -= optind; 2148 argv += optind; 2149 2150 /* get pool name and check number of arguments */ 2151 if (argc < 1) { 2152 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2153 usage(B_FALSE); 2154 } 2155 2156 poolname = argv[0]; 2157 2158 if (argc < 2) { 2159 (void) fprintf(stderr, 2160 gettext("missing <device> specification\n")); 2161 usage(B_FALSE); 2162 } 2163 2164 old_disk = argv[1]; 2165 2166 if (argc < 3) { 2167 if (!replacing) { 2168 (void) fprintf(stderr, 2169 gettext("missing <new_device> specification\n")); 2170 usage(B_FALSE); 2171 } 2172 new_disk = old_disk; 2173 argc -= 1; 2174 argv += 1; 2175 } else { 2176 new_disk = argv[2]; 2177 argc -= 2; 2178 argv += 2; 2179 } 2180 2181 if (argc > 1) { 2182 (void) fprintf(stderr, gettext("too many arguments\n")); 2183 usage(B_FALSE); 2184 } 2185 2186 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2187 return (1); 2188 2189 if (zpool_get_config(zhp, NULL) == NULL) { 2190 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 2191 poolname); 2192 zpool_close(zhp); 2193 return (1); 2194 } 2195 2196 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, argc, argv); 2197 if (nvroot == NULL) { 2198 zpool_close(zhp); 2199 return (1); 2200 } 2201 2202 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 2203 2204 if (!ret) { 2205 zpool_log_history(g_zfs, log_argc, log_argv, poolname, B_TRUE, 2206 B_FALSE); 2207 } 2208 2209 nvlist_free(nvroot); 2210 zpool_close(zhp); 2211 2212 return (ret); 2213 } 2214 2215 /* 2216 * zpool replace [-f] <pool> <device> <new_device> 2217 * 2218 * -f Force attach, even if <new_device> appears to be in use. 2219 * 2220 * Replace <device> with <new_device>. 2221 */ 2222 /* ARGSUSED */ 2223 int 2224 zpool_do_replace(int argc, char **argv) 2225 { 2226 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 2227 } 2228 2229 /* 2230 * zpool attach [-f] <pool> <device> <new_device> 2231 * 2232 * -f Force attach, even if <new_device> appears to be in use. 2233 * 2234 * Attach <new_device> to the mirror containing <device>. If <device> is not 2235 * part of a mirror, then <device> will be transformed into a mirror of 2236 * <device> and <new_device>. In either case, <new_device> will begin life 2237 * with a DTL of [0, now], and will immediately begin to resilver itself. 2238 */ 2239 int 2240 zpool_do_attach(int argc, char **argv) 2241 { 2242 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 2243 } 2244 2245 /* 2246 * zpool detach [-f] <pool> <device> 2247 * 2248 * -f Force detach of <device>, even if DTLs argue against it 2249 * (not supported yet) 2250 * 2251 * Detach a device from a mirror. The operation will be refused if <device> 2252 * is the last device in the mirror, or if the DTLs indicate that this device 2253 * has the only valid copy of some data. 2254 */ 2255 /* ARGSUSED */ 2256 int 2257 zpool_do_detach(int argc, char **argv) 2258 { 2259 int c; 2260 char *poolname, *path; 2261 zpool_handle_t *zhp; 2262 int ret; 2263 2264 /* check options */ 2265 while ((c = getopt(argc, argv, "f")) != -1) { 2266 switch (c) { 2267 case 'f': 2268 case '?': 2269 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2270 optopt); 2271 usage(B_FALSE); 2272 } 2273 } 2274 2275 argc -= optind; 2276 argv += optind; 2277 2278 /* get pool name and check number of arguments */ 2279 if (argc < 1) { 2280 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2281 usage(B_FALSE); 2282 } 2283 2284 if (argc < 2) { 2285 (void) fprintf(stderr, 2286 gettext("missing <device> specification\n")); 2287 usage(B_FALSE); 2288 } 2289 2290 poolname = argv[0]; 2291 path = argv[1]; 2292 2293 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2294 return (1); 2295 2296 ret = zpool_vdev_detach(zhp, path); 2297 2298 if (!ret) { 2299 zpool_log_history(g_zfs, argc + optind, argv - optind, poolname, 2300 B_TRUE, B_FALSE); 2301 } 2302 zpool_close(zhp); 2303 2304 return (ret); 2305 } 2306 2307 /* 2308 * zpool online <pool> <device> ... 2309 */ 2310 /* ARGSUSED */ 2311 int 2312 zpool_do_online(int argc, char **argv) 2313 { 2314 int c, i; 2315 char *poolname; 2316 zpool_handle_t *zhp; 2317 int ret = 0; 2318 2319 /* check options */ 2320 while ((c = getopt(argc, argv, "t")) != -1) { 2321 switch (c) { 2322 case 't': 2323 case '?': 2324 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2325 optopt); 2326 usage(B_FALSE); 2327 } 2328 } 2329 2330 argc -= optind; 2331 argv += optind; 2332 2333 /* get pool name and check number of arguments */ 2334 if (argc < 1) { 2335 (void) fprintf(stderr, gettext("missing pool name\n")); 2336 usage(B_FALSE); 2337 } 2338 if (argc < 2) { 2339 (void) fprintf(stderr, gettext("missing device name\n")); 2340 usage(B_FALSE); 2341 } 2342 2343 poolname = argv[0]; 2344 2345 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2346 return (1); 2347 2348 for (i = 1; i < argc; i++) 2349 if (zpool_vdev_online(zhp, argv[i]) == 0) 2350 (void) printf(gettext("Bringing device %s online\n"), 2351 argv[i]); 2352 else 2353 ret = 1; 2354 2355 if (!ret) { 2356 zpool_log_history(g_zfs, argc + optind, argv - optind, poolname, 2357 B_TRUE, B_FALSE); 2358 } 2359 zpool_close(zhp); 2360 2361 return (ret); 2362 } 2363 2364 /* 2365 * zpool offline [-ft] <pool> <device> ... 2366 * 2367 * -f Force the device into the offline state, even if doing 2368 * so would appear to compromise pool availability. 2369 * (not supported yet) 2370 * 2371 * -t Only take the device off-line temporarily. The offline 2372 * state will not be persistent across reboots. 2373 */ 2374 /* ARGSUSED */ 2375 int 2376 zpool_do_offline(int argc, char **argv) 2377 { 2378 int c, i; 2379 char *poolname; 2380 zpool_handle_t *zhp; 2381 int ret = 0; 2382 boolean_t istmp = B_FALSE; 2383 2384 /* check options */ 2385 while ((c = getopt(argc, argv, "ft")) != -1) { 2386 switch (c) { 2387 case 't': 2388 istmp = B_TRUE; 2389 break; 2390 case 'f': 2391 case '?': 2392 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2393 optopt); 2394 usage(B_FALSE); 2395 } 2396 } 2397 2398 argc -= optind; 2399 argv += optind; 2400 2401 /* get pool name and check number of arguments */ 2402 if (argc < 1) { 2403 (void) fprintf(stderr, gettext("missing pool name\n")); 2404 usage(B_FALSE); 2405 } 2406 if (argc < 2) { 2407 (void) fprintf(stderr, gettext("missing device name\n")); 2408 usage(B_FALSE); 2409 } 2410 2411 poolname = argv[0]; 2412 2413 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2414 return (1); 2415 2416 for (i = 1; i < argc; i++) 2417 if (zpool_vdev_offline(zhp, argv[i], istmp) == 0) 2418 (void) printf(gettext("Bringing device %s offline\n"), 2419 argv[i]); 2420 else 2421 ret = 1; 2422 2423 if (!ret) { 2424 zpool_log_history(g_zfs, argc + optind, argv - optind, poolname, 2425 B_TRUE, B_FALSE); 2426 } 2427 zpool_close(zhp); 2428 2429 return (ret); 2430 } 2431 2432 /* 2433 * zpool clear <pool> [device] 2434 * 2435 * Clear all errors associated with a pool or a particular device. 2436 */ 2437 int 2438 zpool_do_clear(int argc, char **argv) 2439 { 2440 int ret = 0; 2441 zpool_handle_t *zhp; 2442 char *pool, *device; 2443 2444 if (argc < 2) { 2445 (void) fprintf(stderr, gettext("missing pool name\n")); 2446 usage(B_FALSE); 2447 } 2448 2449 if (argc > 3) { 2450 (void) fprintf(stderr, gettext("too many arguments\n")); 2451 usage(B_FALSE); 2452 } 2453 2454 pool = argv[1]; 2455 device = argc == 3 ? argv[2] : NULL; 2456 2457 if ((zhp = zpool_open(g_zfs, pool)) == NULL) 2458 return (1); 2459 2460 if (zpool_clear(zhp, device) != 0) 2461 ret = 1; 2462 2463 if (!ret) 2464 zpool_log_history(g_zfs, argc, argv, pool, B_TRUE, B_FALSE); 2465 zpool_close(zhp); 2466 2467 return (ret); 2468 } 2469 2470 typedef struct scrub_cbdata { 2471 int cb_type; 2472 int cb_argc; 2473 char **cb_argv; 2474 } scrub_cbdata_t; 2475 2476 int 2477 scrub_callback(zpool_handle_t *zhp, void *data) 2478 { 2479 scrub_cbdata_t *cb = data; 2480 int err; 2481 2482 /* 2483 * Ignore faulted pools. 2484 */ 2485 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 2486 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 2487 "currently unavailable\n"), zpool_get_name(zhp)); 2488 return (1); 2489 } 2490 2491 err = zpool_scrub(zhp, cb->cb_type); 2492 2493 if (!err) { 2494 zpool_log_history(g_zfs, cb->cb_argc, cb->cb_argv, 2495 zpool_get_name(zhp), B_TRUE, B_FALSE); 2496 } 2497 2498 return (err != 0); 2499 } 2500 2501 /* 2502 * zpool scrub [-s] <pool> ... 2503 * 2504 * -s Stop. Stops any in-progress scrub. 2505 */ 2506 int 2507 zpool_do_scrub(int argc, char **argv) 2508 { 2509 int c; 2510 scrub_cbdata_t cb; 2511 2512 cb.cb_type = POOL_SCRUB_EVERYTHING; 2513 2514 /* check options */ 2515 while ((c = getopt(argc, argv, "s")) != -1) { 2516 switch (c) { 2517 case 's': 2518 cb.cb_type = POOL_SCRUB_NONE; 2519 break; 2520 case '?': 2521 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2522 optopt); 2523 usage(B_FALSE); 2524 } 2525 } 2526 2527 cb.cb_argc = argc; 2528 cb.cb_argv = argv; 2529 argc -= optind; 2530 argv += optind; 2531 2532 if (argc < 1) { 2533 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2534 usage(B_FALSE); 2535 } 2536 2537 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 2538 } 2539 2540 typedef struct status_cbdata { 2541 int cb_count; 2542 boolean_t cb_allpools; 2543 boolean_t cb_verbose; 2544 boolean_t cb_explain; 2545 boolean_t cb_first; 2546 } status_cbdata_t; 2547 2548 /* 2549 * Print out detailed scrub status. 2550 */ 2551 void 2552 print_scrub_status(nvlist_t *nvroot) 2553 { 2554 vdev_stat_t *vs; 2555 uint_t vsc; 2556 time_t start, end, now; 2557 double fraction_done; 2558 uint64_t examined, total, minutes_left; 2559 char *scrub_type; 2560 2561 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2562 (uint64_t **)&vs, &vsc) == 0); 2563 2564 /* 2565 * If there's never been a scrub, there's not much to say. 2566 */ 2567 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) { 2568 (void) printf(gettext("none requested\n")); 2569 return; 2570 } 2571 2572 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2573 "resilver" : "scrub"; 2574 2575 start = vs->vs_scrub_start; 2576 end = vs->vs_scrub_end; 2577 now = time(NULL); 2578 examined = vs->vs_scrub_examined; 2579 total = vs->vs_alloc; 2580 2581 if (end != 0) { 2582 (void) printf(gettext("%s %s with %llu errors on %s"), 2583 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2584 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2585 return; 2586 } 2587 2588 if (examined == 0) 2589 examined = 1; 2590 if (examined > total) 2591 total = examined; 2592 2593 fraction_done = (double)examined / total; 2594 minutes_left = (uint64_t)((now - start) * 2595 (1 - fraction_done) / fraction_done / 60); 2596 2597 (void) printf(gettext("%s in progress, %.2f%% done, %lluh%um to go\n"), 2598 scrub_type, 100 * fraction_done, 2599 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2600 } 2601 2602 typedef struct spare_cbdata { 2603 uint64_t cb_guid; 2604 zpool_handle_t *cb_zhp; 2605 } spare_cbdata_t; 2606 2607 static boolean_t 2608 find_vdev(nvlist_t *nv, uint64_t search) 2609 { 2610 uint64_t guid; 2611 nvlist_t **child; 2612 uint_t c, children; 2613 2614 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 2615 search == guid) 2616 return (B_TRUE); 2617 2618 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2619 &child, &children) == 0) { 2620 for (c = 0; c < children; c++) 2621 if (find_vdev(child[c], search)) 2622 return (B_TRUE); 2623 } 2624 2625 return (B_FALSE); 2626 } 2627 2628 static int 2629 find_spare(zpool_handle_t *zhp, void *data) 2630 { 2631 spare_cbdata_t *cbp = data; 2632 nvlist_t *config, *nvroot; 2633 2634 config = zpool_get_config(zhp, NULL); 2635 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2636 &nvroot) == 0); 2637 2638 if (find_vdev(nvroot, cbp->cb_guid)) { 2639 cbp->cb_zhp = zhp; 2640 return (1); 2641 } 2642 2643 zpool_close(zhp); 2644 return (0); 2645 } 2646 2647 /* 2648 * Print out configuration state as requested by status_callback. 2649 */ 2650 void 2651 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 2652 int namewidth, int depth, boolean_t isspare) 2653 { 2654 nvlist_t **child; 2655 uint_t c, children; 2656 vdev_stat_t *vs; 2657 char rbuf[6], wbuf[6], cbuf[6], repaired[7]; 2658 char *vname; 2659 uint64_t notpresent; 2660 spare_cbdata_t cb; 2661 const char *state; 2662 2663 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 2664 (uint64_t **)&vs, &c) == 0); 2665 2666 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2667 &child, &children) != 0) 2668 children = 0; 2669 2670 state = state_to_name(vs); 2671 if (isspare) { 2672 /* 2673 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 2674 * online drives. 2675 */ 2676 if (vs->vs_aux == VDEV_AUX_SPARED) 2677 state = "INUSE"; 2678 else if (vs->vs_state == VDEV_STATE_HEALTHY) 2679 state = "AVAIL"; 2680 } 2681 2682 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 2683 name, state); 2684 2685 if (!isspare) { 2686 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 2687 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 2688 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 2689 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 2690 } 2691 2692 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2693 ¬present) == 0) { 2694 char *path; 2695 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2696 (void) printf(" was %s", path); 2697 } else if (vs->vs_aux != 0) { 2698 (void) printf(" "); 2699 2700 switch (vs->vs_aux) { 2701 case VDEV_AUX_OPEN_FAILED: 2702 (void) printf(gettext("cannot open")); 2703 break; 2704 2705 case VDEV_AUX_BAD_GUID_SUM: 2706 (void) printf(gettext("missing device")); 2707 break; 2708 2709 case VDEV_AUX_NO_REPLICAS: 2710 (void) printf(gettext("insufficient replicas")); 2711 break; 2712 2713 case VDEV_AUX_VERSION_NEWER: 2714 (void) printf(gettext("newer version")); 2715 break; 2716 2717 case VDEV_AUX_SPARED: 2718 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2719 &cb.cb_guid) == 0); 2720 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 2721 if (strcmp(zpool_get_name(cb.cb_zhp), 2722 zpool_get_name(zhp)) == 0) 2723 (void) printf(gettext("currently in " 2724 "use")); 2725 else 2726 (void) printf(gettext("in use by " 2727 "pool '%s'"), 2728 zpool_get_name(cb.cb_zhp)); 2729 zpool_close(cb.cb_zhp); 2730 } else { 2731 (void) printf(gettext("currently in use")); 2732 } 2733 break; 2734 2735 default: 2736 (void) printf(gettext("corrupted data")); 2737 break; 2738 } 2739 } else if (vs->vs_scrub_repaired != 0 && children == 0) { 2740 /* 2741 * Report bytes resilvered/repaired on leaf devices. 2742 */ 2743 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired)); 2744 (void) printf(gettext(" %s %s"), repaired, 2745 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2746 "resilvered" : "repaired"); 2747 } 2748 2749 (void) printf("\n"); 2750 2751 for (c = 0; c < children; c++) { 2752 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 2753 print_status_config(zhp, vname, child[c], 2754 namewidth, depth + 2, isspare); 2755 free(vname); 2756 } 2757 } 2758 2759 static void 2760 print_error_log(zpool_handle_t *zhp) 2761 { 2762 nvlist_t *nverrlist; 2763 nvpair_t *elem; 2764 char *pathname; 2765 size_t len = MAXPATHLEN * 2; 2766 2767 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 2768 (void) printf("errors: List of errors unavailable " 2769 "(insufficient privileges)\n"); 2770 return; 2771 } 2772 2773 (void) printf("errors: Permanent errors have been " 2774 "detected in the following files:\n\n"); 2775 2776 pathname = safe_malloc(len); 2777 elem = NULL; 2778 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 2779 nvlist_t *nv; 2780 uint64_t dsobj, obj; 2781 2782 verify(nvpair_value_nvlist(elem, &nv) == 0); 2783 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 2784 &dsobj) == 0); 2785 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 2786 &obj) == 0); 2787 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 2788 (void) printf("%7s %s\n", "", pathname); 2789 } 2790 free(pathname); 2791 nvlist_free(nverrlist); 2792 } 2793 2794 static void 2795 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2796 int namewidth) 2797 { 2798 uint_t i; 2799 char *name; 2800 2801 if (nspares == 0) 2802 return; 2803 2804 (void) printf(gettext("\tspares\n")); 2805 2806 for (i = 0; i < nspares; i++) { 2807 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2808 print_status_config(zhp, name, spares[i], 2809 namewidth, 2, B_TRUE); 2810 free(name); 2811 } 2812 } 2813 2814 /* 2815 * Display a summary of pool status. Displays a summary such as: 2816 * 2817 * pool: tank 2818 * status: DEGRADED 2819 * reason: One or more devices ... 2820 * see: http://www.sun.com/msg/ZFS-xxxx-01 2821 * config: 2822 * mirror DEGRADED 2823 * c1t0d0 OK 2824 * c2t0d0 UNAVAIL 2825 * 2826 * When given the '-v' option, we print out the complete config. If the '-e' 2827 * option is specified, then we print out error rate information as well. 2828 */ 2829 int 2830 status_callback(zpool_handle_t *zhp, void *data) 2831 { 2832 status_cbdata_t *cbp = data; 2833 nvlist_t *config, *nvroot; 2834 char *msgid; 2835 int reason; 2836 const char *health; 2837 uint_t c; 2838 vdev_stat_t *vs; 2839 2840 config = zpool_get_config(zhp, NULL); 2841 reason = zpool_get_status(zhp, &msgid); 2842 2843 cbp->cb_count++; 2844 2845 /* 2846 * If we were given 'zpool status -x', only report those pools with 2847 * problems. 2848 */ 2849 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) { 2850 if (!cbp->cb_allpools) { 2851 (void) printf(gettext("pool '%s' is healthy\n"), 2852 zpool_get_name(zhp)); 2853 if (cbp->cb_first) 2854 cbp->cb_first = B_FALSE; 2855 } 2856 return (0); 2857 } 2858 2859 if (cbp->cb_first) 2860 cbp->cb_first = B_FALSE; 2861 else 2862 (void) printf("\n"); 2863 2864 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2865 &nvroot) == 0); 2866 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2867 (uint64_t **)&vs, &c) == 0); 2868 health = state_to_name(vs); 2869 2870 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 2871 (void) printf(gettext(" state: %s\n"), health); 2872 2873 switch (reason) { 2874 case ZPOOL_STATUS_MISSING_DEV_R: 2875 (void) printf(gettext("status: One or more devices could not " 2876 "be opened. Sufficient replicas exist for\n\tthe pool to " 2877 "continue functioning in a degraded state.\n")); 2878 (void) printf(gettext("action: Attach the missing device and " 2879 "online it using 'zpool online'.\n")); 2880 break; 2881 2882 case ZPOOL_STATUS_MISSING_DEV_NR: 2883 (void) printf(gettext("status: One or more devices could not " 2884 "be opened. There are insufficient\n\treplicas for the " 2885 "pool to continue functioning.\n")); 2886 (void) printf(gettext("action: Attach the missing device and " 2887 "online it using 'zpool online'.\n")); 2888 break; 2889 2890 case ZPOOL_STATUS_CORRUPT_LABEL_R: 2891 (void) printf(gettext("status: One or more devices could not " 2892 "be used because the label is missing or\n\tinvalid. " 2893 "Sufficient replicas exist for the pool to continue\n\t" 2894 "functioning in a degraded state.\n")); 2895 (void) printf(gettext("action: Replace the device using " 2896 "'zpool replace'.\n")); 2897 break; 2898 2899 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 2900 (void) printf(gettext("status: One or more devices could not " 2901 "be used because the label is missing \n\tor invalid. " 2902 "There are insufficient replicas for the pool to " 2903 "continue\n\tfunctioning.\n")); 2904 (void) printf(gettext("action: Destroy and re-create the pool " 2905 "from a backup source.\n")); 2906 break; 2907 2908 case ZPOOL_STATUS_FAILING_DEV: 2909 (void) printf(gettext("status: One or more devices has " 2910 "experienced an unrecoverable error. An\n\tattempt was " 2911 "made to correct the error. Applications are " 2912 "unaffected.\n")); 2913 (void) printf(gettext("action: Determine if the device needs " 2914 "to be replaced, and clear the errors\n\tusing " 2915 "'zpool clear' or replace the device with 'zpool " 2916 "replace'.\n")); 2917 break; 2918 2919 case ZPOOL_STATUS_OFFLINE_DEV: 2920 (void) printf(gettext("status: One or more devices has " 2921 "been taken offline by the administrator.\n\tSufficient " 2922 "replicas exist for the pool to continue functioning in " 2923 "a\n\tdegraded state.\n")); 2924 (void) printf(gettext("action: Online the device using " 2925 "'zpool online' or replace the device with\n\t'zpool " 2926 "replace'.\n")); 2927 break; 2928 2929 case ZPOOL_STATUS_RESILVERING: 2930 (void) printf(gettext("status: One or more devices is " 2931 "currently being resilvered. The pool will\n\tcontinue " 2932 "to function, possibly in a degraded state.\n")); 2933 (void) printf(gettext("action: Wait for the resilver to " 2934 "complete.\n")); 2935 break; 2936 2937 case ZPOOL_STATUS_CORRUPT_DATA: 2938 (void) printf(gettext("status: One or more devices has " 2939 "experienced an error resulting in data\n\tcorruption. " 2940 "Applications may be affected.\n")); 2941 (void) printf(gettext("action: Restore the file in question " 2942 "if possible. Otherwise restore the\n\tentire pool from " 2943 "backup.\n")); 2944 break; 2945 2946 case ZPOOL_STATUS_CORRUPT_POOL: 2947 (void) printf(gettext("status: The pool metadata is corrupted " 2948 "and the pool cannot be opened.\n")); 2949 (void) printf(gettext("action: Destroy and re-create the pool " 2950 "from a backup source.\n")); 2951 break; 2952 2953 case ZPOOL_STATUS_VERSION_OLDER: 2954 (void) printf(gettext("status: The pool is formatted using an " 2955 "older on-disk format. The pool can\n\tstill be used, but " 2956 "some features are unavailable.\n")); 2957 (void) printf(gettext("action: Upgrade the pool using 'zpool " 2958 "upgrade'. Once this is done, the\n\tpool will no longer " 2959 "be accessible on older software versions.\n")); 2960 break; 2961 2962 case ZPOOL_STATUS_VERSION_NEWER: 2963 (void) printf(gettext("status: The pool has been upgraded to a " 2964 "newer, incompatible on-disk version.\n\tThe pool cannot " 2965 "be accessed on this system.\n")); 2966 (void) printf(gettext("action: Access the pool from a system " 2967 "running more recent software, or\n\trestore the pool from " 2968 "backup.\n")); 2969 break; 2970 2971 default: 2972 /* 2973 * The remaining errors can't actually be generated, yet. 2974 */ 2975 assert(reason == ZPOOL_STATUS_OK); 2976 } 2977 2978 if (msgid != NULL) 2979 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 2980 msgid); 2981 2982 if (config != NULL) { 2983 int namewidth; 2984 uint64_t nerr; 2985 nvlist_t **spares; 2986 uint_t nspares; 2987 2988 2989 (void) printf(gettext(" scrub: ")); 2990 print_scrub_status(nvroot); 2991 2992 namewidth = max_width(zhp, nvroot, 0, 0); 2993 if (namewidth < 10) 2994 namewidth = 10; 2995 2996 (void) printf(gettext("config:\n\n")); 2997 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 2998 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 2999 print_status_config(zhp, zpool_get_name(zhp), nvroot, 3000 namewidth, 0, B_FALSE); 3001 3002 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3003 &spares, &nspares) == 0) 3004 print_spares(zhp, spares, nspares, namewidth); 3005 3006 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3007 &nerr) == 0) { 3008 nvlist_t *nverrlist = NULL; 3009 3010 /* 3011 * If the approximate error count is small, get a 3012 * precise count by fetching the entire log and 3013 * uniquifying the results. 3014 */ 3015 if (nerr < 100 && !cbp->cb_verbose && 3016 zpool_get_errlog(zhp, &nverrlist) == 0) { 3017 nvpair_t *elem; 3018 3019 elem = NULL; 3020 nerr = 0; 3021 while ((elem = nvlist_next_nvpair(nverrlist, 3022 elem)) != NULL) { 3023 nerr++; 3024 } 3025 } 3026 nvlist_free(nverrlist); 3027 3028 (void) printf("\n"); 3029 3030 if (nerr == 0) 3031 (void) printf(gettext("errors: No known data " 3032 "errors\n")); 3033 else if (!cbp->cb_verbose) 3034 (void) printf(gettext("errors: %llu data " 3035 "errors, use '-v' for a list\n"), 3036 (u_longlong_t)nerr); 3037 else 3038 print_error_log(zhp); 3039 } 3040 } else { 3041 (void) printf(gettext("config: The configuration cannot be " 3042 "determined.\n")); 3043 } 3044 3045 return (0); 3046 } 3047 3048 /* 3049 * zpool status [-vx] [pool] ... 3050 * 3051 * -v Display complete error logs 3052 * -x Display only pools with potential problems 3053 * 3054 * Describes the health status of all pools or some subset. 3055 */ 3056 int 3057 zpool_do_status(int argc, char **argv) 3058 { 3059 int c; 3060 int ret; 3061 status_cbdata_t cb = { 0 }; 3062 3063 /* check options */ 3064 while ((c = getopt(argc, argv, "vx")) != -1) { 3065 switch (c) { 3066 case 'v': 3067 cb.cb_verbose = B_TRUE; 3068 break; 3069 case 'x': 3070 cb.cb_explain = B_TRUE; 3071 break; 3072 case '?': 3073 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3074 optopt); 3075 usage(B_FALSE); 3076 } 3077 } 3078 3079 argc -= optind; 3080 argv += optind; 3081 3082 cb.cb_first = B_TRUE; 3083 3084 if (argc == 0) 3085 cb.cb_allpools = B_TRUE; 3086 3087 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3088 3089 if (argc == 0 && cb.cb_count == 0) 3090 (void) printf(gettext("no pools available\n")); 3091 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3092 (void) printf(gettext("all pools are healthy\n")); 3093 3094 return (ret); 3095 } 3096 3097 typedef struct upgrade_cbdata { 3098 int cb_all; 3099 int cb_first; 3100 int cb_newer; 3101 int cb_argc; 3102 char **cb_argv; 3103 } upgrade_cbdata_t; 3104 3105 static int 3106 upgrade_cb(zpool_handle_t *zhp, void *arg) 3107 { 3108 upgrade_cbdata_t *cbp = arg; 3109 nvlist_t *config; 3110 uint64_t version; 3111 int ret = 0; 3112 3113 config = zpool_get_config(zhp, NULL); 3114 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3115 &version) == 0); 3116 3117 if (!cbp->cb_newer && version < ZFS_VERSION) { 3118 if (!cbp->cb_all) { 3119 if (cbp->cb_first) { 3120 (void) printf(gettext("The following pools are " 3121 "out of date, and can be upgraded. After " 3122 "being\nupgraded, these pools will no " 3123 "longer be accessible by older software " 3124 "versions.\n\n")); 3125 (void) printf(gettext("VER POOL\n")); 3126 (void) printf(gettext("--- ------------\n")); 3127 cbp->cb_first = B_FALSE; 3128 } 3129 3130 (void) printf("%2llu %s\n", (u_longlong_t)version, 3131 zpool_get_name(zhp)); 3132 } else { 3133 cbp->cb_first = B_FALSE; 3134 ret = zpool_upgrade(zhp); 3135 if (!ret) { 3136 zpool_log_history(g_zfs, cbp->cb_argc, 3137 cbp->cb_argv, zpool_get_name(zhp), B_TRUE, 3138 B_FALSE); 3139 (void) printf(gettext("Successfully upgraded " 3140 "'%s'\n"), zpool_get_name(zhp)); 3141 } 3142 } 3143 } else if (cbp->cb_newer && version > ZFS_VERSION) { 3144 assert(!cbp->cb_all); 3145 3146 if (cbp->cb_first) { 3147 (void) printf(gettext("The following pools are " 3148 "formatted using a newer software version and\n" 3149 "cannot be accessed on the current system.\n\n")); 3150 (void) printf(gettext("VER POOL\n")); 3151 (void) printf(gettext("--- ------------\n")); 3152 cbp->cb_first = B_FALSE; 3153 } 3154 3155 (void) printf("%2llu %s\n", (u_longlong_t)version, 3156 zpool_get_name(zhp)); 3157 } 3158 3159 zpool_close(zhp); 3160 return (ret); 3161 } 3162 3163 /* ARGSUSED */ 3164 static int 3165 upgrade_one(zpool_handle_t *zhp, void *data) 3166 { 3167 nvlist_t *config; 3168 uint64_t version; 3169 int ret; 3170 upgrade_cbdata_t *cbp = data; 3171 3172 config = zpool_get_config(zhp, NULL); 3173 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3174 &version) == 0); 3175 3176 if (version == ZFS_VERSION) { 3177 (void) printf(gettext("Pool '%s' is already formatted " 3178 "using the current version.\n"), zpool_get_name(zhp)); 3179 return (0); 3180 } 3181 3182 ret = zpool_upgrade(zhp); 3183 3184 if (!ret) { 3185 zpool_log_history(g_zfs, cbp->cb_argc, cbp->cb_argv, 3186 zpool_get_name(zhp), B_TRUE, B_FALSE); 3187 (void) printf(gettext("Successfully upgraded '%s' " 3188 "from version %llu to version %llu\n"), zpool_get_name(zhp), 3189 (u_longlong_t)version, (u_longlong_t)ZFS_VERSION); 3190 } 3191 3192 return (ret != 0); 3193 } 3194 3195 /* 3196 * zpool upgrade 3197 * zpool upgrade -v 3198 * zpool upgrade <-a | pool> 3199 * 3200 * With no arguments, display downrev'd ZFS pool available for upgrade. 3201 * Individual pools can be upgraded by specifying the pool, and '-a' will 3202 * upgrade all pools. 3203 */ 3204 int 3205 zpool_do_upgrade(int argc, char **argv) 3206 { 3207 int c; 3208 upgrade_cbdata_t cb = { 0 }; 3209 int ret = 0; 3210 boolean_t showversions = B_FALSE; 3211 3212 /* check options */ 3213 while ((c = getopt(argc, argv, "av")) != -1) { 3214 switch (c) { 3215 case 'a': 3216 cb.cb_all = B_TRUE; 3217 break; 3218 case 'v': 3219 showversions = B_TRUE; 3220 break; 3221 case '?': 3222 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3223 optopt); 3224 usage(B_FALSE); 3225 } 3226 } 3227 3228 cb.cb_argc = argc; 3229 cb.cb_argv = argv; 3230 argc -= optind; 3231 argv += optind; 3232 3233 if (showversions) { 3234 if (cb.cb_all || argc != 0) { 3235 (void) fprintf(stderr, gettext("-v option is " 3236 "incompatible with other arguments\n")); 3237 usage(B_FALSE); 3238 } 3239 } else if (cb.cb_all) { 3240 if (argc != 0) { 3241 (void) fprintf(stderr, gettext("-a option is " 3242 "incompatible with other arguments\n")); 3243 usage(B_FALSE); 3244 } 3245 } 3246 3247 (void) printf(gettext("This system is currently running ZFS version " 3248 "%llu.\n\n"), ZFS_VERSION); 3249 cb.cb_first = B_TRUE; 3250 if (showversions) { 3251 (void) printf(gettext("The following versions are " 3252 "supported:\n\n")); 3253 (void) printf(gettext("VER DESCRIPTION\n")); 3254 (void) printf("--- -----------------------------------------" 3255 "---------------\n"); 3256 (void) printf(gettext(" 1 Initial ZFS version\n")); 3257 (void) printf(gettext(" 2 Ditto blocks " 3258 "(replicated metadata)\n")); 3259 (void) printf(gettext(" 3 Hot spares and double parity " 3260 "RAID-Z\n")); 3261 (void) printf(gettext(" 4 zpool history\n")); 3262 (void) printf(gettext(" 5 Compression using the gzip " 3263 "algorithm\n")); 3264 (void) printf(gettext(" 6 bootfs pool property ")); 3265 (void) printf(gettext("\nFor more information on a particular " 3266 "version, including supported releases, see:\n\n")); 3267 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3268 "version/N\n\n"); 3269 (void) printf(gettext("Where 'N' is the version number.\n")); 3270 } else if (argc == 0) { 3271 int notfound; 3272 3273 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3274 notfound = cb.cb_first; 3275 3276 if (!cb.cb_all && ret == 0) { 3277 if (!cb.cb_first) 3278 (void) printf("\n"); 3279 cb.cb_first = B_TRUE; 3280 cb.cb_newer = B_TRUE; 3281 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3282 if (!cb.cb_first) { 3283 notfound = B_FALSE; 3284 (void) printf("\n"); 3285 } 3286 } 3287 3288 if (ret == 0) { 3289 if (notfound) 3290 (void) printf(gettext("All pools are formatted " 3291 "using this version.\n")); 3292 else if (!cb.cb_all) 3293 (void) printf(gettext("Use 'zpool upgrade -v' " 3294 "for a list of available versions and " 3295 "their associated\nfeatures.\n")); 3296 } 3297 } else { 3298 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3299 upgrade_one, &cb); 3300 } 3301 3302 return (ret); 3303 } 3304 3305 /* 3306 * Print out the command history for a specific pool. 3307 */ 3308 static int 3309 get_history_one(zpool_handle_t *zhp, void *data) 3310 { 3311 nvlist_t *nvhis; 3312 nvlist_t **records; 3313 uint_t numrecords; 3314 char *cmdstr; 3315 uint64_t dst_time; 3316 time_t tsec; 3317 struct tm t; 3318 char tbuf[30]; 3319 int ret, i; 3320 3321 *(boolean_t *)data = B_FALSE; 3322 3323 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3324 3325 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3326 return (ret); 3327 3328 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3329 &records, &numrecords) == 0); 3330 for (i = 0; i < numrecords; i++) { 3331 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3332 &dst_time) == 0) { 3333 verify(nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3334 &cmdstr) == 0); 3335 tsec = dst_time; 3336 (void) localtime_r(&tsec, &t); 3337 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3338 (void) printf("%s %s\n", tbuf, cmdstr); 3339 } 3340 } 3341 (void) printf("\n"); 3342 nvlist_free(nvhis); 3343 3344 return (ret); 3345 } 3346 3347 /* 3348 * zpool history <pool> 3349 * 3350 * Displays the history of commands that modified pools. 3351 */ 3352 int 3353 zpool_do_history(int argc, char **argv) 3354 { 3355 boolean_t first = B_TRUE; 3356 int ret; 3357 3358 argc -= optind; 3359 argv += optind; 3360 3361 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3362 &first); 3363 3364 if (argc == 0 && first == B_TRUE) { 3365 (void) printf(gettext("no pools available\n")); 3366 return (0); 3367 } 3368 3369 return (ret); 3370 } 3371 3372 static int 3373 get_callback(zpool_handle_t *zhp, void *data) 3374 { 3375 libzfs_get_cbdata_t *cbp = (libzfs_get_cbdata_t *)data; 3376 char value[MAXNAMELEN]; 3377 zfs_source_t srctype; 3378 zpool_proplist_t *pl; 3379 3380 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3381 3382 /* 3383 * Skip the special fake placeholder. 3384 */ 3385 if (pl->pl_prop == ZFS_PROP_NAME && 3386 pl == cbp->cb_proplist) 3387 continue; 3388 3389 if (zpool_get_prop(zhp, pl->pl_prop, 3390 value, sizeof (value), &srctype) != 0) 3391 continue; 3392 3393 libzfs_print_one_property(zpool_get_name(zhp), cbp, 3394 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3395 } 3396 return (0); 3397 } 3398 3399 int 3400 zpool_do_get(int argc, char **argv) 3401 { 3402 libzfs_get_cbdata_t cb = { 0 }; 3403 zpool_proplist_t fake_name = { 0 }; 3404 int ret; 3405 3406 if (argc < 3) 3407 usage(B_FALSE); 3408 3409 cb.cb_first = B_TRUE; 3410 cb.cb_sources = ZFS_SRC_ALL; 3411 cb.cb_columns[0] = GET_COL_NAME; 3412 cb.cb_columns[1] = GET_COL_PROPERTY; 3413 cb.cb_columns[2] = GET_COL_VALUE; 3414 cb.cb_columns[3] = GET_COL_SOURCE; 3415 3416 if (zpool_get_proplist(g_zfs, argv[1], &cb.cb_proplist) != 0) 3417 usage(B_FALSE); 3418 3419 if (cb.cb_proplist != NULL) { 3420 fake_name.pl_prop = ZFS_PROP_NAME; 3421 fake_name.pl_width = strlen(gettext("NAME")); 3422 fake_name.pl_next = cb.cb_proplist; 3423 cb.cb_proplist = &fake_name; 3424 } 3425 3426 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3427 get_callback, &cb); 3428 3429 if (cb.cb_proplist == &fake_name) 3430 zfs_free_proplist(fake_name.pl_next); 3431 else 3432 zfs_free_proplist(cb.cb_proplist); 3433 3434 return (ret); 3435 } 3436 3437 typedef struct set_cbdata { 3438 char *cb_propname; 3439 char *cb_value; 3440 boolean_t cb_any_successful; 3441 } set_cbdata_t; 3442 3443 int 3444 set_callback(zpool_handle_t *zhp, void *data) 3445 { 3446 int error; 3447 set_cbdata_t *cb = (set_cbdata_t *)data; 3448 3449 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3450 3451 if (!error) 3452 cb->cb_any_successful = B_TRUE; 3453 3454 return (error); 3455 } 3456 3457 int 3458 zpool_do_set(int argc, char **argv) 3459 { 3460 set_cbdata_t cb = { 0 }; 3461 int error; 3462 3463 if (argc > 1 && argv[1][0] == '-') { 3464 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3465 argv[1][1]); 3466 usage(B_FALSE); 3467 } 3468 3469 if (argc < 2) { 3470 (void) fprintf(stderr, gettext("missing property=value " 3471 "argument\n")); 3472 usage(B_FALSE); 3473 } 3474 3475 if (argc < 3) { 3476 (void) fprintf(stderr, gettext("missing pool name\n")); 3477 usage(B_FALSE); 3478 } 3479 3480 if (argc > 3) { 3481 (void) fprintf(stderr, gettext("too many pool names\n")); 3482 usage(B_FALSE); 3483 } 3484 3485 cb.cb_propname = argv[1]; 3486 cb.cb_value = strchr(cb.cb_propname, '='); 3487 if (cb.cb_value == NULL) { 3488 (void) fprintf(stderr, gettext("missing value in " 3489 "property=value argument\n")); 3490 usage(B_FALSE); 3491 } 3492 3493 *(cb.cb_value) = '\0'; 3494 cb.cb_value++; 3495 3496 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3497 set_callback, &cb); 3498 3499 if (cb.cb_any_successful) { 3500 *(cb.cb_value - 1) = '='; 3501 zpool_log_history(g_zfs, argc, argv, argv[2], B_FALSE, B_FALSE); 3502 } 3503 3504 return (error); 3505 } 3506 3507 static int 3508 find_command_idx(char *command, int *idx) 3509 { 3510 int i; 3511 3512 for (i = 0; i < NCOMMAND; i++) { 3513 if (command_table[i].name == NULL) 3514 continue; 3515 3516 if (strcmp(command, command_table[i].name) == 0) { 3517 *idx = i; 3518 return (0); 3519 } 3520 } 3521 return (1); 3522 } 3523 3524 int 3525 main(int argc, char **argv) 3526 { 3527 int ret; 3528 int i; 3529 char *cmdname; 3530 int found = 0; 3531 3532 (void) setlocale(LC_ALL, ""); 3533 (void) textdomain(TEXT_DOMAIN); 3534 3535 if ((g_zfs = libzfs_init()) == NULL) { 3536 (void) fprintf(stderr, gettext("internal error: failed to " 3537 "initialize ZFS library\n")); 3538 return (1); 3539 } 3540 3541 libzfs_print_on_error(g_zfs, B_TRUE); 3542 3543 opterr = 0; 3544 3545 /* 3546 * Make sure the user has specified some command. 3547 */ 3548 if (argc < 2) { 3549 (void) fprintf(stderr, gettext("missing command\n")); 3550 usage(B_FALSE); 3551 } 3552 3553 cmdname = argv[1]; 3554 3555 /* 3556 * Special case '-?' 3557 */ 3558 if (strcmp(cmdname, "-?") == 0) 3559 usage(B_TRUE); 3560 3561 /* 3562 * Run the appropriate command. 3563 */ 3564 if (find_command_idx(cmdname, &i) == 0) { 3565 current_command = &command_table[i]; 3566 ret = command_table[i].func(argc - 1, argv + 1); 3567 found++; 3568 } 3569 3570 /* 3571 * 'freeze' is a vile debugging abomination, so we treat it as such. 3572 */ 3573 if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3574 char buf[16384]; 3575 int fd = open(ZFS_DEV, O_RDWR); 3576 (void) strcpy((void *)buf, argv[2]); 3577 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3578 } 3579 3580 if (!found) { 3581 (void) fprintf(stderr, gettext("unrecognized " 3582 "command '%s'\n"), cmdname); 3583 usage(B_FALSE); 3584 } 3585 3586 libzfs_fini(g_zfs); 3587 3588 /* 3589 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3590 * for the purposes of running ::findleaks. 3591 */ 3592 if (getenv("ZFS_ABORT") != NULL) { 3593 (void) printf("dumping core by request\n"); 3594 abort(); 3595 } 3596 3597 return (ret); 3598 } 3599