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