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 print_logs(zhp, nvroot, namewidth); 3229 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 3230 &l2cache, &nl2cache) == 0) 3231 print_l2cache(zhp, l2cache, nl2cache, namewidth); 3232 3233 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3234 &spares, &nspares) == 0) 3235 print_spares(zhp, spares, nspares, namewidth); 3236 3237 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3238 &nerr) == 0) { 3239 nvlist_t *nverrlist = NULL; 3240 3241 /* 3242 * If the approximate error count is small, get a 3243 * precise count by fetching the entire log and 3244 * uniquifying the results. 3245 */ 3246 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 3247 zpool_get_errlog(zhp, &nverrlist) == 0) { 3248 nvpair_t *elem; 3249 3250 elem = NULL; 3251 nerr = 0; 3252 while ((elem = nvlist_next_nvpair(nverrlist, 3253 elem)) != NULL) { 3254 nerr++; 3255 } 3256 } 3257 nvlist_free(nverrlist); 3258 3259 (void) printf("\n"); 3260 3261 if (nerr == 0) 3262 (void) printf(gettext("errors: No known data " 3263 "errors\n")); 3264 else if (!cbp->cb_verbose) 3265 (void) printf(gettext("errors: %llu data " 3266 "errors, use '-v' for a list\n"), 3267 (u_longlong_t)nerr); 3268 else 3269 print_error_log(zhp); 3270 } 3271 } else { 3272 (void) printf(gettext("config: The configuration cannot be " 3273 "determined.\n")); 3274 } 3275 3276 return (0); 3277 } 3278 3279 /* 3280 * zpool status [-vx] [pool] ... 3281 * 3282 * -v Display complete error logs 3283 * -x Display only pools with potential problems 3284 * 3285 * Describes the health status of all pools or some subset. 3286 */ 3287 int 3288 zpool_do_status(int argc, char **argv) 3289 { 3290 int c; 3291 int ret; 3292 status_cbdata_t cb = { 0 }; 3293 3294 /* check options */ 3295 while ((c = getopt(argc, argv, "vx")) != -1) { 3296 switch (c) { 3297 case 'v': 3298 cb.cb_verbose = B_TRUE; 3299 break; 3300 case 'x': 3301 cb.cb_explain = B_TRUE; 3302 break; 3303 case '?': 3304 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3305 optopt); 3306 usage(B_FALSE); 3307 } 3308 } 3309 3310 argc -= optind; 3311 argv += optind; 3312 3313 cb.cb_first = B_TRUE; 3314 3315 if (argc == 0) 3316 cb.cb_allpools = B_TRUE; 3317 3318 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3319 3320 if (argc == 0 && cb.cb_count == 0) 3321 (void) printf(gettext("no pools available\n")); 3322 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3323 (void) printf(gettext("all pools are healthy\n")); 3324 3325 return (ret); 3326 } 3327 3328 typedef struct upgrade_cbdata { 3329 int cb_all; 3330 int cb_first; 3331 int cb_newer; 3332 int cb_argc; 3333 uint64_t cb_version; 3334 char **cb_argv; 3335 } upgrade_cbdata_t; 3336 3337 static int 3338 upgrade_cb(zpool_handle_t *zhp, void *arg) 3339 { 3340 upgrade_cbdata_t *cbp = arg; 3341 nvlist_t *config; 3342 uint64_t version; 3343 int ret = 0; 3344 3345 config = zpool_get_config(zhp, NULL); 3346 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3347 &version) == 0); 3348 3349 if (!cbp->cb_newer && version < SPA_VERSION) { 3350 if (!cbp->cb_all) { 3351 if (cbp->cb_first) { 3352 (void) printf(gettext("The following pools are " 3353 "out of date, and can be upgraded. After " 3354 "being\nupgraded, these pools will no " 3355 "longer be accessible by older software " 3356 "versions.\n\n")); 3357 (void) printf(gettext("VER POOL\n")); 3358 (void) printf(gettext("--- ------------\n")); 3359 cbp->cb_first = B_FALSE; 3360 } 3361 3362 (void) printf("%2llu %s\n", (u_longlong_t)version, 3363 zpool_get_name(zhp)); 3364 } else { 3365 cbp->cb_first = B_FALSE; 3366 ret = zpool_upgrade(zhp, cbp->cb_version); 3367 if (!ret) { 3368 (void) printf(gettext("Successfully upgraded " 3369 "'%s'\n\n"), zpool_get_name(zhp)); 3370 } 3371 } 3372 } else if (cbp->cb_newer && version > SPA_VERSION) { 3373 assert(!cbp->cb_all); 3374 3375 if (cbp->cb_first) { 3376 (void) printf(gettext("The following pools are " 3377 "formatted using a newer software version and\n" 3378 "cannot be accessed on the current system.\n\n")); 3379 (void) printf(gettext("VER POOL\n")); 3380 (void) printf(gettext("--- ------------\n")); 3381 cbp->cb_first = B_FALSE; 3382 } 3383 3384 (void) printf("%2llu %s\n", (u_longlong_t)version, 3385 zpool_get_name(zhp)); 3386 } 3387 3388 zpool_close(zhp); 3389 return (ret); 3390 } 3391 3392 /* ARGSUSED */ 3393 static int 3394 upgrade_one(zpool_handle_t *zhp, void *data) 3395 { 3396 upgrade_cbdata_t *cbp = data; 3397 uint64_t cur_version; 3398 int ret; 3399 3400 if (strcmp("log", zpool_get_name(zhp)) == 0) { 3401 (void) printf(gettext("'log' is now a reserved word\n" 3402 "Pool 'log' must be renamed using export and import" 3403 " to upgrade.\n")); 3404 return (1); 3405 } 3406 3407 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 3408 if (cur_version > cbp->cb_version) { 3409 (void) printf(gettext("Pool '%s' is already formatted " 3410 "using more current version '%llu'.\n"), 3411 zpool_get_name(zhp), cur_version); 3412 return (0); 3413 } 3414 if (cur_version == cbp->cb_version) { 3415 (void) printf(gettext("Pool '%s' is already formatted " 3416 "using the current version.\n"), zpool_get_name(zhp)); 3417 return (0); 3418 } 3419 3420 ret = zpool_upgrade(zhp, cbp->cb_version); 3421 3422 if (!ret) { 3423 (void) printf(gettext("Successfully upgraded '%s' " 3424 "from version %llu to version %llu\n\n"), 3425 zpool_get_name(zhp), (u_longlong_t)cur_version, 3426 (u_longlong_t)cbp->cb_version); 3427 } 3428 3429 return (ret != 0); 3430 } 3431 3432 /* 3433 * zpool upgrade 3434 * zpool upgrade -v 3435 * zpool upgrade [-V version] <-a | pool ...> 3436 * 3437 * With no arguments, display downrev'd ZFS pool available for upgrade. 3438 * Individual pools can be upgraded by specifying the pool, and '-a' will 3439 * upgrade all pools. 3440 */ 3441 int 3442 zpool_do_upgrade(int argc, char **argv) 3443 { 3444 int c; 3445 upgrade_cbdata_t cb = { 0 }; 3446 int ret = 0; 3447 boolean_t showversions = B_FALSE; 3448 char *end; 3449 3450 3451 /* check options */ 3452 while ((c = getopt(argc, argv, "avV:")) != -1) { 3453 switch (c) { 3454 case 'a': 3455 cb.cb_all = B_TRUE; 3456 break; 3457 case 'v': 3458 showversions = B_TRUE; 3459 break; 3460 case 'V': 3461 cb.cb_version = strtoll(optarg, &end, 10); 3462 if (*end != '\0' || cb.cb_version > SPA_VERSION || 3463 cb.cb_version < SPA_VERSION_1) { 3464 (void) fprintf(stderr, 3465 gettext("invalid version '%s'\n"), optarg); 3466 usage(B_FALSE); 3467 } 3468 break; 3469 case '?': 3470 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3471 optopt); 3472 usage(B_FALSE); 3473 } 3474 } 3475 3476 cb.cb_argc = argc; 3477 cb.cb_argv = argv; 3478 argc -= optind; 3479 argv += optind; 3480 3481 if (cb.cb_version == 0) { 3482 cb.cb_version = SPA_VERSION; 3483 } else if (!cb.cb_all && argc == 0) { 3484 (void) fprintf(stderr, gettext("-V option is " 3485 "incompatible with other arguments\n")); 3486 usage(B_FALSE); 3487 } 3488 3489 if (showversions) { 3490 if (cb.cb_all || argc != 0) { 3491 (void) fprintf(stderr, gettext("-v option is " 3492 "incompatible with other arguments\n")); 3493 usage(B_FALSE); 3494 } 3495 } else if (cb.cb_all) { 3496 if (argc != 0) { 3497 (void) fprintf(stderr, gettext("-a option should not " 3498 "be used along with a pool name\n")); 3499 usage(B_FALSE); 3500 } 3501 } 3502 3503 (void) printf(gettext("This system is currently running " 3504 "ZFS pool version %llu.\n\n"), SPA_VERSION); 3505 cb.cb_first = B_TRUE; 3506 if (showversions) { 3507 (void) printf(gettext("The following versions are " 3508 "supported:\n\n")); 3509 (void) printf(gettext("VER DESCRIPTION\n")); 3510 (void) printf("--- -----------------------------------------" 3511 "---------------\n"); 3512 (void) printf(gettext(" 1 Initial ZFS version\n")); 3513 (void) printf(gettext(" 2 Ditto blocks " 3514 "(replicated metadata)\n")); 3515 (void) printf(gettext(" 3 Hot spares and double parity " 3516 "RAID-Z\n")); 3517 (void) printf(gettext(" 4 zpool history\n")); 3518 (void) printf(gettext(" 5 Compression using the gzip " 3519 "algorithm\n")); 3520 (void) printf(gettext(" 6 bootfs pool property\n")); 3521 (void) printf(gettext(" 7 Separate intent log devices\n")); 3522 (void) printf(gettext(" 8 Delegated administration\n")); 3523 (void) printf(gettext(" 9 refquota and refreservation " 3524 "properties\n")); 3525 (void) printf(gettext(" 10 Cache devices\n")); 3526 (void) printf(gettext(" 11 Improved scrub performance\n")); 3527 (void) printf(gettext(" 12 Snapshot properties\n")); 3528 (void) printf(gettext(" 13 snapused property\n")); 3529 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 3530 (void) printf(gettext(" 15 user/group space accounting\n")); 3531 (void) printf(gettext("For more information on a particular " 3532 "version, including supported releases, see:\n\n")); 3533 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3534 "version/N\n\n"); 3535 (void) printf(gettext("Where 'N' is the version number.\n")); 3536 } else if (argc == 0) { 3537 int notfound; 3538 3539 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3540 notfound = cb.cb_first; 3541 3542 if (!cb.cb_all && ret == 0) { 3543 if (!cb.cb_first) 3544 (void) printf("\n"); 3545 cb.cb_first = B_TRUE; 3546 cb.cb_newer = B_TRUE; 3547 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3548 if (!cb.cb_first) { 3549 notfound = B_FALSE; 3550 (void) printf("\n"); 3551 } 3552 } 3553 3554 if (ret == 0) { 3555 if (notfound) 3556 (void) printf(gettext("All pools are formatted " 3557 "using this version.\n")); 3558 else if (!cb.cb_all) 3559 (void) printf(gettext("Use 'zpool upgrade -v' " 3560 "for a list of available versions and " 3561 "their associated\nfeatures.\n")); 3562 } 3563 } else { 3564 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3565 upgrade_one, &cb); 3566 } 3567 3568 return (ret); 3569 } 3570 3571 typedef struct hist_cbdata { 3572 boolean_t first; 3573 int longfmt; 3574 int internal; 3575 } hist_cbdata_t; 3576 3577 char *hist_event_table[LOG_END] = { 3578 "invalid event", 3579 "pool create", 3580 "vdev add", 3581 "pool remove", 3582 "pool destroy", 3583 "pool export", 3584 "pool import", 3585 "vdev attach", 3586 "vdev replace", 3587 "vdev detach", 3588 "vdev online", 3589 "vdev offline", 3590 "vdev upgrade", 3591 "pool clear", 3592 "pool scrub", 3593 "pool property set", 3594 "create", 3595 "clone", 3596 "destroy", 3597 "destroy_begin_sync", 3598 "inherit", 3599 "property set", 3600 "quota set", 3601 "permission update", 3602 "permission remove", 3603 "permission who remove", 3604 "promote", 3605 "receive", 3606 "rename", 3607 "reservation set", 3608 "replay_inc_sync", 3609 "replay_full_sync", 3610 "rollback", 3611 "snapshot", 3612 "filesystem version upgrade", 3613 "refquota set", 3614 "refreservation set", 3615 "pool scrub done", 3616 }; 3617 3618 /* 3619 * Print out the command history for a specific pool. 3620 */ 3621 static int 3622 get_history_one(zpool_handle_t *zhp, void *data) 3623 { 3624 nvlist_t *nvhis; 3625 nvlist_t **records; 3626 uint_t numrecords; 3627 char *cmdstr; 3628 char *pathstr; 3629 uint64_t dst_time; 3630 time_t tsec; 3631 struct tm t; 3632 char tbuf[30]; 3633 int ret, i; 3634 uint64_t who; 3635 struct passwd *pwd; 3636 char *hostname; 3637 char *zonename; 3638 char internalstr[MAXPATHLEN]; 3639 hist_cbdata_t *cb = (hist_cbdata_t *)data; 3640 uint64_t txg; 3641 uint64_t ievent; 3642 3643 cb->first = B_FALSE; 3644 3645 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3646 3647 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3648 return (ret); 3649 3650 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3651 &records, &numrecords) == 0); 3652 for (i = 0; i < numrecords; i++) { 3653 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3654 &dst_time) != 0) 3655 continue; 3656 3657 /* is it an internal event or a standard event? */ 3658 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3659 &cmdstr) != 0) { 3660 if (cb->internal == 0) 3661 continue; 3662 3663 if (nvlist_lookup_uint64(records[i], 3664 ZPOOL_HIST_INT_EVENT, &ievent) != 0) 3665 continue; 3666 verify(nvlist_lookup_uint64(records[i], 3667 ZPOOL_HIST_TXG, &txg) == 0); 3668 verify(nvlist_lookup_string(records[i], 3669 ZPOOL_HIST_INT_STR, &pathstr) == 0); 3670 if (ievent >= LOG_END) 3671 continue; 3672 (void) snprintf(internalstr, 3673 sizeof (internalstr), 3674 "[internal %s txg:%lld] %s", 3675 hist_event_table[ievent], txg, 3676 pathstr); 3677 cmdstr = internalstr; 3678 } 3679 tsec = dst_time; 3680 (void) localtime_r(&tsec, &t); 3681 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3682 (void) printf("%s %s", tbuf, cmdstr); 3683 3684 if (!cb->longfmt) { 3685 (void) printf("\n"); 3686 continue; 3687 } 3688 (void) printf(" ["); 3689 if (nvlist_lookup_uint64(records[i], 3690 ZPOOL_HIST_WHO, &who) == 0) { 3691 pwd = getpwuid((uid_t)who); 3692 if (pwd) 3693 (void) printf("user %s on", 3694 pwd->pw_name); 3695 else 3696 (void) printf("user %d on", 3697 (int)who); 3698 } else { 3699 (void) printf(gettext("no info]\n")); 3700 continue; 3701 } 3702 if (nvlist_lookup_string(records[i], 3703 ZPOOL_HIST_HOST, &hostname) == 0) { 3704 (void) printf(" %s", hostname); 3705 } 3706 if (nvlist_lookup_string(records[i], 3707 ZPOOL_HIST_ZONE, &zonename) == 0) { 3708 (void) printf(":%s", zonename); 3709 } 3710 3711 (void) printf("]"); 3712 (void) printf("\n"); 3713 } 3714 (void) printf("\n"); 3715 nvlist_free(nvhis); 3716 3717 return (ret); 3718 } 3719 3720 /* 3721 * zpool history <pool> 3722 * 3723 * Displays the history of commands that modified pools. 3724 */ 3725 3726 3727 int 3728 zpool_do_history(int argc, char **argv) 3729 { 3730 hist_cbdata_t cbdata = { 0 }; 3731 int ret; 3732 int c; 3733 3734 cbdata.first = B_TRUE; 3735 /* check options */ 3736 while ((c = getopt(argc, argv, "li")) != -1) { 3737 switch (c) { 3738 case 'l': 3739 cbdata.longfmt = 1; 3740 break; 3741 case 'i': 3742 cbdata.internal = 1; 3743 break; 3744 case '?': 3745 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3746 optopt); 3747 usage(B_FALSE); 3748 } 3749 } 3750 argc -= optind; 3751 argv += optind; 3752 3753 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3754 &cbdata); 3755 3756 if (argc == 0 && cbdata.first == B_TRUE) { 3757 (void) printf(gettext("no pools available\n")); 3758 return (0); 3759 } 3760 3761 return (ret); 3762 } 3763 3764 static int 3765 get_callback(zpool_handle_t *zhp, void *data) 3766 { 3767 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 3768 char value[MAXNAMELEN]; 3769 zprop_source_t srctype; 3770 zprop_list_t *pl; 3771 3772 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3773 3774 /* 3775 * Skip the special fake placeholder. This will also skip 3776 * over the name property when 'all' is specified. 3777 */ 3778 if (pl->pl_prop == ZPOOL_PROP_NAME && 3779 pl == cbp->cb_proplist) 3780 continue; 3781 3782 if (zpool_get_prop(zhp, pl->pl_prop, 3783 value, sizeof (value), &srctype) != 0) 3784 continue; 3785 3786 zprop_print_one_property(zpool_get_name(zhp), cbp, 3787 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3788 } 3789 return (0); 3790 } 3791 3792 int 3793 zpool_do_get(int argc, char **argv) 3794 { 3795 zprop_get_cbdata_t cb = { 0 }; 3796 zprop_list_t fake_name = { 0 }; 3797 int ret; 3798 3799 if (argc < 3) 3800 usage(B_FALSE); 3801 3802 cb.cb_first = B_TRUE; 3803 cb.cb_sources = ZPROP_SRC_ALL; 3804 cb.cb_columns[0] = GET_COL_NAME; 3805 cb.cb_columns[1] = GET_COL_PROPERTY; 3806 cb.cb_columns[2] = GET_COL_VALUE; 3807 cb.cb_columns[3] = GET_COL_SOURCE; 3808 cb.cb_type = ZFS_TYPE_POOL; 3809 3810 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 3811 ZFS_TYPE_POOL) != 0) 3812 usage(B_FALSE); 3813 3814 if (cb.cb_proplist != NULL) { 3815 fake_name.pl_prop = ZPOOL_PROP_NAME; 3816 fake_name.pl_width = strlen(gettext("NAME")); 3817 fake_name.pl_next = cb.cb_proplist; 3818 cb.cb_proplist = &fake_name; 3819 } 3820 3821 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3822 get_callback, &cb); 3823 3824 if (cb.cb_proplist == &fake_name) 3825 zprop_free_list(fake_name.pl_next); 3826 else 3827 zprop_free_list(cb.cb_proplist); 3828 3829 return (ret); 3830 } 3831 3832 typedef struct set_cbdata { 3833 char *cb_propname; 3834 char *cb_value; 3835 boolean_t cb_any_successful; 3836 } set_cbdata_t; 3837 3838 int 3839 set_callback(zpool_handle_t *zhp, void *data) 3840 { 3841 int error; 3842 set_cbdata_t *cb = (set_cbdata_t *)data; 3843 3844 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3845 3846 if (!error) 3847 cb->cb_any_successful = B_TRUE; 3848 3849 return (error); 3850 } 3851 3852 int 3853 zpool_do_set(int argc, char **argv) 3854 { 3855 set_cbdata_t cb = { 0 }; 3856 int error; 3857 3858 if (argc > 1 && argv[1][0] == '-') { 3859 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3860 argv[1][1]); 3861 usage(B_FALSE); 3862 } 3863 3864 if (argc < 2) { 3865 (void) fprintf(stderr, gettext("missing property=value " 3866 "argument\n")); 3867 usage(B_FALSE); 3868 } 3869 3870 if (argc < 3) { 3871 (void) fprintf(stderr, gettext("missing pool name\n")); 3872 usage(B_FALSE); 3873 } 3874 3875 if (argc > 3) { 3876 (void) fprintf(stderr, gettext("too many pool names\n")); 3877 usage(B_FALSE); 3878 } 3879 3880 cb.cb_propname = argv[1]; 3881 cb.cb_value = strchr(cb.cb_propname, '='); 3882 if (cb.cb_value == NULL) { 3883 (void) fprintf(stderr, gettext("missing value in " 3884 "property=value argument\n")); 3885 usage(B_FALSE); 3886 } 3887 3888 *(cb.cb_value) = '\0'; 3889 cb.cb_value++; 3890 3891 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3892 set_callback, &cb); 3893 3894 return (error); 3895 } 3896 3897 static int 3898 find_command_idx(char *command, int *idx) 3899 { 3900 int i; 3901 3902 for (i = 0; i < NCOMMAND; i++) { 3903 if (command_table[i].name == NULL) 3904 continue; 3905 3906 if (strcmp(command, command_table[i].name) == 0) { 3907 *idx = i; 3908 return (0); 3909 } 3910 } 3911 return (1); 3912 } 3913 3914 int 3915 main(int argc, char **argv) 3916 { 3917 int ret; 3918 int i; 3919 char *cmdname; 3920 3921 (void) setlocale(LC_ALL, ""); 3922 (void) textdomain(TEXT_DOMAIN); 3923 3924 if ((g_zfs = libzfs_init()) == NULL) { 3925 (void) fprintf(stderr, gettext("internal error: failed to " 3926 "initialize ZFS library\n")); 3927 return (1); 3928 } 3929 3930 libzfs_print_on_error(g_zfs, B_TRUE); 3931 3932 opterr = 0; 3933 3934 /* 3935 * Make sure the user has specified some command. 3936 */ 3937 if (argc < 2) { 3938 (void) fprintf(stderr, gettext("missing command\n")); 3939 usage(B_FALSE); 3940 } 3941 3942 cmdname = argv[1]; 3943 3944 /* 3945 * Special case '-?' 3946 */ 3947 if (strcmp(cmdname, "-?") == 0) 3948 usage(B_TRUE); 3949 3950 zpool_set_history_str("zpool", argc, argv, history_str); 3951 verify(zpool_stage_history(g_zfs, history_str) == 0); 3952 3953 /* 3954 * Run the appropriate command. 3955 */ 3956 if (find_command_idx(cmdname, &i) == 0) { 3957 current_command = &command_table[i]; 3958 ret = command_table[i].func(argc - 1, argv + 1); 3959 } else if (strchr(cmdname, '=')) { 3960 verify(find_command_idx("set", &i) == 0); 3961 current_command = &command_table[i]; 3962 ret = command_table[i].func(argc, argv); 3963 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3964 /* 3965 * 'freeze' is a vile debugging abomination, so we treat 3966 * it as such. 3967 */ 3968 char buf[16384]; 3969 int fd = open(ZFS_DEV, O_RDWR); 3970 (void) strcpy((void *)buf, argv[2]); 3971 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3972 } else { 3973 (void) fprintf(stderr, gettext("unrecognized " 3974 "command '%s'\n"), cmdname); 3975 usage(B_FALSE); 3976 } 3977 3978 libzfs_fini(g_zfs); 3979 3980 /* 3981 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3982 * for the purposes of running ::findleaks. 3983 */ 3984 if (getenv("ZFS_ABORT") != NULL) { 3985 (void) printf("dumping core by request\n"); 3986 abort(); 3987 } 3988 3989 return (ret); 3990 } 3991