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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
44 #include <sys/fs/zfs.h>
50 #include "zpool_util.h"
51 #include "zfs_comutil.h"
53 static int zpool_do_create(int, char **);
54 static int zpool_do_destroy(int, char **);
56 static int zpool_do_add(int, char **);
57 static int zpool_do_remove(int, char **);
59 static int zpool_do_list(int, char **);
60 static int zpool_do_iostat(int, char **);
61 static int zpool_do_status(int, char **);
63 static int zpool_do_online(int, char **);
64 static int zpool_do_offline(int, char **);
65 static int zpool_do_clear(int, char **);
67 static int zpool_do_attach(int, char **);
68 static int zpool_do_detach(int, char **);
69 static int zpool_do_replace(int, char **);
71 static int zpool_do_scrub(int, char **);
73 static int zpool_do_import(int, char **);
74 static int zpool_do_export(int, char **);
76 static int zpool_do_upgrade(int, char **);
78 static int zpool_do_history(int, char **);
80 static int zpool_do_get(int, char **);
81 static int zpool_do_set(int, char **);
84 * These libumem hooks provide a reasonable set of defaults for the allocator's
85 * debugging facilities.
90 _umem_debug_init(void)
92 return ("default,verbose"); /* $UMEM_DEBUG setting */
96 _umem_logging_init(void)
98 return ("fail,contents"); /* $UMEM_LOGGING setting */
126 typedef struct zpool_command {
128 int (*func)(int, char **);
133 * Master command table. Each ZFS command has a name, associated function, and
134 * usage message. The usage messages need to be internationalized, so we have
135 * to have a function to return the usage message based on a command index.
137 * These commands are organized according to how they are displayed in the usage
138 * message. An empty command (one with a NULL name) indicates an empty line in
139 * the generic usage message.
141 static zpool_command_t command_table[] = {
142 { "create", zpool_do_create, HELP_CREATE },
143 { "destroy", zpool_do_destroy, HELP_DESTROY },
145 { "add", zpool_do_add, HELP_ADD },
146 { "remove", zpool_do_remove, HELP_REMOVE },
148 { "list", zpool_do_list, HELP_LIST },
149 { "iostat", zpool_do_iostat, HELP_IOSTAT },
150 { "status", zpool_do_status, HELP_STATUS },
152 { "online", zpool_do_online, HELP_ONLINE },
153 { "offline", zpool_do_offline, HELP_OFFLINE },
154 { "clear", zpool_do_clear, HELP_CLEAR },
156 { "attach", zpool_do_attach, HELP_ATTACH },
157 { "detach", zpool_do_detach, HELP_DETACH },
158 { "replace", zpool_do_replace, HELP_REPLACE },
160 { "scrub", zpool_do_scrub, HELP_SCRUB },
162 { "import", zpool_do_import, HELP_IMPORT },
163 { "export", zpool_do_export, HELP_EXPORT },
164 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
166 { "history", zpool_do_history, HELP_HISTORY },
167 { "get", zpool_do_get, HELP_GET },
168 { "set", zpool_do_set, HELP_SET },
171 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
173 zpool_command_t *current_command;
174 static char history_str[HIS_MAX_RECORD_LEN];
177 get_usage(zpool_help_t idx) {
180 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
182 return (gettext("\tattach [-f] <pool> <device> "
185 return (gettext("\tclear <pool> [device]\n"));
187 return (gettext("\tcreate [-fn] [-o property=value] ... \n"
188 "\t [-O file-system-property=value] ... \n"
189 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
191 return (gettext("\tdestroy [-f] <pool>\n"));
193 return (gettext("\tdetach <pool> <device>\n"));
195 return (gettext("\texport [-f] <pool> ...\n"));
197 return (gettext("\thistory [-il] [<pool>] ...\n"));
199 return (gettext("\timport [-d dir] [-D]\n"
200 "\timport [-o mntopts] [-o property=value] ... \n"
201 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
202 "\timport [-o mntopts] [-o property=value] ... \n"
203 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] "
204 "<pool | id> [newpool]\n"));
206 return (gettext("\tiostat [-v] [pool] ... [interval "
209 return (gettext("\tlist [-H] [-o property[,...]] "
212 return (gettext("\toffline [-t] <pool> <device> ...\n"));
214 return (gettext("\tonline <pool> <device> ...\n"));
216 return (gettext("\treplace [-f] <pool> <device> "
219 return (gettext("\tremove <pool> <device> ...\n"));
221 return (gettext("\tscrub [-s] <pool> ...\n"));
223 return (gettext("\tstatus [-vx] [pool] ...\n"));
225 return (gettext("\tupgrade\n"
227 "\tupgrade [-V version] <-a | pool ...>\n"));
229 return (gettext("\tget <\"all\" | property[,...]> "
232 return (gettext("\tset <property=value> <pool> \n"));
241 * Callback routine that will print out a pool property value.
244 print_prop_cb(int prop, void *cb)
248 (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
250 if (zpool_prop_readonly(prop))
251 (void) fprintf(fp, " NO ");
253 (void) fprintf(fp, " YES ");
255 if (zpool_prop_values(prop) == NULL)
256 (void) fprintf(fp, "-\n");
258 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
264 * Display usage message. If we're inside a command, display only the usage for
265 * that command. Otherwise, iterate over the entire command table and display
266 * a complete usage message.
269 usage(boolean_t requested)
271 FILE *fp = requested ? stdout : stderr;
273 if (current_command == NULL) {
276 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
278 gettext("where 'command' is one of the following:\n\n"));
280 for (i = 0; i < NCOMMAND; i++) {
281 if (command_table[i].name == NULL)
282 (void) fprintf(fp, "\n");
284 (void) fprintf(fp, "%s",
285 get_usage(command_table[i].usage));
288 (void) fprintf(fp, gettext("usage:\n"));
289 (void) fprintf(fp, "%s", get_usage(current_command->usage));
292 if (current_command != NULL &&
293 ((strcmp(current_command->name, "set") == 0) ||
294 (strcmp(current_command->name, "get") == 0) ||
295 (strcmp(current_command->name, "list") == 0))) {
298 gettext("\nthe following properties are supported:\n"));
300 (void) fprintf(fp, "\n\t%-13s %s %s\n\n",
301 "PROPERTY", "EDIT", "VALUES");
303 /* Iterate over all properties */
304 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
309 * See comments at end of main().
311 if (getenv("ZFS_ABORT") != NULL) {
312 (void) printf("dumping core by request\n");
316 exit(requested ? 0 : 2);
320 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
321 boolean_t print_logs)
328 (void) printf("\t%*s%s\n", indent, "", name);
330 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
331 &child, &children) != 0)
334 for (c = 0; c < children; c++) {
335 uint64_t is_log = B_FALSE;
337 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
339 if ((is_log && !print_logs) || (!is_log && print_logs))
342 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
343 print_vdev_tree(zhp, vname, child[c], indent + 2,
350 * Add a property pair (name, string-value) into a property nvlist.
353 add_prop_list(const char *propname, char *propval, nvlist_t **props,
356 zpool_prop_t prop = ZPROP_INVAL;
362 if (*props == NULL &&
363 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
364 (void) fprintf(stderr,
365 gettext("internal error: out of memory\n"));
372 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
373 (void) fprintf(stderr, gettext("property '%s' is "
374 "not a valid pool property\n"), propname);
377 normnm = zpool_prop_to_name(prop);
379 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
380 normnm = zfs_prop_to_name(fprop);
386 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
387 prop != ZPOOL_PROP_CACHEFILE) {
388 (void) fprintf(stderr, gettext("property '%s' "
389 "specified multiple times\n"), propname);
393 if (nvlist_add_string(proplist, normnm, propval) != 0) {
394 (void) fprintf(stderr, gettext("internal "
395 "error: out of memory\n"));
403 * zpool add [-fn] <pool> <vdev> ...
405 * -f Force addition of devices, even if they appear in use
406 * -n Do not add the devices, but display the resulting layout if
407 * they were to be added.
409 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
410 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
414 zpool_do_add(int argc, char **argv)
416 boolean_t force = B_FALSE;
417 boolean_t dryrun = B_FALSE;
426 while ((c = getopt(argc, argv, "fn")) != -1) {
435 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
444 /* get pool name and check number of arguments */
446 (void) fprintf(stderr, gettext("missing pool name argument\n"));
450 (void) fprintf(stderr, gettext("missing vdev specification\n"));
459 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
462 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
463 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
469 /* pass off to get_vdev_spec for processing */
470 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
472 if (nvroot == NULL) {
478 nvlist_t *poolnvroot;
480 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
483 (void) printf(gettext("would update '%s' to the following "
484 "configuration:\n"), zpool_get_name(zhp));
486 /* print original main pool and new tree */
487 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
488 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
490 /* Do the same for the logs */
491 if (num_logs(poolnvroot) > 0) {
492 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
493 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
494 } else if (num_logs(nvroot) > 0) {
495 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
500 ret = (zpool_add(zhp, nvroot) != 0);
510 * zpool remove <pool> <vdev> ...
512 * Removes the given vdev from the pool. Currently, this only supports removing
513 * spares and cache devices from the pool. Eventually, we'll want to support
514 * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
517 zpool_do_remove(int argc, char **argv)
526 /* get pool name and check number of arguments */
528 (void) fprintf(stderr, gettext("missing pool name argument\n"));
532 (void) fprintf(stderr, gettext("missing device\n"));
538 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
541 for (i = 1; i < argc; i++) {
542 if (zpool_vdev_remove(zhp, argv[i]) != 0)
550 * zpool create [-fn] [-o property=value] ...
551 * [-O file-system-property=value] ...
552 * [-R root] [-m mountpoint] <pool> <dev> ...
554 * -f Force creation, even if devices appear in use
555 * -n Do not create the pool, but display the resulting layout if it
556 * were to be created.
557 * -R Create a pool under an alternate root
558 * -m Set default mountpoint for the root dataset. By default it's
560 * -o Set property=value.
561 * -O Set fsproperty=value in the pool's root file system
563 * Creates the named pool according to the given vdev specification. The
564 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
565 * we get the nvlist back from get_vdev_spec(), we either print out the contents
566 * (if '-n' was specified), or pass it to libzfs to do the creation.
569 zpool_do_create(int argc, char **argv)
571 boolean_t force = B_FALSE;
572 boolean_t dryrun = B_FALSE;
574 nvlist_t *nvroot = NULL;
577 char *altroot = NULL;
578 char *mountpoint = NULL;
579 nvlist_t *fsprops = NULL;
580 nvlist_t *props = NULL;
584 while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) {
594 if (add_prop_list(zpool_prop_to_name(
595 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
597 if (nvlist_lookup_string(props,
598 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
601 if (add_prop_list(zpool_prop_to_name(
602 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
609 if ((propval = strchr(optarg, '=')) == NULL) {
610 (void) fprintf(stderr, gettext("missing "
611 "'=' for -o option\n"));
617 if (add_prop_list(optarg, propval, &props, B_TRUE))
621 if ((propval = strchr(optarg, '=')) == NULL) {
622 (void) fprintf(stderr, gettext("missing "
623 "'=' for -O option\n"));
629 if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
633 (void) fprintf(stderr, gettext("missing argument for "
634 "'%c' option\n"), optopt);
637 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
646 /* get pool name and check number of arguments */
648 (void) fprintf(stderr, gettext("missing pool name argument\n"));
652 (void) fprintf(stderr, gettext("missing vdev specification\n"));
659 * As a special case, check for use of '/' in the name, and direct the
660 * user to use 'zfs create' instead.
662 if (strchr(poolname, '/') != NULL) {
663 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
664 "character '/' in pool name\n"), poolname);
665 (void) fprintf(stderr, gettext("use 'zfs create' to "
666 "create a dataset\n"));
670 /* pass off to get_vdev_spec for bulk processing */
671 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
676 /* make_root_vdev() allows 0 toplevel children if there are spares */
677 if (!zfs_allocatable_devs(nvroot)) {
678 (void) fprintf(stderr, gettext("invalid vdev "
679 "specification: at least one toplevel vdev must be "
685 if (altroot != NULL && altroot[0] != '/') {
686 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
687 "must be an absolute path\n"), altroot);
692 * Check the validity of the mountpoint and direct the user to use the
693 * '-m' mountpoint option if it looks like its in use.
695 if (mountpoint == NULL ||
696 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
697 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
698 char buf[MAXPATHLEN];
701 if (mountpoint && mountpoint[0] != '/') {
702 (void) fprintf(stderr, gettext("invalid mountpoint "
703 "'%s': must be an absolute path, 'legacy', or "
704 "'none'\n"), mountpoint);
708 if (mountpoint == NULL) {
710 (void) snprintf(buf, sizeof (buf), "%s/%s",
713 (void) snprintf(buf, sizeof (buf), "/%s",
717 (void) snprintf(buf, sizeof (buf), "%s%s",
718 altroot, mountpoint);
720 (void) snprintf(buf, sizeof (buf), "%s",
724 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
725 (void) fprintf(stderr, gettext("mountpoint '%s' : "
726 "%s\n"), buf, strerror(errno));
727 (void) fprintf(stderr, gettext("use '-m' "
728 "option to provide a different default\n"));
733 while (count < 3 && readdir(dirp) != NULL)
735 (void) closedir(dirp);
738 (void) fprintf(stderr, gettext("mountpoint "
739 "'%s' exists and is not empty\n"), buf);
740 (void) fprintf(stderr, gettext("use '-m' "
741 "option to provide a "
742 "different default\n"));
750 * For a dry run invocation, print out a basic message and run
751 * through all the vdevs in the list and print out in an
752 * appropriate hierarchy.
754 (void) printf(gettext("would create '%s' with the "
755 "following layout:\n\n"), poolname);
757 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
758 if (num_logs(nvroot) > 0)
759 print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
764 * Hand off to libzfs.
766 if (zpool_create(g_zfs, poolname,
767 nvroot, props, fsprops) == 0) {
768 zfs_handle_t *pool = zfs_open(g_zfs, poolname,
769 ZFS_TYPE_FILESYSTEM);
771 if (mountpoint != NULL)
772 verify(zfs_prop_set(pool,
774 ZFS_PROP_MOUNTPOINT),
776 if (zfs_mount(pool, NULL, 0) == 0)
777 ret = zfs_shareall(pool);
780 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
781 (void) fprintf(stderr, gettext("pool name may have "
788 nvlist_free(fsprops);
792 nvlist_free(fsprops);
799 * zpool destroy <pool>
801 * -f Forcefully unmount any datasets
803 * Destroy the given pool. Automatically unmounts any datasets in the pool.
806 zpool_do_destroy(int argc, char **argv)
808 boolean_t force = B_FALSE;
815 while ((c = getopt(argc, argv, "f")) != -1) {
821 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
830 /* check arguments */
832 (void) fprintf(stderr, gettext("missing pool argument\n"));
836 (void) fprintf(stderr, gettext("too many arguments\n"));
842 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
844 * As a special case, check for use of '/' in the name, and
845 * direct the user to use 'zfs destroy' instead.
847 if (strchr(pool, '/') != NULL)
848 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
849 "destroy a dataset\n"));
853 if (zpool_disable_datasets(zhp, force) != 0) {
854 (void) fprintf(stderr, gettext("could not destroy '%s': "
855 "could not unmount datasets\n"), zpool_get_name(zhp));
859 ret = (zpool_destroy(zhp) != 0);
867 * zpool export [-f] <pool> ...
869 * -f Forcefully unmount datasets
871 * Export the given pools. By default, the command will attempt to cleanly
872 * unmount any active datasets within the pool. If the '-f' flag is specified,
873 * then the datasets will be forcefully unmounted.
876 zpool_do_export(int argc, char **argv)
878 boolean_t force = B_FALSE;
879 boolean_t hardforce = B_FALSE;
886 while ((c = getopt(argc, argv, "fF")) != -1) {
895 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
904 /* check arguments */
906 (void) fprintf(stderr, gettext("missing pool argument\n"));
911 for (i = 0; i < argc; i++) {
912 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
917 if (zpool_disable_datasets(zhp, force) != 0) {
924 if (zpool_export_force(zhp) != 0)
926 } else if (zpool_export(zhp, force) != 0) {
937 * Given a vdev configuration, determine the maximum width needed for the device
941 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
943 char *name = zpool_vdev_name(g_zfs, zhp, nv);
948 if (strlen(name) + depth > max)
949 max = strlen(name) + depth;
953 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
954 &child, &children) == 0) {
955 for (c = 0; c < children; c++)
956 if ((ret = max_width(zhp, child[c], depth + 2,
961 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
962 &child, &children) == 0) {
963 for (c = 0; c < children; c++)
964 if ((ret = max_width(zhp, child[c], depth + 2,
969 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
970 &child, &children) == 0) {
971 for (c = 0; c < children; c++)
972 if ((ret = max_width(zhp, child[c], depth + 2,
981 typedef struct spare_cbdata {
983 zpool_handle_t *cb_zhp;
987 find_vdev(nvlist_t *nv, uint64_t search)
993 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
997 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
998 &child, &children) == 0) {
999 for (c = 0; c < children; c++)
1000 if (find_vdev(child[c], search))
1008 find_spare(zpool_handle_t *zhp, void *data)
1010 spare_cbdata_t *cbp = data;
1011 nvlist_t *config, *nvroot;
1013 config = zpool_get_config(zhp, NULL);
1014 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1017 if (find_vdev(nvroot, cbp->cb_guid)) {
1027 * Print out configuration state as requested by status_callback.
1030 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
1031 int namewidth, int depth, boolean_t isspare)
1036 char rbuf[6], wbuf[6], cbuf[6], repaired[7];
1038 uint64_t notpresent;
1042 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
1043 (uint64_t **)&vs, &c) == 0);
1045 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1046 &child, &children) != 0)
1049 state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1052 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1055 if (vs->vs_aux == VDEV_AUX_SPARED)
1057 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1061 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
1065 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1066 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1067 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1068 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1071 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1072 ¬present) == 0) {
1074 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1075 (void) printf(" was %s", path);
1076 } else if (vs->vs_aux != 0) {
1079 switch (vs->vs_aux) {
1080 case VDEV_AUX_OPEN_FAILED:
1081 (void) printf(gettext("cannot open"));
1084 case VDEV_AUX_BAD_GUID_SUM:
1085 (void) printf(gettext("missing device"));
1088 case VDEV_AUX_NO_REPLICAS:
1089 (void) printf(gettext("insufficient replicas"));
1092 case VDEV_AUX_VERSION_NEWER:
1093 (void) printf(gettext("newer version"));
1096 case VDEV_AUX_SPARED:
1097 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1099 if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1100 if (strcmp(zpool_get_name(cb.cb_zhp),
1101 zpool_get_name(zhp)) == 0)
1102 (void) printf(gettext("currently in "
1105 (void) printf(gettext("in use by "
1107 zpool_get_name(cb.cb_zhp));
1108 zpool_close(cb.cb_zhp);
1110 (void) printf(gettext("currently in use"));
1114 case VDEV_AUX_ERR_EXCEEDED:
1115 (void) printf(gettext("too many errors"));
1118 case VDEV_AUX_IO_FAILURE:
1119 (void) printf(gettext("experienced I/O failures"));
1122 case VDEV_AUX_BAD_LOG:
1123 (void) printf(gettext("bad intent log"));
1127 (void) printf(gettext("corrupted data"));
1130 } else if (vs->vs_scrub_repaired != 0 && children == 0) {
1132 * Report bytes resilvered/repaired on leaf devices.
1134 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
1135 (void) printf(gettext(" %s %s"), repaired,
1136 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
1137 "resilvered" : "repaired");
1140 (void) printf("\n");
1142 for (c = 0; c < children; c++) {
1143 uint64_t is_log = B_FALSE;
1145 /* Don't print logs here */
1146 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1150 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
1151 print_status_config(zhp, vname, child[c],
1152 namewidth, depth + 2, isspare);
1159 * Print the configuration of an exported pool. Iterate over all vdevs in the
1160 * pool, printing out the name and status for each one.
1163 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
1170 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1171 if (strcmp(type, VDEV_TYPE_MISSING) == 0)
1174 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
1175 (uint64_t **)&vs, &c) == 0);
1177 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1178 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1180 if (vs->vs_aux != 0) {
1183 switch (vs->vs_aux) {
1184 case VDEV_AUX_OPEN_FAILED:
1185 (void) printf(gettext("cannot open"));
1188 case VDEV_AUX_BAD_GUID_SUM:
1189 (void) printf(gettext("missing device"));
1192 case VDEV_AUX_NO_REPLICAS:
1193 (void) printf(gettext("insufficient replicas"));
1196 case VDEV_AUX_VERSION_NEWER:
1197 (void) printf(gettext("newer version"));
1200 case VDEV_AUX_ERR_EXCEEDED:
1201 (void) printf(gettext("too many errors"));
1205 (void) printf(gettext("corrupted data"));
1209 (void) printf("\n");
1211 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1212 &child, &children) != 0)
1215 for (c = 0; c < children; c++) {
1216 uint64_t is_log = B_FALSE;
1218 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1223 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1224 print_import_config(vname, child[c], namewidth, depth + 2);
1228 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1229 &child, &children) == 0) {
1230 (void) printf(gettext("\tcache\n"));
1231 for (c = 0; c < children; c++) {
1232 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1233 (void) printf("\t %s\n", vname);
1238 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1239 &child, &children) == 0) {
1240 (void) printf(gettext("\tspares\n"));
1241 for (c = 0; c < children; c++) {
1242 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1243 (void) printf("\t %s\n", vname);
1251 * Logs are recorded as top level vdevs in the main pool child array
1252 * but with "is_log" set to 1. We use either print_status_config() or
1253 * print_import_config() to print the top level logs then any log
1254 * children (eg mirrored slogs) are printed recursively - which
1255 * works because only the top level vdev is marked "is_log"
1258 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
1263 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1267 (void) printf(gettext("\tlogs\n"));
1269 for (c = 0; c < children; c++) {
1270 uint64_t is_log = B_FALSE;
1273 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1277 name = zpool_vdev_name(g_zfs, zhp, child[c]);
1279 print_status_config(zhp, name, child[c], namewidth,
1282 print_import_config(name, child[c], namewidth, 2);
1287 * Display the status for the given pool.
1290 show_import(nvlist_t *config)
1292 uint64_t pool_state;
1303 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1305 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1307 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1309 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1312 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
1313 (uint64_t **)&vs, &vsc) == 0);
1314 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1316 reason = zpool_import_status(config, &msgid);
1318 (void) printf(gettext(" pool: %s\n"), name);
1319 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
1320 (void) printf(gettext(" state: %s"), health);
1321 if (pool_state == POOL_STATE_DESTROYED)
1322 (void) printf(gettext(" (DESTROYED)"));
1323 (void) printf("\n");
1326 case ZPOOL_STATUS_MISSING_DEV_R:
1327 case ZPOOL_STATUS_MISSING_DEV_NR:
1328 case ZPOOL_STATUS_BAD_GUID_SUM:
1329 (void) printf(gettext("status: One or more devices are missing "
1330 "from the system.\n"));
1333 case ZPOOL_STATUS_CORRUPT_LABEL_R:
1334 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1335 (void) printf(gettext("status: One or more devices contains "
1336 "corrupted data.\n"));
1339 case ZPOOL_STATUS_CORRUPT_DATA:
1340 (void) printf(gettext("status: The pool data is corrupted.\n"));
1343 case ZPOOL_STATUS_OFFLINE_DEV:
1344 (void) printf(gettext("status: One or more devices "
1345 "are offlined.\n"));
1348 case ZPOOL_STATUS_CORRUPT_POOL:
1349 (void) printf(gettext("status: The pool metadata is "
1353 case ZPOOL_STATUS_VERSION_OLDER:
1354 (void) printf(gettext("status: The pool is formatted using an "
1355 "older on-disk version.\n"));
1358 case ZPOOL_STATUS_VERSION_NEWER:
1359 (void) printf(gettext("status: The pool is formatted using an "
1360 "incompatible version.\n"));
1363 case ZPOOL_STATUS_HOSTID_MISMATCH:
1364 (void) printf(gettext("status: The pool was last accessed by "
1365 "another system.\n"));
1368 case ZPOOL_STATUS_FAULTED_DEV_R:
1369 case ZPOOL_STATUS_FAULTED_DEV_NR:
1370 (void) printf(gettext("status: One or more devices are "
1374 case ZPOOL_STATUS_BAD_LOG:
1375 (void) printf(gettext("status: An intent log record cannot be "
1381 * No other status can be seen when importing pools.
1383 assert(reason == ZPOOL_STATUS_OK);
1387 * Print out an action according to the overall state of the pool.
1389 if (vs->vs_state == VDEV_STATE_HEALTHY) {
1390 if (reason == ZPOOL_STATUS_VERSION_OLDER)
1391 (void) printf(gettext("action: The pool can be "
1392 "imported using its name or numeric identifier, "
1393 "though\n\tsome features will not be available "
1394 "without an explicit 'zpool upgrade'.\n"));
1395 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1396 (void) printf(gettext("action: The pool can be "
1397 "imported using its name or numeric "
1398 "identifier and\n\tthe '-f' flag.\n"));
1400 (void) printf(gettext("action: The pool can be "
1401 "imported using its name or numeric "
1403 } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1404 (void) printf(gettext("action: The pool can be imported "
1405 "despite missing or damaged devices. The\n\tfault "
1406 "tolerance of the pool may be compromised if imported.\n"));
1409 case ZPOOL_STATUS_VERSION_NEWER:
1410 (void) printf(gettext("action: The pool cannot be "
1411 "imported. Access the pool on a system running "
1412 "newer\n\tsoftware, or recreate the pool from "
1415 case ZPOOL_STATUS_MISSING_DEV_R:
1416 case ZPOOL_STATUS_MISSING_DEV_NR:
1417 case ZPOOL_STATUS_BAD_GUID_SUM:
1418 (void) printf(gettext("action: The pool cannot be "
1419 "imported. Attach the missing\n\tdevices and try "
1423 (void) printf(gettext("action: The pool cannot be "
1424 "imported due to damaged devices or data.\n"));
1429 * If the state is "closed" or "can't open", and the aux state
1430 * is "corrupt data":
1432 if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1433 (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1434 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1435 if (pool_state == POOL_STATE_DESTROYED)
1436 (void) printf(gettext("\tThe pool was destroyed, "
1437 "but can be imported using the '-Df' flags.\n"));
1438 else if (pool_state != POOL_STATE_EXPORTED)
1439 (void) printf(gettext("\tThe pool may be active on "
1440 "another system, but can be imported using\n\t"
1441 "the '-f' flag.\n"));
1445 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
1448 (void) printf(gettext("config:\n\n"));
1450 namewidth = max_width(NULL, nvroot, 0, 0);
1454 print_import_config(name, nvroot, namewidth, 0);
1455 if (num_logs(nvroot) > 0)
1456 print_logs(NULL, nvroot, namewidth, B_FALSE);
1458 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1459 (void) printf(gettext("\n\tAdditional devices are known to "
1460 "be part of this pool, though their\n\texact "
1461 "configuration cannot be determined.\n"));
1466 * Perform the import for the given configuration. This passes the heavy
1467 * lifting off to zpool_import_props(), and then mounts the datasets contained
1471 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1472 int force, nvlist_t *props, boolean_t do_verbatim)
1474 zpool_handle_t *zhp;
1480 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1483 verify(nvlist_lookup_uint64(config,
1484 ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1485 verify(nvlist_lookup_uint64(config,
1486 ZPOOL_CONFIG_VERSION, &version) == 0);
1487 if (version > SPA_VERSION) {
1488 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1489 "is formatted using a newer ZFS version\n"), name);
1491 } else if (state != POOL_STATE_EXPORTED && !force) {
1494 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1496 if ((unsigned long)hostid != gethostid()) {
1501 verify(nvlist_lookup_string(config,
1502 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1503 verify(nvlist_lookup_uint64(config,
1504 ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0);
1506 (void) fprintf(stderr, gettext("cannot import "
1507 "'%s': pool may be in use from other "
1508 "system, it was last accessed by %s "
1509 "(hostid: 0x%lx) on %s"), name, hostname,
1510 (unsigned long)hostid,
1511 asctime(localtime(&t)));
1512 (void) fprintf(stderr, gettext("use '-f' to "
1513 "import anyway\n"));
1517 (void) fprintf(stderr, gettext("cannot import '%s': "
1518 "pool may be in use from other system\n"), name);
1519 (void) fprintf(stderr, gettext("use '-f' to import "
1525 if (zpool_import_props(g_zfs, config, newname, props, do_verbatim) != 0)
1528 if (newname != NULL)
1529 name = (char *)newname;
1531 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1534 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1535 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1545 * zpool import [-d dir] [-D]
1546 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1547 * [-d dir | -c cachefile] [-f] -a
1548 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1549 * [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1551 * -c Read pool information from a cachefile instead of searching
1554 * -d Scan in a specific directory, other than /dev/dsk. More than
1555 * one directory can be specified using multiple '-d' options.
1557 * -D Scan for previously destroyed pools or import all or only
1558 * specified destroyed pools.
1560 * -R Temporarily import the pool, with all mountpoints relative to
1561 * the given root. The pool will remain exported when the machine
1564 * -f Force import, even if it appears that the pool is active.
1566 * -F Import even in the presence of faulted vdevs. This is an
1567 * intentionally undocumented option for testing purposes, and
1568 * treats the pool configuration as complete, leaving any bad
1569 * vdevs in the FAULTED state. In other words, it does verbatim
1572 * -a Import all pools found.
1574 * -o Set property=value and/or temporary mount options (without '=').
1576 * The import command scans for pools to import, and import pools based on pool
1577 * name and GUID. The pool can also be renamed as part of the import process.
1580 zpool_do_import(int argc, char **argv)
1582 char **searchdirs = NULL;
1586 nvlist_t *pools = NULL;
1587 boolean_t do_all = B_FALSE;
1588 boolean_t do_destroyed = B_FALSE;
1589 char *mntopts = NULL;
1590 boolean_t do_force = B_FALSE;
1593 uint64_t searchguid = 0;
1594 char *searchname = NULL;
1596 nvlist_t *found_config;
1597 nvlist_t *props = NULL;
1599 boolean_t do_verbatim = B_FALSE;
1600 uint64_t pool_state;
1601 char *cachefile = NULL;
1604 while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
1613 if (searchdirs == NULL) {
1614 searchdirs = safe_malloc(sizeof (char *));
1616 char **tmp = safe_malloc((nsearch + 1) *
1618 bcopy(searchdirs, tmp, nsearch *
1623 searchdirs[nsearch++] = optarg;
1626 do_destroyed = B_TRUE;
1632 do_verbatim = B_TRUE;
1635 if ((propval = strchr(optarg, '=')) != NULL) {
1638 if (add_prop_list(optarg, propval,
1646 if (add_prop_list(zpool_prop_to_name(
1647 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1649 if (nvlist_lookup_string(props,
1650 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1653 if (add_prop_list(zpool_prop_to_name(
1654 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1658 (void) fprintf(stderr, gettext("missing argument for "
1659 "'%c' option\n"), optopt);
1663 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1672 if (cachefile && nsearch != 0) {
1673 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1677 if (searchdirs == NULL) {
1678 searchdirs = safe_malloc(sizeof (char *));
1679 searchdirs[0] = "/dev/dsk";
1683 /* check argument count */
1686 (void) fprintf(stderr, gettext("too many arguments\n"));
1691 (void) fprintf(stderr, gettext("too many arguments\n"));
1696 * Check for the SYS_CONFIG privilege. We do this explicitly
1697 * here because otherwise any attempt to discover pools will
1700 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1701 (void) fprintf(stderr, gettext("cannot "
1702 "discover pools: permission denied\n"));
1709 * Depending on the arguments given, we do one of the following:
1711 * <none> Iterate through all pools and display information about
1714 * -a Iterate through all pools and try to import each one.
1716 * <id> Find the pool that corresponds to the given GUID/pool
1717 * name and import that one.
1719 * -D Above options applies only to destroyed pools.
1725 searchguid = strtoull(argv[0], &endptr, 10);
1726 if (errno != 0 || *endptr != '\0')
1727 searchname = argv[0];
1728 found_config = NULL;
1732 pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1734 } else if (searchname != NULL) {
1735 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1739 * It's OK to search by guid even if searchguid is 0.
1741 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1745 if (pools == NULL) {
1747 (void) fprintf(stderr, gettext("cannot import '%s': "
1748 "no such pool available\n"), argv[0]);
1755 * At this point we have a list of import candidate configs. Even if
1756 * we were searching by pool name or guid, we still need to
1757 * post-process the list to deal with pool state and possible
1763 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1765 verify(nvpair_value_nvlist(elem, &config) == 0);
1767 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1769 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1771 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1778 (void) printf("\n");
1781 err |= do_import(config, NULL, mntopts,
1782 do_force, props, do_verbatim);
1784 show_import(config);
1785 } else if (searchname != NULL) {
1789 * We are searching for a pool based on name.
1791 verify(nvlist_lookup_string(config,
1792 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1794 if (strcmp(name, searchname) == 0) {
1795 if (found_config != NULL) {
1796 (void) fprintf(stderr, gettext(
1797 "cannot import '%s': more than "
1798 "one matching pool\n"), searchname);
1799 (void) fprintf(stderr, gettext(
1800 "import by numeric ID instead\n"));
1803 found_config = config;
1809 * Search for a pool by guid.
1811 verify(nvlist_lookup_uint64(config,
1812 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1814 if (guid == searchguid)
1815 found_config = config;
1820 * If we were searching for a specific pool, verify that we found a
1821 * pool, and then do the import.
1823 if (argc != 0 && err == 0) {
1824 if (found_config == NULL) {
1825 (void) fprintf(stderr, gettext("cannot import '%s': "
1826 "no such pool available\n"), argv[0]);
1829 err |= do_import(found_config, argc == 1 ? NULL :
1830 argv[1], mntopts, do_force, props, do_verbatim);
1835 * If we were just looking for pools, report an error if none were
1838 if (argc == 0 && first)
1839 (void) fprintf(stderr,
1840 gettext("no pools available to import\n"));
1847 return (err ? 1 : 0);
1850 typedef struct iostat_cbdata {
1851 zpool_list_t *cb_list;
1858 print_iostat_separator(iostat_cbdata_t *cb)
1862 for (i = 0; i < cb->cb_namewidth; i++)
1864 (void) printf(" ----- ----- ----- ----- ----- -----\n");
1868 print_iostat_header(iostat_cbdata_t *cb)
1870 (void) printf("%*s capacity operations bandwidth\n",
1871 cb->cb_namewidth, "");
1872 (void) printf("%-*s used avail read write read write\n",
1873 cb->cb_namewidth, "pool");
1874 print_iostat_separator(cb);
1878 * Display a single statistic.
1881 print_one_stat(uint64_t value)
1885 zfs_nicenum(value, buf, sizeof (buf));
1886 (void) printf(" %5s", buf);
1890 * Print out all the statistics for the given vdev. This can either be the
1891 * toplevel configuration, or called recursively. If 'name' is NULL, then this
1892 * is a verbose output, and we don't want to display the toplevel pool stats.
1895 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1896 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1898 nvlist_t **oldchild, **newchild;
1900 vdev_stat_t *oldvs, *newvs;
1901 vdev_stat_t zerovs = { 0 };
1906 if (oldnv != NULL) {
1907 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1908 (uint64_t **)&oldvs, &c) == 0);
1913 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1914 (uint64_t **)&newvs, &c) == 0);
1916 if (strlen(name) + depth > cb->cb_namewidth)
1917 (void) printf("%*s%s", depth, "", name);
1919 (void) printf("%*s%s%*s", depth, "", name,
1920 (int)(cb->cb_namewidth - strlen(name) - depth), "");
1922 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1927 scale = (double)NANOSEC / tdelta;
1929 /* only toplevel vdevs have capacity stats */
1930 if (newvs->vs_space == 0) {
1931 (void) printf(" - -");
1933 print_one_stat(newvs->vs_alloc);
1934 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1937 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1938 oldvs->vs_ops[ZIO_TYPE_READ])));
1940 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1941 oldvs->vs_ops[ZIO_TYPE_WRITE])));
1943 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1944 oldvs->vs_bytes[ZIO_TYPE_READ])));
1946 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1947 oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1949 (void) printf("\n");
1951 if (!cb->cb_verbose)
1954 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1955 &newchild, &children) != 0)
1958 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1959 &oldchild, &c) != 0)
1962 for (c = 0; c < children; c++) {
1963 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1964 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1965 newchild[c], cb, depth + 2);
1970 * Include level 2 ARC devices in iostat output
1972 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1973 &newchild, &children) != 0)
1976 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1977 &oldchild, &c) != 0)
1981 (void) printf("%-*s - - - - - "
1982 "-\n", cb->cb_namewidth, "cache");
1983 for (c = 0; c < children; c++) {
1984 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1985 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1986 newchild[c], cb, depth + 2);
1993 refresh_iostat(zpool_handle_t *zhp, void *data)
1995 iostat_cbdata_t *cb = data;
1999 * If the pool has disappeared, remove it from the list and continue.
2001 if (zpool_refresh_stats(zhp, &missing) != 0)
2005 pool_list_remove(cb->cb_list, zhp);
2011 * Callback to print out the iostats for the given pool.
2014 print_iostat(zpool_handle_t *zhp, void *data)
2016 iostat_cbdata_t *cb = data;
2017 nvlist_t *oldconfig, *newconfig;
2018 nvlist_t *oldnvroot, *newnvroot;
2020 newconfig = zpool_get_config(zhp, &oldconfig);
2022 if (cb->cb_iteration == 1)
2025 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2028 if (oldconfig == NULL)
2031 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2035 * Print out the statistics for the pool.
2037 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2040 print_iostat_separator(cb);
2046 get_namewidth(zpool_handle_t *zhp, void *data)
2048 iostat_cbdata_t *cb = data;
2049 nvlist_t *config, *nvroot;
2051 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2052 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2054 if (!cb->cb_verbose)
2055 cb->cb_namewidth = strlen(zpool_get_name(zhp));
2057 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
2061 * The width must fall into the range [10,38]. The upper limit is the
2062 * maximum we can have and still fit in 80 columns.
2064 if (cb->cb_namewidth < 10)
2065 cb->cb_namewidth = 10;
2066 if (cb->cb_namewidth > 38)
2067 cb->cb_namewidth = 38;
2073 * zpool iostat [-v] [pool] ... [interval [count]]
2075 * -v Display statistics for individual vdevs
2077 * This command can be tricky because we want to be able to deal with pool
2078 * creation/destruction as well as vdev configuration changes. The bulk of this
2079 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
2080 * on pool_list_update() to detect the addition of new pools. Configuration
2081 * changes are all handled within libzfs.
2084 zpool_do_iostat(int argc, char **argv)
2089 unsigned long interval = 0, count = 0;
2091 boolean_t verbose = B_FALSE;
2095 while ((c = getopt(argc, argv, "v")) != -1) {
2101 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2111 * Determine if the last argument is an integer or a pool name
2113 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2117 interval = strtoul(argv[argc - 1], &end, 10);
2119 if (*end == '\0' && errno == 0) {
2120 if (interval == 0) {
2121 (void) fprintf(stderr, gettext("interval "
2122 "cannot be zero\n"));
2127 * Ignore the last parameter
2132 * If this is not a valid number, just plow on. The
2133 * user will get a more informative error message later
2141 * If the last argument is also an integer, then we have both a count
2144 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2149 interval = strtoul(argv[argc - 1], &end, 10);
2151 if (*end == '\0' && errno == 0) {
2152 if (interval == 0) {
2153 (void) fprintf(stderr, gettext("interval "
2154 "cannot be zero\n"));
2159 * Ignore the last parameter
2168 * Construct the list of all interesting pools.
2171 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2174 if (pool_list_count(list) == 0 && argc != 0) {
2175 pool_list_free(list);
2179 if (pool_list_count(list) == 0 && interval == 0) {
2180 pool_list_free(list);
2181 (void) fprintf(stderr, gettext("no pools available\n"));
2186 * Enter the main iostat loop.
2189 cb.cb_verbose = verbose;
2190 cb.cb_iteration = 0;
2191 cb.cb_namewidth = 0;
2194 pool_list_update(list);
2196 if ((npools = pool_list_count(list)) == 0)
2200 * Refresh all statistics. This is done as an explicit step
2201 * before calculating the maximum name width, so that any
2202 * configuration changes are properly accounted for.
2204 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2207 * Iterate over all pools to determine the maximum width
2208 * for the pool / device name column across all pools.
2210 cb.cb_namewidth = 0;
2211 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2214 * If it's the first time, or verbose mode, print the header.
2216 if (++cb.cb_iteration == 1 || verbose)
2217 print_iostat_header(&cb);
2219 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2222 * If there's more than one pool, and we're not in verbose mode
2223 * (which prints a separator for us), then print a separator.
2225 if (npools > 1 && !verbose)
2226 print_iostat_separator(&cb);
2229 (void) printf("\n");
2232 * Flush the output so that redirection to a file isn't buffered
2235 (void) fflush(stdout);
2240 if (count != 0 && --count == 0)
2243 (void) sleep(interval);
2246 pool_list_free(list);
2251 typedef struct list_cbdata {
2252 boolean_t cb_scripted;
2254 zprop_list_t *cb_proplist;
2258 * Given a list of columns to display, output appropriate headers for each one.
2261 print_header(zprop_list_t *pl)
2264 boolean_t first = B_TRUE;
2265 boolean_t right_justify;
2267 for (; pl != NULL; pl = pl->pl_next) {
2268 if (pl->pl_prop == ZPROP_INVAL)
2276 header = zpool_prop_column_name(pl->pl_prop);
2277 right_justify = zpool_prop_align_right(pl->pl_prop);
2279 if (pl->pl_next == NULL && !right_justify)
2280 (void) printf("%s", header);
2281 else if (right_justify)
2282 (void) printf("%*s", pl->pl_width, header);
2284 (void) printf("%-*s", pl->pl_width, header);
2287 (void) printf("\n");
2291 * Given a pool and a list of properties, print out all the properties according
2292 * to the described layout.
2295 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2297 boolean_t first = B_TRUE;
2298 char property[ZPOOL_MAXPROPLEN];
2300 boolean_t right_justify;
2303 for (; pl != NULL; pl = pl->pl_next) {
2306 (void) printf("\t");
2313 right_justify = B_FALSE;
2314 if (pl->pl_prop != ZPROP_INVAL) {
2315 if (zpool_get_prop(zhp, pl->pl_prop, property,
2316 sizeof (property), NULL) != 0)
2321 right_justify = zpool_prop_align_right(pl->pl_prop);
2326 width = pl->pl_width;
2329 * If this is being called in scripted mode, or if this is the
2330 * last column and it is left-justified, don't include a width
2333 if (scripted || (pl->pl_next == NULL && !right_justify))
2334 (void) printf("%s", propstr);
2335 else if (right_justify)
2336 (void) printf("%*s", width, propstr);
2338 (void) printf("%-*s", width, propstr);
2341 (void) printf("\n");
2345 * Generic callback function to list a pool.
2348 list_callback(zpool_handle_t *zhp, void *data)
2350 list_cbdata_t *cbp = data;
2352 if (cbp->cb_first) {
2353 if (!cbp->cb_scripted)
2354 print_header(cbp->cb_proplist);
2355 cbp->cb_first = B_FALSE;
2358 print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2364 * zpool list [-H] [-o prop[,prop]*] [pool] ...
2366 * -H Scripted mode. Don't display headers, and separate properties
2368 * -o List of properties to display. Defaults to
2369 * "name,size,used,available,capacity,health,altroot"
2371 * List all pools in the system, whether or not they're healthy. Output space
2372 * statistics for each one, as well as health status summary.
2375 zpool_do_list(int argc, char **argv)
2379 list_cbdata_t cb = { 0 };
2380 static char default_props[] =
2381 "name,size,used,available,capacity,health,altroot";
2382 char *props = default_props;
2385 while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2388 cb.cb_scripted = B_TRUE;
2394 (void) fprintf(stderr, gettext("missing argument for "
2395 "'%c' option\n"), optopt);
2399 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2408 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2411 cb.cb_first = B_TRUE;
2413 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2414 list_callback, &cb);
2416 zprop_free_list(cb.cb_proplist);
2418 if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2419 (void) printf(gettext("no pools available\n"));
2427 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2434 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2435 &child, &children) != 0) {
2436 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2437 if (strncmp(name, "/dev/dsk/", 9) == 0)
2439 if (strncmp(path, "/dev/dsk/", 9) == 0)
2441 if (strcmp(name, path) == 0)
2446 for (c = 0; c < children; c++)
2447 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2454 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2456 boolean_t force = B_FALSE;
2459 char *poolname, *old_disk, *new_disk;
2460 zpool_handle_t *zhp;
2464 while ((c = getopt(argc, argv, "f")) != -1) {
2470 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2479 /* get pool name and check number of arguments */
2481 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2488 (void) fprintf(stderr,
2489 gettext("missing <device> specification\n"));
2497 (void) fprintf(stderr,
2498 gettext("missing <new_device> specification\n"));
2501 new_disk = old_disk;
2511 (void) fprintf(stderr, gettext("too many arguments\n"));
2515 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2518 if (zpool_get_config(zhp, NULL) == NULL) {
2519 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2525 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2527 if (nvroot == NULL) {
2532 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2534 nvlist_free(nvroot);
2541 * zpool replace [-f] <pool> <device> <new_device>
2543 * -f Force attach, even if <new_device> appears to be in use.
2545 * Replace <device> with <new_device>.
2549 zpool_do_replace(int argc, char **argv)
2551 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2555 * zpool attach [-f] <pool> <device> <new_device>
2557 * -f Force attach, even if <new_device> appears to be in use.
2559 * Attach <new_device> to the mirror containing <device>. If <device> is not
2560 * part of a mirror, then <device> will be transformed into a mirror of
2561 * <device> and <new_device>. In either case, <new_device> will begin life
2562 * with a DTL of [0, now], and will immediately begin to resilver itself.
2565 zpool_do_attach(int argc, char **argv)
2567 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2571 * zpool detach [-f] <pool> <device>
2573 * -f Force detach of <device>, even if DTLs argue against it
2574 * (not supported yet)
2576 * Detach a device from a mirror. The operation will be refused if <device>
2577 * is the last device in the mirror, or if the DTLs indicate that this device
2578 * has the only valid copy of some data.
2582 zpool_do_detach(int argc, char **argv)
2585 char *poolname, *path;
2586 zpool_handle_t *zhp;
2590 while ((c = getopt(argc, argv, "f")) != -1) {
2594 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2603 /* get pool name and check number of arguments */
2605 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2610 (void) fprintf(stderr,
2611 gettext("missing <device> specification\n"));
2618 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2621 ret = zpool_vdev_detach(zhp, path);
2629 * zpool online <pool> <device> ...
2632 zpool_do_online(int argc, char **argv)
2636 zpool_handle_t *zhp;
2638 vdev_state_t newstate;
2642 while ((c = getopt(argc, argv, "et")) != -1) {
2645 flags |= ZFS_ONLINE_EXPAND;
2649 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2658 /* get pool name and check number of arguments */
2660 (void) fprintf(stderr, gettext("missing pool name\n"));
2664 (void) fprintf(stderr, gettext("missing device name\n"));
2670 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2673 for (i = 1; i < argc; i++) {
2674 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
2675 if (newstate != VDEV_STATE_HEALTHY) {
2676 (void) printf(gettext("warning: device '%s' "
2677 "onlined, but remains in faulted state\n"),
2679 if (newstate == VDEV_STATE_FAULTED)
2680 (void) printf(gettext("use 'zpool "
2681 "clear' to restore a faulted "
2684 (void) printf(gettext("use 'zpool "
2685 "replace' to replace devices "
2686 "that are no longer present\n"));
2699 * zpool offline [-ft] <pool> <device> ...
2701 * -f Force the device into the offline state, even if doing
2702 * so would appear to compromise pool availability.
2703 * (not supported yet)
2705 * -t Only take the device off-line temporarily. The offline
2706 * state will not be persistent across reboots.
2710 zpool_do_offline(int argc, char **argv)
2714 zpool_handle_t *zhp;
2716 boolean_t istmp = B_FALSE;
2719 while ((c = getopt(argc, argv, "ft")) != -1) {
2726 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2735 /* get pool name and check number of arguments */
2737 (void) fprintf(stderr, gettext("missing pool name\n"));
2741 (void) fprintf(stderr, gettext("missing device name\n"));
2747 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2750 for (i = 1; i < argc; i++) {
2751 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2761 * zpool clear <pool> [device]
2763 * Clear all errors associated with a pool or a particular device.
2766 zpool_do_clear(int argc, char **argv)
2769 zpool_handle_t *zhp;
2770 char *pool, *device;
2773 (void) fprintf(stderr, gettext("missing pool name\n"));
2778 (void) fprintf(stderr, gettext("too many arguments\n"));
2783 device = argc == 3 ? argv[2] : NULL;
2785 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
2788 if (zpool_clear(zhp, device) != 0)
2796 typedef struct scrub_cbdata {
2803 scrub_callback(zpool_handle_t *zhp, void *data)
2805 scrub_cbdata_t *cb = data;
2809 * Ignore faulted pools.
2811 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2812 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2813 "currently unavailable\n"), zpool_get_name(zhp));
2817 err = zpool_scrub(zhp, cb->cb_type);
2823 * zpool scrub [-s] <pool> ...
2825 * -s Stop. Stops any in-progress scrub.
2828 zpool_do_scrub(int argc, char **argv)
2833 cb.cb_type = POOL_SCRUB_EVERYTHING;
2836 while ((c = getopt(argc, argv, "s")) != -1) {
2839 cb.cb_type = POOL_SCRUB_NONE;
2842 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2854 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2858 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2861 typedef struct status_cbdata {
2863 boolean_t cb_allpools;
2864 boolean_t cb_verbose;
2865 boolean_t cb_explain;
2870 * Print out detailed scrub status.
2873 print_scrub_status(nvlist_t *nvroot)
2877 time_t start, end, now;
2878 double fraction_done;
2879 uint64_t examined, total, minutes_left, minutes_taken;
2882 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2883 (uint64_t **)&vs, &vsc) == 0);
2886 * If there's never been a scrub, there's not much to say.
2888 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2889 (void) printf(gettext("none requested\n"));
2893 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2894 "resilver" : "scrub";
2896 start = vs->vs_scrub_start;
2897 end = vs->vs_scrub_end;
2899 examined = vs->vs_scrub_examined;
2900 total = vs->vs_alloc;
2903 minutes_taken = (uint64_t)((end - start) / 60);
2905 (void) printf(gettext("%s %s after %lluh%um with %llu errors "
2907 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2908 (u_longlong_t)(minutes_taken / 60),
2909 (uint_t)(minutes_taken % 60),
2910 (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2916 if (examined > total)
2919 fraction_done = (double)examined / total;
2920 minutes_left = (uint64_t)((now - start) *
2921 (1 - fraction_done) / fraction_done / 60);
2922 minutes_taken = (uint64_t)((now - start) / 60);
2924 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2925 "%lluh%um to go\n"),
2926 scrub_type, (u_longlong_t)(minutes_taken / 60),
2927 (uint_t)(minutes_taken % 60), 100 * fraction_done,
2928 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2932 print_error_log(zpool_handle_t *zhp)
2934 nvlist_t *nverrlist = NULL;
2937 size_t len = MAXPATHLEN * 2;
2939 if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2940 (void) printf("errors: List of errors unavailable "
2941 "(insufficient privileges)\n");
2945 (void) printf("errors: Permanent errors have been "
2946 "detected in the following files:\n\n");
2948 pathname = safe_malloc(len);
2950 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2952 uint64_t dsobj, obj;
2954 verify(nvpair_value_nvlist(elem, &nv) == 0);
2955 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2957 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2959 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2960 (void) printf("%7s %s\n", "", pathname);
2963 nvlist_free(nverrlist);
2967 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2976 (void) printf(gettext("\tspares\n"));
2978 for (i = 0; i < nspares; i++) {
2979 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2980 print_status_config(zhp, name, spares[i],
2981 namewidth, 2, B_TRUE);
2987 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2996 (void) printf(gettext("\tcache\n"));
2998 for (i = 0; i < nl2cache; i++) {
2999 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
3000 print_status_config(zhp, name, l2cache[i],
3001 namewidth, 2, B_FALSE);
3007 * Display a summary of pool status. Displays a summary such as:
3011 * reason: One or more devices ...
3012 * see: http://www.sun.com/msg/ZFS-xxxx-01
3018 * When given the '-v' option, we print out the complete config. If the '-e'
3019 * option is specified, then we print out error rate information as well.
3022 status_callback(zpool_handle_t *zhp, void *data)
3024 status_cbdata_t *cbp = data;
3025 nvlist_t *config, *nvroot;
3032 config = zpool_get_config(zhp, NULL);
3033 reason = zpool_get_status(zhp, &msgid);
3038 * If we were given 'zpool status -x', only report those pools with
3041 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3042 if (!cbp->cb_allpools) {
3043 (void) printf(gettext("pool '%s' is healthy\n"),
3044 zpool_get_name(zhp));
3046 cbp->cb_first = B_FALSE;
3052 cbp->cb_first = B_FALSE;
3054 (void) printf("\n");
3056 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3058 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3059 (uint64_t **)&vs, &c) == 0);
3060 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3062 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
3063 (void) printf(gettext(" state: %s\n"), health);
3066 case ZPOOL_STATUS_MISSING_DEV_R:
3067 (void) printf(gettext("status: One or more devices could not "
3068 "be opened. Sufficient replicas exist for\n\tthe pool to "
3069 "continue functioning in a degraded state.\n"));
3070 (void) printf(gettext("action: Attach the missing device and "
3071 "online it using 'zpool online'.\n"));
3074 case ZPOOL_STATUS_MISSING_DEV_NR:
3075 (void) printf(gettext("status: One or more devices could not "
3076 "be opened. There are insufficient\n\treplicas for the "
3077 "pool to continue functioning.\n"));
3078 (void) printf(gettext("action: Attach the missing device and "
3079 "online it using 'zpool online'.\n"));
3082 case ZPOOL_STATUS_CORRUPT_LABEL_R:
3083 (void) printf(gettext("status: One or more devices could not "
3084 "be used because the label is missing or\n\tinvalid. "
3085 "Sufficient replicas exist for the pool to continue\n\t"
3086 "functioning in a degraded state.\n"));
3087 (void) printf(gettext("action: Replace the device using "
3088 "'zpool replace'.\n"));
3091 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3092 (void) printf(gettext("status: One or more devices could not "
3093 "be used because the label is missing \n\tor invalid. "
3094 "There are insufficient replicas for the pool to "
3095 "continue\n\tfunctioning.\n"));
3096 (void) printf(gettext("action: Destroy and re-create the pool "
3097 "from a backup source.\n"));
3100 case ZPOOL_STATUS_FAILING_DEV:
3101 (void) printf(gettext("status: One or more devices has "
3102 "experienced an unrecoverable error. An\n\tattempt was "
3103 "made to correct the error. Applications are "
3105 (void) printf(gettext("action: Determine if the device needs "
3106 "to be replaced, and clear the errors\n\tusing "
3107 "'zpool clear' or replace the device with 'zpool "
3111 case ZPOOL_STATUS_OFFLINE_DEV:
3112 (void) printf(gettext("status: One or more devices has "
3113 "been taken offline by the administrator.\n\tSufficient "
3114 "replicas exist for the pool to continue functioning in "
3115 "a\n\tdegraded state.\n"));
3116 (void) printf(gettext("action: Online the device using "
3117 "'zpool online' or replace the device with\n\t'zpool "
3121 case ZPOOL_STATUS_REMOVED_DEV:
3122 (void) printf(gettext("status: One or more devices has "
3123 "been removed by the administrator.\n\tSufficient "
3124 "replicas exist for the pool to continue functioning in "
3125 "a\n\tdegraded state.\n"));
3126 (void) printf(gettext("action: Online the device using "
3127 "'zpool online' or replace the device with\n\t'zpool "
3132 case ZPOOL_STATUS_RESILVERING:
3133 (void) printf(gettext("status: One or more devices is "
3134 "currently being resilvered. The pool will\n\tcontinue "
3135 "to function, possibly in a degraded state.\n"));
3136 (void) printf(gettext("action: Wait for the resilver to "
3140 case ZPOOL_STATUS_CORRUPT_DATA:
3141 (void) printf(gettext("status: One or more devices has "
3142 "experienced an error resulting in data\n\tcorruption. "
3143 "Applications may be affected.\n"));
3144 (void) printf(gettext("action: Restore the file in question "
3145 "if possible. Otherwise restore the\n\tentire pool from "
3149 case ZPOOL_STATUS_CORRUPT_POOL:
3150 (void) printf(gettext("status: The pool metadata is corrupted "
3151 "and the pool cannot be opened.\n"));
3152 (void) printf(gettext("action: Destroy and re-create the pool "
3153 "from a backup source.\n"));
3156 case ZPOOL_STATUS_VERSION_OLDER:
3157 (void) printf(gettext("status: The pool is formatted using an "
3158 "older on-disk format. The pool can\n\tstill be used, but "
3159 "some features are unavailable.\n"));
3160 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3161 "upgrade'. Once this is done, the\n\tpool will no longer "
3162 "be accessible on older software versions.\n"));
3165 case ZPOOL_STATUS_VERSION_NEWER:
3166 (void) printf(gettext("status: The pool has been upgraded to a "
3167 "newer, incompatible on-disk version.\n\tThe pool cannot "
3168 "be accessed on this system.\n"));
3169 (void) printf(gettext("action: Access the pool from a system "
3170 "running more recent software, or\n\trestore the pool from "
3174 case ZPOOL_STATUS_FAULTED_DEV_R:
3175 (void) printf(gettext("status: One or more devices are "
3176 "faulted in response to persistent errors.\n\tSufficient "
3177 "replicas exist for the pool to continue functioning "
3178 "in a\n\tdegraded state.\n"));
3179 (void) printf(gettext("action: Replace the faulted device, "
3180 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3183 case ZPOOL_STATUS_FAULTED_DEV_NR:
3184 (void) printf(gettext("status: One or more devices are "
3185 "faulted in response to persistent errors. There are "
3186 "insufficient replicas for the pool to\n\tcontinue "
3188 (void) printf(gettext("action: Destroy and re-create the pool "
3189 "from a backup source. Manually marking the device\n"
3190 "\trepaired using 'zpool clear' may allow some data "
3191 "to be recovered.\n"));
3194 case ZPOOL_STATUS_IO_FAILURE_WAIT:
3195 case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3196 (void) printf(gettext("status: One or more devices are "
3197 "faulted in response to IO failures.\n"));
3198 (void) printf(gettext("action: Make sure the affected devices "
3199 "are connected, then run 'zpool clear'.\n"));
3202 case ZPOOL_STATUS_BAD_LOG:
3203 (void) printf(gettext("status: An intent log record "
3204 "could not be read.\n"
3205 "\tWaiting for adminstrator intervention to fix the "
3206 "faulted pool.\n"));
3207 (void) printf(gettext("action: Either restore the affected "
3208 "device(s) and run 'zpool online',\n"
3209 "\tor ignore the intent log records by running "
3210 "'zpool clear'.\n"));
3215 * The remaining errors can't actually be generated, yet.
3217 assert(reason == ZPOOL_STATUS_OK);
3221 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
3224 if (config != NULL) {
3227 nvlist_t **spares, **l2cache;
3228 uint_t nspares, nl2cache;
3231 (void) printf(gettext(" scrub: "));
3232 print_scrub_status(nvroot);
3234 namewidth = max_width(zhp, nvroot, 0, 0);
3238 (void) printf(gettext("config:\n\n"));
3239 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
3240 "NAME", "STATE", "READ", "WRITE", "CKSUM");
3241 print_status_config(zhp, zpool_get_name(zhp), nvroot,
3242 namewidth, 0, B_FALSE);
3244 if (num_logs(nvroot) > 0)
3245 print_logs(zhp, nvroot, namewidth, B_TRUE);
3246 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3247 &l2cache, &nl2cache) == 0)
3248 print_l2cache(zhp, l2cache, nl2cache, namewidth);
3250 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3251 &spares, &nspares) == 0)
3252 print_spares(zhp, spares, nspares, namewidth);
3254 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3256 nvlist_t *nverrlist = NULL;
3259 * If the approximate error count is small, get a
3260 * precise count by fetching the entire log and
3261 * uniquifying the results.
3263 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3264 zpool_get_errlog(zhp, &nverrlist) == 0) {
3269 while ((elem = nvlist_next_nvpair(nverrlist,
3274 nvlist_free(nverrlist);
3276 (void) printf("\n");
3279 (void) printf(gettext("errors: No known data "
3281 else if (!cbp->cb_verbose)
3282 (void) printf(gettext("errors: %llu data "
3283 "errors, use '-v' for a list\n"),
3284 (u_longlong_t)nerr);
3286 print_error_log(zhp);
3289 (void) printf(gettext("config: The configuration cannot be "
3297 * zpool status [-vx] [pool] ...
3299 * -v Display complete error logs
3300 * -x Display only pools with potential problems
3302 * Describes the health status of all pools or some subset.
3305 zpool_do_status(int argc, char **argv)
3309 status_cbdata_t cb = { 0 };
3312 while ((c = getopt(argc, argv, "vx")) != -1) {
3315 cb.cb_verbose = B_TRUE;
3318 cb.cb_explain = B_TRUE;
3321 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3330 cb.cb_first = B_TRUE;
3333 cb.cb_allpools = B_TRUE;
3335 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3337 if (argc == 0 && cb.cb_count == 0)
3338 (void) printf(gettext("no pools available\n"));
3339 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3340 (void) printf(gettext("all pools are healthy\n"));
3345 typedef struct upgrade_cbdata {
3350 uint64_t cb_version;
3355 upgrade_cb(zpool_handle_t *zhp, void *arg)
3357 upgrade_cbdata_t *cbp = arg;
3362 config = zpool_get_config(zhp, NULL);
3363 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3366 if (!cbp->cb_newer && version < SPA_VERSION) {
3368 if (cbp->cb_first) {
3369 (void) printf(gettext("The following pools are "
3370 "out of date, and can be upgraded. After "
3371 "being\nupgraded, these pools will no "
3372 "longer be accessible by older software "
3374 (void) printf(gettext("VER POOL\n"));
3375 (void) printf(gettext("--- ------------\n"));
3376 cbp->cb_first = B_FALSE;
3379 (void) printf("%2llu %s\n", (u_longlong_t)version,
3380 zpool_get_name(zhp));
3382 cbp->cb_first = B_FALSE;
3383 ret = zpool_upgrade(zhp, cbp->cb_version);
3385 (void) printf(gettext("Successfully upgraded "
3386 "'%s'\n\n"), zpool_get_name(zhp));
3389 } else if (cbp->cb_newer && version > SPA_VERSION) {
3390 assert(!cbp->cb_all);
3392 if (cbp->cb_first) {
3393 (void) printf(gettext("The following pools are "
3394 "formatted using a newer software version and\n"
3395 "cannot be accessed on the current system.\n\n"));
3396 (void) printf(gettext("VER POOL\n"));
3397 (void) printf(gettext("--- ------------\n"));
3398 cbp->cb_first = B_FALSE;
3401 (void) printf("%2llu %s\n", (u_longlong_t)version,
3402 zpool_get_name(zhp));
3411 upgrade_one(zpool_handle_t *zhp, void *data)
3413 upgrade_cbdata_t *cbp = data;
3414 uint64_t cur_version;
3417 if (strcmp("log", zpool_get_name(zhp)) == 0) {
3418 (void) printf(gettext("'log' is now a reserved word\n"
3419 "Pool 'log' must be renamed using export and import"
3424 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3425 if (cur_version > cbp->cb_version) {
3426 (void) printf(gettext("Pool '%s' is already formatted "
3427 "using more current version '%llu'.\n"),
3428 zpool_get_name(zhp), cur_version);
3431 if (cur_version == cbp->cb_version) {
3432 (void) printf(gettext("Pool '%s' is already formatted "
3433 "using the current version.\n"), zpool_get_name(zhp));
3437 ret = zpool_upgrade(zhp, cbp->cb_version);
3440 (void) printf(gettext("Successfully upgraded '%s' "
3441 "from version %llu to version %llu\n\n"),
3442 zpool_get_name(zhp), (u_longlong_t)cur_version,
3443 (u_longlong_t)cbp->cb_version);
3452 * zpool upgrade [-V version] <-a | pool ...>
3454 * With no arguments, display downrev'd ZFS pool available for upgrade.
3455 * Individual pools can be upgraded by specifying the pool, and '-a' will
3456 * upgrade all pools.
3459 zpool_do_upgrade(int argc, char **argv)
3462 upgrade_cbdata_t cb = { 0 };
3464 boolean_t showversions = B_FALSE;
3469 while ((c = getopt(argc, argv, ":avV:")) != -1) {
3475 showversions = B_TRUE;
3478 cb.cb_version = strtoll(optarg, &end, 10);
3479 if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3480 cb.cb_version < SPA_VERSION_1) {
3481 (void) fprintf(stderr,
3482 gettext("invalid version '%s'\n"), optarg);
3487 (void) fprintf(stderr, gettext("missing argument for "
3488 "'%c' option\n"), optopt);
3492 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3503 if (cb.cb_version == 0) {
3504 cb.cb_version = SPA_VERSION;
3505 } else if (!cb.cb_all && argc == 0) {
3506 (void) fprintf(stderr, gettext("-V option is "
3507 "incompatible with other arguments\n"));
3512 if (cb.cb_all || argc != 0) {
3513 (void) fprintf(stderr, gettext("-v option is "
3514 "incompatible with other arguments\n"));
3517 } else if (cb.cb_all) {
3519 (void) fprintf(stderr, gettext("-a option should not "
3520 "be used along with a pool name\n"));
3525 (void) printf(gettext("This system is currently running "
3526 "ZFS pool version %llu.\n\n"), SPA_VERSION);
3527 cb.cb_first = B_TRUE;
3529 (void) printf(gettext("The following versions are "
3531 (void) printf(gettext("VER DESCRIPTION\n"));
3532 (void) printf("--- -----------------------------------------"
3533 "---------------\n");
3534 (void) printf(gettext(" 1 Initial ZFS version\n"));
3535 (void) printf(gettext(" 2 Ditto blocks "
3536 "(replicated metadata)\n"));
3537 (void) printf(gettext(" 3 Hot spares and double parity "
3539 (void) printf(gettext(" 4 zpool history\n"));
3540 (void) printf(gettext(" 5 Compression using the gzip "
3542 (void) printf(gettext(" 6 bootfs pool property\n"));
3543 (void) printf(gettext(" 7 Separate intent log devices\n"));
3544 (void) printf(gettext(" 8 Delegated administration\n"));
3545 (void) printf(gettext(" 9 refquota and refreservation "
3547 (void) printf(gettext(" 10 Cache devices\n"));
3548 (void) printf(gettext(" 11 Improved scrub performance\n"));
3549 (void) printf(gettext(" 12 Snapshot properties\n"));
3550 (void) printf(gettext(" 13 snapused property\n"));
3551 (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
3552 (void) printf(gettext(" 15 user/group space accounting\n"));
3553 (void) printf(gettext(" 16 stmf property support\n"));
3554 (void) printf(gettext(" 17 Triple-parity RAID-Z\n"));
3555 (void) printf(gettext(" 18 snapshot user holds\n"));
3556 (void) printf(gettext("For more information on a particular "
3557 "version, including supported releases, see:\n\n"));
3558 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3560 (void) printf(gettext("Where 'N' is the version number.\n"));
3561 } else if (argc == 0) {
3564 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3565 notfound = cb.cb_first;
3567 if (!cb.cb_all && ret == 0) {
3569 (void) printf("\n");
3570 cb.cb_first = B_TRUE;
3571 cb.cb_newer = B_TRUE;
3572 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3575 (void) printf("\n");
3581 (void) printf(gettext("All pools are formatted "
3582 "using this version.\n"));
3583 else if (!cb.cb_all)
3584 (void) printf(gettext("Use 'zpool upgrade -v' "
3585 "for a list of available versions and "
3586 "their associated\nfeatures.\n"));
3589 ret = for_each_pool(argc, argv, B_FALSE, NULL,
3596 typedef struct hist_cbdata {
3602 char *hist_event_table[LOG_END] = {
3618 "pool property set",
3622 "destroy_begin_sync",
3626 "permission update",
3627 "permission remove",
3628 "permission who remove",
3637 "filesystem version upgrade",
3639 "refreservation set",
3646 * Print out the command history for a specific pool.
3649 get_history_one(zpool_handle_t *zhp, void *data)
3665 char internalstr[MAXPATHLEN];
3666 hist_cbdata_t *cb = (hist_cbdata_t *)data;
3670 cb->first = B_FALSE;
3672 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3674 if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3677 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3678 &records, &numrecords) == 0);
3679 for (i = 0; i < numrecords; i++) {
3680 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3684 /* is it an internal event or a standard event? */
3685 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3687 if (cb->internal == 0)
3690 if (nvlist_lookup_uint64(records[i],
3691 ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3693 verify(nvlist_lookup_uint64(records[i],
3694 ZPOOL_HIST_TXG, &txg) == 0);
3695 verify(nvlist_lookup_string(records[i],
3696 ZPOOL_HIST_INT_STR, &pathstr) == 0);
3697 if (ievent >= LOG_END)
3699 (void) snprintf(internalstr,
3700 sizeof (internalstr),
3701 "[internal %s txg:%lld] %s",
3702 hist_event_table[ievent], txg,
3704 cmdstr = internalstr;
3707 (void) localtime_r(&tsec, &t);
3708 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3709 (void) printf("%s %s", tbuf, cmdstr);
3712 (void) printf("\n");
3715 (void) printf(" [");
3716 if (nvlist_lookup_uint64(records[i],
3717 ZPOOL_HIST_WHO, &who) == 0) {
3718 pwd = getpwuid((uid_t)who);
3720 (void) printf("user %s on",
3723 (void) printf("user %d on",
3726 (void) printf(gettext("no info]\n"));
3729 if (nvlist_lookup_string(records[i],
3730 ZPOOL_HIST_HOST, &hostname) == 0) {
3731 (void) printf(" %s", hostname);
3733 if (nvlist_lookup_string(records[i],
3734 ZPOOL_HIST_ZONE, &zonename) == 0) {
3735 (void) printf(":%s", zonename);
3739 (void) printf("\n");
3741 (void) printf("\n");
3748 * zpool history <pool>
3750 * Displays the history of commands that modified pools.
3755 zpool_do_history(int argc, char **argv)
3757 hist_cbdata_t cbdata = { 0 };
3761 cbdata.first = B_TRUE;
3763 while ((c = getopt(argc, argv, "li")) != -1) {
3769 cbdata.internal = 1;
3772 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3780 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
3783 if (argc == 0 && cbdata.first == B_TRUE) {
3784 (void) printf(gettext("no pools available\n"));
3792 get_callback(zpool_handle_t *zhp, void *data)
3794 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3795 char value[MAXNAMELEN];
3796 zprop_source_t srctype;
3799 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3802 * Skip the special fake placeholder. This will also skip
3803 * over the name property when 'all' is specified.
3805 if (pl->pl_prop == ZPOOL_PROP_NAME &&
3806 pl == cbp->cb_proplist)
3809 if (zpool_get_prop(zhp, pl->pl_prop,
3810 value, sizeof (value), &srctype) != 0)
3813 zprop_print_one_property(zpool_get_name(zhp), cbp,
3814 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3820 zpool_do_get(int argc, char **argv)
3822 zprop_get_cbdata_t cb = { 0 };
3823 zprop_list_t fake_name = { 0 };
3829 cb.cb_first = B_TRUE;
3830 cb.cb_sources = ZPROP_SRC_ALL;
3831 cb.cb_columns[0] = GET_COL_NAME;
3832 cb.cb_columns[1] = GET_COL_PROPERTY;
3833 cb.cb_columns[2] = GET_COL_VALUE;
3834 cb.cb_columns[3] = GET_COL_SOURCE;
3835 cb.cb_type = ZFS_TYPE_POOL;
3837 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
3838 ZFS_TYPE_POOL) != 0)
3841 if (cb.cb_proplist != NULL) {
3842 fake_name.pl_prop = ZPOOL_PROP_NAME;
3843 fake_name.pl_width = strlen(gettext("NAME"));
3844 fake_name.pl_next = cb.cb_proplist;
3845 cb.cb_proplist = &fake_name;
3848 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3851 if (cb.cb_proplist == &fake_name)
3852 zprop_free_list(fake_name.pl_next);
3854 zprop_free_list(cb.cb_proplist);
3859 typedef struct set_cbdata {
3862 boolean_t cb_any_successful;
3866 set_callback(zpool_handle_t *zhp, void *data)
3869 set_cbdata_t *cb = (set_cbdata_t *)data;
3871 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3874 cb->cb_any_successful = B_TRUE;
3880 zpool_do_set(int argc, char **argv)
3882 set_cbdata_t cb = { 0 };
3885 if (argc > 1 && argv[1][0] == '-') {
3886 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3892 (void) fprintf(stderr, gettext("missing property=value "
3898 (void) fprintf(stderr, gettext("missing pool name\n"));
3903 (void) fprintf(stderr, gettext("too many pool names\n"));
3907 cb.cb_propname = argv[1];
3908 cb.cb_value = strchr(cb.cb_propname, '=');
3909 if (cb.cb_value == NULL) {
3910 (void) fprintf(stderr, gettext("missing value in "
3911 "property=value argument\n"));
3915 *(cb.cb_value) = '\0';
3918 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3925 find_command_idx(char *command, int *idx)
3929 for (i = 0; i < NCOMMAND; i++) {
3930 if (command_table[i].name == NULL)
3933 if (strcmp(command, command_table[i].name) == 0) {
3942 main(int argc, char **argv)
3948 (void) setlocale(LC_ALL, "");
3949 (void) textdomain(TEXT_DOMAIN);
3951 if ((g_zfs = libzfs_init()) == NULL) {
3952 (void) fprintf(stderr, gettext("internal error: failed to "
3953 "initialize ZFS library\n"));
3957 libzfs_print_on_error(g_zfs, B_TRUE);
3962 * Make sure the user has specified some command.
3965 (void) fprintf(stderr, gettext("missing command\n"));
3974 if (strcmp(cmdname, "-?") == 0)
3977 zpool_set_history_str("zpool", argc, argv, history_str);
3978 verify(zpool_stage_history(g_zfs, history_str) == 0);
3981 * Run the appropriate command.
3983 if (find_command_idx(cmdname, &i) == 0) {
3984 current_command = &command_table[i];
3985 ret = command_table[i].func(argc - 1, argv + 1);
3986 } else if (strchr(cmdname, '=')) {
3987 verify(find_command_idx("set", &i) == 0);
3988 current_command = &command_table[i];
3989 ret = command_table[i].func(argc, argv);
3990 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3992 * 'freeze' is a vile debugging abomination, so we treat
3996 int fd = open(ZFS_DEV, O_RDWR);
3997 (void) strcpy((void *)buf, argv[2]);
3998 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
4000 (void) fprintf(stderr, gettext("unrecognized "
4001 "command '%s'\n"), cmdname);
4008 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
4009 * for the purposes of running ::findleaks.
4011 if (getenv("ZFS_ABORT") != NULL) {
4012 (void) printf("dumping core by request\n");