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