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