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