1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <assert.h> 30 #include <ctype.h> 31 #include <dirent.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <libgen.h> 35 #include <libintl.h> 36 #include <libuutil.h> 37 #include <locale.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <strings.h> 42 #include <unistd.h> 43 #include <priv.h> 44 #include <pwd.h> 45 #include <zone.h> 46 #include <sys/fs/zfs.h> 47 48 #include <sys/stat.h> 49 50 #include <libzfs.h> 51 52 #include "zpool_util.h" 53 54 static int zpool_do_create(int, char **); 55 static int zpool_do_destroy(int, char **); 56 57 static int zpool_do_add(int, char **); 58 static int zpool_do_remove(int, char **); 59 60 static int zpool_do_list(int, char **); 61 static int zpool_do_iostat(int, char **); 62 static int zpool_do_status(int, char **); 63 64 static int zpool_do_online(int, char **); 65 static int zpool_do_offline(int, char **); 66 static int zpool_do_clear(int, char **); 67 68 static int zpool_do_attach(int, char **); 69 static int zpool_do_detach(int, char **); 70 static int zpool_do_replace(int, char **); 71 72 static int zpool_do_scrub(int, char **); 73 74 static int zpool_do_import(int, char **); 75 static int zpool_do_export(int, char **); 76 77 static int zpool_do_upgrade(int, char **); 78 79 static int zpool_do_history(int, char **); 80 81 static int zpool_do_get(int, char **); 82 static int zpool_do_set(int, char **); 83 84 /* 85 * These libumem hooks provide a reasonable set of defaults for the allocator's 86 * debugging facilities. 87 */ 88 const char * 89 _umem_debug_init(void) 90 { 91 return ("default,verbose"); /* $UMEM_DEBUG setting */ 92 } 93 94 const char * 95 _umem_logging_init(void) 96 { 97 return ("fail,contents"); /* $UMEM_LOGGING setting */ 98 } 99 100 typedef enum { 101 HELP_ADD, 102 HELP_ATTACH, 103 HELP_CLEAR, 104 HELP_CREATE, 105 HELP_DESTROY, 106 HELP_DETACH, 107 HELP_EXPORT, 108 HELP_HISTORY, 109 HELP_IMPORT, 110 HELP_IOSTAT, 111 HELP_LIST, 112 HELP_OFFLINE, 113 HELP_ONLINE, 114 HELP_REPLACE, 115 HELP_REMOVE, 116 HELP_SCRUB, 117 HELP_STATUS, 118 HELP_UPGRADE, 119 HELP_GET, 120 HELP_SET 121 } zpool_help_t; 122 123 124 typedef struct zpool_command { 125 const char *name; 126 int (*func)(int, char **); 127 zpool_help_t usage; 128 } zpool_command_t; 129 130 /* 131 * Master command table. Each ZFS command has a name, associated function, and 132 * usage message. The usage messages need to be internationalized, so we have 133 * to have a function to return the usage message based on a command index. 134 * 135 * These commands are organized according to how they are displayed in the usage 136 * message. An empty command (one with a NULL name) indicates an empty line in 137 * the generic usage message. 138 */ 139 static zpool_command_t command_table[] = { 140 { "create", zpool_do_create, HELP_CREATE }, 141 { "destroy", zpool_do_destroy, HELP_DESTROY }, 142 { NULL }, 143 { "add", zpool_do_add, HELP_ADD }, 144 { "remove", zpool_do_remove, HELP_REMOVE }, 145 { NULL }, 146 { "list", zpool_do_list, HELP_LIST }, 147 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 148 { "status", zpool_do_status, HELP_STATUS }, 149 { NULL }, 150 { "online", zpool_do_online, HELP_ONLINE }, 151 { "offline", zpool_do_offline, HELP_OFFLINE }, 152 { "clear", zpool_do_clear, HELP_CLEAR }, 153 { NULL }, 154 { "attach", zpool_do_attach, HELP_ATTACH }, 155 { "detach", zpool_do_detach, HELP_DETACH }, 156 { "replace", zpool_do_replace, HELP_REPLACE }, 157 { NULL }, 158 { "scrub", zpool_do_scrub, HELP_SCRUB }, 159 { NULL }, 160 { "import", zpool_do_import, HELP_IMPORT }, 161 { "export", zpool_do_export, HELP_EXPORT }, 162 { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 163 { NULL }, 164 { "history", zpool_do_history, HELP_HISTORY }, 165 { "get", zpool_do_get, HELP_GET }, 166 { "set", zpool_do_set, HELP_SET }, 167 }; 168 169 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) 170 171 zpool_command_t *current_command; 172 static char history_str[HIS_MAX_RECORD_LEN]; 173 174 static const char * 175 get_usage(zpool_help_t idx) { 176 switch (idx) { 177 case HELP_ADD: 178 return (gettext("\tadd [-fn] <pool> <vdev> ...\n")); 179 case HELP_ATTACH: 180 return (gettext("\tattach [-f] <pool> <device> " 181 "<new-device>\n")); 182 case HELP_CLEAR: 183 return (gettext("\tclear <pool> [device]\n")); 184 case HELP_CREATE: 185 return (gettext("\tcreate [-fn] [-o property=value] ... \n" 186 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n")); 187 case HELP_DESTROY: 188 return (gettext("\tdestroy [-f] <pool>\n")); 189 case HELP_DETACH: 190 return (gettext("\tdetach <pool> <device>\n")); 191 case HELP_EXPORT: 192 return (gettext("\texport [-f] <pool> ...\n")); 193 case HELP_HISTORY: 194 return (gettext("\thistory [-il] [<pool>] ...\n")); 195 case HELP_IMPORT: 196 return (gettext("\timport [-d dir] [-D]\n" 197 "\timport [-o mntopts] [-o property=value] ... \n" 198 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n" 199 "\timport [-o mntopts] [-o property=value] ... \n" 200 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] " 201 "<pool | id> [newpool]\n")); 202 case HELP_IOSTAT: 203 return (gettext("\tiostat [-v] [pool] ... [interval " 204 "[count]]\n")); 205 case HELP_LIST: 206 return (gettext("\tlist [-H] [-o property[,...]] " 207 "[pool] ...\n")); 208 case HELP_OFFLINE: 209 return (gettext("\toffline [-t] <pool> <device> ...\n")); 210 case HELP_ONLINE: 211 return (gettext("\tonline <pool> <device> ...\n")); 212 case HELP_REPLACE: 213 return (gettext("\treplace [-f] <pool> <device> " 214 "[new-device]\n")); 215 case HELP_REMOVE: 216 return (gettext("\tremove <pool> <device> ...\n")); 217 case HELP_SCRUB: 218 return (gettext("\tscrub [-s] <pool> ...\n")); 219 case HELP_STATUS: 220 return (gettext("\tstatus [-vx] [pool] ...\n")); 221 case HELP_UPGRADE: 222 return (gettext("\tupgrade\n" 223 "\tupgrade -v\n" 224 "\tupgrade [-V version] <-a | pool ...>\n")); 225 case HELP_GET: 226 return (gettext("\tget <\"all\" | property[,...]> " 227 "<pool> ...\n")); 228 case HELP_SET: 229 return (gettext("\tset <property=value> <pool> \n")); 230 } 231 232 abort(); 233 /* NOTREACHED */ 234 } 235 236 237 /* 238 * Callback routine that will print out a pool property value. 239 */ 240 static int 241 print_prop_cb(int prop, void *cb) 242 { 243 FILE *fp = cb; 244 245 (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop)); 246 247 if (zpool_prop_readonly(prop)) 248 (void) fprintf(fp, " NO "); 249 else 250 (void) fprintf(fp, " YES "); 251 252 if (zpool_prop_values(prop) == NULL) 253 (void) fprintf(fp, "-\n"); 254 else 255 (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 256 257 return (ZPROP_CONT); 258 } 259 260 /* 261 * Display usage message. If we're inside a command, display only the usage for 262 * that command. Otherwise, iterate over the entire command table and display 263 * a complete usage message. 264 */ 265 void 266 usage(boolean_t requested) 267 { 268 FILE *fp = requested ? stdout : stderr; 269 270 if (current_command == NULL) { 271 int i; 272 273 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 274 (void) fprintf(fp, 275 gettext("where 'command' is one of the following:\n\n")); 276 277 for (i = 0; i < NCOMMAND; i++) { 278 if (command_table[i].name == NULL) 279 (void) fprintf(fp, "\n"); 280 else 281 (void) fprintf(fp, "%s", 282 get_usage(command_table[i].usage)); 283 } 284 } else { 285 (void) fprintf(fp, gettext("usage:\n")); 286 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 287 } 288 289 if (current_command != NULL && 290 ((strcmp(current_command->name, "set") == 0) || 291 (strcmp(current_command->name, "get") == 0) || 292 (strcmp(current_command->name, "list") == 0))) { 293 294 (void) fprintf(fp, 295 gettext("\nthe following properties are supported:\n")); 296 297 (void) fprintf(fp, "\n\t%-13s %s %s\n\n", 298 "PROPERTY", "EDIT", "VALUES"); 299 300 /* Iterate over all properties */ 301 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 302 ZFS_TYPE_POOL); 303 } 304 305 /* 306 * See comments at end of main(). 307 */ 308 if (getenv("ZFS_ABORT") != NULL) { 309 (void) printf("dumping core by request\n"); 310 abort(); 311 } 312 313 exit(requested ? 0 : 2); 314 } 315 316 void 317 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 318 boolean_t print_logs) 319 { 320 nvlist_t **child; 321 uint_t c, children; 322 char *vname; 323 324 if (name != NULL) 325 (void) printf("\t%*s%s\n", indent, "", name); 326 327 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 328 &child, &children) != 0) 329 return; 330 331 for (c = 0; c < children; c++) { 332 uint64_t is_log = B_FALSE; 333 334 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 335 &is_log); 336 if ((is_log && !print_logs) || (!is_log && print_logs)) 337 continue; 338 339 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 340 print_vdev_tree(zhp, vname, child[c], indent + 2, 341 B_FALSE); 342 free(vname); 343 } 344 } 345 346 /* 347 * Add a property pair (name, string-value) into a property nvlist. 348 */ 349 static int 350 add_prop_list(const char *propname, char *propval, nvlist_t **props) 351 { 352 char *strval; 353 nvlist_t *proplist; 354 zpool_prop_t prop; 355 356 if (*props == NULL && 357 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 358 (void) fprintf(stderr, 359 gettext("internal error: out of memory\n")); 360 return (1); 361 } 362 363 proplist = *props; 364 365 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) { 366 (void) fprintf(stderr, gettext("property '%s' is " 367 "not a valid pool property\n"), propname); 368 return (2); 369 } 370 371 /* Use normalized property name for nvlist operations */ 372 if (nvlist_lookup_string(proplist, zpool_prop_to_name(prop), 373 &strval) == 0 && prop != ZPOOL_PROP_CACHEFILE) { 374 (void) fprintf(stderr, gettext("property '%s' " 375 "specified multiple times\n"), propname); 376 return (2); 377 } 378 379 if (nvlist_add_string(proplist, zpool_prop_to_name(prop), 380 propval) != 0) { 381 (void) fprintf(stderr, gettext("internal " 382 "error: out of memory\n")); 383 return (1); 384 } 385 386 return (0); 387 } 388 389 /* 390 * zpool add [-fn] <pool> <vdev> ... 391 * 392 * -f Force addition of devices, even if they appear in use 393 * -n Do not add the devices, but display the resulting layout if 394 * they were to be added. 395 * 396 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 397 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to 398 * libzfs. 399 */ 400 int 401 zpool_do_add(int argc, char **argv) 402 { 403 boolean_t force = B_FALSE; 404 boolean_t dryrun = B_FALSE; 405 int c; 406 nvlist_t *nvroot; 407 char *poolname; 408 int ret; 409 zpool_handle_t *zhp; 410 nvlist_t *config; 411 412 /* check options */ 413 while ((c = getopt(argc, argv, "fn")) != -1) { 414 switch (c) { 415 case 'f': 416 force = B_TRUE; 417 break; 418 case 'n': 419 dryrun = B_TRUE; 420 break; 421 case '?': 422 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 423 optopt); 424 usage(B_FALSE); 425 } 426 } 427 428 argc -= optind; 429 argv += optind; 430 431 /* get pool name and check number of arguments */ 432 if (argc < 1) { 433 (void) fprintf(stderr, gettext("missing pool name argument\n")); 434 usage(B_FALSE); 435 } 436 if (argc < 2) { 437 (void) fprintf(stderr, gettext("missing vdev specification\n")); 438 usage(B_FALSE); 439 } 440 441 poolname = argv[0]; 442 443 argc--; 444 argv++; 445 446 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 447 return (1); 448 449 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 450 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 451 poolname); 452 zpool_close(zhp); 453 return (1); 454 } 455 456 /* pass off to get_vdev_spec for processing */ 457 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, argc, argv); 458 if (nvroot == NULL) { 459 zpool_close(zhp); 460 return (1); 461 } 462 463 if (dryrun) { 464 nvlist_t *poolnvroot; 465 466 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 467 &poolnvroot) == 0); 468 469 (void) printf(gettext("would update '%s' to the following " 470 "configuration:\n"), zpool_get_name(zhp)); 471 472 /* print original main pool and new tree */ 473 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE); 474 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE); 475 476 /* Do the same for the logs */ 477 if (num_logs(poolnvroot) > 0) { 478 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE); 479 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE); 480 } else if (num_logs(nvroot) > 0) { 481 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE); 482 } 483 484 ret = 0; 485 } else { 486 ret = (zpool_add(zhp, nvroot) != 0); 487 } 488 489 nvlist_free(nvroot); 490 zpool_close(zhp); 491 492 return (ret); 493 } 494 495 /* 496 * zpool remove <pool> <vdev> ... 497 * 498 * Removes the given vdev from the pool. Currently, this only supports removing 499 * spares and cache devices from the pool. Eventually, we'll want to support 500 * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs. 501 */ 502 int 503 zpool_do_remove(int argc, char **argv) 504 { 505 char *poolname; 506 int i, ret = 0; 507 zpool_handle_t *zhp; 508 509 argc--; 510 argv++; 511 512 /* get pool name and check number of arguments */ 513 if (argc < 1) { 514 (void) fprintf(stderr, gettext("missing pool name argument\n")); 515 usage(B_FALSE); 516 } 517 if (argc < 2) { 518 (void) fprintf(stderr, gettext("missing device\n")); 519 usage(B_FALSE); 520 } 521 522 poolname = argv[0]; 523 524 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 525 return (1); 526 527 for (i = 1; i < argc; i++) { 528 if (zpool_vdev_remove(zhp, argv[i]) != 0) 529 ret = 1; 530 } 531 532 return (ret); 533 } 534 535 /* 536 * zpool create [-fn] [-o property=value] ... [-R root] [-m mountpoint] 537 * <pool> <dev> ... 538 * 539 * -f Force creation, even if devices appear in use 540 * -n Do not create the pool, but display the resulting layout if it 541 * were to be created. 542 * -R Create a pool under an alternate root 543 * -m Set default mountpoint for the root dataset. By default it's 544 * '/<pool>' 545 * -o Set property=value. 546 * 547 * Creates the named pool according to the given vdev specification. The 548 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once 549 * we get the nvlist back from get_vdev_spec(), we either print out the contents 550 * (if '-n' was specified), or pass it to libzfs to do the creation. 551 */ 552 int 553 zpool_do_create(int argc, char **argv) 554 { 555 boolean_t force = B_FALSE; 556 boolean_t dryrun = B_FALSE; 557 int c; 558 nvlist_t *nvroot = NULL; 559 char *poolname; 560 int ret = 1; 561 char *altroot = NULL; 562 char *mountpoint = NULL; 563 nvlist_t **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 "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, minutes_taken; 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 minutes_taken = (uint64_t)((end - start) / 60); 2609 2610 (void) printf(gettext("%s %s after %lluh%um with %llu errors " 2611 "on %s"), 2612 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2613 (u_longlong_t)(minutes_taken / 60), 2614 (uint_t)(minutes_taken % 60), 2615 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2616 return; 2617 } 2618 2619 if (examined == 0) 2620 examined = 1; 2621 if (examined > total) 2622 total = examined; 2623 2624 fraction_done = (double)examined / total; 2625 minutes_left = (uint64_t)((now - start) * 2626 (1 - fraction_done) / fraction_done / 60); 2627 minutes_taken = (uint64_t)((now - start) / 60); 2628 2629 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, " 2630 "%lluh%um to go\n"), 2631 scrub_type, (u_longlong_t)(minutes_taken / 60), 2632 (uint_t)(minutes_taken % 60), 100 * fraction_done, 2633 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2634 } 2635 2636 typedef struct spare_cbdata { 2637 uint64_t cb_guid; 2638 zpool_handle_t *cb_zhp; 2639 } spare_cbdata_t; 2640 2641 static boolean_t 2642 find_vdev(nvlist_t *nv, uint64_t search) 2643 { 2644 uint64_t guid; 2645 nvlist_t **child; 2646 uint_t c, children; 2647 2648 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 2649 search == guid) 2650 return (B_TRUE); 2651 2652 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2653 &child, &children) == 0) { 2654 for (c = 0; c < children; c++) 2655 if (find_vdev(child[c], search)) 2656 return (B_TRUE); 2657 } 2658 2659 return (B_FALSE); 2660 } 2661 2662 static int 2663 find_spare(zpool_handle_t *zhp, void *data) 2664 { 2665 spare_cbdata_t *cbp = data; 2666 nvlist_t *config, *nvroot; 2667 2668 config = zpool_get_config(zhp, NULL); 2669 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2670 &nvroot) == 0); 2671 2672 if (find_vdev(nvroot, cbp->cb_guid)) { 2673 cbp->cb_zhp = zhp; 2674 return (1); 2675 } 2676 2677 zpool_close(zhp); 2678 return (0); 2679 } 2680 2681 /* 2682 * Print out configuration state as requested by status_callback. 2683 */ 2684 void 2685 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 2686 int namewidth, int depth, boolean_t isspare, boolean_t print_logs) 2687 { 2688 nvlist_t **child; 2689 uint_t c, children; 2690 vdev_stat_t *vs; 2691 char rbuf[6], wbuf[6], cbuf[6], repaired[7]; 2692 char *vname; 2693 uint64_t notpresent; 2694 spare_cbdata_t cb; 2695 char *state; 2696 2697 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 2698 (uint64_t **)&vs, &c) == 0); 2699 2700 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2701 &child, &children) != 0) 2702 children = 0; 2703 2704 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 2705 if (isspare) { 2706 /* 2707 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 2708 * online drives. 2709 */ 2710 if (vs->vs_aux == VDEV_AUX_SPARED) 2711 state = "INUSE"; 2712 else if (vs->vs_state == VDEV_STATE_HEALTHY) 2713 state = "AVAIL"; 2714 } 2715 2716 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 2717 name, state); 2718 2719 if (!isspare) { 2720 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 2721 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 2722 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 2723 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 2724 } 2725 2726 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2727 ¬present) == 0) { 2728 char *path; 2729 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2730 (void) printf(" was %s", path); 2731 } else if (vs->vs_aux != 0) { 2732 (void) printf(" "); 2733 2734 switch (vs->vs_aux) { 2735 case VDEV_AUX_OPEN_FAILED: 2736 (void) printf(gettext("cannot open")); 2737 break; 2738 2739 case VDEV_AUX_BAD_GUID_SUM: 2740 (void) printf(gettext("missing device")); 2741 break; 2742 2743 case VDEV_AUX_NO_REPLICAS: 2744 (void) printf(gettext("insufficient replicas")); 2745 break; 2746 2747 case VDEV_AUX_VERSION_NEWER: 2748 (void) printf(gettext("newer version")); 2749 break; 2750 2751 case VDEV_AUX_SPARED: 2752 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2753 &cb.cb_guid) == 0); 2754 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 2755 if (strcmp(zpool_get_name(cb.cb_zhp), 2756 zpool_get_name(zhp)) == 0) 2757 (void) printf(gettext("currently in " 2758 "use")); 2759 else 2760 (void) printf(gettext("in use by " 2761 "pool '%s'"), 2762 zpool_get_name(cb.cb_zhp)); 2763 zpool_close(cb.cb_zhp); 2764 } else { 2765 (void) printf(gettext("currently in use")); 2766 } 2767 break; 2768 2769 case VDEV_AUX_ERR_EXCEEDED: 2770 (void) printf(gettext("too many errors")); 2771 break; 2772 2773 default: 2774 (void) printf(gettext("corrupted data")); 2775 break; 2776 } 2777 } else if (vs->vs_scrub_repaired != 0 && children == 0) { 2778 /* 2779 * Report bytes resilvered/repaired on leaf devices. 2780 */ 2781 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired)); 2782 (void) printf(gettext(" %s %s"), repaired, 2783 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2784 "resilvered" : "repaired"); 2785 } 2786 2787 (void) printf("\n"); 2788 2789 for (c = 0; c < children; c++) { 2790 uint64_t is_log = B_FALSE; 2791 2792 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2793 &is_log); 2794 if ((is_log && !print_logs) || (!is_log && print_logs)) 2795 continue; 2796 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 2797 print_status_config(zhp, vname, child[c], 2798 namewidth, depth + 2, isspare, B_FALSE); 2799 free(vname); 2800 } 2801 } 2802 2803 static void 2804 print_error_log(zpool_handle_t *zhp) 2805 { 2806 nvlist_t *nverrlist = NULL; 2807 nvpair_t *elem; 2808 char *pathname; 2809 size_t len = MAXPATHLEN * 2; 2810 2811 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 2812 (void) printf("errors: List of errors unavailable " 2813 "(insufficient privileges)\n"); 2814 return; 2815 } 2816 2817 (void) printf("errors: Permanent errors have been " 2818 "detected in the following files:\n\n"); 2819 2820 pathname = safe_malloc(len); 2821 elem = NULL; 2822 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 2823 nvlist_t *nv; 2824 uint64_t dsobj, obj; 2825 2826 verify(nvpair_value_nvlist(elem, &nv) == 0); 2827 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 2828 &dsobj) == 0); 2829 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 2830 &obj) == 0); 2831 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 2832 (void) printf("%7s %s\n", "", pathname); 2833 } 2834 free(pathname); 2835 nvlist_free(nverrlist); 2836 } 2837 2838 static void 2839 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2840 int namewidth) 2841 { 2842 uint_t i; 2843 char *name; 2844 2845 if (nspares == 0) 2846 return; 2847 2848 (void) printf(gettext("\tspares\n")); 2849 2850 for (i = 0; i < nspares; i++) { 2851 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2852 print_status_config(zhp, name, spares[i], 2853 namewidth, 2, B_TRUE, B_FALSE); 2854 free(name); 2855 } 2856 } 2857 2858 static void 2859 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 2860 int namewidth) 2861 { 2862 uint_t i; 2863 char *name; 2864 2865 if (nl2cache == 0) 2866 return; 2867 2868 (void) printf(gettext("\tcache\n")); 2869 2870 for (i = 0; i < nl2cache; i++) { 2871 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]); 2872 print_status_config(zhp, name, l2cache[i], 2873 namewidth, 2, B_FALSE, B_FALSE); 2874 free(name); 2875 } 2876 } 2877 2878 /* 2879 * Display a summary of pool status. Displays a summary such as: 2880 * 2881 * pool: tank 2882 * status: DEGRADED 2883 * reason: One or more devices ... 2884 * see: http://www.sun.com/msg/ZFS-xxxx-01 2885 * config: 2886 * mirror DEGRADED 2887 * c1t0d0 OK 2888 * c2t0d0 UNAVAIL 2889 * 2890 * When given the '-v' option, we print out the complete config. If the '-e' 2891 * option is specified, then we print out error rate information as well. 2892 */ 2893 int 2894 status_callback(zpool_handle_t *zhp, void *data) 2895 { 2896 status_cbdata_t *cbp = data; 2897 nvlist_t *config, *nvroot; 2898 char *msgid; 2899 int reason; 2900 const char *health; 2901 uint_t c; 2902 vdev_stat_t *vs; 2903 2904 config = zpool_get_config(zhp, NULL); 2905 reason = zpool_get_status(zhp, &msgid); 2906 2907 cbp->cb_count++; 2908 2909 /* 2910 * If we were given 'zpool status -x', only report those pools with 2911 * problems. 2912 */ 2913 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) { 2914 if (!cbp->cb_allpools) { 2915 (void) printf(gettext("pool '%s' is healthy\n"), 2916 zpool_get_name(zhp)); 2917 if (cbp->cb_first) 2918 cbp->cb_first = B_FALSE; 2919 } 2920 return (0); 2921 } 2922 2923 if (cbp->cb_first) 2924 cbp->cb_first = B_FALSE; 2925 else 2926 (void) printf("\n"); 2927 2928 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2929 &nvroot) == 0); 2930 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2931 (uint64_t **)&vs, &c) == 0); 2932 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 2933 2934 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 2935 (void) printf(gettext(" state: %s\n"), health); 2936 2937 switch (reason) { 2938 case ZPOOL_STATUS_MISSING_DEV_R: 2939 (void) printf(gettext("status: One or more devices could not " 2940 "be opened. Sufficient replicas exist for\n\tthe pool to " 2941 "continue functioning in a degraded state.\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_MISSING_DEV_NR: 2947 (void) printf(gettext("status: One or more devices could not " 2948 "be opened. There are insufficient\n\treplicas for the " 2949 "pool to continue functioning.\n")); 2950 (void) printf(gettext("action: Attach the missing device and " 2951 "online it using 'zpool online'.\n")); 2952 break; 2953 2954 case ZPOOL_STATUS_CORRUPT_LABEL_R: 2955 (void) printf(gettext("status: One or more devices could not " 2956 "be used because the label is missing or\n\tinvalid. " 2957 "Sufficient replicas exist for the pool to continue\n\t" 2958 "functioning in a degraded state.\n")); 2959 (void) printf(gettext("action: Replace the device using " 2960 "'zpool replace'.\n")); 2961 break; 2962 2963 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 2964 (void) printf(gettext("status: One or more devices could not " 2965 "be used because the label is missing \n\tor invalid. " 2966 "There are insufficient replicas for the pool to " 2967 "continue\n\tfunctioning.\n")); 2968 (void) printf(gettext("action: Destroy and re-create the pool " 2969 "from a backup source.\n")); 2970 break; 2971 2972 case ZPOOL_STATUS_FAILING_DEV: 2973 (void) printf(gettext("status: One or more devices has " 2974 "experienced an unrecoverable error. An\n\tattempt was " 2975 "made to correct the error. Applications are " 2976 "unaffected.\n")); 2977 (void) printf(gettext("action: Determine if the device needs " 2978 "to be replaced, and clear the errors\n\tusing " 2979 "'zpool clear' or replace the device with 'zpool " 2980 "replace'.\n")); 2981 break; 2982 2983 case ZPOOL_STATUS_OFFLINE_DEV: 2984 (void) printf(gettext("status: One or more devices has " 2985 "been taken offline by the administrator.\n\tSufficient " 2986 "replicas exist for the pool to continue functioning in " 2987 "a\n\tdegraded state.\n")); 2988 (void) printf(gettext("action: Online the device using " 2989 "'zpool online' or replace the device with\n\t'zpool " 2990 "replace'.\n")); 2991 break; 2992 2993 case ZPOOL_STATUS_RESILVERING: 2994 (void) printf(gettext("status: One or more devices is " 2995 "currently being resilvered. The pool will\n\tcontinue " 2996 "to function, possibly in a degraded state.\n")); 2997 (void) printf(gettext("action: Wait for the resilver to " 2998 "complete.\n")); 2999 break; 3000 3001 case ZPOOL_STATUS_CORRUPT_DATA: 3002 (void) printf(gettext("status: One or more devices has " 3003 "experienced an error resulting in data\n\tcorruption. " 3004 "Applications may be affected.\n")); 3005 (void) printf(gettext("action: Restore the file in question " 3006 "if possible. Otherwise restore the\n\tentire pool from " 3007 "backup.\n")); 3008 break; 3009 3010 case ZPOOL_STATUS_CORRUPT_POOL: 3011 (void) printf(gettext("status: The pool metadata is corrupted " 3012 "and the pool cannot be opened.\n")); 3013 (void) printf(gettext("action: Destroy and re-create the pool " 3014 "from a backup source.\n")); 3015 break; 3016 3017 case ZPOOL_STATUS_VERSION_OLDER: 3018 (void) printf(gettext("status: The pool is formatted using an " 3019 "older on-disk format. The pool can\n\tstill be used, but " 3020 "some features are unavailable.\n")); 3021 (void) printf(gettext("action: Upgrade the pool using 'zpool " 3022 "upgrade'. Once this is done, the\n\tpool will no longer " 3023 "be accessible on older software versions.\n")); 3024 break; 3025 3026 case ZPOOL_STATUS_VERSION_NEWER: 3027 (void) printf(gettext("status: The pool has been upgraded to a " 3028 "newer, incompatible on-disk version.\n\tThe pool cannot " 3029 "be accessed on this system.\n")); 3030 (void) printf(gettext("action: Access the pool from a system " 3031 "running more recent software, or\n\trestore the pool from " 3032 "backup.\n")); 3033 break; 3034 3035 case ZPOOL_STATUS_FAULTED_DEV_R: 3036 (void) printf(gettext("status: One or more devices are " 3037 "faulted in response to persistent errors.\n\tSufficient " 3038 "replicas exist for the pool to continue functioning " 3039 "in a\n\tdegraded state.\n")); 3040 (void) printf(gettext("action: Replace the faulted device, " 3041 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 3042 break; 3043 3044 case ZPOOL_STATUS_FAULTED_DEV_NR: 3045 (void) printf(gettext("status: One or more devices are " 3046 "faulted in response to persistent errors. There are " 3047 "insufficient replicas for the pool to\n\tcontinue " 3048 "functioning.\n")); 3049 (void) printf(gettext("action: Destroy and re-create the pool " 3050 "from a backup source. Manually marking the device\n" 3051 "\trepaired using 'zpool clear' may allow some data " 3052 "to be recovered.\n")); 3053 break; 3054 3055 default: 3056 /* 3057 * The remaining errors can't actually be generated, yet. 3058 */ 3059 assert(reason == ZPOOL_STATUS_OK); 3060 } 3061 3062 if (msgid != NULL) 3063 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 3064 msgid); 3065 3066 if (config != NULL) { 3067 int namewidth; 3068 uint64_t nerr; 3069 nvlist_t **spares, **l2cache; 3070 uint_t nspares, nl2cache; 3071 3072 3073 (void) printf(gettext(" scrub: ")); 3074 print_scrub_status(nvroot); 3075 3076 namewidth = max_width(zhp, nvroot, 0, 0); 3077 if (namewidth < 10) 3078 namewidth = 10; 3079 3080 (void) printf(gettext("config:\n\n")); 3081 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 3082 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 3083 print_status_config(zhp, zpool_get_name(zhp), nvroot, 3084 namewidth, 0, B_FALSE, B_FALSE); 3085 if (num_logs(nvroot) > 0) 3086 print_status_config(zhp, "logs", nvroot, namewidth, 0, 3087 B_FALSE, B_TRUE); 3088 3089 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 3090 &l2cache, &nl2cache) == 0) 3091 print_l2cache(zhp, l2cache, nl2cache, namewidth); 3092 3093 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3094 &spares, &nspares) == 0) 3095 print_spares(zhp, spares, nspares, namewidth); 3096 3097 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3098 &nerr) == 0) { 3099 nvlist_t *nverrlist = NULL; 3100 3101 /* 3102 * If the approximate error count is small, get a 3103 * precise count by fetching the entire log and 3104 * uniquifying the results. 3105 */ 3106 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 3107 zpool_get_errlog(zhp, &nverrlist) == 0) { 3108 nvpair_t *elem; 3109 3110 elem = NULL; 3111 nerr = 0; 3112 while ((elem = nvlist_next_nvpair(nverrlist, 3113 elem)) != NULL) { 3114 nerr++; 3115 } 3116 } 3117 nvlist_free(nverrlist); 3118 3119 (void) printf("\n"); 3120 3121 if (nerr == 0) 3122 (void) printf(gettext("errors: No known data " 3123 "errors\n")); 3124 else if (!cbp->cb_verbose) 3125 (void) printf(gettext("errors: %llu data " 3126 "errors, use '-v' for a list\n"), 3127 (u_longlong_t)nerr); 3128 else 3129 print_error_log(zhp); 3130 } 3131 } else { 3132 (void) printf(gettext("config: The configuration cannot be " 3133 "determined.\n")); 3134 } 3135 3136 return (0); 3137 } 3138 3139 /* 3140 * zpool status [-vx] [pool] ... 3141 * 3142 * -v Display complete error logs 3143 * -x Display only pools with potential problems 3144 * 3145 * Describes the health status of all pools or some subset. 3146 */ 3147 int 3148 zpool_do_status(int argc, char **argv) 3149 { 3150 int c; 3151 int ret; 3152 status_cbdata_t cb = { 0 }; 3153 3154 /* check options */ 3155 while ((c = getopt(argc, argv, "vx")) != -1) { 3156 switch (c) { 3157 case 'v': 3158 cb.cb_verbose = B_TRUE; 3159 break; 3160 case 'x': 3161 cb.cb_explain = B_TRUE; 3162 break; 3163 case '?': 3164 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3165 optopt); 3166 usage(B_FALSE); 3167 } 3168 } 3169 3170 argc -= optind; 3171 argv += optind; 3172 3173 cb.cb_first = B_TRUE; 3174 3175 if (argc == 0) 3176 cb.cb_allpools = B_TRUE; 3177 3178 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3179 3180 if (argc == 0 && cb.cb_count == 0) 3181 (void) printf(gettext("no pools available\n")); 3182 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3183 (void) printf(gettext("all pools are healthy\n")); 3184 3185 return (ret); 3186 } 3187 3188 typedef struct upgrade_cbdata { 3189 int cb_all; 3190 int cb_first; 3191 int cb_newer; 3192 int cb_argc; 3193 uint64_t cb_version; 3194 char **cb_argv; 3195 } upgrade_cbdata_t; 3196 3197 static int 3198 upgrade_cb(zpool_handle_t *zhp, void *arg) 3199 { 3200 upgrade_cbdata_t *cbp = arg; 3201 nvlist_t *config; 3202 uint64_t version; 3203 int ret = 0; 3204 3205 config = zpool_get_config(zhp, NULL); 3206 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3207 &version) == 0); 3208 3209 if (!cbp->cb_newer && version < SPA_VERSION) { 3210 if (!cbp->cb_all) { 3211 if (cbp->cb_first) { 3212 (void) printf(gettext("The following pools are " 3213 "out of date, and can be upgraded. After " 3214 "being\nupgraded, these pools will no " 3215 "longer be accessible by older software " 3216 "versions.\n\n")); 3217 (void) printf(gettext("VER POOL\n")); 3218 (void) printf(gettext("--- ------------\n")); 3219 cbp->cb_first = B_FALSE; 3220 } 3221 3222 (void) printf("%2llu %s\n", (u_longlong_t)version, 3223 zpool_get_name(zhp)); 3224 } else { 3225 cbp->cb_first = B_FALSE; 3226 ret = zpool_upgrade(zhp, cbp->cb_version); 3227 if (!ret) { 3228 (void) printf(gettext("Successfully upgraded " 3229 "'%s'\n\n"), zpool_get_name(zhp)); 3230 } 3231 } 3232 } else if (cbp->cb_newer && version > SPA_VERSION) { 3233 assert(!cbp->cb_all); 3234 3235 if (cbp->cb_first) { 3236 (void) printf(gettext("The following pools are " 3237 "formatted using a newer software version and\n" 3238 "cannot be accessed on the current system.\n\n")); 3239 (void) printf(gettext("VER POOL\n")); 3240 (void) printf(gettext("--- ------------\n")); 3241 cbp->cb_first = B_FALSE; 3242 } 3243 3244 (void) printf("%2llu %s\n", (u_longlong_t)version, 3245 zpool_get_name(zhp)); 3246 } 3247 3248 zpool_close(zhp); 3249 return (ret); 3250 } 3251 3252 /* ARGSUSED */ 3253 static int 3254 upgrade_one(zpool_handle_t *zhp, void *data) 3255 { 3256 upgrade_cbdata_t *cbp = data; 3257 uint64_t cur_version; 3258 int ret; 3259 3260 if (strcmp("log", zpool_get_name(zhp)) == 0) { 3261 (void) printf(gettext("'log' is now a reserved word\n" 3262 "Pool 'log' must be renamed using export and import" 3263 " to upgrade.\n")); 3264 return (1); 3265 } 3266 3267 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 3268 if (cur_version >= cbp->cb_version) { 3269 (void) printf(gettext("Pool '%s' is already formatted " 3270 "using more current version '%d'.\n"), zpool_get_name(zhp), 3271 cur_version); 3272 return (0); 3273 } 3274 3275 ret = zpool_upgrade(zhp, cbp->cb_version); 3276 3277 if (!ret) { 3278 (void) printf(gettext("Successfully upgraded '%s' " 3279 "from version %llu to version %llu\n\n"), 3280 zpool_get_name(zhp), (u_longlong_t)cur_version, 3281 (u_longlong_t)cbp->cb_version); 3282 } 3283 3284 return (ret != 0); 3285 } 3286 3287 /* 3288 * zpool upgrade 3289 * zpool upgrade -v 3290 * zpool upgrade [-V version] <-a | pool ...> 3291 * 3292 * With no arguments, display downrev'd ZFS pool available for upgrade. 3293 * Individual pools can be upgraded by specifying the pool, and '-a' will 3294 * upgrade all pools. 3295 */ 3296 int 3297 zpool_do_upgrade(int argc, char **argv) 3298 { 3299 int c; 3300 upgrade_cbdata_t cb = { 0 }; 3301 int ret = 0; 3302 boolean_t showversions = B_FALSE; 3303 char *end; 3304 3305 3306 /* check options */ 3307 while ((c = getopt(argc, argv, "avV:")) != -1) { 3308 switch (c) { 3309 case 'a': 3310 cb.cb_all = B_TRUE; 3311 break; 3312 case 'v': 3313 showversions = B_TRUE; 3314 break; 3315 case 'V': 3316 cb.cb_version = strtoll(optarg, &end, 10); 3317 if (*end != '\0' || cb.cb_version > SPA_VERSION || 3318 cb.cb_version < SPA_VERSION_1) { 3319 (void) fprintf(stderr, 3320 gettext("invalid version '%s'\n"), optarg); 3321 usage(B_FALSE); 3322 } 3323 break; 3324 case '?': 3325 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3326 optopt); 3327 usage(B_FALSE); 3328 } 3329 } 3330 3331 cb.cb_argc = argc; 3332 cb.cb_argv = argv; 3333 argc -= optind; 3334 argv += optind; 3335 3336 if (cb.cb_version == 0) { 3337 cb.cb_version = SPA_VERSION; 3338 } else if (!cb.cb_all && argc == 0) { 3339 (void) fprintf(stderr, gettext("-V option is " 3340 "incompatible with other arguments\n")); 3341 usage(B_FALSE); 3342 } 3343 3344 if (showversions) { 3345 if (cb.cb_all || argc != 0) { 3346 (void) fprintf(stderr, gettext("-v option is " 3347 "incompatible with other arguments\n")); 3348 usage(B_FALSE); 3349 } 3350 } else if (cb.cb_all) { 3351 if (argc != 0) { 3352 (void) fprintf(stderr, gettext("-a option should not " 3353 "be used along with a pool name\n")); 3354 usage(B_FALSE); 3355 } 3356 } 3357 3358 (void) printf(gettext("This system is currently running " 3359 "ZFS pool version %llu.\n\n"), SPA_VERSION); 3360 cb.cb_first = B_TRUE; 3361 if (showversions) { 3362 (void) printf(gettext("The following versions are " 3363 "supported:\n\n")); 3364 (void) printf(gettext("VER DESCRIPTION\n")); 3365 (void) printf("--- -----------------------------------------" 3366 "---------------\n"); 3367 (void) printf(gettext(" 1 Initial ZFS version\n")); 3368 (void) printf(gettext(" 2 Ditto blocks " 3369 "(replicated metadata)\n")); 3370 (void) printf(gettext(" 3 Hot spares and double parity " 3371 "RAID-Z\n")); 3372 (void) printf(gettext(" 4 zpool history\n")); 3373 (void) printf(gettext(" 5 Compression using the gzip " 3374 "algorithm\n")); 3375 (void) printf(gettext(" 6 bootfs pool property\n")); 3376 (void) printf(gettext(" 7 Separate intent log devices\n")); 3377 (void) printf(gettext(" 8 Delegated administration\n")); 3378 (void) printf(gettext(" 9 refquota and refreservation " 3379 "properties\n")); 3380 (void) printf(gettext(" 10 Cache devices\n")); 3381 (void) printf(gettext("For more information on a particular " 3382 "version, including supported releases, see:\n\n")); 3383 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3384 "version/N\n\n"); 3385 (void) printf(gettext("Where 'N' is the version number.\n")); 3386 } else if (argc == 0) { 3387 int notfound; 3388 3389 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3390 notfound = cb.cb_first; 3391 3392 if (!cb.cb_all && ret == 0) { 3393 if (!cb.cb_first) 3394 (void) printf("\n"); 3395 cb.cb_first = B_TRUE; 3396 cb.cb_newer = B_TRUE; 3397 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3398 if (!cb.cb_first) { 3399 notfound = B_FALSE; 3400 (void) printf("\n"); 3401 } 3402 } 3403 3404 if (ret == 0) { 3405 if (notfound) 3406 (void) printf(gettext("All pools are formatted " 3407 "using this version.\n")); 3408 else if (!cb.cb_all) 3409 (void) printf(gettext("Use 'zpool upgrade -v' " 3410 "for a list of available versions and " 3411 "their associated\nfeatures.\n")); 3412 } 3413 } else { 3414 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3415 upgrade_one, &cb); 3416 } 3417 3418 return (ret); 3419 } 3420 3421 typedef struct hist_cbdata { 3422 boolean_t first; 3423 int longfmt; 3424 int internal; 3425 } hist_cbdata_t; 3426 3427 char *hist_event_table[LOG_END] = { 3428 "invalid event", 3429 "pool create", 3430 "vdev add", 3431 "pool remove", 3432 "pool destroy", 3433 "pool export", 3434 "pool import", 3435 "vdev attach", 3436 "vdev replace", 3437 "vdev detach", 3438 "vdev online", 3439 "vdev offline", 3440 "vdev upgrade", 3441 "pool clear", 3442 "pool scrub", 3443 "pool property set", 3444 "create", 3445 "clone", 3446 "destroy", 3447 "destroy_begin_sync", 3448 "inherit", 3449 "property set", 3450 "quota set", 3451 "permission update", 3452 "permission remove", 3453 "permission who remove", 3454 "promote", 3455 "receive", 3456 "rename", 3457 "reservation set", 3458 "replay_inc_sync", 3459 "replay_full_sync", 3460 "rollback", 3461 "snapshot", 3462 "filesystem version upgrade", 3463 "refquota set", 3464 "refreservation set", 3465 }; 3466 3467 /* 3468 * Print out the command history for a specific pool. 3469 */ 3470 static int 3471 get_history_one(zpool_handle_t *zhp, void *data) 3472 { 3473 nvlist_t *nvhis; 3474 nvlist_t **records; 3475 uint_t numrecords; 3476 char *cmdstr; 3477 char *pathstr; 3478 uint64_t dst_time; 3479 time_t tsec; 3480 struct tm t; 3481 char tbuf[30]; 3482 int ret, i; 3483 uint64_t who; 3484 struct passwd *pwd; 3485 char *hostname; 3486 char *zonename; 3487 char internalstr[MAXPATHLEN]; 3488 hist_cbdata_t *cb = (hist_cbdata_t *)data; 3489 uint64_t txg; 3490 uint64_t ievent; 3491 3492 cb->first = B_FALSE; 3493 3494 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3495 3496 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3497 return (ret); 3498 3499 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3500 &records, &numrecords) == 0); 3501 for (i = 0; i < numrecords; i++) { 3502 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3503 &dst_time) != 0) 3504 continue; 3505 3506 /* is it an internal event or a standard event? */ 3507 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3508 &cmdstr) != 0) { 3509 if (cb->internal == 0) 3510 continue; 3511 3512 if (nvlist_lookup_uint64(records[i], 3513 ZPOOL_HIST_INT_EVENT, &ievent) != 0) 3514 continue; 3515 verify(nvlist_lookup_uint64(records[i], 3516 ZPOOL_HIST_TXG, &txg) == 0); 3517 verify(nvlist_lookup_string(records[i], 3518 ZPOOL_HIST_INT_STR, &pathstr) == 0); 3519 if (ievent > LOG_END) 3520 continue; 3521 (void) snprintf(internalstr, 3522 sizeof (internalstr), 3523 "[internal %s txg:%lld] %s", 3524 hist_event_table[ievent], txg, 3525 pathstr); 3526 cmdstr = internalstr; 3527 } 3528 tsec = dst_time; 3529 (void) localtime_r(&tsec, &t); 3530 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3531 (void) printf("%s %s", tbuf, cmdstr); 3532 3533 if (!cb->longfmt) { 3534 (void) printf("\n"); 3535 continue; 3536 } 3537 (void) printf(" ["); 3538 if (nvlist_lookup_uint64(records[i], 3539 ZPOOL_HIST_WHO, &who) == 0) { 3540 pwd = getpwuid((uid_t)who); 3541 if (pwd) 3542 (void) printf("user %s on", 3543 pwd->pw_name); 3544 else 3545 (void) printf("user %d on", 3546 (int)who); 3547 } else { 3548 (void) printf(gettext("no info]\n")); 3549 continue; 3550 } 3551 if (nvlist_lookup_string(records[i], 3552 ZPOOL_HIST_HOST, &hostname) == 0) { 3553 (void) printf(" %s", hostname); 3554 } 3555 if (nvlist_lookup_string(records[i], 3556 ZPOOL_HIST_ZONE, &zonename) == 0) { 3557 (void) printf(":%s", zonename); 3558 } 3559 3560 (void) printf("]"); 3561 (void) printf("\n"); 3562 } 3563 (void) printf("\n"); 3564 nvlist_free(nvhis); 3565 3566 return (ret); 3567 } 3568 3569 /* 3570 * zpool history <pool> 3571 * 3572 * Displays the history of commands that modified pools. 3573 */ 3574 3575 3576 int 3577 zpool_do_history(int argc, char **argv) 3578 { 3579 hist_cbdata_t cbdata = { 0 }; 3580 int ret; 3581 int c; 3582 3583 cbdata.first = B_TRUE; 3584 /* check options */ 3585 while ((c = getopt(argc, argv, "li")) != -1) { 3586 switch (c) { 3587 case 'l': 3588 cbdata.longfmt = 1; 3589 break; 3590 case 'i': 3591 cbdata.internal = 1; 3592 break; 3593 case '?': 3594 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3595 optopt); 3596 usage(B_FALSE); 3597 } 3598 } 3599 argc -= optind; 3600 argv += optind; 3601 3602 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3603 &cbdata); 3604 3605 if (argc == 0 && cbdata.first == B_TRUE) { 3606 (void) printf(gettext("no pools available\n")); 3607 return (0); 3608 } 3609 3610 return (ret); 3611 } 3612 3613 static int 3614 get_callback(zpool_handle_t *zhp, void *data) 3615 { 3616 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 3617 char value[MAXNAMELEN]; 3618 zprop_source_t srctype; 3619 zprop_list_t *pl; 3620 3621 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3622 3623 /* 3624 * Skip the special fake placeholder. This will also skip 3625 * over the name property when 'all' is specified. 3626 */ 3627 if (pl->pl_prop == ZPOOL_PROP_NAME && 3628 pl == cbp->cb_proplist) 3629 continue; 3630 3631 if (zpool_get_prop(zhp, pl->pl_prop, 3632 value, sizeof (value), &srctype) != 0) 3633 continue; 3634 3635 zprop_print_one_property(zpool_get_name(zhp), cbp, 3636 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3637 } 3638 return (0); 3639 } 3640 3641 int 3642 zpool_do_get(int argc, char **argv) 3643 { 3644 zprop_get_cbdata_t cb = { 0 }; 3645 zprop_list_t fake_name = { 0 }; 3646 int ret; 3647 3648 if (argc < 3) 3649 usage(B_FALSE); 3650 3651 cb.cb_first = B_TRUE; 3652 cb.cb_sources = ZPROP_SRC_ALL; 3653 cb.cb_columns[0] = GET_COL_NAME; 3654 cb.cb_columns[1] = GET_COL_PROPERTY; 3655 cb.cb_columns[2] = GET_COL_VALUE; 3656 cb.cb_columns[3] = GET_COL_SOURCE; 3657 cb.cb_type = ZFS_TYPE_POOL; 3658 3659 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 3660 ZFS_TYPE_POOL) != 0) 3661 usage(B_FALSE); 3662 3663 if (cb.cb_proplist != NULL) { 3664 fake_name.pl_prop = ZPOOL_PROP_NAME; 3665 fake_name.pl_width = strlen(gettext("NAME")); 3666 fake_name.pl_next = cb.cb_proplist; 3667 cb.cb_proplist = &fake_name; 3668 } 3669 3670 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3671 get_callback, &cb); 3672 3673 if (cb.cb_proplist == &fake_name) 3674 zprop_free_list(fake_name.pl_next); 3675 else 3676 zprop_free_list(cb.cb_proplist); 3677 3678 return (ret); 3679 } 3680 3681 typedef struct set_cbdata { 3682 char *cb_propname; 3683 char *cb_value; 3684 boolean_t cb_any_successful; 3685 } set_cbdata_t; 3686 3687 int 3688 set_callback(zpool_handle_t *zhp, void *data) 3689 { 3690 int error; 3691 set_cbdata_t *cb = (set_cbdata_t *)data; 3692 3693 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3694 3695 if (!error) 3696 cb->cb_any_successful = B_TRUE; 3697 3698 return (error); 3699 } 3700 3701 int 3702 zpool_do_set(int argc, char **argv) 3703 { 3704 set_cbdata_t cb = { 0 }; 3705 int error; 3706 3707 if (argc > 1 && argv[1][0] == '-') { 3708 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3709 argv[1][1]); 3710 usage(B_FALSE); 3711 } 3712 3713 if (argc < 2) { 3714 (void) fprintf(stderr, gettext("missing property=value " 3715 "argument\n")); 3716 usage(B_FALSE); 3717 } 3718 3719 if (argc < 3) { 3720 (void) fprintf(stderr, gettext("missing pool name\n")); 3721 usage(B_FALSE); 3722 } 3723 3724 if (argc > 3) { 3725 (void) fprintf(stderr, gettext("too many pool names\n")); 3726 usage(B_FALSE); 3727 } 3728 3729 cb.cb_propname = argv[1]; 3730 cb.cb_value = strchr(cb.cb_propname, '='); 3731 if (cb.cb_value == NULL) { 3732 (void) fprintf(stderr, gettext("missing value in " 3733 "property=value argument\n")); 3734 usage(B_FALSE); 3735 } 3736 3737 *(cb.cb_value) = '\0'; 3738 cb.cb_value++; 3739 3740 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3741 set_callback, &cb); 3742 3743 return (error); 3744 } 3745 3746 static int 3747 find_command_idx(char *command, int *idx) 3748 { 3749 int i; 3750 3751 for (i = 0; i < NCOMMAND; i++) { 3752 if (command_table[i].name == NULL) 3753 continue; 3754 3755 if (strcmp(command, command_table[i].name) == 0) { 3756 *idx = i; 3757 return (0); 3758 } 3759 } 3760 return (1); 3761 } 3762 3763 int 3764 main(int argc, char **argv) 3765 { 3766 int ret; 3767 int i; 3768 char *cmdname; 3769 3770 (void) setlocale(LC_ALL, ""); 3771 (void) textdomain(TEXT_DOMAIN); 3772 3773 if ((g_zfs = libzfs_init()) == NULL) { 3774 (void) fprintf(stderr, gettext("internal error: failed to " 3775 "initialize ZFS library\n")); 3776 return (1); 3777 } 3778 3779 libzfs_print_on_error(g_zfs, B_TRUE); 3780 3781 opterr = 0; 3782 3783 /* 3784 * Make sure the user has specified some command. 3785 */ 3786 if (argc < 2) { 3787 (void) fprintf(stderr, gettext("missing command\n")); 3788 usage(B_FALSE); 3789 } 3790 3791 cmdname = argv[1]; 3792 3793 /* 3794 * Special case '-?' 3795 */ 3796 if (strcmp(cmdname, "-?") == 0) 3797 usage(B_TRUE); 3798 3799 zpool_set_history_str("zpool", argc, argv, history_str); 3800 verify(zpool_stage_history(g_zfs, history_str) == 0); 3801 3802 /* 3803 * Run the appropriate command. 3804 */ 3805 if (find_command_idx(cmdname, &i) == 0) { 3806 current_command = &command_table[i]; 3807 ret = command_table[i].func(argc - 1, argv + 1); 3808 } else if (strchr(cmdname, '=')) { 3809 verify(find_command_idx("set", &i) == 0); 3810 current_command = &command_table[i]; 3811 ret = command_table[i].func(argc, argv); 3812 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3813 /* 3814 * 'freeze' is a vile debugging abomination, so we treat 3815 * it as such. 3816 */ 3817 char buf[16384]; 3818 int fd = open(ZFS_DEV, O_RDWR); 3819 (void) strcpy((void *)buf, argv[2]); 3820 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3821 } else { 3822 (void) fprintf(stderr, gettext("unrecognized " 3823 "command '%s'\n"), cmdname); 3824 usage(B_FALSE); 3825 } 3826 3827 libzfs_fini(g_zfs); 3828 3829 /* 3830 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3831 * for the purposes of running ::findleaks. 3832 */ 3833 if (getenv("ZFS_ABORT") != NULL) { 3834 (void) printf("dumping core by request\n"); 3835 abort(); 3836 } 3837 3838 return (ret); 3839 } 3840