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