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