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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2012 by Delphix. All rights reserved. 26 * Copyright (c) 2012 by Frederik Wessels. All rights reserved. 27 */ 28 29 #include <assert.h> 30 #include <ctype.h> 31 #include <dirent.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <libgen.h> 35 #include <libintl.h> 36 #include <libuutil.h> 37 #include <locale.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <strings.h> 42 #include <unistd.h> 43 #include <priv.h> 44 #include <pwd.h> 45 #include <zone.h> 46 #include <zfs_prop.h> 47 #include <sys/fs/zfs.h> 48 #include <sys/stat.h> 49 50 #include <libzfs.h> 51 52 #include "zpool_util.h" 53 #include "zfs_comutil.h" 54 #include "zfeature_common.h" 55 56 #include "statcommon.h" 57 58 static int zpool_do_create(int, char **); 59 static int zpool_do_destroy(int, char **); 60 61 static int zpool_do_add(int, char **); 62 static int zpool_do_remove(int, char **); 63 64 static int zpool_do_list(int, char **); 65 static int zpool_do_iostat(int, char **); 66 static int zpool_do_status(int, char **); 67 68 static int zpool_do_online(int, char **); 69 static int zpool_do_offline(int, char **); 70 static int zpool_do_clear(int, char **); 71 static int zpool_do_reopen(int, char **); 72 73 static int zpool_do_reguid(int, char **); 74 75 static int zpool_do_attach(int, char **); 76 static int zpool_do_detach(int, char **); 77 static int zpool_do_replace(int, char **); 78 static int zpool_do_split(int, char **); 79 80 static int zpool_do_scrub(int, char **); 81 82 static int zpool_do_import(int, char **); 83 static int zpool_do_export(int, char **); 84 85 static int zpool_do_upgrade(int, char **); 86 87 static int zpool_do_history(int, char **); 88 89 static int zpool_do_get(int, char **); 90 static int zpool_do_set(int, char **); 91 92 /* 93 * These libumem hooks provide a reasonable set of defaults for the allocator's 94 * debugging facilities. 95 */ 96 97 #ifdef DEBUG 98 const char * 99 _umem_debug_init(void) 100 { 101 return ("default,verbose"); /* $UMEM_DEBUG setting */ 102 } 103 104 const char * 105 _umem_logging_init(void) 106 { 107 return ("fail,contents"); /* $UMEM_LOGGING setting */ 108 } 109 #endif 110 111 typedef enum { 112 HELP_ADD, 113 HELP_ATTACH, 114 HELP_CLEAR, 115 HELP_CREATE, 116 HELP_DESTROY, 117 HELP_DETACH, 118 HELP_EXPORT, 119 HELP_HISTORY, 120 HELP_IMPORT, 121 HELP_IOSTAT, 122 HELP_LIST, 123 HELP_OFFLINE, 124 HELP_ONLINE, 125 HELP_REPLACE, 126 HELP_REMOVE, 127 HELP_SCRUB, 128 HELP_STATUS, 129 HELP_UPGRADE, 130 HELP_GET, 131 HELP_SET, 132 HELP_SPLIT, 133 HELP_REGUID, 134 HELP_REOPEN 135 } zpool_help_t; 136 137 138 typedef struct zpool_command { 139 const char *name; 140 int (*func)(int, char **); 141 zpool_help_t usage; 142 } zpool_command_t; 143 144 /* 145 * Master command table. Each ZFS command has a name, associated function, and 146 * usage message. The usage messages need to be internationalized, so we have 147 * to have a function to return the usage message based on a command index. 148 * 149 * These commands are organized according to how they are displayed in the usage 150 * message. An empty command (one with a NULL name) indicates an empty line in 151 * the generic usage message. 152 */ 153 static zpool_command_t command_table[] = { 154 { "create", zpool_do_create, HELP_CREATE }, 155 { "destroy", zpool_do_destroy, HELP_DESTROY }, 156 { NULL }, 157 { "add", zpool_do_add, HELP_ADD }, 158 { "remove", zpool_do_remove, HELP_REMOVE }, 159 { NULL }, 160 { "list", zpool_do_list, HELP_LIST }, 161 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 162 { "status", zpool_do_status, HELP_STATUS }, 163 { NULL }, 164 { "online", zpool_do_online, HELP_ONLINE }, 165 { "offline", zpool_do_offline, HELP_OFFLINE }, 166 { "clear", zpool_do_clear, HELP_CLEAR }, 167 { "reopen", zpool_do_reopen, HELP_REOPEN }, 168 { NULL }, 169 { "attach", zpool_do_attach, HELP_ATTACH }, 170 { "detach", zpool_do_detach, HELP_DETACH }, 171 { "replace", zpool_do_replace, HELP_REPLACE }, 172 { "split", zpool_do_split, HELP_SPLIT }, 173 { NULL }, 174 { "scrub", zpool_do_scrub, HELP_SCRUB }, 175 { NULL }, 176 { "import", zpool_do_import, HELP_IMPORT }, 177 { "export", zpool_do_export, HELP_EXPORT }, 178 { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 179 { "reguid", zpool_do_reguid, HELP_REGUID }, 180 { NULL }, 181 { "history", zpool_do_history, HELP_HISTORY }, 182 { "get", zpool_do_get, HELP_GET }, 183 { "set", zpool_do_set, HELP_SET }, 184 }; 185 186 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) 187 188 static zpool_command_t *current_command; 189 static char history_str[HIS_MAX_RECORD_LEN]; 190 static boolean_t log_history = B_TRUE; 191 static uint_t timestamp_fmt = NODATE; 192 193 static const char * 194 get_usage(zpool_help_t idx) { 195 switch (idx) { 196 case HELP_ADD: 197 return (gettext("\tadd [-fn] <pool> <vdev> ...\n")); 198 case HELP_ATTACH: 199 return (gettext("\tattach [-f] <pool> <device> " 200 "<new-device>\n")); 201 case HELP_CLEAR: 202 return (gettext("\tclear [-nF] <pool> [device]\n")); 203 case HELP_CREATE: 204 return (gettext("\tcreate [-fnd] [-o property=value] ... \n" 205 "\t [-O file-system-property=value] ... \n" 206 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n")); 207 case HELP_DESTROY: 208 return (gettext("\tdestroy [-f] <pool>\n")); 209 case HELP_DETACH: 210 return (gettext("\tdetach <pool> <device>\n")); 211 case HELP_EXPORT: 212 return (gettext("\texport [-f] <pool> ...\n")); 213 case HELP_HISTORY: 214 return (gettext("\thistory [-il] [<pool>] ...\n")); 215 case HELP_IMPORT: 216 return (gettext("\timport [-d dir] [-D]\n" 217 "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n" 218 "\timport [-o mntopts] [-o property=value] ... \n" 219 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] " 220 "[-R root] [-F [-n]] -a\n" 221 "\timport [-o mntopts] [-o property=value] ... \n" 222 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] " 223 "[-R root] [-F [-n]]\n" 224 "\t <pool | id> [newpool]\n")); 225 case HELP_IOSTAT: 226 return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval " 227 "[count]]\n")); 228 case HELP_LIST: 229 return (gettext("\tlist [-H] [-o property[,...]] " 230 "[-T d|u] [pool] ... [interval [count]]\n")); 231 case HELP_OFFLINE: 232 return (gettext("\toffline [-t] <pool> <device> ...\n")); 233 case HELP_ONLINE: 234 return (gettext("\tonline <pool> <device> ...\n")); 235 case HELP_REPLACE: 236 return (gettext("\treplace [-f] <pool> <device> " 237 "[new-device]\n")); 238 case HELP_REMOVE: 239 return (gettext("\tremove <pool> <device> ...\n")); 240 case HELP_REOPEN: 241 return (gettext("\treopen <pool>\n")); 242 case HELP_SCRUB: 243 return (gettext("\tscrub [-s] <pool> ...\n")); 244 case HELP_STATUS: 245 return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval " 246 "[count]]\n")); 247 case HELP_UPGRADE: 248 return (gettext("\tupgrade\n" 249 "\tupgrade -v\n" 250 "\tupgrade [-V version] <-a | pool ...>\n")); 251 case HELP_GET: 252 return (gettext("\tget <\"all\" | property[,...]> " 253 "<pool> ...\n")); 254 case HELP_SET: 255 return (gettext("\tset <property=value> <pool> \n")); 256 case HELP_SPLIT: 257 return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n" 258 "\t [-o property=value] <pool> <newpool> " 259 "[<device> ...]\n")); 260 case HELP_REGUID: 261 return (gettext("\treguid <pool>\n")); 262 } 263 264 abort(); 265 /* NOTREACHED */ 266 } 267 268 269 /* 270 * Callback routine that will print out a pool property value. 271 */ 272 static int 273 print_prop_cb(int prop, void *cb) 274 { 275 FILE *fp = cb; 276 277 (void) fprintf(fp, "\t%-15s ", zpool_prop_to_name(prop)); 278 279 if (zpool_prop_readonly(prop)) 280 (void) fprintf(fp, " NO "); 281 else 282 (void) fprintf(fp, " YES "); 283 284 if (zpool_prop_values(prop) == NULL) 285 (void) fprintf(fp, "-\n"); 286 else 287 (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 288 289 return (ZPROP_CONT); 290 } 291 292 /* 293 * Display usage message. If we're inside a command, display only the usage for 294 * that command. Otherwise, iterate over the entire command table and display 295 * a complete usage message. 296 */ 297 void 298 usage(boolean_t requested) 299 { 300 FILE *fp = requested ? stdout : stderr; 301 302 if (current_command == NULL) { 303 int i; 304 305 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 306 (void) fprintf(fp, 307 gettext("where 'command' is one of the following:\n\n")); 308 309 for (i = 0; i < NCOMMAND; i++) { 310 if (command_table[i].name == NULL) 311 (void) fprintf(fp, "\n"); 312 else 313 (void) fprintf(fp, "%s", 314 get_usage(command_table[i].usage)); 315 } 316 } else { 317 (void) fprintf(fp, gettext("usage:\n")); 318 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 319 } 320 321 if (current_command != NULL && 322 ((strcmp(current_command->name, "set") == 0) || 323 (strcmp(current_command->name, "get") == 0) || 324 (strcmp(current_command->name, "list") == 0))) { 325 326 (void) fprintf(fp, 327 gettext("\nthe following properties are supported:\n")); 328 329 (void) fprintf(fp, "\n\t%-15s %s %s\n\n", 330 "PROPERTY", "EDIT", "VALUES"); 331 332 /* Iterate over all properties */ 333 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 334 ZFS_TYPE_POOL); 335 336 (void) fprintf(fp, "\t%-15s ", "feature@..."); 337 (void) fprintf(fp, "YES disabled | enabled | active\n"); 338 339 (void) fprintf(fp, gettext("\nThe feature@ properties must be " 340 "appended with a feature name.\nSee zpool-features(5).\n")); 341 } 342 343 /* 344 * See comments at end of main(). 345 */ 346 if (getenv("ZFS_ABORT") != NULL) { 347 (void) printf("dumping core by request\n"); 348 abort(); 349 } 350 351 exit(requested ? 0 : 2); 352 } 353 354 void 355 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 356 boolean_t print_logs) 357 { 358 nvlist_t **child; 359 uint_t c, children; 360 char *vname; 361 362 if (name != NULL) 363 (void) printf("\t%*s%s\n", indent, "", name); 364 365 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 366 &child, &children) != 0) 367 return; 368 369 for (c = 0; c < children; c++) { 370 uint64_t is_log = B_FALSE; 371 372 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 373 &is_log); 374 if ((is_log && !print_logs) || (!is_log && print_logs)) 375 continue; 376 377 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 378 print_vdev_tree(zhp, vname, child[c], indent + 2, 379 B_FALSE); 380 free(vname); 381 } 382 } 383 384 static boolean_t 385 prop_list_contains_feature(nvlist_t *proplist) 386 { 387 nvpair_t *nvp; 388 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp; 389 nvp = nvlist_next_nvpair(proplist, nvp)) { 390 if (zpool_prop_feature(nvpair_name(nvp))) 391 return (B_TRUE); 392 } 393 return (B_FALSE); 394 } 395 396 /* 397 * Add a property pair (name, string-value) into a property nvlist. 398 */ 399 static int 400 add_prop_list(const char *propname, char *propval, nvlist_t **props, 401 boolean_t poolprop) 402 { 403 zpool_prop_t prop = ZPROP_INVAL; 404 zfs_prop_t fprop; 405 nvlist_t *proplist; 406 const char *normnm; 407 char *strval; 408 409 if (*props == NULL && 410 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 411 (void) fprintf(stderr, 412 gettext("internal error: out of memory\n")); 413 return (1); 414 } 415 416 proplist = *props; 417 418 if (poolprop) { 419 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION); 420 421 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL && 422 !zpool_prop_feature(propname)) { 423 (void) fprintf(stderr, gettext("property '%s' is " 424 "not a valid pool property\n"), propname); 425 return (2); 426 } 427 428 /* 429 * feature@ properties and version should not be specified 430 * at the same time. 431 */ 432 if ((prop == ZPROP_INVAL && zpool_prop_feature(propname) && 433 nvlist_exists(proplist, vname)) || 434 (prop == ZPOOL_PROP_VERSION && 435 prop_list_contains_feature(proplist))) { 436 (void) fprintf(stderr, gettext("'feature@' and " 437 "'version' properties cannot be specified " 438 "together\n")); 439 return (2); 440 } 441 442 443 if (zpool_prop_feature(propname)) 444 normnm = propname; 445 else 446 normnm = zpool_prop_to_name(prop); 447 } else { 448 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) { 449 normnm = zfs_prop_to_name(fprop); 450 } else { 451 normnm = propname; 452 } 453 } 454 455 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 && 456 prop != ZPOOL_PROP_CACHEFILE) { 457 (void) fprintf(stderr, gettext("property '%s' " 458 "specified multiple times\n"), propname); 459 return (2); 460 } 461 462 if (nvlist_add_string(proplist, normnm, propval) != 0) { 463 (void) fprintf(stderr, gettext("internal " 464 "error: out of memory\n")); 465 return (1); 466 } 467 468 return (0); 469 } 470 471 /* 472 * zpool add [-fn] <pool> <vdev> ... 473 * 474 * -f Force addition of devices, even if they appear in use 475 * -n Do not add the devices, but display the resulting layout if 476 * they were to be added. 477 * 478 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 479 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to 480 * libzfs. 481 */ 482 int 483 zpool_do_add(int argc, char **argv) 484 { 485 boolean_t force = B_FALSE; 486 boolean_t dryrun = B_FALSE; 487 int c; 488 nvlist_t *nvroot; 489 char *poolname; 490 int ret; 491 zpool_handle_t *zhp; 492 nvlist_t *config; 493 494 /* check options */ 495 while ((c = getopt(argc, argv, "fn")) != -1) { 496 switch (c) { 497 case 'f': 498 force = B_TRUE; 499 break; 500 case 'n': 501 dryrun = B_TRUE; 502 break; 503 case '?': 504 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 505 optopt); 506 usage(B_FALSE); 507 } 508 } 509 510 argc -= optind; 511 argv += optind; 512 513 /* get pool name and check number of arguments */ 514 if (argc < 1) { 515 (void) fprintf(stderr, gettext("missing pool name argument\n")); 516 usage(B_FALSE); 517 } 518 if (argc < 2) { 519 (void) fprintf(stderr, gettext("missing vdev specification\n")); 520 usage(B_FALSE); 521 } 522 523 poolname = argv[0]; 524 525 argc--; 526 argv++; 527 528 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 529 return (1); 530 531 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 532 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 533 poolname); 534 zpool_close(zhp); 535 return (1); 536 } 537 538 /* pass off to get_vdev_spec for processing */ 539 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun, 540 argc, argv); 541 if (nvroot == NULL) { 542 zpool_close(zhp); 543 return (1); 544 } 545 546 if (dryrun) { 547 nvlist_t *poolnvroot; 548 549 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 550 &poolnvroot) == 0); 551 552 (void) printf(gettext("would update '%s' to the following " 553 "configuration:\n"), zpool_get_name(zhp)); 554 555 /* print original main pool and new tree */ 556 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE); 557 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE); 558 559 /* Do the same for the logs */ 560 if (num_logs(poolnvroot) > 0) { 561 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE); 562 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE); 563 } else if (num_logs(nvroot) > 0) { 564 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE); 565 } 566 567 ret = 0; 568 } else { 569 ret = (zpool_add(zhp, nvroot) != 0); 570 } 571 572 nvlist_free(nvroot); 573 zpool_close(zhp); 574 575 return (ret); 576 } 577 578 /* 579 * zpool remove <pool> <vdev> ... 580 * 581 * Removes the given vdev from the pool. Currently, this supports removing 582 * spares, cache, and log devices from the pool. 583 */ 584 int 585 zpool_do_remove(int argc, char **argv) 586 { 587 char *poolname; 588 int i, ret = 0; 589 zpool_handle_t *zhp; 590 591 argc--; 592 argv++; 593 594 /* get pool name and check number of arguments */ 595 if (argc < 1) { 596 (void) fprintf(stderr, gettext("missing pool name argument\n")); 597 usage(B_FALSE); 598 } 599 if (argc < 2) { 600 (void) fprintf(stderr, gettext("missing device\n")); 601 usage(B_FALSE); 602 } 603 604 poolname = argv[0]; 605 606 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 607 return (1); 608 609 for (i = 1; i < argc; i++) { 610 if (zpool_vdev_remove(zhp, argv[i]) != 0) 611 ret = 1; 612 } 613 614 return (ret); 615 } 616 617 /* 618 * zpool create [-fnd] [-o property=value] ... 619 * [-O file-system-property=value] ... 620 * [-R root] [-m mountpoint] <pool> <dev> ... 621 * 622 * -f Force creation, even if devices appear in use 623 * -n Do not create the pool, but display the resulting layout if it 624 * were to be created. 625 * -R Create a pool under an alternate root 626 * -m Set default mountpoint for the root dataset. By default it's 627 * '/<pool>' 628 * -o Set property=value. 629 * -d Don't automatically enable all supported pool features 630 * (individual features can be enabled with -o). 631 * -O Set fsproperty=value in the pool's root file system 632 * 633 * Creates the named pool according to the given vdev specification. The 634 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once 635 * we get the nvlist back from get_vdev_spec(), we either print out the contents 636 * (if '-n' was specified), or pass it to libzfs to do the creation. 637 */ 638 int 639 zpool_do_create(int argc, char **argv) 640 { 641 boolean_t force = B_FALSE; 642 boolean_t dryrun = B_FALSE; 643 boolean_t enable_all_pool_feat = B_TRUE; 644 int c; 645 nvlist_t *nvroot = NULL; 646 char *poolname; 647 int ret = 1; 648 char *altroot = NULL; 649 char *mountpoint = NULL; 650 nvlist_t *fsprops = NULL; 651 nvlist_t *props = NULL; 652 char *propval; 653 654 /* check options */ 655 while ((c = getopt(argc, argv, ":fndR:m:o:O:")) != -1) { 656 switch (c) { 657 case 'f': 658 force = B_TRUE; 659 break; 660 case 'n': 661 dryrun = B_TRUE; 662 break; 663 case 'd': 664 enable_all_pool_feat = B_FALSE; 665 break; 666 case 'R': 667 altroot = optarg; 668 if (add_prop_list(zpool_prop_to_name( 669 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 670 goto errout; 671 if (nvlist_lookup_string(props, 672 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 673 &propval) == 0) 674 break; 675 if (add_prop_list(zpool_prop_to_name( 676 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 677 goto errout; 678 break; 679 case 'm': 680 /* Equivalent to -O mountpoint=optarg */ 681 mountpoint = optarg; 682 break; 683 case 'o': 684 if ((propval = strchr(optarg, '=')) == NULL) { 685 (void) fprintf(stderr, gettext("missing " 686 "'=' for -o option\n")); 687 goto errout; 688 } 689 *propval = '\0'; 690 propval++; 691 692 if (add_prop_list(optarg, propval, &props, B_TRUE)) 693 goto errout; 694 695 /* 696 * If the user is creating a pool that doesn't support 697 * feature flags, don't enable any features. 698 */ 699 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) { 700 char *end; 701 u_longlong_t ver; 702 703 ver = strtoull(propval, &end, 10); 704 if (*end == '\0' && 705 ver < SPA_VERSION_FEATURES) { 706 enable_all_pool_feat = B_FALSE; 707 } 708 } 709 break; 710 case 'O': 711 if ((propval = strchr(optarg, '=')) == NULL) { 712 (void) fprintf(stderr, gettext("missing " 713 "'=' for -O option\n")); 714 goto errout; 715 } 716 *propval = '\0'; 717 propval++; 718 719 /* 720 * Mountpoints are checked and then added later. 721 * Uniquely among properties, they can be specified 722 * more than once, to avoid conflict with -m. 723 */ 724 if (0 == strcmp(optarg, 725 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) { 726 mountpoint = propval; 727 } else if (add_prop_list(optarg, propval, &fsprops, 728 B_FALSE)) { 729 goto errout; 730 } 731 break; 732 case ':': 733 (void) fprintf(stderr, gettext("missing argument for " 734 "'%c' option\n"), optopt); 735 goto badusage; 736 case '?': 737 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 738 optopt); 739 goto badusage; 740 } 741 } 742 743 argc -= optind; 744 argv += optind; 745 746 /* get pool name and check number of arguments */ 747 if (argc < 1) { 748 (void) fprintf(stderr, gettext("missing pool name argument\n")); 749 goto badusage; 750 } 751 if (argc < 2) { 752 (void) fprintf(stderr, gettext("missing vdev specification\n")); 753 goto badusage; 754 } 755 756 poolname = argv[0]; 757 758 /* 759 * As a special case, check for use of '/' in the name, and direct the 760 * user to use 'zfs create' instead. 761 */ 762 if (strchr(poolname, '/') != NULL) { 763 (void) fprintf(stderr, gettext("cannot create '%s': invalid " 764 "character '/' in pool name\n"), poolname); 765 (void) fprintf(stderr, gettext("use 'zfs create' to " 766 "create a dataset\n")); 767 goto errout; 768 } 769 770 /* pass off to get_vdev_spec for bulk processing */ 771 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun, 772 argc - 1, argv + 1); 773 if (nvroot == NULL) 774 goto errout; 775 776 /* make_root_vdev() allows 0 toplevel children if there are spares */ 777 if (!zfs_allocatable_devs(nvroot)) { 778 (void) fprintf(stderr, gettext("invalid vdev " 779 "specification: at least one toplevel vdev must be " 780 "specified\n")); 781 goto errout; 782 } 783 784 if (altroot != NULL && altroot[0] != '/') { 785 (void) fprintf(stderr, gettext("invalid alternate root '%s': " 786 "must be an absolute path\n"), altroot); 787 goto errout; 788 } 789 790 /* 791 * Check the validity of the mountpoint and direct the user to use the 792 * '-m' mountpoint option if it looks like its in use. 793 */ 794 if (mountpoint == NULL || 795 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && 796 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { 797 char buf[MAXPATHLEN]; 798 DIR *dirp; 799 800 if (mountpoint && mountpoint[0] != '/') { 801 (void) fprintf(stderr, gettext("invalid mountpoint " 802 "'%s': must be an absolute path, 'legacy', or " 803 "'none'\n"), mountpoint); 804 goto errout; 805 } 806 807 if (mountpoint == NULL) { 808 if (altroot != NULL) 809 (void) snprintf(buf, sizeof (buf), "%s/%s", 810 altroot, poolname); 811 else 812 (void) snprintf(buf, sizeof (buf), "/%s", 813 poolname); 814 } else { 815 if (altroot != NULL) 816 (void) snprintf(buf, sizeof (buf), "%s%s", 817 altroot, mountpoint); 818 else 819 (void) snprintf(buf, sizeof (buf), "%s", 820 mountpoint); 821 } 822 823 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { 824 (void) fprintf(stderr, gettext("mountpoint '%s' : " 825 "%s\n"), buf, strerror(errno)); 826 (void) fprintf(stderr, gettext("use '-m' " 827 "option to provide a different default\n")); 828 goto errout; 829 } else if (dirp) { 830 int count = 0; 831 832 while (count < 3 && readdir(dirp) != NULL) 833 count++; 834 (void) closedir(dirp); 835 836 if (count > 2) { 837 (void) fprintf(stderr, gettext("mountpoint " 838 "'%s' exists and is not empty\n"), buf); 839 (void) fprintf(stderr, gettext("use '-m' " 840 "option to provide a " 841 "different default\n")); 842 goto errout; 843 } 844 } 845 } 846 847 /* 848 * Now that the mountpoint's validity has been checked, ensure that 849 * the property is set appropriately prior to creating the pool. 850 */ 851 if (mountpoint != NULL) { 852 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 853 mountpoint, &fsprops, B_FALSE); 854 if (ret != 0) 855 goto errout; 856 } 857 858 ret = 1; 859 if (dryrun) { 860 /* 861 * For a dry run invocation, print out a basic message and run 862 * through all the vdevs in the list and print out in an 863 * appropriate hierarchy. 864 */ 865 (void) printf(gettext("would create '%s' with the " 866 "following layout:\n\n"), poolname); 867 868 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE); 869 if (num_logs(nvroot) > 0) 870 print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE); 871 872 ret = 0; 873 } else { 874 /* 875 * Hand off to libzfs. 876 */ 877 if (enable_all_pool_feat) { 878 int i; 879 for (i = 0; i < SPA_FEATURES; i++) { 880 char propname[MAXPATHLEN]; 881 zfeature_info_t *feat = &spa_feature_table[i]; 882 883 (void) snprintf(propname, sizeof (propname), 884 "feature@%s", feat->fi_uname); 885 886 /* 887 * Skip feature if user specified it manually 888 * on the command line. 889 */ 890 if (nvlist_exists(props, propname)) 891 continue; 892 893 ret = add_prop_list(propname, 894 ZFS_FEATURE_ENABLED, &props, B_TRUE); 895 if (ret != 0) 896 goto errout; 897 } 898 } 899 900 ret = 1; 901 if (zpool_create(g_zfs, poolname, 902 nvroot, props, fsprops) == 0) { 903 zfs_handle_t *pool = zfs_open(g_zfs, poolname, 904 ZFS_TYPE_FILESYSTEM); 905 if (pool != NULL) { 906 if (zfs_mount(pool, NULL, 0) == 0) 907 ret = zfs_shareall(pool); 908 zfs_close(pool); 909 } 910 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { 911 (void) fprintf(stderr, gettext("pool name may have " 912 "been omitted\n")); 913 } 914 } 915 916 errout: 917 nvlist_free(nvroot); 918 nvlist_free(fsprops); 919 nvlist_free(props); 920 return (ret); 921 badusage: 922 nvlist_free(fsprops); 923 nvlist_free(props); 924 usage(B_FALSE); 925 return (2); 926 } 927 928 /* 929 * zpool destroy <pool> 930 * 931 * -f Forcefully unmount any datasets 932 * 933 * Destroy the given pool. Automatically unmounts any datasets in the pool. 934 */ 935 int 936 zpool_do_destroy(int argc, char **argv) 937 { 938 boolean_t force = B_FALSE; 939 int c; 940 char *pool; 941 zpool_handle_t *zhp; 942 int ret; 943 944 /* check options */ 945 while ((c = getopt(argc, argv, "f")) != -1) { 946 switch (c) { 947 case 'f': 948 force = B_TRUE; 949 break; 950 case '?': 951 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 952 optopt); 953 usage(B_FALSE); 954 } 955 } 956 957 argc -= optind; 958 argv += optind; 959 960 /* check arguments */ 961 if (argc < 1) { 962 (void) fprintf(stderr, gettext("missing pool argument\n")); 963 usage(B_FALSE); 964 } 965 if (argc > 1) { 966 (void) fprintf(stderr, gettext("too many arguments\n")); 967 usage(B_FALSE); 968 } 969 970 pool = argv[0]; 971 972 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 973 /* 974 * As a special case, check for use of '/' in the name, and 975 * direct the user to use 'zfs destroy' instead. 976 */ 977 if (strchr(pool, '/') != NULL) 978 (void) fprintf(stderr, gettext("use 'zfs destroy' to " 979 "destroy a dataset\n")); 980 return (1); 981 } 982 983 if (zpool_disable_datasets(zhp, force) != 0) { 984 (void) fprintf(stderr, gettext("could not destroy '%s': " 985 "could not unmount datasets\n"), zpool_get_name(zhp)); 986 return (1); 987 } 988 989 /* The history must be logged as part of the export */ 990 log_history = B_FALSE; 991 992 ret = (zpool_destroy(zhp, history_str) != 0); 993 994 zpool_close(zhp); 995 996 return (ret); 997 } 998 999 /* 1000 * zpool export [-f] <pool> ... 1001 * 1002 * -f Forcefully unmount datasets 1003 * 1004 * Export the given pools. By default, the command will attempt to cleanly 1005 * unmount any active datasets within the pool. If the '-f' flag is specified, 1006 * then the datasets will be forcefully unmounted. 1007 */ 1008 int 1009 zpool_do_export(int argc, char **argv) 1010 { 1011 boolean_t force = B_FALSE; 1012 boolean_t hardforce = B_FALSE; 1013 int c; 1014 zpool_handle_t *zhp; 1015 int ret; 1016 int i; 1017 1018 /* check options */ 1019 while ((c = getopt(argc, argv, "fF")) != -1) { 1020 switch (c) { 1021 case 'f': 1022 force = B_TRUE; 1023 break; 1024 case 'F': 1025 hardforce = B_TRUE; 1026 break; 1027 case '?': 1028 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1029 optopt); 1030 usage(B_FALSE); 1031 } 1032 } 1033 1034 argc -= optind; 1035 argv += optind; 1036 1037 /* check arguments */ 1038 if (argc < 1) { 1039 (void) fprintf(stderr, gettext("missing pool argument\n")); 1040 usage(B_FALSE); 1041 } 1042 1043 ret = 0; 1044 for (i = 0; i < argc; i++) { 1045 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) { 1046 ret = 1; 1047 continue; 1048 } 1049 1050 if (zpool_disable_datasets(zhp, force) != 0) { 1051 ret = 1; 1052 zpool_close(zhp); 1053 continue; 1054 } 1055 1056 /* The history must be logged as part of the export */ 1057 log_history = B_FALSE; 1058 1059 if (hardforce) { 1060 if (zpool_export_force(zhp, history_str) != 0) 1061 ret = 1; 1062 } else if (zpool_export(zhp, force, history_str) != 0) { 1063 ret = 1; 1064 } 1065 1066 zpool_close(zhp); 1067 } 1068 1069 return (ret); 1070 } 1071 1072 /* 1073 * Given a vdev configuration, determine the maximum width needed for the device 1074 * name column. 1075 */ 1076 static int 1077 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max) 1078 { 1079 char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE); 1080 nvlist_t **child; 1081 uint_t c, children; 1082 int ret; 1083 1084 if (strlen(name) + depth > max) 1085 max = strlen(name) + depth; 1086 1087 free(name); 1088 1089 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1090 &child, &children) == 0) { 1091 for (c = 0; c < children; c++) 1092 if ((ret = max_width(zhp, child[c], depth + 2, 1093 max)) > max) 1094 max = ret; 1095 } 1096 1097 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1098 &child, &children) == 0) { 1099 for (c = 0; c < children; c++) 1100 if ((ret = max_width(zhp, child[c], depth + 2, 1101 max)) > max) 1102 max = ret; 1103 } 1104 1105 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1106 &child, &children) == 0) { 1107 for (c = 0; c < children; c++) 1108 if ((ret = max_width(zhp, child[c], depth + 2, 1109 max)) > max) 1110 max = ret; 1111 } 1112 1113 1114 return (max); 1115 } 1116 1117 typedef struct spare_cbdata { 1118 uint64_t cb_guid; 1119 zpool_handle_t *cb_zhp; 1120 } spare_cbdata_t; 1121 1122 static boolean_t 1123 find_vdev(nvlist_t *nv, uint64_t search) 1124 { 1125 uint64_t guid; 1126 nvlist_t **child; 1127 uint_t c, children; 1128 1129 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 1130 search == guid) 1131 return (B_TRUE); 1132 1133 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1134 &child, &children) == 0) { 1135 for (c = 0; c < children; c++) 1136 if (find_vdev(child[c], search)) 1137 return (B_TRUE); 1138 } 1139 1140 return (B_FALSE); 1141 } 1142 1143 static int 1144 find_spare(zpool_handle_t *zhp, void *data) 1145 { 1146 spare_cbdata_t *cbp = data; 1147 nvlist_t *config, *nvroot; 1148 1149 config = zpool_get_config(zhp, NULL); 1150 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1151 &nvroot) == 0); 1152 1153 if (find_vdev(nvroot, cbp->cb_guid)) { 1154 cbp->cb_zhp = zhp; 1155 return (1); 1156 } 1157 1158 zpool_close(zhp); 1159 return (0); 1160 } 1161 1162 /* 1163 * Print out configuration state as requested by status_callback. 1164 */ 1165 void 1166 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 1167 int namewidth, int depth, boolean_t isspare) 1168 { 1169 nvlist_t **child; 1170 uint_t c, children; 1171 pool_scan_stat_t *ps = NULL; 1172 vdev_stat_t *vs; 1173 char rbuf[6], wbuf[6], cbuf[6]; 1174 char *vname; 1175 uint64_t notpresent; 1176 spare_cbdata_t cb; 1177 char *state; 1178 1179 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1180 &child, &children) != 0) 1181 children = 0; 1182 1183 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 1184 (uint64_t **)&vs, &c) == 0); 1185 1186 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1187 if (isspare) { 1188 /* 1189 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 1190 * online drives. 1191 */ 1192 if (vs->vs_aux == VDEV_AUX_SPARED) 1193 state = "INUSE"; 1194 else if (vs->vs_state == VDEV_STATE_HEALTHY) 1195 state = "AVAIL"; 1196 } 1197 1198 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 1199 name, state); 1200 1201 if (!isspare) { 1202 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 1203 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 1204 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 1205 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 1206 } 1207 1208 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1209 ¬present) == 0) { 1210 char *path; 1211 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 1212 (void) printf(" was %s", path); 1213 } else if (vs->vs_aux != 0) { 1214 (void) printf(" "); 1215 1216 switch (vs->vs_aux) { 1217 case VDEV_AUX_OPEN_FAILED: 1218 (void) printf(gettext("cannot open")); 1219 break; 1220 1221 case VDEV_AUX_BAD_GUID_SUM: 1222 (void) printf(gettext("missing device")); 1223 break; 1224 1225 case VDEV_AUX_NO_REPLICAS: 1226 (void) printf(gettext("insufficient replicas")); 1227 break; 1228 1229 case VDEV_AUX_VERSION_NEWER: 1230 (void) printf(gettext("newer version")); 1231 break; 1232 1233 case VDEV_AUX_UNSUP_FEAT: 1234 (void) printf(gettext("unsupported feature(s)")); 1235 break; 1236 1237 case VDEV_AUX_SPARED: 1238 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1239 &cb.cb_guid) == 0); 1240 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 1241 if (strcmp(zpool_get_name(cb.cb_zhp), 1242 zpool_get_name(zhp)) == 0) 1243 (void) printf(gettext("currently in " 1244 "use")); 1245 else 1246 (void) printf(gettext("in use by " 1247 "pool '%s'"), 1248 zpool_get_name(cb.cb_zhp)); 1249 zpool_close(cb.cb_zhp); 1250 } else { 1251 (void) printf(gettext("currently in use")); 1252 } 1253 break; 1254 1255 case VDEV_AUX_ERR_EXCEEDED: 1256 (void) printf(gettext("too many errors")); 1257 break; 1258 1259 case VDEV_AUX_IO_FAILURE: 1260 (void) printf(gettext("experienced I/O failures")); 1261 break; 1262 1263 case VDEV_AUX_BAD_LOG: 1264 (void) printf(gettext("bad intent log")); 1265 break; 1266 1267 case VDEV_AUX_EXTERNAL: 1268 (void) printf(gettext("external device fault")); 1269 break; 1270 1271 case VDEV_AUX_SPLIT_POOL: 1272 (void) printf(gettext("split into new pool")); 1273 break; 1274 1275 default: 1276 (void) printf(gettext("corrupted data")); 1277 break; 1278 } 1279 } 1280 1281 (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS, 1282 (uint64_t **)&ps, &c); 1283 1284 if (ps && ps->pss_state == DSS_SCANNING && 1285 vs->vs_scan_processed != 0 && children == 0) { 1286 (void) printf(gettext(" (%s)"), 1287 (ps->pss_func == POOL_SCAN_RESILVER) ? 1288 "resilvering" : "repairing"); 1289 } 1290 1291 (void) printf("\n"); 1292 1293 for (c = 0; c < children; c++) { 1294 uint64_t islog = B_FALSE, ishole = B_FALSE; 1295 1296 /* Don't print logs or holes here */ 1297 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1298 &islog); 1299 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE, 1300 &ishole); 1301 if (islog || ishole) 1302 continue; 1303 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE); 1304 print_status_config(zhp, vname, child[c], 1305 namewidth, depth + 2, isspare); 1306 free(vname); 1307 } 1308 } 1309 1310 1311 /* 1312 * Print the configuration of an exported pool. Iterate over all vdevs in the 1313 * pool, printing out the name and status for each one. 1314 */ 1315 void 1316 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth) 1317 { 1318 nvlist_t **child; 1319 uint_t c, children; 1320 vdev_stat_t *vs; 1321 char *type, *vname; 1322 1323 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 1324 if (strcmp(type, VDEV_TYPE_MISSING) == 0 || 1325 strcmp(type, VDEV_TYPE_HOLE) == 0) 1326 return; 1327 1328 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 1329 (uint64_t **)&vs, &c) == 0); 1330 1331 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name); 1332 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux)); 1333 1334 if (vs->vs_aux != 0) { 1335 (void) printf(" "); 1336 1337 switch (vs->vs_aux) { 1338 case VDEV_AUX_OPEN_FAILED: 1339 (void) printf(gettext("cannot open")); 1340 break; 1341 1342 case VDEV_AUX_BAD_GUID_SUM: 1343 (void) printf(gettext("missing device")); 1344 break; 1345 1346 case VDEV_AUX_NO_REPLICAS: 1347 (void) printf(gettext("insufficient replicas")); 1348 break; 1349 1350 case VDEV_AUX_VERSION_NEWER: 1351 (void) printf(gettext("newer version")); 1352 break; 1353 1354 case VDEV_AUX_UNSUP_FEAT: 1355 (void) printf(gettext("unsupported feature(s)")); 1356 break; 1357 1358 case VDEV_AUX_ERR_EXCEEDED: 1359 (void) printf(gettext("too many errors")); 1360 break; 1361 1362 default: 1363 (void) printf(gettext("corrupted data")); 1364 break; 1365 } 1366 } 1367 (void) printf("\n"); 1368 1369 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1370 &child, &children) != 0) 1371 return; 1372 1373 for (c = 0; c < children; c++) { 1374 uint64_t is_log = B_FALSE; 1375 1376 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1377 &is_log); 1378 if (is_log) 1379 continue; 1380 1381 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE); 1382 print_import_config(vname, child[c], namewidth, depth + 2); 1383 free(vname); 1384 } 1385 1386 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1387 &child, &children) == 0) { 1388 (void) printf(gettext("\tcache\n")); 1389 for (c = 0; c < children; c++) { 1390 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE); 1391 (void) printf("\t %s\n", vname); 1392 free(vname); 1393 } 1394 } 1395 1396 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1397 &child, &children) == 0) { 1398 (void) printf(gettext("\tspares\n")); 1399 for (c = 0; c < children; c++) { 1400 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE); 1401 (void) printf("\t %s\n", vname); 1402 free(vname); 1403 } 1404 } 1405 } 1406 1407 /* 1408 * Print log vdevs. 1409 * Logs are recorded as top level vdevs in the main pool child array 1410 * but with "is_log" set to 1. We use either print_status_config() or 1411 * print_import_config() to print the top level logs then any log 1412 * children (eg mirrored slogs) are printed recursively - which 1413 * works because only the top level vdev is marked "is_log" 1414 */ 1415 static void 1416 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose) 1417 { 1418 uint_t c, children; 1419 nvlist_t **child; 1420 1421 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child, 1422 &children) != 0) 1423 return; 1424 1425 (void) printf(gettext("\tlogs\n")); 1426 1427 for (c = 0; c < children; c++) { 1428 uint64_t is_log = B_FALSE; 1429 char *name; 1430 1431 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1432 &is_log); 1433 if (!is_log) 1434 continue; 1435 name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE); 1436 if (verbose) 1437 print_status_config(zhp, name, child[c], namewidth, 1438 2, B_FALSE); 1439 else 1440 print_import_config(name, child[c], namewidth, 2); 1441 free(name); 1442 } 1443 } 1444 1445 /* 1446 * Display the status for the given pool. 1447 */ 1448 static void 1449 show_import(nvlist_t *config) 1450 { 1451 uint64_t pool_state; 1452 vdev_stat_t *vs; 1453 char *name; 1454 uint64_t guid; 1455 char *msgid; 1456 nvlist_t *nvroot; 1457 int reason; 1458 const char *health; 1459 uint_t vsc; 1460 int namewidth; 1461 char *comment; 1462 1463 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1464 &name) == 0); 1465 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 1466 &guid) == 0); 1467 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1468 &pool_state) == 0); 1469 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1470 &nvroot) == 0); 1471 1472 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 1473 (uint64_t **)&vs, &vsc) == 0); 1474 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1475 1476 reason = zpool_import_status(config, &msgid); 1477 1478 (void) printf(gettext(" pool: %s\n"), name); 1479 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid); 1480 (void) printf(gettext(" state: %s"), health); 1481 if (pool_state == POOL_STATE_DESTROYED) 1482 (void) printf(gettext(" (DESTROYED)")); 1483 (void) printf("\n"); 1484 1485 switch (reason) { 1486 case ZPOOL_STATUS_MISSING_DEV_R: 1487 case ZPOOL_STATUS_MISSING_DEV_NR: 1488 case ZPOOL_STATUS_BAD_GUID_SUM: 1489 (void) printf(gettext(" status: One or more devices are " 1490 "missing from the system.\n")); 1491 break; 1492 1493 case ZPOOL_STATUS_CORRUPT_LABEL_R: 1494 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 1495 (void) printf(gettext(" status: One or more devices contains " 1496 "corrupted data.\n")); 1497 break; 1498 1499 case ZPOOL_STATUS_CORRUPT_DATA: 1500 (void) printf( 1501 gettext(" status: The pool data is corrupted.\n")); 1502 break; 1503 1504 case ZPOOL_STATUS_OFFLINE_DEV: 1505 (void) printf(gettext(" status: One or more devices " 1506 "are offlined.\n")); 1507 break; 1508 1509 case ZPOOL_STATUS_CORRUPT_POOL: 1510 (void) printf(gettext(" status: The pool metadata is " 1511 "corrupted.\n")); 1512 break; 1513 1514 case ZPOOL_STATUS_VERSION_OLDER: 1515 (void) printf(gettext(" status: The pool is formatted using a " 1516 "legacy on-disk version.\n")); 1517 break; 1518 1519 case ZPOOL_STATUS_VERSION_NEWER: 1520 (void) printf(gettext(" status: The pool is formatted using an " 1521 "incompatible version.\n")); 1522 break; 1523 1524 case ZPOOL_STATUS_FEAT_DISABLED: 1525 (void) printf(gettext(" status: Some supported features are " 1526 "not enabled on the pool.\n")); 1527 break; 1528 1529 case ZPOOL_STATUS_UNSUP_FEAT_READ: 1530 (void) printf(gettext("status: The pool uses the following " 1531 "feature(s) not supported on this sytem:\n")); 1532 zpool_print_unsup_feat(config); 1533 break; 1534 1535 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 1536 (void) printf(gettext("status: The pool can only be accessed " 1537 "in read-only mode on this system. It\n\tcannot be " 1538 "accessed in read-write mode because it uses the " 1539 "following\n\tfeature(s) not supported on this system:\n")); 1540 zpool_print_unsup_feat(config); 1541 break; 1542 1543 case ZPOOL_STATUS_HOSTID_MISMATCH: 1544 (void) printf(gettext(" status: The pool was last accessed by " 1545 "another system.\n")); 1546 break; 1547 1548 case ZPOOL_STATUS_FAULTED_DEV_R: 1549 case ZPOOL_STATUS_FAULTED_DEV_NR: 1550 (void) printf(gettext(" status: One or more devices are " 1551 "faulted.\n")); 1552 break; 1553 1554 case ZPOOL_STATUS_BAD_LOG: 1555 (void) printf(gettext(" status: An intent log record cannot be " 1556 "read.\n")); 1557 break; 1558 1559 case ZPOOL_STATUS_RESILVERING: 1560 (void) printf(gettext(" status: One or more devices were being " 1561 "resilvered.\n")); 1562 break; 1563 1564 default: 1565 /* 1566 * No other status can be seen when importing pools. 1567 */ 1568 assert(reason == ZPOOL_STATUS_OK); 1569 } 1570 1571 /* 1572 * Print out an action according to the overall state of the pool. 1573 */ 1574 if (vs->vs_state == VDEV_STATE_HEALTHY) { 1575 if (reason == ZPOOL_STATUS_VERSION_OLDER || 1576 reason == ZPOOL_STATUS_FEAT_DISABLED) { 1577 (void) printf(gettext(" action: The pool can be " 1578 "imported using its name or numeric identifier, " 1579 "though\n\tsome features will not be available " 1580 "without an explicit 'zpool upgrade'.\n")); 1581 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) { 1582 (void) printf(gettext(" action: The pool can be " 1583 "imported using its name or numeric " 1584 "identifier and\n\tthe '-f' flag.\n")); 1585 } else { 1586 (void) printf(gettext(" action: The pool can be " 1587 "imported using its name or numeric " 1588 "identifier.\n")); 1589 } 1590 } else if (vs->vs_state == VDEV_STATE_DEGRADED) { 1591 (void) printf(gettext(" action: The pool can be imported " 1592 "despite missing or damaged devices. The\n\tfault " 1593 "tolerance of the pool may be compromised if imported.\n")); 1594 } else { 1595 switch (reason) { 1596 case ZPOOL_STATUS_VERSION_NEWER: 1597 (void) printf(gettext(" action: The pool cannot be " 1598 "imported. Access the pool on a system running " 1599 "newer\n\tsoftware, or recreate the pool from " 1600 "backup.\n")); 1601 break; 1602 case ZPOOL_STATUS_UNSUP_FEAT_READ: 1603 (void) printf(gettext("action: The pool cannot be " 1604 "imported. Access the pool on a system that " 1605 "supports\n\tthe required feature(s), or recreate " 1606 "the pool from backup.\n")); 1607 break; 1608 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 1609 (void) printf(gettext("action: The pool cannot be " 1610 "imported in read-write mode. Import the pool " 1611 "with\n" 1612 "\t\"-o readonly=on\", access the pool on a system " 1613 "that supports the\n\trequired feature(s), or " 1614 "recreate the pool from backup.\n")); 1615 break; 1616 case ZPOOL_STATUS_MISSING_DEV_R: 1617 case ZPOOL_STATUS_MISSING_DEV_NR: 1618 case ZPOOL_STATUS_BAD_GUID_SUM: 1619 (void) printf(gettext(" action: The pool cannot be " 1620 "imported. Attach the missing\n\tdevices and try " 1621 "again.\n")); 1622 break; 1623 default: 1624 (void) printf(gettext(" action: The pool cannot be " 1625 "imported due to damaged devices or data.\n")); 1626 } 1627 } 1628 1629 /* Print the comment attached to the pool. */ 1630 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) 1631 (void) printf(gettext("comment: %s\n"), comment); 1632 1633 /* 1634 * If the state is "closed" or "can't open", and the aux state 1635 * is "corrupt data": 1636 */ 1637 if (((vs->vs_state == VDEV_STATE_CLOSED) || 1638 (vs->vs_state == VDEV_STATE_CANT_OPEN)) && 1639 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) { 1640 if (pool_state == POOL_STATE_DESTROYED) 1641 (void) printf(gettext("\tThe pool was destroyed, " 1642 "but can be imported using the '-Df' flags.\n")); 1643 else if (pool_state != POOL_STATE_EXPORTED) 1644 (void) printf(gettext("\tThe pool may be active on " 1645 "another system, but can be imported using\n\t" 1646 "the '-f' flag.\n")); 1647 } 1648 1649 if (msgid != NULL) 1650 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 1651 msgid); 1652 1653 (void) printf(gettext(" config:\n\n")); 1654 1655 namewidth = max_width(NULL, nvroot, 0, 0); 1656 if (namewidth < 10) 1657 namewidth = 10; 1658 1659 print_import_config(name, nvroot, namewidth, 0); 1660 if (num_logs(nvroot) > 0) 1661 print_logs(NULL, nvroot, namewidth, B_FALSE); 1662 1663 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) { 1664 (void) printf(gettext("\n\tAdditional devices are known to " 1665 "be part of this pool, though their\n\texact " 1666 "configuration cannot be determined.\n")); 1667 } 1668 } 1669 1670 /* 1671 * Perform the import for the given configuration. This passes the heavy 1672 * lifting off to zpool_import_props(), and then mounts the datasets contained 1673 * within the pool. 1674 */ 1675 static int 1676 do_import(nvlist_t *config, const char *newname, const char *mntopts, 1677 nvlist_t *props, int flags) 1678 { 1679 zpool_handle_t *zhp; 1680 char *name; 1681 uint64_t state; 1682 uint64_t version; 1683 1684 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1685 &name) == 0); 1686 1687 verify(nvlist_lookup_uint64(config, 1688 ZPOOL_CONFIG_POOL_STATE, &state) == 0); 1689 verify(nvlist_lookup_uint64(config, 1690 ZPOOL_CONFIG_VERSION, &version) == 0); 1691 if (!SPA_VERSION_IS_SUPPORTED(version)) { 1692 (void) fprintf(stderr, gettext("cannot import '%s': pool " 1693 "is formatted using an unsupported ZFS version\n"), name); 1694 return (1); 1695 } else if (state != POOL_STATE_EXPORTED && 1696 !(flags & ZFS_IMPORT_ANY_HOST)) { 1697 uint64_t hostid; 1698 1699 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, 1700 &hostid) == 0) { 1701 if ((unsigned long)hostid != gethostid()) { 1702 char *hostname; 1703 uint64_t timestamp; 1704 time_t t; 1705 1706 verify(nvlist_lookup_string(config, 1707 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); 1708 verify(nvlist_lookup_uint64(config, 1709 ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0); 1710 t = timestamp; 1711 (void) fprintf(stderr, gettext("cannot import " 1712 "'%s': pool may be in use from other " 1713 "system, it was last accessed by %s " 1714 "(hostid: 0x%lx) on %s"), name, hostname, 1715 (unsigned long)hostid, 1716 asctime(localtime(&t))); 1717 (void) fprintf(stderr, gettext("use '-f' to " 1718 "import anyway\n")); 1719 return (1); 1720 } 1721 } else { 1722 (void) fprintf(stderr, gettext("cannot import '%s': " 1723 "pool may be in use from other system\n"), name); 1724 (void) fprintf(stderr, gettext("use '-f' to import " 1725 "anyway\n")); 1726 return (1); 1727 } 1728 } 1729 1730 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0) 1731 return (1); 1732 1733 if (newname != NULL) 1734 name = (char *)newname; 1735 1736 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) 1737 return (1); 1738 1739 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 1740 !(flags & ZFS_IMPORT_ONLY) && 1741 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 1742 zpool_close(zhp); 1743 return (1); 1744 } 1745 1746 zpool_close(zhp); 1747 return (0); 1748 } 1749 1750 /* 1751 * zpool import [-d dir] [-D] 1752 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 1753 * [-d dir | -c cachefile] [-f] -a 1754 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 1755 * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool] 1756 * 1757 * -c Read pool information from a cachefile instead of searching 1758 * devices. 1759 * 1760 * -d Scan in a specific directory, other than /dev/dsk. More than 1761 * one directory can be specified using multiple '-d' options. 1762 * 1763 * -D Scan for previously destroyed pools or import all or only 1764 * specified destroyed pools. 1765 * 1766 * -R Temporarily import the pool, with all mountpoints relative to 1767 * the given root. The pool will remain exported when the machine 1768 * is rebooted. 1769 * 1770 * -V Import even in the presence of faulted vdevs. This is an 1771 * intentionally undocumented option for testing purposes, and 1772 * treats the pool configuration as complete, leaving any bad 1773 * vdevs in the FAULTED state. In other words, it does verbatim 1774 * import. 1775 * 1776 * -f Force import, even if it appears that the pool is active. 1777 * 1778 * -F Attempt rewind if necessary. 1779 * 1780 * -n See if rewind would work, but don't actually rewind. 1781 * 1782 * -N Import the pool but don't mount datasets. 1783 * 1784 * -T Specify a starting txg to use for import. This option is 1785 * intentionally undocumented option for testing purposes. 1786 * 1787 * -a Import all pools found. 1788 * 1789 * -o Set property=value and/or temporary mount options (without '='). 1790 * 1791 * The import command scans for pools to import, and import pools based on pool 1792 * name and GUID. The pool can also be renamed as part of the import process. 1793 */ 1794 int 1795 zpool_do_import(int argc, char **argv) 1796 { 1797 char **searchdirs = NULL; 1798 int nsearch = 0; 1799 int c; 1800 int err = 0; 1801 nvlist_t *pools = NULL; 1802 boolean_t do_all = B_FALSE; 1803 boolean_t do_destroyed = B_FALSE; 1804 char *mntopts = NULL; 1805 nvpair_t *elem; 1806 nvlist_t *config; 1807 uint64_t searchguid = 0; 1808 char *searchname = NULL; 1809 char *propval; 1810 nvlist_t *found_config; 1811 nvlist_t *policy = NULL; 1812 nvlist_t *props = NULL; 1813 boolean_t first; 1814 int flags = ZFS_IMPORT_NORMAL; 1815 uint32_t rewind_policy = ZPOOL_NO_REWIND; 1816 boolean_t dryrun = B_FALSE; 1817 boolean_t do_rewind = B_FALSE; 1818 boolean_t xtreme_rewind = B_FALSE; 1819 uint64_t pool_state, txg = -1ULL; 1820 char *cachefile = NULL; 1821 importargs_t idata = { 0 }; 1822 char *endptr; 1823 1824 /* check options */ 1825 while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) { 1826 switch (c) { 1827 case 'a': 1828 do_all = B_TRUE; 1829 break; 1830 case 'c': 1831 cachefile = optarg; 1832 break; 1833 case 'd': 1834 if (searchdirs == NULL) { 1835 searchdirs = safe_malloc(sizeof (char *)); 1836 } else { 1837 char **tmp = safe_malloc((nsearch + 1) * 1838 sizeof (char *)); 1839 bcopy(searchdirs, tmp, nsearch * 1840 sizeof (char *)); 1841 free(searchdirs); 1842 searchdirs = tmp; 1843 } 1844 searchdirs[nsearch++] = optarg; 1845 break; 1846 case 'D': 1847 do_destroyed = B_TRUE; 1848 break; 1849 case 'f': 1850 flags |= ZFS_IMPORT_ANY_HOST; 1851 break; 1852 case 'F': 1853 do_rewind = B_TRUE; 1854 break; 1855 case 'm': 1856 flags |= ZFS_IMPORT_MISSING_LOG; 1857 break; 1858 case 'n': 1859 dryrun = B_TRUE; 1860 break; 1861 case 'N': 1862 flags |= ZFS_IMPORT_ONLY; 1863 break; 1864 case 'o': 1865 if ((propval = strchr(optarg, '=')) != NULL) { 1866 *propval = '\0'; 1867 propval++; 1868 if (add_prop_list(optarg, propval, 1869 &props, B_TRUE)) 1870 goto error; 1871 } else { 1872 mntopts = optarg; 1873 } 1874 break; 1875 case 'R': 1876 if (add_prop_list(zpool_prop_to_name( 1877 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 1878 goto error; 1879 if (nvlist_lookup_string(props, 1880 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 1881 &propval) == 0) 1882 break; 1883 if (add_prop_list(zpool_prop_to_name( 1884 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1885 goto error; 1886 break; 1887 case 'T': 1888 errno = 0; 1889 txg = strtoull(optarg, &endptr, 10); 1890 if (errno != 0 || *endptr != '\0') { 1891 (void) fprintf(stderr, 1892 gettext("invalid txg value\n")); 1893 usage(B_FALSE); 1894 } 1895 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND; 1896 break; 1897 case 'V': 1898 flags |= ZFS_IMPORT_VERBATIM; 1899 break; 1900 case 'X': 1901 xtreme_rewind = B_TRUE; 1902 break; 1903 case ':': 1904 (void) fprintf(stderr, gettext("missing argument for " 1905 "'%c' option\n"), optopt); 1906 usage(B_FALSE); 1907 break; 1908 case '?': 1909 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1910 optopt); 1911 usage(B_FALSE); 1912 } 1913 } 1914 1915 argc -= optind; 1916 argv += optind; 1917 1918 if (cachefile && nsearch != 0) { 1919 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 1920 usage(B_FALSE); 1921 } 1922 1923 if ((dryrun || xtreme_rewind) && !do_rewind) { 1924 (void) fprintf(stderr, 1925 gettext("-n or -X only meaningful with -F\n")); 1926 usage(B_FALSE); 1927 } 1928 if (dryrun) 1929 rewind_policy = ZPOOL_TRY_REWIND; 1930 else if (do_rewind) 1931 rewind_policy = ZPOOL_DO_REWIND; 1932 if (xtreme_rewind) 1933 rewind_policy |= ZPOOL_EXTREME_REWIND; 1934 1935 /* In the future, we can capture further policy and include it here */ 1936 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 1937 nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 || 1938 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0) 1939 goto error; 1940 1941 if (searchdirs == NULL) { 1942 searchdirs = safe_malloc(sizeof (char *)); 1943 searchdirs[0] = "/dev/dsk"; 1944 nsearch = 1; 1945 } 1946 1947 /* check argument count */ 1948 if (do_all) { 1949 if (argc != 0) { 1950 (void) fprintf(stderr, gettext("too many arguments\n")); 1951 usage(B_FALSE); 1952 } 1953 } else { 1954 if (argc > 2) { 1955 (void) fprintf(stderr, gettext("too many arguments\n")); 1956 usage(B_FALSE); 1957 } 1958 1959 /* 1960 * Check for the SYS_CONFIG privilege. We do this explicitly 1961 * here because otherwise any attempt to discover pools will 1962 * silently fail. 1963 */ 1964 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 1965 (void) fprintf(stderr, gettext("cannot " 1966 "discover pools: permission denied\n")); 1967 free(searchdirs); 1968 nvlist_free(policy); 1969 return (1); 1970 } 1971 } 1972 1973 /* 1974 * Depending on the arguments given, we do one of the following: 1975 * 1976 * <none> Iterate through all pools and display information about 1977 * each one. 1978 * 1979 * -a Iterate through all pools and try to import each one. 1980 * 1981 * <id> Find the pool that corresponds to the given GUID/pool 1982 * name and import that one. 1983 * 1984 * -D Above options applies only to destroyed pools. 1985 */ 1986 if (argc != 0) { 1987 char *endptr; 1988 1989 errno = 0; 1990 searchguid = strtoull(argv[0], &endptr, 10); 1991 if (errno != 0 || *endptr != '\0') 1992 searchname = argv[0]; 1993 found_config = NULL; 1994 1995 /* 1996 * User specified a name or guid. Ensure it's unique. 1997 */ 1998 idata.unique = B_TRUE; 1999 } 2000 2001 2002 idata.path = searchdirs; 2003 idata.paths = nsearch; 2004 idata.poolname = searchname; 2005 idata.guid = searchguid; 2006 idata.cachefile = cachefile; 2007 2008 pools = zpool_search_import(g_zfs, &idata); 2009 2010 if (pools != NULL && idata.exists && 2011 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) { 2012 (void) fprintf(stderr, gettext("cannot import '%s': " 2013 "a pool with that name already exists\n"), 2014 argv[0]); 2015 (void) fprintf(stderr, gettext("use the form '%s " 2016 "<pool | id> <newpool>' to give it a new name\n"), 2017 "zpool import"); 2018 err = 1; 2019 } else if (pools == NULL && idata.exists) { 2020 (void) fprintf(stderr, gettext("cannot import '%s': " 2021 "a pool with that name is already created/imported,\n"), 2022 argv[0]); 2023 (void) fprintf(stderr, gettext("and no additional pools " 2024 "with that name were found\n")); 2025 err = 1; 2026 } else if (pools == NULL) { 2027 if (argc != 0) { 2028 (void) fprintf(stderr, gettext("cannot import '%s': " 2029 "no such pool available\n"), argv[0]); 2030 } 2031 err = 1; 2032 } 2033 2034 if (err == 1) { 2035 free(searchdirs); 2036 nvlist_free(policy); 2037 return (1); 2038 } 2039 2040 /* 2041 * At this point we have a list of import candidate configs. Even if 2042 * we were searching by pool name or guid, we still need to 2043 * post-process the list to deal with pool state and possible 2044 * duplicate names. 2045 */ 2046 err = 0; 2047 elem = NULL; 2048 first = B_TRUE; 2049 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 2050 2051 verify(nvpair_value_nvlist(elem, &config) == 0); 2052 2053 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 2054 &pool_state) == 0); 2055 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 2056 continue; 2057 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 2058 continue; 2059 2060 verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY, 2061 policy) == 0); 2062 2063 if (argc == 0) { 2064 if (first) 2065 first = B_FALSE; 2066 else if (!do_all) 2067 (void) printf("\n"); 2068 2069 if (do_all) { 2070 err |= do_import(config, NULL, mntopts, 2071 props, flags); 2072 } else { 2073 show_import(config); 2074 } 2075 } else if (searchname != NULL) { 2076 char *name; 2077 2078 /* 2079 * We are searching for a pool based on name. 2080 */ 2081 verify(nvlist_lookup_string(config, 2082 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 2083 2084 if (strcmp(name, searchname) == 0) { 2085 if (found_config != NULL) { 2086 (void) fprintf(stderr, gettext( 2087 "cannot import '%s': more than " 2088 "one matching pool\n"), searchname); 2089 (void) fprintf(stderr, gettext( 2090 "import by numeric ID instead\n")); 2091 err = B_TRUE; 2092 } 2093 found_config = config; 2094 } 2095 } else { 2096 uint64_t guid; 2097 2098 /* 2099 * Search for a pool by guid. 2100 */ 2101 verify(nvlist_lookup_uint64(config, 2102 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 2103 2104 if (guid == searchguid) 2105 found_config = config; 2106 } 2107 } 2108 2109 /* 2110 * If we were searching for a specific pool, verify that we found a 2111 * pool, and then do the import. 2112 */ 2113 if (argc != 0 && err == 0) { 2114 if (found_config == NULL) { 2115 (void) fprintf(stderr, gettext("cannot import '%s': " 2116 "no such pool available\n"), argv[0]); 2117 err = B_TRUE; 2118 } else { 2119 err |= do_import(found_config, argc == 1 ? NULL : 2120 argv[1], mntopts, props, flags); 2121 } 2122 } 2123 2124 /* 2125 * If we were just looking for pools, report an error if none were 2126 * found. 2127 */ 2128 if (argc == 0 && first) 2129 (void) fprintf(stderr, 2130 gettext("no pools available to import\n")); 2131 2132 error: 2133 nvlist_free(props); 2134 nvlist_free(pools); 2135 nvlist_free(policy); 2136 free(searchdirs); 2137 2138 return (err ? 1 : 0); 2139 } 2140 2141 typedef struct iostat_cbdata { 2142 boolean_t cb_verbose; 2143 int cb_namewidth; 2144 int cb_iteration; 2145 zpool_list_t *cb_list; 2146 } iostat_cbdata_t; 2147 2148 static void 2149 print_iostat_separator(iostat_cbdata_t *cb) 2150 { 2151 int i = 0; 2152 2153 for (i = 0; i < cb->cb_namewidth; i++) 2154 (void) printf("-"); 2155 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 2156 } 2157 2158 static void 2159 print_iostat_header(iostat_cbdata_t *cb) 2160 { 2161 (void) printf("%*s capacity operations bandwidth\n", 2162 cb->cb_namewidth, ""); 2163 (void) printf("%-*s alloc free read write read write\n", 2164 cb->cb_namewidth, "pool"); 2165 print_iostat_separator(cb); 2166 } 2167 2168 /* 2169 * Display a single statistic. 2170 */ 2171 static void 2172 print_one_stat(uint64_t value) 2173 { 2174 char buf[64]; 2175 2176 zfs_nicenum(value, buf, sizeof (buf)); 2177 (void) printf(" %5s", buf); 2178 } 2179 2180 /* 2181 * Print out all the statistics for the given vdev. This can either be the 2182 * toplevel configuration, or called recursively. If 'name' is NULL, then this 2183 * is a verbose output, and we don't want to display the toplevel pool stats. 2184 */ 2185 void 2186 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 2187 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 2188 { 2189 nvlist_t **oldchild, **newchild; 2190 uint_t c, children; 2191 vdev_stat_t *oldvs, *newvs; 2192 vdev_stat_t zerovs = { 0 }; 2193 uint64_t tdelta; 2194 double scale; 2195 char *vname; 2196 2197 if (oldnv != NULL) { 2198 verify(nvlist_lookup_uint64_array(oldnv, 2199 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0); 2200 } else { 2201 oldvs = &zerovs; 2202 } 2203 2204 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS, 2205 (uint64_t **)&newvs, &c) == 0); 2206 2207 if (strlen(name) + depth > cb->cb_namewidth) 2208 (void) printf("%*s%s", depth, "", name); 2209 else 2210 (void) printf("%*s%s%*s", depth, "", name, 2211 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 2212 2213 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 2214 2215 if (tdelta == 0) 2216 scale = 1.0; 2217 else 2218 scale = (double)NANOSEC / tdelta; 2219 2220 /* only toplevel vdevs have capacity stats */ 2221 if (newvs->vs_space == 0) { 2222 (void) printf(" - -"); 2223 } else { 2224 print_one_stat(newvs->vs_alloc); 2225 print_one_stat(newvs->vs_space - newvs->vs_alloc); 2226 } 2227 2228 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 2229 oldvs->vs_ops[ZIO_TYPE_READ]))); 2230 2231 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 2232 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 2233 2234 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 2235 oldvs->vs_bytes[ZIO_TYPE_READ]))); 2236 2237 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 2238 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 2239 2240 (void) printf("\n"); 2241 2242 if (!cb->cb_verbose) 2243 return; 2244 2245 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 2246 &newchild, &children) != 0) 2247 return; 2248 2249 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 2250 &oldchild, &c) != 0) 2251 return; 2252 2253 for (c = 0; c < children; c++) { 2254 uint64_t ishole = B_FALSE, islog = B_FALSE; 2255 2256 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE, 2257 &ishole); 2258 2259 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG, 2260 &islog); 2261 2262 if (ishole || islog) 2263 continue; 2264 2265 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE); 2266 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 2267 newchild[c], cb, depth + 2); 2268 free(vname); 2269 } 2270 2271 /* 2272 * Log device section 2273 */ 2274 2275 if (num_logs(newnv) > 0) { 2276 (void) printf("%-*s - - - - - " 2277 "-\n", cb->cb_namewidth, "logs"); 2278 2279 for (c = 0; c < children; c++) { 2280 uint64_t islog = B_FALSE; 2281 (void) nvlist_lookup_uint64(newchild[c], 2282 ZPOOL_CONFIG_IS_LOG, &islog); 2283 2284 if (islog) { 2285 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 2286 B_FALSE); 2287 print_vdev_stats(zhp, vname, oldnv ? 2288 oldchild[c] : NULL, newchild[c], 2289 cb, depth + 2); 2290 free(vname); 2291 } 2292 } 2293 2294 } 2295 2296 /* 2297 * Include level 2 ARC devices in iostat output 2298 */ 2299 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 2300 &newchild, &children) != 0) 2301 return; 2302 2303 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 2304 &oldchild, &c) != 0) 2305 return; 2306 2307 if (children > 0) { 2308 (void) printf("%-*s - - - - - " 2309 "-\n", cb->cb_namewidth, "cache"); 2310 for (c = 0; c < children; c++) { 2311 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 2312 B_FALSE); 2313 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 2314 newchild[c], cb, depth + 2); 2315 free(vname); 2316 } 2317 } 2318 } 2319 2320 static int 2321 refresh_iostat(zpool_handle_t *zhp, void *data) 2322 { 2323 iostat_cbdata_t *cb = data; 2324 boolean_t missing; 2325 2326 /* 2327 * If the pool has disappeared, remove it from the list and continue. 2328 */ 2329 if (zpool_refresh_stats(zhp, &missing) != 0) 2330 return (-1); 2331 2332 if (missing) 2333 pool_list_remove(cb->cb_list, zhp); 2334 2335 return (0); 2336 } 2337 2338 /* 2339 * Callback to print out the iostats for the given pool. 2340 */ 2341 int 2342 print_iostat(zpool_handle_t *zhp, void *data) 2343 { 2344 iostat_cbdata_t *cb = data; 2345 nvlist_t *oldconfig, *newconfig; 2346 nvlist_t *oldnvroot, *newnvroot; 2347 2348 newconfig = zpool_get_config(zhp, &oldconfig); 2349 2350 if (cb->cb_iteration == 1) 2351 oldconfig = NULL; 2352 2353 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 2354 &newnvroot) == 0); 2355 2356 if (oldconfig == NULL) 2357 oldnvroot = NULL; 2358 else 2359 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 2360 &oldnvroot) == 0); 2361 2362 /* 2363 * Print out the statistics for the pool. 2364 */ 2365 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 2366 2367 if (cb->cb_verbose) 2368 print_iostat_separator(cb); 2369 2370 return (0); 2371 } 2372 2373 int 2374 get_namewidth(zpool_handle_t *zhp, void *data) 2375 { 2376 iostat_cbdata_t *cb = data; 2377 nvlist_t *config, *nvroot; 2378 2379 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 2380 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2381 &nvroot) == 0); 2382 if (!cb->cb_verbose) 2383 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 2384 else 2385 cb->cb_namewidth = max_width(zhp, nvroot, 0, 2386 cb->cb_namewidth); 2387 } 2388 2389 /* 2390 * The width must fall into the range [10,38]. The upper limit is the 2391 * maximum we can have and still fit in 80 columns. 2392 */ 2393 if (cb->cb_namewidth < 10) 2394 cb->cb_namewidth = 10; 2395 if (cb->cb_namewidth > 38) 2396 cb->cb_namewidth = 38; 2397 2398 return (0); 2399 } 2400 2401 /* 2402 * Parse the input string, get the 'interval' and 'count' value if there is one. 2403 */ 2404 static void 2405 get_interval_count(int *argcp, char **argv, unsigned long *iv, 2406 unsigned long *cnt) 2407 { 2408 unsigned long interval = 0, count = 0; 2409 int argc = *argcp, errno; 2410 2411 /* 2412 * Determine if the last argument is an integer or a pool name 2413 */ 2414 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2415 char *end; 2416 2417 errno = 0; 2418 interval = strtoul(argv[argc - 1], &end, 10); 2419 2420 if (*end == '\0' && errno == 0) { 2421 if (interval == 0) { 2422 (void) fprintf(stderr, gettext("interval " 2423 "cannot be zero\n")); 2424 usage(B_FALSE); 2425 } 2426 /* 2427 * Ignore the last parameter 2428 */ 2429 argc--; 2430 } else { 2431 /* 2432 * If this is not a valid number, just plow on. The 2433 * user will get a more informative error message later 2434 * on. 2435 */ 2436 interval = 0; 2437 } 2438 } 2439 2440 /* 2441 * If the last argument is also an integer, then we have both a count 2442 * and an interval. 2443 */ 2444 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2445 char *end; 2446 2447 errno = 0; 2448 count = interval; 2449 interval = strtoul(argv[argc - 1], &end, 10); 2450 2451 if (*end == '\0' && errno == 0) { 2452 if (interval == 0) { 2453 (void) fprintf(stderr, gettext("interval " 2454 "cannot be zero\n")); 2455 usage(B_FALSE); 2456 } 2457 2458 /* 2459 * Ignore the last parameter 2460 */ 2461 argc--; 2462 } else { 2463 interval = 0; 2464 } 2465 } 2466 2467 *iv = interval; 2468 *cnt = count; 2469 *argcp = argc; 2470 } 2471 2472 static void 2473 get_timestamp_arg(char c) 2474 { 2475 if (c == 'u') 2476 timestamp_fmt = UDATE; 2477 else if (c == 'd') 2478 timestamp_fmt = DDATE; 2479 else 2480 usage(B_FALSE); 2481 } 2482 2483 /* 2484 * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]] 2485 * 2486 * -v Display statistics for individual vdevs 2487 * -T Display a timestamp in date(1) or Unix format 2488 * 2489 * This command can be tricky because we want to be able to deal with pool 2490 * creation/destruction as well as vdev configuration changes. The bulk of this 2491 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 2492 * on pool_list_update() to detect the addition of new pools. Configuration 2493 * changes are all handled within libzfs. 2494 */ 2495 int 2496 zpool_do_iostat(int argc, char **argv) 2497 { 2498 int c; 2499 int ret; 2500 int npools; 2501 unsigned long interval = 0, count = 0; 2502 zpool_list_t *list; 2503 boolean_t verbose = B_FALSE; 2504 iostat_cbdata_t cb; 2505 2506 /* check options */ 2507 while ((c = getopt(argc, argv, "T:v")) != -1) { 2508 switch (c) { 2509 case 'T': 2510 get_timestamp_arg(*optarg); 2511 break; 2512 case 'v': 2513 verbose = B_TRUE; 2514 break; 2515 case '?': 2516 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2517 optopt); 2518 usage(B_FALSE); 2519 } 2520 } 2521 2522 argc -= optind; 2523 argv += optind; 2524 2525 get_interval_count(&argc, argv, &interval, &count); 2526 2527 /* 2528 * Construct the list of all interesting pools. 2529 */ 2530 ret = 0; 2531 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL) 2532 return (1); 2533 2534 if (pool_list_count(list) == 0 && argc != 0) { 2535 pool_list_free(list); 2536 return (1); 2537 } 2538 2539 if (pool_list_count(list) == 0 && interval == 0) { 2540 pool_list_free(list); 2541 (void) fprintf(stderr, gettext("no pools available\n")); 2542 return (1); 2543 } 2544 2545 /* 2546 * Enter the main iostat loop. 2547 */ 2548 cb.cb_list = list; 2549 cb.cb_verbose = verbose; 2550 cb.cb_iteration = 0; 2551 cb.cb_namewidth = 0; 2552 2553 for (;;) { 2554 pool_list_update(list); 2555 2556 if ((npools = pool_list_count(list)) == 0) 2557 break; 2558 2559 /* 2560 * Refresh all statistics. This is done as an explicit step 2561 * before calculating the maximum name width, so that any 2562 * configuration changes are properly accounted for. 2563 */ 2564 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 2565 2566 /* 2567 * Iterate over all pools to determine the maximum width 2568 * for the pool / device name column across all pools. 2569 */ 2570 cb.cb_namewidth = 0; 2571 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 2572 2573 if (timestamp_fmt != NODATE) 2574 print_timestamp(timestamp_fmt); 2575 2576 /* 2577 * If it's the first time, or verbose mode, print the header. 2578 */ 2579 if (++cb.cb_iteration == 1 || verbose) 2580 print_iostat_header(&cb); 2581 2582 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 2583 2584 /* 2585 * If there's more than one pool, and we're not in verbose mode 2586 * (which prints a separator for us), then print a separator. 2587 */ 2588 if (npools > 1 && !verbose) 2589 print_iostat_separator(&cb); 2590 2591 if (verbose) 2592 (void) printf("\n"); 2593 2594 /* 2595 * Flush the output so that redirection to a file isn't buffered 2596 * indefinitely. 2597 */ 2598 (void) fflush(stdout); 2599 2600 if (interval == 0) 2601 break; 2602 2603 if (count != 0 && --count == 0) 2604 break; 2605 2606 (void) sleep(interval); 2607 } 2608 2609 pool_list_free(list); 2610 2611 return (ret); 2612 } 2613 2614 typedef struct list_cbdata { 2615 boolean_t cb_verbose; 2616 int cb_namewidth; 2617 boolean_t cb_scripted; 2618 zprop_list_t *cb_proplist; 2619 } list_cbdata_t; 2620 2621 /* 2622 * Given a list of columns to display, output appropriate headers for each one. 2623 */ 2624 static void 2625 print_header(list_cbdata_t *cb) 2626 { 2627 zprop_list_t *pl = cb->cb_proplist; 2628 char headerbuf[ZPOOL_MAXPROPLEN]; 2629 const char *header; 2630 boolean_t first = B_TRUE; 2631 boolean_t right_justify; 2632 size_t width = 0; 2633 2634 for (; pl != NULL; pl = pl->pl_next) { 2635 width = pl->pl_width; 2636 if (first && cb->cb_verbose) { 2637 /* 2638 * Reset the width to accommodate the verbose listing 2639 * of devices. 2640 */ 2641 width = cb->cb_namewidth; 2642 } 2643 2644 if (!first) 2645 (void) printf(" "); 2646 else 2647 first = B_FALSE; 2648 2649 right_justify = B_FALSE; 2650 if (pl->pl_prop != ZPROP_INVAL) { 2651 header = zpool_prop_column_name(pl->pl_prop); 2652 right_justify = zpool_prop_align_right(pl->pl_prop); 2653 } else { 2654 int i; 2655 2656 for (i = 0; pl->pl_user_prop[i] != '\0'; i++) 2657 headerbuf[i] = toupper(pl->pl_user_prop[i]); 2658 headerbuf[i] = '\0'; 2659 header = headerbuf; 2660 } 2661 2662 if (pl->pl_next == NULL && !right_justify) 2663 (void) printf("%s", header); 2664 else if (right_justify) 2665 (void) printf("%*s", width, header); 2666 else 2667 (void) printf("%-*s", width, header); 2668 2669 } 2670 2671 (void) printf("\n"); 2672 } 2673 2674 /* 2675 * Given a pool and a list of properties, print out all the properties according 2676 * to the described layout. 2677 */ 2678 static void 2679 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) 2680 { 2681 zprop_list_t *pl = cb->cb_proplist; 2682 boolean_t first = B_TRUE; 2683 char property[ZPOOL_MAXPROPLEN]; 2684 char *propstr; 2685 boolean_t right_justify; 2686 size_t width; 2687 2688 for (; pl != NULL; pl = pl->pl_next) { 2689 2690 width = pl->pl_width; 2691 if (first && cb->cb_verbose) { 2692 /* 2693 * Reset the width to accommodate the verbose listing 2694 * of devices. 2695 */ 2696 width = cb->cb_namewidth; 2697 } 2698 2699 if (!first) { 2700 if (cb->cb_scripted) 2701 (void) printf("\t"); 2702 else 2703 (void) printf(" "); 2704 } else { 2705 first = B_FALSE; 2706 } 2707 2708 right_justify = B_FALSE; 2709 if (pl->pl_prop != ZPROP_INVAL) { 2710 if (pl->pl_prop == ZPOOL_PROP_EXPANDSZ && 2711 zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0) 2712 propstr = "-"; 2713 else if (zpool_get_prop(zhp, pl->pl_prop, property, 2714 sizeof (property), NULL) != 0) 2715 propstr = "-"; 2716 else 2717 propstr = property; 2718 2719 right_justify = zpool_prop_align_right(pl->pl_prop); 2720 } else if ((zpool_prop_feature(pl->pl_user_prop) || 2721 zpool_prop_unsupported(pl->pl_user_prop)) && 2722 zpool_prop_get_feature(zhp, pl->pl_user_prop, property, 2723 sizeof (property)) == 0) { 2724 propstr = property; 2725 } else { 2726 propstr = "-"; 2727 } 2728 2729 2730 /* 2731 * If this is being called in scripted mode, or if this is the 2732 * last column and it is left-justified, don't include a width 2733 * format specifier. 2734 */ 2735 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) 2736 (void) printf("%s", propstr); 2737 else if (right_justify) 2738 (void) printf("%*s", width, propstr); 2739 else 2740 (void) printf("%-*s", width, propstr); 2741 } 2742 2743 (void) printf("\n"); 2744 } 2745 2746 static void 2747 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted) 2748 { 2749 char propval[64]; 2750 boolean_t fixed; 2751 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL); 2752 2753 zfs_nicenum(value, propval, sizeof (propval)); 2754 2755 if (prop == ZPOOL_PROP_EXPANDSZ && value == 0) 2756 (void) strlcpy(propval, "-", sizeof (propval)); 2757 2758 if (scripted) 2759 (void) printf("\t%s", propval); 2760 else 2761 (void) printf(" %*s", width, propval); 2762 } 2763 2764 void 2765 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 2766 list_cbdata_t *cb, int depth) 2767 { 2768 nvlist_t **child; 2769 vdev_stat_t *vs; 2770 uint_t c, children; 2771 char *vname; 2772 boolean_t scripted = cb->cb_scripted; 2773 2774 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 2775 (uint64_t **)&vs, &c) == 0); 2776 2777 if (name != NULL) { 2778 if (scripted) 2779 (void) printf("\t%s", name); 2780 else if (strlen(name) + depth > cb->cb_namewidth) 2781 (void) printf("%*s%s", depth, "", name); 2782 else 2783 (void) printf("%*s%s%*s", depth, "", name, 2784 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 2785 2786 /* only toplevel vdevs have capacity stats */ 2787 if (vs->vs_space == 0) { 2788 if (scripted) 2789 (void) printf("\t-\t-\t-"); 2790 else 2791 (void) printf(" - - -"); 2792 } else { 2793 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, 2794 scripted); 2795 print_one_column(ZPOOL_PROP_CAPACITY, vs->vs_alloc, 2796 scripted); 2797 print_one_column(ZPOOL_PROP_FREE, 2798 vs->vs_space - vs->vs_alloc, scripted); 2799 } 2800 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, 2801 scripted); 2802 (void) printf("\n"); 2803 } 2804 2805 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2806 &child, &children) != 0) 2807 return; 2808 2809 for (c = 0; c < children; c++) { 2810 uint64_t ishole = B_FALSE; 2811 2812 if (nvlist_lookup_uint64(child[c], 2813 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) 2814 continue; 2815 2816 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 2817 print_list_stats(zhp, vname, child[c], cb, depth + 2); 2818 free(vname); 2819 } 2820 2821 /* 2822 * Include level 2 ARC devices in iostat output 2823 */ 2824 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 2825 &child, &children) != 0) 2826 return; 2827 2828 if (children > 0) { 2829 (void) printf("%-*s - - - - - " 2830 "-\n", cb->cb_namewidth, "cache"); 2831 for (c = 0; c < children; c++) { 2832 vname = zpool_vdev_name(g_zfs, zhp, child[c], 2833 B_FALSE); 2834 print_list_stats(zhp, vname, child[c], cb, depth + 2); 2835 free(vname); 2836 } 2837 } 2838 } 2839 2840 2841 /* 2842 * Generic callback function to list a pool. 2843 */ 2844 int 2845 list_callback(zpool_handle_t *zhp, void *data) 2846 { 2847 list_cbdata_t *cbp = data; 2848 nvlist_t *config; 2849 nvlist_t *nvroot; 2850 2851 config = zpool_get_config(zhp, NULL); 2852 2853 print_pool(zhp, cbp); 2854 if (!cbp->cb_verbose) 2855 return (0); 2856 2857 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2858 &nvroot) == 0); 2859 print_list_stats(zhp, NULL, nvroot, cbp, 0); 2860 2861 return (0); 2862 } 2863 2864 /* 2865 * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] 2866 * 2867 * -H Scripted mode. Don't display headers, and separate properties 2868 * by a single tab. 2869 * -o List of properties to display. Defaults to 2870 * "name,size,allocated,free,capacity,health,altroot" 2871 * -T Display a timestamp in date(1) or Unix format 2872 * 2873 * List all pools in the system, whether or not they're healthy. Output space 2874 * statistics for each one, as well as health status summary. 2875 */ 2876 int 2877 zpool_do_list(int argc, char **argv) 2878 { 2879 int c; 2880 int ret; 2881 list_cbdata_t cb = { 0 }; 2882 static char default_props[] = 2883 "name,size,allocated,free,expandsize,capacity,dedupratio," 2884 "health,altroot"; 2885 char *props = default_props; 2886 unsigned long interval = 0, count = 0; 2887 zpool_list_t *list; 2888 boolean_t first = B_TRUE; 2889 2890 /* check options */ 2891 while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) { 2892 switch (c) { 2893 case 'H': 2894 cb.cb_scripted = B_TRUE; 2895 break; 2896 case 'o': 2897 props = optarg; 2898 break; 2899 case 'T': 2900 get_timestamp_arg(*optarg); 2901 break; 2902 case 'v': 2903 cb.cb_verbose = B_TRUE; 2904 break; 2905 case ':': 2906 (void) fprintf(stderr, gettext("missing argument for " 2907 "'%c' option\n"), optopt); 2908 usage(B_FALSE); 2909 break; 2910 case '?': 2911 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2912 optopt); 2913 usage(B_FALSE); 2914 } 2915 } 2916 2917 argc -= optind; 2918 argv += optind; 2919 2920 get_interval_count(&argc, argv, &interval, &count); 2921 2922 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 2923 usage(B_FALSE); 2924 2925 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, &ret)) == NULL) 2926 return (1); 2927 2928 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) { 2929 (void) printf(gettext("no pools available\n")); 2930 zprop_free_list(cb.cb_proplist); 2931 return (0); 2932 } 2933 2934 for (;;) { 2935 pool_list_update(list); 2936 2937 if (pool_list_count(list) == 0) 2938 break; 2939 2940 cb.cb_namewidth = 0; 2941 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 2942 2943 if (timestamp_fmt != NODATE) 2944 print_timestamp(timestamp_fmt); 2945 2946 if (!cb.cb_scripted && (first || cb.cb_verbose)) { 2947 print_header(&cb); 2948 first = B_FALSE; 2949 } 2950 ret = pool_list_iter(list, B_TRUE, list_callback, &cb); 2951 2952 if (interval == 0) 2953 break; 2954 2955 if (count != 0 && --count == 0) 2956 break; 2957 2958 (void) sleep(interval); 2959 } 2960 2961 zprop_free_list(cb.cb_proplist); 2962 return (ret); 2963 } 2964 2965 static nvlist_t * 2966 zpool_get_vdev_by_name(nvlist_t *nv, char *name) 2967 { 2968 nvlist_t **child; 2969 uint_t c, children; 2970 nvlist_t *match; 2971 char *path; 2972 2973 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2974 &child, &children) != 0) { 2975 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2976 if (strncmp(name, "/dev/dsk/", 9) == 0) 2977 name += 9; 2978 if (strncmp(path, "/dev/dsk/", 9) == 0) 2979 path += 9; 2980 if (strcmp(name, path) == 0) 2981 return (nv); 2982 return (NULL); 2983 } 2984 2985 for (c = 0; c < children; c++) 2986 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL) 2987 return (match); 2988 2989 return (NULL); 2990 } 2991 2992 static int 2993 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 2994 { 2995 boolean_t force = B_FALSE; 2996 int c; 2997 nvlist_t *nvroot; 2998 char *poolname, *old_disk, *new_disk; 2999 zpool_handle_t *zhp; 3000 int ret; 3001 3002 /* check options */ 3003 while ((c = getopt(argc, argv, "f")) != -1) { 3004 switch (c) { 3005 case 'f': 3006 force = B_TRUE; 3007 break; 3008 case '?': 3009 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3010 optopt); 3011 usage(B_FALSE); 3012 } 3013 } 3014 3015 argc -= optind; 3016 argv += optind; 3017 3018 /* get pool name and check number of arguments */ 3019 if (argc < 1) { 3020 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3021 usage(B_FALSE); 3022 } 3023 3024 poolname = argv[0]; 3025 3026 if (argc < 2) { 3027 (void) fprintf(stderr, 3028 gettext("missing <device> specification\n")); 3029 usage(B_FALSE); 3030 } 3031 3032 old_disk = argv[1]; 3033 3034 if (argc < 3) { 3035 if (!replacing) { 3036 (void) fprintf(stderr, 3037 gettext("missing <new_device> specification\n")); 3038 usage(B_FALSE); 3039 } 3040 new_disk = old_disk; 3041 argc -= 1; 3042 argv += 1; 3043 } else { 3044 new_disk = argv[2]; 3045 argc -= 2; 3046 argv += 2; 3047 } 3048 3049 if (argc > 1) { 3050 (void) fprintf(stderr, gettext("too many arguments\n")); 3051 usage(B_FALSE); 3052 } 3053 3054 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3055 return (1); 3056 3057 if (zpool_get_config(zhp, NULL) == NULL) { 3058 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 3059 poolname); 3060 zpool_close(zhp); 3061 return (1); 3062 } 3063 3064 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, 3065 argc, argv); 3066 if (nvroot == NULL) { 3067 zpool_close(zhp); 3068 return (1); 3069 } 3070 3071 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 3072 3073 nvlist_free(nvroot); 3074 zpool_close(zhp); 3075 3076 return (ret); 3077 } 3078 3079 /* 3080 * zpool replace [-f] <pool> <device> <new_device> 3081 * 3082 * -f Force attach, even if <new_device> appears to be in use. 3083 * 3084 * Replace <device> with <new_device>. 3085 */ 3086 /* ARGSUSED */ 3087 int 3088 zpool_do_replace(int argc, char **argv) 3089 { 3090 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 3091 } 3092 3093 /* 3094 * zpool attach [-f] <pool> <device> <new_device> 3095 * 3096 * -f Force attach, even if <new_device> appears to be in use. 3097 * 3098 * Attach <new_device> to the mirror containing <device>. If <device> is not 3099 * part of a mirror, then <device> will be transformed into a mirror of 3100 * <device> and <new_device>. In either case, <new_device> will begin life 3101 * with a DTL of [0, now], and will immediately begin to resilver itself. 3102 */ 3103 int 3104 zpool_do_attach(int argc, char **argv) 3105 { 3106 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 3107 } 3108 3109 /* 3110 * zpool detach [-f] <pool> <device> 3111 * 3112 * -f Force detach of <device>, even if DTLs argue against it 3113 * (not supported yet) 3114 * 3115 * Detach a device from a mirror. The operation will be refused if <device> 3116 * is the last device in the mirror, or if the DTLs indicate that this device 3117 * has the only valid copy of some data. 3118 */ 3119 /* ARGSUSED */ 3120 int 3121 zpool_do_detach(int argc, char **argv) 3122 { 3123 int c; 3124 char *poolname, *path; 3125 zpool_handle_t *zhp; 3126 int ret; 3127 3128 /* check options */ 3129 while ((c = getopt(argc, argv, "f")) != -1) { 3130 switch (c) { 3131 case 'f': 3132 case '?': 3133 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3134 optopt); 3135 usage(B_FALSE); 3136 } 3137 } 3138 3139 argc -= optind; 3140 argv += optind; 3141 3142 /* get pool name and check number of arguments */ 3143 if (argc < 1) { 3144 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3145 usage(B_FALSE); 3146 } 3147 3148 if (argc < 2) { 3149 (void) fprintf(stderr, 3150 gettext("missing <device> specification\n")); 3151 usage(B_FALSE); 3152 } 3153 3154 poolname = argv[0]; 3155 path = argv[1]; 3156 3157 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3158 return (1); 3159 3160 ret = zpool_vdev_detach(zhp, path); 3161 3162 zpool_close(zhp); 3163 3164 return (ret); 3165 } 3166 3167 /* 3168 * zpool split [-n] [-o prop=val] ... 3169 * [-o mntopt] ... 3170 * [-R altroot] <pool> <newpool> [<device> ...] 3171 * 3172 * -n Do not split the pool, but display the resulting layout if 3173 * it were to be split. 3174 * -o Set property=value, or set mount options. 3175 * -R Mount the split-off pool under an alternate root. 3176 * 3177 * Splits the named pool and gives it the new pool name. Devices to be split 3178 * off may be listed, provided that no more than one device is specified 3179 * per top-level vdev mirror. The newly split pool is left in an exported 3180 * state unless -R is specified. 3181 * 3182 * Restrictions: the top-level of the pool pool must only be made up of 3183 * mirrors; all devices in the pool must be healthy; no device may be 3184 * undergoing a resilvering operation. 3185 */ 3186 int 3187 zpool_do_split(int argc, char **argv) 3188 { 3189 char *srcpool, *newpool, *propval; 3190 char *mntopts = NULL; 3191 splitflags_t flags; 3192 int c, ret = 0; 3193 zpool_handle_t *zhp; 3194 nvlist_t *config, *props = NULL; 3195 3196 flags.dryrun = B_FALSE; 3197 flags.import = B_FALSE; 3198 3199 /* check options */ 3200 while ((c = getopt(argc, argv, ":R:no:")) != -1) { 3201 switch (c) { 3202 case 'R': 3203 flags.import = B_TRUE; 3204 if (add_prop_list( 3205 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg, 3206 &props, B_TRUE) != 0) { 3207 if (props) 3208 nvlist_free(props); 3209 usage(B_FALSE); 3210 } 3211 break; 3212 case 'n': 3213 flags.dryrun = B_TRUE; 3214 break; 3215 case 'o': 3216 if ((propval = strchr(optarg, '=')) != NULL) { 3217 *propval = '\0'; 3218 propval++; 3219 if (add_prop_list(optarg, propval, 3220 &props, B_TRUE) != 0) { 3221 if (props) 3222 nvlist_free(props); 3223 usage(B_FALSE); 3224 } 3225 } else { 3226 mntopts = optarg; 3227 } 3228 break; 3229 case ':': 3230 (void) fprintf(stderr, gettext("missing argument for " 3231 "'%c' option\n"), optopt); 3232 usage(B_FALSE); 3233 break; 3234 case '?': 3235 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3236 optopt); 3237 usage(B_FALSE); 3238 break; 3239 } 3240 } 3241 3242 if (!flags.import && mntopts != NULL) { 3243 (void) fprintf(stderr, gettext("setting mntopts is only " 3244 "valid when importing the pool\n")); 3245 usage(B_FALSE); 3246 } 3247 3248 argc -= optind; 3249 argv += optind; 3250 3251 if (argc < 1) { 3252 (void) fprintf(stderr, gettext("Missing pool name\n")); 3253 usage(B_FALSE); 3254 } 3255 if (argc < 2) { 3256 (void) fprintf(stderr, gettext("Missing new pool name\n")); 3257 usage(B_FALSE); 3258 } 3259 3260 srcpool = argv[0]; 3261 newpool = argv[1]; 3262 3263 argc -= 2; 3264 argv += 2; 3265 3266 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) 3267 return (1); 3268 3269 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 3270 if (config == NULL) { 3271 ret = 1; 3272 } else { 3273 if (flags.dryrun) { 3274 (void) printf(gettext("would create '%s' with the " 3275 "following layout:\n\n"), newpool); 3276 print_vdev_tree(NULL, newpool, config, 0, B_FALSE); 3277 } 3278 nvlist_free(config); 3279 } 3280 3281 zpool_close(zhp); 3282 3283 if (ret != 0 || flags.dryrun || !flags.import) 3284 return (ret); 3285 3286 /* 3287 * The split was successful. Now we need to open the new 3288 * pool and import it. 3289 */ 3290 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) 3291 return (1); 3292 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 3293 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 3294 ret = 1; 3295 (void) fprintf(stderr, gettext("Split was successful, but " 3296 "the datasets could not all be mounted\n")); 3297 (void) fprintf(stderr, gettext("Try doing '%s' with a " 3298 "different altroot\n"), "zpool import"); 3299 } 3300 zpool_close(zhp); 3301 3302 return (ret); 3303 } 3304 3305 3306 3307 /* 3308 * zpool online <pool> <device> ... 3309 */ 3310 int 3311 zpool_do_online(int argc, char **argv) 3312 { 3313 int c, i; 3314 char *poolname; 3315 zpool_handle_t *zhp; 3316 int ret = 0; 3317 vdev_state_t newstate; 3318 int flags = 0; 3319 3320 /* check options */ 3321 while ((c = getopt(argc, argv, "et")) != -1) { 3322 switch (c) { 3323 case 'e': 3324 flags |= ZFS_ONLINE_EXPAND; 3325 break; 3326 case 't': 3327 case '?': 3328 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3329 optopt); 3330 usage(B_FALSE); 3331 } 3332 } 3333 3334 argc -= optind; 3335 argv += optind; 3336 3337 /* get pool name and check number of arguments */ 3338 if (argc < 1) { 3339 (void) fprintf(stderr, gettext("missing pool name\n")); 3340 usage(B_FALSE); 3341 } 3342 if (argc < 2) { 3343 (void) fprintf(stderr, gettext("missing device name\n")); 3344 usage(B_FALSE); 3345 } 3346 3347 poolname = argv[0]; 3348 3349 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3350 return (1); 3351 3352 for (i = 1; i < argc; i++) { 3353 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 3354 if (newstate != VDEV_STATE_HEALTHY) { 3355 (void) printf(gettext("warning: device '%s' " 3356 "onlined, but remains in faulted state\n"), 3357 argv[i]); 3358 if (newstate == VDEV_STATE_FAULTED) 3359 (void) printf(gettext("use 'zpool " 3360 "clear' to restore a faulted " 3361 "device\n")); 3362 else 3363 (void) printf(gettext("use 'zpool " 3364 "replace' to replace devices " 3365 "that are no longer present\n")); 3366 } 3367 } else { 3368 ret = 1; 3369 } 3370 } 3371 3372 zpool_close(zhp); 3373 3374 return (ret); 3375 } 3376 3377 /* 3378 * zpool offline [-ft] <pool> <device> ... 3379 * 3380 * -f Force the device into the offline state, even if doing 3381 * so would appear to compromise pool availability. 3382 * (not supported yet) 3383 * 3384 * -t Only take the device off-line temporarily. The offline 3385 * state will not be persistent across reboots. 3386 */ 3387 /* ARGSUSED */ 3388 int 3389 zpool_do_offline(int argc, char **argv) 3390 { 3391 int c, i; 3392 char *poolname; 3393 zpool_handle_t *zhp; 3394 int ret = 0; 3395 boolean_t istmp = B_FALSE; 3396 3397 /* check options */ 3398 while ((c = getopt(argc, argv, "ft")) != -1) { 3399 switch (c) { 3400 case 't': 3401 istmp = B_TRUE; 3402 break; 3403 case 'f': 3404 case '?': 3405 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3406 optopt); 3407 usage(B_FALSE); 3408 } 3409 } 3410 3411 argc -= optind; 3412 argv += optind; 3413 3414 /* get pool name and check number of arguments */ 3415 if (argc < 1) { 3416 (void) fprintf(stderr, gettext("missing pool name\n")); 3417 usage(B_FALSE); 3418 } 3419 if (argc < 2) { 3420 (void) fprintf(stderr, gettext("missing device name\n")); 3421 usage(B_FALSE); 3422 } 3423 3424 poolname = argv[0]; 3425 3426 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3427 return (1); 3428 3429 for (i = 1; i < argc; i++) { 3430 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 3431 ret = 1; 3432 } 3433 3434 zpool_close(zhp); 3435 3436 return (ret); 3437 } 3438 3439 /* 3440 * zpool clear <pool> [device] 3441 * 3442 * Clear all errors associated with a pool or a particular device. 3443 */ 3444 int 3445 zpool_do_clear(int argc, char **argv) 3446 { 3447 int c; 3448 int ret = 0; 3449 boolean_t dryrun = B_FALSE; 3450 boolean_t do_rewind = B_FALSE; 3451 boolean_t xtreme_rewind = B_FALSE; 3452 uint32_t rewind_policy = ZPOOL_NO_REWIND; 3453 nvlist_t *policy = NULL; 3454 zpool_handle_t *zhp; 3455 char *pool, *device; 3456 3457 /* check options */ 3458 while ((c = getopt(argc, argv, "FnX")) != -1) { 3459 switch (c) { 3460 case 'F': 3461 do_rewind = B_TRUE; 3462 break; 3463 case 'n': 3464 dryrun = B_TRUE; 3465 break; 3466 case 'X': 3467 xtreme_rewind = B_TRUE; 3468 break; 3469 case '?': 3470 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3471 optopt); 3472 usage(B_FALSE); 3473 } 3474 } 3475 3476 argc -= optind; 3477 argv += optind; 3478 3479 if (argc < 1) { 3480 (void) fprintf(stderr, gettext("missing pool name\n")); 3481 usage(B_FALSE); 3482 } 3483 3484 if (argc > 2) { 3485 (void) fprintf(stderr, gettext("too many arguments\n")); 3486 usage(B_FALSE); 3487 } 3488 3489 if ((dryrun || xtreme_rewind) && !do_rewind) { 3490 (void) fprintf(stderr, 3491 gettext("-n or -X only meaningful with -F\n")); 3492 usage(B_FALSE); 3493 } 3494 if (dryrun) 3495 rewind_policy = ZPOOL_TRY_REWIND; 3496 else if (do_rewind) 3497 rewind_policy = ZPOOL_DO_REWIND; 3498 if (xtreme_rewind) 3499 rewind_policy |= ZPOOL_EXTREME_REWIND; 3500 3501 /* In future, further rewind policy choices can be passed along here */ 3502 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 3503 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0) 3504 return (1); 3505 3506 pool = argv[0]; 3507 device = argc == 2 ? argv[1] : NULL; 3508 3509 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 3510 nvlist_free(policy); 3511 return (1); 3512 } 3513 3514 if (zpool_clear(zhp, device, policy) != 0) 3515 ret = 1; 3516 3517 zpool_close(zhp); 3518 3519 nvlist_free(policy); 3520 3521 return (ret); 3522 } 3523 3524 /* 3525 * zpool reguid <pool> 3526 */ 3527 int 3528 zpool_do_reguid(int argc, char **argv) 3529 { 3530 int c; 3531 char *poolname; 3532 zpool_handle_t *zhp; 3533 int ret = 0; 3534 3535 /* check options */ 3536 while ((c = getopt(argc, argv, "")) != -1) { 3537 switch (c) { 3538 case '?': 3539 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3540 optopt); 3541 usage(B_FALSE); 3542 } 3543 } 3544 3545 argc -= optind; 3546 argv += optind; 3547 3548 /* get pool name and check number of arguments */ 3549 if (argc < 1) { 3550 (void) fprintf(stderr, gettext("missing pool name\n")); 3551 usage(B_FALSE); 3552 } 3553 3554 if (argc > 1) { 3555 (void) fprintf(stderr, gettext("too many arguments\n")); 3556 usage(B_FALSE); 3557 } 3558 3559 poolname = argv[0]; 3560 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3561 return (1); 3562 3563 ret = zpool_reguid(zhp); 3564 3565 zpool_close(zhp); 3566 return (ret); 3567 } 3568 3569 3570 /* 3571 * zpool reopen <pool> 3572 * 3573 * Reopen the pool so that the kernel can update the sizes of all vdevs. 3574 */ 3575 int 3576 zpool_do_reopen(int argc, char **argv) 3577 { 3578 int c; 3579 int ret = 0; 3580 zpool_handle_t *zhp; 3581 char *pool; 3582 3583 /* check options */ 3584 while ((c = getopt(argc, argv, "")) != -1) { 3585 switch (c) { 3586 case '?': 3587 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3588 optopt); 3589 usage(B_FALSE); 3590 } 3591 } 3592 3593 argc--; 3594 argv++; 3595 3596 if (argc < 1) { 3597 (void) fprintf(stderr, gettext("missing pool name\n")); 3598 usage(B_FALSE); 3599 } 3600 3601 if (argc > 1) { 3602 (void) fprintf(stderr, gettext("too many arguments\n")); 3603 usage(B_FALSE); 3604 } 3605 3606 pool = argv[0]; 3607 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 3608 return (1); 3609 3610 ret = zpool_reopen(zhp); 3611 zpool_close(zhp); 3612 return (ret); 3613 } 3614 3615 typedef struct scrub_cbdata { 3616 int cb_type; 3617 int cb_argc; 3618 char **cb_argv; 3619 } scrub_cbdata_t; 3620 3621 int 3622 scrub_callback(zpool_handle_t *zhp, void *data) 3623 { 3624 scrub_cbdata_t *cb = data; 3625 int err; 3626 3627 /* 3628 * Ignore faulted pools. 3629 */ 3630 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 3631 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 3632 "currently unavailable\n"), zpool_get_name(zhp)); 3633 return (1); 3634 } 3635 3636 err = zpool_scan(zhp, cb->cb_type); 3637 3638 return (err != 0); 3639 } 3640 3641 /* 3642 * zpool scrub [-s] <pool> ... 3643 * 3644 * -s Stop. Stops any in-progress scrub. 3645 */ 3646 int 3647 zpool_do_scrub(int argc, char **argv) 3648 { 3649 int c; 3650 scrub_cbdata_t cb; 3651 3652 cb.cb_type = POOL_SCAN_SCRUB; 3653 3654 /* check options */ 3655 while ((c = getopt(argc, argv, "s")) != -1) { 3656 switch (c) { 3657 case 's': 3658 cb.cb_type = POOL_SCAN_NONE; 3659 break; 3660 case '?': 3661 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3662 optopt); 3663 usage(B_FALSE); 3664 } 3665 } 3666 3667 cb.cb_argc = argc; 3668 cb.cb_argv = argv; 3669 argc -= optind; 3670 argv += optind; 3671 3672 if (argc < 1) { 3673 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3674 usage(B_FALSE); 3675 } 3676 3677 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 3678 } 3679 3680 typedef struct status_cbdata { 3681 int cb_count; 3682 boolean_t cb_allpools; 3683 boolean_t cb_verbose; 3684 boolean_t cb_explain; 3685 boolean_t cb_first; 3686 boolean_t cb_dedup_stats; 3687 } status_cbdata_t; 3688 3689 /* 3690 * Print out detailed scrub status. 3691 */ 3692 void 3693 print_scan_status(pool_scan_stat_t *ps) 3694 { 3695 time_t start, end; 3696 uint64_t elapsed, mins_left, hours_left; 3697 uint64_t pass_exam, examined, total; 3698 uint_t rate; 3699 double fraction_done; 3700 char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 3701 3702 (void) printf(gettext(" scan: ")); 3703 3704 /* If there's never been a scan, there's not much to say. */ 3705 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 3706 ps->pss_func >= POOL_SCAN_FUNCS) { 3707 (void) printf(gettext("none requested\n")); 3708 return; 3709 } 3710 3711 start = ps->pss_start_time; 3712 end = ps->pss_end_time; 3713 zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf)); 3714 3715 assert(ps->pss_func == POOL_SCAN_SCRUB || 3716 ps->pss_func == POOL_SCAN_RESILVER); 3717 /* 3718 * Scan is finished or canceled. 3719 */ 3720 if (ps->pss_state == DSS_FINISHED) { 3721 uint64_t minutes_taken = (end - start) / 60; 3722 char *fmt; 3723 3724 if (ps->pss_func == POOL_SCAN_SCRUB) { 3725 fmt = gettext("scrub repaired %s in %lluh%um with " 3726 "%llu errors on %s"); 3727 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 3728 fmt = gettext("resilvered %s in %lluh%um with " 3729 "%llu errors on %s"); 3730 } 3731 /* LINTED */ 3732 (void) printf(fmt, processed_buf, 3733 (u_longlong_t)(minutes_taken / 60), 3734 (uint_t)(minutes_taken % 60), 3735 (u_longlong_t)ps->pss_errors, 3736 ctime((time_t *)&end)); 3737 return; 3738 } else if (ps->pss_state == DSS_CANCELED) { 3739 if (ps->pss_func == POOL_SCAN_SCRUB) { 3740 (void) printf(gettext("scrub canceled on %s"), 3741 ctime(&end)); 3742 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 3743 (void) printf(gettext("resilver canceled on %s"), 3744 ctime(&end)); 3745 } 3746 return; 3747 } 3748 3749 assert(ps->pss_state == DSS_SCANNING); 3750 3751 /* 3752 * Scan is in progress. 3753 */ 3754 if (ps->pss_func == POOL_SCAN_SCRUB) { 3755 (void) printf(gettext("scrub in progress since %s"), 3756 ctime(&start)); 3757 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 3758 (void) printf(gettext("resilver in progress since %s"), 3759 ctime(&start)); 3760 } 3761 3762 examined = ps->pss_examined ? ps->pss_examined : 1; 3763 total = ps->pss_to_examine; 3764 fraction_done = (double)examined / total; 3765 3766 /* elapsed time for this pass */ 3767 elapsed = time(NULL) - ps->pss_pass_start; 3768 elapsed = elapsed ? elapsed : 1; 3769 pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1; 3770 rate = pass_exam / elapsed; 3771 rate = rate ? rate : 1; 3772 mins_left = ((total - examined) / rate) / 60; 3773 hours_left = mins_left / 60; 3774 3775 zfs_nicenum(examined, examined_buf, sizeof (examined_buf)); 3776 zfs_nicenum(total, total_buf, sizeof (total_buf)); 3777 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 3778 3779 /* 3780 * do not print estimated time if hours_left is more than 30 days 3781 */ 3782 (void) printf(gettext(" %s scanned out of %s at %s/s"), 3783 examined_buf, total_buf, rate_buf); 3784 if (hours_left < (30 * 24)) { 3785 (void) printf(gettext(", %lluh%um to go\n"), 3786 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 3787 } else { 3788 (void) printf(gettext( 3789 ", (scan is slow, no estimated time)\n")); 3790 } 3791 3792 if (ps->pss_func == POOL_SCAN_RESILVER) { 3793 (void) printf(gettext(" %s resilvered, %.2f%% done\n"), 3794 processed_buf, 100 * fraction_done); 3795 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 3796 (void) printf(gettext(" %s repaired, %.2f%% done\n"), 3797 processed_buf, 100 * fraction_done); 3798 } 3799 } 3800 3801 static void 3802 print_error_log(zpool_handle_t *zhp) 3803 { 3804 nvlist_t *nverrlist = NULL; 3805 nvpair_t *elem; 3806 char *pathname; 3807 size_t len = MAXPATHLEN * 2; 3808 3809 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 3810 (void) printf("errors: List of errors unavailable " 3811 "(insufficient privileges)\n"); 3812 return; 3813 } 3814 3815 (void) printf("errors: Permanent errors have been " 3816 "detected in the following files:\n\n"); 3817 3818 pathname = safe_malloc(len); 3819 elem = NULL; 3820 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 3821 nvlist_t *nv; 3822 uint64_t dsobj, obj; 3823 3824 verify(nvpair_value_nvlist(elem, &nv) == 0); 3825 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 3826 &dsobj) == 0); 3827 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 3828 &obj) == 0); 3829 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 3830 (void) printf("%7s %s\n", "", pathname); 3831 } 3832 free(pathname); 3833 nvlist_free(nverrlist); 3834 } 3835 3836 static void 3837 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 3838 int namewidth) 3839 { 3840 uint_t i; 3841 char *name; 3842 3843 if (nspares == 0) 3844 return; 3845 3846 (void) printf(gettext("\tspares\n")); 3847 3848 for (i = 0; i < nspares; i++) { 3849 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE); 3850 print_status_config(zhp, name, spares[i], 3851 namewidth, 2, B_TRUE); 3852 free(name); 3853 } 3854 } 3855 3856 static void 3857 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 3858 int namewidth) 3859 { 3860 uint_t i; 3861 char *name; 3862 3863 if (nl2cache == 0) 3864 return; 3865 3866 (void) printf(gettext("\tcache\n")); 3867 3868 for (i = 0; i < nl2cache; i++) { 3869 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE); 3870 print_status_config(zhp, name, l2cache[i], 3871 namewidth, 2, B_FALSE); 3872 free(name); 3873 } 3874 } 3875 3876 static void 3877 print_dedup_stats(nvlist_t *config) 3878 { 3879 ddt_histogram_t *ddh; 3880 ddt_stat_t *dds; 3881 ddt_object_t *ddo; 3882 uint_t c; 3883 3884 /* 3885 * If the pool was faulted then we may not have been able to 3886 * obtain the config. Otherwise, if we have anything in the dedup 3887 * table continue processing the stats. 3888 */ 3889 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 3890 (uint64_t **)&ddo, &c) != 0) 3891 return; 3892 3893 (void) printf("\n"); 3894 (void) printf(gettext(" dedup: ")); 3895 if (ddo->ddo_count == 0) { 3896 (void) printf(gettext("no DDT entries\n")); 3897 return; 3898 } 3899 3900 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n", 3901 (u_longlong_t)ddo->ddo_count, 3902 (u_longlong_t)ddo->ddo_dspace, 3903 (u_longlong_t)ddo->ddo_mspace); 3904 3905 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 3906 (uint64_t **)&dds, &c) == 0); 3907 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 3908 (uint64_t **)&ddh, &c) == 0); 3909 zpool_dump_ddt(dds, ddh); 3910 } 3911 3912 /* 3913 * Display a summary of pool status. Displays a summary such as: 3914 * 3915 * pool: tank 3916 * status: DEGRADED 3917 * reason: One or more devices ... 3918 * see: http://illumos.org/msg/ZFS-xxxx-01 3919 * config: 3920 * mirror DEGRADED 3921 * c1t0d0 OK 3922 * c2t0d0 UNAVAIL 3923 * 3924 * When given the '-v' option, we print out the complete config. If the '-e' 3925 * option is specified, then we print out error rate information as well. 3926 */ 3927 int 3928 status_callback(zpool_handle_t *zhp, void *data) 3929 { 3930 status_cbdata_t *cbp = data; 3931 nvlist_t *config, *nvroot; 3932 char *msgid; 3933 int reason; 3934 const char *health; 3935 uint_t c; 3936 vdev_stat_t *vs; 3937 3938 config = zpool_get_config(zhp, NULL); 3939 reason = zpool_get_status(zhp, &msgid); 3940 3941 cbp->cb_count++; 3942 3943 /* 3944 * If we were given 'zpool status -x', only report those pools with 3945 * problems. 3946 */ 3947 if (cbp->cb_explain && 3948 (reason == ZPOOL_STATUS_OK || 3949 reason == ZPOOL_STATUS_VERSION_OLDER || 3950 reason == ZPOOL_STATUS_FEAT_DISABLED)) { 3951 if (!cbp->cb_allpools) { 3952 (void) printf(gettext("pool '%s' is healthy\n"), 3953 zpool_get_name(zhp)); 3954 if (cbp->cb_first) 3955 cbp->cb_first = B_FALSE; 3956 } 3957 return (0); 3958 } 3959 3960 if (cbp->cb_first) 3961 cbp->cb_first = B_FALSE; 3962 else 3963 (void) printf("\n"); 3964 3965 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 3966 &nvroot) == 0); 3967 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 3968 (uint64_t **)&vs, &c) == 0); 3969 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 3970 3971 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 3972 (void) printf(gettext(" state: %s\n"), health); 3973 3974 switch (reason) { 3975 case ZPOOL_STATUS_MISSING_DEV_R: 3976 (void) printf(gettext("status: One or more devices could not " 3977 "be opened. Sufficient replicas exist for\n\tthe pool to " 3978 "continue functioning in a degraded state.\n")); 3979 (void) printf(gettext("action: Attach the missing device and " 3980 "online it using 'zpool online'.\n")); 3981 break; 3982 3983 case ZPOOL_STATUS_MISSING_DEV_NR: 3984 (void) printf(gettext("status: One or more devices could not " 3985 "be opened. There are insufficient\n\treplicas for the " 3986 "pool to continue functioning.\n")); 3987 (void) printf(gettext("action: Attach the missing device and " 3988 "online it using 'zpool online'.\n")); 3989 break; 3990 3991 case ZPOOL_STATUS_CORRUPT_LABEL_R: 3992 (void) printf(gettext("status: One or more devices could not " 3993 "be used because the label is missing or\n\tinvalid. " 3994 "Sufficient replicas exist for the pool to continue\n\t" 3995 "functioning in a degraded state.\n")); 3996 (void) printf(gettext("action: Replace the device using " 3997 "'zpool replace'.\n")); 3998 break; 3999 4000 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 4001 (void) printf(gettext("status: One or more devices could not " 4002 "be used because the label is missing \n\tor invalid. " 4003 "There are insufficient replicas for the pool to " 4004 "continue\n\tfunctioning.\n")); 4005 zpool_explain_recover(zpool_get_handle(zhp), 4006 zpool_get_name(zhp), reason, config); 4007 break; 4008 4009 case ZPOOL_STATUS_FAILING_DEV: 4010 (void) printf(gettext("status: One or more devices has " 4011 "experienced an unrecoverable error. An\n\tattempt was " 4012 "made to correct the error. Applications are " 4013 "unaffected.\n")); 4014 (void) printf(gettext("action: Determine if the device needs " 4015 "to be replaced, and clear the errors\n\tusing " 4016 "'zpool clear' or replace the device with 'zpool " 4017 "replace'.\n")); 4018 break; 4019 4020 case ZPOOL_STATUS_OFFLINE_DEV: 4021 (void) printf(gettext("status: One or more devices has " 4022 "been taken offline by the administrator.\n\tSufficient " 4023 "replicas exist for the pool to continue functioning in " 4024 "a\n\tdegraded state.\n")); 4025 (void) printf(gettext("action: Online the device using " 4026 "'zpool online' or replace the device with\n\t'zpool " 4027 "replace'.\n")); 4028 break; 4029 4030 case ZPOOL_STATUS_REMOVED_DEV: 4031 (void) printf(gettext("status: One or more devices has " 4032 "been removed by the administrator.\n\tSufficient " 4033 "replicas exist for the pool to continue functioning in " 4034 "a\n\tdegraded state.\n")); 4035 (void) printf(gettext("action: Online the device using " 4036 "'zpool online' or replace the device with\n\t'zpool " 4037 "replace'.\n")); 4038 break; 4039 4040 case ZPOOL_STATUS_RESILVERING: 4041 (void) printf(gettext("status: One or more devices is " 4042 "currently being resilvered. The pool will\n\tcontinue " 4043 "to function, possibly in a degraded state.\n")); 4044 (void) printf(gettext("action: Wait for the resilver to " 4045 "complete.\n")); 4046 break; 4047 4048 case ZPOOL_STATUS_CORRUPT_DATA: 4049 (void) printf(gettext("status: One or more devices has " 4050 "experienced an error resulting in data\n\tcorruption. " 4051 "Applications may be affected.\n")); 4052 (void) printf(gettext("action: Restore the file in question " 4053 "if possible. Otherwise restore the\n\tentire pool from " 4054 "backup.\n")); 4055 break; 4056 4057 case ZPOOL_STATUS_CORRUPT_POOL: 4058 (void) printf(gettext("status: The pool metadata is corrupted " 4059 "and the pool cannot be opened.\n")); 4060 zpool_explain_recover(zpool_get_handle(zhp), 4061 zpool_get_name(zhp), reason, config); 4062 break; 4063 4064 case ZPOOL_STATUS_VERSION_OLDER: 4065 (void) printf(gettext("status: The pool is formatted using a " 4066 "legacy on-disk format. The pool can\n\tstill be used, " 4067 "but some features are unavailable.\n")); 4068 (void) printf(gettext("action: Upgrade the pool using 'zpool " 4069 "upgrade'. Once this is done, the\n\tpool will no longer " 4070 "be accessible on software that does not support feature\n" 4071 "\tflags.\n")); 4072 break; 4073 4074 case ZPOOL_STATUS_VERSION_NEWER: 4075 (void) printf(gettext("status: The pool has been upgraded to a " 4076 "newer, incompatible on-disk version.\n\tThe pool cannot " 4077 "be accessed on this system.\n")); 4078 (void) printf(gettext("action: Access the pool from a system " 4079 "running more recent software, or\n\trestore the pool from " 4080 "backup.\n")); 4081 break; 4082 4083 case ZPOOL_STATUS_FEAT_DISABLED: 4084 (void) printf(gettext("status: Some supported features are not " 4085 "enabled on the pool. The pool can\n\tstill be used, but " 4086 "some features are unavailable.\n")); 4087 (void) printf(gettext("action: Enable all features using " 4088 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 4089 "longer be accessible by software that does not support\n\t" 4090 "the features. See zpool-features(5) for details.\n")); 4091 break; 4092 4093 case ZPOOL_STATUS_UNSUP_FEAT_READ: 4094 (void) printf(gettext("status: The pool cannot be accessed on " 4095 "this system because it uses the\n\tfollowing feature(s) " 4096 "not supported on this system:\n")); 4097 zpool_print_unsup_feat(config); 4098 (void) printf("\n"); 4099 (void) printf(gettext("action: Access the pool from a system " 4100 "that supports the required feature(s),\n\tor restore the " 4101 "pool from backup.\n")); 4102 break; 4103 4104 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 4105 (void) printf(gettext("status: The pool can only be accessed " 4106 "in read-only mode on this system. It\n\tcannot be " 4107 "accessed in read-write mode because it uses the " 4108 "following\n\tfeature(s) not supported on this system:\n")); 4109 zpool_print_unsup_feat(config); 4110 (void) printf("\n"); 4111 (void) printf(gettext("action: The pool cannot be accessed in " 4112 "read-write mode. Import the pool with\n" 4113 "\t\"-o readonly=on\", access the pool from a system that " 4114 "supports the\n\trequired feature(s), or restore the " 4115 "pool from backup.\n")); 4116 break; 4117 4118 case ZPOOL_STATUS_FAULTED_DEV_R: 4119 (void) printf(gettext("status: One or more devices are " 4120 "faulted in response to persistent errors.\n\tSufficient " 4121 "replicas exist for the pool to continue functioning " 4122 "in a\n\tdegraded state.\n")); 4123 (void) printf(gettext("action: Replace the faulted device, " 4124 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 4125 break; 4126 4127 case ZPOOL_STATUS_FAULTED_DEV_NR: 4128 (void) printf(gettext("status: One or more devices are " 4129 "faulted in response to persistent errors. There are " 4130 "insufficient replicas for the pool to\n\tcontinue " 4131 "functioning.\n")); 4132 (void) printf(gettext("action: Destroy and re-create the pool " 4133 "from a backup source. Manually marking the device\n" 4134 "\trepaired using 'zpool clear' may allow some data " 4135 "to be recovered.\n")); 4136 break; 4137 4138 case ZPOOL_STATUS_IO_FAILURE_WAIT: 4139 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 4140 (void) printf(gettext("status: One or more devices are " 4141 "faulted in response to IO failures.\n")); 4142 (void) printf(gettext("action: Make sure the affected devices " 4143 "are connected, then run 'zpool clear'.\n")); 4144 break; 4145 4146 case ZPOOL_STATUS_BAD_LOG: 4147 (void) printf(gettext("status: An intent log record " 4148 "could not be read.\n" 4149 "\tWaiting for adminstrator intervention to fix the " 4150 "faulted pool.\n")); 4151 (void) printf(gettext("action: Either restore the affected " 4152 "device(s) and run 'zpool online',\n" 4153 "\tor ignore the intent log records by running " 4154 "'zpool clear'.\n")); 4155 break; 4156 4157 default: 4158 /* 4159 * The remaining errors can't actually be generated, yet. 4160 */ 4161 assert(reason == ZPOOL_STATUS_OK); 4162 } 4163 4164 if (msgid != NULL) 4165 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 4166 msgid); 4167 4168 if (config != NULL) { 4169 int namewidth; 4170 uint64_t nerr; 4171 nvlist_t **spares, **l2cache; 4172 uint_t nspares, nl2cache; 4173 pool_scan_stat_t *ps = NULL; 4174 4175 (void) nvlist_lookup_uint64_array(nvroot, 4176 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c); 4177 print_scan_status(ps); 4178 4179 namewidth = max_width(zhp, nvroot, 0, 0); 4180 if (namewidth < 10) 4181 namewidth = 10; 4182 4183 (void) printf(gettext("config:\n\n")); 4184 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 4185 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 4186 print_status_config(zhp, zpool_get_name(zhp), nvroot, 4187 namewidth, 0, B_FALSE); 4188 4189 if (num_logs(nvroot) > 0) 4190 print_logs(zhp, nvroot, namewidth, B_TRUE); 4191 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 4192 &l2cache, &nl2cache) == 0) 4193 print_l2cache(zhp, l2cache, nl2cache, namewidth); 4194 4195 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 4196 &spares, &nspares) == 0) 4197 print_spares(zhp, spares, nspares, namewidth); 4198 4199 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 4200 &nerr) == 0) { 4201 nvlist_t *nverrlist = NULL; 4202 4203 /* 4204 * If the approximate error count is small, get a 4205 * precise count by fetching the entire log and 4206 * uniquifying the results. 4207 */ 4208 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 4209 zpool_get_errlog(zhp, &nverrlist) == 0) { 4210 nvpair_t *elem; 4211 4212 elem = NULL; 4213 nerr = 0; 4214 while ((elem = nvlist_next_nvpair(nverrlist, 4215 elem)) != NULL) { 4216 nerr++; 4217 } 4218 } 4219 nvlist_free(nverrlist); 4220 4221 (void) printf("\n"); 4222 4223 if (nerr == 0) 4224 (void) printf(gettext("errors: No known data " 4225 "errors\n")); 4226 else if (!cbp->cb_verbose) 4227 (void) printf(gettext("errors: %llu data " 4228 "errors, use '-v' for a list\n"), 4229 (u_longlong_t)nerr); 4230 else 4231 print_error_log(zhp); 4232 } 4233 4234 if (cbp->cb_dedup_stats) 4235 print_dedup_stats(config); 4236 } else { 4237 (void) printf(gettext("config: The configuration cannot be " 4238 "determined.\n")); 4239 } 4240 4241 return (0); 4242 } 4243 4244 /* 4245 * zpool status [-vx] [-T d|u] [pool] ... [interval [count]] 4246 * 4247 * -v Display complete error logs 4248 * -x Display only pools with potential problems 4249 * -D Display dedup status (undocumented) 4250 * -T Display a timestamp in date(1) or Unix format 4251 * 4252 * Describes the health status of all pools or some subset. 4253 */ 4254 int 4255 zpool_do_status(int argc, char **argv) 4256 { 4257 int c; 4258 int ret; 4259 unsigned long interval = 0, count = 0; 4260 status_cbdata_t cb = { 0 }; 4261 4262 /* check options */ 4263 while ((c = getopt(argc, argv, "vxDT:")) != -1) { 4264 switch (c) { 4265 case 'v': 4266 cb.cb_verbose = B_TRUE; 4267 break; 4268 case 'x': 4269 cb.cb_explain = B_TRUE; 4270 break; 4271 case 'D': 4272 cb.cb_dedup_stats = B_TRUE; 4273 break; 4274 case 'T': 4275 get_timestamp_arg(*optarg); 4276 break; 4277 case '?': 4278 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4279 optopt); 4280 usage(B_FALSE); 4281 } 4282 } 4283 4284 argc -= optind; 4285 argv += optind; 4286 4287 get_interval_count(&argc, argv, &interval, &count); 4288 4289 if (argc == 0) 4290 cb.cb_allpools = B_TRUE; 4291 4292 cb.cb_first = B_TRUE; 4293 4294 for (;;) { 4295 if (timestamp_fmt != NODATE) 4296 print_timestamp(timestamp_fmt); 4297 4298 ret = for_each_pool(argc, argv, B_TRUE, NULL, 4299 status_callback, &cb); 4300 4301 if (argc == 0 && cb.cb_count == 0) 4302 (void) printf(gettext("no pools available\n")); 4303 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 4304 (void) printf(gettext("all pools are healthy\n")); 4305 4306 if (ret != 0) 4307 return (ret); 4308 4309 if (interval == 0) 4310 break; 4311 4312 if (count != 0 && --count == 0) 4313 break; 4314 4315 (void) sleep(interval); 4316 } 4317 4318 return (0); 4319 } 4320 4321 typedef struct upgrade_cbdata { 4322 int cb_first; 4323 int cb_argc; 4324 uint64_t cb_version; 4325 char **cb_argv; 4326 } upgrade_cbdata_t; 4327 4328 static int 4329 upgrade_version(zpool_handle_t *zhp, uint64_t version) 4330 { 4331 int ret; 4332 nvlist_t *config; 4333 uint64_t oldversion; 4334 4335 config = zpool_get_config(zhp, NULL); 4336 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4337 &oldversion) == 0); 4338 4339 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 4340 assert(oldversion < version); 4341 4342 ret = zpool_upgrade(zhp, version); 4343 if (ret != 0) 4344 return (ret); 4345 4346 if (version >= SPA_VERSION_FEATURES) { 4347 (void) printf(gettext("Successfully upgraded " 4348 "'%s' from version %llu to feature flags.\n"), 4349 zpool_get_name(zhp), oldversion); 4350 } else { 4351 (void) printf(gettext("Successfully upgraded " 4352 "'%s' from version %llu to version %llu.\n"), 4353 zpool_get_name(zhp), oldversion, version); 4354 } 4355 4356 return (0); 4357 } 4358 4359 static int 4360 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 4361 { 4362 int i, ret, count; 4363 boolean_t firstff = B_TRUE; 4364 nvlist_t *enabled = zpool_get_features(zhp); 4365 4366 count = 0; 4367 for (i = 0; i < SPA_FEATURES; i++) { 4368 const char *fname = spa_feature_table[i].fi_uname; 4369 const char *fguid = spa_feature_table[i].fi_guid; 4370 if (!nvlist_exists(enabled, fguid)) { 4371 char *propname; 4372 verify(-1 != asprintf(&propname, "feature@%s", fname)); 4373 ret = zpool_set_prop(zhp, propname, 4374 ZFS_FEATURE_ENABLED); 4375 if (ret != 0) { 4376 free(propname); 4377 return (ret); 4378 } 4379 count++; 4380 4381 if (firstff) { 4382 (void) printf(gettext("Enabled the " 4383 "following features on '%s':\n"), 4384 zpool_get_name(zhp)); 4385 firstff = B_FALSE; 4386 } 4387 (void) printf(gettext(" %s\n"), fname); 4388 free(propname); 4389 } 4390 } 4391 4392 if (countp != NULL) 4393 *countp = count; 4394 return (0); 4395 } 4396 4397 static int 4398 upgrade_cb(zpool_handle_t *zhp, void *arg) 4399 { 4400 upgrade_cbdata_t *cbp = arg; 4401 nvlist_t *config; 4402 uint64_t version; 4403 boolean_t printnl = B_FALSE; 4404 int ret; 4405 4406 config = zpool_get_config(zhp, NULL); 4407 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4408 &version) == 0); 4409 4410 assert(SPA_VERSION_IS_SUPPORTED(version)); 4411 4412 if (version < cbp->cb_version) { 4413 cbp->cb_first = B_FALSE; 4414 ret = upgrade_version(zhp, cbp->cb_version); 4415 if (ret != 0) 4416 return (ret); 4417 printnl = B_TRUE; 4418 4419 /* 4420 * If they did "zpool upgrade -a", then we could 4421 * be doing ioctls to different pools. We need 4422 * to log this history once to each pool, and bypass 4423 * the normal history logging that happens in main(). 4424 */ 4425 (void) zpool_log_history(g_zfs, history_str); 4426 log_history = B_FALSE; 4427 } 4428 4429 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 4430 int count; 4431 ret = upgrade_enable_all(zhp, &count); 4432 if (ret != 0) 4433 return (ret); 4434 4435 if (count > 0) { 4436 cbp->cb_first = B_FALSE; 4437 printnl = B_TRUE; 4438 } 4439 } 4440 4441 if (printnl) { 4442 (void) printf(gettext("\n")); 4443 } 4444 4445 return (0); 4446 } 4447 4448 static int 4449 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 4450 { 4451 upgrade_cbdata_t *cbp = arg; 4452 nvlist_t *config; 4453 uint64_t version; 4454 4455 config = zpool_get_config(zhp, NULL); 4456 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4457 &version) == 0); 4458 4459 assert(SPA_VERSION_IS_SUPPORTED(version)); 4460 4461 if (version < SPA_VERSION_FEATURES) { 4462 if (cbp->cb_first) { 4463 (void) printf(gettext("The following pools are " 4464 "formatted with legacy version numbers and can\n" 4465 "be upgraded to use feature flags. After " 4466 "being upgraded, these pools\nwill no " 4467 "longer be accessible by software that does not " 4468 "support feature\nflags.\n\n")); 4469 (void) printf(gettext("VER POOL\n")); 4470 (void) printf(gettext("--- ------------\n")); 4471 cbp->cb_first = B_FALSE; 4472 } 4473 4474 (void) printf("%2llu %s\n", (u_longlong_t)version, 4475 zpool_get_name(zhp)); 4476 } 4477 4478 return (0); 4479 } 4480 4481 static int 4482 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 4483 { 4484 upgrade_cbdata_t *cbp = arg; 4485 nvlist_t *config; 4486 uint64_t version; 4487 4488 config = zpool_get_config(zhp, NULL); 4489 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4490 &version) == 0); 4491 4492 if (version >= SPA_VERSION_FEATURES) { 4493 int i; 4494 boolean_t poolfirst = B_TRUE; 4495 nvlist_t *enabled = zpool_get_features(zhp); 4496 4497 for (i = 0; i < SPA_FEATURES; i++) { 4498 const char *fguid = spa_feature_table[i].fi_guid; 4499 const char *fname = spa_feature_table[i].fi_uname; 4500 if (!nvlist_exists(enabled, fguid)) { 4501 if (cbp->cb_first) { 4502 (void) printf(gettext("\nSome " 4503 "supported features are not " 4504 "enabled on the following pools. " 4505 "Once a\nfeature is enabled the " 4506 "pool may become incompatible with " 4507 "software\nthat does not support " 4508 "the feature. See " 4509 "zpool-features(5) for " 4510 "details.\n\n")); 4511 (void) printf(gettext("POOL " 4512 "FEATURE\n")); 4513 (void) printf(gettext("------" 4514 "---------\n")); 4515 cbp->cb_first = B_FALSE; 4516 } 4517 4518 if (poolfirst) { 4519 (void) printf(gettext("%s\n"), 4520 zpool_get_name(zhp)); 4521 poolfirst = B_FALSE; 4522 } 4523 4524 (void) printf(gettext(" %s\n"), fname); 4525 } 4526 } 4527 } 4528 4529 return (0); 4530 } 4531 4532 /* ARGSUSED */ 4533 static int 4534 upgrade_one(zpool_handle_t *zhp, void *data) 4535 { 4536 boolean_t printnl = B_FALSE; 4537 upgrade_cbdata_t *cbp = data; 4538 uint64_t cur_version; 4539 int ret; 4540 4541 if (strcmp("log", zpool_get_name(zhp)) == 0) { 4542 (void) printf(gettext("'log' is now a reserved word\n" 4543 "Pool 'log' must be renamed using export and import" 4544 " to upgrade.\n")); 4545 return (1); 4546 } 4547 4548 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 4549 if (cur_version > cbp->cb_version) { 4550 (void) printf(gettext("Pool '%s' is already formatted " 4551 "using more current version '%llu'.\n\n"), 4552 zpool_get_name(zhp), cur_version); 4553 return (0); 4554 } 4555 4556 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 4557 (void) printf(gettext("Pool '%s' is already formatted " 4558 "using version %llu.\n\n"), zpool_get_name(zhp), 4559 cbp->cb_version); 4560 return (0); 4561 } 4562 4563 if (cur_version != cbp->cb_version) { 4564 printnl = B_TRUE; 4565 ret = upgrade_version(zhp, cbp->cb_version); 4566 if (ret != 0) 4567 return (ret); 4568 } 4569 4570 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 4571 int count = 0; 4572 ret = upgrade_enable_all(zhp, &count); 4573 if (ret != 0) 4574 return (ret); 4575 4576 if (count != 0) { 4577 printnl = B_TRUE; 4578 } else if (cur_version == SPA_VERSION) { 4579 (void) printf(gettext("Pool '%s' already has all " 4580 "supported features enabled.\n"), 4581 zpool_get_name(zhp)); 4582 } 4583 } 4584 4585 if (printnl) { 4586 (void) printf(gettext("\n")); 4587 } 4588 4589 return (0); 4590 } 4591 4592 /* 4593 * zpool upgrade 4594 * zpool upgrade -v 4595 * zpool upgrade [-V version] <-a | pool ...> 4596 * 4597 * With no arguments, display downrev'd ZFS pool available for upgrade. 4598 * Individual pools can be upgraded by specifying the pool, and '-a' will 4599 * upgrade all pools. 4600 */ 4601 int 4602 zpool_do_upgrade(int argc, char **argv) 4603 { 4604 int c; 4605 upgrade_cbdata_t cb = { 0 }; 4606 int ret = 0; 4607 boolean_t showversions = B_FALSE; 4608 boolean_t upgradeall = B_FALSE; 4609 char *end; 4610 4611 4612 /* check options */ 4613 while ((c = getopt(argc, argv, ":avV:")) != -1) { 4614 switch (c) { 4615 case 'a': 4616 upgradeall = B_TRUE; 4617 break; 4618 case 'v': 4619 showversions = B_TRUE; 4620 break; 4621 case 'V': 4622 cb.cb_version = strtoll(optarg, &end, 10); 4623 if (*end != '\0' || 4624 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 4625 (void) fprintf(stderr, 4626 gettext("invalid version '%s'\n"), optarg); 4627 usage(B_FALSE); 4628 } 4629 break; 4630 case ':': 4631 (void) fprintf(stderr, gettext("missing argument for " 4632 "'%c' option\n"), optopt); 4633 usage(B_FALSE); 4634 break; 4635 case '?': 4636 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4637 optopt); 4638 usage(B_FALSE); 4639 } 4640 } 4641 4642 cb.cb_argc = argc; 4643 cb.cb_argv = argv; 4644 argc -= optind; 4645 argv += optind; 4646 4647 if (cb.cb_version == 0) { 4648 cb.cb_version = SPA_VERSION; 4649 } else if (!upgradeall && argc == 0) { 4650 (void) fprintf(stderr, gettext("-V option is " 4651 "incompatible with other arguments\n")); 4652 usage(B_FALSE); 4653 } 4654 4655 if (showversions) { 4656 if (upgradeall || argc != 0) { 4657 (void) fprintf(stderr, gettext("-v option is " 4658 "incompatible with other arguments\n")); 4659 usage(B_FALSE); 4660 } 4661 } else if (upgradeall) { 4662 if (argc != 0) { 4663 (void) fprintf(stderr, gettext("-a option should not " 4664 "be used along with a pool name\n")); 4665 usage(B_FALSE); 4666 } 4667 } 4668 4669 (void) printf(gettext("This system supports ZFS pool feature " 4670 "flags.\n\n")); 4671 if (showversions) { 4672 int i; 4673 4674 (void) printf(gettext("The following features are " 4675 "supported:\n\n")); 4676 (void) printf(gettext("FEAT DESCRIPTION\n")); 4677 (void) printf("----------------------------------------------" 4678 "---------------\n"); 4679 for (i = 0; i < SPA_FEATURES; i++) { 4680 zfeature_info_t *fi = &spa_feature_table[i]; 4681 const char *ro = fi->fi_can_readonly ? 4682 " (read-only compatible)" : ""; 4683 4684 (void) printf("%-37s%s\n", fi->fi_uname, ro); 4685 (void) printf(" %s\n", fi->fi_desc); 4686 } 4687 (void) printf("\n"); 4688 4689 (void) printf(gettext("The following legacy versions are also " 4690 "supported:\n\n")); 4691 (void) printf(gettext("VER DESCRIPTION\n")); 4692 (void) printf("--- -----------------------------------------" 4693 "---------------\n"); 4694 (void) printf(gettext(" 1 Initial ZFS version\n")); 4695 (void) printf(gettext(" 2 Ditto blocks " 4696 "(replicated metadata)\n")); 4697 (void) printf(gettext(" 3 Hot spares and double parity " 4698 "RAID-Z\n")); 4699 (void) printf(gettext(" 4 zpool history\n")); 4700 (void) printf(gettext(" 5 Compression using the gzip " 4701 "algorithm\n")); 4702 (void) printf(gettext(" 6 bootfs pool property\n")); 4703 (void) printf(gettext(" 7 Separate intent log devices\n")); 4704 (void) printf(gettext(" 8 Delegated administration\n")); 4705 (void) printf(gettext(" 9 refquota and refreservation " 4706 "properties\n")); 4707 (void) printf(gettext(" 10 Cache devices\n")); 4708 (void) printf(gettext(" 11 Improved scrub performance\n")); 4709 (void) printf(gettext(" 12 Snapshot properties\n")); 4710 (void) printf(gettext(" 13 snapused property\n")); 4711 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 4712 (void) printf(gettext(" 15 user/group space accounting\n")); 4713 (void) printf(gettext(" 16 stmf property support\n")); 4714 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 4715 (void) printf(gettext(" 18 Snapshot user holds\n")); 4716 (void) printf(gettext(" 19 Log device removal\n")); 4717 (void) printf(gettext(" 20 Compression using zle " 4718 "(zero-length encoding)\n")); 4719 (void) printf(gettext(" 21 Deduplication\n")); 4720 (void) printf(gettext(" 22 Received properties\n")); 4721 (void) printf(gettext(" 23 Slim ZIL\n")); 4722 (void) printf(gettext(" 24 System attributes\n")); 4723 (void) printf(gettext(" 25 Improved scrub stats\n")); 4724 (void) printf(gettext(" 26 Improved snapshot deletion " 4725 "performance\n")); 4726 (void) printf(gettext(" 27 Improved snapshot creation " 4727 "performance\n")); 4728 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 4729 (void) printf(gettext("\nFor more information on a particular " 4730 "version, including supported releases,\n")); 4731 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 4732 } else if (argc == 0 && upgradeall) { 4733 cb.cb_first = B_TRUE; 4734 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 4735 if (ret == 0 && cb.cb_first) { 4736 if (cb.cb_version == SPA_VERSION) { 4737 (void) printf(gettext("All pools are already " 4738 "formatted using feature flags.\n\n")); 4739 (void) printf(gettext("Every feature flags " 4740 "pool already has all supported features " 4741 "enabled.\n")); 4742 } else { 4743 (void) printf(gettext("All pools are already " 4744 "formatted with version %llu or higher.\n"), 4745 cb.cb_version); 4746 } 4747 } 4748 } else if (argc == 0) { 4749 cb.cb_first = B_TRUE; 4750 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 4751 assert(ret == 0); 4752 4753 if (cb.cb_first) { 4754 (void) printf(gettext("All pools are formatted " 4755 "using feature flags.\n\n")); 4756 } else { 4757 (void) printf(gettext("\nUse 'zpool upgrade -v' " 4758 "for a list of available legacy versions.\n")); 4759 } 4760 4761 cb.cb_first = B_TRUE; 4762 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 4763 assert(ret == 0); 4764 4765 if (cb.cb_first) { 4766 (void) printf(gettext("Every feature flags pool has " 4767 "all supported features enabled.\n")); 4768 } else { 4769 (void) printf(gettext("\n")); 4770 } 4771 } else { 4772 ret = for_each_pool(argc, argv, B_FALSE, NULL, 4773 upgrade_one, &cb); 4774 } 4775 4776 return (ret); 4777 } 4778 4779 typedef struct hist_cbdata { 4780 boolean_t first; 4781 boolean_t longfmt; 4782 boolean_t internal; 4783 } hist_cbdata_t; 4784 4785 /* 4786 * Print out the command history for a specific pool. 4787 */ 4788 static int 4789 get_history_one(zpool_handle_t *zhp, void *data) 4790 { 4791 nvlist_t *nvhis; 4792 nvlist_t **records; 4793 uint_t numrecords; 4794 int ret, i; 4795 hist_cbdata_t *cb = (hist_cbdata_t *)data; 4796 4797 cb->first = B_FALSE; 4798 4799 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 4800 4801 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 4802 return (ret); 4803 4804 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 4805 &records, &numrecords) == 0); 4806 for (i = 0; i < numrecords; i++) { 4807 nvlist_t *rec = records[i]; 4808 char tbuf[30] = ""; 4809 4810 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 4811 time_t tsec; 4812 struct tm t; 4813 4814 tsec = fnvlist_lookup_uint64(records[i], 4815 ZPOOL_HIST_TIME); 4816 (void) localtime_r(&tsec, &t); 4817 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 4818 } 4819 4820 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 4821 (void) printf("%s %s", tbuf, 4822 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 4823 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 4824 int ievent = 4825 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 4826 if (!cb->internal) 4827 continue; 4828 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 4829 (void) printf("%s unrecognized record:\n", 4830 tbuf); 4831 dump_nvlist(rec, 4); 4832 continue; 4833 } 4834 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 4835 zfs_history_event_names[ievent], 4836 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 4837 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 4838 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 4839 if (!cb->internal) 4840 continue; 4841 (void) printf("%s [txg:%lld] %s", tbuf, 4842 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 4843 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 4844 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 4845 (void) printf(" %s (%llu)", 4846 fnvlist_lookup_string(rec, 4847 ZPOOL_HIST_DSNAME), 4848 fnvlist_lookup_uint64(rec, 4849 ZPOOL_HIST_DSID)); 4850 } 4851 (void) printf(" %s", fnvlist_lookup_string(rec, 4852 ZPOOL_HIST_INT_STR)); 4853 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 4854 if (!cb->internal) 4855 continue; 4856 (void) printf("%s ioctl %s\n", tbuf, 4857 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 4858 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 4859 (void) printf(" input:\n"); 4860 dump_nvlist(fnvlist_lookup_nvlist(rec, 4861 ZPOOL_HIST_INPUT_NVL), 8); 4862 } 4863 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 4864 (void) printf(" output:\n"); 4865 dump_nvlist(fnvlist_lookup_nvlist(rec, 4866 ZPOOL_HIST_OUTPUT_NVL), 8); 4867 } 4868 } else { 4869 if (!cb->internal) 4870 continue; 4871 (void) printf("%s unrecognized record:\n", tbuf); 4872 dump_nvlist(rec, 4); 4873 } 4874 4875 if (!cb->longfmt) { 4876 (void) printf("\n"); 4877 continue; 4878 } 4879 (void) printf(" ["); 4880 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 4881 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 4882 struct passwd *pwd = getpwuid(who); 4883 (void) printf("user %d ", (int)who); 4884 if (pwd != NULL) 4885 (void) printf("(%s) ", pwd->pw_name); 4886 } 4887 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 4888 (void) printf("on %s", 4889 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 4890 } 4891 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 4892 (void) printf(":%s", 4893 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 4894 } 4895 (void) printf("]"); 4896 (void) printf("\n"); 4897 } 4898 (void) printf("\n"); 4899 nvlist_free(nvhis); 4900 4901 return (ret); 4902 } 4903 4904 /* 4905 * zpool history <pool> 4906 * 4907 * Displays the history of commands that modified pools. 4908 */ 4909 int 4910 zpool_do_history(int argc, char **argv) 4911 { 4912 hist_cbdata_t cbdata = { 0 }; 4913 int ret; 4914 int c; 4915 4916 cbdata.first = B_TRUE; 4917 /* check options */ 4918 while ((c = getopt(argc, argv, "li")) != -1) { 4919 switch (c) { 4920 case 'l': 4921 cbdata.longfmt = B_TRUE; 4922 break; 4923 case 'i': 4924 cbdata.internal = B_TRUE; 4925 break; 4926 case '?': 4927 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4928 optopt); 4929 usage(B_FALSE); 4930 } 4931 } 4932 argc -= optind; 4933 argv += optind; 4934 4935 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 4936 &cbdata); 4937 4938 if (argc == 0 && cbdata.first == B_TRUE) { 4939 (void) printf(gettext("no pools available\n")); 4940 return (0); 4941 } 4942 4943 return (ret); 4944 } 4945 4946 static int 4947 get_callback(zpool_handle_t *zhp, void *data) 4948 { 4949 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 4950 char value[MAXNAMELEN]; 4951 zprop_source_t srctype; 4952 zprop_list_t *pl; 4953 4954 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 4955 4956 /* 4957 * Skip the special fake placeholder. This will also skip 4958 * over the name property when 'all' is specified. 4959 */ 4960 if (pl->pl_prop == ZPOOL_PROP_NAME && 4961 pl == cbp->cb_proplist) 4962 continue; 4963 4964 if (pl->pl_prop == ZPROP_INVAL && 4965 (zpool_prop_feature(pl->pl_user_prop) || 4966 zpool_prop_unsupported(pl->pl_user_prop))) { 4967 srctype = ZPROP_SRC_LOCAL; 4968 4969 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 4970 value, sizeof (value)) == 0) { 4971 zprop_print_one_property(zpool_get_name(zhp), 4972 cbp, pl->pl_user_prop, value, srctype, 4973 NULL, NULL); 4974 } 4975 } else { 4976 if (zpool_get_prop(zhp, pl->pl_prop, value, 4977 sizeof (value), &srctype) != 0) 4978 continue; 4979 4980 zprop_print_one_property(zpool_get_name(zhp), cbp, 4981 zpool_prop_to_name(pl->pl_prop), value, srctype, 4982 NULL, NULL); 4983 } 4984 } 4985 return (0); 4986 } 4987 4988 int 4989 zpool_do_get(int argc, char **argv) 4990 { 4991 zprop_get_cbdata_t cb = { 0 }; 4992 zprop_list_t fake_name = { 0 }; 4993 int ret; 4994 4995 if (argc < 2) { 4996 (void) fprintf(stderr, gettext("missing property " 4997 "argument\n")); 4998 usage(B_FALSE); 4999 } 5000 5001 cb.cb_first = B_TRUE; 5002 cb.cb_sources = ZPROP_SRC_ALL; 5003 cb.cb_columns[0] = GET_COL_NAME; 5004 cb.cb_columns[1] = GET_COL_PROPERTY; 5005 cb.cb_columns[2] = GET_COL_VALUE; 5006 cb.cb_columns[3] = GET_COL_SOURCE; 5007 cb.cb_type = ZFS_TYPE_POOL; 5008 5009 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 5010 ZFS_TYPE_POOL) != 0) 5011 usage(B_FALSE); 5012 5013 if (cb.cb_proplist != NULL) { 5014 fake_name.pl_prop = ZPOOL_PROP_NAME; 5015 fake_name.pl_width = strlen(gettext("NAME")); 5016 fake_name.pl_next = cb.cb_proplist; 5017 cb.cb_proplist = &fake_name; 5018 } 5019 5020 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 5021 get_callback, &cb); 5022 5023 if (cb.cb_proplist == &fake_name) 5024 zprop_free_list(fake_name.pl_next); 5025 else 5026 zprop_free_list(cb.cb_proplist); 5027 5028 return (ret); 5029 } 5030 5031 typedef struct set_cbdata { 5032 char *cb_propname; 5033 char *cb_value; 5034 boolean_t cb_any_successful; 5035 } set_cbdata_t; 5036 5037 int 5038 set_callback(zpool_handle_t *zhp, void *data) 5039 { 5040 int error; 5041 set_cbdata_t *cb = (set_cbdata_t *)data; 5042 5043 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 5044 5045 if (!error) 5046 cb->cb_any_successful = B_TRUE; 5047 5048 return (error); 5049 } 5050 5051 int 5052 zpool_do_set(int argc, char **argv) 5053 { 5054 set_cbdata_t cb = { 0 }; 5055 int error; 5056 5057 if (argc > 1 && argv[1][0] == '-') { 5058 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5059 argv[1][1]); 5060 usage(B_FALSE); 5061 } 5062 5063 if (argc < 2) { 5064 (void) fprintf(stderr, gettext("missing property=value " 5065 "argument\n")); 5066 usage(B_FALSE); 5067 } 5068 5069 if (argc < 3) { 5070 (void) fprintf(stderr, gettext("missing pool name\n")); 5071 usage(B_FALSE); 5072 } 5073 5074 if (argc > 3) { 5075 (void) fprintf(stderr, gettext("too many pool names\n")); 5076 usage(B_FALSE); 5077 } 5078 5079 cb.cb_propname = argv[1]; 5080 cb.cb_value = strchr(cb.cb_propname, '='); 5081 if (cb.cb_value == NULL) { 5082 (void) fprintf(stderr, gettext("missing value in " 5083 "property=value argument\n")); 5084 usage(B_FALSE); 5085 } 5086 5087 *(cb.cb_value) = '\0'; 5088 cb.cb_value++; 5089 5090 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 5091 set_callback, &cb); 5092 5093 return (error); 5094 } 5095 5096 static int 5097 find_command_idx(char *command, int *idx) 5098 { 5099 int i; 5100 5101 for (i = 0; i < NCOMMAND; i++) { 5102 if (command_table[i].name == NULL) 5103 continue; 5104 5105 if (strcmp(command, command_table[i].name) == 0) { 5106 *idx = i; 5107 return (0); 5108 } 5109 } 5110 return (1); 5111 } 5112 5113 int 5114 main(int argc, char **argv) 5115 { 5116 int ret; 5117 int i; 5118 char *cmdname; 5119 5120 (void) setlocale(LC_ALL, ""); 5121 (void) textdomain(TEXT_DOMAIN); 5122 5123 if ((g_zfs = libzfs_init()) == NULL) { 5124 (void) fprintf(stderr, gettext("internal error: failed to " 5125 "initialize ZFS library\n")); 5126 return (1); 5127 } 5128 5129 libzfs_print_on_error(g_zfs, B_TRUE); 5130 5131 opterr = 0; 5132 5133 /* 5134 * Make sure the user has specified some command. 5135 */ 5136 if (argc < 2) { 5137 (void) fprintf(stderr, gettext("missing command\n")); 5138 usage(B_FALSE); 5139 } 5140 5141 cmdname = argv[1]; 5142 5143 /* 5144 * Special case '-?' 5145 */ 5146 if (strcmp(cmdname, "-?") == 0) 5147 usage(B_TRUE); 5148 5149 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 5150 5151 /* 5152 * Run the appropriate command. 5153 */ 5154 if (find_command_idx(cmdname, &i) == 0) { 5155 current_command = &command_table[i]; 5156 ret = command_table[i].func(argc - 1, argv + 1); 5157 } else if (strchr(cmdname, '=')) { 5158 verify(find_command_idx("set", &i) == 0); 5159 current_command = &command_table[i]; 5160 ret = command_table[i].func(argc, argv); 5161 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 5162 /* 5163 * 'freeze' is a vile debugging abomination, so we treat 5164 * it as such. 5165 */ 5166 char buf[16384]; 5167 int fd = open(ZFS_DEV, O_RDWR); 5168 (void) strcpy((void *)buf, argv[2]); 5169 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 5170 } else { 5171 (void) fprintf(stderr, gettext("unrecognized " 5172 "command '%s'\n"), cmdname); 5173 usage(B_FALSE); 5174 } 5175 5176 if (ret == 0 && log_history) 5177 (void) zpool_log_history(g_zfs, history_str); 5178 5179 libzfs_fini(g_zfs); 5180 5181 /* 5182 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 5183 * for the purposes of running ::findleaks. 5184 */ 5185 if (getenv("ZFS_ABORT") != NULL) { 5186 (void) printf("dumping core by request\n"); 5187 abort(); 5188 } 5189 5190 return (ret); 5191 }