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