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