1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2011, 2018 by Delphix. All rights reserved. 25 * Copyright (c) 2012 by Frederik Wessels. All rights reserved. 26 * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved. 27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>. 28 * Copyright 2016 Nexenta Systems, Inc. 29 * Copyright (c) 2017 Datto Inc. 30 * Copyright (c) 2017, Intel Corporation. 31 * Copyright 2019 Joyent, Inc. 32 */ 33 34 #include <assert.h> 35 #include <ctype.h> 36 #include <dirent.h> 37 #include <errno.h> 38 #include <fcntl.h> 39 #include <getopt.h> 40 #include <libgen.h> 41 #include <libintl.h> 42 #include <libuutil.h> 43 #include <locale.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <strings.h> 48 #include <unistd.h> 49 #include <priv.h> 50 #include <pwd.h> 51 #include <zone.h> 52 #include <zfs_prop.h> 53 #include <sys/fs/zfs.h> 54 #include <sys/stat.h> 55 #include <sys/debug.h> 56 57 #include <libzfs.h> 58 59 #include "zpool_util.h" 60 #include "zfs_comutil.h" 61 #include "zfeature_common.h" 62 63 #include "statcommon.h" 64 65 static int zpool_do_create(int, char **); 66 static int zpool_do_destroy(int, char **); 67 68 static int zpool_do_add(int, char **); 69 static int zpool_do_remove(int, char **); 70 static int zpool_do_labelclear(int, char **); 71 72 static int zpool_do_checkpoint(int, char **); 73 74 static int zpool_do_list(int, char **); 75 static int zpool_do_iostat(int, char **); 76 static int zpool_do_status(int, char **); 77 78 static int zpool_do_online(int, char **); 79 static int zpool_do_offline(int, char **); 80 static int zpool_do_clear(int, char **); 81 static int zpool_do_reopen(int, char **); 82 83 static int zpool_do_reguid(int, char **); 84 85 static int zpool_do_attach(int, char **); 86 static int zpool_do_detach(int, char **); 87 static int zpool_do_replace(int, char **); 88 static int zpool_do_split(int, char **); 89 90 static int zpool_do_initialize(int, char **); 91 static int zpool_do_scrub(int, char **); 92 93 static int zpool_do_import(int, char **); 94 static int zpool_do_export(int, char **); 95 96 static int zpool_do_upgrade(int, char **); 97 98 static int zpool_do_history(int, char **); 99 100 static int zpool_do_get(int, char **); 101 static int zpool_do_set(int, char **); 102 103 static int zpool_do_sync(int, char **); 104 105 /* 106 * These libumem hooks provide a reasonable set of defaults for the allocator's 107 * debugging facilities. 108 */ 109 110 #ifdef DEBUG 111 const char * 112 _umem_debug_init(void) 113 { 114 return ("default,verbose"); /* $UMEM_DEBUG setting */ 115 } 116 117 const char * 118 _umem_logging_init(void) 119 { 120 return ("fail,contents"); /* $UMEM_LOGGING setting */ 121 } 122 #endif 123 124 typedef enum { 125 HELP_ADD, 126 HELP_ATTACH, 127 HELP_CLEAR, 128 HELP_CREATE, 129 HELP_CHECKPOINT, 130 HELP_DESTROY, 131 HELP_DETACH, 132 HELP_EXPORT, 133 HELP_HISTORY, 134 HELP_IMPORT, 135 HELP_IOSTAT, 136 HELP_LABELCLEAR, 137 HELP_LIST, 138 HELP_OFFLINE, 139 HELP_ONLINE, 140 HELP_REPLACE, 141 HELP_REMOVE, 142 HELP_INITIALIZE, 143 HELP_SCRUB, 144 HELP_STATUS, 145 HELP_UPGRADE, 146 HELP_GET, 147 HELP_SET, 148 HELP_SPLIT, 149 HELP_SYNC, 150 HELP_REGUID, 151 HELP_REOPEN 152 } zpool_help_t; 153 154 155 typedef struct zpool_command { 156 const char *name; 157 int (*func)(int, char **); 158 zpool_help_t usage; 159 } zpool_command_t; 160 161 /* 162 * Master command table. Each ZFS command has a name, associated function, and 163 * usage message. The usage messages need to be internationalized, so we have 164 * to have a function to return the usage message based on a command index. 165 * 166 * These commands are organized according to how they are displayed in the usage 167 * message. An empty command (one with a NULL name) indicates an empty line in 168 * the generic usage message. 169 */ 170 static zpool_command_t command_table[] = { 171 { "create", zpool_do_create, HELP_CREATE }, 172 { "destroy", zpool_do_destroy, HELP_DESTROY }, 173 { NULL }, 174 { "add", zpool_do_add, HELP_ADD }, 175 { "remove", zpool_do_remove, HELP_REMOVE }, 176 { NULL }, 177 { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR }, 178 { NULL }, 179 { "checkpoint", zpool_do_checkpoint, HELP_CHECKPOINT }, 180 { NULL }, 181 { "list", zpool_do_list, HELP_LIST }, 182 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 183 { "status", zpool_do_status, HELP_STATUS }, 184 { NULL }, 185 { "online", zpool_do_online, HELP_ONLINE }, 186 { "offline", zpool_do_offline, HELP_OFFLINE }, 187 { "clear", zpool_do_clear, HELP_CLEAR }, 188 { "reopen", zpool_do_reopen, HELP_REOPEN }, 189 { NULL }, 190 { "attach", zpool_do_attach, HELP_ATTACH }, 191 { "detach", zpool_do_detach, HELP_DETACH }, 192 { "replace", zpool_do_replace, HELP_REPLACE }, 193 { "split", zpool_do_split, HELP_SPLIT }, 194 { NULL }, 195 { "initialize", zpool_do_initialize, HELP_INITIALIZE }, 196 { "scrub", zpool_do_scrub, HELP_SCRUB }, 197 { NULL }, 198 { "import", zpool_do_import, HELP_IMPORT }, 199 { "export", zpool_do_export, HELP_EXPORT }, 200 { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 201 { "reguid", zpool_do_reguid, HELP_REGUID }, 202 { NULL }, 203 { "history", zpool_do_history, HELP_HISTORY }, 204 { "get", zpool_do_get, HELP_GET }, 205 { "set", zpool_do_set, HELP_SET }, 206 { "sync", zpool_do_sync, HELP_SYNC }, 207 }; 208 209 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) 210 211 #define VDEV_ALLOC_CLASS_LOGS "logs" 212 213 static zpool_command_t *current_command; 214 static char history_str[HIS_MAX_RECORD_LEN]; 215 static boolean_t log_history = B_TRUE; 216 static uint_t timestamp_fmt = NODATE; 217 218 static const char * 219 get_usage(zpool_help_t idx) 220 { 221 switch (idx) { 222 case HELP_ADD: 223 return (gettext("\tadd [-fgLnP] <pool> <vdev> ...\n")); 224 case HELP_ATTACH: 225 return (gettext("\tattach [-f] <pool> <device> " 226 "<new-device>\n")); 227 case HELP_CLEAR: 228 return (gettext("\tclear [-nF] <pool> [device]\n")); 229 case HELP_CREATE: 230 return (gettext("\tcreate [-fnd] [-B] " 231 "[-o property=value] ... \n" 232 "\t [-O file-system-property=value] ...\n" 233 "\t [-m mountpoint] [-R root] [-t tempname] " 234 "<pool> <vdev> ...\n")); 235 case HELP_CHECKPOINT: 236 return (gettext("\tcheckpoint [--discard] <pool> ...\n")); 237 case HELP_DESTROY: 238 return (gettext("\tdestroy [-f] <pool>\n")); 239 case HELP_DETACH: 240 return (gettext("\tdetach <pool> <device>\n")); 241 case HELP_EXPORT: 242 return (gettext("\texport [-f] <pool> ...\n")); 243 case HELP_HISTORY: 244 return (gettext("\thistory [-il] [<pool>] ...\n")); 245 case HELP_IMPORT: 246 return (gettext("\timport [-d dir] [-D]\n" 247 "\timport [-o mntopts] [-o property=value] ... \n" 248 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] " 249 "[-R root] [-F [-n]] -a\n" 250 "\timport [-o mntopts] [-o property=value] ... \n" 251 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] " 252 "[-R root] [-F [-n]] [-t]\n" 253 "\t [--rewind-to-checkpoint] <pool | id> [newpool]\n")); 254 case HELP_IOSTAT: 255 return (gettext("\tiostat [-gLPv] [-T d|u] [pool] ... " 256 "[interval [count]]\n")); 257 case HELP_LABELCLEAR: 258 return (gettext("\tlabelclear [-f] <vdev>\n")); 259 case HELP_LIST: 260 return (gettext("\tlist [-gHLpPv] [-o property[,...]] " 261 "[-T d|u] [pool] ... [interval [count]]\n")); 262 case HELP_OFFLINE: 263 return (gettext("\toffline [-t] <pool> <device> ...\n")); 264 case HELP_ONLINE: 265 return (gettext("\tonline <pool> <device> ...\n")); 266 case HELP_REPLACE: 267 return (gettext("\treplace [-f] <pool> <device> " 268 "[new-device]\n")); 269 case HELP_REMOVE: 270 return (gettext("\tremove [-nps] <pool> <device> ...\n")); 271 case HELP_REOPEN: 272 return (gettext("\treopen <pool>\n")); 273 case HELP_INITIALIZE: 274 return (gettext("\tinitialize [-cs] <pool> [<device> ...]\n")); 275 case HELP_SCRUB: 276 return (gettext("\tscrub [-s | -p] <pool> ...\n")); 277 case HELP_STATUS: 278 return (gettext("\tstatus [-DgLPvx] [-T d|u] [pool] ... " 279 "[interval [count]]\n")); 280 case HELP_UPGRADE: 281 return (gettext("\tupgrade\n" 282 "\tupgrade -v\n" 283 "\tupgrade [-V version] <-a | pool ...>\n")); 284 case HELP_GET: 285 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] " 286 "<\"all\" | property[,...]> <pool> ...\n")); 287 case HELP_SET: 288 return (gettext("\tset <property=value> <pool> \n")); 289 case HELP_SPLIT: 290 return (gettext("\tsplit [-gLnP] [-R altroot] [-o mntopts]\n" 291 "\t [-o property=value] <pool> <newpool> " 292 "[<device> ...]\n")); 293 case HELP_REGUID: 294 return (gettext("\treguid <pool>\n")); 295 case HELP_SYNC: 296 return (gettext("\tsync [pool] ...\n")); 297 } 298 299 abort(); 300 /* NOTREACHED */ 301 } 302 303 304 /* 305 * Callback routine that will print out a pool property value. 306 */ 307 static int 308 print_prop_cb(int prop, void *cb) 309 { 310 FILE *fp = cb; 311 312 (void) fprintf(fp, "\t%-19s ", zpool_prop_to_name(prop)); 313 314 if (zpool_prop_readonly(prop)) 315 (void) fprintf(fp, " NO "); 316 else 317 (void) fprintf(fp, " YES "); 318 319 if (zpool_prop_values(prop) == NULL) 320 (void) fprintf(fp, "-\n"); 321 else 322 (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 323 324 return (ZPROP_CONT); 325 } 326 327 /* 328 * Display usage message. If we're inside a command, display only the usage for 329 * that command. Otherwise, iterate over the entire command table and display 330 * a complete usage message. 331 */ 332 void 333 usage(boolean_t requested) 334 { 335 FILE *fp = requested ? stdout : stderr; 336 337 if (current_command == NULL) { 338 int i; 339 340 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 341 (void) fprintf(fp, 342 gettext("where 'command' is one of the following:\n\n")); 343 344 for (i = 0; i < NCOMMAND; i++) { 345 if (command_table[i].name == NULL) 346 (void) fprintf(fp, "\n"); 347 else 348 (void) fprintf(fp, "%s", 349 get_usage(command_table[i].usage)); 350 } 351 } else { 352 (void) fprintf(fp, gettext("usage:\n")); 353 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 354 } 355 356 if (current_command != NULL && 357 ((strcmp(current_command->name, "set") == 0) || 358 (strcmp(current_command->name, "get") == 0) || 359 (strcmp(current_command->name, "list") == 0))) { 360 361 (void) fprintf(fp, 362 gettext("\nthe following properties are supported:\n")); 363 364 (void) fprintf(fp, "\n\t%-19s %s %s\n\n", 365 "PROPERTY", "EDIT", "VALUES"); 366 367 /* Iterate over all properties */ 368 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 369 ZFS_TYPE_POOL); 370 371 (void) fprintf(fp, "\t%-19s ", "feature@..."); 372 (void) fprintf(fp, "YES disabled | enabled | active\n"); 373 374 (void) fprintf(fp, gettext("\nThe feature@ properties must be " 375 "appended with a feature name.\nSee zpool-features(5).\n")); 376 } 377 378 /* 379 * See comments at end of main(). 380 */ 381 if (getenv("ZFS_ABORT") != NULL) { 382 (void) printf("dumping core by request\n"); 383 abort(); 384 } 385 386 exit(requested ? 0 : 2); 387 } 388 389 /* 390 * print a pool vdev config for dry runs 391 */ 392 static void 393 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 394 const char *match, int name_flags) 395 { 396 nvlist_t **child; 397 uint_t c, children; 398 char *vname; 399 boolean_t printed = B_FALSE; 400 401 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 402 &child, &children) != 0) { 403 if (name != NULL) 404 (void) printf("\t%*s%s\n", indent, "", name); 405 return; 406 } 407 408 for (c = 0; c < children; c++) { 409 uint64_t is_log = B_FALSE; 410 char *class = ""; 411 412 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 413 &is_log); 414 if (is_log) 415 class = VDEV_ALLOC_BIAS_LOG; 416 (void) nvlist_lookup_string(child[c], 417 ZPOOL_CONFIG_ALLOCATION_BIAS, &class); 418 if (strcmp(match, class) != 0) 419 continue; 420 421 if (!printed && name != NULL) { 422 (void) printf("\t%*s%s\n", indent, "", name); 423 printed = B_TRUE; 424 } 425 vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags); 426 print_vdev_tree(zhp, vname, child[c], indent + 2, "", 427 name_flags); 428 free(vname); 429 } 430 } 431 432 static boolean_t 433 prop_list_contains_feature(nvlist_t *proplist) 434 { 435 nvpair_t *nvp; 436 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp; 437 nvp = nvlist_next_nvpair(proplist, nvp)) { 438 if (zpool_prop_feature(nvpair_name(nvp))) 439 return (B_TRUE); 440 } 441 return (B_FALSE); 442 } 443 444 /* 445 * Add a property pair (name, string-value) into a property nvlist. 446 */ 447 static int 448 add_prop_list(const char *propname, char *propval, nvlist_t **props, 449 boolean_t poolprop) 450 { 451 zpool_prop_t prop = ZPOOL_PROP_INVAL; 452 zfs_prop_t fprop; 453 nvlist_t *proplist; 454 const char *normnm; 455 char *strval; 456 457 if (*props == NULL && 458 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 459 (void) fprintf(stderr, 460 gettext("internal error: out of memory\n")); 461 return (1); 462 } 463 464 proplist = *props; 465 466 if (poolprop) { 467 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION); 468 469 if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL && 470 !zpool_prop_feature(propname)) { 471 (void) fprintf(stderr, gettext("property '%s' is " 472 "not a valid pool property\n"), propname); 473 return (2); 474 } 475 476 /* 477 * feature@ properties and version should not be specified 478 * at the same time. 479 */ 480 if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) && 481 nvlist_exists(proplist, vname)) || 482 (prop == ZPOOL_PROP_VERSION && 483 prop_list_contains_feature(proplist))) { 484 (void) fprintf(stderr, gettext("'feature@' and " 485 "'version' properties cannot be specified " 486 "together\n")); 487 return (2); 488 } 489 490 491 if (zpool_prop_feature(propname)) 492 normnm = propname; 493 else 494 normnm = zpool_prop_to_name(prop); 495 } else { 496 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) { 497 normnm = zfs_prop_to_name(fprop); 498 } else { 499 normnm = propname; 500 } 501 } 502 503 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 && 504 prop != ZPOOL_PROP_CACHEFILE) { 505 (void) fprintf(stderr, gettext("property '%s' " 506 "specified multiple times\n"), propname); 507 return (2); 508 } 509 510 if (nvlist_add_string(proplist, normnm, propval) != 0) { 511 (void) fprintf(stderr, gettext("internal " 512 "error: out of memory\n")); 513 return (1); 514 } 515 516 return (0); 517 } 518 519 /* 520 * Set a default property pair (name, string-value) in a property nvlist 521 */ 522 static int 523 add_prop_list_default(const char *propname, char *propval, nvlist_t **props, 524 boolean_t poolprop) 525 { 526 char *pval; 527 528 if (nvlist_lookup_string(*props, propname, &pval) == 0) 529 return (0); 530 531 return (add_prop_list(propname, propval, props, poolprop)); 532 } 533 534 /* 535 * zpool add [-fgLnP] [-o property=value] <pool> <vdev> ... 536 * 537 * -f Force addition of devices, even if they appear in use 538 * -g Display guid for individual vdev name. 539 * -L Follow links when resolving vdev path name. 540 * -n Do not add the devices, but display the resulting layout if 541 * they were to be added. 542 * -P Display full path for vdev name. 543 * 544 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 545 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to 546 * libzfs. 547 */ 548 int 549 zpool_do_add(int argc, char **argv) 550 { 551 boolean_t force = B_FALSE; 552 boolean_t dryrun = B_FALSE; 553 int name_flags = 0; 554 int c; 555 nvlist_t *nvroot; 556 char *poolname; 557 zpool_boot_label_t boot_type; 558 uint64_t boot_size; 559 int ret; 560 zpool_handle_t *zhp; 561 nvlist_t *config; 562 563 /* check options */ 564 while ((c = getopt(argc, argv, "fgLnP")) != -1) { 565 switch (c) { 566 case 'f': 567 force = B_TRUE; 568 break; 569 case 'g': 570 name_flags |= VDEV_NAME_GUID; 571 break; 572 case 'L': 573 name_flags |= VDEV_NAME_FOLLOW_LINKS; 574 break; 575 case 'n': 576 dryrun = B_TRUE; 577 break; 578 case 'P': 579 name_flags |= VDEV_NAME_PATH; 580 break; 581 case '?': 582 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 583 optopt); 584 usage(B_FALSE); 585 } 586 } 587 588 argc -= optind; 589 argv += optind; 590 591 /* get pool name and check number of arguments */ 592 if (argc < 1) { 593 (void) fprintf(stderr, gettext("missing pool name argument\n")); 594 usage(B_FALSE); 595 } 596 if (argc < 2) { 597 (void) fprintf(stderr, gettext("missing vdev specification\n")); 598 usage(B_FALSE); 599 } 600 601 poolname = argv[0]; 602 603 argc--; 604 argv++; 605 606 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 607 return (1); 608 609 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 610 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 611 poolname); 612 zpool_close(zhp); 613 return (1); 614 } 615 616 if (zpool_is_bootable(zhp)) 617 boot_type = ZPOOL_COPY_BOOT_LABEL; 618 else 619 boot_type = ZPOOL_NO_BOOT_LABEL; 620 621 /* pass off to get_vdev_spec for processing */ 622 boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL); 623 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun, 624 boot_type, boot_size, argc, argv); 625 if (nvroot == NULL) { 626 zpool_close(zhp); 627 return (1); 628 } 629 630 if (dryrun) { 631 nvlist_t *poolnvroot; 632 633 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 634 &poolnvroot) == 0); 635 636 (void) printf(gettext("would update '%s' to the following " 637 "configuration:\n"), zpool_get_name(zhp)); 638 639 /* print original main pool and new tree */ 640 print_vdev_tree(zhp, poolname, poolnvroot, 0, "", 641 name_flags | VDEV_NAME_TYPE_ID); 642 print_vdev_tree(zhp, NULL, nvroot, 0, "", name_flags); 643 644 /* print other classes: 'dedup', 'special', and 'log' */ 645 print_vdev_tree(zhp, "dedup", poolnvroot, 0, 646 VDEV_ALLOC_BIAS_DEDUP, name_flags); 647 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_DEDUP, 648 name_flags); 649 650 print_vdev_tree(zhp, "special", poolnvroot, 0, 651 VDEV_ALLOC_BIAS_SPECIAL, name_flags); 652 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_SPECIAL, 653 name_flags); 654 655 print_vdev_tree(zhp, "logs", poolnvroot, 0, VDEV_ALLOC_BIAS_LOG, 656 name_flags); 657 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_LOG, 658 name_flags); 659 660 ret = 0; 661 } else { 662 ret = (zpool_add(zhp, nvroot) != 0); 663 } 664 665 nvlist_free(nvroot); 666 zpool_close(zhp); 667 668 return (ret); 669 } 670 671 /* 672 * zpool remove <pool> <vdev> ... 673 * 674 * Removes the given vdev from the pool. 675 */ 676 int 677 zpool_do_remove(int argc, char **argv) 678 { 679 char *poolname; 680 int i, ret = 0; 681 zpool_handle_t *zhp; 682 boolean_t stop = B_FALSE; 683 boolean_t noop = B_FALSE; 684 boolean_t parsable = B_FALSE; 685 char c; 686 687 /* check options */ 688 while ((c = getopt(argc, argv, "nps")) != -1) { 689 switch (c) { 690 case 'n': 691 noop = B_TRUE; 692 break; 693 case 'p': 694 parsable = B_TRUE; 695 break; 696 case 's': 697 stop = B_TRUE; 698 break; 699 case '?': 700 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 701 optopt); 702 usage(B_FALSE); 703 } 704 } 705 706 argc -= optind; 707 argv += optind; 708 709 /* get pool name and check number of arguments */ 710 if (argc < 1) { 711 (void) fprintf(stderr, gettext("missing pool name argument\n")); 712 usage(B_FALSE); 713 } 714 715 poolname = argv[0]; 716 717 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 718 return (1); 719 720 if (stop && noop) { 721 (void) fprintf(stderr, gettext("stop request ignored\n")); 722 return (0); 723 } 724 725 if (stop) { 726 if (argc > 1) { 727 (void) fprintf(stderr, gettext("too many arguments\n")); 728 usage(B_FALSE); 729 } 730 if (zpool_vdev_remove_cancel(zhp) != 0) 731 ret = 1; 732 } else { 733 if (argc < 2) { 734 (void) fprintf(stderr, gettext("missing device\n")); 735 usage(B_FALSE); 736 } 737 738 for (i = 1; i < argc; i++) { 739 if (noop) { 740 uint64_t size; 741 742 if (zpool_vdev_indirect_size(zhp, argv[i], 743 &size) != 0) { 744 ret = 1; 745 break; 746 } 747 if (parsable) { 748 (void) printf("%s %llu\n", 749 argv[i], size); 750 } else { 751 char valstr[32]; 752 zfs_nicenum(size, valstr, 753 sizeof (valstr)); 754 (void) printf("Memory that will be " 755 "used after removing %s: %s\n", 756 argv[i], valstr); 757 } 758 } else { 759 if (zpool_vdev_remove(zhp, argv[i]) != 0) 760 ret = 1; 761 } 762 } 763 } 764 765 return (ret); 766 } 767 768 /* 769 * zpool labelclear [-f] <vdev> 770 * 771 * -f Force clearing the label for the vdevs which are members of 772 * the exported or foreign pools. 773 * 774 * Verifies that the vdev is not active and zeros out the label information 775 * on the device. 776 */ 777 int 778 zpool_do_labelclear(int argc, char **argv) 779 { 780 char vdev[MAXPATHLEN]; 781 char *name = NULL; 782 struct stat st; 783 int c, fd, ret = 0; 784 nvlist_t *config; 785 pool_state_t state; 786 boolean_t inuse = B_FALSE; 787 boolean_t force = B_FALSE; 788 789 /* check options */ 790 while ((c = getopt(argc, argv, "f")) != -1) { 791 switch (c) { 792 case 'f': 793 force = B_TRUE; 794 break; 795 default: 796 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 797 optopt); 798 usage(B_FALSE); 799 } 800 } 801 802 argc -= optind; 803 argv += optind; 804 805 /* get vdev name */ 806 if (argc < 1) { 807 (void) fprintf(stderr, gettext("missing vdev name\n")); 808 usage(B_FALSE); 809 } 810 if (argc > 1) { 811 (void) fprintf(stderr, gettext("too many arguments\n")); 812 usage(B_FALSE); 813 } 814 815 /* 816 * Check if we were given absolute path and use it as is. 817 * Otherwise if the provided vdev name doesn't point to a file, 818 * try prepending dsk path and appending s0. 819 */ 820 (void) strlcpy(vdev, argv[0], sizeof (vdev)); 821 if (vdev[0] != '/' && stat(vdev, &st) != 0) { 822 char *s; 823 824 (void) snprintf(vdev, sizeof (vdev), "%s/%s", 825 ZFS_DISK_ROOT, argv[0]); 826 if ((s = strrchr(argv[0], 's')) == NULL || 827 !isdigit(*(s + 1))) 828 (void) strlcat(vdev, "s0", sizeof (vdev)); 829 if (stat(vdev, &st) != 0) { 830 (void) fprintf(stderr, gettext( 831 "failed to find device %s, try specifying absolute " 832 "path instead\n"), argv[0]); 833 return (1); 834 } 835 } 836 837 if ((fd = open(vdev, O_RDWR)) < 0) { 838 (void) fprintf(stderr, gettext("failed to open %s: %s\n"), 839 vdev, strerror(errno)); 840 return (1); 841 } 842 843 if (zpool_read_label(fd, &config) != 0) { 844 (void) fprintf(stderr, 845 gettext("failed to read label from %s\n"), vdev); 846 return (1); 847 } 848 nvlist_free(config); 849 850 ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse); 851 if (ret != 0) { 852 (void) fprintf(stderr, 853 gettext("failed to check state for %s\n"), vdev); 854 return (1); 855 } 856 857 if (!inuse) 858 goto wipe_label; 859 860 switch (state) { 861 default: 862 case POOL_STATE_ACTIVE: 863 case POOL_STATE_SPARE: 864 case POOL_STATE_L2CACHE: 865 (void) fprintf(stderr, gettext( 866 "%s is a member (%s) of pool \"%s\"\n"), 867 vdev, zpool_pool_state_to_name(state), name); 868 ret = 1; 869 goto errout; 870 871 case POOL_STATE_EXPORTED: 872 if (force) 873 break; 874 (void) fprintf(stderr, gettext( 875 "use '-f' to override the following error:\n" 876 "%s is a member of exported pool \"%s\"\n"), 877 vdev, name); 878 ret = 1; 879 goto errout; 880 881 case POOL_STATE_POTENTIALLY_ACTIVE: 882 if (force) 883 break; 884 (void) fprintf(stderr, gettext( 885 "use '-f' to override the following error:\n" 886 "%s is a member of potentially active pool \"%s\"\n"), 887 vdev, name); 888 ret = 1; 889 goto errout; 890 891 case POOL_STATE_DESTROYED: 892 /* inuse should never be set for a destroyed pool */ 893 assert(0); 894 break; 895 } 896 897 wipe_label: 898 ret = zpool_clear_label(fd); 899 if (ret != 0) { 900 (void) fprintf(stderr, 901 gettext("failed to clear label for %s\n"), vdev); 902 } 903 904 errout: 905 free(name); 906 (void) close(fd); 907 908 return (ret); 909 } 910 911 /* 912 * zpool create [-fnd] [-B] [-o property=value] ... 913 * [-O file-system-property=value] ... 914 * [-R root] [-m mountpoint] [-t tempname] <pool> <dev> ... 915 * 916 * -B Create boot partition. 917 * -f Force creation, even if devices appear in use 918 * -n Do not create the pool, but display the resulting layout if it 919 * were to be created. 920 * -R Create a pool under an alternate root 921 * -m Set default mountpoint for the root dataset. By default it's 922 * '/<pool>' 923 * -t Use the temporary name until the pool is exported. 924 * -o Set property=value. 925 * -d Don't automatically enable all supported pool features 926 * (individual features can be enabled with -o). 927 * -O Set fsproperty=value in the pool's root file system 928 * 929 * Creates the named pool according to the given vdev specification. The 930 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once 931 * we get the nvlist back from get_vdev_spec(), we either print out the contents 932 * (if '-n' was specified), or pass it to libzfs to do the creation. 933 */ 934 935 #define SYSTEM256 (256 * 1024 * 1024) 936 int 937 zpool_do_create(int argc, char **argv) 938 { 939 boolean_t force = B_FALSE; 940 boolean_t dryrun = B_FALSE; 941 boolean_t enable_all_pool_feat = B_TRUE; 942 zpool_boot_label_t boot_type = ZPOOL_NO_BOOT_LABEL; 943 uint64_t boot_size = 0; 944 int c; 945 nvlist_t *nvroot = NULL; 946 char *poolname; 947 char *tname = NULL; 948 int ret = 1; 949 char *altroot = NULL; 950 char *mountpoint = NULL; 951 nvlist_t *fsprops = NULL; 952 nvlist_t *props = NULL; 953 char *propval; 954 955 /* check options */ 956 while ((c = getopt(argc, argv, ":fndBR:m:o:O:t:")) != -1) { 957 switch (c) { 958 case 'f': 959 force = B_TRUE; 960 break; 961 case 'n': 962 dryrun = B_TRUE; 963 break; 964 case 'd': 965 enable_all_pool_feat = B_FALSE; 966 break; 967 case 'B': 968 /* 969 * We should create the system partition. 970 * Also make sure the size is set. 971 */ 972 boot_type = ZPOOL_CREATE_BOOT_LABEL; 973 if (boot_size == 0) 974 boot_size = SYSTEM256; 975 break; 976 case 'R': 977 altroot = optarg; 978 if (add_prop_list(zpool_prop_to_name( 979 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 980 goto errout; 981 if (add_prop_list_default(zpool_prop_to_name( 982 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 983 goto errout; 984 break; 985 case 'm': 986 /* Equivalent to -O mountpoint=optarg */ 987 mountpoint = optarg; 988 break; 989 case 'o': 990 if ((propval = strchr(optarg, '=')) == NULL) { 991 (void) fprintf(stderr, gettext("missing " 992 "'=' for -o option\n")); 993 goto errout; 994 } 995 *propval = '\0'; 996 propval++; 997 998 if (add_prop_list(optarg, propval, &props, B_TRUE)) 999 goto errout; 1000 1001 /* 1002 * Get bootsize value for make_root_vdev(). 1003 */ 1004 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_BOOTSIZE) { 1005 if (zfs_nicestrtonum(g_zfs, propval, 1006 &boot_size) < 0 || boot_size == 0) { 1007 (void) fprintf(stderr, 1008 gettext("bad boot partition size " 1009 "'%s': %s\n"), propval, 1010 libzfs_error_description(g_zfs)); 1011 goto errout; 1012 } 1013 } 1014 1015 /* 1016 * If the user is creating a pool that doesn't support 1017 * feature flags, don't enable any features. 1018 */ 1019 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) { 1020 char *end; 1021 u_longlong_t ver; 1022 1023 ver = strtoull(propval, &end, 10); 1024 if (*end == '\0' && 1025 ver < SPA_VERSION_FEATURES) { 1026 enable_all_pool_feat = B_FALSE; 1027 } 1028 } 1029 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT) 1030 altroot = propval; 1031 break; 1032 case 'O': 1033 if ((propval = strchr(optarg, '=')) == NULL) { 1034 (void) fprintf(stderr, gettext("missing " 1035 "'=' for -O option\n")); 1036 goto errout; 1037 } 1038 *propval = '\0'; 1039 propval++; 1040 1041 /* 1042 * Mountpoints are checked and then added later. 1043 * Uniquely among properties, they can be specified 1044 * more than once, to avoid conflict with -m. 1045 */ 1046 if (0 == strcmp(optarg, 1047 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) { 1048 mountpoint = propval; 1049 } else if (add_prop_list(optarg, propval, &fsprops, 1050 B_FALSE)) { 1051 goto errout; 1052 } 1053 break; 1054 case 't': 1055 /* 1056 * Sanity check temporary pool name. 1057 */ 1058 if (strchr(optarg, '/') != NULL) { 1059 (void) fprintf(stderr, gettext("cannot create " 1060 "'%s': invalid character '/' in temporary " 1061 "name\n"), optarg); 1062 (void) fprintf(stderr, gettext("use 'zfs " 1063 "create' to create a dataset\n")); 1064 goto errout; 1065 } 1066 1067 if (add_prop_list(zpool_prop_to_name( 1068 ZPOOL_PROP_TNAME), optarg, &props, B_TRUE)) 1069 goto errout; 1070 if (add_prop_list_default(zpool_prop_to_name( 1071 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1072 goto errout; 1073 tname = optarg; 1074 break; 1075 case ':': 1076 (void) fprintf(stderr, gettext("missing argument for " 1077 "'%c' option\n"), optopt); 1078 goto badusage; 1079 case '?': 1080 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1081 optopt); 1082 goto badusage; 1083 } 1084 } 1085 1086 argc -= optind; 1087 argv += optind; 1088 1089 /* get pool name and check number of arguments */ 1090 if (argc < 1) { 1091 (void) fprintf(stderr, gettext("missing pool name argument\n")); 1092 goto badusage; 1093 } 1094 if (argc < 2) { 1095 (void) fprintf(stderr, gettext("missing vdev specification\n")); 1096 goto badusage; 1097 } 1098 1099 poolname = argv[0]; 1100 1101 /* 1102 * As a special case, check for use of '/' in the name, and direct the 1103 * user to use 'zfs create' instead. 1104 */ 1105 if (strchr(poolname, '/') != NULL) { 1106 (void) fprintf(stderr, gettext("cannot create '%s': invalid " 1107 "character '/' in pool name\n"), poolname); 1108 (void) fprintf(stderr, gettext("use 'zfs create' to " 1109 "create a dataset\n")); 1110 goto errout; 1111 } 1112 1113 /* 1114 * Make sure the bootsize is set when ZPOOL_CREATE_BOOT_LABEL is used, 1115 * and not set otherwise. 1116 */ 1117 if (boot_type == ZPOOL_CREATE_BOOT_LABEL) { 1118 const char *propname; 1119 char *strptr, *buf = NULL; 1120 int rv; 1121 1122 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE); 1123 if (nvlist_lookup_string(props, propname, &strptr) != 0) { 1124 (void) asprintf(&buf, "%" PRIu64, boot_size); 1125 if (buf == NULL) { 1126 (void) fprintf(stderr, 1127 gettext("internal error: out of memory\n")); 1128 goto errout; 1129 } 1130 rv = add_prop_list(propname, buf, &props, B_TRUE); 1131 free(buf); 1132 if (rv != 0) 1133 goto errout; 1134 } 1135 } else { 1136 const char *propname; 1137 char *strptr; 1138 1139 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE); 1140 if (nvlist_lookup_string(props, propname, &strptr) == 0) { 1141 (void) fprintf(stderr, gettext("error: setting boot " 1142 "partition size requires option '-B'\n")); 1143 goto errout; 1144 } 1145 } 1146 1147 /* pass off to get_vdev_spec for bulk processing */ 1148 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun, 1149 boot_type, boot_size, argc - 1, argv + 1); 1150 if (nvroot == NULL) 1151 goto errout; 1152 1153 /* make_root_vdev() allows 0 toplevel children if there are spares */ 1154 if (!zfs_allocatable_devs(nvroot)) { 1155 (void) fprintf(stderr, gettext("invalid vdev " 1156 "specification: at least one toplevel vdev must be " 1157 "specified\n")); 1158 goto errout; 1159 } 1160 1161 if (altroot != NULL && altroot[0] != '/') { 1162 (void) fprintf(stderr, gettext("invalid alternate root '%s': " 1163 "must be an absolute path\n"), altroot); 1164 goto errout; 1165 } 1166 1167 /* 1168 * Check the validity of the mountpoint and direct the user to use the 1169 * '-m' mountpoint option if it looks like its in use. 1170 */ 1171 if (mountpoint == NULL || 1172 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && 1173 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { 1174 char buf[MAXPATHLEN]; 1175 DIR *dirp; 1176 1177 if (mountpoint && mountpoint[0] != '/') { 1178 (void) fprintf(stderr, gettext("invalid mountpoint " 1179 "'%s': must be an absolute path, 'legacy', or " 1180 "'none'\n"), mountpoint); 1181 goto errout; 1182 } 1183 1184 if (mountpoint == NULL) { 1185 if (altroot != NULL) 1186 (void) snprintf(buf, sizeof (buf), "%s/%s", 1187 altroot, poolname); 1188 else 1189 (void) snprintf(buf, sizeof (buf), "/%s", 1190 poolname); 1191 } else { 1192 if (altroot != NULL) 1193 (void) snprintf(buf, sizeof (buf), "%s%s", 1194 altroot, mountpoint); 1195 else 1196 (void) snprintf(buf, sizeof (buf), "%s", 1197 mountpoint); 1198 } 1199 1200 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { 1201 (void) fprintf(stderr, gettext("mountpoint '%s' : " 1202 "%s\n"), buf, strerror(errno)); 1203 (void) fprintf(stderr, gettext("use '-m' " 1204 "option to provide a different default\n")); 1205 goto errout; 1206 } else if (dirp) { 1207 int count = 0; 1208 1209 while (count < 3 && readdir(dirp) != NULL) 1210 count++; 1211 (void) closedir(dirp); 1212 1213 if (count > 2) { 1214 (void) fprintf(stderr, gettext("mountpoint " 1215 "'%s' exists and is not empty\n"), buf); 1216 (void) fprintf(stderr, gettext("use '-m' " 1217 "option to provide a " 1218 "different default\n")); 1219 goto errout; 1220 } 1221 } 1222 } 1223 1224 /* 1225 * Now that the mountpoint's validity has been checked, ensure that 1226 * the property is set appropriately prior to creating the pool. 1227 */ 1228 if (mountpoint != NULL) { 1229 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1230 mountpoint, &fsprops, B_FALSE); 1231 if (ret != 0) 1232 goto errout; 1233 } 1234 1235 ret = 1; 1236 if (dryrun) { 1237 /* 1238 * For a dry run invocation, print out a basic message and run 1239 * through all the vdevs in the list and print out in an 1240 * appropriate hierarchy. 1241 */ 1242 (void) printf(gettext("would create '%s' with the " 1243 "following layout:\n\n"), poolname); 1244 1245 print_vdev_tree(NULL, poolname, nvroot, 0, "", 0); 1246 print_vdev_tree(NULL, "dedup", nvroot, 0, 1247 VDEV_ALLOC_BIAS_DEDUP, 0); 1248 print_vdev_tree(NULL, "special", nvroot, 0, 1249 VDEV_ALLOC_BIAS_SPECIAL, 0); 1250 print_vdev_tree(NULL, "logs", nvroot, 0, 1251 VDEV_ALLOC_BIAS_LOG, 0); 1252 1253 ret = 0; 1254 } else { 1255 /* 1256 * Hand off to libzfs. 1257 */ 1258 if (enable_all_pool_feat) { 1259 spa_feature_t i; 1260 for (i = 0; i < SPA_FEATURES; i++) { 1261 char propname[MAXPATHLEN]; 1262 zfeature_info_t *feat = &spa_feature_table[i]; 1263 1264 (void) snprintf(propname, sizeof (propname), 1265 "feature@%s", feat->fi_uname); 1266 1267 /* 1268 * Skip feature if user specified it manually 1269 * on the command line. 1270 */ 1271 if (nvlist_exists(props, propname)) 1272 continue; 1273 1274 ret = add_prop_list(propname, 1275 ZFS_FEATURE_ENABLED, &props, B_TRUE); 1276 if (ret != 0) 1277 goto errout; 1278 } 1279 } 1280 1281 ret = 1; 1282 if (zpool_create(g_zfs, poolname, 1283 nvroot, props, fsprops) == 0) { 1284 zfs_handle_t *pool = zfs_open(g_zfs, 1285 tname ? tname : poolname, ZFS_TYPE_FILESYSTEM); 1286 if (pool != NULL) { 1287 if (zfs_mount(pool, NULL, 0) == 0) 1288 ret = zfs_shareall(pool); 1289 zfs_close(pool); 1290 } 1291 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { 1292 (void) fprintf(stderr, gettext("pool name may have " 1293 "been omitted\n")); 1294 } 1295 } 1296 1297 errout: 1298 nvlist_free(nvroot); 1299 nvlist_free(fsprops); 1300 nvlist_free(props); 1301 return (ret); 1302 badusage: 1303 nvlist_free(fsprops); 1304 nvlist_free(props); 1305 usage(B_FALSE); 1306 return (2); 1307 } 1308 1309 /* 1310 * zpool destroy <pool> 1311 * 1312 * -f Forcefully unmount any datasets 1313 * 1314 * Destroy the given pool. Automatically unmounts any datasets in the pool. 1315 */ 1316 int 1317 zpool_do_destroy(int argc, char **argv) 1318 { 1319 boolean_t force = B_FALSE; 1320 int c; 1321 char *pool; 1322 zpool_handle_t *zhp; 1323 int ret; 1324 1325 /* check options */ 1326 while ((c = getopt(argc, argv, "f")) != -1) { 1327 switch (c) { 1328 case 'f': 1329 force = B_TRUE; 1330 break; 1331 case '?': 1332 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1333 optopt); 1334 usage(B_FALSE); 1335 } 1336 } 1337 1338 argc -= optind; 1339 argv += optind; 1340 1341 /* check arguments */ 1342 if (argc < 1) { 1343 (void) fprintf(stderr, gettext("missing pool argument\n")); 1344 usage(B_FALSE); 1345 } 1346 if (argc > 1) { 1347 (void) fprintf(stderr, gettext("too many arguments\n")); 1348 usage(B_FALSE); 1349 } 1350 1351 pool = argv[0]; 1352 1353 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 1354 /* 1355 * As a special case, check for use of '/' in the name, and 1356 * direct the user to use 'zfs destroy' instead. 1357 */ 1358 if (strchr(pool, '/') != NULL) 1359 (void) fprintf(stderr, gettext("use 'zfs destroy' to " 1360 "destroy a dataset\n")); 1361 return (1); 1362 } 1363 1364 if (zpool_disable_datasets(zhp, force) != 0) { 1365 (void) fprintf(stderr, gettext("could not destroy '%s': " 1366 "could not unmount datasets\n"), zpool_get_name(zhp)); 1367 return (1); 1368 } 1369 1370 /* The history must be logged as part of the export */ 1371 log_history = B_FALSE; 1372 1373 ret = (zpool_destroy(zhp, history_str) != 0); 1374 1375 zpool_close(zhp); 1376 1377 return (ret); 1378 } 1379 1380 /* 1381 * zpool export [-f] <pool> ... 1382 * 1383 * -f Forcefully unmount datasets 1384 * 1385 * Export the given pools. By default, the command will attempt to cleanly 1386 * unmount any active datasets within the pool. If the '-f' flag is specified, 1387 * then the datasets will be forcefully unmounted. 1388 */ 1389 int 1390 zpool_do_export(int argc, char **argv) 1391 { 1392 boolean_t force = B_FALSE; 1393 boolean_t hardforce = B_FALSE; 1394 int c; 1395 zpool_handle_t *zhp; 1396 int ret; 1397 int i; 1398 1399 /* check options */ 1400 while ((c = getopt(argc, argv, "fF")) != -1) { 1401 switch (c) { 1402 case 'f': 1403 force = B_TRUE; 1404 break; 1405 case 'F': 1406 hardforce = B_TRUE; 1407 break; 1408 case '?': 1409 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1410 optopt); 1411 usage(B_FALSE); 1412 } 1413 } 1414 1415 argc -= optind; 1416 argv += optind; 1417 1418 /* check arguments */ 1419 if (argc < 1) { 1420 (void) fprintf(stderr, gettext("missing pool argument\n")); 1421 usage(B_FALSE); 1422 } 1423 1424 ret = 0; 1425 for (i = 0; i < argc; i++) { 1426 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) { 1427 ret = 1; 1428 continue; 1429 } 1430 1431 if (zpool_disable_datasets(zhp, force) != 0) { 1432 ret = 1; 1433 zpool_close(zhp); 1434 continue; 1435 } 1436 1437 /* The history must be logged as part of the export */ 1438 log_history = B_FALSE; 1439 1440 if (hardforce) { 1441 if (zpool_export_force(zhp, history_str) != 0) 1442 ret = 1; 1443 } else if (zpool_export(zhp, force, history_str) != 0) { 1444 ret = 1; 1445 } 1446 1447 zpool_close(zhp); 1448 } 1449 1450 return (ret); 1451 } 1452 1453 /* 1454 * Given a vdev configuration, determine the maximum width needed for the device 1455 * name column. 1456 */ 1457 static int 1458 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max, 1459 int name_flags) 1460 { 1461 char *name; 1462 nvlist_t **child; 1463 uint_t c, children; 1464 int ret; 1465 1466 name = zpool_vdev_name(g_zfs, zhp, nv, name_flags | VDEV_NAME_TYPE_ID); 1467 if (strlen(name) + depth > max) 1468 max = strlen(name) + depth; 1469 1470 free(name); 1471 1472 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1473 &child, &children) == 0) { 1474 for (c = 0; c < children; c++) 1475 if ((ret = max_width(zhp, child[c], depth + 2, 1476 max, name_flags)) > max) 1477 max = ret; 1478 } 1479 1480 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1481 &child, &children) == 0) { 1482 for (c = 0; c < children; c++) 1483 if ((ret = max_width(zhp, child[c], depth + 2, 1484 max, name_flags)) > max) 1485 max = ret; 1486 } 1487 1488 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1489 &child, &children) == 0) { 1490 for (c = 0; c < children; c++) 1491 if ((ret = max_width(zhp, child[c], depth + 2, 1492 max, name_flags)) > max) 1493 max = ret; 1494 } 1495 1496 return (max); 1497 } 1498 1499 typedef struct spare_cbdata { 1500 uint64_t cb_guid; 1501 zpool_handle_t *cb_zhp; 1502 } spare_cbdata_t; 1503 1504 static boolean_t 1505 find_vdev(nvlist_t *nv, uint64_t search) 1506 { 1507 uint64_t guid; 1508 nvlist_t **child; 1509 uint_t c, children; 1510 1511 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 1512 search == guid) 1513 return (B_TRUE); 1514 1515 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1516 &child, &children) == 0) { 1517 for (c = 0; c < children; c++) 1518 if (find_vdev(child[c], search)) 1519 return (B_TRUE); 1520 } 1521 1522 return (B_FALSE); 1523 } 1524 1525 static int 1526 find_spare(zpool_handle_t *zhp, void *data) 1527 { 1528 spare_cbdata_t *cbp = data; 1529 nvlist_t *config, *nvroot; 1530 1531 config = zpool_get_config(zhp, NULL); 1532 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1533 &nvroot) == 0); 1534 1535 if (find_vdev(nvroot, cbp->cb_guid)) { 1536 cbp->cb_zhp = zhp; 1537 return (1); 1538 } 1539 1540 zpool_close(zhp); 1541 return (0); 1542 } 1543 1544 typedef struct status_cbdata { 1545 int cb_count; 1546 int cb_name_flags; 1547 int cb_namewidth; 1548 boolean_t cb_allpools; 1549 boolean_t cb_verbose; 1550 boolean_t cb_explain; 1551 boolean_t cb_first; 1552 boolean_t cb_dedup_stats; 1553 boolean_t cb_print_status; 1554 } status_cbdata_t; 1555 1556 /* 1557 * Print out configuration state as requested by status_callback. 1558 */ 1559 static void 1560 print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, 1561 nvlist_t *nv, int depth, boolean_t isspare) 1562 { 1563 nvlist_t **child, *root; 1564 uint_t c, children; 1565 pool_scan_stat_t *ps = NULL; 1566 vdev_stat_t *vs; 1567 char rbuf[6], wbuf[6], cbuf[6]; 1568 char *vname; 1569 uint64_t notpresent; 1570 spare_cbdata_t spare_cb; 1571 const char *state; 1572 char *type; 1573 1574 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1575 &child, &children) != 0) 1576 children = 0; 1577 1578 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 1579 (uint64_t **)&vs, &c) == 0); 1580 1581 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 1582 1583 if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) 1584 return; 1585 1586 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1587 if (isspare) { 1588 /* 1589 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 1590 * online drives. 1591 */ 1592 if (vs->vs_aux == VDEV_AUX_SPARED) 1593 state = "INUSE"; 1594 else if (vs->vs_state == VDEV_STATE_HEALTHY) 1595 state = "AVAIL"; 1596 } 1597 1598 (void) printf("\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth, 1599 name, state); 1600 1601 if (!isspare) { 1602 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 1603 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 1604 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 1605 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 1606 } 1607 1608 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1609 ¬present) == 0) { 1610 char *path; 1611 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 1612 (void) printf(" was %s", path); 1613 } else if (vs->vs_aux != 0) { 1614 (void) printf(" "); 1615 1616 switch (vs->vs_aux) { 1617 case VDEV_AUX_OPEN_FAILED: 1618 (void) printf(gettext("cannot open")); 1619 break; 1620 1621 case VDEV_AUX_BAD_GUID_SUM: 1622 (void) printf(gettext("missing device")); 1623 break; 1624 1625 case VDEV_AUX_NO_REPLICAS: 1626 (void) printf(gettext("insufficient replicas")); 1627 break; 1628 1629 case VDEV_AUX_VERSION_NEWER: 1630 (void) printf(gettext("newer version")); 1631 break; 1632 1633 case VDEV_AUX_UNSUP_FEAT: 1634 (void) printf(gettext("unsupported feature(s)")); 1635 break; 1636 1637 case VDEV_AUX_SPARED: 1638 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1639 &spare_cb.cb_guid) == 0); 1640 if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) { 1641 if (strcmp(zpool_get_name(spare_cb.cb_zhp), 1642 zpool_get_name(zhp)) == 0) 1643 (void) printf(gettext("currently in " 1644 "use")); 1645 else 1646 (void) printf(gettext("in use by " 1647 "pool '%s'"), 1648 zpool_get_name(spare_cb.cb_zhp)); 1649 zpool_close(spare_cb.cb_zhp); 1650 } else { 1651 (void) printf(gettext("currently in use")); 1652 } 1653 break; 1654 1655 case VDEV_AUX_ERR_EXCEEDED: 1656 (void) printf(gettext("too many errors")); 1657 break; 1658 1659 case VDEV_AUX_IO_FAILURE: 1660 (void) printf(gettext("experienced I/O failures")); 1661 break; 1662 1663 case VDEV_AUX_BAD_LOG: 1664 (void) printf(gettext("bad intent log")); 1665 break; 1666 1667 case VDEV_AUX_EXTERNAL: 1668 (void) printf(gettext("external device fault")); 1669 break; 1670 1671 case VDEV_AUX_SPLIT_POOL: 1672 (void) printf(gettext("split into new pool")); 1673 break; 1674 1675 case VDEV_AUX_ACTIVE: 1676 (void) printf(gettext("currently in use")); 1677 break; 1678 1679 case VDEV_AUX_CHILDREN_OFFLINE: 1680 (void) printf(gettext("all children offline")); 1681 break; 1682 1683 default: 1684 (void) printf(gettext("corrupted data")); 1685 break; 1686 } 1687 } 1688 1689 /* The root vdev has the scrub/resilver stats */ 1690 root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 1691 ZPOOL_CONFIG_VDEV_TREE); 1692 (void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS, 1693 (uint64_t **)&ps, &c); 1694 1695 if (ps && ps->pss_state == DSS_SCANNING && 1696 vs->vs_scan_processed != 0 && children == 0) { 1697 (void) printf(gettext(" (%s)"), 1698 (ps->pss_func == POOL_SCAN_RESILVER) ? 1699 "resilvering" : "repairing"); 1700 } 1701 1702 if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE || 1703 vs->vs_initialize_state == VDEV_INITIALIZE_SUSPENDED || 1704 vs->vs_initialize_state == VDEV_INITIALIZE_COMPLETE) && 1705 !vs->vs_scan_removing) { 1706 char zbuf[1024]; 1707 char tbuf[256]; 1708 struct tm zaction_ts; 1709 1710 time_t t = vs->vs_initialize_action_time; 1711 int initialize_pct = 100; 1712 if (vs->vs_initialize_state != VDEV_INITIALIZE_COMPLETE) { 1713 initialize_pct = (vs->vs_initialize_bytes_done * 100 / 1714 (vs->vs_initialize_bytes_est + 1)); 1715 } 1716 1717 (void) localtime_r(&t, &zaction_ts); 1718 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts); 1719 1720 switch (vs->vs_initialize_state) { 1721 case VDEV_INITIALIZE_SUSPENDED: 1722 (void) snprintf(zbuf, sizeof (zbuf), 1723 ", suspended, started at %s", tbuf); 1724 break; 1725 case VDEV_INITIALIZE_ACTIVE: 1726 (void) snprintf(zbuf, sizeof (zbuf), 1727 ", started at %s", tbuf); 1728 break; 1729 case VDEV_INITIALIZE_COMPLETE: 1730 (void) snprintf(zbuf, sizeof (zbuf), 1731 ", completed at %s", tbuf); 1732 break; 1733 } 1734 1735 (void) printf(gettext(" (%d%% initialized%s)"), 1736 initialize_pct, zbuf); 1737 } 1738 1739 (void) printf("\n"); 1740 1741 for (c = 0; c < children; c++) { 1742 uint64_t islog = B_FALSE, ishole = B_FALSE; 1743 1744 /* Don't print logs or holes here */ 1745 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1746 &islog); 1747 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE, 1748 &ishole); 1749 if (islog || ishole) 1750 continue; 1751 /* Only print normal classes here */ 1752 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 1753 continue; 1754 1755 vname = zpool_vdev_name(g_zfs, zhp, child[c], 1756 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 1757 1758 print_status_config(zhp, cb, vname, child[c], depth + 2, 1759 isspare); 1760 free(vname); 1761 } 1762 } 1763 1764 /* 1765 * Print the configuration of an exported pool. Iterate over all vdevs in the 1766 * pool, printing out the name and status for each one. 1767 */ 1768 static void 1769 print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv, 1770 int depth) 1771 { 1772 nvlist_t **child; 1773 uint_t c, children; 1774 vdev_stat_t *vs; 1775 char *type, *vname; 1776 1777 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 1778 if (strcmp(type, VDEV_TYPE_MISSING) == 0 || 1779 strcmp(type, VDEV_TYPE_HOLE) == 0) 1780 return; 1781 1782 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 1783 (uint64_t **)&vs, &c) == 0); 1784 1785 (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name); 1786 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux)); 1787 1788 if (vs->vs_aux != 0) { 1789 (void) printf(" "); 1790 1791 switch (vs->vs_aux) { 1792 case VDEV_AUX_OPEN_FAILED: 1793 (void) printf(gettext("cannot open")); 1794 break; 1795 1796 case VDEV_AUX_BAD_GUID_SUM: 1797 (void) printf(gettext("missing device")); 1798 break; 1799 1800 case VDEV_AUX_NO_REPLICAS: 1801 (void) printf(gettext("insufficient replicas")); 1802 break; 1803 1804 case VDEV_AUX_VERSION_NEWER: 1805 (void) printf(gettext("newer version")); 1806 break; 1807 1808 case VDEV_AUX_UNSUP_FEAT: 1809 (void) printf(gettext("unsupported feature(s)")); 1810 break; 1811 1812 case VDEV_AUX_ERR_EXCEEDED: 1813 (void) printf(gettext("too many errors")); 1814 break; 1815 1816 case VDEV_AUX_ACTIVE: 1817 (void) printf(gettext("currently in use")); 1818 break; 1819 1820 case VDEV_AUX_CHILDREN_OFFLINE: 1821 (void) printf(gettext("all children offline")); 1822 break; 1823 1824 default: 1825 (void) printf(gettext("corrupted data")); 1826 break; 1827 } 1828 } 1829 (void) printf("\n"); 1830 1831 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1832 &child, &children) != 0) 1833 return; 1834 1835 for (c = 0; c < children; c++) { 1836 uint64_t is_log = B_FALSE; 1837 1838 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1839 &is_log); 1840 if (is_log) 1841 continue; 1842 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 1843 continue; 1844 1845 vname = zpool_vdev_name(g_zfs, NULL, child[c], 1846 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 1847 print_import_config(cb, vname, child[c], depth + 2); 1848 free(vname); 1849 } 1850 1851 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1852 &child, &children) == 0) { 1853 (void) printf(gettext("\tcache\n")); 1854 for (c = 0; c < children; c++) { 1855 vname = zpool_vdev_name(g_zfs, NULL, child[c], 1856 cb->cb_name_flags); 1857 (void) printf("\t %s\n", vname); 1858 free(vname); 1859 } 1860 } 1861 1862 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1863 &child, &children) == 0) { 1864 (void) printf(gettext("\tspares\n")); 1865 for (c = 0; c < children; c++) { 1866 vname = zpool_vdev_name(g_zfs, NULL, child[c], 1867 cb->cb_name_flags); 1868 (void) printf("\t %s\n", vname); 1869 free(vname); 1870 } 1871 } 1872 } 1873 1874 /* 1875 * Print specialized class vdevs. 1876 * 1877 * These are recorded as top level vdevs in the main pool child array 1878 * but with "is_log" set to 1 or an "alloc_bias" string. We use either 1879 * print_status_config() or print_import_config() to print the top level 1880 * class vdevs then any of their children (eg mirrored slogs) are printed 1881 * recursively - which works because only the top level vdev is marked. 1882 */ 1883 static void 1884 print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv, 1885 const char *class) 1886 { 1887 uint_t c, children; 1888 nvlist_t **child; 1889 boolean_t printed = B_FALSE; 1890 1891 assert(zhp != NULL || !cb->cb_verbose); 1892 1893 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child, 1894 &children) != 0) 1895 return; 1896 1897 for (c = 0; c < children; c++) { 1898 uint64_t is_log = B_FALSE; 1899 char *bias = NULL; 1900 char *type = NULL; 1901 1902 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1903 &is_log); 1904 1905 if (is_log) { 1906 bias = VDEV_ALLOC_CLASS_LOGS; 1907 } else { 1908 (void) nvlist_lookup_string(child[c], 1909 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 1910 (void) nvlist_lookup_string(child[c], 1911 ZPOOL_CONFIG_TYPE, &type); 1912 } 1913 1914 if (bias == NULL || strcmp(bias, class) != 0) 1915 continue; 1916 if (!is_log && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 1917 continue; 1918 1919 if (!printed) { 1920 (void) printf("\t%s\t\n", gettext(class)); 1921 printed = B_TRUE; 1922 } 1923 1924 char *name = zpool_vdev_name(g_zfs, zhp, child[c], 1925 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 1926 if (cb->cb_print_status) 1927 print_status_config(zhp, cb, name, child[c], 2, 1928 B_FALSE); 1929 else 1930 print_import_config(cb, name, child[c], 2); 1931 free(name); 1932 } 1933 } 1934 1935 /* 1936 * Display the status for the given pool. 1937 */ 1938 static void 1939 show_import(nvlist_t *config) 1940 { 1941 uint64_t pool_state; 1942 vdev_stat_t *vs; 1943 char *name; 1944 uint64_t guid; 1945 uint64_t hostid = 0; 1946 char *msgid; 1947 char *hostname = "unknown"; 1948 nvlist_t *nvroot, *nvinfo; 1949 int reason; 1950 const char *health; 1951 uint_t vsc; 1952 char *comment; 1953 status_cbdata_t cb = { 0 }; 1954 1955 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1956 &name) == 0); 1957 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 1958 &guid) == 0); 1959 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1960 &pool_state) == 0); 1961 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1962 &nvroot) == 0); 1963 1964 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 1965 (uint64_t **)&vs, &vsc) == 0); 1966 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1967 1968 reason = zpool_import_status(config, &msgid); 1969 1970 (void) printf(gettext(" pool: %s\n"), name); 1971 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid); 1972 (void) printf(gettext(" state: %s"), health); 1973 if (pool_state == POOL_STATE_DESTROYED) 1974 (void) printf(gettext(" (DESTROYED)")); 1975 (void) printf("\n"); 1976 1977 switch (reason) { 1978 case ZPOOL_STATUS_MISSING_DEV_R: 1979 case ZPOOL_STATUS_MISSING_DEV_NR: 1980 case ZPOOL_STATUS_BAD_GUID_SUM: 1981 (void) printf(gettext(" status: One or more devices are " 1982 "missing from the system.\n")); 1983 break; 1984 1985 case ZPOOL_STATUS_CORRUPT_LABEL_R: 1986 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 1987 (void) printf(gettext(" status: One or more devices contains " 1988 "corrupted data.\n")); 1989 break; 1990 1991 case ZPOOL_STATUS_CORRUPT_DATA: 1992 (void) printf( 1993 gettext(" status: The pool data is corrupted.\n")); 1994 break; 1995 1996 case ZPOOL_STATUS_OFFLINE_DEV: 1997 (void) printf(gettext(" status: One or more devices " 1998 "are offlined.\n")); 1999 break; 2000 2001 case ZPOOL_STATUS_CORRUPT_POOL: 2002 (void) printf(gettext(" status: The pool metadata is " 2003 "corrupted.\n")); 2004 break; 2005 2006 case ZPOOL_STATUS_VERSION_OLDER: 2007 (void) printf(gettext(" status: The pool is formatted using a " 2008 "legacy on-disk version.\n")); 2009 break; 2010 2011 case ZPOOL_STATUS_VERSION_NEWER: 2012 (void) printf(gettext(" status: The pool is formatted using an " 2013 "incompatible version.\n")); 2014 break; 2015 2016 case ZPOOL_STATUS_FEAT_DISABLED: 2017 (void) printf(gettext(" status: Some supported features are " 2018 "not enabled on the pool.\n")); 2019 break; 2020 2021 case ZPOOL_STATUS_UNSUP_FEAT_READ: 2022 (void) printf(gettext("status: The pool uses the following " 2023 "feature(s) not supported on this system:\n")); 2024 zpool_print_unsup_feat(config); 2025 break; 2026 2027 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 2028 (void) printf(gettext("status: The pool can only be accessed " 2029 "in read-only mode on this system. It\n\tcannot be " 2030 "accessed in read-write mode because it uses the " 2031 "following\n\tfeature(s) not supported on this system:\n")); 2032 zpool_print_unsup_feat(config); 2033 break; 2034 2035 case ZPOOL_STATUS_HOSTID_ACTIVE: 2036 (void) printf(gettext(" status: The pool is currently " 2037 "imported by another system.\n")); 2038 break; 2039 2040 case ZPOOL_STATUS_HOSTID_REQUIRED: 2041 (void) printf(gettext(" status: The pool has the " 2042 "multihost property on. It cannot\n\tbe safely imported " 2043 "when the system hostid is not set.\n")); 2044 break; 2045 2046 case ZPOOL_STATUS_HOSTID_MISMATCH: 2047 (void) printf(gettext(" status: The pool was last accessed by " 2048 "another system.\n")); 2049 break; 2050 2051 case ZPOOL_STATUS_FAULTED_DEV_R: 2052 case ZPOOL_STATUS_FAULTED_DEV_NR: 2053 (void) printf(gettext(" status: One or more devices are " 2054 "faulted.\n")); 2055 break; 2056 2057 case ZPOOL_STATUS_BAD_LOG: 2058 (void) printf(gettext(" status: An intent log record cannot be " 2059 "read.\n")); 2060 break; 2061 2062 case ZPOOL_STATUS_RESILVERING: 2063 (void) printf(gettext(" status: One or more devices were being " 2064 "resilvered.\n")); 2065 break; 2066 2067 default: 2068 /* 2069 * No other status can be seen when importing pools. 2070 */ 2071 assert(reason == ZPOOL_STATUS_OK); 2072 } 2073 2074 /* 2075 * Print out an action according to the overall state of the pool. 2076 */ 2077 if (vs->vs_state == VDEV_STATE_HEALTHY) { 2078 if (reason == ZPOOL_STATUS_VERSION_OLDER || 2079 reason == ZPOOL_STATUS_FEAT_DISABLED) { 2080 (void) printf(gettext(" action: The pool can be " 2081 "imported using its name or numeric identifier, " 2082 "though\n\tsome features will not be available " 2083 "without an explicit 'zpool upgrade'.\n")); 2084 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) { 2085 (void) printf(gettext(" action: The pool can be " 2086 "imported using its name or numeric " 2087 "identifier and\n\tthe '-f' flag.\n")); 2088 } else { 2089 (void) printf(gettext(" action: The pool can be " 2090 "imported using its name or numeric " 2091 "identifier.\n")); 2092 } 2093 } else if (vs->vs_state == VDEV_STATE_DEGRADED) { 2094 (void) printf(gettext(" action: The pool can be imported " 2095 "despite missing or damaged devices. The\n\tfault " 2096 "tolerance of the pool may be compromised if imported.\n")); 2097 } else { 2098 switch (reason) { 2099 case ZPOOL_STATUS_VERSION_NEWER: 2100 (void) printf(gettext(" action: The pool cannot be " 2101 "imported. Access the pool on a system running " 2102 "newer\n\tsoftware, or recreate the pool from " 2103 "backup.\n")); 2104 break; 2105 case ZPOOL_STATUS_UNSUP_FEAT_READ: 2106 (void) printf(gettext("action: The pool cannot be " 2107 "imported. Access the pool on a system that " 2108 "supports\n\tthe required feature(s), or recreate " 2109 "the pool from backup.\n")); 2110 break; 2111 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 2112 (void) printf(gettext("action: The pool cannot be " 2113 "imported in read-write mode. Import the pool " 2114 "with\n" 2115 "\t\"-o readonly=on\", access the pool on a system " 2116 "that supports the\n\trequired feature(s), or " 2117 "recreate the pool from backup.\n")); 2118 break; 2119 case ZPOOL_STATUS_MISSING_DEV_R: 2120 case ZPOOL_STATUS_MISSING_DEV_NR: 2121 case ZPOOL_STATUS_BAD_GUID_SUM: 2122 (void) printf(gettext(" action: The pool cannot be " 2123 "imported. Attach the missing\n\tdevices and try " 2124 "again.\n")); 2125 break; 2126 case ZPOOL_STATUS_HOSTID_ACTIVE: 2127 VERIFY0(nvlist_lookup_nvlist(config, 2128 ZPOOL_CONFIG_LOAD_INFO, &nvinfo)); 2129 2130 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME)) 2131 hostname = fnvlist_lookup_string(nvinfo, 2132 ZPOOL_CONFIG_MMP_HOSTNAME); 2133 2134 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID)) 2135 hostid = fnvlist_lookup_uint64(nvinfo, 2136 ZPOOL_CONFIG_MMP_HOSTID); 2137 2138 (void) printf(gettext(" action: The pool must be " 2139 "exported from %s (hostid=%lx)\n\tbefore it " 2140 "can be safely imported.\n"), hostname, 2141 (unsigned long) hostid); 2142 break; 2143 case ZPOOL_STATUS_HOSTID_REQUIRED: 2144 (void) printf(gettext(" action: Check the SMF " 2145 "svc:/system/hostid service.\n")); 2146 break; 2147 default: 2148 (void) printf(gettext(" action: The pool cannot be " 2149 "imported due to damaged devices or data.\n")); 2150 } 2151 } 2152 2153 /* Print the comment attached to the pool. */ 2154 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) 2155 (void) printf(gettext("comment: %s\n"), comment); 2156 2157 /* 2158 * If the state is "closed" or "can't open", and the aux state 2159 * is "corrupt data": 2160 */ 2161 if (((vs->vs_state == VDEV_STATE_CLOSED) || 2162 (vs->vs_state == VDEV_STATE_CANT_OPEN)) && 2163 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) { 2164 if (pool_state == POOL_STATE_DESTROYED) 2165 (void) printf(gettext("\tThe pool was destroyed, " 2166 "but can be imported using the '-Df' flags.\n")); 2167 else if (pool_state != POOL_STATE_EXPORTED) 2168 (void) printf(gettext("\tThe pool may be active on " 2169 "another system, but can be imported using\n\t" 2170 "the '-f' flag.\n")); 2171 } 2172 2173 if (msgid != NULL) 2174 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 2175 msgid); 2176 2177 (void) printf(gettext(" config:\n\n")); 2178 2179 cb.cb_namewidth = max_width(NULL, nvroot, 0, 0, 0); 2180 if (cb.cb_namewidth < 10) 2181 cb.cb_namewidth = 10; 2182 2183 print_import_config(&cb, name, nvroot, 0); 2184 2185 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_DEDUP); 2186 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_SPECIAL); 2187 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS); 2188 2189 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) { 2190 (void) printf(gettext("\n\tAdditional devices are known to " 2191 "be part of this pool, though their\n\texact " 2192 "configuration cannot be determined.\n")); 2193 } 2194 } 2195 2196 static boolean_t 2197 zfs_force_import_required(nvlist_t *config) 2198 { 2199 uint64_t state; 2200 uint64_t hostid = 0; 2201 nvlist_t *nvinfo; 2202 2203 state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE); 2204 (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid); 2205 2206 if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid()) 2207 return (B_TRUE); 2208 2209 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); 2210 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) { 2211 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo, 2212 ZPOOL_CONFIG_MMP_STATE); 2213 2214 if (mmp_state != MMP_STATE_INACTIVE) 2215 return (B_TRUE); 2216 } 2217 2218 return (B_FALSE); 2219 } 2220 2221 /* 2222 * Perform the import for the given configuration. This passes the heavy 2223 * lifting off to zpool_import_props(), and then mounts the datasets contained 2224 * within the pool. 2225 */ 2226 static int 2227 do_import(nvlist_t *config, const char *newname, const char *mntopts, 2228 nvlist_t *props, int flags) 2229 { 2230 zpool_handle_t *zhp; 2231 char *name; 2232 uint64_t version; 2233 2234 name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); 2235 version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION); 2236 2237 if (!SPA_VERSION_IS_SUPPORTED(version)) { 2238 (void) fprintf(stderr, gettext("cannot import '%s': pool " 2239 "is formatted using an unsupported ZFS version\n"), name); 2240 return (1); 2241 } else if (zfs_force_import_required(config) && 2242 !(flags & ZFS_IMPORT_ANY_HOST)) { 2243 mmp_state_t mmp_state = MMP_STATE_INACTIVE; 2244 nvlist_t *nvinfo; 2245 2246 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); 2247 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) 2248 mmp_state = fnvlist_lookup_uint64(nvinfo, 2249 ZPOOL_CONFIG_MMP_STATE); 2250 2251 if (mmp_state == MMP_STATE_ACTIVE) { 2252 char *hostname = "<unknown>"; 2253 uint64_t hostid = 0; 2254 2255 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME)) 2256 hostname = fnvlist_lookup_string(nvinfo, 2257 ZPOOL_CONFIG_MMP_HOSTNAME); 2258 2259 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID)) 2260 hostid = fnvlist_lookup_uint64(nvinfo, 2261 ZPOOL_CONFIG_MMP_HOSTID); 2262 2263 (void) fprintf(stderr, gettext("cannot import '%s': " 2264 "pool is imported on %s (hostid: " 2265 "0x%lx)\nExport the pool on the other system, " 2266 "then run 'zpool import'.\n"), 2267 name, hostname, (unsigned long) hostid); 2268 } else if (mmp_state == MMP_STATE_NO_HOSTID) { 2269 (void) fprintf(stderr, gettext("Cannot import '%s': " 2270 "pool has the multihost property on and the\n" 2271 "system's hostid is not set.\n"), name); 2272 } else { 2273 char *hostname = "<unknown>"; 2274 uint64_t timestamp = 0; 2275 uint64_t hostid = 0; 2276 2277 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME)) 2278 hostname = fnvlist_lookup_string(config, 2279 ZPOOL_CONFIG_HOSTNAME); 2280 2281 if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP)) 2282 timestamp = fnvlist_lookup_uint64(config, 2283 ZPOOL_CONFIG_TIMESTAMP); 2284 2285 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID)) 2286 hostid = fnvlist_lookup_uint64(config, 2287 ZPOOL_CONFIG_HOSTID); 2288 2289 (void) fprintf(stderr, gettext("cannot import '%s': " 2290 "pool was previously in use from another system.\n" 2291 "Last accessed by %s (hostid=%lx) at %s" 2292 "The pool can be imported, use 'zpool import -f' " 2293 "to import the pool.\n"), name, hostname, 2294 (unsigned long)hostid, ctime((time_t *)×tamp)); 2295 2296 } 2297 2298 return (1); 2299 } 2300 2301 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0) 2302 return (1); 2303 2304 if (newname != NULL) 2305 name = (char *)newname; 2306 2307 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) 2308 return (1); 2309 2310 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 2311 !(flags & ZFS_IMPORT_ONLY) && 2312 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 2313 zpool_close(zhp); 2314 return (1); 2315 } 2316 2317 zpool_close(zhp); 2318 return (0); 2319 } 2320 2321 /* 2322 * zpool checkpoint <pool> 2323 * checkpoint --discard <pool> 2324 * 2325 * -d Discard the checkpoint from a checkpointed 2326 * --discard pool. 2327 * 2328 * Checkpoints the specified pool, by taking a "snapshot" of its 2329 * current state. A pool can only have one checkpoint at a time. 2330 */ 2331 int 2332 zpool_do_checkpoint(int argc, char **argv) 2333 { 2334 boolean_t discard; 2335 char *pool; 2336 zpool_handle_t *zhp; 2337 int c, err; 2338 2339 struct option long_options[] = { 2340 {"discard", no_argument, NULL, 'd'}, 2341 {0, 0, 0, 0} 2342 }; 2343 2344 discard = B_FALSE; 2345 while ((c = getopt_long(argc, argv, ":d", long_options, NULL)) != -1) { 2346 switch (c) { 2347 case 'd': 2348 discard = B_TRUE; 2349 break; 2350 case '?': 2351 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2352 optopt); 2353 usage(B_FALSE); 2354 } 2355 } 2356 2357 argc -= optind; 2358 argv += optind; 2359 2360 if (argc < 1) { 2361 (void) fprintf(stderr, gettext("missing pool argument\n")); 2362 usage(B_FALSE); 2363 } 2364 2365 if (argc > 1) { 2366 (void) fprintf(stderr, gettext("too many arguments\n")); 2367 usage(B_FALSE); 2368 } 2369 2370 pool = argv[0]; 2371 2372 if ((zhp = zpool_open(g_zfs, pool)) == NULL) { 2373 /* As a special case, check for use of '/' in the name */ 2374 if (strchr(pool, '/') != NULL) 2375 (void) fprintf(stderr, gettext("'zpool checkpoint' " 2376 "doesn't work on datasets. To save the state " 2377 "of a dataset from a specific point in time " 2378 "please use 'zfs snapshot'\n")); 2379 return (1); 2380 } 2381 2382 if (discard) 2383 err = (zpool_discard_checkpoint(zhp) != 0); 2384 else 2385 err = (zpool_checkpoint(zhp) != 0); 2386 2387 zpool_close(zhp); 2388 2389 return (err); 2390 } 2391 2392 #define CHECKPOINT_OPT 1024 2393 2394 /* 2395 * zpool import [-d dir] [-D] 2396 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 2397 * [-d dir | -c cachefile] [-f] -a 2398 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 2399 * [-d dir | -c cachefile] [-f] [-n] [-F] [-t] 2400 * <pool | id> [newpool] 2401 * 2402 * -c Read pool information from a cachefile instead of searching 2403 * devices. 2404 * 2405 * -d Scan in a specific directory, other than /dev/dsk. More than 2406 * one directory can be specified using multiple '-d' options. 2407 * 2408 * -D Scan for previously destroyed pools or import all or only 2409 * specified destroyed pools. 2410 * 2411 * -R Temporarily import the pool, with all mountpoints relative to 2412 * the given root. The pool will remain exported when the machine 2413 * is rebooted. 2414 * 2415 * -V Import even in the presence of faulted vdevs. This is an 2416 * intentionally undocumented option for testing purposes, and 2417 * treats the pool configuration as complete, leaving any bad 2418 * vdevs in the FAULTED state. In other words, it does verbatim 2419 * import. 2420 * 2421 * -f Force import, even if it appears that the pool is active. 2422 * 2423 * -F Attempt rewind if necessary. 2424 * 2425 * -n See if rewind would work, but don't actually rewind. 2426 * 2427 * -N Import the pool but don't mount datasets. 2428 * 2429 * -t Use newpool as a temporary pool name instead of renaming 2430 * the pool. 2431 * 2432 * -T Specify a starting txg to use for import. This option is 2433 * intentionally undocumented option for testing purposes. 2434 * 2435 * -a Import all pools found. 2436 * 2437 * -o Set property=value and/or temporary mount options (without '='). 2438 * 2439 * --rewind-to-checkpoint 2440 * Import the pool and revert back to the checkpoint. 2441 * 2442 * The import command scans for pools to import, and import pools based on pool 2443 * name and GUID. The pool can also be renamed as part of the import process. 2444 */ 2445 int 2446 zpool_do_import(int argc, char **argv) 2447 { 2448 char **searchdirs = NULL; 2449 int nsearch = 0; 2450 int c; 2451 int err = 0; 2452 nvlist_t *pools = NULL; 2453 boolean_t do_all = B_FALSE; 2454 boolean_t do_destroyed = B_FALSE; 2455 char *mntopts = NULL; 2456 nvpair_t *elem; 2457 nvlist_t *config; 2458 uint64_t searchguid = 0; 2459 char *searchname = NULL; 2460 char *propval; 2461 nvlist_t *found_config; 2462 nvlist_t *policy = NULL; 2463 nvlist_t *props = NULL; 2464 boolean_t first; 2465 int flags = ZFS_IMPORT_NORMAL; 2466 uint32_t rewind_policy = ZPOOL_NO_REWIND; 2467 boolean_t dryrun = B_FALSE; 2468 boolean_t do_rewind = B_FALSE; 2469 boolean_t xtreme_rewind = B_FALSE; 2470 uint64_t pool_state, txg = -1ULL; 2471 char *cachefile = NULL; 2472 importargs_t idata = { 0 }; 2473 char *endptr; 2474 2475 2476 struct option long_options[] = { 2477 {"rewind-to-checkpoint", no_argument, NULL, CHECKPOINT_OPT}, 2478 {0, 0, 0, 0} 2479 }; 2480 2481 /* check options */ 2482 while ((c = getopt_long(argc, argv, ":aCc:d:DEfFmnNo:rR:tT:VX", 2483 long_options, NULL)) != -1) { 2484 switch (c) { 2485 case 'a': 2486 do_all = B_TRUE; 2487 break; 2488 case 'c': 2489 cachefile = optarg; 2490 break; 2491 case 'd': 2492 if (searchdirs == NULL) { 2493 searchdirs = safe_malloc(sizeof (char *)); 2494 } else { 2495 char **tmp = safe_malloc((nsearch + 1) * 2496 sizeof (char *)); 2497 bcopy(searchdirs, tmp, nsearch * 2498 sizeof (char *)); 2499 free(searchdirs); 2500 searchdirs = tmp; 2501 } 2502 searchdirs[nsearch++] = optarg; 2503 break; 2504 case 'D': 2505 do_destroyed = B_TRUE; 2506 break; 2507 case 'f': 2508 flags |= ZFS_IMPORT_ANY_HOST; 2509 break; 2510 case 'F': 2511 do_rewind = B_TRUE; 2512 break; 2513 case 'm': 2514 flags |= ZFS_IMPORT_MISSING_LOG; 2515 break; 2516 case 'n': 2517 dryrun = B_TRUE; 2518 break; 2519 case 'N': 2520 flags |= ZFS_IMPORT_ONLY; 2521 break; 2522 case 'o': 2523 if ((propval = strchr(optarg, '=')) != NULL) { 2524 *propval = '\0'; 2525 propval++; 2526 if (add_prop_list(optarg, propval, 2527 &props, B_TRUE)) 2528 goto error; 2529 } else { 2530 mntopts = optarg; 2531 } 2532 break; 2533 case 'R': 2534 if (add_prop_list(zpool_prop_to_name( 2535 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 2536 goto error; 2537 if (add_prop_list_default(zpool_prop_to_name( 2538 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 2539 goto error; 2540 break; 2541 case 't': 2542 flags |= ZFS_IMPORT_TEMP_NAME; 2543 if (add_prop_list_default(zpool_prop_to_name( 2544 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 2545 goto error; 2546 break; 2547 case 'T': 2548 errno = 0; 2549 txg = strtoull(optarg, &endptr, 0); 2550 if (errno != 0 || *endptr != '\0') { 2551 (void) fprintf(stderr, 2552 gettext("invalid txg value\n")); 2553 usage(B_FALSE); 2554 } 2555 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND; 2556 break; 2557 case 'V': 2558 flags |= ZFS_IMPORT_VERBATIM; 2559 break; 2560 case 'X': 2561 xtreme_rewind = B_TRUE; 2562 break; 2563 case CHECKPOINT_OPT: 2564 flags |= ZFS_IMPORT_CHECKPOINT; 2565 break; 2566 case ':': 2567 (void) fprintf(stderr, gettext("missing argument for " 2568 "'%c' option\n"), optopt); 2569 usage(B_FALSE); 2570 break; 2571 case '?': 2572 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2573 optopt); 2574 usage(B_FALSE); 2575 } 2576 } 2577 2578 argc -= optind; 2579 argv += optind; 2580 2581 if (cachefile && nsearch != 0) { 2582 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 2583 usage(B_FALSE); 2584 } 2585 2586 if ((dryrun || xtreme_rewind) && !do_rewind) { 2587 (void) fprintf(stderr, 2588 gettext("-n or -X only meaningful with -F\n")); 2589 usage(B_FALSE); 2590 } 2591 if (dryrun) 2592 rewind_policy = ZPOOL_TRY_REWIND; 2593 else if (do_rewind) 2594 rewind_policy = ZPOOL_DO_REWIND; 2595 if (xtreme_rewind) 2596 rewind_policy |= ZPOOL_EXTREME_REWIND; 2597 2598 /* In the future, we can capture further policy and include it here */ 2599 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 2600 nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, txg) != 0 || 2601 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 2602 rewind_policy) != 0) 2603 goto error; 2604 2605 if (searchdirs == NULL) { 2606 searchdirs = safe_malloc(sizeof (char *)); 2607 searchdirs[0] = ZFS_DISK_ROOT; 2608 nsearch = 1; 2609 } 2610 2611 /* check argument count */ 2612 if (do_all) { 2613 if (argc != 0) { 2614 (void) fprintf(stderr, gettext("too many arguments\n")); 2615 usage(B_FALSE); 2616 } 2617 } else { 2618 if (argc > 2) { 2619 (void) fprintf(stderr, gettext("too many arguments\n")); 2620 usage(B_FALSE); 2621 } 2622 2623 /* 2624 * Check for the SYS_CONFIG privilege. We do this explicitly 2625 * here because otherwise any attempt to discover pools will 2626 * silently fail. 2627 */ 2628 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 2629 (void) fprintf(stderr, gettext("cannot " 2630 "discover pools: permission denied\n")); 2631 free(searchdirs); 2632 nvlist_free(policy); 2633 return (1); 2634 } 2635 } 2636 2637 /* 2638 * Depending on the arguments given, we do one of the following: 2639 * 2640 * <none> Iterate through all pools and display information about 2641 * each one. 2642 * 2643 * -a Iterate through all pools and try to import each one. 2644 * 2645 * <id> Find the pool that corresponds to the given GUID/pool 2646 * name and import that one. 2647 * 2648 * -D Above options applies only to destroyed pools. 2649 */ 2650 if (argc != 0) { 2651 char *endptr; 2652 2653 errno = 0; 2654 searchguid = strtoull(argv[0], &endptr, 10); 2655 if (errno != 0 || *endptr != '\0') { 2656 searchname = argv[0]; 2657 searchguid = 0; 2658 } 2659 found_config = NULL; 2660 2661 /* 2662 * User specified a name or guid. Ensure it's unique. 2663 */ 2664 idata.unique = B_TRUE; 2665 } 2666 2667 2668 idata.path = searchdirs; 2669 idata.paths = nsearch; 2670 idata.poolname = searchname; 2671 idata.guid = searchguid; 2672 idata.cachefile = cachefile; 2673 idata.policy = policy; 2674 2675 pools = zpool_search_import(g_zfs, &idata); 2676 2677 if (pools != NULL && idata.exists && 2678 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) { 2679 (void) fprintf(stderr, gettext("cannot import '%s': " 2680 "a pool with that name already exists\n"), 2681 argv[0]); 2682 (void) fprintf(stderr, gettext("use the form 'zpool import " 2683 "[-t] <pool | id> <newpool>' to give it a new temporary " 2684 "or permanent name\n")); 2685 err = 1; 2686 } else if (pools == NULL && idata.exists) { 2687 (void) fprintf(stderr, gettext("cannot import '%s': " 2688 "a pool with that name is already created/imported,\n"), 2689 argv[0]); 2690 (void) fprintf(stderr, gettext("and no additional pools " 2691 "with that name were found\n")); 2692 err = 1; 2693 } else if (pools == NULL) { 2694 if (argc != 0) { 2695 (void) fprintf(stderr, gettext("cannot import '%s': " 2696 "no such pool available\n"), argv[0]); 2697 } 2698 err = 1; 2699 } 2700 2701 if (err == 1) { 2702 free(searchdirs); 2703 nvlist_free(policy); 2704 return (1); 2705 } 2706 2707 /* 2708 * At this point we have a list of import candidate configs. Even if 2709 * we were searching by pool name or guid, we still need to 2710 * post-process the list to deal with pool state and possible 2711 * duplicate names. 2712 */ 2713 err = 0; 2714 elem = NULL; 2715 first = B_TRUE; 2716 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 2717 2718 verify(nvpair_value_nvlist(elem, &config) == 0); 2719 2720 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 2721 &pool_state) == 0); 2722 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 2723 continue; 2724 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 2725 continue; 2726 2727 verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY, 2728 policy) == 0); 2729 2730 if (argc == 0) { 2731 if (first) 2732 first = B_FALSE; 2733 else if (!do_all) 2734 (void) printf("\n"); 2735 2736 if (do_all) { 2737 err |= do_import(config, NULL, mntopts, 2738 props, flags); 2739 } else { 2740 show_import(config); 2741 } 2742 } else if (searchname != NULL) { 2743 char *name; 2744 2745 /* 2746 * We are searching for a pool based on name. 2747 */ 2748 verify(nvlist_lookup_string(config, 2749 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 2750 2751 if (strcmp(name, searchname) == 0) { 2752 if (found_config != NULL) { 2753 (void) fprintf(stderr, gettext( 2754 "cannot import '%s': more than " 2755 "one matching pool\n"), searchname); 2756 (void) fprintf(stderr, gettext( 2757 "import by numeric ID instead\n")); 2758 err = B_TRUE; 2759 } 2760 found_config = config; 2761 } 2762 } else { 2763 uint64_t guid; 2764 2765 /* 2766 * Search for a pool by guid. 2767 */ 2768 verify(nvlist_lookup_uint64(config, 2769 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 2770 2771 if (guid == searchguid) 2772 found_config = config; 2773 } 2774 } 2775 2776 /* 2777 * If we were searching for a specific pool, verify that we found a 2778 * pool, and then do the import. 2779 */ 2780 if (argc != 0 && err == 0) { 2781 if (found_config == NULL) { 2782 (void) fprintf(stderr, gettext("cannot import '%s': " 2783 "no such pool available\n"), argv[0]); 2784 err = B_TRUE; 2785 } else { 2786 err |= do_import(found_config, argc == 1 ? NULL : 2787 argv[1], mntopts, props, flags); 2788 } 2789 } 2790 2791 /* 2792 * If we were just looking for pools, report an error if none were 2793 * found. 2794 */ 2795 if (argc == 0 && first) 2796 (void) fprintf(stderr, 2797 gettext("no pools available to import\n")); 2798 2799 error: 2800 nvlist_free(props); 2801 nvlist_free(pools); 2802 nvlist_free(policy); 2803 free(searchdirs); 2804 2805 return (err ? 1 : 0); 2806 } 2807 2808 /* 2809 * zpool sync [-f] [pool] ... 2810 * 2811 * -f (undocumented) force uberblock (and config including zpool cache file) 2812 * update. 2813 * 2814 * Sync the specified pool(s). 2815 * Without arguments "zpool sync" will sync all pools. 2816 * This command initiates TXG sync(s) and will return after the TXG(s) commit. 2817 * 2818 */ 2819 static int 2820 zpool_do_sync(int argc, char **argv) 2821 { 2822 int ret; 2823 boolean_t force = B_FALSE; 2824 2825 /* check options */ 2826 while ((ret = getopt(argc, argv, "f")) != -1) { 2827 switch (ret) { 2828 case 'f': 2829 force = B_TRUE; 2830 break; 2831 case '?': 2832 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2833 optopt); 2834 usage(B_FALSE); 2835 } 2836 } 2837 2838 argc -= optind; 2839 argv += optind; 2840 2841 /* if argc == 0 we will execute zpool_sync_one on all pools */ 2842 ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force); 2843 2844 return (ret); 2845 } 2846 2847 typedef struct iostat_cbdata { 2848 boolean_t cb_verbose; 2849 int cb_name_flags; 2850 int cb_namewidth; 2851 int cb_iteration; 2852 boolean_t cb_scripted; 2853 zpool_list_t *cb_list; 2854 } iostat_cbdata_t; 2855 2856 static void 2857 print_iostat_separator(iostat_cbdata_t *cb) 2858 { 2859 int i = 0; 2860 2861 for (i = 0; i < cb->cb_namewidth; i++) 2862 (void) printf("-"); 2863 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 2864 } 2865 2866 static void 2867 print_iostat_header(iostat_cbdata_t *cb) 2868 { 2869 (void) printf("%*s capacity operations bandwidth\n", 2870 cb->cb_namewidth, ""); 2871 (void) printf("%-*s alloc free read write read write\n", 2872 cb->cb_namewidth, "pool"); 2873 print_iostat_separator(cb); 2874 } 2875 2876 /* 2877 * Display a single statistic. 2878 */ 2879 static void 2880 print_one_stat(uint64_t value) 2881 { 2882 char buf[64]; 2883 2884 zfs_nicenum(value, buf, sizeof (buf)); 2885 (void) printf(" %5s", buf); 2886 } 2887 2888 static const char *class_name[] = { 2889 VDEV_ALLOC_BIAS_DEDUP, 2890 VDEV_ALLOC_BIAS_SPECIAL, 2891 VDEV_ALLOC_CLASS_LOGS 2892 }; 2893 2894 /* 2895 * Print out all the statistics for the given vdev. This can either be the 2896 * toplevel configuration, or called recursively. If 'name' is NULL, then this 2897 * is a verbose output, and we don't want to display the toplevel pool stats. 2898 */ 2899 static void 2900 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 2901 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 2902 { 2903 nvlist_t **oldchild, **newchild; 2904 uint_t c, children; 2905 vdev_stat_t *oldvs, *newvs; 2906 vdev_stat_t zerovs = { 0 }; 2907 char *vname; 2908 uint64_t tdelta; 2909 double scale; 2910 2911 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 2912 return; 2913 2914 if (oldnv != NULL) { 2915 verify(nvlist_lookup_uint64_array(oldnv, 2916 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0); 2917 } else { 2918 oldvs = &zerovs; 2919 } 2920 2921 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS, 2922 (uint64_t **)&newvs, &c) == 0); 2923 2924 if (strlen(name) + depth > cb->cb_namewidth) 2925 (void) printf("%*s%s", depth, "", name); 2926 else 2927 (void) printf("%*s%s%*s", depth, "", name, 2928 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 2929 2930 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 2931 2932 if (tdelta == 0) 2933 scale = 1.0; 2934 else 2935 scale = (double)NANOSEC / tdelta; 2936 2937 /* only toplevel vdevs have capacity stats */ 2938 if (newvs->vs_space == 0) { 2939 (void) printf(" - -"); 2940 } else { 2941 print_one_stat(newvs->vs_alloc); 2942 print_one_stat(newvs->vs_space - newvs->vs_alloc); 2943 } 2944 2945 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 2946 oldvs->vs_ops[ZIO_TYPE_READ]))); 2947 2948 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 2949 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 2950 2951 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 2952 oldvs->vs_bytes[ZIO_TYPE_READ]))); 2953 2954 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 2955 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 2956 2957 (void) printf("\n"); 2958 2959 if (!cb->cb_verbose) 2960 return; 2961 2962 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 2963 &newchild, &children) != 0) 2964 return; 2965 2966 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 2967 &oldchild, &c) != 0) 2968 return; 2969 2970 /* 2971 * print normal top-level devices 2972 */ 2973 for (c = 0; c < children; c++) { 2974 uint64_t ishole = B_FALSE, islog = B_FALSE; 2975 2976 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE, 2977 &ishole); 2978 2979 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG, 2980 &islog); 2981 2982 if (ishole || islog) 2983 continue; 2984 2985 if (nvlist_exists(newchild[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 2986 continue; 2987 2988 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 2989 cb->cb_name_flags); 2990 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 2991 newchild[c], cb, depth + 2); 2992 free(vname); 2993 } 2994 2995 /* 2996 * print all other top-level devices 2997 */ 2998 for (uint_t n = 0; n < 3; n++) { 2999 for (c = 0; c < children; c++) { 3000 uint64_t islog = B_FALSE; 3001 char *bias = NULL; 3002 char *type = NULL; 3003 3004 (void) nvlist_lookup_uint64(newchild[c], 3005 ZPOOL_CONFIG_IS_LOG, &islog); 3006 if (islog) { 3007 bias = VDEV_ALLOC_CLASS_LOGS; 3008 } else { 3009 (void) nvlist_lookup_string(newchild[c], 3010 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 3011 (void) nvlist_lookup_string(newchild[c], 3012 ZPOOL_CONFIG_TYPE, &type); 3013 } 3014 if (bias == NULL || strcmp(bias, class_name[n]) != 0) 3015 continue; 3016 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 3017 continue; 3018 3019 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 3020 cb->cb_name_flags); 3021 print_vdev_stats(zhp, vname, oldnv ? 3022 oldchild[c] : NULL, newchild[c], cb, depth + 2); 3023 free(vname); 3024 } 3025 3026 } 3027 3028 /* 3029 * Include level 2 ARC devices in iostat output 3030 */ 3031 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 3032 &newchild, &children) != 0) 3033 return; 3034 3035 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 3036 &oldchild, &c) != 0) 3037 return; 3038 3039 if (children > 0) { 3040 (void) printf("%-*s - - - - - " 3041 "-\n", cb->cb_namewidth, "cache"); 3042 for (c = 0; c < children; c++) { 3043 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 3044 cb->cb_name_flags); 3045 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 3046 newchild[c], cb, depth + 2); 3047 free(vname); 3048 } 3049 } 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