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