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