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