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