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.
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.
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]
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) 2013 by Prasad Joshi (sTec). All rights reserved.
27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
28 * Copyright 2016 Nexenta Systems, Inc.
29 * Copyright (c) 2017 Datto Inc.
51 #include <sys/fs/zfs.h>
56 #include "zpool_util.h"
57 #include "zfs_comutil.h"
58 #include "zfeature_common.h"
60 #include "statcommon.h"
62 static int zpool_do_create(int, char **);
63 static int zpool_do_destroy(int, char **);
65 static int zpool_do_add(int, char **);
66 static int zpool_do_remove(int, char **);
67 static int zpool_do_labelclear(int, char **);
69 static int zpool_do_checkpoint(int, char **);
71 static int zpool_do_list(int, char **);
72 static int zpool_do_iostat(int, char **);
73 static int zpool_do_status(int, char **);
75 static int zpool_do_online(int, char **);
76 static int zpool_do_offline(int, char **);
77 static int zpool_do_clear(int, char **);
78 static int zpool_do_reopen(int, char **);
80 static int zpool_do_reguid(int, char **);
82 static int zpool_do_attach(int, char **);
83 static int zpool_do_detach(int, char **);
84 static int zpool_do_replace(int, char **);
85 static int zpool_do_split(int, char **);
87 static int zpool_do_initialize(int, char **);
88 static int zpool_do_scrub(int, char **);
90 static int zpool_do_import(int, char **);
91 static int zpool_do_export(int, char **);
93 static int zpool_do_upgrade(int, char **);
95 static int zpool_do_history(int, char **);
97 static int zpool_do_get(int, char **);
98 static int zpool_do_set(int, char **);
101 * These libumem hooks provide a reasonable set of defaults for the allocator's
102 * debugging facilities.
107 _umem_debug_init(void)
109 return ("default,verbose"); /* $UMEM_DEBUG setting */
113 _umem_logging_init(void)
115 return ("fail,contents"); /* $UMEM_LOGGING setting */
149 typedef struct zpool_command
{
151 int (*func
)(int, char **);
156 * Master command table. Each ZFS command has a name, associated function, and
157 * usage message. The usage messages need to be internationalized, so we have
158 * to have a function to return the usage message based on a command index.
160 * These commands are organized according to how they are displayed in the usage
161 * message. An empty command (one with a NULL name) indicates an empty line in
162 * the generic usage message.
164 static zpool_command_t command_table
[] = {
165 { "create", zpool_do_create
, HELP_CREATE
},
166 { "destroy", zpool_do_destroy
, HELP_DESTROY
},
168 { "add", zpool_do_add
, HELP_ADD
},
169 { "remove", zpool_do_remove
, HELP_REMOVE
},
171 { "labelclear", zpool_do_labelclear
, HELP_LABELCLEAR
},
173 { "checkpoint", zpool_do_checkpoint
, HELP_CHECKPOINT
},
175 { "list", zpool_do_list
, HELP_LIST
},
176 { "iostat", zpool_do_iostat
, HELP_IOSTAT
},
177 { "status", zpool_do_status
, HELP_STATUS
},
179 { "online", zpool_do_online
, HELP_ONLINE
},
180 { "offline", zpool_do_offline
, HELP_OFFLINE
},
181 { "clear", zpool_do_clear
, HELP_CLEAR
},
182 { "reopen", zpool_do_reopen
, HELP_REOPEN
},
184 { "attach", zpool_do_attach
, HELP_ATTACH
},
185 { "detach", zpool_do_detach
, HELP_DETACH
},
186 { "replace", zpool_do_replace
, HELP_REPLACE
},
187 { "split", zpool_do_split
, HELP_SPLIT
},
189 { "initialize", zpool_do_initialize
, HELP_INITIALIZE
},
190 { "scrub", zpool_do_scrub
, HELP_SCRUB
},
192 { "import", zpool_do_import
, HELP_IMPORT
},
193 { "export", zpool_do_export
, HELP_EXPORT
},
194 { "upgrade", zpool_do_upgrade
, HELP_UPGRADE
},
195 { "reguid", zpool_do_reguid
, HELP_REGUID
},
197 { "history", zpool_do_history
, HELP_HISTORY
},
198 { "get", zpool_do_get
, HELP_GET
},
199 { "set", zpool_do_set
, HELP_SET
},
202 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
204 static zpool_command_t
*current_command
;
205 static char history_str
[HIS_MAX_RECORD_LEN
];
206 static boolean_t log_history
= B_TRUE
;
207 static uint_t timestamp_fmt
= NODATE
;
210 get_usage(zpool_help_t idx
)
214 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
216 return (gettext("\tattach [-f] <pool> <device> "
219 return (gettext("\tclear [-nF] <pool> [device]\n"));
221 return (gettext("\tcreate [-fnd] [-B] "
222 "[-o property=value] ... \n"
223 "\t [-O file-system-property=value] ... \n"
224 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
225 case HELP_CHECKPOINT
:
226 return (gettext("\tcheckpoint [--discard] <pool> ...\n"));
228 return (gettext("\tdestroy [-f] <pool>\n"));
230 return (gettext("\tdetach <pool> <device>\n"));
232 return (gettext("\texport [-f] <pool> ...\n"));
234 return (gettext("\thistory [-il] [<pool>] ...\n"));
236 return (gettext("\timport [-d dir] [-D]\n"
237 "\timport [-o mntopts] [-o property=value] ... \n"
238 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
239 "[-R root] [-F [-n]] -a\n"
240 "\timport [-o mntopts] [-o property=value] ... \n"
241 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
242 "[-R root] [-F [-n]]\n"
243 "\t [--rewind-to-checkpoint] <pool | id> [newpool]\n"));
245 return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
247 case HELP_LABELCLEAR
:
248 return (gettext("\tlabelclear [-f] <vdev>\n"));
250 return (gettext("\tlist [-Hp] [-o property[,...]] "
251 "[-T d|u] [pool] ... [interval [count]]\n"));
253 return (gettext("\toffline [-t] <pool> <device> ...\n"));
255 return (gettext("\tonline <pool> <device> ...\n"));
257 return (gettext("\treplace [-f] <pool> <device> "
260 return (gettext("\tremove [-nps] <pool> <device> ...\n"));
262 return (gettext("\treopen <pool>\n"));
263 case HELP_INITIALIZE
:
264 return (gettext("\tinitialize [-cs] <pool> [<device> ...]\n"));
266 return (gettext("\tscrub [-s | -p] <pool> ...\n"));
268 return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
271 return (gettext("\tupgrade\n"
273 "\tupgrade [-V version] <-a | pool ...>\n"));
275 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
276 "<\"all\" | property[,...]> <pool> ...\n"));
278 return (gettext("\tset <property=value> <pool> \n"));
280 return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
281 "\t [-o property=value] <pool> <newpool> "
282 "[<device> ...]\n"));
284 return (gettext("\treguid <pool>\n"));
293 * Callback routine that will print out a pool property value.
296 print_prop_cb(int prop
, void *cb
)
300 (void) fprintf(fp
, "\t%-15s ", zpool_prop_to_name(prop
));
302 if (zpool_prop_readonly(prop
))
303 (void) fprintf(fp
, " NO ");
305 (void) fprintf(fp
, " YES ");
307 if (zpool_prop_values(prop
) == NULL
)
308 (void) fprintf(fp
, "-\n");
310 (void) fprintf(fp
, "%s\n", zpool_prop_values(prop
));
316 * Display usage message. If we're inside a command, display only the usage for
317 * that command. Otherwise, iterate over the entire command table and display
318 * a complete usage message.
321 usage(boolean_t requested
)
323 FILE *fp
= requested
? stdout
: stderr
;
325 if (current_command
== NULL
) {
328 (void) fprintf(fp
, gettext("usage: zpool command args ...\n"));
330 gettext("where 'command' is one of the following:\n\n"));
332 for (i
= 0; i
< NCOMMAND
; i
++) {
333 if (command_table
[i
].name
== NULL
)
334 (void) fprintf(fp
, "\n");
336 (void) fprintf(fp
, "%s",
337 get_usage(command_table
[i
].usage
));
340 (void) fprintf(fp
, gettext("usage:\n"));
341 (void) fprintf(fp
, "%s", get_usage(current_command
->usage
));
344 if (current_command
!= NULL
&&
345 ((strcmp(current_command
->name
, "set") == 0) ||
346 (strcmp(current_command
->name
, "get") == 0) ||
347 (strcmp(current_command
->name
, "list") == 0))) {
350 gettext("\nthe following properties are supported:\n"));
352 (void) fprintf(fp
, "\n\t%-15s %s %s\n\n",
353 "PROPERTY", "EDIT", "VALUES");
355 /* Iterate over all properties */
356 (void) zprop_iter(print_prop_cb
, fp
, B_FALSE
, B_TRUE
,
359 (void) fprintf(fp
, "\t%-15s ", "feature@...");
360 (void) fprintf(fp
, "YES disabled | enabled | active\n");
362 (void) fprintf(fp
, gettext("\nThe feature@ properties must be "
363 "appended with a feature name.\nSee zpool-features(5).\n"));
367 * See comments at end of main().
369 if (getenv("ZFS_ABORT") != NULL
) {
370 (void) printf("dumping core by request\n");
374 exit(requested
? 0 : 2);
378 print_vdev_tree(zpool_handle_t
*zhp
, const char *name
, nvlist_t
*nv
, int indent
,
379 boolean_t print_logs
)
386 (void) printf("\t%*s%s\n", indent
, "", name
);
388 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
389 &child
, &children
) != 0)
392 for (c
= 0; c
< children
; c
++) {
393 uint64_t is_log
= B_FALSE
;
395 (void) nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_LOG
,
397 if ((is_log
&& !print_logs
) || (!is_log
&& print_logs
))
400 vname
= zpool_vdev_name(g_zfs
, zhp
, child
[c
], B_FALSE
);
401 print_vdev_tree(zhp
, vname
, child
[c
], indent
+ 2,
408 prop_list_contains_feature(nvlist_t
*proplist
)
411 for (nvp
= nvlist_next_nvpair(proplist
, NULL
); NULL
!= nvp
;
412 nvp
= nvlist_next_nvpair(proplist
, nvp
)) {
413 if (zpool_prop_feature(nvpair_name(nvp
)))
420 * Add a property pair (name, string-value) into a property nvlist.
423 add_prop_list(const char *propname
, char *propval
, nvlist_t
**props
,
426 zpool_prop_t prop
= ZPOOL_PROP_INVAL
;
432 if (*props
== NULL
&&
433 nvlist_alloc(props
, NV_UNIQUE_NAME
, 0) != 0) {
434 (void) fprintf(stderr
,
435 gettext("internal error: out of memory\n"));
442 const char *vname
= zpool_prop_to_name(ZPOOL_PROP_VERSION
);
444 if ((prop
= zpool_name_to_prop(propname
)) == ZPOOL_PROP_INVAL
&&
445 !zpool_prop_feature(propname
)) {
446 (void) fprintf(stderr
, gettext("property '%s' is "
447 "not a valid pool property\n"), propname
);
452 * feature@ properties and version should not be specified
455 if ((prop
== ZPOOL_PROP_INVAL
&& zpool_prop_feature(propname
) &&
456 nvlist_exists(proplist
, vname
)) ||
457 (prop
== ZPOOL_PROP_VERSION
&&
458 prop_list_contains_feature(proplist
))) {
459 (void) fprintf(stderr
, gettext("'feature@' and "
460 "'version' properties cannot be specified "
466 if (zpool_prop_feature(propname
))
469 normnm
= zpool_prop_to_name(prop
);
471 if ((fprop
= zfs_name_to_prop(propname
)) != ZPROP_INVAL
) {
472 normnm
= zfs_prop_to_name(fprop
);
478 if (nvlist_lookup_string(proplist
, normnm
, &strval
) == 0 &&
479 prop
!= ZPOOL_PROP_CACHEFILE
) {
480 (void) fprintf(stderr
, gettext("property '%s' "
481 "specified multiple times\n"), propname
);
485 if (nvlist_add_string(proplist
, normnm
, propval
) != 0) {
486 (void) fprintf(stderr
, gettext("internal "
487 "error: out of memory\n"));
495 * zpool add [-fn] <pool> <vdev> ...
497 * -f Force addition of devices, even if they appear in use
498 * -n Do not add the devices, but display the resulting layout if
499 * they were to be added.
501 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
502 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
506 zpool_do_add(int argc
, char **argv
)
508 boolean_t force
= B_FALSE
;
509 boolean_t dryrun
= B_FALSE
;
513 zpool_boot_label_t boot_type
;
520 while ((c
= getopt(argc
, argv
, "fn")) != -1) {
529 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
538 /* get pool name and check number of arguments */
540 (void) fprintf(stderr
, gettext("missing pool name argument\n"));
544 (void) fprintf(stderr
, gettext("missing vdev specification\n"));
553 if ((zhp
= zpool_open(g_zfs
, poolname
)) == NULL
)
556 if ((config
= zpool_get_config(zhp
, NULL
)) == NULL
) {
557 (void) fprintf(stderr
, gettext("pool '%s' is unavailable\n"),
563 if (zpool_is_bootable(zhp
))
564 boot_type
= ZPOOL_COPY_BOOT_LABEL
;
566 boot_type
= ZPOOL_NO_BOOT_LABEL
;
568 /* pass off to get_vdev_spec for processing */
569 boot_size
= zpool_get_prop_int(zhp
, ZPOOL_PROP_BOOTSIZE
, NULL
);
570 nvroot
= make_root_vdev(zhp
, force
, !force
, B_FALSE
, dryrun
,
571 boot_type
, boot_size
, argc
, argv
);
572 if (nvroot
== NULL
) {
578 nvlist_t
*poolnvroot
;
580 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
583 (void) printf(gettext("would update '%s' to the following "
584 "configuration:\n"), zpool_get_name(zhp
));
586 /* print original main pool and new tree */
587 print_vdev_tree(zhp
, poolname
, poolnvroot
, 0, B_FALSE
);
588 print_vdev_tree(zhp
, NULL
, nvroot
, 0, B_FALSE
);
590 /* Do the same for the logs */
591 if (num_logs(poolnvroot
) > 0) {
592 print_vdev_tree(zhp
, "logs", poolnvroot
, 0, B_TRUE
);
593 print_vdev_tree(zhp
, NULL
, nvroot
, 0, B_TRUE
);
594 } else if (num_logs(nvroot
) > 0) {
595 print_vdev_tree(zhp
, "logs", nvroot
, 0, B_TRUE
);
600 ret
= (zpool_add(zhp
, nvroot
) != 0);
610 * zpool remove <pool> <vdev> ...
612 * Removes the given vdev from the pool.
615 zpool_do_remove(int argc
, char **argv
)
620 boolean_t stop
= B_FALSE
;
621 boolean_t noop
= B_FALSE
;
622 boolean_t parsable
= B_FALSE
;
626 while ((c
= getopt(argc
, argv
, "nps")) != -1) {
638 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
647 /* get pool name and check number of arguments */
649 (void) fprintf(stderr
, gettext("missing pool name argument\n"));
655 if ((zhp
= zpool_open(g_zfs
, poolname
)) == NULL
)
659 (void) fprintf(stderr
, gettext("stop request ignored\n"));
665 (void) fprintf(stderr
, gettext("too many arguments\n"));
668 if (zpool_vdev_remove_cancel(zhp
) != 0)
672 (void) fprintf(stderr
, gettext("missing device\n"));
676 for (i
= 1; i
< argc
; i
++) {
680 if (zpool_vdev_indirect_size(zhp
, argv
[i
],
686 (void) printf("%s %llu\n",
690 zfs_nicenum(size
, valstr
,
692 (void) printf("Memory that will be "
693 "used after removing %s: %s\n",
697 if (zpool_vdev_remove(zhp
, argv
[i
]) != 0)
707 * zpool labelclear [-f] <vdev>
709 * -f Force clearing the label for the vdevs which are members of
710 * the exported or foreign pools.
712 * Verifies that the vdev is not active and zeros out the label information
716 zpool_do_labelclear(int argc
, char **argv
)
718 char vdev
[MAXPATHLEN
];
724 boolean_t inuse
= B_FALSE
;
725 boolean_t force
= B_FALSE
;
728 while ((c
= getopt(argc
, argv
, "f")) != -1) {
734 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
745 (void) fprintf(stderr
, gettext("missing vdev name\n"));
749 (void) fprintf(stderr
, gettext("too many arguments\n"));
754 * Check if we were given absolute path and use it as is.
755 * Otherwise if the provided vdev name doesn't point to a file,
756 * try prepending dsk path and appending s0.
758 (void) strlcpy(vdev
, argv
[0], sizeof (vdev
));
759 if (vdev
[0] != '/' && stat(vdev
, &st
) != 0) {
762 (void) snprintf(vdev
, sizeof (vdev
), "%s/%s",
763 ZFS_DISK_ROOT
, argv
[0]);
764 if ((s
= strrchr(argv
[0], 's')) == NULL
||
766 (void) strlcat(vdev
, "s0", sizeof (vdev
));
767 if (stat(vdev
, &st
) != 0) {
768 (void) fprintf(stderr
, gettext(
769 "failed to find device %s, try specifying absolute "
770 "path instead\n"), argv
[0]);
775 if ((fd
= open(vdev
, O_RDWR
)) < 0) {
776 (void) fprintf(stderr
, gettext("failed to open %s: %s\n"),
777 vdev
, strerror(errno
));
781 if (zpool_read_label(fd
, &config
) != 0) {
782 (void) fprintf(stderr
,
783 gettext("failed to read label from %s\n"), vdev
);
788 ret
= zpool_in_use(g_zfs
, fd
, &state
, &name
, &inuse
);
790 (void) fprintf(stderr
,
791 gettext("failed to check state for %s\n"), vdev
);
800 case POOL_STATE_ACTIVE
:
801 case POOL_STATE_SPARE
:
802 case POOL_STATE_L2CACHE
:
803 (void) fprintf(stderr
, gettext(
804 "%s is a member (%s) of pool \"%s\"\n"),
805 vdev
, zpool_pool_state_to_name(state
), name
);
809 case POOL_STATE_EXPORTED
:
812 (void) fprintf(stderr
, gettext(
813 "use '-f' to override the following error:\n"
814 "%s is a member of exported pool \"%s\"\n"),
819 case POOL_STATE_POTENTIALLY_ACTIVE
:
822 (void) fprintf(stderr
, gettext(
823 "use '-f' to override the following error:\n"
824 "%s is a member of potentially active pool \"%s\"\n"),
829 case POOL_STATE_DESTROYED
:
830 /* inuse should never be set for a destroyed pool */
836 ret
= zpool_clear_label(fd
);
838 (void) fprintf(stderr
,
839 gettext("failed to clear label for %s\n"), vdev
);
850 * zpool create [-fnd] [-B] [-o property=value] ...
851 * [-O file-system-property=value] ...
852 * [-R root] [-m mountpoint] <pool> <dev> ...
854 * -B Create boot partition.
855 * -f Force creation, even if devices appear in use
856 * -n Do not create the pool, but display the resulting layout if it
857 * were to be created.
858 * -R Create a pool under an alternate root
859 * -m Set default mountpoint for the root dataset. By default it's
861 * -o Set property=value.
862 * -d Don't automatically enable all supported pool features
863 * (individual features can be enabled with -o).
864 * -O Set fsproperty=value in the pool's root file system
866 * Creates the named pool according to the given vdev specification. The
867 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
868 * we get the nvlist back from get_vdev_spec(), we either print out the contents
869 * (if '-n' was specified), or pass it to libzfs to do the creation.
872 #define SYSTEM256 (256 * 1024 * 1024)
874 zpool_do_create(int argc
, char **argv
)
876 boolean_t force
= B_FALSE
;
877 boolean_t dryrun
= B_FALSE
;
878 boolean_t enable_all_pool_feat
= B_TRUE
;
879 zpool_boot_label_t boot_type
= ZPOOL_NO_BOOT_LABEL
;
880 uint64_t boot_size
= 0;
882 nvlist_t
*nvroot
= NULL
;
885 char *altroot
= NULL
;
886 char *mountpoint
= NULL
;
887 nvlist_t
*fsprops
= NULL
;
888 nvlist_t
*props
= NULL
;
892 while ((c
= getopt(argc
, argv
, ":fndBR:m:o:O:")) != -1) {
901 enable_all_pool_feat
= B_FALSE
;
905 * We should create the system partition.
906 * Also make sure the size is set.
908 boot_type
= ZPOOL_CREATE_BOOT_LABEL
;
910 boot_size
= SYSTEM256
;
914 if (add_prop_list(zpool_prop_to_name(
915 ZPOOL_PROP_ALTROOT
), optarg
, &props
, B_TRUE
))
917 if (nvlist_lookup_string(props
,
918 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE
),
921 if (add_prop_list(zpool_prop_to_name(
922 ZPOOL_PROP_CACHEFILE
), "none", &props
, B_TRUE
))
926 /* Equivalent to -O mountpoint=optarg */
930 if ((propval
= strchr(optarg
, '=')) == NULL
) {
931 (void) fprintf(stderr
, gettext("missing "
932 "'=' for -o option\n"));
938 if (add_prop_list(optarg
, propval
, &props
, B_TRUE
))
942 * Get bootsize value for make_root_vdev().
944 if (zpool_name_to_prop(optarg
) == ZPOOL_PROP_BOOTSIZE
) {
945 if (zfs_nicestrtonum(g_zfs
, propval
,
946 &boot_size
) < 0 || boot_size
== 0) {
947 (void) fprintf(stderr
,
948 gettext("bad boot partition size "
949 "'%s': %s\n"), propval
,
950 libzfs_error_description(g_zfs
));
956 * If the user is creating a pool that doesn't support
957 * feature flags, don't enable any features.
959 if (zpool_name_to_prop(optarg
) == ZPOOL_PROP_VERSION
) {
963 ver
= strtoull(propval
, &end
, 10);
965 ver
< SPA_VERSION_FEATURES
) {
966 enable_all_pool_feat
= B_FALSE
;
969 if (zpool_name_to_prop(optarg
) == ZPOOL_PROP_ALTROOT
)
973 if ((propval
= strchr(optarg
, '=')) == NULL
) {
974 (void) fprintf(stderr
, gettext("missing "
975 "'=' for -O option\n"));
982 * Mountpoints are checked and then added later.
983 * Uniquely among properties, they can be specified
984 * more than once, to avoid conflict with -m.
986 if (0 == strcmp(optarg
,
987 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT
))) {
988 mountpoint
= propval
;
989 } else if (add_prop_list(optarg
, propval
, &fsprops
,
995 (void) fprintf(stderr
, gettext("missing argument for "
996 "'%c' option\n"), optopt
);
999 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
1008 /* get pool name and check number of arguments */
1010 (void) fprintf(stderr
, gettext("missing pool name argument\n"));
1014 (void) fprintf(stderr
, gettext("missing vdev specification\n"));
1021 * As a special case, check for use of '/' in the name, and direct the
1022 * user to use 'zfs create' instead.
1024 if (strchr(poolname
, '/') != NULL
) {
1025 (void) fprintf(stderr
, gettext("cannot create '%s': invalid "
1026 "character '/' in pool name\n"), poolname
);
1027 (void) fprintf(stderr
, gettext("use 'zfs create' to "
1028 "create a dataset\n"));
1033 * Make sure the bootsize is set when ZPOOL_CREATE_BOOT_LABEL is used,
1034 * and not set otherwise.
1036 if (boot_type
== ZPOOL_CREATE_BOOT_LABEL
) {
1037 const char *propname
;
1038 char *strptr
, *buf
= NULL
;
1041 propname
= zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE
);
1042 if (nvlist_lookup_string(props
, propname
, &strptr
) != 0) {
1043 (void) asprintf(&buf
, "%" PRIu64
, boot_size
);
1045 (void) fprintf(stderr
,
1046 gettext("internal error: out of memory\n"));
1049 rv
= add_prop_list(propname
, buf
, &props
, B_TRUE
);
1055 const char *propname
;
1058 propname
= zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE
);
1059 if (nvlist_lookup_string(props
, propname
, &strptr
) == 0) {
1060 (void) fprintf(stderr
, gettext("error: setting boot "
1061 "partition size requires option '-B'\n"));
1066 /* pass off to get_vdev_spec for bulk processing */
1067 nvroot
= make_root_vdev(NULL
, force
, !force
, B_FALSE
, dryrun
,
1068 boot_type
, boot_size
, argc
- 1, argv
+ 1);
1072 /* make_root_vdev() allows 0 toplevel children if there are spares */
1073 if (!zfs_allocatable_devs(nvroot
)) {
1074 (void) fprintf(stderr
, gettext("invalid vdev "
1075 "specification: at least one toplevel vdev must be "
1080 if (altroot
!= NULL
&& altroot
[0] != '/') {
1081 (void) fprintf(stderr
, gettext("invalid alternate root '%s': "
1082 "must be an absolute path\n"), altroot
);
1087 * Check the validity of the mountpoint and direct the user to use the
1088 * '-m' mountpoint option if it looks like its in use.
1090 if (mountpoint
== NULL
||
1091 (strcmp(mountpoint
, ZFS_MOUNTPOINT_LEGACY
) != 0 &&
1092 strcmp(mountpoint
, ZFS_MOUNTPOINT_NONE
) != 0)) {
1093 char buf
[MAXPATHLEN
];
1096 if (mountpoint
&& mountpoint
[0] != '/') {
1097 (void) fprintf(stderr
, gettext("invalid mountpoint "
1098 "'%s': must be an absolute path, 'legacy', or "
1099 "'none'\n"), mountpoint
);
1103 if (mountpoint
== NULL
) {
1104 if (altroot
!= NULL
)
1105 (void) snprintf(buf
, sizeof (buf
), "%s/%s",
1108 (void) snprintf(buf
, sizeof (buf
), "/%s",
1111 if (altroot
!= NULL
)
1112 (void) snprintf(buf
, sizeof (buf
), "%s%s",
1113 altroot
, mountpoint
);
1115 (void) snprintf(buf
, sizeof (buf
), "%s",
1119 if ((dirp
= opendir(buf
)) == NULL
&& errno
!= ENOENT
) {
1120 (void) fprintf(stderr
, gettext("mountpoint '%s' : "
1121 "%s\n"), buf
, strerror(errno
));
1122 (void) fprintf(stderr
, gettext("use '-m' "
1123 "option to provide a different default\n"));
1128 while (count
< 3 && readdir(dirp
) != NULL
)
1130 (void) closedir(dirp
);
1133 (void) fprintf(stderr
, gettext("mountpoint "
1134 "'%s' exists and is not empty\n"), buf
);
1135 (void) fprintf(stderr
, gettext("use '-m' "
1136 "option to provide a "
1137 "different default\n"));
1144 * Now that the mountpoint's validity has been checked, ensure that
1145 * the property is set appropriately prior to creating the pool.
1147 if (mountpoint
!= NULL
) {
1148 ret
= add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT
),
1149 mountpoint
, &fsprops
, B_FALSE
);
1157 * For a dry run invocation, print out a basic message and run
1158 * through all the vdevs in the list and print out in an
1159 * appropriate hierarchy.
1161 (void) printf(gettext("would create '%s' with the "
1162 "following layout:\n\n"), poolname
);
1164 print_vdev_tree(NULL
, poolname
, nvroot
, 0, B_FALSE
);
1165 if (num_logs(nvroot
) > 0)
1166 print_vdev_tree(NULL
, "logs", nvroot
, 0, B_TRUE
);
1171 * Hand off to libzfs.
1173 if (enable_all_pool_feat
) {
1175 for (i
= 0; i
< SPA_FEATURES
; i
++) {
1176 char propname
[MAXPATHLEN
];
1177 zfeature_info_t
*feat
= &spa_feature_table
[i
];
1179 (void) snprintf(propname
, sizeof (propname
),
1180 "feature@%s", feat
->fi_uname
);
1183 * Skip feature if user specified it manually
1184 * on the command line.
1186 if (nvlist_exists(props
, propname
))
1189 ret
= add_prop_list(propname
,
1190 ZFS_FEATURE_ENABLED
, &props
, B_TRUE
);
1197 if (zpool_create(g_zfs
, poolname
,
1198 nvroot
, props
, fsprops
) == 0) {
1199 zfs_handle_t
*pool
= zfs_open(g_zfs
, poolname
,
1200 ZFS_TYPE_FILESYSTEM
);
1202 if (zfs_mount(pool
, NULL
, 0) == 0)
1203 ret
= zfs_shareall(pool
);
1206 } else if (libzfs_errno(g_zfs
) == EZFS_INVALIDNAME
) {
1207 (void) fprintf(stderr
, gettext("pool name may have "
1213 nvlist_free(nvroot
);
1214 nvlist_free(fsprops
);
1218 nvlist_free(fsprops
);
1225 * zpool destroy <pool>
1227 * -f Forcefully unmount any datasets
1229 * Destroy the given pool. Automatically unmounts any datasets in the pool.
1232 zpool_do_destroy(int argc
, char **argv
)
1234 boolean_t force
= B_FALSE
;
1237 zpool_handle_t
*zhp
;
1241 while ((c
= getopt(argc
, argv
, "f")) != -1) {
1247 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
1256 /* check arguments */
1258 (void) fprintf(stderr
, gettext("missing pool argument\n"));
1262 (void) fprintf(stderr
, gettext("too many arguments\n"));
1268 if ((zhp
= zpool_open_canfail(g_zfs
, pool
)) == NULL
) {
1270 * As a special case, check for use of '/' in the name, and
1271 * direct the user to use 'zfs destroy' instead.
1273 if (strchr(pool
, '/') != NULL
)
1274 (void) fprintf(stderr
, gettext("use 'zfs destroy' to "
1275 "destroy a dataset\n"));
1279 if (zpool_disable_datasets(zhp
, force
) != 0) {
1280 (void) fprintf(stderr
, gettext("could not destroy '%s': "
1281 "could not unmount datasets\n"), zpool_get_name(zhp
));
1285 /* The history must be logged as part of the export */
1286 log_history
= B_FALSE
;
1288 ret
= (zpool_destroy(zhp
, history_str
) != 0);
1296 * zpool export [-f] <pool> ...
1298 * -f Forcefully unmount datasets
1300 * Export the given pools. By default, the command will attempt to cleanly
1301 * unmount any active datasets within the pool. If the '-f' flag is specified,
1302 * then the datasets will be forcefully unmounted.
1305 zpool_do_export(int argc
, char **argv
)
1307 boolean_t force
= B_FALSE
;
1308 boolean_t hardforce
= B_FALSE
;
1310 zpool_handle_t
*zhp
;
1315 while ((c
= getopt(argc
, argv
, "fF")) != -1) {
1324 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
1333 /* check arguments */
1335 (void) fprintf(stderr
, gettext("missing pool argument\n"));
1340 for (i
= 0; i
< argc
; i
++) {
1341 if ((zhp
= zpool_open_canfail(g_zfs
, argv
[i
])) == NULL
) {
1346 if (zpool_disable_datasets(zhp
, force
) != 0) {
1352 /* The history must be logged as part of the export */
1353 log_history
= B_FALSE
;
1356 if (zpool_export_force(zhp
, history_str
) != 0)
1358 } else if (zpool_export(zhp
, force
, history_str
) != 0) {
1369 * Given a vdev configuration, determine the maximum width needed for the device
1373 max_width(zpool_handle_t
*zhp
, nvlist_t
*nv
, int depth
, int max
)
1375 char *name
= zpool_vdev_name(g_zfs
, zhp
, nv
, B_TRUE
);
1380 if (strlen(name
) + depth
> max
)
1381 max
= strlen(name
) + depth
;
1385 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_SPARES
,
1386 &child
, &children
) == 0) {
1387 for (c
= 0; c
< children
; c
++)
1388 if ((ret
= max_width(zhp
, child
[c
], depth
+ 2,
1393 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_L2CACHE
,
1394 &child
, &children
) == 0) {
1395 for (c
= 0; c
< children
; c
++)
1396 if ((ret
= max_width(zhp
, child
[c
], depth
+ 2,
1401 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
1402 &child
, &children
) == 0) {
1403 for (c
= 0; c
< children
; c
++)
1404 if ((ret
= max_width(zhp
, child
[c
], depth
+ 2,
1413 typedef struct spare_cbdata
{
1415 zpool_handle_t
*cb_zhp
;
1419 find_vdev(nvlist_t
*nv
, uint64_t search
)
1425 if (nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
, &guid
) == 0 &&
1429 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
1430 &child
, &children
) == 0) {
1431 for (c
= 0; c
< children
; c
++)
1432 if (find_vdev(child
[c
], search
))
1440 find_spare(zpool_handle_t
*zhp
, void *data
)
1442 spare_cbdata_t
*cbp
= data
;
1443 nvlist_t
*config
, *nvroot
;
1445 config
= zpool_get_config(zhp
, NULL
);
1446 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
1449 if (find_vdev(nvroot
, cbp
->cb_guid
)) {
1459 * Print out configuration state as requested by status_callback.
1462 print_status_config(zpool_handle_t
*zhp
, const char *name
, nvlist_t
*nv
,
1463 int namewidth
, int depth
, boolean_t isspare
)
1467 pool_scan_stat_t
*ps
= NULL
;
1469 char rbuf
[6], wbuf
[6], cbuf
[6];
1471 uint64_t notpresent
;
1476 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
1477 &child
, &children
) != 0)
1480 verify(nvlist_lookup_uint64_array(nv
, ZPOOL_CONFIG_VDEV_STATS
,
1481 (uint64_t **)&vs
, &c
) == 0);
1483 verify(nvlist_lookup_string(nv
, ZPOOL_CONFIG_TYPE
, &type
) == 0);
1485 if (strcmp(type
, VDEV_TYPE_INDIRECT
) == 0)
1488 state
= zpool_state_to_name(vs
->vs_state
, vs
->vs_aux
);
1491 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1494 if (vs
->vs_aux
== VDEV_AUX_SPARED
)
1496 else if (vs
->vs_state
== VDEV_STATE_HEALTHY
)
1500 (void) printf("\t%*s%-*s %-8s", depth
, "", namewidth
- depth
,
1504 zfs_nicenum(vs
->vs_read_errors
, rbuf
, sizeof (rbuf
));
1505 zfs_nicenum(vs
->vs_write_errors
, wbuf
, sizeof (wbuf
));
1506 zfs_nicenum(vs
->vs_checksum_errors
, cbuf
, sizeof (cbuf
));
1507 (void) printf(" %5s %5s %5s", rbuf
, wbuf
, cbuf
);
1510 if (nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_NOT_PRESENT
,
1511 ¬present
) == 0) {
1513 verify(nvlist_lookup_string(nv
, ZPOOL_CONFIG_PATH
, &path
) == 0);
1514 (void) printf(" was %s", path
);
1515 } else if (vs
->vs_aux
!= 0) {
1518 switch (vs
->vs_aux
) {
1519 case VDEV_AUX_OPEN_FAILED
:
1520 (void) printf(gettext("cannot open"));
1523 case VDEV_AUX_BAD_GUID_SUM
:
1524 (void) printf(gettext("missing device"));
1527 case VDEV_AUX_NO_REPLICAS
:
1528 (void) printf(gettext("insufficient replicas"));
1531 case VDEV_AUX_VERSION_NEWER
:
1532 (void) printf(gettext("newer version"));
1535 case VDEV_AUX_UNSUP_FEAT
:
1536 (void) printf(gettext("unsupported feature(s)"));
1539 case VDEV_AUX_SPARED
:
1540 verify(nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
,
1542 if (zpool_iter(g_zfs
, find_spare
, &cb
) == 1) {
1543 if (strcmp(zpool_get_name(cb
.cb_zhp
),
1544 zpool_get_name(zhp
)) == 0)
1545 (void) printf(gettext("currently in "
1548 (void) printf(gettext("in use by "
1550 zpool_get_name(cb
.cb_zhp
));
1551 zpool_close(cb
.cb_zhp
);
1553 (void) printf(gettext("currently in use"));
1557 case VDEV_AUX_ERR_EXCEEDED
:
1558 (void) printf(gettext("too many errors"));
1561 case VDEV_AUX_IO_FAILURE
:
1562 (void) printf(gettext("experienced I/O failures"));
1565 case VDEV_AUX_BAD_LOG
:
1566 (void) printf(gettext("bad intent log"));
1569 case VDEV_AUX_EXTERNAL
:
1570 (void) printf(gettext("external device fault"));
1573 case VDEV_AUX_SPLIT_POOL
:
1574 (void) printf(gettext("split into new pool"));
1577 case VDEV_AUX_CHILDREN_OFFLINE
:
1578 (void) printf(gettext("all children offline"));
1582 (void) printf(gettext("corrupted data"));
1587 (void) nvlist_lookup_uint64_array(nv
, ZPOOL_CONFIG_SCAN_STATS
,
1588 (uint64_t **)&ps
, &c
);
1590 if (ps
&& ps
->pss_state
== DSS_SCANNING
&&
1591 vs
->vs_scan_processed
!= 0 && children
== 0) {
1592 (void) printf(gettext(" (%s)"),
1593 (ps
->pss_func
== POOL_SCAN_RESILVER
) ?
1594 "resilvering" : "repairing");
1597 if ((vs
->vs_initialize_state
== VDEV_INITIALIZE_ACTIVE
||
1598 vs
->vs_initialize_state
== VDEV_INITIALIZE_SUSPENDED
||
1599 vs
->vs_initialize_state
== VDEV_INITIALIZE_COMPLETE
) &&
1600 !vs
->vs_scan_removing
) {
1603 struct tm zaction_ts
;
1605 time_t t
= vs
->vs_initialize_action_time
;
1606 int initialize_pct
= 100;
1607 if (vs
->vs_initialize_state
!= VDEV_INITIALIZE_COMPLETE
) {
1608 initialize_pct
= (vs
->vs_initialize_bytes_done
* 100 /
1609 (vs
->vs_initialize_bytes_est
+ 1));
1612 (void) localtime_r(&t
, &zaction_ts
);
1613 (void) strftime(tbuf
, sizeof (tbuf
), "%c", &zaction_ts
);
1615 switch (vs
->vs_initialize_state
) {
1616 case VDEV_INITIALIZE_SUSPENDED
:
1617 (void) snprintf(zbuf
, sizeof (zbuf
),
1618 ", suspended, started at %s", tbuf
);
1620 case VDEV_INITIALIZE_ACTIVE
:
1621 (void) snprintf(zbuf
, sizeof (zbuf
),
1622 ", started at %s", tbuf
);
1624 case VDEV_INITIALIZE_COMPLETE
:
1625 (void) snprintf(zbuf
, sizeof (zbuf
),
1626 ", completed at %s", tbuf
);
1630 (void) printf(gettext(" (%d%% initialized%s)"),
1631 initialize_pct
, zbuf
);
1634 (void) printf("\n");
1636 for (c
= 0; c
< children
; c
++) {
1637 uint64_t islog
= B_FALSE
, ishole
= B_FALSE
;
1639 /* Don't print logs or holes here */
1640 (void) nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_LOG
,
1642 (void) nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_HOLE
,
1644 if (islog
|| ishole
)
1646 vname
= zpool_vdev_name(g_zfs
, zhp
, child
[c
], B_TRUE
);
1647 print_status_config(zhp
, vname
, child
[c
],
1648 namewidth
, depth
+ 2, isspare
);
1655 * Print the configuration of an exported pool. Iterate over all vdevs in the
1656 * pool, printing out the name and status for each one.
1659 print_import_config(const char *name
, nvlist_t
*nv
, int namewidth
, int depth
)
1666 verify(nvlist_lookup_string(nv
, ZPOOL_CONFIG_TYPE
, &type
) == 0);
1667 if (strcmp(type
, VDEV_TYPE_MISSING
) == 0 ||
1668 strcmp(type
, VDEV_TYPE_HOLE
) == 0)
1671 verify(nvlist_lookup_uint64_array(nv
, ZPOOL_CONFIG_VDEV_STATS
,
1672 (uint64_t **)&vs
, &c
) == 0);
1674 (void) printf("\t%*s%-*s", depth
, "", namewidth
- depth
, name
);
1675 (void) printf(" %s", zpool_state_to_name(vs
->vs_state
, vs
->vs_aux
));
1677 if (vs
->vs_aux
!= 0) {
1680 switch (vs
->vs_aux
) {
1681 case VDEV_AUX_OPEN_FAILED
:
1682 (void) printf(gettext("cannot open"));
1685 case VDEV_AUX_BAD_GUID_SUM
:
1686 (void) printf(gettext("missing device"));
1689 case VDEV_AUX_NO_REPLICAS
:
1690 (void) printf(gettext("insufficient replicas"));
1693 case VDEV_AUX_VERSION_NEWER
:
1694 (void) printf(gettext("newer version"));
1697 case VDEV_AUX_UNSUP_FEAT
:
1698 (void) printf(gettext("unsupported feature(s)"));
1701 case VDEV_AUX_ERR_EXCEEDED
:
1702 (void) printf(gettext("too many errors"));
1705 case VDEV_AUX_CHILDREN_OFFLINE
:
1706 (void) printf(gettext("all children offline"));
1710 (void) printf(gettext("corrupted data"));
1714 (void) printf("\n");
1716 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
1717 &child
, &children
) != 0)
1720 for (c
= 0; c
< children
; c
++) {
1721 uint64_t is_log
= B_FALSE
;
1723 (void) nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_LOG
,
1728 vname
= zpool_vdev_name(g_zfs
, NULL
, child
[c
], B_TRUE
);
1729 print_import_config(vname
, child
[c
], namewidth
, depth
+ 2);
1733 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_L2CACHE
,
1734 &child
, &children
) == 0) {
1735 (void) printf(gettext("\tcache\n"));
1736 for (c
= 0; c
< children
; c
++) {
1737 vname
= zpool_vdev_name(g_zfs
, NULL
, child
[c
], B_FALSE
);
1738 (void) printf("\t %s\n", vname
);
1743 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_SPARES
,
1744 &child
, &children
) == 0) {
1745 (void) printf(gettext("\tspares\n"));
1746 for (c
= 0; c
< children
; c
++) {
1747 vname
= zpool_vdev_name(g_zfs
, NULL
, child
[c
], B_FALSE
);
1748 (void) printf("\t %s\n", vname
);
1756 * Logs are recorded as top level vdevs in the main pool child array
1757 * but with "is_log" set to 1. We use either print_status_config() or
1758 * print_import_config() to print the top level logs then any log
1759 * children (eg mirrored slogs) are printed recursively - which
1760 * works because only the top level vdev is marked "is_log"
1763 print_logs(zpool_handle_t
*zhp
, nvlist_t
*nv
, int namewidth
, boolean_t verbose
)
1768 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
, &child
,
1772 (void) printf(gettext("\tlogs\n"));
1774 for (c
= 0; c
< children
; c
++) {
1775 uint64_t is_log
= B_FALSE
;
1778 (void) nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_LOG
,
1782 name
= zpool_vdev_name(g_zfs
, zhp
, child
[c
], B_TRUE
);
1784 print_status_config(zhp
, name
, child
[c
], namewidth
,
1787 print_import_config(name
, child
[c
], namewidth
, 2);
1793 * Display the status for the given pool.
1796 show_import(nvlist_t
*config
)
1798 uint64_t pool_state
;
1810 verify(nvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
,
1812 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
,
1814 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_STATE
,
1816 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
1819 verify(nvlist_lookup_uint64_array(nvroot
, ZPOOL_CONFIG_VDEV_STATS
,
1820 (uint64_t **)&vs
, &vsc
) == 0);
1821 health
= zpool_state_to_name(vs
->vs_state
, vs
->vs_aux
);
1823 reason
= zpool_import_status(config
, &msgid
);
1825 (void) printf(gettext(" pool: %s\n"), name
);
1826 (void) printf(gettext(" id: %llu\n"), (u_longlong_t
)guid
);
1827 (void) printf(gettext(" state: %s"), health
);
1828 if (pool_state
== POOL_STATE_DESTROYED
)
1829 (void) printf(gettext(" (DESTROYED)"));
1830 (void) printf("\n");
1833 case ZPOOL_STATUS_MISSING_DEV_R
:
1834 case ZPOOL_STATUS_MISSING_DEV_NR
:
1835 case ZPOOL_STATUS_BAD_GUID_SUM
:
1836 (void) printf(gettext(" status: One or more devices are "
1837 "missing from the system.\n"));
1840 case ZPOOL_STATUS_CORRUPT_LABEL_R
:
1841 case ZPOOL_STATUS_CORRUPT_LABEL_NR
:
1842 (void) printf(gettext(" status: One or more devices contains "
1843 "corrupted data.\n"));
1846 case ZPOOL_STATUS_CORRUPT_DATA
:
1848 gettext(" status: The pool data is corrupted.\n"));
1851 case ZPOOL_STATUS_OFFLINE_DEV
:
1852 (void) printf(gettext(" status: One or more devices "
1853 "are offlined.\n"));
1856 case ZPOOL_STATUS_CORRUPT_POOL
:
1857 (void) printf(gettext(" status: The pool metadata is "
1861 case ZPOOL_STATUS_VERSION_OLDER
:
1862 (void) printf(gettext(" status: The pool is formatted using a "
1863 "legacy on-disk version.\n"));
1866 case ZPOOL_STATUS_VERSION_NEWER
:
1867 (void) printf(gettext(" status: The pool is formatted using an "
1868 "incompatible version.\n"));
1871 case ZPOOL_STATUS_FEAT_DISABLED
:
1872 (void) printf(gettext(" status: Some supported features are "
1873 "not enabled on the pool.\n"));
1876 case ZPOOL_STATUS_UNSUP_FEAT_READ
:
1877 (void) printf(gettext("status: The pool uses the following "
1878 "feature(s) not supported on this system:\n"));
1879 zpool_print_unsup_feat(config
);
1882 case ZPOOL_STATUS_UNSUP_FEAT_WRITE
:
1883 (void) printf(gettext("status: The pool can only be accessed "
1884 "in read-only mode on this system. It\n\tcannot be "
1885 "accessed in read-write mode because it uses the "
1886 "following\n\tfeature(s) not supported on this system:\n"));
1887 zpool_print_unsup_feat(config
);
1890 case ZPOOL_STATUS_HOSTID_MISMATCH
:
1891 (void) printf(gettext(" status: The pool was last accessed by "
1892 "another system.\n"));
1895 case ZPOOL_STATUS_FAULTED_DEV_R
:
1896 case ZPOOL_STATUS_FAULTED_DEV_NR
:
1897 (void) printf(gettext(" status: One or more devices are "
1901 case ZPOOL_STATUS_BAD_LOG
:
1902 (void) printf(gettext(" status: An intent log record cannot be "
1906 case ZPOOL_STATUS_RESILVERING
:
1907 (void) printf(gettext(" status: One or more devices were being "
1913 * No other status can be seen when importing pools.
1915 assert(reason
== ZPOOL_STATUS_OK
);
1919 * Print out an action according to the overall state of the pool.
1921 if (vs
->vs_state
== VDEV_STATE_HEALTHY
) {
1922 if (reason
== ZPOOL_STATUS_VERSION_OLDER
||
1923 reason
== ZPOOL_STATUS_FEAT_DISABLED
) {
1924 (void) printf(gettext(" action: The pool can be "
1925 "imported using its name or numeric identifier, "
1926 "though\n\tsome features will not be available "
1927 "without an explicit 'zpool upgrade'.\n"));
1928 } else if (reason
== ZPOOL_STATUS_HOSTID_MISMATCH
) {
1929 (void) printf(gettext(" action: The pool can be "
1930 "imported using its name or numeric "
1931 "identifier and\n\tthe '-f' flag.\n"));
1933 (void) printf(gettext(" action: The pool can be "
1934 "imported using its name or numeric "
1937 } else if (vs
->vs_state
== VDEV_STATE_DEGRADED
) {
1938 (void) printf(gettext(" action: The pool can be imported "
1939 "despite missing or damaged devices. The\n\tfault "
1940 "tolerance of the pool may be compromised if imported.\n"));
1943 case ZPOOL_STATUS_VERSION_NEWER
:
1944 (void) printf(gettext(" action: The pool cannot be "
1945 "imported. Access the pool on a system running "
1946 "newer\n\tsoftware, or recreate the pool from "
1949 case ZPOOL_STATUS_UNSUP_FEAT_READ
:
1950 (void) printf(gettext("action: The pool cannot be "
1951 "imported. Access the pool on a system that "
1952 "supports\n\tthe required feature(s), or recreate "
1953 "the pool from backup.\n"));
1955 case ZPOOL_STATUS_UNSUP_FEAT_WRITE
:
1956 (void) printf(gettext("action: The pool cannot be "
1957 "imported in read-write mode. Import the pool "
1959 "\t\"-o readonly=on\", access the pool on a system "
1960 "that supports the\n\trequired feature(s), or "
1961 "recreate the pool from backup.\n"));
1963 case ZPOOL_STATUS_MISSING_DEV_R
:
1964 case ZPOOL_STATUS_MISSING_DEV_NR
:
1965 case ZPOOL_STATUS_BAD_GUID_SUM
:
1966 (void) printf(gettext(" action: The pool cannot be "
1967 "imported. Attach the missing\n\tdevices and try "
1971 (void) printf(gettext(" action: The pool cannot be "
1972 "imported due to damaged devices or data.\n"));
1976 /* Print the comment attached to the pool. */
1977 if (nvlist_lookup_string(config
, ZPOOL_CONFIG_COMMENT
, &comment
) == 0)
1978 (void) printf(gettext("comment: %s\n"), comment
);
1981 * If the state is "closed" or "can't open", and the aux state
1982 * is "corrupt data":
1984 if (((vs
->vs_state
== VDEV_STATE_CLOSED
) ||
1985 (vs
->vs_state
== VDEV_STATE_CANT_OPEN
)) &&
1986 (vs
->vs_aux
== VDEV_AUX_CORRUPT_DATA
)) {
1987 if (pool_state
== POOL_STATE_DESTROYED
)
1988 (void) printf(gettext("\tThe pool was destroyed, "
1989 "but can be imported using the '-Df' flags.\n"));
1990 else if (pool_state
!= POOL_STATE_EXPORTED
)
1991 (void) printf(gettext("\tThe pool may be active on "
1992 "another system, but can be imported using\n\t"
1993 "the '-f' flag.\n"));
1997 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"),
2000 (void) printf(gettext(" config:\n\n"));
2002 namewidth
= max_width(NULL
, nvroot
, 0, 0);
2006 print_import_config(name
, nvroot
, namewidth
, 0);
2007 if (num_logs(nvroot
) > 0)
2008 print_logs(NULL
, nvroot
, namewidth
, B_FALSE
);
2010 if (reason
== ZPOOL_STATUS_BAD_GUID_SUM
) {
2011 (void) printf(gettext("\n\tAdditional devices are known to "
2012 "be part of this pool, though their\n\texact "
2013 "configuration cannot be determined.\n"));
2018 * Perform the import for the given configuration. This passes the heavy
2019 * lifting off to zpool_import_props(), and then mounts the datasets contained
2023 do_import(nvlist_t
*config
, const char *newname
, const char *mntopts
,
2024 nvlist_t
*props
, int flags
)
2026 zpool_handle_t
*zhp
;
2031 verify(nvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
,
2034 verify(nvlist_lookup_uint64(config
,
2035 ZPOOL_CONFIG_POOL_STATE
, &state
) == 0);
2036 verify(nvlist_lookup_uint64(config
,
2037 ZPOOL_CONFIG_VERSION
, &version
) == 0);
2038 if (!SPA_VERSION_IS_SUPPORTED(version
)) {
2039 (void) fprintf(stderr
, gettext("cannot import '%s': pool "
2040 "is formatted using an unsupported ZFS version\n"), name
);
2042 } else if (state
!= POOL_STATE_EXPORTED
&&
2043 !(flags
& ZFS_IMPORT_ANY_HOST
)) {
2046 if (nvlist_lookup_uint64(config
, ZPOOL_CONFIG_HOSTID
,
2048 if ((unsigned long)hostid
!= gethostid()) {
2053 verify(nvlist_lookup_string(config
,
2054 ZPOOL_CONFIG_HOSTNAME
, &hostname
) == 0);
2055 verify(nvlist_lookup_uint64(config
,
2056 ZPOOL_CONFIG_TIMESTAMP
, ×tamp
) == 0);
2058 (void) fprintf(stderr
, gettext("cannot import "
2059 "'%s': pool may be in use from other "
2060 "system, it was last accessed by %s "
2061 "(hostid: 0x%lx) on %s"), name
, hostname
,
2062 (unsigned long)hostid
,
2063 asctime(localtime(&t
)));
2064 (void) fprintf(stderr
, gettext("use '-f' to "
2065 "import anyway\n"));
2069 (void) fprintf(stderr
, gettext("cannot import '%s': "
2070 "pool may be in use from other system\n"), name
);
2071 (void) fprintf(stderr
, gettext("use '-f' to import "
2077 if (zpool_import_props(g_zfs
, config
, newname
, props
, flags
) != 0)
2080 if (newname
!= NULL
)
2081 name
= (char *)newname
;
2083 if ((zhp
= zpool_open_canfail(g_zfs
, name
)) == NULL
)
2086 if (zpool_get_state(zhp
) != POOL_STATE_UNAVAIL
&&
2087 !(flags
& ZFS_IMPORT_ONLY
) &&
2088 zpool_enable_datasets(zhp
, mntopts
, 0) != 0) {
2098 * zpool checkpoint <pool>
2099 * checkpoint --discard <pool>
2101 * -d Discard the checkpoint from a checkpointed
2104 * Checkpoints the specified pool, by taking a "snapshot" of its
2105 * current state. A pool can only have one checkpoint at a time.
2108 zpool_do_checkpoint(int argc
, char **argv
)
2112 zpool_handle_t
*zhp
;
2115 struct option long_options
[] = {
2116 {"discard", no_argument
, NULL
, 'd'},
2121 while ((c
= getopt_long(argc
, argv
, ":d", long_options
, NULL
)) != -1) {
2127 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
2137 (void) fprintf(stderr
, gettext("missing pool argument\n"));
2142 (void) fprintf(stderr
, gettext("too many arguments\n"));
2148 if ((zhp
= zpool_open(g_zfs
, pool
)) == NULL
) {
2149 /* As a special case, check for use of '/' in the name */
2150 if (strchr(pool
, '/') != NULL
)
2151 (void) fprintf(stderr
, gettext("'zpool checkpoint' "
2152 "doesn't work on datasets. To save the state "
2153 "of a dataset from a specific point in time "
2154 "please use 'zfs snapshot'\n"));
2159 err
= (zpool_discard_checkpoint(zhp
) != 0);
2161 err
= (zpool_checkpoint(zhp
) != 0);
2168 #define CHECKPOINT_OPT 1024
2171 * zpool import [-d dir] [-D]
2172 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2173 * [-d dir | -c cachefile] [-f] -a
2174 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2175 * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
2177 * -c Read pool information from a cachefile instead of searching
2180 * -d Scan in a specific directory, other than /dev/dsk. More than
2181 * one directory can be specified using multiple '-d' options.
2183 * -D Scan for previously destroyed pools or import all or only
2184 * specified destroyed pools.
2186 * -R Temporarily import the pool, with all mountpoints relative to
2187 * the given root. The pool will remain exported when the machine
2190 * -V Import even in the presence of faulted vdevs. This is an
2191 * intentionally undocumented option for testing purposes, and
2192 * treats the pool configuration as complete, leaving any bad
2193 * vdevs in the FAULTED state. In other words, it does verbatim
2196 * -f Force import, even if it appears that the pool is active.
2198 * -F Attempt rewind if necessary.
2200 * -n See if rewind would work, but don't actually rewind.
2202 * -N Import the pool but don't mount datasets.
2204 * -T Specify a starting txg to use for import. This option is
2205 * intentionally undocumented option for testing purposes.
2207 * -a Import all pools found.
2209 * -o Set property=value and/or temporary mount options (without '=').
2211 * --rewind-to-checkpoint
2212 * Import the pool and revert back to the checkpoint.
2214 * The import command scans for pools to import, and import pools based on pool
2215 * name and GUID. The pool can also be renamed as part of the import process.
2218 zpool_do_import(int argc
, char **argv
)
2220 char **searchdirs
= NULL
;
2224 nvlist_t
*pools
= NULL
;
2225 boolean_t do_all
= B_FALSE
;
2226 boolean_t do_destroyed
= B_FALSE
;
2227 char *mntopts
= NULL
;
2230 uint64_t searchguid
= 0;
2231 char *searchname
= NULL
;
2233 nvlist_t
*found_config
;
2234 nvlist_t
*policy
= NULL
;
2235 nvlist_t
*props
= NULL
;
2237 int flags
= ZFS_IMPORT_NORMAL
;
2238 uint32_t rewind_policy
= ZPOOL_NO_REWIND
;
2239 boolean_t dryrun
= B_FALSE
;
2240 boolean_t do_rewind
= B_FALSE
;
2241 boolean_t xtreme_rewind
= B_FALSE
;
2242 uint64_t pool_state
, txg
= -1ULL;
2243 char *cachefile
= NULL
;
2244 importargs_t idata
= { 0 };
2248 struct option long_options
[] = {
2249 {"rewind-to-checkpoint", no_argument
, NULL
, CHECKPOINT_OPT
},
2254 while ((c
= getopt_long(argc
, argv
, ":aCc:d:DEfFmnNo:rR:T:VX",
2255 long_options
, NULL
)) != -1) {
2264 if (searchdirs
== NULL
) {
2265 searchdirs
= safe_malloc(sizeof (char *));
2267 char **tmp
= safe_malloc((nsearch
+ 1) *
2269 bcopy(searchdirs
, tmp
, nsearch
*
2274 searchdirs
[nsearch
++] = optarg
;
2277 do_destroyed
= B_TRUE
;
2280 flags
|= ZFS_IMPORT_ANY_HOST
;
2286 flags
|= ZFS_IMPORT_MISSING_LOG
;
2292 flags
|= ZFS_IMPORT_ONLY
;
2295 if ((propval
= strchr(optarg
, '=')) != NULL
) {
2298 if (add_prop_list(optarg
, propval
,
2306 if (add_prop_list(zpool_prop_to_name(
2307 ZPOOL_PROP_ALTROOT
), optarg
, &props
, B_TRUE
))
2309 if (nvlist_lookup_string(props
,
2310 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE
),
2313 if (add_prop_list(zpool_prop_to_name(
2314 ZPOOL_PROP_CACHEFILE
), "none", &props
, B_TRUE
))
2319 txg
= strtoull(optarg
, &endptr
, 0);
2320 if (errno
!= 0 || *endptr
!= '\0') {
2321 (void) fprintf(stderr
,
2322 gettext("invalid txg value\n"));
2325 rewind_policy
= ZPOOL_DO_REWIND
| ZPOOL_EXTREME_REWIND
;
2328 flags
|= ZFS_IMPORT_VERBATIM
;
2331 xtreme_rewind
= B_TRUE
;
2333 case CHECKPOINT_OPT
:
2334 flags
|= ZFS_IMPORT_CHECKPOINT
;
2337 (void) fprintf(stderr
, gettext("missing argument for "
2338 "'%c' option\n"), optopt
);
2342 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
2351 if (cachefile
&& nsearch
!= 0) {
2352 (void) fprintf(stderr
, gettext("-c is incompatible with -d\n"));
2356 if ((dryrun
|| xtreme_rewind
) && !do_rewind
) {
2357 (void) fprintf(stderr
,
2358 gettext("-n or -X only meaningful with -F\n"));
2362 rewind_policy
= ZPOOL_TRY_REWIND
;
2364 rewind_policy
= ZPOOL_DO_REWIND
;
2366 rewind_policy
|= ZPOOL_EXTREME_REWIND
;
2368 /* In the future, we can capture further policy and include it here */
2369 if (nvlist_alloc(&policy
, NV_UNIQUE_NAME
, 0) != 0 ||
2370 nvlist_add_uint64(policy
, ZPOOL_LOAD_REQUEST_TXG
, txg
) != 0 ||
2371 nvlist_add_uint32(policy
, ZPOOL_LOAD_REWIND_POLICY
,
2372 rewind_policy
) != 0)
2375 if (searchdirs
== NULL
) {
2376 searchdirs
= safe_malloc(sizeof (char *));
2377 searchdirs
[0] = ZFS_DISK_ROOT
;
2381 /* check argument count */
2384 (void) fprintf(stderr
, gettext("too many arguments\n"));
2389 (void) fprintf(stderr
, gettext("too many arguments\n"));
2394 * Check for the SYS_CONFIG privilege. We do this explicitly
2395 * here because otherwise any attempt to discover pools will
2398 if (argc
== 0 && !priv_ineffect(PRIV_SYS_CONFIG
)) {
2399 (void) fprintf(stderr
, gettext("cannot "
2400 "discover pools: permission denied\n"));
2402 nvlist_free(policy
);
2408 * Depending on the arguments given, we do one of the following:
2410 * <none> Iterate through all pools and display information about
2413 * -a Iterate through all pools and try to import each one.
2415 * <id> Find the pool that corresponds to the given GUID/pool
2416 * name and import that one.
2418 * -D Above options applies only to destroyed pools.
2424 searchguid
= strtoull(argv
[0], &endptr
, 10);
2425 if (errno
!= 0 || *endptr
!= '\0') {
2426 searchname
= argv
[0];
2429 found_config
= NULL
;
2432 * User specified a name or guid. Ensure it's unique.
2434 idata
.unique
= B_TRUE
;
2438 idata
.path
= searchdirs
;
2439 idata
.paths
= nsearch
;
2440 idata
.poolname
= searchname
;
2441 idata
.guid
= searchguid
;
2442 idata
.cachefile
= cachefile
;
2443 idata
.policy
= policy
;
2445 pools
= zpool_search_import(g_zfs
, &idata
);
2447 if (pools
!= NULL
&& idata
.exists
&&
2448 (argc
== 1 || strcmp(argv
[0], argv
[1]) == 0)) {
2449 (void) fprintf(stderr
, gettext("cannot import '%s': "
2450 "a pool with that name already exists\n"),
2452 (void) fprintf(stderr
, gettext("use the form '%s "
2453 "<pool | id> <newpool>' to give it a new name\n"),
2456 } else if (pools
== NULL
&& idata
.exists
) {
2457 (void) fprintf(stderr
, gettext("cannot import '%s': "
2458 "a pool with that name is already created/imported,\n"),
2460 (void) fprintf(stderr
, gettext("and no additional pools "
2461 "with that name were found\n"));
2463 } else if (pools
== NULL
) {
2465 (void) fprintf(stderr
, gettext("cannot import '%s': "
2466 "no such pool available\n"), argv
[0]);
2473 nvlist_free(policy
);
2478 * At this point we have a list of import candidate configs. Even if
2479 * we were searching by pool name or guid, we still need to
2480 * post-process the list to deal with pool state and possible
2486 while ((elem
= nvlist_next_nvpair(pools
, elem
)) != NULL
) {
2488 verify(nvpair_value_nvlist(elem
, &config
) == 0);
2490 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_STATE
,
2492 if (!do_destroyed
&& pool_state
== POOL_STATE_DESTROYED
)
2494 if (do_destroyed
&& pool_state
!= POOL_STATE_DESTROYED
)
2497 verify(nvlist_add_nvlist(config
, ZPOOL_LOAD_POLICY
,
2504 (void) printf("\n");
2507 err
|= do_import(config
, NULL
, mntopts
,
2510 show_import(config
);
2512 } else if (searchname
!= NULL
) {
2516 * We are searching for a pool based on name.
2518 verify(nvlist_lookup_string(config
,
2519 ZPOOL_CONFIG_POOL_NAME
, &name
) == 0);
2521 if (strcmp(name
, searchname
) == 0) {
2522 if (found_config
!= NULL
) {
2523 (void) fprintf(stderr
, gettext(
2524 "cannot import '%s': more than "
2525 "one matching pool\n"), searchname
);
2526 (void) fprintf(stderr
, gettext(
2527 "import by numeric ID instead\n"));
2530 found_config
= config
;
2536 * Search for a pool by guid.
2538 verify(nvlist_lookup_uint64(config
,
2539 ZPOOL_CONFIG_POOL_GUID
, &guid
) == 0);
2541 if (guid
== searchguid
)
2542 found_config
= config
;
2547 * If we were searching for a specific pool, verify that we found a
2548 * pool, and then do the import.
2550 if (argc
!= 0 && err
== 0) {
2551 if (found_config
== NULL
) {
2552 (void) fprintf(stderr
, gettext("cannot import '%s': "
2553 "no such pool available\n"), argv
[0]);
2556 err
|= do_import(found_config
, argc
== 1 ? NULL
:
2557 argv
[1], mntopts
, props
, flags
);
2562 * If we were just looking for pools, report an error if none were
2565 if (argc
== 0 && first
)
2566 (void) fprintf(stderr
,
2567 gettext("no pools available to import\n"));
2572 nvlist_free(policy
);
2575 return (err
? 1 : 0);
2578 typedef struct iostat_cbdata
{
2579 boolean_t cb_verbose
;
2582 zpool_list_t
*cb_list
;
2586 print_iostat_separator(iostat_cbdata_t
*cb
)
2590 for (i
= 0; i
< cb
->cb_namewidth
; i
++)
2592 (void) printf(" ----- ----- ----- ----- ----- -----\n");
2596 print_iostat_header(iostat_cbdata_t
*cb
)
2598 (void) printf("%*s capacity operations bandwidth\n",
2599 cb
->cb_namewidth
, "");
2600 (void) printf("%-*s alloc free read write read write\n",
2601 cb
->cb_namewidth
, "pool");
2602 print_iostat_separator(cb
);
2606 * Display a single statistic.
2609 print_one_stat(uint64_t value
)
2613 zfs_nicenum(value
, buf
, sizeof (buf
));
2614 (void) printf(" %5s", buf
);
2618 * Print out all the statistics for the given vdev. This can either be the
2619 * toplevel configuration, or called recursively. If 'name' is NULL, then this
2620 * is a verbose output, and we don't want to display the toplevel pool stats.
2623 print_vdev_stats(zpool_handle_t
*zhp
, const char *name
, nvlist_t
*oldnv
,
2624 nvlist_t
*newnv
, iostat_cbdata_t
*cb
, int depth
)
2626 nvlist_t
**oldchild
, **newchild
;
2628 vdev_stat_t
*oldvs
, *newvs
;
2629 vdev_stat_t zerovs
= { 0 };
2634 if (strcmp(name
, VDEV_TYPE_INDIRECT
) == 0)
2637 if (oldnv
!= NULL
) {
2638 verify(nvlist_lookup_uint64_array(oldnv
,
2639 ZPOOL_CONFIG_VDEV_STATS
, (uint64_t **)&oldvs
, &c
) == 0);
2644 verify(nvlist_lookup_uint64_array(newnv
, ZPOOL_CONFIG_VDEV_STATS
,
2645 (uint64_t **)&newvs
, &c
) == 0);
2647 if (strlen(name
) + depth
> cb
->cb_namewidth
)
2648 (void) printf("%*s%s", depth
, "", name
);
2650 (void) printf("%*s%s%*s", depth
, "", name
,
2651 (int)(cb
->cb_namewidth
- strlen(name
) - depth
), "");
2653 tdelta
= newvs
->vs_timestamp
- oldvs
->vs_timestamp
;
2658 scale
= (double)NANOSEC
/ tdelta
;
2660 /* only toplevel vdevs have capacity stats */
2661 if (newvs
->vs_space
== 0) {
2662 (void) printf(" - -");
2664 print_one_stat(newvs
->vs_alloc
);
2665 print_one_stat(newvs
->vs_space
- newvs
->vs_alloc
);
2668 print_one_stat((uint64_t)(scale
* (newvs
->vs_ops
[ZIO_TYPE_READ
] -
2669 oldvs
->vs_ops
[ZIO_TYPE_READ
])));
2671 print_one_stat((uint64_t)(scale
* (newvs
->vs_ops
[ZIO_TYPE_WRITE
] -
2672 oldvs
->vs_ops
[ZIO_TYPE_WRITE
])));
2674 print_one_stat((uint64_t)(scale
* (newvs
->vs_bytes
[ZIO_TYPE_READ
] -
2675 oldvs
->vs_bytes
[ZIO_TYPE_READ
])));
2677 print_one_stat((uint64_t)(scale
* (newvs
->vs_bytes
[ZIO_TYPE_WRITE
] -
2678 oldvs
->vs_bytes
[ZIO_TYPE_WRITE
])));
2680 (void) printf("\n");
2682 if (!cb
->cb_verbose
)
2685 if (nvlist_lookup_nvlist_array(newnv
, ZPOOL_CONFIG_CHILDREN
,
2686 &newchild
, &children
) != 0)
2689 if (oldnv
&& nvlist_lookup_nvlist_array(oldnv
, ZPOOL_CONFIG_CHILDREN
,
2690 &oldchild
, &c
) != 0)
2693 for (c
= 0; c
< children
; c
++) {
2694 uint64_t ishole
= B_FALSE
, islog
= B_FALSE
;
2696 (void) nvlist_lookup_uint64(newchild
[c
], ZPOOL_CONFIG_IS_HOLE
,
2699 (void) nvlist_lookup_uint64(newchild
[c
], ZPOOL_CONFIG_IS_LOG
,
2702 if (ishole
|| islog
)
2705 vname
= zpool_vdev_name(g_zfs
, zhp
, newchild
[c
], B_FALSE
);
2706 print_vdev_stats(zhp
, vname
, oldnv
? oldchild
[c
] : NULL
,
2707 newchild
[c
], cb
, depth
+ 2);
2712 * Log device section
2715 if (num_logs(newnv
) > 0) {
2716 (void) printf("%-*s - - - - - "
2717 "-\n", cb
->cb_namewidth
, "logs");
2719 for (c
= 0; c
< children
; c
++) {
2720 uint64_t islog
= B_FALSE
;
2721 (void) nvlist_lookup_uint64(newchild
[c
],
2722 ZPOOL_CONFIG_IS_LOG
, &islog
);
2725 vname
= zpool_vdev_name(g_zfs
, zhp
, newchild
[c
],
2727 print_vdev_stats(zhp
, vname
, oldnv
?
2728 oldchild
[c
] : NULL
, newchild
[c
],
2737 * Include level 2 ARC devices in iostat output
2739 if (nvlist_lookup_nvlist_array(newnv
, ZPOOL_CONFIG_L2CACHE
,
2740 &newchild
, &children
) != 0)
2743 if (oldnv
&& nvlist_lookup_nvlist_array(oldnv
, ZPOOL_CONFIG_L2CACHE
,
2744 &oldchild
, &c
) != 0)
2748 (void) printf("%-*s - - - - - "
2749 "-\n", cb
->cb_namewidth
, "cache");
2750 for (c
= 0; c
< children
; c
++) {
2751 vname
= zpool_vdev_name(g_zfs
, zhp
, newchild
[c
],
2753 print_vdev_stats(zhp
, vname
, oldnv
? oldchild
[c
] : NULL
,
2754 newchild
[c
], cb
, depth
+ 2);
2761 refresh_iostat(zpool_handle_t
*zhp
, void *data
)
2763 iostat_cbdata_t
*cb
= data
;
2767 * If the pool has disappeared, remove it from the list and continue.
2769 if (zpool_refresh_stats(zhp
, &missing
) != 0)
2773 pool_list_remove(cb
->cb_list
, zhp
);
2779 * Callback to print out the iostats for the given pool.
2782 print_iostat(zpool_handle_t
*zhp
, void *data
)
2784 iostat_cbdata_t
*cb
= data
;
2785 nvlist_t
*oldconfig
, *newconfig
;
2786 nvlist_t
*oldnvroot
, *newnvroot
;
2788 newconfig
= zpool_get_config(zhp
, &oldconfig
);
2790 if (cb
->cb_iteration
== 1)
2793 verify(nvlist_lookup_nvlist(newconfig
, ZPOOL_CONFIG_VDEV_TREE
,
2796 if (oldconfig
== NULL
)
2799 verify(nvlist_lookup_nvlist(oldconfig
, ZPOOL_CONFIG_VDEV_TREE
,
2803 * Print out the statistics for the pool.
2805 print_vdev_stats(zhp
, zpool_get_name(zhp
), oldnvroot
, newnvroot
, cb
, 0);
2808 print_iostat_separator(cb
);
2814 get_namewidth(zpool_handle_t
*zhp
, void *data
)
2816 iostat_cbdata_t
*cb
= data
;
2817 nvlist_t
*config
, *nvroot
;
2819 if ((config
= zpool_get_config(zhp
, NULL
)) != NULL
) {
2820 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
2822 if (!cb
->cb_verbose
)
2823 cb
->cb_namewidth
= strlen(zpool_get_name(zhp
));
2825 cb
->cb_namewidth
= max_width(zhp
, nvroot
, 0,
2830 * The width must fall into the range [10,38]. The upper limit is the
2831 * maximum we can have and still fit in 80 columns.
2833 if (cb
->cb_namewidth
< 10)
2834 cb
->cb_namewidth
= 10;
2835 if (cb
->cb_namewidth
> 38)
2836 cb
->cb_namewidth
= 38;
2842 * Parse the input string, get the 'interval' and 'count' value if there is one.
2845 get_interval_count(int *argcp
, char **argv
, unsigned long *iv
,
2848 unsigned long interval
= 0, count
= 0;
2849 int argc
= *argcp
, errno
;
2852 * Determine if the last argument is an integer or a pool name
2854 if (argc
> 0 && isdigit(argv
[argc
- 1][0])) {
2858 interval
= strtoul(argv
[argc
- 1], &end
, 10);
2860 if (*end
== '\0' && errno
== 0) {
2861 if (interval
== 0) {
2862 (void) fprintf(stderr
, gettext("interval "
2863 "cannot be zero\n"));
2867 * Ignore the last parameter
2872 * If this is not a valid number, just plow on. The
2873 * user will get a more informative error message later
2881 * If the last argument is also an integer, then we have both a count
2884 if (argc
> 0 && isdigit(argv
[argc
- 1][0])) {
2889 interval
= strtoul(argv
[argc
- 1], &end
, 10);
2891 if (*end
== '\0' && errno
== 0) {
2892 if (interval
== 0) {
2893 (void) fprintf(stderr
, gettext("interval "
2894 "cannot be zero\n"));
2899 * Ignore the last parameter
2913 get_timestamp_arg(char c
)
2916 timestamp_fmt
= UDATE
;
2918 timestamp_fmt
= DDATE
;
2924 * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
2926 * -v Display statistics for individual vdevs
2927 * -T Display a timestamp in date(1) or Unix format
2929 * This command can be tricky because we want to be able to deal with pool
2930 * creation/destruction as well as vdev configuration changes. The bulk of this
2931 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
2932 * on pool_list_update() to detect the addition of new pools. Configuration
2933 * changes are all handled within libzfs.
2936 zpool_do_iostat(int argc
, char **argv
)
2941 unsigned long interval
= 0, count
= 0;
2943 boolean_t verbose
= B_FALSE
;
2947 while ((c
= getopt(argc
, argv
, "T:v")) != -1) {
2950 get_timestamp_arg(*optarg
);
2956 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
2965 get_interval_count(&argc
, argv
, &interval
, &count
);
2968 * Construct the list of all interesting pools.
2971 if ((list
= pool_list_get(argc
, argv
, NULL
, &ret
)) == NULL
)
2974 if (pool_list_count(list
) == 0 && argc
!= 0) {
2975 pool_list_free(list
);
2979 if (pool_list_count(list
) == 0 && interval
== 0) {
2980 pool_list_free(list
);
2981 (void) fprintf(stderr
, gettext("no pools available\n"));
2986 * Enter the main iostat loop.
2989 cb
.cb_verbose
= verbose
;
2990 cb
.cb_iteration
= 0;
2991 cb
.cb_namewidth
= 0;
2994 pool_list_update(list
);
2996 if ((npools
= pool_list_count(list
)) == 0)
3000 * Refresh all statistics. This is done as an explicit step
3001 * before calculating the maximum name width, so that any
3002 * configuration changes are properly accounted for.
3004 (void) pool_list_iter(list
, B_FALSE
, refresh_iostat
, &cb
);
3007 * Iterate over all pools to determine the maximum width
3008 * for the pool / device name column across all pools.
3010 cb
.cb_namewidth
= 0;
3011 (void) pool_list_iter(list
, B_FALSE
, get_namewidth
, &cb
);
3013 if (timestamp_fmt
!= NODATE
)
3014 print_timestamp(timestamp_fmt
);
3017 * If it's the first time, or verbose mode, print the header.
3019 if (++cb
.cb_iteration
== 1 || verbose
)
3020 print_iostat_header(&cb
);
3022 (void) pool_list_iter(list
, B_FALSE
, print_iostat
, &cb
);
3025 * If there's more than one pool, and we're not in verbose mode
3026 * (which prints a separator for us), then print a separator.
3028 if (npools
> 1 && !verbose
)
3029 print_iostat_separator(&cb
);
3032 (void) printf("\n");
3035 * Flush the output so that redirection to a file isn't buffered
3038 (void) fflush(stdout
);
3043 if (count
!= 0 && --count
== 0)
3046 (void) sleep(interval
);
3049 pool_list_free(list
);
3054 typedef struct list_cbdata
{
3055 boolean_t cb_verbose
;
3057 boolean_t cb_scripted
;
3058 zprop_list_t
*cb_proplist
;
3059 boolean_t cb_literal
;
3063 * Given a list of columns to display, output appropriate headers for each one.
3066 print_header(list_cbdata_t
*cb
)
3068 zprop_list_t
*pl
= cb
->cb_proplist
;
3069 char headerbuf
[ZPOOL_MAXPROPLEN
];
3071 boolean_t first
= B_TRUE
;
3072 boolean_t right_justify
;
3075 for (; pl
!= NULL
; pl
= pl
->pl_next
) {
3076 width
= pl
->pl_width
;
3077 if (first
&& cb
->cb_verbose
) {
3079 * Reset the width to accommodate the verbose listing
3082 width
= cb
->cb_namewidth
;
3090 right_justify
= B_FALSE
;
3091 if (pl
->pl_prop
!= ZPROP_INVAL
) {
3092 header
= zpool_prop_column_name(pl
->pl_prop
);
3093 right_justify
= zpool_prop_align_right(pl
->pl_prop
);
3097 for (i
= 0; pl
->pl_user_prop
[i
] != '\0'; i
++)
3098 headerbuf
[i
] = toupper(pl
->pl_user_prop
[i
]);
3099 headerbuf
[i
] = '\0';
3103 if (pl
->pl_next
== NULL
&& !right_justify
)
3104 (void) printf("%s", header
);
3105 else if (right_justify
)
3106 (void) printf("%*s", width
, header
);
3108 (void) printf("%-*s", width
, header
);
3112 (void) printf("\n");
3116 * Given a pool and a list of properties, print out all the properties according
3117 * to the described layout.
3120 print_pool(zpool_handle_t
*zhp
, list_cbdata_t
*cb
)
3122 zprop_list_t
*pl
= cb
->cb_proplist
;
3123 boolean_t first
= B_TRUE
;
3124 char property
[ZPOOL_MAXPROPLEN
];
3126 boolean_t right_justify
;
3129 for (; pl
!= NULL
; pl
= pl
->pl_next
) {
3131 width
= pl
->pl_width
;
3132 if (first
&& cb
->cb_verbose
) {
3134 * Reset the width to accommodate the verbose listing
3137 width
= cb
->cb_namewidth
;
3141 if (cb
->cb_scripted
)
3142 (void) printf("\t");
3149 right_justify
= B_FALSE
;
3150 if (pl
->pl_prop
!= ZPROP_INVAL
) {
3151 if (zpool_get_prop(zhp
, pl
->pl_prop
, property
,
3152 sizeof (property
), NULL
, cb
->cb_literal
) != 0)
3157 right_justify
= zpool_prop_align_right(pl
->pl_prop
);
3158 } else if ((zpool_prop_feature(pl
->pl_user_prop
) ||
3159 zpool_prop_unsupported(pl
->pl_user_prop
)) &&
3160 zpool_prop_get_feature(zhp
, pl
->pl_user_prop
, property
,
3161 sizeof (property
)) == 0) {
3169 * If this is being called in scripted mode, or if this is the
3170 * last column and it is left-justified, don't include a width
3173 if (cb
->cb_scripted
|| (pl
->pl_next
== NULL
&& !right_justify
))
3174 (void) printf("%s", propstr
);
3175 else if (right_justify
)
3176 (void) printf("%*s", width
, propstr
);
3178 (void) printf("%-*s", width
, propstr
);
3181 (void) printf("\n");
3185 print_one_column(zpool_prop_t prop
, uint64_t value
, boolean_t scripted
,
3190 size_t width
= zprop_width(prop
, &fixed
, ZFS_TYPE_POOL
);
3193 case ZPOOL_PROP_EXPANDSZ
:
3194 case ZPOOL_PROP_CHECKPOINT
:
3196 (void) strlcpy(propval
, "-", sizeof (propval
));
3198 zfs_nicenum(value
, propval
, sizeof (propval
));
3200 case ZPOOL_PROP_FRAGMENTATION
:
3201 if (value
== ZFS_FRAG_INVALID
) {
3202 (void) strlcpy(propval
, "-", sizeof (propval
));
3204 (void) snprintf(propval
, sizeof (propval
), "%llu%%",
3208 case ZPOOL_PROP_CAPACITY
:
3209 (void) snprintf(propval
, sizeof (propval
), "%llu%%", value
);
3212 zfs_nicenum(value
, propval
, sizeof (propval
));
3216 (void) strlcpy(propval
, "-", sizeof (propval
));
3219 (void) printf("\t%s", propval
);
3221 (void) printf(" %*s", width
, propval
);
3225 print_list_stats(zpool_handle_t
*zhp
, const char *name
, nvlist_t
*nv
,
3226 list_cbdata_t
*cb
, int depth
)
3232 boolean_t scripted
= cb
->cb_scripted
;
3233 uint64_t islog
= B_FALSE
;
3234 boolean_t haslog
= B_FALSE
;
3235 char *dashes
= "%-*s - - - - - -\n";
3237 verify(nvlist_lookup_uint64_array(nv
, ZPOOL_CONFIG_VDEV_STATS
,
3238 (uint64_t **)&vs
, &c
) == 0);
3241 boolean_t toplevel
= (vs
->vs_space
!= 0);
3244 if (strcmp(name
, VDEV_TYPE_INDIRECT
) == 0)
3248 (void) printf("\t%s", name
);
3249 else if (strlen(name
) + depth
> cb
->cb_namewidth
)
3250 (void) printf("%*s%s", depth
, "", name
);
3252 (void) printf("%*s%s%*s", depth
, "", name
,
3253 (int)(cb
->cb_namewidth
- strlen(name
) - depth
), "");
3256 * Print the properties for the individual vdevs. Some
3257 * properties are only applicable to toplevel vdevs. The
3258 * 'toplevel' boolean value is passed to the print_one_column()
3259 * to indicate that the value is valid.
3261 print_one_column(ZPOOL_PROP_SIZE
, vs
->vs_space
, scripted
,
3263 print_one_column(ZPOOL_PROP_ALLOCATED
, vs
->vs_alloc
, scripted
,
3265 print_one_column(ZPOOL_PROP_FREE
, vs
->vs_space
- vs
->vs_alloc
,
3266 scripted
, toplevel
);
3267 print_one_column(ZPOOL_PROP_CHECKPOINT
,
3268 vs
->vs_checkpoint_space
, scripted
, toplevel
);
3269 print_one_column(ZPOOL_PROP_EXPANDSZ
, vs
->vs_esize
, scripted
,
3271 print_one_column(ZPOOL_PROP_FRAGMENTATION
,
3272 vs
->vs_fragmentation
, scripted
,
3273 (vs
->vs_fragmentation
!= ZFS_FRAG_INVALID
&& toplevel
));
3274 cap
= (vs
->vs_space
== 0) ? 0 :
3275 (vs
->vs_alloc
* 100 / vs
->vs_space
);
3276 print_one_column(ZPOOL_PROP_CAPACITY
, cap
, scripted
, toplevel
);
3277 (void) printf("\n");
3280 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
3281 &child
, &children
) != 0)
3284 for (c
= 0; c
< children
; c
++) {
3285 uint64_t ishole
= B_FALSE
;
3287 if (nvlist_lookup_uint64(child
[c
],
3288 ZPOOL_CONFIG_IS_HOLE
, &ishole
) == 0 && ishole
)
3291 if (nvlist_lookup_uint64(child
[c
],
3292 ZPOOL_CONFIG_IS_LOG
, &islog
) == 0 && islog
) {
3297 vname
= zpool_vdev_name(g_zfs
, zhp
, child
[c
], B_FALSE
);
3298 print_list_stats(zhp
, vname
, child
[c
], cb
, depth
+ 2);
3302 if (haslog
== B_TRUE
) {
3303 /* LINTED E_SEC_PRINTF_VAR_FMT */
3304 (void) printf(dashes
, cb
->cb_namewidth
, "log");
3305 for (c
= 0; c
< children
; c
++) {
3306 if (nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_LOG
,
3307 &islog
) != 0 || !islog
)
3309 vname
= zpool_vdev_name(g_zfs
, zhp
, child
[c
], B_FALSE
);
3310 print_list_stats(zhp
, vname
, child
[c
], cb
, depth
+ 2);
3315 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_L2CACHE
,
3316 &child
, &children
) == 0 && children
> 0) {
3317 /* LINTED E_SEC_PRINTF_VAR_FMT */
3318 (void) printf(dashes
, cb
->cb_namewidth
, "cache");
3319 for (c
= 0; c
< children
; c
++) {
3320 vname
= zpool_vdev_name(g_zfs
, zhp
, child
[c
], B_FALSE
);
3321 print_list_stats(zhp
, vname
, child
[c
], cb
, depth
+ 2);
3326 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_SPARES
, &child
,
3327 &children
) == 0 && children
> 0) {
3328 /* LINTED E_SEC_PRINTF_VAR_FMT */
3329 (void) printf(dashes
, cb
->cb_namewidth
, "spare");
3330 for (c
= 0; c
< children
; c
++) {
3331 vname
= zpool_vdev_name(g_zfs
, zhp
, child
[c
], B_FALSE
);
3332 print_list_stats(zhp
, vname
, child
[c
], cb
, depth
+ 2);
3340 * Generic callback function to list a pool.
3343 list_callback(zpool_handle_t
*zhp
, void *data
)
3345 list_cbdata_t
*cbp
= data
;
3349 config
= zpool_get_config(zhp
, NULL
);
3351 print_pool(zhp
, cbp
);
3352 if (!cbp
->cb_verbose
)
3355 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
3357 print_list_stats(zhp
, NULL
, nvroot
, cbp
, 0);
3363 * zpool list [-Hp] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
3365 * -H Scripted mode. Don't display headers, and separate properties
3367 * -o List of properties to display. Defaults to
3368 * "name,size,allocated,free,expandsize,fragmentation,capacity,"
3369 * "dedupratio,health,altroot"
3370 * -p Diplay values in parsable (exact) format.
3371 * -T Display a timestamp in date(1) or Unix format
3373 * List all pools in the system, whether or not they're healthy. Output space
3374 * statistics for each one, as well as health status summary.
3377 zpool_do_list(int argc
, char **argv
)
3381 list_cbdata_t cb
= { 0 };
3382 static char default_props
[] =
3383 "name,size,allocated,free,checkpoint,expandsize,fragmentation,"
3384 "capacity,dedupratio,health,altroot";
3385 char *props
= default_props
;
3386 unsigned long interval
= 0, count
= 0;
3388 boolean_t first
= B_TRUE
;
3391 while ((c
= getopt(argc
, argv
, ":Ho:pT:v")) != -1) {
3394 cb
.cb_scripted
= B_TRUE
;
3400 cb
.cb_literal
= B_TRUE
;
3403 get_timestamp_arg(*optarg
);
3406 cb
.cb_verbose
= B_TRUE
;
3409 (void) fprintf(stderr
, gettext("missing argument for "
3410 "'%c' option\n"), optopt
);
3414 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
3423 get_interval_count(&argc
, argv
, &interval
, &count
);
3425 if (zprop_get_list(g_zfs
, props
, &cb
.cb_proplist
, ZFS_TYPE_POOL
) != 0)
3429 if ((list
= pool_list_get(argc
, argv
, &cb
.cb_proplist
,
3433 if (pool_list_count(list
) == 0)
3436 cb
.cb_namewidth
= 0;
3437 (void) pool_list_iter(list
, B_FALSE
, get_namewidth
, &cb
);
3439 if (timestamp_fmt
!= NODATE
)
3440 print_timestamp(timestamp_fmt
);
3442 if (!cb
.cb_scripted
&& (first
|| cb
.cb_verbose
)) {
3446 ret
= pool_list_iter(list
, B_TRUE
, list_callback
, &cb
);
3451 if (count
!= 0 && --count
== 0)
3454 pool_list_free(list
);
3455 (void) sleep(interval
);
3458 if (argc
== 0 && !cb
.cb_scripted
&& pool_list_count(list
) == 0) {
3459 (void) printf(gettext("no pools available\n"));
3463 pool_list_free(list
);
3464 zprop_free_list(cb
.cb_proplist
);
3469 zpool_do_attach_or_replace(int argc
, char **argv
, int replacing
)
3471 boolean_t force
= B_FALSE
;
3474 char *poolname
, *old_disk
, *new_disk
;
3475 zpool_handle_t
*zhp
;
3476 zpool_boot_label_t boot_type
;
3481 while ((c
= getopt(argc
, argv
, "f")) != -1) {
3487 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
3496 /* get pool name and check number of arguments */
3498 (void) fprintf(stderr
, gettext("missing pool name argument\n"));
3505 (void) fprintf(stderr
,
3506 gettext("missing <device> specification\n"));
3514 (void) fprintf(stderr
,
3515 gettext("missing <new_device> specification\n"));
3518 new_disk
= old_disk
;
3528 (void) fprintf(stderr
, gettext("too many arguments\n"));
3532 if ((zhp
= zpool_open(g_zfs
, poolname
)) == NULL
)
3535 if (zpool_get_config(zhp
, NULL
) == NULL
) {
3536 (void) fprintf(stderr
, gettext("pool '%s' is unavailable\n"),
3542 if (zpool_is_bootable(zhp
))
3543 boot_type
= ZPOOL_COPY_BOOT_LABEL
;
3545 boot_type
= ZPOOL_NO_BOOT_LABEL
;
3547 boot_size
= zpool_get_prop_int(zhp
, ZPOOL_PROP_BOOTSIZE
, NULL
);
3548 nvroot
= make_root_vdev(zhp
, force
, B_FALSE
, replacing
, B_FALSE
,
3549 boot_type
, boot_size
, argc
, argv
);
3550 if (nvroot
== NULL
) {
3555 ret
= zpool_vdev_attach(zhp
, old_disk
, new_disk
, nvroot
, replacing
);
3557 nvlist_free(nvroot
);
3564 * zpool replace [-f] <pool> <device> <new_device>
3566 * -f Force attach, even if <new_device> appears to be in use.
3568 * Replace <device> with <new_device>.
3572 zpool_do_replace(int argc
, char **argv
)
3574 return (zpool_do_attach_or_replace(argc
, argv
, B_TRUE
));
3578 * zpool attach [-f] <pool> <device> <new_device>
3580 * -f Force attach, even if <new_device> appears to be in use.
3582 * Attach <new_device> to the mirror containing <device>. If <device> is not
3583 * part of a mirror, then <device> will be transformed into a mirror of
3584 * <device> and <new_device>. In either case, <new_device> will begin life
3585 * with a DTL of [0, now], and will immediately begin to resilver itself.
3588 zpool_do_attach(int argc
, char **argv
)
3590 return (zpool_do_attach_or_replace(argc
, argv
, B_FALSE
));
3594 * zpool detach [-f] <pool> <device>
3596 * -f Force detach of <device>, even if DTLs argue against it
3597 * (not supported yet)
3599 * Detach a device from a mirror. The operation will be refused if <device>
3600 * is the last device in the mirror, or if the DTLs indicate that this device
3601 * has the only valid copy of some data.
3605 zpool_do_detach(int argc
, char **argv
)
3608 char *poolname
, *path
;
3609 zpool_handle_t
*zhp
;
3613 while ((c
= getopt(argc
, argv
, "f")) != -1) {
3617 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
3626 /* get pool name and check number of arguments */
3628 (void) fprintf(stderr
, gettext("missing pool name argument\n"));
3633 (void) fprintf(stderr
,
3634 gettext("missing <device> specification\n"));
3641 if ((zhp
= zpool_open(g_zfs
, poolname
)) == NULL
)
3644 ret
= zpool_vdev_detach(zhp
, path
);
3652 * zpool split [-n] [-o prop=val] ...
3654 * [-R altroot] <pool> <newpool> [<device> ...]
3656 * -n Do not split the pool, but display the resulting layout if
3657 * it were to be split.
3658 * -o Set property=value, or set mount options.
3659 * -R Mount the split-off pool under an alternate root.
3661 * Splits the named pool and gives it the new pool name. Devices to be split
3662 * off may be listed, provided that no more than one device is specified
3663 * per top-level vdev mirror. The newly split pool is left in an exported
3664 * state unless -R is specified.
3666 * Restrictions: the top-level of the pool pool must only be made up of
3667 * mirrors; all devices in the pool must be healthy; no device may be
3668 * undergoing a resilvering operation.
3671 zpool_do_split(int argc
, char **argv
)
3673 char *srcpool
, *newpool
, *propval
;
3674 char *mntopts
= NULL
;
3677 zpool_handle_t
*zhp
;
3678 nvlist_t
*config
, *props
= NULL
;
3680 flags
.dryrun
= B_FALSE
;
3681 flags
.import
= B_FALSE
;
3684 while ((c
= getopt(argc
, argv
, ":R:no:")) != -1) {
3687 flags
.import
= B_TRUE
;
3689 zpool_prop_to_name(ZPOOL_PROP_ALTROOT
), optarg
,
3690 &props
, B_TRUE
) != 0) {
3696 flags
.dryrun
= B_TRUE
;
3699 if ((propval
= strchr(optarg
, '=')) != NULL
) {
3702 if (add_prop_list(optarg
, propval
,
3703 &props
, B_TRUE
) != 0) {
3712 (void) fprintf(stderr
, gettext("missing argument for "
3713 "'%c' option\n"), optopt
);
3717 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
3724 if (!flags
.import
&& mntopts
!= NULL
) {
3725 (void) fprintf(stderr
, gettext("setting mntopts is only "
3726 "valid when importing the pool\n"));
3734 (void) fprintf(stderr
, gettext("Missing pool name\n"));
3738 (void) fprintf(stderr
, gettext("Missing new pool name\n"));
3748 if ((zhp
= zpool_open(g_zfs
, srcpool
)) == NULL
)
3751 config
= split_mirror_vdev(zhp
, newpool
, props
, flags
, argc
, argv
);
3752 if (config
== NULL
) {
3756 (void) printf(gettext("would create '%s' with the "
3757 "following layout:\n\n"), newpool
);
3758 print_vdev_tree(NULL
, newpool
, config
, 0, B_FALSE
);
3760 nvlist_free(config
);
3765 if (ret
!= 0 || flags
.dryrun
|| !flags
.import
)
3769 * The split was successful. Now we need to open the new
3770 * pool and import it.
3772 if ((zhp
= zpool_open_canfail(g_zfs
, newpool
)) == NULL
)
3774 if (zpool_get_state(zhp
) != POOL_STATE_UNAVAIL
&&
3775 zpool_enable_datasets(zhp
, mntopts
, 0) != 0) {
3777 (void) fprintf(stderr
, gettext("Split was successful, but "
3778 "the datasets could not all be mounted\n"));
3779 (void) fprintf(stderr
, gettext("Try doing '%s' with a "
3780 "different altroot\n"), "zpool import");
3790 * zpool online <pool> <device> ...
3793 zpool_do_online(int argc
, char **argv
)
3797 zpool_handle_t
*zhp
;
3799 vdev_state_t newstate
;
3803 while ((c
= getopt(argc
, argv
, "et")) != -1) {
3806 flags
|= ZFS_ONLINE_EXPAND
;
3810 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
3819 /* get pool name and check number of arguments */
3821 (void) fprintf(stderr
, gettext("missing pool name\n"));
3825 (void) fprintf(stderr
, gettext("missing device name\n"));
3831 if ((zhp
= zpool_open(g_zfs
, poolname
)) == NULL
)
3834 for (i
= 1; i
< argc
; i
++) {
3835 if (zpool_vdev_online(zhp
, argv
[i
], flags
, &newstate
) == 0) {
3836 if (newstate
!= VDEV_STATE_HEALTHY
) {
3837 (void) printf(gettext("warning: device '%s' "
3838 "onlined, but remains in faulted state\n"),
3840 if (newstate
== VDEV_STATE_FAULTED
)
3841 (void) printf(gettext("use 'zpool "
3842 "clear' to restore a faulted "
3845 (void) printf(gettext("use 'zpool "
3846 "replace' to replace devices "
3847 "that are no longer present\n"));
3860 * zpool offline [-ft] <pool> <device> ...
3862 * -f Force the device into the offline state, even if doing
3863 * so would appear to compromise pool availability.
3864 * (not supported yet)
3866 * -t Only take the device off-line temporarily. The offline
3867 * state will not be persistent across reboots.
3871 zpool_do_offline(int argc
, char **argv
)
3875 zpool_handle_t
*zhp
;
3877 boolean_t istmp
= B_FALSE
;
3880 while ((c
= getopt(argc
, argv
, "ft")) != -1) {
3887 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
3896 /* get pool name and check number of arguments */
3898 (void) fprintf(stderr
, gettext("missing pool name\n"));
3902 (void) fprintf(stderr
, gettext("missing device name\n"));
3908 if ((zhp
= zpool_open(g_zfs
, poolname
)) == NULL
)
3911 for (i
= 1; i
< argc
; i
++) {
3912 if (zpool_vdev_offline(zhp
, argv
[i
], istmp
) != 0)
3922 * zpool clear <pool> [device]
3924 * Clear all errors associated with a pool or a particular device.
3927 zpool_do_clear(int argc
, char **argv
)
3931 boolean_t dryrun
= B_FALSE
;
3932 boolean_t do_rewind
= B_FALSE
;
3933 boolean_t xtreme_rewind
= B_FALSE
;
3934 uint32_t rewind_policy
= ZPOOL_NO_REWIND
;
3935 nvlist_t
*policy
= NULL
;
3936 zpool_handle_t
*zhp
;
3937 char *pool
, *device
;
3940 while ((c
= getopt(argc
, argv
, "FnX")) != -1) {
3949 xtreme_rewind
= B_TRUE
;
3952 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
3962 (void) fprintf(stderr
, gettext("missing pool name\n"));
3967 (void) fprintf(stderr
, gettext("too many arguments\n"));
3971 if ((dryrun
|| xtreme_rewind
) && !do_rewind
) {
3972 (void) fprintf(stderr
,
3973 gettext("-n or -X only meaningful with -F\n"));
3977 rewind_policy
= ZPOOL_TRY_REWIND
;
3979 rewind_policy
= ZPOOL_DO_REWIND
;
3981 rewind_policy
|= ZPOOL_EXTREME_REWIND
;
3983 /* In future, further rewind policy choices can be passed along here */
3984 if (nvlist_alloc(&policy
, NV_UNIQUE_NAME
, 0) != 0 ||
3985 nvlist_add_uint32(policy
, ZPOOL_LOAD_REWIND_POLICY
,
3986 rewind_policy
) != 0) {
3991 device
= argc
== 2 ? argv
[1] : NULL
;
3993 if ((zhp
= zpool_open_canfail(g_zfs
, pool
)) == NULL
) {
3994 nvlist_free(policy
);
3998 if (zpool_clear(zhp
, device
, policy
) != 0)
4003 nvlist_free(policy
);
4009 * zpool reguid <pool>
4012 zpool_do_reguid(int argc
, char **argv
)
4016 zpool_handle_t
*zhp
;
4020 while ((c
= getopt(argc
, argv
, "")) != -1) {
4023 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
4032 /* get pool name and check number of arguments */
4034 (void) fprintf(stderr
, gettext("missing pool name\n"));
4039 (void) fprintf(stderr
, gettext("too many arguments\n"));
4044 if ((zhp
= zpool_open(g_zfs
, poolname
)) == NULL
)
4047 ret
= zpool_reguid(zhp
);
4055 * zpool reopen <pool>
4057 * Reopen the pool so that the kernel can update the sizes of all vdevs.
4060 zpool_do_reopen(int argc
, char **argv
)
4064 zpool_handle_t
*zhp
;
4068 while ((c
= getopt(argc
, argv
, "")) != -1) {
4071 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
4081 (void) fprintf(stderr
, gettext("missing pool name\n"));
4086 (void) fprintf(stderr
, gettext("too many arguments\n"));
4091 if ((zhp
= zpool_open_canfail(g_zfs
, pool
)) == NULL
)
4094 ret
= zpool_reopen(zhp
);
4099 typedef struct scrub_cbdata
{
4103 pool_scrub_cmd_t cb_scrub_cmd
;
4107 zpool_has_checkpoint(zpool_handle_t
*zhp
)
4109 nvlist_t
*config
, *nvroot
;
4111 config
= zpool_get_config(zhp
, NULL
);
4113 if (config
!= NULL
) {
4114 pool_checkpoint_stat_t
*pcs
= NULL
;
4117 nvroot
= fnvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
);
4118 (void) nvlist_lookup_uint64_array(nvroot
,
4119 ZPOOL_CONFIG_CHECKPOINT_STATS
, (uint64_t **)&pcs
, &c
);
4121 if (pcs
== NULL
|| pcs
->pcs_state
== CS_NONE
)
4124 assert(pcs
->pcs_state
== CS_CHECKPOINT_EXISTS
||
4125 pcs
->pcs_state
== CS_CHECKPOINT_DISCARDING
);
4133 scrub_callback(zpool_handle_t
*zhp
, void *data
)
4135 scrub_cbdata_t
*cb
= data
;
4139 * Ignore faulted pools.
4141 if (zpool_get_state(zhp
) == POOL_STATE_UNAVAIL
) {
4142 (void) fprintf(stderr
, gettext("cannot scrub '%s': pool is "
4143 "currently unavailable\n"), zpool_get_name(zhp
));
4147 err
= zpool_scan(zhp
, cb
->cb_type
, cb
->cb_scrub_cmd
);
4149 if (err
== 0 && zpool_has_checkpoint(zhp
) &&
4150 cb
->cb_type
== POOL_SCAN_SCRUB
) {
4151 (void) printf(gettext("warning: will not scrub state that "
4152 "belongs to the checkpoint of pool '%s'\n"),
4153 zpool_get_name(zhp
));
4160 * zpool scrub [-s | -p] <pool> ...
4162 * -s Stop. Stops any in-progress scrub.
4163 * -p Pause. Pause in-progress scrub.
4166 zpool_do_scrub(int argc
, char **argv
)
4171 cb
.cb_type
= POOL_SCAN_SCRUB
;
4172 cb
.cb_scrub_cmd
= POOL_SCRUB_NORMAL
;
4175 while ((c
= getopt(argc
, argv
, "sp")) != -1) {
4178 cb
.cb_type
= POOL_SCAN_NONE
;
4181 cb
.cb_scrub_cmd
= POOL_SCRUB_PAUSE
;
4184 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
4190 if (cb
.cb_type
== POOL_SCAN_NONE
&&
4191 cb
.cb_scrub_cmd
== POOL_SCRUB_PAUSE
) {
4192 (void) fprintf(stderr
, gettext("invalid option combination: "
4193 "-s and -p are mutually exclusive\n"));
4203 (void) fprintf(stderr
, gettext("missing pool name argument\n"));
4207 return (for_each_pool(argc
, argv
, B_TRUE
, NULL
, scrub_callback
, &cb
));
4211 zpool_collect_leaves(zpool_handle_t
*zhp
, nvlist_t
*nvroot
, nvlist_t
*res
)
4213 uint_t children
= 0;
4217 (void) nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_CHILDREN
,
4220 if (children
== 0) {
4221 char *path
= zpool_vdev_name(g_zfs
, zhp
, nvroot
, B_FALSE
);
4222 fnvlist_add_boolean(res
, path
);
4227 for (i
= 0; i
< children
; i
++) {
4228 zpool_collect_leaves(zhp
, child
[i
], res
);
4233 * zpool initialize [-cs] <pool> [<vdev> ...]
4234 * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
4235 * if none specified.
4237 * -c Cancel. Ends active initializing.
4238 * -s Suspend. Initializing can then be restarted with no flags.
4241 zpool_do_initialize(int argc
, char **argv
)
4245 zpool_handle_t
*zhp
;
4249 struct option long_options
[] = {
4250 {"cancel", no_argument
, NULL
, 'c'},
4251 {"suspend", no_argument
, NULL
, 's'},
4255 pool_initialize_func_t cmd_type
= POOL_INITIALIZE_DO
;
4256 while ((c
= getopt_long(argc
, argv
, "cs", long_options
, NULL
)) != -1) {
4259 if (cmd_type
!= POOL_INITIALIZE_DO
) {
4260 (void) fprintf(stderr
, gettext("-c cannot be "
4261 "combined with other options\n"));
4264 cmd_type
= POOL_INITIALIZE_CANCEL
;
4267 if (cmd_type
!= POOL_INITIALIZE_DO
) {
4268 (void) fprintf(stderr
, gettext("-s cannot be "
4269 "combined with other options\n"));
4272 cmd_type
= POOL_INITIALIZE_SUSPEND
;
4276 (void) fprintf(stderr
,
4277 gettext("invalid option '%c'\n"), optopt
);
4279 (void) fprintf(stderr
,
4280 gettext("invalid option '%s'\n"),
4291 (void) fprintf(stderr
, gettext("missing pool name argument\n"));
4297 zhp
= zpool_open(g_zfs
, poolname
);
4301 vdevs
= fnvlist_alloc();
4303 /* no individual leaf vdevs specified, so add them all */
4304 nvlist_t
*config
= zpool_get_config(zhp
, NULL
);
4305 nvlist_t
*nvroot
= fnvlist_lookup_nvlist(config
,
4306 ZPOOL_CONFIG_VDEV_TREE
);
4307 zpool_collect_leaves(zhp
, nvroot
, vdevs
);
4310 for (i
= 1; i
< argc
; i
++) {
4311 fnvlist_add_boolean(vdevs
, argv
[i
]);
4315 err
= zpool_initialize(zhp
, cmd_type
, vdevs
);
4317 fnvlist_free(vdevs
);
4323 typedef struct status_cbdata
{
4325 boolean_t cb_allpools
;
4326 boolean_t cb_verbose
;
4327 boolean_t cb_explain
;
4329 boolean_t cb_dedup_stats
;
4333 * Print out detailed scrub status.
4336 print_scan_status(pool_scan_stat_t
*ps
)
4338 time_t start
, end
, pause
;
4339 uint64_t elapsed
, mins_left
, hours_left
;
4340 uint64_t pass_exam
, examined
, total
;
4342 double fraction_done
;
4343 char processed_buf
[7], examined_buf
[7], total_buf
[7], rate_buf
[7];
4345 (void) printf(gettext(" scan: "));
4347 /* If there's never been a scan, there's not much to say. */
4348 if (ps
== NULL
|| ps
->pss_func
== POOL_SCAN_NONE
||
4349 ps
->pss_func
>= POOL_SCAN_FUNCS
) {
4350 (void) printf(gettext("none requested\n"));
4354 start
= ps
->pss_start_time
;
4355 end
= ps
->pss_end_time
;
4356 pause
= ps
->pss_pass_scrub_pause
;
4357 zfs_nicenum(ps
->pss_processed
, processed_buf
, sizeof (processed_buf
));
4359 assert(ps
->pss_func
== POOL_SCAN_SCRUB
||
4360 ps
->pss_func
== POOL_SCAN_RESILVER
);
4362 * Scan is finished or canceled.
4364 if (ps
->pss_state
== DSS_FINISHED
) {
4365 uint64_t minutes_taken
= (end
- start
) / 60;
4368 if (ps
->pss_func
== POOL_SCAN_SCRUB
) {
4369 fmt
= gettext("scrub repaired %s in %lluh%um with "
4370 "%llu errors on %s");
4371 } else if (ps
->pss_func
== POOL_SCAN_RESILVER
) {
4372 fmt
= gettext("resilvered %s in %lluh%um with "
4373 "%llu errors on %s");
4376 (void) printf(fmt
, processed_buf
,
4377 (u_longlong_t
)(minutes_taken
/ 60),
4378 (uint_t
)(minutes_taken
% 60),
4379 (u_longlong_t
)ps
->pss_errors
,
4380 ctime((time_t *)&end
));
4382 } else if (ps
->pss_state
== DSS_CANCELED
) {
4383 if (ps
->pss_func
== POOL_SCAN_SCRUB
) {
4384 (void) printf(gettext("scrub canceled on %s"),
4386 } else if (ps
->pss_func
== POOL_SCAN_RESILVER
) {
4387 (void) printf(gettext("resilver canceled on %s"),
4393 assert(ps
->pss_state
== DSS_SCANNING
);
4396 * Scan is in progress.
4398 if (ps
->pss_func
== POOL_SCAN_SCRUB
) {
4400 (void) printf(gettext("scrub in progress since %s"),
4404 struct tm
*p
= localtime(&pause
);
4405 (void) strftime(buf
, sizeof (buf
), "%a %b %e %T %Y", p
);
4406 (void) printf(gettext("scrub paused since %s\n"), buf
);
4407 (void) printf(gettext("\tscrub started on %s"),
4410 } else if (ps
->pss_func
== POOL_SCAN_RESILVER
) {
4411 (void) printf(gettext("resilver in progress since %s"),
4415 examined
= ps
->pss_examined
? ps
->pss_examined
: 1;
4416 total
= ps
->pss_to_examine
;
4417 fraction_done
= (double)examined
/ total
;
4419 /* elapsed time for this pass */
4420 elapsed
= time(NULL
) - ps
->pss_pass_start
;
4421 elapsed
-= ps
->pss_pass_scrub_spent_paused
;
4422 elapsed
= elapsed
? elapsed
: 1;
4423 pass_exam
= ps
->pss_pass_exam
? ps
->pss_pass_exam
: 1;
4424 rate
= pass_exam
/ elapsed
;
4425 rate
= rate
? rate
: 1;
4426 mins_left
= ((total
- examined
) / rate
) / 60;
4427 hours_left
= mins_left
/ 60;
4429 zfs_nicenum(examined
, examined_buf
, sizeof (examined_buf
));
4430 zfs_nicenum(total
, total_buf
, sizeof (total_buf
));
4433 * do not print estimated time if hours_left is more than 30 days
4434 * or we have a paused scrub
4437 zfs_nicenum(rate
, rate_buf
, sizeof (rate_buf
));
4438 (void) printf(gettext("\t%s scanned out of %s at %s/s"),
4439 examined_buf
, total_buf
, rate_buf
);
4440 if (hours_left
< (30 * 24)) {
4441 (void) printf(gettext(", %lluh%um to go\n"),
4442 (u_longlong_t
)hours_left
, (uint_t
)(mins_left
% 60));
4444 (void) printf(gettext(
4445 ", (scan is slow, no estimated time)\n"));
4448 (void) printf(gettext("\t%s scanned out of %s\n"),
4449 examined_buf
, total_buf
);
4452 if (ps
->pss_func
== POOL_SCAN_RESILVER
) {
4453 (void) printf(gettext(" %s resilvered, %.2f%% done\n"),
4454 processed_buf
, 100 * fraction_done
);
4455 } else if (ps
->pss_func
== POOL_SCAN_SCRUB
) {
4456 (void) printf(gettext(" %s repaired, %.2f%% done\n"),
4457 processed_buf
, 100 * fraction_done
);
4462 * As we don't scrub checkpointed blocks, we want to warn the
4463 * user that we skipped scanning some blocks if a checkpoint exists
4464 * or existed at any time during the scan.
4467 print_checkpoint_scan_warning(pool_scan_stat_t
*ps
, pool_checkpoint_stat_t
*pcs
)
4469 if (ps
== NULL
|| pcs
== NULL
)
4472 if (pcs
->pcs_state
== CS_NONE
||
4473 pcs
->pcs_state
== CS_CHECKPOINT_DISCARDING
)
4476 assert(pcs
->pcs_state
== CS_CHECKPOINT_EXISTS
);
4478 if (ps
->pss_state
== DSS_NONE
)
4481 if ((ps
->pss_state
== DSS_FINISHED
|| ps
->pss_state
== DSS_CANCELED
) &&
4482 ps
->pss_end_time
< pcs
->pcs_start_time
)
4485 if (ps
->pss_state
== DSS_FINISHED
|| ps
->pss_state
== DSS_CANCELED
) {
4486 (void) printf(gettext(" scan warning: skipped blocks "
4487 "that are only referenced by the checkpoint.\n"));
4489 assert(ps
->pss_state
== DSS_SCANNING
);
4490 (void) printf(gettext(" scan warning: skipping blocks "
4491 "that are only referenced by the checkpoint.\n"));
4496 * Print out detailed removal status.
4499 print_removal_status(zpool_handle_t
*zhp
, pool_removal_stat_t
*prs
)
4501 char copied_buf
[7], examined_buf
[7], total_buf
[7], rate_buf
[7];
4503 nvlist_t
*config
, *nvroot
;
4508 if (prs
== NULL
|| prs
->prs_state
== DSS_NONE
)
4512 * Determine name of vdev.
4514 config
= zpool_get_config(zhp
, NULL
);
4515 nvroot
= fnvlist_lookup_nvlist(config
,
4516 ZPOOL_CONFIG_VDEV_TREE
);
4517 verify(nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_CHILDREN
,
4518 &child
, &children
) == 0);
4519 assert(prs
->prs_removing_vdev
< children
);
4520 vdev_name
= zpool_vdev_name(g_zfs
, zhp
,
4521 child
[prs
->prs_removing_vdev
], B_TRUE
);
4523 (void) printf(gettext("remove: "));
4525 start
= prs
->prs_start_time
;
4526 end
= prs
->prs_end_time
;
4527 zfs_nicenum(prs
->prs_copied
, copied_buf
, sizeof (copied_buf
));
4530 * Removal is finished or canceled.
4532 if (prs
->prs_state
== DSS_FINISHED
) {
4533 uint64_t minutes_taken
= (end
- start
) / 60;
4535 (void) printf(gettext("Removal of vdev %llu copied %s "
4536 "in %lluh%um, completed on %s"),
4537 (longlong_t
)prs
->prs_removing_vdev
,
4539 (u_longlong_t
)(minutes_taken
/ 60),
4540 (uint_t
)(minutes_taken
% 60),
4541 ctime((time_t *)&end
));
4542 } else if (prs
->prs_state
== DSS_CANCELED
) {
4543 (void) printf(gettext("Removal of %s canceled on %s"),
4544 vdev_name
, ctime(&end
));
4546 uint64_t copied
, total
, elapsed
, mins_left
, hours_left
;
4547 double fraction_done
;
4550 assert(prs
->prs_state
== DSS_SCANNING
);
4553 * Removal is in progress.
4555 (void) printf(gettext(
4556 "Evacuation of %s in progress since %s"),
4557 vdev_name
, ctime(&start
));
4559 copied
= prs
->prs_copied
> 0 ? prs
->prs_copied
: 1;
4560 total
= prs
->prs_to_copy
;
4561 fraction_done
= (double)copied
/ total
;
4563 /* elapsed time for this pass */
4564 elapsed
= time(NULL
) - prs
->prs_start_time
;
4565 elapsed
= elapsed
> 0 ? elapsed
: 1;
4566 rate
= copied
/ elapsed
;
4567 rate
= rate
> 0 ? rate
: 1;
4568 mins_left
= ((total
- copied
) / rate
) / 60;
4569 hours_left
= mins_left
/ 60;
4571 zfs_nicenum(copied
, examined_buf
, sizeof (examined_buf
));
4572 zfs_nicenum(total
, total_buf
, sizeof (total_buf
));
4573 zfs_nicenum(rate
, rate_buf
, sizeof (rate_buf
));
4576 * do not print estimated time if hours_left is more than
4579 (void) printf(gettext(" %s copied out of %s at %s/s, "
4581 examined_buf
, total_buf
, rate_buf
, 100 * fraction_done
);
4582 if (hours_left
< (30 * 24)) {
4583 (void) printf(gettext(", %lluh%um to go\n"),
4584 (u_longlong_t
)hours_left
, (uint_t
)(mins_left
% 60));
4586 (void) printf(gettext(
4587 ", (copy is slow, no estimated time)\n"));
4591 if (prs
->prs_mapping_memory
> 0) {
4593 zfs_nicenum(prs
->prs_mapping_memory
, mem_buf
, sizeof (mem_buf
));
4594 (void) printf(gettext(" %s memory used for "
4595 "removed device mappings\n"),
4601 print_checkpoint_status(pool_checkpoint_stat_t
*pcs
)
4606 if (pcs
== NULL
|| pcs
->pcs_state
== CS_NONE
)
4609 (void) printf(gettext("checkpoint: "));
4611 start
= pcs
->pcs_start_time
;
4612 zfs_nicenum(pcs
->pcs_space
, space_buf
, sizeof (space_buf
));
4614 if (pcs
->pcs_state
== CS_CHECKPOINT_EXISTS
) {
4615 char *date
= ctime(&start
);
4618 * ctime() adds a newline at the end of the generated
4619 * string, thus the weird format specifier and the
4620 * strlen() call used to chop it off from the output.
4622 (void) printf(gettext("created %.*s, consumes %s\n"),
4623 strlen(date
) - 1, date
, space_buf
);
4627 assert(pcs
->pcs_state
== CS_CHECKPOINT_DISCARDING
);
4629 (void) printf(gettext("discarding, %s remaining.\n"),
4634 print_error_log(zpool_handle_t
*zhp
)
4636 nvlist_t
*nverrlist
= NULL
;
4639 size_t len
= MAXPATHLEN
* 2;
4641 if (zpool_get_errlog(zhp
, &nverrlist
) != 0) {
4642 (void) printf("errors: List of errors unavailable "
4643 "(insufficient privileges)\n");
4647 (void) printf("errors: Permanent errors have been "
4648 "detected in the following files:\n\n");
4650 pathname
= safe_malloc(len
);
4652 while ((elem
= nvlist_next_nvpair(nverrlist
, elem
)) != NULL
) {
4654 uint64_t dsobj
, obj
;
4656 verify(nvpair_value_nvlist(elem
, &nv
) == 0);
4657 verify(nvlist_lookup_uint64(nv
, ZPOOL_ERR_DATASET
,
4659 verify(nvlist_lookup_uint64(nv
, ZPOOL_ERR_OBJECT
,
4661 zpool_obj_to_path(zhp
, dsobj
, obj
, pathname
, len
);
4662 (void) printf("%7s %s\n", "", pathname
);
4665 nvlist_free(nverrlist
);
4669 print_spares(zpool_handle_t
*zhp
, nvlist_t
**spares
, uint_t nspares
,
4678 (void) printf(gettext("\tspares\n"));
4680 for (i
= 0; i
< nspares
; i
++) {
4681 name
= zpool_vdev_name(g_zfs
, zhp
, spares
[i
], B_FALSE
);
4682 print_status_config(zhp
, name
, spares
[i
],
4683 namewidth
, 2, B_TRUE
);
4689 print_l2cache(zpool_handle_t
*zhp
, nvlist_t
**l2cache
, uint_t nl2cache
,
4698 (void) printf(gettext("\tcache\n"));
4700 for (i
= 0; i
< nl2cache
; i
++) {
4701 name
= zpool_vdev_name(g_zfs
, zhp
, l2cache
[i
], B_FALSE
);
4702 print_status_config(zhp
, name
, l2cache
[i
],
4703 namewidth
, 2, B_FALSE
);
4709 print_dedup_stats(nvlist_t
*config
)
4711 ddt_histogram_t
*ddh
;
4717 * If the pool was faulted then we may not have been able to
4718 * obtain the config. Otherwise, if we have anything in the dedup
4719 * table continue processing the stats.
4721 if (nvlist_lookup_uint64_array(config
, ZPOOL_CONFIG_DDT_OBJ_STATS
,
4722 (uint64_t **)&ddo
, &c
) != 0)
4725 (void) printf("\n");
4726 (void) printf(gettext(" dedup: "));
4727 if (ddo
->ddo_count
== 0) {
4728 (void) printf(gettext("no DDT entries\n"));
4732 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
4733 (u_longlong_t
)ddo
->ddo_count
,
4734 (u_longlong_t
)ddo
->ddo_dspace
,
4735 (u_longlong_t
)ddo
->ddo_mspace
);
4737 verify(nvlist_lookup_uint64_array(config
, ZPOOL_CONFIG_DDT_STATS
,
4738 (uint64_t **)&dds
, &c
) == 0);
4739 verify(nvlist_lookup_uint64_array(config
, ZPOOL_CONFIG_DDT_HISTOGRAM
,
4740 (uint64_t **)&ddh
, &c
) == 0);
4741 zpool_dump_ddt(dds
, ddh
);
4745 * Display a summary of pool status. Displays a summary such as:
4749 * reason: One or more devices ...
4750 * see: http://illumos.org/msg/ZFS-xxxx-01
4756 * When given the '-v' option, we print out the complete config. If the '-e'
4757 * option is specified, then we print out error rate information as well.
4760 status_callback(zpool_handle_t
*zhp
, void *data
)
4762 status_cbdata_t
*cbp
= data
;
4763 nvlist_t
*config
, *nvroot
;
4770 config
= zpool_get_config(zhp
, NULL
);
4771 reason
= zpool_get_status(zhp
, &msgid
);
4776 * If we were given 'zpool status -x', only report those pools with
4779 if (cbp
->cb_explain
&&
4780 (reason
== ZPOOL_STATUS_OK
||
4781 reason
== ZPOOL_STATUS_VERSION_OLDER
||
4782 reason
== ZPOOL_STATUS_FEAT_DISABLED
)) {
4783 if (!cbp
->cb_allpools
) {
4784 (void) printf(gettext("pool '%s' is healthy\n"),
4785 zpool_get_name(zhp
));
4787 cbp
->cb_first
= B_FALSE
;
4793 cbp
->cb_first
= B_FALSE
;
4795 (void) printf("\n");
4797 nvroot
= fnvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
);
4798 verify(nvlist_lookup_uint64_array(nvroot
, ZPOOL_CONFIG_VDEV_STATS
,
4799 (uint64_t **)&vs
, &c
) == 0);
4800 health
= zpool_state_to_name(vs
->vs_state
, vs
->vs_aux
);
4802 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp
));
4803 (void) printf(gettext(" state: %s\n"), health
);
4806 case ZPOOL_STATUS_MISSING_DEV_R
:
4807 (void) printf(gettext("status: One or more devices could not "
4808 "be opened. Sufficient replicas exist for\n\tthe pool to "
4809 "continue functioning in a degraded state.\n"));
4810 (void) printf(gettext("action: Attach the missing device and "
4811 "online it using 'zpool online'.\n"));
4814 case ZPOOL_STATUS_MISSING_DEV_NR
:
4815 (void) printf(gettext("status: One or more devices could not "
4816 "be opened. There are insufficient\n\treplicas for the "
4817 "pool to continue functioning.\n"));
4818 (void) printf(gettext("action: Attach the missing device and "
4819 "online it using 'zpool online'.\n"));
4822 case ZPOOL_STATUS_CORRUPT_LABEL_R
:
4823 (void) printf(gettext("status: One or more devices could not "
4824 "be used because the label is missing or\n\tinvalid. "
4825 "Sufficient replicas exist for the pool to continue\n\t"
4826 "functioning in a degraded state.\n"));
4827 (void) printf(gettext("action: Replace the device using "
4828 "'zpool replace'.\n"));
4831 case ZPOOL_STATUS_CORRUPT_LABEL_NR
:
4832 (void) printf(gettext("status: One or more devices could not "
4833 "be used because the label is missing \n\tor invalid. "
4834 "There are insufficient replicas for the pool to "
4835 "continue\n\tfunctioning.\n"));
4836 zpool_explain_recover(zpool_get_handle(zhp
),
4837 zpool_get_name(zhp
), reason
, config
);
4840 case ZPOOL_STATUS_FAILING_DEV
:
4841 (void) printf(gettext("status: One or more devices has "
4842 "experienced an unrecoverable error. An\n\tattempt was "
4843 "made to correct the error. Applications are "
4845 (void) printf(gettext("action: Determine if the device needs "
4846 "to be replaced, and clear the errors\n\tusing "
4847 "'zpool clear' or replace the device with 'zpool "
4851 case ZPOOL_STATUS_OFFLINE_DEV
:
4852 (void) printf(gettext("status: One or more devices has "
4853 "been taken offline by the administrator.\n\tSufficient "
4854 "replicas exist for the pool to continue functioning in "
4855 "a\n\tdegraded state.\n"));
4856 (void) printf(gettext("action: Online the device using "
4857 "'zpool online' or replace the device with\n\t'zpool "
4861 case ZPOOL_STATUS_REMOVED_DEV
:
4862 (void) printf(gettext("status: One or more devices has "
4863 "been removed by the administrator.\n\tSufficient "
4864 "replicas exist for the pool to continue functioning in "
4865 "a\n\tdegraded state.\n"));
4866 (void) printf(gettext("action: Online the device using "
4867 "'zpool online' or replace the device with\n\t'zpool "
4871 case ZPOOL_STATUS_RESILVERING
:
4872 (void) printf(gettext("status: One or more devices is "
4873 "currently being resilvered. The pool will\n\tcontinue "
4874 "to function, possibly in a degraded state.\n"));
4875 (void) printf(gettext("action: Wait for the resilver to "
4879 case ZPOOL_STATUS_CORRUPT_DATA
:
4880 (void) printf(gettext("status: One or more devices has "
4881 "experienced an error resulting in data\n\tcorruption. "
4882 "Applications may be affected.\n"));
4883 (void) printf(gettext("action: Restore the file in question "
4884 "if possible. Otherwise restore the\n\tentire pool from "
4888 case ZPOOL_STATUS_CORRUPT_POOL
:
4889 (void) printf(gettext("status: The pool metadata is corrupted "
4890 "and the pool cannot be opened.\n"));
4891 zpool_explain_recover(zpool_get_handle(zhp
),
4892 zpool_get_name(zhp
), reason
, config
);
4895 case ZPOOL_STATUS_VERSION_OLDER
:
4896 (void) printf(gettext("status: The pool is formatted using a "
4897 "legacy on-disk format. The pool can\n\tstill be used, "
4898 "but some features are unavailable.\n"));
4899 (void) printf(gettext("action: Upgrade the pool using 'zpool "
4900 "upgrade'. Once this is done, the\n\tpool will no longer "
4901 "be accessible on software that does not support feature\n"
4905 case ZPOOL_STATUS_VERSION_NEWER
:
4906 (void) printf(gettext("status: The pool has been upgraded to a "
4907 "newer, incompatible on-disk version.\n\tThe pool cannot "
4908 "be accessed on this system.\n"));
4909 (void) printf(gettext("action: Access the pool from a system "
4910 "running more recent software, or\n\trestore the pool from "
4914 case ZPOOL_STATUS_FEAT_DISABLED
:
4915 (void) printf(gettext("status: Some supported features are not "
4916 "enabled on the pool. The pool can\n\tstill be used, but "
4917 "some features are unavailable.\n"));
4918 (void) printf(gettext("action: Enable all features using "
4919 "'zpool upgrade'. Once this is done,\n\tthe pool may no "
4920 "longer be accessible by software that does not support\n\t"
4921 "the features. See zpool-features(5) for details.\n"));
4924 case ZPOOL_STATUS_UNSUP_FEAT_READ
:
4925 (void) printf(gettext("status: The pool cannot be accessed on "
4926 "this system because it uses the\n\tfollowing feature(s) "
4927 "not supported on this system:\n"));
4928 zpool_print_unsup_feat(config
);
4929 (void) printf("\n");
4930 (void) printf(gettext("action: Access the pool from a system "
4931 "that supports the required feature(s),\n\tor restore the "
4932 "pool from backup.\n"));
4935 case ZPOOL_STATUS_UNSUP_FEAT_WRITE
:
4936 (void) printf(gettext("status: The pool can only be accessed "
4937 "in read-only mode on this system. It\n\tcannot be "
4938 "accessed in read-write mode because it uses the "
4939 "following\n\tfeature(s) not supported on this system:\n"));
4940 zpool_print_unsup_feat(config
);
4941 (void) printf("\n");
4942 (void) printf(gettext("action: The pool cannot be accessed in "
4943 "read-write mode. Import the pool with\n"
4944 "\t\"-o readonly=on\", access the pool from a system that "
4945 "supports the\n\trequired feature(s), or restore the "
4946 "pool from backup.\n"));
4949 case ZPOOL_STATUS_FAULTED_DEV_R
:
4950 (void) printf(gettext("status: One or more devices are "
4951 "faulted in response to persistent errors.\n\tSufficient "
4952 "replicas exist for the pool to continue functioning "
4953 "in a\n\tdegraded state.\n"));
4954 (void) printf(gettext("action: Replace the faulted device, "
4955 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
4958 case ZPOOL_STATUS_FAULTED_DEV_NR
:
4959 (void) printf(gettext("status: One or more devices are "
4960 "faulted in response to persistent errors. There are "
4961 "insufficient replicas for the pool to\n\tcontinue "
4963 (void) printf(gettext("action: Destroy and re-create the pool "
4964 "from a backup source. Manually marking the device\n"
4965 "\trepaired using 'zpool clear' may allow some data "
4966 "to be recovered.\n"));
4969 case ZPOOL_STATUS_IO_FAILURE_WAIT
:
4970 case ZPOOL_STATUS_IO_FAILURE_CONTINUE
:
4971 (void) printf(gettext("status: One or more devices are "
4972 "faulted in response to IO failures.\n"));
4973 (void) printf(gettext("action: Make sure the affected devices "
4974 "are connected, then run 'zpool clear'.\n"));
4977 case ZPOOL_STATUS_BAD_LOG
:
4978 (void) printf(gettext("status: An intent log record "
4979 "could not be read.\n"
4980 "\tWaiting for adminstrator intervention to fix the "
4981 "faulted pool.\n"));
4982 (void) printf(gettext("action: Either restore the affected "
4983 "device(s) and run 'zpool online',\n"
4984 "\tor ignore the intent log records by running "
4985 "'zpool clear'.\n"));
4990 * The remaining errors can't actually be generated, yet.
4992 assert(reason
== ZPOOL_STATUS_OK
);
4996 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"),
4999 if (config
!= NULL
) {
5002 nvlist_t
**spares
, **l2cache
;
5003 uint_t nspares
, nl2cache
;
5004 pool_checkpoint_stat_t
*pcs
= NULL
;
5005 pool_scan_stat_t
*ps
= NULL
;
5006 pool_removal_stat_t
*prs
= NULL
;
5008 (void) nvlist_lookup_uint64_array(nvroot
,
5009 ZPOOL_CONFIG_CHECKPOINT_STATS
, (uint64_t **)&pcs
, &c
);
5010 (void) nvlist_lookup_uint64_array(nvroot
,
5011 ZPOOL_CONFIG_SCAN_STATS
, (uint64_t **)&ps
, &c
);
5012 (void) nvlist_lookup_uint64_array(nvroot
,
5013 ZPOOL_CONFIG_REMOVAL_STATS
, (uint64_t **)&prs
, &c
);
5015 print_scan_status(ps
);
5016 print_checkpoint_scan_warning(ps
, pcs
);
5017 print_removal_status(zhp
, prs
);
5018 print_checkpoint_status(pcs
);
5020 namewidth
= max_width(zhp
, nvroot
, 0, 0);
5024 (void) printf(gettext("config:\n\n"));
5025 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth
,
5026 "NAME", "STATE", "READ", "WRITE", "CKSUM");
5027 print_status_config(zhp
, zpool_get_name(zhp
), nvroot
,
5028 namewidth
, 0, B_FALSE
);
5030 if (num_logs(nvroot
) > 0)
5031 print_logs(zhp
, nvroot
, namewidth
, B_TRUE
);
5032 if (nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_L2CACHE
,
5033 &l2cache
, &nl2cache
) == 0)
5034 print_l2cache(zhp
, l2cache
, nl2cache
, namewidth
);
5036 if (nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_SPARES
,
5037 &spares
, &nspares
) == 0)
5038 print_spares(zhp
, spares
, nspares
, namewidth
);
5040 if (nvlist_lookup_uint64(config
, ZPOOL_CONFIG_ERRCOUNT
,
5042 nvlist_t
*nverrlist
= NULL
;
5045 * If the approximate error count is small, get a
5046 * precise count by fetching the entire log and
5047 * uniquifying the results.
5049 if (nerr
> 0 && nerr
< 100 && !cbp
->cb_verbose
&&
5050 zpool_get_errlog(zhp
, &nverrlist
) == 0) {
5055 while ((elem
= nvlist_next_nvpair(nverrlist
,
5060 nvlist_free(nverrlist
);
5062 (void) printf("\n");
5065 (void) printf(gettext("errors: No known data "
5067 else if (!cbp
->cb_verbose
)
5068 (void) printf(gettext("errors: %llu data "
5069 "errors, use '-v' for a list\n"),
5070 (u_longlong_t
)nerr
);
5072 print_error_log(zhp
);
5075 if (cbp
->cb_dedup_stats
)
5076 print_dedup_stats(config
);
5078 (void) printf(gettext("config: The configuration cannot be "
5086 * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
5088 * -v Display complete error logs
5089 * -x Display only pools with potential problems
5090 * -D Display dedup status (undocumented)
5091 * -T Display a timestamp in date(1) or Unix format
5093 * Describes the health status of all pools or some subset.
5096 zpool_do_status(int argc
, char **argv
)
5100 unsigned long interval
= 0, count
= 0;
5101 status_cbdata_t cb
= { 0 };
5104 while ((c
= getopt(argc
, argv
, "vxDT:")) != -1) {
5107 cb
.cb_verbose
= B_TRUE
;
5110 cb
.cb_explain
= B_TRUE
;
5113 cb
.cb_dedup_stats
= B_TRUE
;
5116 get_timestamp_arg(*optarg
);
5119 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
5128 get_interval_count(&argc
, argv
, &interval
, &count
);
5131 cb
.cb_allpools
= B_TRUE
;
5133 cb
.cb_first
= B_TRUE
;
5136 if (timestamp_fmt
!= NODATE
)
5137 print_timestamp(timestamp_fmt
);
5139 ret
= for_each_pool(argc
, argv
, B_TRUE
, NULL
,
5140 status_callback
, &cb
);
5142 if (argc
== 0 && cb
.cb_count
== 0)
5143 (void) printf(gettext("no pools available\n"));
5144 else if (cb
.cb_explain
&& cb
.cb_first
&& cb
.cb_allpools
)
5145 (void) printf(gettext("all pools are healthy\n"));
5153 if (count
!= 0 && --count
== 0)
5156 (void) sleep(interval
);
5162 typedef struct upgrade_cbdata
{
5165 uint64_t cb_version
;
5170 upgrade_version(zpool_handle_t
*zhp
, uint64_t version
)
5174 uint64_t oldversion
;
5176 config
= zpool_get_config(zhp
, NULL
);
5177 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_VERSION
,
5180 assert(SPA_VERSION_IS_SUPPORTED(oldversion
));
5181 assert(oldversion
< version
);
5183 ret
= zpool_upgrade(zhp
, version
);
5187 if (version
>= SPA_VERSION_FEATURES
) {
5188 (void) printf(gettext("Successfully upgraded "
5189 "'%s' from version %llu to feature flags.\n"),
5190 zpool_get_name(zhp
), oldversion
);
5192 (void) printf(gettext("Successfully upgraded "
5193 "'%s' from version %llu to version %llu.\n"),
5194 zpool_get_name(zhp
), oldversion
, version
);
5201 upgrade_enable_all(zpool_handle_t
*zhp
, int *countp
)
5204 boolean_t firstff
= B_TRUE
;
5205 nvlist_t
*enabled
= zpool_get_features(zhp
);
5208 for (i
= 0; i
< SPA_FEATURES
; i
++) {
5209 const char *fname
= spa_feature_table
[i
].fi_uname
;
5210 const char *fguid
= spa_feature_table
[i
].fi_guid
;
5211 if (!nvlist_exists(enabled
, fguid
)) {
5213 verify(-1 != asprintf(&propname
, "feature@%s", fname
));
5214 ret
= zpool_set_prop(zhp
, propname
,
5215 ZFS_FEATURE_ENABLED
);
5223 (void) printf(gettext("Enabled the "
5224 "following features on '%s':\n"),
5225 zpool_get_name(zhp
));
5228 (void) printf(gettext(" %s\n"), fname
);
5239 upgrade_cb(zpool_handle_t
*zhp
, void *arg
)
5241 upgrade_cbdata_t
*cbp
= arg
;
5244 boolean_t printnl
= B_FALSE
;
5247 config
= zpool_get_config(zhp
, NULL
);
5248 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_VERSION
,
5251 assert(SPA_VERSION_IS_SUPPORTED(version
));
5253 if (version
< cbp
->cb_version
) {
5254 cbp
->cb_first
= B_FALSE
;
5255 ret
= upgrade_version(zhp
, cbp
->cb_version
);
5261 * If they did "zpool upgrade -a", then we could
5262 * be doing ioctls to different pools. We need
5263 * to log this history once to each pool, and bypass
5264 * the normal history logging that happens in main().
5266 (void) zpool_log_history(g_zfs
, history_str
);
5267 log_history
= B_FALSE
;
5270 if (cbp
->cb_version
>= SPA_VERSION_FEATURES
) {
5272 ret
= upgrade_enable_all(zhp
, &count
);
5277 cbp
->cb_first
= B_FALSE
;
5283 (void) printf(gettext("\n"));
5290 upgrade_list_older_cb(zpool_handle_t
*zhp
, void *arg
)
5292 upgrade_cbdata_t
*cbp
= arg
;
5296 config
= zpool_get_config(zhp
, NULL
);
5297 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_VERSION
,
5300 assert(SPA_VERSION_IS_SUPPORTED(version
));
5302 if (version
< SPA_VERSION_FEATURES
) {
5303 if (cbp
->cb_first
) {
5304 (void) printf(gettext("The following pools are "
5305 "formatted with legacy version numbers and can\n"
5306 "be upgraded to use feature flags. After "
5307 "being upgraded, these pools\nwill no "
5308 "longer be accessible by software that does not "
5309 "support feature\nflags.\n\n"));
5310 (void) printf(gettext("VER POOL\n"));
5311 (void) printf(gettext("--- ------------\n"));
5312 cbp
->cb_first
= B_FALSE
;
5315 (void) printf("%2llu %s\n", (u_longlong_t
)version
,
5316 zpool_get_name(zhp
));
5323 upgrade_list_disabled_cb(zpool_handle_t
*zhp
, void *arg
)
5325 upgrade_cbdata_t
*cbp
= arg
;
5329 config
= zpool_get_config(zhp
, NULL
);
5330 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_VERSION
,
5333 if (version
>= SPA_VERSION_FEATURES
) {
5335 boolean_t poolfirst
= B_TRUE
;
5336 nvlist_t
*enabled
= zpool_get_features(zhp
);
5338 for (i
= 0; i
< SPA_FEATURES
; i
++) {
5339 const char *fguid
= spa_feature_table
[i
].fi_guid
;
5340 const char *fname
= spa_feature_table
[i
].fi_uname
;
5341 if (!nvlist_exists(enabled
, fguid
)) {
5342 if (cbp
->cb_first
) {
5343 (void) printf(gettext("\nSome "
5344 "supported features are not "
5345 "enabled on the following pools. "
5346 "Once a\nfeature is enabled the "
5347 "pool may become incompatible with "
5348 "software\nthat does not support "
5350 "zpool-features(5) for "
5352 (void) printf(gettext("POOL "
5354 (void) printf(gettext("------"
5356 cbp
->cb_first
= B_FALSE
;
5360 (void) printf(gettext("%s\n"),
5361 zpool_get_name(zhp
));
5362 poolfirst
= B_FALSE
;
5365 (void) printf(gettext(" %s\n"), fname
);
5375 upgrade_one(zpool_handle_t
*zhp
, void *data
)
5377 boolean_t printnl
= B_FALSE
;
5378 upgrade_cbdata_t
*cbp
= data
;
5379 uint64_t cur_version
;
5382 if (strcmp("log", zpool_get_name(zhp
)) == 0) {
5383 (void) printf(gettext("'log' is now a reserved word\n"
5384 "Pool 'log' must be renamed using export and import"
5389 cur_version
= zpool_get_prop_int(zhp
, ZPOOL_PROP_VERSION
, NULL
);
5390 if (cur_version
> cbp
->cb_version
) {
5391 (void) printf(gettext("Pool '%s' is already formatted "
5392 "using more current version '%llu'.\n\n"),
5393 zpool_get_name(zhp
), cur_version
);
5397 if (cbp
->cb_version
!= SPA_VERSION
&& cur_version
== cbp
->cb_version
) {
5398 (void) printf(gettext("Pool '%s' is already formatted "
5399 "using version %llu.\n\n"), zpool_get_name(zhp
),
5404 if (cur_version
!= cbp
->cb_version
) {
5406 ret
= upgrade_version(zhp
, cbp
->cb_version
);
5411 if (cbp
->cb_version
>= SPA_VERSION_FEATURES
) {
5413 ret
= upgrade_enable_all(zhp
, &count
);
5419 } else if (cur_version
== SPA_VERSION
) {
5420 (void) printf(gettext("Pool '%s' already has all "
5421 "supported features enabled.\n"),
5422 zpool_get_name(zhp
));
5427 (void) printf(gettext("\n"));
5436 * zpool upgrade [-V version] <-a | pool ...>
5438 * With no arguments, display downrev'd ZFS pool available for upgrade.
5439 * Individual pools can be upgraded by specifying the pool, and '-a' will
5440 * upgrade all pools.
5443 zpool_do_upgrade(int argc
, char **argv
)
5446 upgrade_cbdata_t cb
= { 0 };
5448 boolean_t showversions
= B_FALSE
;
5449 boolean_t upgradeall
= B_FALSE
;
5454 while ((c
= getopt(argc
, argv
, ":avV:")) != -1) {
5457 upgradeall
= B_TRUE
;
5460 showversions
= B_TRUE
;
5463 cb
.cb_version
= strtoll(optarg
, &end
, 10);
5465 !SPA_VERSION_IS_SUPPORTED(cb
.cb_version
)) {
5466 (void) fprintf(stderr
,
5467 gettext("invalid version '%s'\n"), optarg
);
5472 (void) fprintf(stderr
, gettext("missing argument for "
5473 "'%c' option\n"), optopt
);
5477 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
5488 if (cb
.cb_version
== 0) {
5489 cb
.cb_version
= SPA_VERSION
;
5490 } else if (!upgradeall
&& argc
== 0) {
5491 (void) fprintf(stderr
, gettext("-V option is "
5492 "incompatible with other arguments\n"));
5497 if (upgradeall
|| argc
!= 0) {
5498 (void) fprintf(stderr
, gettext("-v option is "
5499 "incompatible with other arguments\n"));
5502 } else if (upgradeall
) {
5504 (void) fprintf(stderr
, gettext("-a option should not "
5505 "be used along with a pool name\n"));
5510 (void) printf(gettext("This system supports ZFS pool feature "
5515 (void) printf(gettext("The following features are "
5517 (void) printf(gettext("FEAT DESCRIPTION\n"));
5518 (void) printf("----------------------------------------------"
5519 "---------------\n");
5520 for (i
= 0; i
< SPA_FEATURES
; i
++) {
5521 zfeature_info_t
*fi
= &spa_feature_table
[i
];
5523 (fi
->fi_flags
& ZFEATURE_FLAG_READONLY_COMPAT
) ?
5524 " (read-only compatible)" : "";
5526 (void) printf("%-37s%s\n", fi
->fi_uname
, ro
);
5527 (void) printf(" %s\n", fi
->fi_desc
);
5529 (void) printf("\n");
5531 (void) printf(gettext("The following legacy versions are also "
5533 (void) printf(gettext("VER DESCRIPTION\n"));
5534 (void) printf("--- -----------------------------------------"
5535 "---------------\n");
5536 (void) printf(gettext(" 1 Initial ZFS version\n"));
5537 (void) printf(gettext(" 2 Ditto blocks "
5538 "(replicated metadata)\n"));
5539 (void) printf(gettext(" 3 Hot spares and double parity "
5541 (void) printf(gettext(" 4 zpool history\n"));
5542 (void) printf(gettext(" 5 Compression using the gzip "
5544 (void) printf(gettext(" 6 bootfs pool property\n"));
5545 (void) printf(gettext(" 7 Separate intent log devices\n"));
5546 (void) printf(gettext(" 8 Delegated administration\n"));
5547 (void) printf(gettext(" 9 refquota and refreservation "
5549 (void) printf(gettext(" 10 Cache devices\n"));
5550 (void) printf(gettext(" 11 Improved scrub performance\n"));
5551 (void) printf(gettext(" 12 Snapshot properties\n"));
5552 (void) printf(gettext(" 13 snapused property\n"));
5553 (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
5554 (void) printf(gettext(" 15 user/group space accounting\n"));
5555 (void) printf(gettext(" 16 stmf property support\n"));
5556 (void) printf(gettext(" 17 Triple-parity RAID-Z\n"));
5557 (void) printf(gettext(" 18 Snapshot user holds\n"));
5558 (void) printf(gettext(" 19 Log device removal\n"));
5559 (void) printf(gettext(" 20 Compression using zle "
5560 "(zero-length encoding)\n"));
5561 (void) printf(gettext(" 21 Deduplication\n"));
5562 (void) printf(gettext(" 22 Received properties\n"));
5563 (void) printf(gettext(" 23 Slim ZIL\n"));
5564 (void) printf(gettext(" 24 System attributes\n"));
5565 (void) printf(gettext(" 25 Improved scrub stats\n"));
5566 (void) printf(gettext(" 26 Improved snapshot deletion "
5568 (void) printf(gettext(" 27 Improved snapshot creation "
5570 (void) printf(gettext(" 28 Multiple vdev replacements\n"));
5571 (void) printf(gettext("\nFor more information on a particular "
5572 "version, including supported releases,\n"));
5573 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
5574 } else if (argc
== 0 && upgradeall
) {
5575 cb
.cb_first
= B_TRUE
;
5576 ret
= zpool_iter(g_zfs
, upgrade_cb
, &cb
);
5577 if (ret
== 0 && cb
.cb_first
) {
5578 if (cb
.cb_version
== SPA_VERSION
) {
5579 (void) printf(gettext("All pools are already "
5580 "formatted using feature flags.\n\n"));
5581 (void) printf(gettext("Every feature flags "
5582 "pool already has all supported features "
5585 (void) printf(gettext("All pools are already "
5586 "formatted with version %llu or higher.\n"),
5590 } else if (argc
== 0) {
5591 cb
.cb_first
= B_TRUE
;
5592 ret
= zpool_iter(g_zfs
, upgrade_list_older_cb
, &cb
);
5596 (void) printf(gettext("All pools are formatted "
5597 "using feature flags.\n\n"));
5599 (void) printf(gettext("\nUse 'zpool upgrade -v' "
5600 "for a list of available legacy versions.\n"));
5603 cb
.cb_first
= B_TRUE
;
5604 ret
= zpool_iter(g_zfs
, upgrade_list_disabled_cb
, &cb
);
5608 (void) printf(gettext("Every feature flags pool has "
5609 "all supported features enabled.\n"));
5611 (void) printf(gettext("\n"));
5614 ret
= for_each_pool(argc
, argv
, B_FALSE
, NULL
,
5621 typedef struct hist_cbdata
{
5628 * Print out the command history for a specific pool.
5631 get_history_one(zpool_handle_t
*zhp
, void *data
)
5637 hist_cbdata_t
*cb
= (hist_cbdata_t
*)data
;
5639 cb
->first
= B_FALSE
;
5641 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp
));
5643 if ((ret
= zpool_get_history(zhp
, &nvhis
)) != 0)
5646 verify(nvlist_lookup_nvlist_array(nvhis
, ZPOOL_HIST_RECORD
,
5647 &records
, &numrecords
) == 0);
5648 for (i
= 0; i
< numrecords
; i
++) {
5649 nvlist_t
*rec
= records
[i
];
5652 if (nvlist_exists(rec
, ZPOOL_HIST_TIME
)) {
5656 tsec
= fnvlist_lookup_uint64(records
[i
],
5658 (void) localtime_r(&tsec
, &t
);
5659 (void) strftime(tbuf
, sizeof (tbuf
), "%F.%T", &t
);
5662 if (nvlist_exists(rec
, ZPOOL_HIST_CMD
)) {
5663 (void) printf("%s %s", tbuf
,
5664 fnvlist_lookup_string(rec
, ZPOOL_HIST_CMD
));
5665 } else if (nvlist_exists(rec
, ZPOOL_HIST_INT_EVENT
)) {
5667 fnvlist_lookup_uint64(rec
, ZPOOL_HIST_INT_EVENT
);
5670 if (ievent
>= ZFS_NUM_LEGACY_HISTORY_EVENTS
) {
5671 (void) printf("%s unrecognized record:\n",
5673 dump_nvlist(rec
, 4);
5676 (void) printf("%s [internal %s txg:%lld] %s", tbuf
,
5677 zfs_history_event_names
[ievent
],
5678 fnvlist_lookup_uint64(rec
, ZPOOL_HIST_TXG
),
5679 fnvlist_lookup_string(rec
, ZPOOL_HIST_INT_STR
));
5680 } else if (nvlist_exists(rec
, ZPOOL_HIST_INT_NAME
)) {
5683 (void) printf("%s [txg:%lld] %s", tbuf
,
5684 fnvlist_lookup_uint64(rec
, ZPOOL_HIST_TXG
),
5685 fnvlist_lookup_string(rec
, ZPOOL_HIST_INT_NAME
));
5686 if (nvlist_exists(rec
, ZPOOL_HIST_DSNAME
)) {
5687 (void) printf(" %s (%llu)",
5688 fnvlist_lookup_string(rec
,
5690 fnvlist_lookup_uint64(rec
,
5693 (void) printf(" %s", fnvlist_lookup_string(rec
,
5694 ZPOOL_HIST_INT_STR
));
5695 } else if (nvlist_exists(rec
, ZPOOL_HIST_IOCTL
)) {
5698 (void) printf("%s ioctl %s\n", tbuf
,
5699 fnvlist_lookup_string(rec
, ZPOOL_HIST_IOCTL
));
5700 if (nvlist_exists(rec
, ZPOOL_HIST_INPUT_NVL
)) {
5701 (void) printf(" input:\n");
5702 dump_nvlist(fnvlist_lookup_nvlist(rec
,
5703 ZPOOL_HIST_INPUT_NVL
), 8);
5705 if (nvlist_exists(rec
, ZPOOL_HIST_OUTPUT_NVL
)) {
5706 (void) printf(" output:\n");
5707 dump_nvlist(fnvlist_lookup_nvlist(rec
,
5708 ZPOOL_HIST_OUTPUT_NVL
), 8);
5710 if (nvlist_exists(rec
, ZPOOL_HIST_ERRNO
)) {
5711 (void) printf(" errno: %lld\n",
5712 fnvlist_lookup_int64(rec
,
5718 (void) printf("%s unrecognized record:\n", tbuf
);
5719 dump_nvlist(rec
, 4);
5723 (void) printf("\n");
5726 (void) printf(" [");
5727 if (nvlist_exists(rec
, ZPOOL_HIST_WHO
)) {
5728 uid_t who
= fnvlist_lookup_uint64(rec
, ZPOOL_HIST_WHO
);
5729 struct passwd
*pwd
= getpwuid(who
);
5730 (void) printf("user %d ", (int)who
);
5732 (void) printf("(%s) ", pwd
->pw_name
);
5734 if (nvlist_exists(rec
, ZPOOL_HIST_HOST
)) {
5735 (void) printf("on %s",
5736 fnvlist_lookup_string(rec
, ZPOOL_HIST_HOST
));
5738 if (nvlist_exists(rec
, ZPOOL_HIST_ZONE
)) {
5739 (void) printf(":%s",
5740 fnvlist_lookup_string(rec
, ZPOOL_HIST_ZONE
));
5743 (void) printf("\n");
5745 (void) printf("\n");
5752 * zpool history <pool>
5754 * Displays the history of commands that modified pools.
5757 zpool_do_history(int argc
, char **argv
)
5759 hist_cbdata_t cbdata
= { 0 };
5763 cbdata
.first
= B_TRUE
;
5765 while ((c
= getopt(argc
, argv
, "li")) != -1) {
5768 cbdata
.longfmt
= B_TRUE
;
5771 cbdata
.internal
= B_TRUE
;
5774 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
5782 ret
= for_each_pool(argc
, argv
, B_FALSE
, NULL
, get_history_one
,
5785 if (argc
== 0 && cbdata
.first
== B_TRUE
) {
5786 (void) printf(gettext("no pools available\n"));
5794 get_callback(zpool_handle_t
*zhp
, void *data
)
5796 zprop_get_cbdata_t
*cbp
= (zprop_get_cbdata_t
*)data
;
5797 char value
[MAXNAMELEN
];
5798 zprop_source_t srctype
;
5801 for (pl
= cbp
->cb_proplist
; pl
!= NULL
; pl
= pl
->pl_next
) {
5804 * Skip the special fake placeholder. This will also skip
5805 * over the name property when 'all' is specified.
5807 if (pl
->pl_prop
== ZPOOL_PROP_NAME
&&
5808 pl
== cbp
->cb_proplist
)
5811 if (pl
->pl_prop
== ZPROP_INVAL
&&
5812 (zpool_prop_feature(pl
->pl_user_prop
) ||
5813 zpool_prop_unsupported(pl
->pl_user_prop
))) {
5814 srctype
= ZPROP_SRC_LOCAL
;
5816 if (zpool_prop_get_feature(zhp
, pl
->pl_user_prop
,
5817 value
, sizeof (value
)) == 0) {
5818 zprop_print_one_property(zpool_get_name(zhp
),
5819 cbp
, pl
->pl_user_prop
, value
, srctype
,
5823 if (zpool_get_prop(zhp
, pl
->pl_prop
, value
,
5824 sizeof (value
), &srctype
, cbp
->cb_literal
) != 0)
5827 zprop_print_one_property(zpool_get_name(zhp
), cbp
,
5828 zpool_prop_to_name(pl
->pl_prop
), value
, srctype
,
5836 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
5838 * -H Scripted mode. Don't display headers, and separate properties
5840 * -o List of columns to display. Defaults to
5841 * "name,property,value,source".
5842 * -p Diplay values in parsable (exact) format.
5844 * Get properties of pools in the system. Output space statistics
5845 * for each one as well as other attributes.
5848 zpool_do_get(int argc
, char **argv
)
5850 zprop_get_cbdata_t cb
= { 0 };
5851 zprop_list_t fake_name
= { 0 };
5856 cb
.cb_first
= B_TRUE
;
5859 * Set up default columns and sources.
5861 cb
.cb_sources
= ZPROP_SRC_ALL
;
5862 cb
.cb_columns
[0] = GET_COL_NAME
;
5863 cb
.cb_columns
[1] = GET_COL_PROPERTY
;
5864 cb
.cb_columns
[2] = GET_COL_VALUE
;
5865 cb
.cb_columns
[3] = GET_COL_SOURCE
;
5866 cb
.cb_type
= ZFS_TYPE_POOL
;
5869 while ((c
= getopt(argc
, argv
, ":Hpo:")) != -1) {
5872 cb
.cb_literal
= B_TRUE
;
5875 cb
.cb_scripted
= B_TRUE
;
5878 bzero(&cb
.cb_columns
, sizeof (cb
.cb_columns
));
5880 while (*optarg
!= '\0') {
5881 static char *col_subopts
[] =
5882 { "name", "property", "value", "source",
5885 if (i
== ZFS_GET_NCOLS
) {
5886 (void) fprintf(stderr
, gettext("too "
5887 "many fields given to -o "
5892 switch (getsubopt(&optarg
, col_subopts
,
5895 cb
.cb_columns
[i
++] = GET_COL_NAME
;
5898 cb
.cb_columns
[i
++] = GET_COL_PROPERTY
;
5901 cb
.cb_columns
[i
++] = GET_COL_VALUE
;
5904 cb
.cb_columns
[i
++] = GET_COL_SOURCE
;
5908 (void) fprintf(stderr
,
5909 gettext("\"all\" conflicts "
5910 "with specific fields "
5911 "given to -o option\n"));
5914 cb
.cb_columns
[0] = GET_COL_NAME
;
5915 cb
.cb_columns
[1] = GET_COL_PROPERTY
;
5916 cb
.cb_columns
[2] = GET_COL_VALUE
;
5917 cb
.cb_columns
[3] = GET_COL_SOURCE
;
5921 (void) fprintf(stderr
,
5922 gettext("invalid column name "
5929 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
5939 (void) fprintf(stderr
, gettext("missing property "
5944 if (zprop_get_list(g_zfs
, argv
[0], &cb
.cb_proplist
,
5945 ZFS_TYPE_POOL
) != 0)
5951 if (cb
.cb_proplist
!= NULL
) {
5952 fake_name
.pl_prop
= ZPOOL_PROP_NAME
;
5953 fake_name
.pl_width
= strlen(gettext("NAME"));
5954 fake_name
.pl_next
= cb
.cb_proplist
;
5955 cb
.cb_proplist
= &fake_name
;
5958 ret
= for_each_pool(argc
, argv
, B_TRUE
, &cb
.cb_proplist
,
5961 if (cb
.cb_proplist
== &fake_name
)
5962 zprop_free_list(fake_name
.pl_next
);
5964 zprop_free_list(cb
.cb_proplist
);
5969 typedef struct set_cbdata
{
5972 boolean_t cb_any_successful
;
5976 set_callback(zpool_handle_t
*zhp
, void *data
)
5979 set_cbdata_t
*cb
= (set_cbdata_t
*)data
;
5981 error
= zpool_set_prop(zhp
, cb
->cb_propname
, cb
->cb_value
);
5984 cb
->cb_any_successful
= B_TRUE
;
5990 zpool_do_set(int argc
, char **argv
)
5992 set_cbdata_t cb
= { 0 };
5995 if (argc
> 1 && argv
[1][0] == '-') {
5996 (void) fprintf(stderr
, gettext("invalid option '%c'\n"),
6002 (void) fprintf(stderr
, gettext("missing property=value "
6008 (void) fprintf(stderr
, gettext("missing pool name\n"));
6013 (void) fprintf(stderr
, gettext("too many pool names\n"));
6017 cb
.cb_propname
= argv
[1];
6018 cb
.cb_value
= strchr(cb
.cb_propname
, '=');
6019 if (cb
.cb_value
== NULL
) {
6020 (void) fprintf(stderr
, gettext("missing value in "
6021 "property=value argument\n"));
6025 *(cb
.cb_value
) = '\0';
6028 error
= for_each_pool(argc
- 2, argv
+ 2, B_TRUE
, NULL
,
6035 find_command_idx(char *command
, int *idx
)
6039 for (i
= 0; i
< NCOMMAND
; i
++) {
6040 if (command_table
[i
].name
== NULL
)
6043 if (strcmp(command
, command_table
[i
].name
) == 0) {
6052 main(int argc
, char **argv
)
6058 (void) setlocale(LC_ALL
, "");
6059 (void) textdomain(TEXT_DOMAIN
);
6061 if ((g_zfs
= libzfs_init()) == NULL
) {
6062 (void) fprintf(stderr
, gettext("internal error: failed to "
6063 "initialize ZFS library\n"));
6067 libzfs_print_on_error(g_zfs
, B_TRUE
);
6072 * Make sure the user has specified some command.
6075 (void) fprintf(stderr
, gettext("missing command\n"));
6084 if (strcmp(cmdname
, "-?") == 0)
6087 zfs_save_arguments(argc
, argv
, history_str
, sizeof (history_str
));
6090 * Run the appropriate command.
6092 if (find_command_idx(cmdname
, &i
) == 0) {
6093 current_command
= &command_table
[i
];
6094 ret
= command_table
[i
].func(argc
- 1, argv
+ 1);
6095 } else if (strchr(cmdname
, '=')) {
6096 verify(find_command_idx("set", &i
) == 0);
6097 current_command
= &command_table
[i
];
6098 ret
= command_table
[i
].func(argc
, argv
);
6099 } else if (strcmp(cmdname
, "freeze") == 0 && argc
== 3) {
6101 * 'freeze' is a vile debugging abomination, so we treat
6105 int fd
= open(ZFS_DEV
, O_RDWR
);
6106 (void) strcpy((void *)buf
, argv
[2]);
6107 return (!!ioctl(fd
, ZFS_IOC_POOL_FREEZE
, buf
));
6109 (void) fprintf(stderr
, gettext("unrecognized "
6110 "command '%s'\n"), cmdname
);
6114 if (ret
== 0 && log_history
)
6115 (void) zpool_log_history(g_zfs
, history_str
);
6120 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
6121 * for the purposes of running ::findleaks.
6123 if (getenv("ZFS_ABORT") != NULL
) {
6124 (void) printf("dumping core by request\n");