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_LOAD_REQUEST_TXG, txg) != 0 || 2329 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 2330 rewind_policy) != 0) 2331 goto error; 2332 2333 if (searchdirs == NULL) { 2334 searchdirs = safe_malloc(sizeof (char *)); 2335 searchdirs[0] = ZFS_DISK_ROOT; 2336 nsearch = 1; 2337 } 2338 2339 /* check argument count */ 2340 if (do_all) { 2341 if (argc != 0) { 2342 (void) fprintf(stderr, gettext("too many arguments\n")); 2343 usage(B_FALSE); 2344 } 2345 } else { 2346 if (argc > 2) { 2347 (void) fprintf(stderr, gettext("too many arguments\n")); 2348 usage(B_FALSE); 2349 } 2350 2351 /* 2352 * Check for the SYS_CONFIG privilege. We do this explicitly 2353 * here because otherwise any attempt to discover pools will 2354 * silently fail. 2355 */ 2356 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 2357 (void) fprintf(stderr, gettext("cannot " 2358 "discover pools: permission denied\n")); 2359 free(searchdirs); 2360 nvlist_free(policy); 2361 return (1); 2362 } 2363 } 2364 2365 /* 2366 * Depending on the arguments given, we do one of the following: 2367 * 2368 * <none> Iterate through all pools and display information about 2369 * each one. 2370 * 2371 * -a Iterate through all pools and try to import each one. 2372 * 2373 * <id> Find the pool that corresponds to the given GUID/pool 2374 * name and import that one. 2375 * 2376 * -D Above options applies only to destroyed pools. 2377 */ 2378 if (argc != 0) { 2379 char *endptr; 2380 2381 errno = 0; 2382 searchguid = strtoull(argv[0], &endptr, 10); 2383 if (errno != 0 || *endptr != '\0') { 2384 searchname = argv[0]; 2385 searchguid = 0; 2386 } 2387 found_config = NULL; 2388 2389 /* 2390 * User specified a name or guid. Ensure it's unique. 2391 */ 2392 idata.unique = B_TRUE; 2393 } 2394 2395 2396 idata.path = searchdirs; 2397 idata.paths = nsearch; 2398 idata.poolname = searchname; 2399 idata.guid = searchguid; 2400 idata.cachefile = cachefile; 2401 idata.policy = policy; 2402 2403 pools = zpool_search_import(g_zfs, &idata); 2404 2405 if (pools != NULL && idata.exists && 2406 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) { 2407 (void) fprintf(stderr, gettext("cannot import '%s': " 2408 "a pool with that name already exists\n"), 2409 argv[0]); 2410 (void) fprintf(stderr, gettext("use the form '%s " 2411 "<pool | id> <newpool>' to give it a new name\n"), 2412 "zpool import"); 2413 err = 1; 2414 } else if (pools == NULL && idata.exists) { 2415 (void) fprintf(stderr, gettext("cannot import '%s': " 2416 "a pool with that name is already created/imported,\n"), 2417 argv[0]); 2418 (void) fprintf(stderr, gettext("and no additional pools " 2419 "with that name were found\n")); 2420 err = 1; 2421 } else if (pools == NULL) { 2422 if (argc != 0) { 2423 (void) fprintf(stderr, gettext("cannot import '%s': " 2424 "no such pool available\n"), argv[0]); 2425 } 2426 err = 1; 2427 } 2428 2429 if (err == 1) { 2430 free(searchdirs); 2431 nvlist_free(policy); 2432 return (1); 2433 } 2434 2435 /* 2436 * At this point we have a list of import candidate configs. Even if 2437 * we were searching by pool name or guid, we still need to 2438 * post-process the list to deal with pool state and possible 2439 * duplicate names. 2440 */ 2441 err = 0; 2442 elem = NULL; 2443 first = B_TRUE; 2444 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 2445 2446 verify(nvpair_value_nvlist(elem, &config) == 0); 2447 2448 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 2449 &pool_state) == 0); 2450 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 2451 continue; 2452 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 2453 continue; 2454 2455 verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY, 2456 policy) == 0); 2457 2458 if (argc == 0) { 2459 if (first) 2460 first = B_FALSE; 2461 else if (!do_all) 2462 (void) printf("\n"); 2463 2464 if (do_all) { 2465 err |= do_import(config, NULL, mntopts, 2466 props, flags); 2467 } else { 2468 show_import(config); 2469 } 2470 } else if (searchname != NULL) { 2471 char *name; 2472 2473 /* 2474 * We are searching for a pool based on name. 2475 */ 2476 verify(nvlist_lookup_string(config, 2477 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 2478 2479 if (strcmp(name, searchname) == 0) { 2480 if (found_config != NULL) { 2481 (void) fprintf(stderr, gettext( 2482 "cannot import '%s': more than " 2483 "one matching pool\n"), searchname); 2484 (void) fprintf(stderr, gettext( 2485 "import by numeric ID instead\n")); 2486 err = B_TRUE; 2487 } 2488 found_config = config; 2489 } 2490 } else { 2491 uint64_t guid; 2492 2493 /* 2494 * Search for a pool by guid. 2495 */ 2496 verify(nvlist_lookup_uint64(config, 2497 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 2498 2499 if (guid == searchguid) 2500 found_config = config; 2501 } 2502 } 2503 2504 /* 2505 * If we were searching for a specific pool, verify that we found a 2506 * pool, and then do the import. 2507 */ 2508 if (argc != 0 && err == 0) { 2509 if (found_config == NULL) { 2510 (void) fprintf(stderr, gettext("cannot import '%s': " 2511 "no such pool available\n"), argv[0]); 2512 err = B_TRUE; 2513 } else { 2514 err |= do_import(found_config, argc == 1 ? NULL : 2515 argv[1], mntopts, props, flags); 2516 } 2517 } 2518 2519 /* 2520 * If we were just looking for pools, report an error if none were 2521 * found. 2522 */ 2523 if (argc == 0 && first) 2524 (void) fprintf(stderr, 2525 gettext("no pools available to import\n")); 2526 2527 error: 2528 nvlist_free(props); 2529 nvlist_free(pools); 2530 nvlist_free(policy); 2531 free(searchdirs); 2532 2533 return (err ? 1 : 0); 2534 } 2535 2536 typedef struct iostat_cbdata { 2537 boolean_t cb_verbose; 2538 int cb_namewidth; 2539 int cb_iteration; 2540 zpool_list_t *cb_list; 2541 } iostat_cbdata_t; 2542 2543 static void 2544 print_iostat_separator(iostat_cbdata_t *cb) 2545 { 2546 int i = 0; 2547 2548 for (i = 0; i < cb->cb_namewidth; i++) 2549 (void) printf("-"); 2550 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 2551 } 2552 2553 static void 2554 print_iostat_header(iostat_cbdata_t *cb) 2555 { 2556 (void) printf("%*s capacity operations bandwidth\n", 2557 cb->cb_namewidth, ""); 2558 (void) printf("%-*s alloc free read write read write\n", 2559 cb->cb_namewidth, "pool"); 2560 print_iostat_separator(cb); 2561 } 2562 2563 /* 2564 * Display a single statistic. 2565 */ 2566 static void 2567 print_one_stat(uint64_t value) 2568 { 2569 char buf[64]; 2570 2571 zfs_nicenum(value, buf, sizeof (buf)); 2572 (void) printf(" %5s", buf); 2573 } 2574 2575 /* 2576 * Print out all the statistics for the given vdev. This can either be the 2577 * toplevel configuration, or called recursively. If 'name' is NULL, then this 2578 * is a verbose output, and we don't want to display the toplevel pool stats. 2579 */ 2580 void 2581 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 2582 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 2583 { 2584 nvlist_t **oldchild, **newchild; 2585 uint_t c, children; 2586 vdev_stat_t *oldvs, *newvs; 2587 vdev_stat_t zerovs = { 0 }; 2588 uint64_t tdelta; 2589 double scale; 2590 char *vname; 2591 2592 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 2593 return; 2594 2595 if (oldnv != NULL) { 2596 verify(nvlist_lookup_uint64_array(oldnv, 2597 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0); 2598 } else { 2599 oldvs = &zerovs; 2600 } 2601 2602 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS, 2603 (uint64_t **)&newvs, &c) == 0); 2604 2605 if (strlen(name) + depth > cb->cb_namewidth) 2606 (void) printf("%*s%s", depth, "", name); 2607 else 2608 (void) printf("%*s%s%*s", depth, "", name, 2609 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 2610 2611 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 2612 2613 if (tdelta == 0) 2614 scale = 1.0; 2615 else 2616 scale = (double)NANOSEC / tdelta; 2617 2618 /* only toplevel vdevs have capacity stats */ 2619 if (newvs->vs_space == 0) { 2620 (void) printf(" - -"); 2621 } else { 2622 print_one_stat(newvs->vs_alloc); 2623 print_one_stat(newvs->vs_space - newvs->vs_alloc); 2624 } 2625 2626 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 2627 oldvs->vs_ops[ZIO_TYPE_READ]))); 2628 2629 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 2630 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 2631 2632 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 2633 oldvs->vs_bytes[ZIO_TYPE_READ]))); 2634 2635 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 2636 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 2637 2638 (void) printf("\n"); 2639 2640 if (!cb->cb_verbose) 2641 return; 2642 2643 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 2644 &newchild, &children) != 0) 2645 return; 2646 2647 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 2648 &oldchild, &c) != 0) 2649 return; 2650 2651 for (c = 0; c < children; c++) { 2652 uint64_t ishole = B_FALSE, islog = B_FALSE; 2653 2654 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE, 2655 &ishole); 2656 2657 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG, 2658 &islog); 2659 2660 if (ishole || islog) 2661 continue; 2662 2663 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE); 2664 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 2665 newchild[c], cb, depth + 2); 2666 free(vname); 2667 } 2668 2669 /* 2670 * Log device section 2671 */ 2672 2673 if (num_logs(newnv) > 0) { 2674 (void) printf("%-*s - - - - - " 2675 "-\n", cb->cb_namewidth, "logs"); 2676 2677 for (c = 0; c < children; c++) { 2678 uint64_t islog = B_FALSE; 2679 (void) nvlist_lookup_uint64(newchild[c], 2680 ZPOOL_CONFIG_IS_LOG, &islog); 2681 2682 if (islog) { 2683 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 2684 B_FALSE); 2685 print_vdev_stats(zhp, vname, oldnv ? 2686 oldchild[c] : NULL, newchild[c], 2687 cb, depth + 2); 2688 free(vname); 2689 } 2690 } 2691 2692 } 2693 2694 /* 2695 * Include level 2 ARC devices in iostat output 2696 */ 2697 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 2698 &newchild, &children) != 0) 2699 return; 2700 2701 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 2702 &oldchild, &c) != 0) 2703 return; 2704 2705 if (children > 0) { 2706 (void) printf("%-*s - - - - - " 2707 "-\n", cb->cb_namewidth, "cache"); 2708 for (c = 0; c < children; c++) { 2709 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 2710 B_FALSE); 2711 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 2712 newchild[c], cb, depth + 2); 2713 free(vname); 2714 } 2715 } 2716 } 2717 2718 static int 2719 refresh_iostat(zpool_handle_t *zhp, void *data) 2720 { 2721 iostat_cbdata_t *cb = data; 2722 boolean_t missing; 2723 2724 /* 2725 * If the pool has disappeared, remove it from the list and continue. 2726 */ 2727 if (zpool_refresh_stats(zhp, &missing) != 0) 2728 return (-1); 2729 2730 if (missing) 2731 pool_list_remove(cb->cb_list, zhp); 2732 2733 return (0); 2734 } 2735 2736 /* 2737 * Callback to print out the iostats for the given pool. 2738 */ 2739 int 2740 print_iostat(zpool_handle_t *zhp, void *data) 2741 { 2742 iostat_cbdata_t *cb = data; 2743 nvlist_t *oldconfig, *newconfig; 2744 nvlist_t *oldnvroot, *newnvroot; 2745 2746 newconfig = zpool_get_config(zhp, &oldconfig); 2747 2748 if (cb->cb_iteration == 1) 2749 oldconfig = NULL; 2750 2751 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 2752 &newnvroot) == 0); 2753 2754 if (oldconfig == NULL) 2755 oldnvroot = NULL; 2756 else 2757 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 2758 &oldnvroot) == 0); 2759 2760 /* 2761 * Print out the statistics for the pool. 2762 */ 2763 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 2764 2765 if (cb->cb_verbose) 2766 print_iostat_separator(cb); 2767 2768 return (0); 2769 } 2770 2771 int 2772 get_namewidth(zpool_handle_t *zhp, void *data) 2773 { 2774 iostat_cbdata_t *cb = data; 2775 nvlist_t *config, *nvroot; 2776 2777 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 2778 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2779 &nvroot) == 0); 2780 if (!cb->cb_verbose) 2781 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 2782 else 2783 cb->cb_namewidth = max_width(zhp, nvroot, 0, 2784 cb->cb_namewidth); 2785 } 2786 2787 /* 2788 * The width must fall into the range [10,38]. The upper limit is the 2789 * maximum we can have and still fit in 80 columns. 2790 */ 2791 if (cb->cb_namewidth < 10) 2792 cb->cb_namewidth = 10; 2793 if (cb->cb_namewidth > 38) 2794 cb->cb_namewidth = 38; 2795 2796 return (0); 2797 } 2798 2799 /* 2800 * Parse the input string, get the 'interval' and 'count' value if there is one. 2801 */ 2802 static void 2803 get_interval_count(int *argcp, char **argv, unsigned long *iv, 2804 unsigned long *cnt) 2805 { 2806 unsigned long interval = 0, count = 0; 2807 int argc = *argcp, errno; 2808 2809 /* 2810 * Determine if the last argument is an integer or a pool name 2811 */ 2812 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2813 char *end; 2814 2815 errno = 0; 2816 interval = strtoul(argv[argc - 1], &end, 10); 2817 2818 if (*end == '\0' && errno == 0) { 2819 if (interval == 0) { 2820 (void) fprintf(stderr, gettext("interval " 2821 "cannot be zero\n")); 2822 usage(B_FALSE); 2823 } 2824 /* 2825 * Ignore the last parameter 2826 */ 2827 argc--; 2828 } else { 2829 /* 2830 * If this is not a valid number, just plow on. The 2831 * user will get a more informative error message later 2832 * on. 2833 */ 2834 interval = 0; 2835 } 2836 } 2837 2838 /* 2839 * If the last argument is also an integer, then we have both a count 2840 * and an interval. 2841 */ 2842 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2843 char *end; 2844 2845 errno = 0; 2846 count = interval; 2847 interval = strtoul(argv[argc - 1], &end, 10); 2848 2849 if (*end == '\0' && errno == 0) { 2850 if (interval == 0) { 2851 (void) fprintf(stderr, gettext("interval " 2852 "cannot be zero\n")); 2853 usage(B_FALSE); 2854 } 2855 2856 /* 2857 * Ignore the last parameter 2858 */ 2859 argc--; 2860 } else { 2861 interval = 0; 2862 } 2863 } 2864 2865 *iv = interval; 2866 *cnt = count; 2867 *argcp = argc; 2868 } 2869 2870 static void 2871 get_timestamp_arg(char c) 2872 { 2873 if (c == 'u') 2874 timestamp_fmt = UDATE; 2875 else if (c == 'd') 2876 timestamp_fmt = DDATE; 2877 else 2878 usage(B_FALSE); 2879 } 2880 2881 /* 2882 * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]] 2883 * 2884 * -v Display statistics for individual vdevs 2885 * -T Display a timestamp in date(1) or Unix format 2886 * 2887 * This command can be tricky because we want to be able to deal with pool 2888 * creation/destruction as well as vdev configuration changes. The bulk of this 2889 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 2890 * on pool_list_update() to detect the addition of new pools. Configuration 2891 * changes are all handled within libzfs. 2892 */ 2893 int 2894 zpool_do_iostat(int argc, char **argv) 2895 { 2896 int c; 2897 int ret; 2898 int npools; 2899 unsigned long interval = 0, count = 0; 2900 zpool_list_t *list; 2901 boolean_t verbose = B_FALSE; 2902 iostat_cbdata_t cb; 2903 2904 /* check options */ 2905 while ((c = getopt(argc, argv, "T:v")) != -1) { 2906 switch (c) { 2907 case 'T': 2908 get_timestamp_arg(*optarg); 2909 break; 2910 case 'v': 2911 verbose = B_TRUE; 2912 break; 2913 case '?': 2914 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2915 optopt); 2916 usage(B_FALSE); 2917 } 2918 } 2919 2920 argc -= optind; 2921 argv += optind; 2922 2923 get_interval_count(&argc, argv, &interval, &count); 2924 2925 /* 2926 * Construct the list of all interesting pools. 2927 */ 2928 ret = 0; 2929 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL) 2930 return (1); 2931 2932 if (pool_list_count(list) == 0 && argc != 0) { 2933 pool_list_free(list); 2934 return (1); 2935 } 2936 2937 if (pool_list_count(list) == 0 && interval == 0) { 2938 pool_list_free(list); 2939 (void) fprintf(stderr, gettext("no pools available\n")); 2940 return (1); 2941 } 2942 2943 /* 2944 * Enter the main iostat loop. 2945 */ 2946 cb.cb_list = list; 2947 cb.cb_verbose = verbose; 2948 cb.cb_iteration = 0; 2949 cb.cb_namewidth = 0; 2950 2951 for (;;) { 2952 pool_list_update(list); 2953 2954 if ((npools = pool_list_count(list)) == 0) 2955 break; 2956 2957 /* 2958 * Refresh all statistics. This is done as an explicit step 2959 * before calculating the maximum name width, so that any 2960 * configuration changes are properly accounted for. 2961 */ 2962 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 2963 2964 /* 2965 * Iterate over all pools to determine the maximum width 2966 * for the pool / device name column across all pools. 2967 */ 2968 cb.cb_namewidth = 0; 2969 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 2970 2971 if (timestamp_fmt != NODATE) 2972 print_timestamp(timestamp_fmt); 2973 2974 /* 2975 * If it's the first time, or verbose mode, print the header. 2976 */ 2977 if (++cb.cb_iteration == 1 || verbose) 2978 print_iostat_header(&cb); 2979 2980 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 2981 2982 /* 2983 * If there's more than one pool, and we're not in verbose mode 2984 * (which prints a separator for us), then print a separator. 2985 */ 2986 if (npools > 1 && !verbose) 2987 print_iostat_separator(&cb); 2988 2989 if (verbose) 2990 (void) printf("\n"); 2991 2992 /* 2993 * Flush the output so that redirection to a file isn't buffered 2994 * indefinitely. 2995 */ 2996 (void) fflush(stdout); 2997 2998 if (interval == 0) 2999 break; 3000 3001 if (count != 0 && --count == 0) 3002 break; 3003 3004 (void) sleep(interval); 3005 } 3006 3007 pool_list_free(list); 3008 3009 return (ret); 3010 } 3011 3012 typedef struct list_cbdata { 3013 boolean_t cb_verbose; 3014 int cb_namewidth; 3015 boolean_t cb_scripted; 3016 zprop_list_t *cb_proplist; 3017 boolean_t cb_literal; 3018 } list_cbdata_t; 3019 3020 /* 3021 * Given a list of columns to display, output appropriate headers for each one. 3022 */ 3023 static void 3024 print_header(list_cbdata_t *cb) 3025 { 3026 zprop_list_t *pl = cb->cb_proplist; 3027 char headerbuf[ZPOOL_MAXPROPLEN]; 3028 const char *header; 3029 boolean_t first = B_TRUE; 3030 boolean_t right_justify; 3031 size_t width = 0; 3032 3033 for (; pl != NULL; pl = pl->pl_next) { 3034 width = pl->pl_width; 3035 if (first && cb->cb_verbose) { 3036 /* 3037 * Reset the width to accommodate the verbose listing 3038 * of devices. 3039 */ 3040 width = cb->cb_namewidth; 3041 } 3042 3043 if (!first) 3044 (void) printf(" "); 3045 else 3046 first = B_FALSE; 3047 3048 right_justify = B_FALSE; 3049 if (pl->pl_prop != ZPROP_INVAL) { 3050 header = zpool_prop_column_name(pl->pl_prop); 3051 right_justify = zpool_prop_align_right(pl->pl_prop); 3052 } else { 3053 int i; 3054 3055 for (i = 0; pl->pl_user_prop[i] != '\0'; i++) 3056 headerbuf[i] = toupper(pl->pl_user_prop[i]); 3057 headerbuf[i] = '\0'; 3058 header = headerbuf; 3059 } 3060 3061 if (pl->pl_next == NULL && !right_justify) 3062 (void) printf("%s", header); 3063 else if (right_justify) 3064 (void) printf("%*s", width, header); 3065 else 3066 (void) printf("%-*s", width, header); 3067 3068 } 3069 3070 (void) printf("\n"); 3071 } 3072 3073 /* 3074 * Given a pool and a list of properties, print out all the properties according 3075 * to the described layout. 3076 */ 3077 static void 3078 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) 3079 { 3080 zprop_list_t *pl = cb->cb_proplist; 3081 boolean_t first = B_TRUE; 3082 char property[ZPOOL_MAXPROPLEN]; 3083 char *propstr; 3084 boolean_t right_justify; 3085 size_t width; 3086 3087 for (; pl != NULL; pl = pl->pl_next) { 3088 3089 width = pl->pl_width; 3090 if (first && cb->cb_verbose) { 3091 /* 3092 * Reset the width to accommodate the verbose listing 3093 * of devices. 3094 */ 3095 width = cb->cb_namewidth; 3096 } 3097 3098 if (!first) { 3099 if (cb->cb_scripted) 3100 (void) printf("\t"); 3101 else 3102 (void) printf(" "); 3103 } else { 3104 first = B_FALSE; 3105 } 3106 3107 right_justify = B_FALSE; 3108 if (pl->pl_prop != ZPROP_INVAL) { 3109 if (zpool_get_prop(zhp, pl->pl_prop, property, 3110 sizeof (property), NULL, cb->cb_literal) != 0) 3111 propstr = "-"; 3112 else 3113 propstr = property; 3114 3115 right_justify = zpool_prop_align_right(pl->pl_prop); 3116 } else if ((zpool_prop_feature(pl->pl_user_prop) || 3117 zpool_prop_unsupported(pl->pl_user_prop)) && 3118 zpool_prop_get_feature(zhp, pl->pl_user_prop, property, 3119 sizeof (property)) == 0) { 3120 propstr = property; 3121 } else { 3122 propstr = "-"; 3123 } 3124 3125 3126 /* 3127 * If this is being called in scripted mode, or if this is the 3128 * last column and it is left-justified, don't include a width 3129 * format specifier. 3130 */ 3131 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) 3132 (void) printf("%s", propstr); 3133 else if (right_justify) 3134 (void) printf("%*s", width, propstr); 3135 else 3136 (void) printf("%-*s", width, propstr); 3137 } 3138 3139 (void) printf("\n"); 3140 } 3141 3142 static void 3143 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted, 3144 boolean_t valid) 3145 { 3146 char propval[64]; 3147 boolean_t fixed; 3148 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL); 3149 3150 switch (prop) { 3151 case ZPOOL_PROP_EXPANDSZ: 3152 case ZPOOL_PROP_CHECKPOINT: 3153 if (value == 0) 3154 (void) strlcpy(propval, "-", sizeof (propval)); 3155 else 3156 zfs_nicenum(value, propval, sizeof (propval)); 3157 break; 3158 case ZPOOL_PROP_FRAGMENTATION: 3159 if (value == ZFS_FRAG_INVALID) { 3160 (void) strlcpy(propval, "-", sizeof (propval)); 3161 } else { 3162 (void) snprintf(propval, sizeof (propval), "%llu%%", 3163 value); 3164 } 3165 break; 3166 case ZPOOL_PROP_CAPACITY: 3167 (void) snprintf(propval, sizeof (propval), "%llu%%", value); 3168 break; 3169 default: 3170 zfs_nicenum(value, propval, sizeof (propval)); 3171 } 3172 3173 if (!valid) 3174 (void) strlcpy(propval, "-", sizeof (propval)); 3175 3176 if (scripted) 3177 (void) printf("\t%s", propval); 3178 else 3179 (void) printf(" %*s", width, propval); 3180 } 3181 3182 void 3183 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 3184 list_cbdata_t *cb, int depth) 3185 { 3186 nvlist_t **child; 3187 vdev_stat_t *vs; 3188 uint_t c, children; 3189 char *vname; 3190 boolean_t scripted = cb->cb_scripted; 3191 uint64_t islog = B_FALSE; 3192 boolean_t haslog = B_FALSE; 3193 char *dashes = "%-*s - - - - - -\n"; 3194 3195 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 3196 (uint64_t **)&vs, &c) == 0); 3197 3198 if (name != NULL) { 3199 boolean_t toplevel = (vs->vs_space != 0); 3200 uint64_t cap; 3201 3202 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 3203 return; 3204 3205 if (scripted) 3206 (void) printf("\t%s", name); 3207 else if (strlen(name) + depth > cb->cb_namewidth) 3208 (void) printf("%*s%s", depth, "", name); 3209 else 3210 (void) printf("%*s%s%*s", depth, "", name, 3211 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 3212 3213 /* 3214 * Print the properties for the individual vdevs. Some 3215 * properties are only applicable to toplevel vdevs. The 3216 * 'toplevel' boolean value is passed to the print_one_column() 3217 * to indicate that the value is valid. 3218 */ 3219 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted, 3220 toplevel); 3221 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted, 3222 toplevel); 3223 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc, 3224 scripted, toplevel); 3225 print_one_column(ZPOOL_PROP_CHECKPOINT, 3226 vs->vs_checkpoint_space, scripted, toplevel); 3227 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted, 3228 B_TRUE); 3229 print_one_column(ZPOOL_PROP_FRAGMENTATION, 3230 vs->vs_fragmentation, scripted, 3231 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel)); 3232 cap = (vs->vs_space == 0) ? 0 : 3233 (vs->vs_alloc * 100 / vs->vs_space); 3234 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel); 3235 (void) printf("\n"); 3236 } 3237 3238 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 3239 &child, &children) != 0) 3240 return; 3241 3242 for (c = 0; c < children; c++) { 3243 uint64_t ishole = B_FALSE; 3244 3245 if (nvlist_lookup_uint64(child[c], 3246 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) 3247 continue; 3248 3249 if (nvlist_lookup_uint64(child[c], 3250 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) { 3251 haslog = B_TRUE; 3252 continue; 3253 } 3254 3255 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3256 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3257 free(vname); 3258 } 3259 3260 if (haslog == B_TRUE) { 3261 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3262 (void) printf(dashes, cb->cb_namewidth, "log"); 3263 for (c = 0; c < children; c++) { 3264 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 3265 &islog) != 0 || !islog) 3266 continue; 3267 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3268 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3269 free(vname); 3270 } 3271 } 3272 3273 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 3274 &child, &children) == 0 && children > 0) { 3275 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3276 (void) printf(dashes, cb->cb_namewidth, "cache"); 3277 for (c = 0; c < children; c++) { 3278 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3279 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3280 free(vname); 3281 } 3282 } 3283 3284 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child, 3285 &children) == 0 && children > 0) { 3286 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3287 (void) printf(dashes, cb->cb_namewidth, "spare"); 3288 for (c = 0; c < children; c++) { 3289 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3290 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3291 free(vname); 3292 } 3293 } 3294 } 3295 3296 3297 /* 3298 * Generic callback function to list a pool. 3299 */ 3300 int 3301 list_callback(zpool_handle_t *zhp, void *data) 3302 { 3303 list_cbdata_t *cbp = data; 3304 nvlist_t *config; 3305 nvlist_t *nvroot; 3306 3307 config = zpool_get_config(zhp, NULL); 3308 3309 print_pool(zhp, cbp); 3310 if (!cbp->cb_verbose) 3311 return (0); 3312 3313 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 3314 &nvroot) == 0); 3315 print_list_stats(zhp, NULL, nvroot, cbp, 0); 3316 3317 return (0); 3318 } 3319 3320 /* 3321 * zpool list [-Hp] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] 3322 * 3323 * -H Scripted mode. Don't display headers, and separate properties 3324 * by a single tab. 3325 * -o List of properties to display. Defaults to 3326 * "name,size,allocated,free,expandsize,fragmentation,capacity," 3327 * "dedupratio,health,altroot" 3328 * -p Diplay values in parsable (exact) format. 3329 * -T Display a timestamp in date(1) or Unix format 3330 * 3331 * List all pools in the system, whether or not they're healthy. Output space 3332 * statistics for each one, as well as health status summary. 3333 */ 3334 int 3335 zpool_do_list(int argc, char **argv) 3336 { 3337 int c; 3338 int ret; 3339 list_cbdata_t cb = { 0 }; 3340 static char default_props[] = 3341 "name,size,allocated,free,checkpoint,expandsize,fragmentation," 3342 "capacity,dedupratio,health,altroot"; 3343 char *props = default_props; 3344 unsigned long interval = 0, count = 0; 3345 zpool_list_t *list; 3346 boolean_t first = B_TRUE; 3347 3348 /* check options */ 3349 while ((c = getopt(argc, argv, ":Ho:pT:v")) != -1) { 3350 switch (c) { 3351 case 'H': 3352 cb.cb_scripted = B_TRUE; 3353 break; 3354 case 'o': 3355 props = optarg; 3356 break; 3357 case 'p': 3358 cb.cb_literal = B_TRUE; 3359 break; 3360 case 'T': 3361 get_timestamp_arg(*optarg); 3362 break; 3363 case 'v': 3364 cb.cb_verbose = B_TRUE; 3365 break; 3366 case ':': 3367 (void) fprintf(stderr, gettext("missing argument for " 3368 "'%c' option\n"), optopt); 3369 usage(B_FALSE); 3370 break; 3371 case '?': 3372 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3373 optopt); 3374 usage(B_FALSE); 3375 } 3376 } 3377 3378 argc -= optind; 3379 argv += optind; 3380 3381 get_interval_count(&argc, argv, &interval, &count); 3382 3383 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 3384 usage(B_FALSE); 3385 3386 for (;;) { 3387 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, 3388 &ret)) == NULL) 3389 return (1); 3390 3391 if (pool_list_count(list) == 0) 3392 break; 3393 3394 cb.cb_namewidth = 0; 3395 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 3396 3397 if (timestamp_fmt != NODATE) 3398 print_timestamp(timestamp_fmt); 3399 3400 if (!cb.cb_scripted && (first || cb.cb_verbose)) { 3401 print_header(&cb); 3402 first = B_FALSE; 3403 } 3404 ret = pool_list_iter(list, B_TRUE, list_callback, &cb); 3405 3406 if (interval == 0) 3407 break; 3408 3409 if (count != 0 && --count == 0) 3410 break; 3411 3412 pool_list_free(list); 3413 (void) sleep(interval); 3414 } 3415 3416 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) { 3417 (void) printf(gettext("no pools available\n")); 3418 ret = 0; 3419 } 3420 3421 pool_list_free(list); 3422 zprop_free_list(cb.cb_proplist); 3423 return (ret); 3424 } 3425 3426 static int 3427 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 3428 { 3429 boolean_t force = B_FALSE; 3430 int c; 3431 nvlist_t *nvroot; 3432 char *poolname, *old_disk, *new_disk; 3433 zpool_handle_t *zhp; 3434 zpool_boot_label_t boot_type; 3435 uint64_t boot_size; 3436 int ret; 3437 3438 /* check options */ 3439 while ((c = getopt(argc, argv, "f")) != -1) { 3440 switch (c) { 3441 case 'f': 3442 force = B_TRUE; 3443 break; 3444 case '?': 3445 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3446 optopt); 3447 usage(B_FALSE); 3448 } 3449 } 3450 3451 argc -= optind; 3452 argv += optind; 3453 3454 /* get pool name and check number of arguments */ 3455 if (argc < 1) { 3456 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3457 usage(B_FALSE); 3458 } 3459 3460 poolname = argv[0]; 3461 3462 if (argc < 2) { 3463 (void) fprintf(stderr, 3464 gettext("missing <device> specification\n")); 3465 usage(B_FALSE); 3466 } 3467 3468 old_disk = argv[1]; 3469 3470 if (argc < 3) { 3471 if (!replacing) { 3472 (void) fprintf(stderr, 3473 gettext("missing <new_device> specification\n")); 3474 usage(B_FALSE); 3475 } 3476 new_disk = old_disk; 3477 argc -= 1; 3478 argv += 1; 3479 } else { 3480 new_disk = argv[2]; 3481 argc -= 2; 3482 argv += 2; 3483 } 3484 3485 if (argc > 1) { 3486 (void) fprintf(stderr, gettext("too many arguments\n")); 3487 usage(B_FALSE); 3488 } 3489 3490 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3491 return (1); 3492 3493 if (zpool_get_config(zhp, NULL) == NULL) { 3494 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 3495 poolname); 3496 zpool_close(zhp); 3497 return (1); 3498 } 3499 3500 if (zpool_is_bootable(zhp)) 3501 boot_type = ZPOOL_COPY_BOOT_LABEL; 3502 else 3503 boot_type = ZPOOL_NO_BOOT_LABEL; 3504 3505 boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL); 3506 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, 3507 boot_type, boot_size, argc, argv); 3508 if (nvroot == NULL) { 3509 zpool_close(zhp); 3510 return (1); 3511 } 3512 3513 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 3514 3515 nvlist_free(nvroot); 3516 zpool_close(zhp); 3517 3518 return (ret); 3519 } 3520 3521 /* 3522 * zpool replace [-f] <pool> <device> <new_device> 3523 * 3524 * -f Force attach, even if <new_device> appears to be in use. 3525 * 3526 * Replace <device> with <new_device>. 3527 */ 3528 /* ARGSUSED */ 3529 int 3530 zpool_do_replace(int argc, char **argv) 3531 { 3532 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 3533 } 3534 3535 /* 3536 * zpool attach [-f] <pool> <device> <new_device> 3537 * 3538 * -f Force attach, even if <new_device> appears to be in use. 3539 * 3540 * Attach <new_device> to the mirror containing <device>. If <device> is not 3541 * part of a mirror, then <device> will be transformed into a mirror of 3542 * <device> and <new_device>. In either case, <new_device> will begin life 3543 * with a DTL of [0, now], and will immediately begin to resilver itself. 3544 */ 3545 int 3546 zpool_do_attach(int argc, char **argv) 3547 { 3548 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 3549 } 3550 3551 /* 3552 * zpool detach [-f] <pool> <device> 3553 * 3554 * -f Force detach of <device>, even if DTLs argue against it 3555 * (not supported yet) 3556 * 3557 * Detach a device from a mirror. The operation will be refused if <device> 3558 * is the last device in the mirror, or if the DTLs indicate that this device 3559 * has the only valid copy of some data. 3560 */ 3561 /* ARGSUSED */ 3562 int 3563 zpool_do_detach(int argc, char **argv) 3564 { 3565 int c; 3566 char *poolname, *path; 3567 zpool_handle_t *zhp; 3568 int ret; 3569 3570 /* check options */ 3571 while ((c = getopt(argc, argv, "f")) != -1) { 3572 switch (c) { 3573 case 'f': 3574 case '?': 3575 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3576 optopt); 3577 usage(B_FALSE); 3578 } 3579 } 3580 3581 argc -= optind; 3582 argv += optind; 3583 3584 /* get pool name and check number of arguments */ 3585 if (argc < 1) { 3586 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3587 usage(B_FALSE); 3588 } 3589 3590 if (argc < 2) { 3591 (void) fprintf(stderr, 3592 gettext("missing <device> specification\n")); 3593 usage(B_FALSE); 3594 } 3595 3596 poolname = argv[0]; 3597 path = argv[1]; 3598 3599 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3600 return (1); 3601 3602 ret = zpool_vdev_detach(zhp, path); 3603 3604 zpool_close(zhp); 3605 3606 return (ret); 3607 } 3608 3609 /* 3610 * zpool split [-n] [-o prop=val] ... 3611 * [-o mntopt] ... 3612 * [-R altroot] <pool> <newpool> [<device> ...] 3613 * 3614 * -n Do not split the pool, but display the resulting layout if 3615 * it were to be split. 3616 * -o Set property=value, or set mount options. 3617 * -R Mount the split-off pool under an alternate root. 3618 * 3619 * Splits the named pool and gives it the new pool name. Devices to be split 3620 * off may be listed, provided that no more than one device is specified 3621 * per top-level vdev mirror. The newly split pool is left in an exported 3622 * state unless -R is specified. 3623 * 3624 * Restrictions: the top-level of the pool pool must only be made up of 3625 * mirrors; all devices in the pool must be healthy; no device may be 3626 * undergoing a resilvering operation. 3627 */ 3628 int 3629 zpool_do_split(int argc, char **argv) 3630 { 3631 char *srcpool, *newpool, *propval; 3632 char *mntopts = NULL; 3633 splitflags_t flags; 3634 int c, ret = 0; 3635 zpool_handle_t *zhp; 3636 nvlist_t *config, *props = NULL; 3637 3638 flags.dryrun = B_FALSE; 3639 flags.import = B_FALSE; 3640 3641 /* check options */ 3642 while ((c = getopt(argc, argv, ":R:no:")) != -1) { 3643 switch (c) { 3644 case 'R': 3645 flags.import = B_TRUE; 3646 if (add_prop_list( 3647 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg, 3648 &props, B_TRUE) != 0) { 3649 nvlist_free(props); 3650 usage(B_FALSE); 3651 } 3652 break; 3653 case 'n': 3654 flags.dryrun = B_TRUE; 3655 break; 3656 case 'o': 3657 if ((propval = strchr(optarg, '=')) != NULL) { 3658 *propval = '\0'; 3659 propval++; 3660 if (add_prop_list(optarg, propval, 3661 &props, B_TRUE) != 0) { 3662 nvlist_free(props); 3663 usage(B_FALSE); 3664 } 3665 } else { 3666 mntopts = optarg; 3667 } 3668 break; 3669 case ':': 3670 (void) fprintf(stderr, gettext("missing argument for " 3671 "'%c' option\n"), optopt); 3672 usage(B_FALSE); 3673 break; 3674 case '?': 3675 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3676 optopt); 3677 usage(B_FALSE); 3678 break; 3679 } 3680 } 3681 3682 if (!flags.import && mntopts != NULL) { 3683 (void) fprintf(stderr, gettext("setting mntopts is only " 3684 "valid when importing the pool\n")); 3685 usage(B_FALSE); 3686 } 3687 3688 argc -= optind; 3689 argv += optind; 3690 3691 if (argc < 1) { 3692 (void) fprintf(stderr, gettext("Missing pool name\n")); 3693 usage(B_FALSE); 3694 } 3695 if (argc < 2) { 3696 (void) fprintf(stderr, gettext("Missing new pool name\n")); 3697 usage(B_FALSE); 3698 } 3699 3700 srcpool = argv[0]; 3701 newpool = argv[1]; 3702 3703 argc -= 2; 3704 argv += 2; 3705 3706 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) 3707 return (1); 3708 3709 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 3710 if (config == NULL) { 3711 ret = 1; 3712 } else { 3713 if (flags.dryrun) { 3714 (void) printf(gettext("would create '%s' with the " 3715 "following layout:\n\n"), newpool); 3716 print_vdev_tree(NULL, newpool, config, 0, B_FALSE); 3717 } 3718 nvlist_free(config); 3719 } 3720 3721 zpool_close(zhp); 3722 3723 if (ret != 0 || flags.dryrun || !flags.import) 3724 return (ret); 3725 3726 /* 3727 * The split was successful. Now we need to open the new 3728 * pool and import it. 3729 */ 3730 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) 3731 return (1); 3732 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 3733 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 3734 ret = 1; 3735 (void) fprintf(stderr, gettext("Split was successful, but " 3736 "the datasets could not all be mounted\n")); 3737 (void) fprintf(stderr, gettext("Try doing '%s' with a " 3738 "different altroot\n"), "zpool import"); 3739 } 3740 zpool_close(zhp); 3741 3742 return (ret); 3743 } 3744 3745 3746 3747 /* 3748 * zpool online <pool> <device> ... 3749 */ 3750 int 3751 zpool_do_online(int argc, char **argv) 3752 { 3753 int c, i; 3754 char *poolname; 3755 zpool_handle_t *zhp; 3756 int ret = 0; 3757 vdev_state_t newstate; 3758 int flags = 0; 3759 3760 /* check options */ 3761 while ((c = getopt(argc, argv, "et")) != -1) { 3762 switch (c) { 3763 case 'e': 3764 flags |= ZFS_ONLINE_EXPAND; 3765 break; 3766 case 't': 3767 case '?': 3768 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3769 optopt); 3770 usage(B_FALSE); 3771 } 3772 } 3773 3774 argc -= optind; 3775 argv += optind; 3776 3777 /* get pool name and check number of arguments */ 3778 if (argc < 1) { 3779 (void) fprintf(stderr, gettext("missing pool name\n")); 3780 usage(B_FALSE); 3781 } 3782 if (argc < 2) { 3783 (void) fprintf(stderr, gettext("missing device name\n")); 3784 usage(B_FALSE); 3785 } 3786 3787 poolname = argv[0]; 3788 3789 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3790 return (1); 3791 3792 for (i = 1; i < argc; i++) { 3793 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 3794 if (newstate != VDEV_STATE_HEALTHY) { 3795 (void) printf(gettext("warning: device '%s' " 3796 "onlined, but remains in faulted state\n"), 3797 argv[i]); 3798 if (newstate == VDEV_STATE_FAULTED) 3799 (void) printf(gettext("use 'zpool " 3800 "clear' to restore a faulted " 3801 "device\n")); 3802 else 3803 (void) printf(gettext("use 'zpool " 3804 "replace' to replace devices " 3805 "that are no longer present\n")); 3806 } 3807 } else { 3808 ret = 1; 3809 } 3810 } 3811 3812 zpool_close(zhp); 3813 3814 return (ret); 3815 } 3816 3817 /* 3818 * zpool offline [-ft] <pool> <device> ... 3819 * 3820 * -f Force the device into the offline state, even if doing 3821 * so would appear to compromise pool availability. 3822 * (not supported yet) 3823 * 3824 * -t Only take the device off-line temporarily. The offline 3825 * state will not be persistent across reboots. 3826 */ 3827 /* ARGSUSED */ 3828 int 3829 zpool_do_offline(int argc, char **argv) 3830 { 3831 int c, i; 3832 char *poolname; 3833 zpool_handle_t *zhp; 3834 int ret = 0; 3835 boolean_t istmp = B_FALSE; 3836 3837 /* check options */ 3838 while ((c = getopt(argc, argv, "ft")) != -1) { 3839 switch (c) { 3840 case 't': 3841 istmp = B_TRUE; 3842 break; 3843 case 'f': 3844 case '?': 3845 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3846 optopt); 3847 usage(B_FALSE); 3848 } 3849 } 3850 3851 argc -= optind; 3852 argv += optind; 3853 3854 /* get pool name and check number of arguments */ 3855 if (argc < 1) { 3856 (void) fprintf(stderr, gettext("missing pool name\n")); 3857 usage(B_FALSE); 3858 } 3859 if (argc < 2) { 3860 (void) fprintf(stderr, gettext("missing device name\n")); 3861 usage(B_FALSE); 3862 } 3863 3864 poolname = argv[0]; 3865 3866 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3867 return (1); 3868 3869 for (i = 1; i < argc; i++) { 3870 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 3871 ret = 1; 3872 } 3873 3874 zpool_close(zhp); 3875 3876 return (ret); 3877 } 3878 3879 /* 3880 * zpool clear <pool> [device] 3881 * 3882 * Clear all errors associated with a pool or a particular device. 3883 */ 3884 int 3885 zpool_do_clear(int argc, char **argv) 3886 { 3887 int c; 3888 int ret = 0; 3889 boolean_t dryrun = B_FALSE; 3890 boolean_t do_rewind = B_FALSE; 3891 boolean_t xtreme_rewind = B_FALSE; 3892 uint32_t rewind_policy = ZPOOL_NO_REWIND; 3893 nvlist_t *policy = NULL; 3894 zpool_handle_t *zhp; 3895 char *pool, *device; 3896 3897 /* check options */ 3898 while ((c = getopt(argc, argv, "FnX")) != -1) { 3899 switch (c) { 3900 case 'F': 3901 do_rewind = B_TRUE; 3902 break; 3903 case 'n': 3904 dryrun = B_TRUE; 3905 break; 3906 case 'X': 3907 xtreme_rewind = B_TRUE; 3908 break; 3909 case '?': 3910 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3911 optopt); 3912 usage(B_FALSE); 3913 } 3914 } 3915 3916 argc -= optind; 3917 argv += optind; 3918 3919 if (argc < 1) { 3920 (void) fprintf(stderr, gettext("missing pool name\n")); 3921 usage(B_FALSE); 3922 } 3923 3924 if (argc > 2) { 3925 (void) fprintf(stderr, gettext("too many arguments\n")); 3926 usage(B_FALSE); 3927 } 3928 3929 if ((dryrun || xtreme_rewind) && !do_rewind) { 3930 (void) fprintf(stderr, 3931 gettext("-n or -X only meaningful with -F\n")); 3932 usage(B_FALSE); 3933 } 3934 if (dryrun) 3935 rewind_policy = ZPOOL_TRY_REWIND; 3936 else if (do_rewind) 3937 rewind_policy = ZPOOL_DO_REWIND; 3938 if (xtreme_rewind) 3939 rewind_policy |= ZPOOL_EXTREME_REWIND; 3940 3941 /* In future, further rewind policy choices can be passed along here */ 3942 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 3943 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 3944 rewind_policy) != 0) { 3945 return (1); 3946 } 3947 3948 pool = argv[0]; 3949 device = argc == 2 ? argv[1] : NULL; 3950 3951 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 3952 nvlist_free(policy); 3953 return (1); 3954 } 3955 3956 if (zpool_clear(zhp, device, policy) != 0) 3957 ret = 1; 3958 3959 zpool_close(zhp); 3960 3961 nvlist_free(policy); 3962 3963 return (ret); 3964 } 3965 3966 /* 3967 * zpool reguid <pool> 3968 */ 3969 int 3970 zpool_do_reguid(int argc, char **argv) 3971 { 3972 int c; 3973 char *poolname; 3974 zpool_handle_t *zhp; 3975 int ret = 0; 3976 3977 /* check options */ 3978 while ((c = getopt(argc, argv, "")) != -1) { 3979 switch (c) { 3980 case '?': 3981 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3982 optopt); 3983 usage(B_FALSE); 3984 } 3985 } 3986 3987 argc -= optind; 3988 argv += optind; 3989 3990 /* get pool name and check number of arguments */ 3991 if (argc < 1) { 3992 (void) fprintf(stderr, gettext("missing pool name\n")); 3993 usage(B_FALSE); 3994 } 3995 3996 if (argc > 1) { 3997 (void) fprintf(stderr, gettext("too many arguments\n")); 3998 usage(B_FALSE); 3999 } 4000 4001 poolname = argv[0]; 4002 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 4003 return (1); 4004 4005 ret = zpool_reguid(zhp); 4006 4007 zpool_close(zhp); 4008 return (ret); 4009 } 4010 4011 4012 /* 4013 * zpool reopen <pool> 4014 * 4015 * Reopen the pool so that the kernel can update the sizes of all vdevs. 4016 */ 4017 int 4018 zpool_do_reopen(int argc, char **argv) 4019 { 4020 int c; 4021 int ret = 0; 4022 zpool_handle_t *zhp; 4023 char *pool; 4024 4025 /* check options */ 4026 while ((c = getopt(argc, argv, "")) != -1) { 4027 switch (c) { 4028 case '?': 4029 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4030 optopt); 4031 usage(B_FALSE); 4032 } 4033 } 4034 4035 argc--; 4036 argv++; 4037 4038 if (argc < 1) { 4039 (void) fprintf(stderr, gettext("missing pool name\n")); 4040 usage(B_FALSE); 4041 } 4042 4043 if (argc > 1) { 4044 (void) fprintf(stderr, gettext("too many arguments\n")); 4045 usage(B_FALSE); 4046 } 4047 4048 pool = argv[0]; 4049 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 4050 return (1); 4051 4052 ret = zpool_reopen(zhp); 4053 zpool_close(zhp); 4054 return (ret); 4055 } 4056 4057 typedef struct scrub_cbdata { 4058 int cb_type; 4059 int cb_argc; 4060 char **cb_argv; 4061 pool_scrub_cmd_t cb_scrub_cmd; 4062 } scrub_cbdata_t; 4063 4064 static boolean_t 4065 zpool_has_checkpoint(zpool_handle_t *zhp) 4066 { 4067 nvlist_t *config, *nvroot; 4068 4069 config = zpool_get_config(zhp, NULL); 4070 4071 if (config != NULL) { 4072 pool_checkpoint_stat_t *pcs = NULL; 4073 uint_t c; 4074 4075 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 4076 (void) nvlist_lookup_uint64_array(nvroot, 4077 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 4078 4079 if (pcs == NULL || pcs->pcs_state == CS_NONE) 4080 return (B_FALSE); 4081 4082 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS || 4083 pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 4084 return (B_TRUE); 4085 } 4086 4087 return (B_FALSE); 4088 } 4089 4090 int 4091 scrub_callback(zpool_handle_t *zhp, void *data) 4092 { 4093 scrub_cbdata_t *cb = data; 4094 int err; 4095 4096 /* 4097 * Ignore faulted pools. 4098 */ 4099 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 4100 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 4101 "currently unavailable\n"), zpool_get_name(zhp)); 4102 return (1); 4103 } 4104 4105 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd); 4106 4107 if (err == 0 && zpool_has_checkpoint(zhp) && 4108 cb->cb_type == POOL_SCAN_SCRUB) { 4109 (void) printf(gettext("warning: will not scrub state that " 4110 "belongs to the checkpoint of pool '%s'\n"), 4111 zpool_get_name(zhp)); 4112 } 4113 4114 return (err != 0); 4115 } 4116 4117 /* 4118 * zpool scrub [-s | -p] <pool> ... 4119 * 4120 * -s Stop. Stops any in-progress scrub. 4121 * -p Pause. Pause in-progress scrub. 4122 */ 4123 int 4124 zpool_do_scrub(int argc, char **argv) 4125 { 4126 int c; 4127 scrub_cbdata_t cb; 4128 4129 cb.cb_type = POOL_SCAN_SCRUB; 4130 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 4131 4132 /* check options */ 4133 while ((c = getopt(argc, argv, "sp")) != -1) { 4134 switch (c) { 4135 case 's': 4136 cb.cb_type = POOL_SCAN_NONE; 4137 break; 4138 case 'p': 4139 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE; 4140 break; 4141 case '?': 4142 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4143 optopt); 4144 usage(B_FALSE); 4145 } 4146 } 4147 4148 if (cb.cb_type == POOL_SCAN_NONE && 4149 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) { 4150 (void) fprintf(stderr, gettext("invalid option combination: " 4151 "-s and -p are mutually exclusive\n")); 4152 usage(B_FALSE); 4153 } 4154 4155 cb.cb_argc = argc; 4156 cb.cb_argv = argv; 4157 argc -= optind; 4158 argv += optind; 4159 4160 if (argc < 1) { 4161 (void) fprintf(stderr, gettext("missing pool name argument\n")); 4162 usage(B_FALSE); 4163 } 4164 4165 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 4166 } 4167 4168 typedef struct status_cbdata { 4169 int cb_count; 4170 boolean_t cb_allpools; 4171 boolean_t cb_verbose; 4172 boolean_t cb_explain; 4173 boolean_t cb_first; 4174 boolean_t cb_dedup_stats; 4175 } status_cbdata_t; 4176 4177 /* 4178 * Print out detailed scrub status. 4179 */ 4180 static void 4181 print_scan_status(pool_scan_stat_t *ps) 4182 { 4183 time_t start, end, pause; 4184 uint64_t elapsed, mins_left, hours_left; 4185 uint64_t pass_exam, examined, total; 4186 uint_t rate; 4187 double fraction_done; 4188 char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 4189 4190 (void) printf(gettext(" scan: ")); 4191 4192 /* If there's never been a scan, there's not much to say. */ 4193 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 4194 ps->pss_func >= POOL_SCAN_FUNCS) { 4195 (void) printf(gettext("none requested\n")); 4196 return; 4197 } 4198 4199 start = ps->pss_start_time; 4200 end = ps->pss_end_time; 4201 pause = ps->pss_pass_scrub_pause; 4202 zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf)); 4203 4204 assert(ps->pss_func == POOL_SCAN_SCRUB || 4205 ps->pss_func == POOL_SCAN_RESILVER); 4206 /* 4207 * Scan is finished or canceled. 4208 */ 4209 if (ps->pss_state == DSS_FINISHED) { 4210 uint64_t minutes_taken = (end - start) / 60; 4211 char *fmt = NULL; 4212 4213 if (ps->pss_func == POOL_SCAN_SCRUB) { 4214 fmt = gettext("scrub repaired %s in %lluh%um with " 4215 "%llu errors on %s"); 4216 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 4217 fmt = gettext("resilvered %s in %lluh%um with " 4218 "%llu errors on %s"); 4219 } 4220 /* LINTED */ 4221 (void) printf(fmt, processed_buf, 4222 (u_longlong_t)(minutes_taken / 60), 4223 (uint_t)(minutes_taken % 60), 4224 (u_longlong_t)ps->pss_errors, 4225 ctime((time_t *)&end)); 4226 return; 4227 } else if (ps->pss_state == DSS_CANCELED) { 4228 if (ps->pss_func == POOL_SCAN_SCRUB) { 4229 (void) printf(gettext("scrub canceled on %s"), 4230 ctime(&end)); 4231 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 4232 (void) printf(gettext("resilver canceled on %s"), 4233 ctime(&end)); 4234 } 4235 return; 4236 } 4237 4238 assert(ps->pss_state == DSS_SCANNING); 4239 4240 /* 4241 * Scan is in progress. 4242 */ 4243 if (ps->pss_func == POOL_SCAN_SCRUB) { 4244 if (pause == 0) { 4245 (void) printf(gettext("scrub in progress since %s"), 4246 ctime(&start)); 4247 } else { 4248 char buf[32]; 4249 struct tm *p = localtime(&pause); 4250 (void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p); 4251 (void) printf(gettext("scrub paused since %s\n"), buf); 4252 (void) printf(gettext("\tscrub started on %s"), 4253 ctime(&start)); 4254 } 4255 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 4256 (void) printf(gettext("resilver in progress since %s"), 4257 ctime(&start)); 4258 } 4259 4260 examined = ps->pss_examined ? ps->pss_examined : 1; 4261 total = ps->pss_to_examine; 4262 fraction_done = (double)examined / total; 4263 4264 /* elapsed time for this pass */ 4265 elapsed = time(NULL) - ps->pss_pass_start; 4266 elapsed -= ps->pss_pass_scrub_spent_paused; 4267 elapsed = elapsed ? elapsed : 1; 4268 pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1; 4269 rate = pass_exam / elapsed; 4270 rate = rate ? rate : 1; 4271 mins_left = ((total - examined) / rate) / 60; 4272 hours_left = mins_left / 60; 4273 4274 zfs_nicenum(examined, examined_buf, sizeof (examined_buf)); 4275 zfs_nicenum(total, total_buf, sizeof (total_buf)); 4276 4277 /* 4278 * do not print estimated time if hours_left is more than 30 days 4279 * or we have a paused scrub 4280 */ 4281 if (pause == 0) { 4282 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 4283 (void) printf(gettext("\t%s scanned out of %s at %s/s"), 4284 examined_buf, total_buf, rate_buf); 4285 if (hours_left < (30 * 24)) { 4286 (void) printf(gettext(", %lluh%um to go\n"), 4287 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 4288 } else { 4289 (void) printf(gettext( 4290 ", (scan is slow, no estimated time)\n")); 4291 } 4292 } else { 4293 (void) printf(gettext("\t%s scanned out of %s\n"), 4294 examined_buf, total_buf); 4295 } 4296 4297 if (ps->pss_func == POOL_SCAN_RESILVER) { 4298 (void) printf(gettext(" %s resilvered, %.2f%% done\n"), 4299 processed_buf, 100 * fraction_done); 4300 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 4301 (void) printf(gettext(" %s repaired, %.2f%% done\n"), 4302 processed_buf, 100 * fraction_done); 4303 } 4304 } 4305 4306 /* 4307 * As we don't scrub checkpointed blocks, we want to warn the 4308 * user that we skipped scanning some blocks if a checkpoint exists 4309 * or existed at any time during the scan. 4310 */ 4311 static void 4312 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs) 4313 { 4314 if (ps == NULL || pcs == NULL) 4315 return; 4316 4317 if (pcs->pcs_state == CS_NONE || 4318 pcs->pcs_state == CS_CHECKPOINT_DISCARDING) 4319 return; 4320 4321 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS); 4322 4323 if (ps->pss_state == DSS_NONE) 4324 return; 4325 4326 if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) && 4327 ps->pss_end_time < pcs->pcs_start_time) 4328 return; 4329 4330 if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) { 4331 (void) printf(gettext(" scan warning: skipped blocks " 4332 "that are only referenced by the checkpoint.\n")); 4333 } else { 4334 assert(ps->pss_state == DSS_SCANNING); 4335 (void) printf(gettext(" scan warning: skipping blocks " 4336 "that are only referenced by the checkpoint.\n")); 4337 } 4338 } 4339 4340 /* 4341 * Print out detailed removal status. 4342 */ 4343 static void 4344 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs) 4345 { 4346 char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 4347 time_t start, end; 4348 nvlist_t *config, *nvroot; 4349 nvlist_t **child; 4350 uint_t children; 4351 char *vdev_name; 4352 4353 if (prs == NULL || prs->prs_state == DSS_NONE) 4354 return; 4355 4356 /* 4357 * Determine name of vdev. 4358 */ 4359 config = zpool_get_config(zhp, NULL); 4360 nvroot = fnvlist_lookup_nvlist(config, 4361 ZPOOL_CONFIG_VDEV_TREE); 4362 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 4363 &child, &children) == 0); 4364 assert(prs->prs_removing_vdev < children); 4365 vdev_name = zpool_vdev_name(g_zfs, zhp, 4366 child[prs->prs_removing_vdev], B_TRUE); 4367 4368 (void) printf(gettext("remove: ")); 4369 4370 start = prs->prs_start_time; 4371 end = prs->prs_end_time; 4372 zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf)); 4373 4374 /* 4375 * Removal is finished or canceled. 4376 */ 4377 if (prs->prs_state == DSS_FINISHED) { 4378 uint64_t minutes_taken = (end - start) / 60; 4379 4380 (void) printf(gettext("Removal of vdev %llu copied %s " 4381 "in %lluh%um, completed on %s"), 4382 (longlong_t)prs->prs_removing_vdev, 4383 copied_buf, 4384 (u_longlong_t)(minutes_taken / 60), 4385 (uint_t)(minutes_taken % 60), 4386 ctime((time_t *)&end)); 4387 } else if (prs->prs_state == DSS_CANCELED) { 4388 (void) printf(gettext("Removal of %s canceled on %s"), 4389 vdev_name, ctime(&end)); 4390 } else { 4391 uint64_t copied, total, elapsed, mins_left, hours_left; 4392 double fraction_done; 4393 uint_t rate; 4394 4395 assert(prs->prs_state == DSS_SCANNING); 4396 4397 /* 4398 * Removal is in progress. 4399 */ 4400 (void) printf(gettext( 4401 "Evacuation of %s in progress since %s"), 4402 vdev_name, ctime(&start)); 4403 4404 copied = prs->prs_copied > 0 ? prs->prs_copied : 1; 4405 total = prs->prs_to_copy; 4406 fraction_done = (double)copied / total; 4407 4408 /* elapsed time for this pass */ 4409 elapsed = time(NULL) - prs->prs_start_time; 4410 elapsed = elapsed > 0 ? elapsed : 1; 4411 rate = copied / elapsed; 4412 rate = rate > 0 ? rate : 1; 4413 mins_left = ((total - copied) / rate) / 60; 4414 hours_left = mins_left / 60; 4415 4416 zfs_nicenum(copied, examined_buf, sizeof (examined_buf)); 4417 zfs_nicenum(total, total_buf, sizeof (total_buf)); 4418 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 4419 4420 /* 4421 * do not print estimated time if hours_left is more than 4422 * 30 days 4423 */ 4424 (void) printf(gettext(" %s copied out of %s at %s/s, " 4425 "%.2f%% done"), 4426 examined_buf, total_buf, rate_buf, 100 * fraction_done); 4427 if (hours_left < (30 * 24)) { 4428 (void) printf(gettext(", %lluh%um to go\n"), 4429 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 4430 } else { 4431 (void) printf(gettext( 4432 ", (copy is slow, no estimated time)\n")); 4433 } 4434 } 4435 4436 if (prs->prs_mapping_memory > 0) { 4437 char mem_buf[7]; 4438 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf)); 4439 (void) printf(gettext(" %s memory used for " 4440 "removed device mappings\n"), 4441 mem_buf); 4442 } 4443 } 4444 4445 static void 4446 print_checkpoint_status(pool_checkpoint_stat_t *pcs) 4447 { 4448 time_t start; 4449 char space_buf[7]; 4450 4451 if (pcs == NULL || pcs->pcs_state == CS_NONE) 4452 return; 4453 4454 (void) printf(gettext("checkpoint: ")); 4455 4456 start = pcs->pcs_start_time; 4457 zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf)); 4458 4459 if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) { 4460 char *date = ctime(&start); 4461 4462 /* 4463 * ctime() adds a newline at the end of the generated 4464 * string, thus the weird format specifier and the 4465 * strlen() call used to chop it off from the output. 4466 */ 4467 (void) printf(gettext("created %.*s, consumes %s\n"), 4468 strlen(date) - 1, date, space_buf); 4469 return; 4470 } 4471 4472 assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 4473 4474 (void) printf(gettext("discarding, %s remaining.\n"), 4475 space_buf); 4476 } 4477 4478 static void 4479 print_error_log(zpool_handle_t *zhp) 4480 { 4481 nvlist_t *nverrlist = NULL; 4482 nvpair_t *elem; 4483 char *pathname; 4484 size_t len = MAXPATHLEN * 2; 4485 4486 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 4487 (void) printf("errors: List of errors unavailable " 4488 "(insufficient privileges)\n"); 4489 return; 4490 } 4491 4492 (void) printf("errors: Permanent errors have been " 4493 "detected in the following files:\n\n"); 4494 4495 pathname = safe_malloc(len); 4496 elem = NULL; 4497 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 4498 nvlist_t *nv; 4499 uint64_t dsobj, obj; 4500 4501 verify(nvpair_value_nvlist(elem, &nv) == 0); 4502 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 4503 &dsobj) == 0); 4504 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 4505 &obj) == 0); 4506 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 4507 (void) printf("%7s %s\n", "", pathname); 4508 } 4509 free(pathname); 4510 nvlist_free(nverrlist); 4511 } 4512 4513 static void 4514 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 4515 int namewidth) 4516 { 4517 uint_t i; 4518 char *name; 4519 4520 if (nspares == 0) 4521 return; 4522 4523 (void) printf(gettext("\tspares\n")); 4524 4525 for (i = 0; i < nspares; i++) { 4526 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE); 4527 print_status_config(zhp, name, spares[i], 4528 namewidth, 2, B_TRUE); 4529 free(name); 4530 } 4531 } 4532 4533 static void 4534 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 4535 int namewidth) 4536 { 4537 uint_t i; 4538 char *name; 4539 4540 if (nl2cache == 0) 4541 return; 4542 4543 (void) printf(gettext("\tcache\n")); 4544 4545 for (i = 0; i < nl2cache; i++) { 4546 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE); 4547 print_status_config(zhp, name, l2cache[i], 4548 namewidth, 2, B_FALSE); 4549 free(name); 4550 } 4551 } 4552 4553 static void 4554 print_dedup_stats(nvlist_t *config) 4555 { 4556 ddt_histogram_t *ddh; 4557 ddt_stat_t *dds; 4558 ddt_object_t *ddo; 4559 uint_t c; 4560 4561 /* 4562 * If the pool was faulted then we may not have been able to 4563 * obtain the config. Otherwise, if we have anything in the dedup 4564 * table continue processing the stats. 4565 */ 4566 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 4567 (uint64_t **)&ddo, &c) != 0) 4568 return; 4569 4570 (void) printf("\n"); 4571 (void) printf(gettext(" dedup: ")); 4572 if (ddo->ddo_count == 0) { 4573 (void) printf(gettext("no DDT entries\n")); 4574 return; 4575 } 4576 4577 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n", 4578 (u_longlong_t)ddo->ddo_count, 4579 (u_longlong_t)ddo->ddo_dspace, 4580 (u_longlong_t)ddo->ddo_mspace); 4581 4582 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 4583 (uint64_t **)&dds, &c) == 0); 4584 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 4585 (uint64_t **)&ddh, &c) == 0); 4586 zpool_dump_ddt(dds, ddh); 4587 } 4588 4589 /* 4590 * Display a summary of pool status. Displays a summary such as: 4591 * 4592 * pool: tank 4593 * status: DEGRADED 4594 * reason: One or more devices ... 4595 * see: http://illumos.org/msg/ZFS-xxxx-01 4596 * config: 4597 * mirror DEGRADED 4598 * c1t0d0 OK 4599 * c2t0d0 UNAVAIL 4600 * 4601 * When given the '-v' option, we print out the complete config. If the '-e' 4602 * option is specified, then we print out error rate information as well. 4603 */ 4604 int 4605 status_callback(zpool_handle_t *zhp, void *data) 4606 { 4607 status_cbdata_t *cbp = data; 4608 nvlist_t *config, *nvroot; 4609 char *msgid; 4610 int reason; 4611 const char *health; 4612 uint_t c; 4613 vdev_stat_t *vs; 4614 4615 config = zpool_get_config(zhp, NULL); 4616 reason = zpool_get_status(zhp, &msgid); 4617 4618 cbp->cb_count++; 4619 4620 /* 4621 * If we were given 'zpool status -x', only report those pools with 4622 * problems. 4623 */ 4624 if (cbp->cb_explain && 4625 (reason == ZPOOL_STATUS_OK || 4626 reason == ZPOOL_STATUS_VERSION_OLDER || 4627 reason == ZPOOL_STATUS_FEAT_DISABLED)) { 4628 if (!cbp->cb_allpools) { 4629 (void) printf(gettext("pool '%s' is healthy\n"), 4630 zpool_get_name(zhp)); 4631 if (cbp->cb_first) 4632 cbp->cb_first = B_FALSE; 4633 } 4634 return (0); 4635 } 4636 4637 if (cbp->cb_first) 4638 cbp->cb_first = B_FALSE; 4639 else 4640 (void) printf("\n"); 4641 4642 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 4643 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 4644 (uint64_t **)&vs, &c) == 0); 4645 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 4646 4647 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 4648 (void) printf(gettext(" state: %s\n"), health); 4649 4650 switch (reason) { 4651 case ZPOOL_STATUS_MISSING_DEV_R: 4652 (void) printf(gettext("status: One or more devices could not " 4653 "be opened. Sufficient replicas exist for\n\tthe pool to " 4654 "continue functioning in a degraded state.\n")); 4655 (void) printf(gettext("action: Attach the missing device and " 4656 "online it using 'zpool online'.\n")); 4657 break; 4658 4659 case ZPOOL_STATUS_MISSING_DEV_NR: 4660 (void) printf(gettext("status: One or more devices could not " 4661 "be opened. There are insufficient\n\treplicas for the " 4662 "pool to continue functioning.\n")); 4663 (void) printf(gettext("action: Attach the missing device and " 4664 "online it using 'zpool online'.\n")); 4665 break; 4666 4667 case ZPOOL_STATUS_CORRUPT_LABEL_R: 4668 (void) printf(gettext("status: One or more devices could not " 4669 "be used because the label is missing or\n\tinvalid. " 4670 "Sufficient replicas exist for the pool to continue\n\t" 4671 "functioning in a degraded state.\n")); 4672 (void) printf(gettext("action: Replace the device using " 4673 "'zpool replace'.\n")); 4674 break; 4675 4676 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 4677 (void) printf(gettext("status: One or more devices could not " 4678 "be used because the label is missing \n\tor invalid. " 4679 "There are insufficient replicas for the pool to " 4680 "continue\n\tfunctioning.\n")); 4681 zpool_explain_recover(zpool_get_handle(zhp), 4682 zpool_get_name(zhp), reason, config); 4683 break; 4684 4685 case ZPOOL_STATUS_FAILING_DEV: 4686 (void) printf(gettext("status: One or more devices has " 4687 "experienced an unrecoverable error. An\n\tattempt was " 4688 "made to correct the error. Applications are " 4689 "unaffected.\n")); 4690 (void) printf(gettext("action: Determine if the device needs " 4691 "to be replaced, and clear the errors\n\tusing " 4692 "'zpool clear' or replace the device with 'zpool " 4693 "replace'.\n")); 4694 break; 4695 4696 case ZPOOL_STATUS_OFFLINE_DEV: 4697 (void) printf(gettext("status: One or more devices has " 4698 "been taken offline by the administrator.\n\tSufficient " 4699 "replicas exist for the pool to continue functioning in " 4700 "a\n\tdegraded state.\n")); 4701 (void) printf(gettext("action: Online the device using " 4702 "'zpool online' or replace the device with\n\t'zpool " 4703 "replace'.\n")); 4704 break; 4705 4706 case ZPOOL_STATUS_REMOVED_DEV: 4707 (void) printf(gettext("status: One or more devices has " 4708 "been removed by the administrator.\n\tSufficient " 4709 "replicas exist for the pool to continue functioning in " 4710 "a\n\tdegraded state.\n")); 4711 (void) printf(gettext("action: Online the device using " 4712 "'zpool online' or replace the device with\n\t'zpool " 4713 "replace'.\n")); 4714 break; 4715 4716 case ZPOOL_STATUS_RESILVERING: 4717 (void) printf(gettext("status: One or more devices is " 4718 "currently being resilvered. The pool will\n\tcontinue " 4719 "to function, possibly in a degraded state.\n")); 4720 (void) printf(gettext("action: Wait for the resilver to " 4721 "complete.\n")); 4722 break; 4723 4724 case ZPOOL_STATUS_CORRUPT_DATA: 4725 (void) printf(gettext("status: One or more devices has " 4726 "experienced an error resulting in data\n\tcorruption. " 4727 "Applications may be affected.\n")); 4728 (void) printf(gettext("action: Restore the file in question " 4729 "if possible. Otherwise restore the\n\tentire pool from " 4730 "backup.\n")); 4731 break; 4732 4733 case ZPOOL_STATUS_CORRUPT_POOL: 4734 (void) printf(gettext("status: The pool metadata is corrupted " 4735 "and the pool cannot be opened.\n")); 4736 zpool_explain_recover(zpool_get_handle(zhp), 4737 zpool_get_name(zhp), reason, config); 4738 break; 4739 4740 case ZPOOL_STATUS_VERSION_OLDER: 4741 (void) printf(gettext("status: The pool is formatted using a " 4742 "legacy on-disk format. The pool can\n\tstill be used, " 4743 "but some features are unavailable.\n")); 4744 (void) printf(gettext("action: Upgrade the pool using 'zpool " 4745 "upgrade'. Once this is done, the\n\tpool will no longer " 4746 "be accessible on software that does not support feature\n" 4747 "\tflags.\n")); 4748 break; 4749 4750 case ZPOOL_STATUS_VERSION_NEWER: 4751 (void) printf(gettext("status: The pool has been upgraded to a " 4752 "newer, incompatible on-disk version.\n\tThe pool cannot " 4753 "be accessed on this system.\n")); 4754 (void) printf(gettext("action: Access the pool from a system " 4755 "running more recent software, or\n\trestore the pool from " 4756 "backup.\n")); 4757 break; 4758 4759 case ZPOOL_STATUS_FEAT_DISABLED: 4760 (void) printf(gettext("status: Some supported features are not " 4761 "enabled on the pool. The pool can\n\tstill be used, but " 4762 "some features are unavailable.\n")); 4763 (void) printf(gettext("action: Enable all features using " 4764 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 4765 "longer be accessible by software that does not support\n\t" 4766 "the features. See zpool-features(5) for details.\n")); 4767 break; 4768 4769 case ZPOOL_STATUS_UNSUP_FEAT_READ: 4770 (void) printf(gettext("status: The pool cannot be accessed on " 4771 "this system because it uses the\n\tfollowing feature(s) " 4772 "not supported on this system:\n")); 4773 zpool_print_unsup_feat(config); 4774 (void) printf("\n"); 4775 (void) printf(gettext("action: Access the pool from a system " 4776 "that supports the required feature(s),\n\tor restore the " 4777 "pool from backup.\n")); 4778 break; 4779 4780 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 4781 (void) printf(gettext("status: The pool can only be accessed " 4782 "in read-only mode on this system. It\n\tcannot be " 4783 "accessed in read-write mode because it uses the " 4784 "following\n\tfeature(s) not supported on this system:\n")); 4785 zpool_print_unsup_feat(config); 4786 (void) printf("\n"); 4787 (void) printf(gettext("action: The pool cannot be accessed in " 4788 "read-write mode. Import the pool with\n" 4789 "\t\"-o readonly=on\", access the pool from a system that " 4790 "supports the\n\trequired feature(s), or restore the " 4791 "pool from backup.\n")); 4792 break; 4793 4794 case ZPOOL_STATUS_FAULTED_DEV_R: 4795 (void) printf(gettext("status: One or more devices are " 4796 "faulted in response to persistent errors.\n\tSufficient " 4797 "replicas exist for the pool to continue functioning " 4798 "in a\n\tdegraded state.\n")); 4799 (void) printf(gettext("action: Replace the faulted device, " 4800 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 4801 break; 4802 4803 case ZPOOL_STATUS_FAULTED_DEV_NR: 4804 (void) printf(gettext("status: One or more devices are " 4805 "faulted in response to persistent errors. There are " 4806 "insufficient replicas for the pool to\n\tcontinue " 4807 "functioning.\n")); 4808 (void) printf(gettext("action: Destroy and re-create the pool " 4809 "from a backup source. Manually marking the device\n" 4810 "\trepaired using 'zpool clear' may allow some data " 4811 "to be recovered.\n")); 4812 break; 4813 4814 case ZPOOL_STATUS_IO_FAILURE_WAIT: 4815 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 4816 (void) printf(gettext("status: One or more devices are " 4817 "faulted in response to IO failures.\n")); 4818 (void) printf(gettext("action: Make sure the affected devices " 4819 "are connected, then run 'zpool clear'.\n")); 4820 break; 4821 4822 case ZPOOL_STATUS_BAD_LOG: 4823 (void) printf(gettext("status: An intent log record " 4824 "could not be read.\n" 4825 "\tWaiting for adminstrator intervention to fix the " 4826 "faulted pool.\n")); 4827 (void) printf(gettext("action: Either restore the affected " 4828 "device(s) and run 'zpool online',\n" 4829 "\tor ignore the intent log records by running " 4830 "'zpool clear'.\n")); 4831 break; 4832 4833 default: 4834 /* 4835 * The remaining errors can't actually be generated, yet. 4836 */ 4837 assert(reason == ZPOOL_STATUS_OK); 4838 } 4839 4840 if (msgid != NULL) 4841 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 4842 msgid); 4843 4844 if (config != NULL) { 4845 int namewidth; 4846 uint64_t nerr; 4847 nvlist_t **spares, **l2cache; 4848 uint_t nspares, nl2cache; 4849 pool_checkpoint_stat_t *pcs = NULL; 4850 pool_scan_stat_t *ps = NULL; 4851 pool_removal_stat_t *prs = NULL; 4852 4853 (void) nvlist_lookup_uint64_array(nvroot, 4854 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 4855 (void) nvlist_lookup_uint64_array(nvroot, 4856 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c); 4857 (void) nvlist_lookup_uint64_array(nvroot, 4858 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 4859 4860 print_scan_status(ps); 4861 print_checkpoint_scan_warning(ps, pcs); 4862 print_removal_status(zhp, prs); 4863 print_checkpoint_status(pcs); 4864 4865 namewidth = max_width(zhp, nvroot, 0, 0); 4866 if (namewidth < 10) 4867 namewidth = 10; 4868 4869 (void) printf(gettext("config:\n\n")); 4870 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 4871 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 4872 print_status_config(zhp, zpool_get_name(zhp), nvroot, 4873 namewidth, 0, B_FALSE); 4874 4875 if (num_logs(nvroot) > 0) 4876 print_logs(zhp, nvroot, namewidth, B_TRUE); 4877 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 4878 &l2cache, &nl2cache) == 0) 4879 print_l2cache(zhp, l2cache, nl2cache, namewidth); 4880 4881 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 4882 &spares, &nspares) == 0) 4883 print_spares(zhp, spares, nspares, namewidth); 4884 4885 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 4886 &nerr) == 0) { 4887 nvlist_t *nverrlist = NULL; 4888 4889 /* 4890 * If the approximate error count is small, get a 4891 * precise count by fetching the entire log and 4892 * uniquifying the results. 4893 */ 4894 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 4895 zpool_get_errlog(zhp, &nverrlist) == 0) { 4896 nvpair_t *elem; 4897 4898 elem = NULL; 4899 nerr = 0; 4900 while ((elem = nvlist_next_nvpair(nverrlist, 4901 elem)) != NULL) { 4902 nerr++; 4903 } 4904 } 4905 nvlist_free(nverrlist); 4906 4907 (void) printf("\n"); 4908 4909 if (nerr == 0) 4910 (void) printf(gettext("errors: No known data " 4911 "errors\n")); 4912 else if (!cbp->cb_verbose) 4913 (void) printf(gettext("errors: %llu data " 4914 "errors, use '-v' for a list\n"), 4915 (u_longlong_t)nerr); 4916 else 4917 print_error_log(zhp); 4918 } 4919 4920 if (cbp->cb_dedup_stats) 4921 print_dedup_stats(config); 4922 } else { 4923 (void) printf(gettext("config: The configuration cannot be " 4924 "determined.\n")); 4925 } 4926 4927 return (0); 4928 } 4929 4930 /* 4931 * zpool status [-vx] [-T d|u] [pool] ... [interval [count]] 4932 * 4933 * -v Display complete error logs 4934 * -x Display only pools with potential problems 4935 * -D Display dedup status (undocumented) 4936 * -T Display a timestamp in date(1) or Unix format 4937 * 4938 * Describes the health status of all pools or some subset. 4939 */ 4940 int 4941 zpool_do_status(int argc, char **argv) 4942 { 4943 int c; 4944 int ret; 4945 unsigned long interval = 0, count = 0; 4946 status_cbdata_t cb = { 0 }; 4947 4948 /* check options */ 4949 while ((c = getopt(argc, argv, "vxDT:")) != -1) { 4950 switch (c) { 4951 case 'v': 4952 cb.cb_verbose = B_TRUE; 4953 break; 4954 case 'x': 4955 cb.cb_explain = B_TRUE; 4956 break; 4957 case 'D': 4958 cb.cb_dedup_stats = B_TRUE; 4959 break; 4960 case 'T': 4961 get_timestamp_arg(*optarg); 4962 break; 4963 case '?': 4964 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4965 optopt); 4966 usage(B_FALSE); 4967 } 4968 } 4969 4970 argc -= optind; 4971 argv += optind; 4972 4973 get_interval_count(&argc, argv, &interval, &count); 4974 4975 if (argc == 0) 4976 cb.cb_allpools = B_TRUE; 4977 4978 cb.cb_first = B_TRUE; 4979 4980 for (;;) { 4981 if (timestamp_fmt != NODATE) 4982 print_timestamp(timestamp_fmt); 4983 4984 ret = for_each_pool(argc, argv, B_TRUE, NULL, 4985 status_callback, &cb); 4986 4987 if (argc == 0 && cb.cb_count == 0) 4988 (void) printf(gettext("no pools available\n")); 4989 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 4990 (void) printf(gettext("all pools are healthy\n")); 4991 4992 if (ret != 0) 4993 return (ret); 4994 4995 if (interval == 0) 4996 break; 4997 4998 if (count != 0 && --count == 0) 4999 break; 5000 5001 (void) sleep(interval); 5002 } 5003 5004 return (0); 5005 } 5006 5007 typedef struct upgrade_cbdata { 5008 int cb_first; 5009 int cb_argc; 5010 uint64_t cb_version; 5011 char **cb_argv; 5012 } upgrade_cbdata_t; 5013 5014 static int 5015 upgrade_version(zpool_handle_t *zhp, uint64_t version) 5016 { 5017 int ret; 5018 nvlist_t *config; 5019 uint64_t oldversion; 5020 5021 config = zpool_get_config(zhp, NULL); 5022 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 5023 &oldversion) == 0); 5024 5025 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 5026 assert(oldversion < version); 5027 5028 ret = zpool_upgrade(zhp, version); 5029 if (ret != 0) 5030 return (ret); 5031 5032 if (version >= SPA_VERSION_FEATURES) { 5033 (void) printf(gettext("Successfully upgraded " 5034 "'%s' from version %llu to feature flags.\n"), 5035 zpool_get_name(zhp), oldversion); 5036 } else { 5037 (void) printf(gettext("Successfully upgraded " 5038 "'%s' from version %llu to version %llu.\n"), 5039 zpool_get_name(zhp), oldversion, version); 5040 } 5041 5042 return (0); 5043 } 5044 5045 static int 5046 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 5047 { 5048 int i, ret, count; 5049 boolean_t firstff = B_TRUE; 5050 nvlist_t *enabled = zpool_get_features(zhp); 5051 5052 count = 0; 5053 for (i = 0; i < SPA_FEATURES; i++) { 5054 const char *fname = spa_feature_table[i].fi_uname; 5055 const char *fguid = spa_feature_table[i].fi_guid; 5056 if (!nvlist_exists(enabled, fguid)) { 5057 char *propname; 5058 verify(-1 != asprintf(&propname, "feature@%s", fname)); 5059 ret = zpool_set_prop(zhp, propname, 5060 ZFS_FEATURE_ENABLED); 5061 if (ret != 0) { 5062 free(propname); 5063 return (ret); 5064 } 5065 count++; 5066 5067 if (firstff) { 5068 (void) printf(gettext("Enabled the " 5069 "following features on '%s':\n"), 5070 zpool_get_name(zhp)); 5071 firstff = B_FALSE; 5072 } 5073 (void) printf(gettext(" %s\n"), fname); 5074 free(propname); 5075 } 5076 } 5077 5078 if (countp != NULL) 5079 *countp = count; 5080 return (0); 5081 } 5082 5083 static int 5084 upgrade_cb(zpool_handle_t *zhp, void *arg) 5085 { 5086 upgrade_cbdata_t *cbp = arg; 5087 nvlist_t *config; 5088 uint64_t version; 5089 boolean_t printnl = B_FALSE; 5090 int ret; 5091 5092 config = zpool_get_config(zhp, NULL); 5093 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 5094 &version) == 0); 5095 5096 assert(SPA_VERSION_IS_SUPPORTED(version)); 5097 5098 if (version < cbp->cb_version) { 5099 cbp->cb_first = B_FALSE; 5100 ret = upgrade_version(zhp, cbp->cb_version); 5101 if (ret != 0) 5102 return (ret); 5103 printnl = B_TRUE; 5104 5105 /* 5106 * If they did "zpool upgrade -a", then we could 5107 * be doing ioctls to different pools. We need 5108 * to log this history once to each pool, and bypass 5109 * the normal history logging that happens in main(). 5110 */ 5111 (void) zpool_log_history(g_zfs, history_str); 5112 log_history = B_FALSE; 5113 } 5114 5115 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 5116 int count; 5117 ret = upgrade_enable_all(zhp, &count); 5118 if (ret != 0) 5119 return (ret); 5120 5121 if (count > 0) { 5122 cbp->cb_first = B_FALSE; 5123 printnl = B_TRUE; 5124 } 5125 } 5126 5127 if (printnl) { 5128 (void) printf(gettext("\n")); 5129 } 5130 5131 return (0); 5132 } 5133 5134 static int 5135 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 5136 { 5137 upgrade_cbdata_t *cbp = arg; 5138 nvlist_t *config; 5139 uint64_t version; 5140 5141 config = zpool_get_config(zhp, NULL); 5142 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 5143 &version) == 0); 5144 5145 assert(SPA_VERSION_IS_SUPPORTED(version)); 5146 5147 if (version < SPA_VERSION_FEATURES) { 5148 if (cbp->cb_first) { 5149 (void) printf(gettext("The following pools are " 5150 "formatted with legacy version numbers and can\n" 5151 "be upgraded to use feature flags. After " 5152 "being upgraded, these pools\nwill no " 5153 "longer be accessible by software that does not " 5154 "support feature\nflags.\n\n")); 5155 (void) printf(gettext("VER POOL\n")); 5156 (void) printf(gettext("--- ------------\n")); 5157 cbp->cb_first = B_FALSE; 5158 } 5159 5160 (void) printf("%2llu %s\n", (u_longlong_t)version, 5161 zpool_get_name(zhp)); 5162 } 5163 5164 return (0); 5165 } 5166 5167 static int 5168 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 5169 { 5170 upgrade_cbdata_t *cbp = arg; 5171 nvlist_t *config; 5172 uint64_t version; 5173 5174 config = zpool_get_config(zhp, NULL); 5175 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 5176 &version) == 0); 5177 5178 if (version >= SPA_VERSION_FEATURES) { 5179 int i; 5180 boolean_t poolfirst = B_TRUE; 5181 nvlist_t *enabled = zpool_get_features(zhp); 5182 5183 for (i = 0; i < SPA_FEATURES; i++) { 5184 const char *fguid = spa_feature_table[i].fi_guid; 5185 const char *fname = spa_feature_table[i].fi_uname; 5186 if (!nvlist_exists(enabled, fguid)) { 5187 if (cbp->cb_first) { 5188 (void) printf(gettext("\nSome " 5189 "supported features are not " 5190 "enabled on the following pools. " 5191 "Once a\nfeature is enabled the " 5192 "pool may become incompatible with " 5193 "software\nthat does not support " 5194 "the feature. See " 5195 "zpool-features(5) for " 5196 "details.\n\n")); 5197 (void) printf(gettext("POOL " 5198 "FEATURE\n")); 5199 (void) printf(gettext("------" 5200 "---------\n")); 5201 cbp->cb_first = B_FALSE; 5202 } 5203 5204 if (poolfirst) { 5205 (void) printf(gettext("%s\n"), 5206 zpool_get_name(zhp)); 5207 poolfirst = B_FALSE; 5208 } 5209 5210 (void) printf(gettext(" %s\n"), fname); 5211 } 5212 } 5213 } 5214 5215 return (0); 5216 } 5217 5218 /* ARGSUSED */ 5219 static int 5220 upgrade_one(zpool_handle_t *zhp, void *data) 5221 { 5222 boolean_t printnl = B_FALSE; 5223 upgrade_cbdata_t *cbp = data; 5224 uint64_t cur_version; 5225 int ret; 5226 5227 if (strcmp("log", zpool_get_name(zhp)) == 0) { 5228 (void) printf(gettext("'log' is now a reserved word\n" 5229 "Pool 'log' must be renamed using export and import" 5230 " to upgrade.\n")); 5231 return (1); 5232 } 5233 5234 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 5235 if (cur_version > cbp->cb_version) { 5236 (void) printf(gettext("Pool '%s' is already formatted " 5237 "using more current version '%llu'.\n\n"), 5238 zpool_get_name(zhp), cur_version); 5239 return (0); 5240 } 5241 5242 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 5243 (void) printf(gettext("Pool '%s' is already formatted " 5244 "using version %llu.\n\n"), zpool_get_name(zhp), 5245 cbp->cb_version); 5246 return (0); 5247 } 5248 5249 if (cur_version != cbp->cb_version) { 5250 printnl = B_TRUE; 5251 ret = upgrade_version(zhp, cbp->cb_version); 5252 if (ret != 0) 5253 return (ret); 5254 } 5255 5256 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 5257 int count = 0; 5258 ret = upgrade_enable_all(zhp, &count); 5259 if (ret != 0) 5260 return (ret); 5261 5262 if (count != 0) { 5263 printnl = B_TRUE; 5264 } else if (cur_version == SPA_VERSION) { 5265 (void) printf(gettext("Pool '%s' already has all " 5266 "supported features enabled.\n"), 5267 zpool_get_name(zhp)); 5268 } 5269 } 5270 5271 if (printnl) { 5272 (void) printf(gettext("\n")); 5273 } 5274 5275 return (0); 5276 } 5277 5278 /* 5279 * zpool upgrade 5280 * zpool upgrade -v 5281 * zpool upgrade [-V version] <-a | pool ...> 5282 * 5283 * With no arguments, display downrev'd ZFS pool available for upgrade. 5284 * Individual pools can be upgraded by specifying the pool, and '-a' will 5285 * upgrade all pools. 5286 */ 5287 int 5288 zpool_do_upgrade(int argc, char **argv) 5289 { 5290 int c; 5291 upgrade_cbdata_t cb = { 0 }; 5292 int ret = 0; 5293 boolean_t showversions = B_FALSE; 5294 boolean_t upgradeall = B_FALSE; 5295 char *end; 5296 5297 5298 /* check options */ 5299 while ((c = getopt(argc, argv, ":avV:")) != -1) { 5300 switch (c) { 5301 case 'a': 5302 upgradeall = B_TRUE; 5303 break; 5304 case 'v': 5305 showversions = B_TRUE; 5306 break; 5307 case 'V': 5308 cb.cb_version = strtoll(optarg, &end, 10); 5309 if (*end != '\0' || 5310 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 5311 (void) fprintf(stderr, 5312 gettext("invalid version '%s'\n"), optarg); 5313 usage(B_FALSE); 5314 } 5315 break; 5316 case ':': 5317 (void) fprintf(stderr, gettext("missing argument for " 5318 "'%c' option\n"), optopt); 5319 usage(B_FALSE); 5320 break; 5321 case '?': 5322 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5323 optopt); 5324 usage(B_FALSE); 5325 } 5326 } 5327 5328 cb.cb_argc = argc; 5329 cb.cb_argv = argv; 5330 argc -= optind; 5331 argv += optind; 5332 5333 if (cb.cb_version == 0) { 5334 cb.cb_version = SPA_VERSION; 5335 } else if (!upgradeall && argc == 0) { 5336 (void) fprintf(stderr, gettext("-V option is " 5337 "incompatible with other arguments\n")); 5338 usage(B_FALSE); 5339 } 5340 5341 if (showversions) { 5342 if (upgradeall || argc != 0) { 5343 (void) fprintf(stderr, gettext("-v option is " 5344 "incompatible with other arguments\n")); 5345 usage(B_FALSE); 5346 } 5347 } else if (upgradeall) { 5348 if (argc != 0) { 5349 (void) fprintf(stderr, gettext("-a option should not " 5350 "be used along with a pool name\n")); 5351 usage(B_FALSE); 5352 } 5353 } 5354 5355 (void) printf(gettext("This system supports ZFS pool feature " 5356 "flags.\n\n")); 5357 if (showversions) { 5358 int i; 5359 5360 (void) printf(gettext("The following features are " 5361 "supported:\n\n")); 5362 (void) printf(gettext("FEAT DESCRIPTION\n")); 5363 (void) printf("----------------------------------------------" 5364 "---------------\n"); 5365 for (i = 0; i < SPA_FEATURES; i++) { 5366 zfeature_info_t *fi = &spa_feature_table[i]; 5367 const char *ro = 5368 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? 5369 " (read-only compatible)" : ""; 5370 5371 (void) printf("%-37s%s\n", fi->fi_uname, ro); 5372 (void) printf(" %s\n", fi->fi_desc); 5373 } 5374 (void) printf("\n"); 5375 5376 (void) printf(gettext("The following legacy versions are also " 5377 "supported:\n\n")); 5378 (void) printf(gettext("VER DESCRIPTION\n")); 5379 (void) printf("--- -----------------------------------------" 5380 "---------------\n"); 5381 (void) printf(gettext(" 1 Initial ZFS version\n")); 5382 (void) printf(gettext(" 2 Ditto blocks " 5383 "(replicated metadata)\n")); 5384 (void) printf(gettext(" 3 Hot spares and double parity " 5385 "RAID-Z\n")); 5386 (void) printf(gettext(" 4 zpool history\n")); 5387 (void) printf(gettext(" 5 Compression using the gzip " 5388 "algorithm\n")); 5389 (void) printf(gettext(" 6 bootfs pool property\n")); 5390 (void) printf(gettext(" 7 Separate intent log devices\n")); 5391 (void) printf(gettext(" 8 Delegated administration\n")); 5392 (void) printf(gettext(" 9 refquota and refreservation " 5393 "properties\n")); 5394 (void) printf(gettext(" 10 Cache devices\n")); 5395 (void) printf(gettext(" 11 Improved scrub performance\n")); 5396 (void) printf(gettext(" 12 Snapshot properties\n")); 5397 (void) printf(gettext(" 13 snapused property\n")); 5398 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 5399 (void) printf(gettext(" 15 user/group space accounting\n")); 5400 (void) printf(gettext(" 16 stmf property support\n")); 5401 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 5402 (void) printf(gettext(" 18 Snapshot user holds\n")); 5403 (void) printf(gettext(" 19 Log device removal\n")); 5404 (void) printf(gettext(" 20 Compression using zle " 5405 "(zero-length encoding)\n")); 5406 (void) printf(gettext(" 21 Deduplication\n")); 5407 (void) printf(gettext(" 22 Received properties\n")); 5408 (void) printf(gettext(" 23 Slim ZIL\n")); 5409 (void) printf(gettext(" 24 System attributes\n")); 5410 (void) printf(gettext(" 25 Improved scrub stats\n")); 5411 (void) printf(gettext(" 26 Improved snapshot deletion " 5412 "performance\n")); 5413 (void) printf(gettext(" 27 Improved snapshot creation " 5414 "performance\n")); 5415 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 5416 (void) printf(gettext("\nFor more information on a particular " 5417 "version, including supported releases,\n")); 5418 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 5419 } else if (argc == 0 && upgradeall) { 5420 cb.cb_first = B_TRUE; 5421 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 5422 if (ret == 0 && cb.cb_first) { 5423 if (cb.cb_version == SPA_VERSION) { 5424 (void) printf(gettext("All pools are already " 5425 "formatted using feature flags.\n\n")); 5426 (void) printf(gettext("Every feature flags " 5427 "pool already has all supported features " 5428 "enabled.\n")); 5429 } else { 5430 (void) printf(gettext("All pools are already " 5431 "formatted with version %llu or higher.\n"), 5432 cb.cb_version); 5433 } 5434 } 5435 } else if (argc == 0) { 5436 cb.cb_first = B_TRUE; 5437 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 5438 assert(ret == 0); 5439 5440 if (cb.cb_first) { 5441 (void) printf(gettext("All pools are formatted " 5442 "using feature flags.\n\n")); 5443 } else { 5444 (void) printf(gettext("\nUse 'zpool upgrade -v' " 5445 "for a list of available legacy versions.\n")); 5446 } 5447 5448 cb.cb_first = B_TRUE; 5449 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 5450 assert(ret == 0); 5451 5452 if (cb.cb_first) { 5453 (void) printf(gettext("Every feature flags pool has " 5454 "all supported features enabled.\n")); 5455 } else { 5456 (void) printf(gettext("\n")); 5457 } 5458 } else { 5459 ret = for_each_pool(argc, argv, B_FALSE, NULL, 5460 upgrade_one, &cb); 5461 } 5462 5463 return (ret); 5464 } 5465 5466 typedef struct hist_cbdata { 5467 boolean_t first; 5468 boolean_t longfmt; 5469 boolean_t internal; 5470 } hist_cbdata_t; 5471 5472 /* 5473 * Print out the command history for a specific pool. 5474 */ 5475 static int 5476 get_history_one(zpool_handle_t *zhp, void *data) 5477 { 5478 nvlist_t *nvhis; 5479 nvlist_t **records; 5480 uint_t numrecords; 5481 int ret, i; 5482 hist_cbdata_t *cb = (hist_cbdata_t *)data; 5483 5484 cb->first = B_FALSE; 5485 5486 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 5487 5488 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 5489 return (ret); 5490 5491 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 5492 &records, &numrecords) == 0); 5493 for (i = 0; i < numrecords; i++) { 5494 nvlist_t *rec = records[i]; 5495 char tbuf[30] = ""; 5496 5497 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 5498 time_t tsec; 5499 struct tm t; 5500 5501 tsec = fnvlist_lookup_uint64(records[i], 5502 ZPOOL_HIST_TIME); 5503 (void) localtime_r(&tsec, &t); 5504 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 5505 } 5506 5507 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 5508 (void) printf("%s %s", tbuf, 5509 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 5510 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 5511 int ievent = 5512 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 5513 if (!cb->internal) 5514 continue; 5515 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 5516 (void) printf("%s unrecognized record:\n", 5517 tbuf); 5518 dump_nvlist(rec, 4); 5519 continue; 5520 } 5521 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 5522 zfs_history_event_names[ievent], 5523 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 5524 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 5525 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 5526 if (!cb->internal) 5527 continue; 5528 (void) printf("%s [txg:%lld] %s", tbuf, 5529 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 5530 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 5531 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 5532 (void) printf(" %s (%llu)", 5533 fnvlist_lookup_string(rec, 5534 ZPOOL_HIST_DSNAME), 5535 fnvlist_lookup_uint64(rec, 5536 ZPOOL_HIST_DSID)); 5537 } 5538 (void) printf(" %s", fnvlist_lookup_string(rec, 5539 ZPOOL_HIST_INT_STR)); 5540 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 5541 if (!cb->internal) 5542 continue; 5543 (void) printf("%s ioctl %s\n", tbuf, 5544 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 5545 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 5546 (void) printf(" input:\n"); 5547 dump_nvlist(fnvlist_lookup_nvlist(rec, 5548 ZPOOL_HIST_INPUT_NVL), 8); 5549 } 5550 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 5551 (void) printf(" output:\n"); 5552 dump_nvlist(fnvlist_lookup_nvlist(rec, 5553 ZPOOL_HIST_OUTPUT_NVL), 8); 5554 } 5555 if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) { 5556 (void) printf(" errno: %lld\n", 5557 fnvlist_lookup_int64(rec, 5558 ZPOOL_HIST_ERRNO)); 5559 } 5560 } else { 5561 if (!cb->internal) 5562 continue; 5563 (void) printf("%s unrecognized record:\n", tbuf); 5564 dump_nvlist(rec, 4); 5565 } 5566 5567 if (!cb->longfmt) { 5568 (void) printf("\n"); 5569 continue; 5570 } 5571 (void) printf(" ["); 5572 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 5573 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 5574 struct passwd *pwd = getpwuid(who); 5575 (void) printf("user %d ", (int)who); 5576 if (pwd != NULL) 5577 (void) printf("(%s) ", pwd->pw_name); 5578 } 5579 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 5580 (void) printf("on %s", 5581 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 5582 } 5583 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 5584 (void) printf(":%s", 5585 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 5586 } 5587 (void) printf("]"); 5588 (void) printf("\n"); 5589 } 5590 (void) printf("\n"); 5591 nvlist_free(nvhis); 5592 5593 return (ret); 5594 } 5595 5596 /* 5597 * zpool history <pool> 5598 * 5599 * Displays the history of commands that modified pools. 5600 */ 5601 int 5602 zpool_do_history(int argc, char **argv) 5603 { 5604 hist_cbdata_t cbdata = { 0 }; 5605 int ret; 5606 int c; 5607 5608 cbdata.first = B_TRUE; 5609 /* check options */ 5610 while ((c = getopt(argc, argv, "li")) != -1) { 5611 switch (c) { 5612 case 'l': 5613 cbdata.longfmt = B_TRUE; 5614 break; 5615 case 'i': 5616 cbdata.internal = B_TRUE; 5617 break; 5618 case '?': 5619 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5620 optopt); 5621 usage(B_FALSE); 5622 } 5623 } 5624 argc -= optind; 5625 argv += optind; 5626 5627 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 5628 &cbdata); 5629 5630 if (argc == 0 && cbdata.first == B_TRUE) { 5631 (void) printf(gettext("no pools available\n")); 5632 return (0); 5633 } 5634 5635 return (ret); 5636 } 5637 5638 static int 5639 get_callback(zpool_handle_t *zhp, void *data) 5640 { 5641 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 5642 char value[MAXNAMELEN]; 5643 zprop_source_t srctype; 5644 zprop_list_t *pl; 5645 5646 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 5647 5648 /* 5649 * Skip the special fake placeholder. This will also skip 5650 * over the name property when 'all' is specified. 5651 */ 5652 if (pl->pl_prop == ZPOOL_PROP_NAME && 5653 pl == cbp->cb_proplist) 5654 continue; 5655 5656 if (pl->pl_prop == ZPROP_INVAL && 5657 (zpool_prop_feature(pl->pl_user_prop) || 5658 zpool_prop_unsupported(pl->pl_user_prop))) { 5659 srctype = ZPROP_SRC_LOCAL; 5660 5661 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 5662 value, sizeof (value)) == 0) { 5663 zprop_print_one_property(zpool_get_name(zhp), 5664 cbp, pl->pl_user_prop, value, srctype, 5665 NULL, NULL); 5666 } 5667 } else { 5668 if (zpool_get_prop(zhp, pl->pl_prop, value, 5669 sizeof (value), &srctype, cbp->cb_literal) != 0) 5670 continue; 5671 5672 zprop_print_one_property(zpool_get_name(zhp), cbp, 5673 zpool_prop_to_name(pl->pl_prop), value, srctype, 5674 NULL, NULL); 5675 } 5676 } 5677 return (0); 5678 } 5679 5680 /* 5681 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... 5682 * 5683 * -H Scripted mode. Don't display headers, and separate properties 5684 * by a single tab. 5685 * -o List of columns to display. Defaults to 5686 * "name,property,value,source". 5687 * -p Diplay values in parsable (exact) format. 5688 * 5689 * Get properties of pools in the system. Output space statistics 5690 * for each one as well as other attributes. 5691 */ 5692 int 5693 zpool_do_get(int argc, char **argv) 5694 { 5695 zprop_get_cbdata_t cb = { 0 }; 5696 zprop_list_t fake_name = { 0 }; 5697 int ret; 5698 int c, i; 5699 char *value; 5700 5701 cb.cb_first = B_TRUE; 5702 5703 /* 5704 * Set up default columns and sources. 5705 */ 5706 cb.cb_sources = ZPROP_SRC_ALL; 5707 cb.cb_columns[0] = GET_COL_NAME; 5708 cb.cb_columns[1] = GET_COL_PROPERTY; 5709 cb.cb_columns[2] = GET_COL_VALUE; 5710 cb.cb_columns[3] = GET_COL_SOURCE; 5711 cb.cb_type = ZFS_TYPE_POOL; 5712 5713 /* check options */ 5714 while ((c = getopt(argc, argv, ":Hpo:")) != -1) { 5715 switch (c) { 5716 case 'p': 5717 cb.cb_literal = B_TRUE; 5718 break; 5719 case 'H': 5720 cb.cb_scripted = B_TRUE; 5721 break; 5722 case 'o': 5723 bzero(&cb.cb_columns, sizeof (cb.cb_columns)); 5724 i = 0; 5725 while (*optarg != '\0') { 5726 static char *col_subopts[] = 5727 { "name", "property", "value", "source", 5728 "all", NULL }; 5729 5730 if (i == ZFS_GET_NCOLS) { 5731 (void) fprintf(stderr, gettext("too " 5732 "many fields given to -o " 5733 "option\n")); 5734 usage(B_FALSE); 5735 } 5736 5737 switch (getsubopt(&optarg, col_subopts, 5738 &value)) { 5739 case 0: 5740 cb.cb_columns[i++] = GET_COL_NAME; 5741 break; 5742 case 1: 5743 cb.cb_columns[i++] = GET_COL_PROPERTY; 5744 break; 5745 case 2: 5746 cb.cb_columns[i++] = GET_COL_VALUE; 5747 break; 5748 case 3: 5749 cb.cb_columns[i++] = GET_COL_SOURCE; 5750 break; 5751 case 4: 5752 if (i > 0) { 5753 (void) fprintf(stderr, 5754 gettext("\"all\" conflicts " 5755 "with specific fields " 5756 "given to -o option\n")); 5757 usage(B_FALSE); 5758 } 5759 cb.cb_columns[0] = GET_COL_NAME; 5760 cb.cb_columns[1] = GET_COL_PROPERTY; 5761 cb.cb_columns[2] = GET_COL_VALUE; 5762 cb.cb_columns[3] = GET_COL_SOURCE; 5763 i = ZFS_GET_NCOLS; 5764 break; 5765 default: 5766 (void) fprintf(stderr, 5767 gettext("invalid column name " 5768 "'%s'\n"), value); 5769 usage(B_FALSE); 5770 } 5771 } 5772 break; 5773 case '?': 5774 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5775 optopt); 5776 usage(B_FALSE); 5777 } 5778 } 5779 5780 argc -= optind; 5781 argv += optind; 5782 5783 if (argc < 1) { 5784 (void) fprintf(stderr, gettext("missing property " 5785 "argument\n")); 5786 usage(B_FALSE); 5787 } 5788 5789 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, 5790 ZFS_TYPE_POOL) != 0) 5791 usage(B_FALSE); 5792 5793 argc--; 5794 argv++; 5795 5796 if (cb.cb_proplist != NULL) { 5797 fake_name.pl_prop = ZPOOL_PROP_NAME; 5798 fake_name.pl_width = strlen(gettext("NAME")); 5799 fake_name.pl_next = cb.cb_proplist; 5800 cb.cb_proplist = &fake_name; 5801 } 5802 5803 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 5804 get_callback, &cb); 5805 5806 if (cb.cb_proplist == &fake_name) 5807 zprop_free_list(fake_name.pl_next); 5808 else 5809 zprop_free_list(cb.cb_proplist); 5810 5811 return (ret); 5812 } 5813 5814 typedef struct set_cbdata { 5815 char *cb_propname; 5816 char *cb_value; 5817 boolean_t cb_any_successful; 5818 } set_cbdata_t; 5819 5820 int 5821 set_callback(zpool_handle_t *zhp, void *data) 5822 { 5823 int error; 5824 set_cbdata_t *cb = (set_cbdata_t *)data; 5825 5826 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 5827 5828 if (!error) 5829 cb->cb_any_successful = B_TRUE; 5830 5831 return (error); 5832 } 5833 5834 int 5835 zpool_do_set(int argc, char **argv) 5836 { 5837 set_cbdata_t cb = { 0 }; 5838 int error; 5839 5840 if (argc > 1 && argv[1][0] == '-') { 5841 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5842 argv[1][1]); 5843 usage(B_FALSE); 5844 } 5845 5846 if (argc < 2) { 5847 (void) fprintf(stderr, gettext("missing property=value " 5848 "argument\n")); 5849 usage(B_FALSE); 5850 } 5851 5852 if (argc < 3) { 5853 (void) fprintf(stderr, gettext("missing pool name\n")); 5854 usage(B_FALSE); 5855 } 5856 5857 if (argc > 3) { 5858 (void) fprintf(stderr, gettext("too many pool names\n")); 5859 usage(B_FALSE); 5860 } 5861 5862 cb.cb_propname = argv[1]; 5863 cb.cb_value = strchr(cb.cb_propname, '='); 5864 if (cb.cb_value == NULL) { 5865 (void) fprintf(stderr, gettext("missing value in " 5866 "property=value argument\n")); 5867 usage(B_FALSE); 5868 } 5869 5870 *(cb.cb_value) = '\0'; 5871 cb.cb_value++; 5872 5873 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 5874 set_callback, &cb); 5875 5876 return (error); 5877 } 5878 5879 static int 5880 find_command_idx(char *command, int *idx) 5881 { 5882 int i; 5883 5884 for (i = 0; i < NCOMMAND; i++) { 5885 if (command_table[i].name == NULL) 5886 continue; 5887 5888 if (strcmp(command, command_table[i].name) == 0) { 5889 *idx = i; 5890 return (0); 5891 } 5892 } 5893 return (1); 5894 } 5895 5896 int 5897 main(int argc, char **argv) 5898 { 5899 int ret = 0; 5900 int i; 5901 char *cmdname; 5902 5903 (void) setlocale(LC_ALL, ""); 5904 (void) textdomain(TEXT_DOMAIN); 5905 5906 if ((g_zfs = libzfs_init()) == NULL) { 5907 (void) fprintf(stderr, gettext("internal error: failed to " 5908 "initialize ZFS library\n")); 5909 return (1); 5910 } 5911 5912 libzfs_print_on_error(g_zfs, B_TRUE); 5913 5914 opterr = 0; 5915 5916 /* 5917 * Make sure the user has specified some command. 5918 */ 5919 if (argc < 2) { 5920 (void) fprintf(stderr, gettext("missing command\n")); 5921 usage(B_FALSE); 5922 } 5923 5924 cmdname = argv[1]; 5925 5926 /* 5927 * Special case '-?' 5928 */ 5929 if (strcmp(cmdname, "-?") == 0) 5930 usage(B_TRUE); 5931 5932 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 5933 5934 /* 5935 * Run the appropriate command. 5936 */ 5937 if (find_command_idx(cmdname, &i) == 0) { 5938 current_command = &command_table[i]; 5939 ret = command_table[i].func(argc - 1, argv + 1); 5940 } else if (strchr(cmdname, '=')) { 5941 verify(find_command_idx("set", &i) == 0); 5942 current_command = &command_table[i]; 5943 ret = command_table[i].func(argc, argv); 5944 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 5945 /* 5946 * 'freeze' is a vile debugging abomination, so we treat 5947 * it as such. 5948 */ 5949 char buf[16384]; 5950 int fd = open(ZFS_DEV, O_RDWR); 5951 (void) strcpy((void *)buf, argv[2]); 5952 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 5953 } else { 5954 (void) fprintf(stderr, gettext("unrecognized " 5955 "command '%s'\n"), cmdname); 5956 usage(B_FALSE); 5957 } 5958 5959 if (ret == 0 && log_history) 5960 (void) zpool_log_history(g_zfs, history_str); 5961 5962 libzfs_fini(g_zfs); 5963 5964 /* 5965 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 5966 * for the purposes of running ::findleaks. 5967 */ 5968 if (getenv("ZFS_ABORT") != NULL) { 5969 (void) printf("dumping core by request\n"); 5970 abort(); 5971 } 5972 5973 return (ret); 5974 } 5975