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