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