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