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