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