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