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