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