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