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 allowfaulted)
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,
1529 if (newname != NULL)
1530 name = (char *)newname;
1532 verify((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.
1571 * -a Import all pools found.
1573 * -o Set property=value and/or temporary mount options (without '=').
1575 * The import command scans for pools to import, and import pools based on pool
1576 * name and GUID. The pool can also be renamed as part of the import process.
1579 zpool_do_import(int argc, char **argv)
1581 char **searchdirs = NULL;
1585 nvlist_t *pools = NULL;
1586 boolean_t do_all = B_FALSE;
1587 boolean_t do_destroyed = B_FALSE;
1588 char *mntopts = NULL;
1589 boolean_t do_force = B_FALSE;
1592 uint64_t searchguid = 0;
1593 char *searchname = NULL;
1595 nvlist_t *found_config;
1596 nvlist_t *props = NULL;
1598 boolean_t allow_faulted = B_FALSE;
1599 uint64_t pool_state;
1600 char *cachefile = NULL;
1603 while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
1612 if (searchdirs == NULL) {
1613 searchdirs = safe_malloc(sizeof (char *));
1615 char **tmp = safe_malloc((nsearch + 1) *
1617 bcopy(searchdirs, tmp, nsearch *
1622 searchdirs[nsearch++] = optarg;
1625 do_destroyed = B_TRUE;
1631 allow_faulted = B_TRUE;
1634 if ((propval = strchr(optarg, '=')) != NULL) {
1637 if (add_prop_list(optarg, propval,
1645 if (add_prop_list(zpool_prop_to_name(
1646 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1648 if (nvlist_lookup_string(props,
1649 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1652 if (add_prop_list(zpool_prop_to_name(
1653 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1657 (void) fprintf(stderr, gettext("missing argument for "
1658 "'%c' option\n"), optopt);
1662 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1671 if (cachefile && nsearch != 0) {
1672 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1676 if (searchdirs == NULL) {
1677 searchdirs = safe_malloc(sizeof (char *));
1678 searchdirs[0] = "/dev/dsk";
1682 /* check argument count */
1685 (void) fprintf(stderr, gettext("too many arguments\n"));
1690 (void) fprintf(stderr, gettext("too many arguments\n"));
1695 * Check for the SYS_CONFIG privilege. We do this explicitly
1696 * here because otherwise any attempt to discover pools will
1699 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1700 (void) fprintf(stderr, gettext("cannot "
1701 "discover pools: permission denied\n"));
1708 * Depending on the arguments given, we do one of the following:
1710 * <none> Iterate through all pools and display information about
1713 * -a Iterate through all pools and try to import each one.
1715 * <id> Find the pool that corresponds to the given GUID/pool
1716 * name and import that one.
1718 * -D Above options applies only to destroyed pools.
1724 searchguid = strtoull(argv[0], &endptr, 10);
1725 if (errno != 0 || *endptr != '\0')
1726 searchname = argv[0];
1727 found_config = NULL;
1731 pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1733 } else if (searchname != NULL) {
1734 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1738 * It's OK to search by guid even if searchguid is 0.
1740 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1744 if (pools == NULL) {
1746 (void) fprintf(stderr, gettext("cannot import '%s': "
1747 "no such pool available\n"), argv[0]);
1754 * At this point we have a list of import candidate configs. Even if
1755 * we were searching by pool name or guid, we still need to
1756 * post-process the list to deal with pool state and possible
1762 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1764 verify(nvpair_value_nvlist(elem, &config) == 0);
1766 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1768 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1770 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1777 (void) printf("\n");
1780 err |= do_import(config, NULL, mntopts,
1781 do_force, props, allow_faulted);
1783 show_import(config);
1784 } else if (searchname != NULL) {
1788 * We are searching for a pool based on name.
1790 verify(nvlist_lookup_string(config,
1791 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1793 if (strcmp(name, searchname) == 0) {
1794 if (found_config != NULL) {
1795 (void) fprintf(stderr, gettext(
1796 "cannot import '%s': more than "
1797 "one matching pool\n"), searchname);
1798 (void) fprintf(stderr, gettext(
1799 "import by numeric ID instead\n"));
1802 found_config = config;
1808 * Search for a pool by guid.
1810 verify(nvlist_lookup_uint64(config,
1811 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1813 if (guid == searchguid)
1814 found_config = config;
1819 * If we were searching for a specific pool, verify that we found a
1820 * pool, and then do the import.
1822 if (argc != 0 && err == 0) {
1823 if (found_config == NULL) {
1824 (void) fprintf(stderr, gettext("cannot import '%s': "
1825 "no such pool available\n"), argv[0]);
1828 err |= do_import(found_config, argc == 1 ? NULL :
1829 argv[1], mntopts, do_force, props, allow_faulted);
1834 * If we were just looking for pools, report an error if none were
1837 if (argc == 0 && first)
1838 (void) fprintf(stderr,
1839 gettext("no pools available to import\n"));
1846 return (err ? 1 : 0);
1849 typedef struct iostat_cbdata {
1850 zpool_list_t *cb_list;
1857 print_iostat_separator(iostat_cbdata_t *cb)
1861 for (i = 0; i < cb->cb_namewidth; i++)
1863 (void) printf(" ----- ----- ----- ----- ----- -----\n");
1867 print_iostat_header(iostat_cbdata_t *cb)
1869 (void) printf("%*s capacity operations bandwidth\n",
1870 cb->cb_namewidth, "");
1871 (void) printf("%-*s used avail read write read write\n",
1872 cb->cb_namewidth, "pool");
1873 print_iostat_separator(cb);
1877 * Display a single statistic.
1880 print_one_stat(uint64_t value)
1884 zfs_nicenum(value, buf, sizeof (buf));
1885 (void) printf(" %5s", buf);
1889 * Print out all the statistics for the given vdev. This can either be the
1890 * toplevel configuration, or called recursively. If 'name' is NULL, then this
1891 * is a verbose output, and we don't want to display the toplevel pool stats.
1894 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1895 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1897 nvlist_t **oldchild, **newchild;
1899 vdev_stat_t *oldvs, *newvs;
1900 vdev_stat_t zerovs = { 0 };
1905 if (oldnv != NULL) {
1906 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1907 (uint64_t **)&oldvs, &c) == 0);
1912 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1913 (uint64_t **)&newvs, &c) == 0);
1915 if (strlen(name) + depth > cb->cb_namewidth)
1916 (void) printf("%*s%s", depth, "", name);
1918 (void) printf("%*s%s%*s", depth, "", name,
1919 (int)(cb->cb_namewidth - strlen(name) - depth), "");
1921 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1926 scale = (double)NANOSEC / tdelta;
1928 /* only toplevel vdevs have capacity stats */
1929 if (newvs->vs_space == 0) {
1930 (void) printf(" - -");
1932 print_one_stat(newvs->vs_alloc);
1933 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1936 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1937 oldvs->vs_ops[ZIO_TYPE_READ])));
1939 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1940 oldvs->vs_ops[ZIO_TYPE_WRITE])));
1942 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1943 oldvs->vs_bytes[ZIO_TYPE_READ])));
1945 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1946 oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1948 (void) printf("\n");
1950 if (!cb->cb_verbose)
1953 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1954 &newchild, &children) != 0)
1957 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1958 &oldchild, &c) != 0)
1961 for (c = 0; c < children; c++) {
1962 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1963 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1964 newchild[c], cb, depth + 2);
1969 * Include level 2 ARC devices in iostat output
1971 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1972 &newchild, &children) != 0)
1975 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1976 &oldchild, &c) != 0)
1980 (void) printf("%-*s - - - - - "
1981 "-\n", cb->cb_namewidth, "cache");
1982 for (c = 0; c < children; c++) {
1983 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1984 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1985 newchild[c], cb, depth + 2);
1992 refresh_iostat(zpool_handle_t *zhp, void *data)
1994 iostat_cbdata_t *cb = data;
1998 * If the pool has disappeared, remove it from the list and continue.
2000 if (zpool_refresh_stats(zhp, &missing) != 0)
2004 pool_list_remove(cb->cb_list, zhp);
2010 * Callback to print out the iostats for the given pool.
2013 print_iostat(zpool_handle_t *zhp, void *data)
2015 iostat_cbdata_t *cb = data;
2016 nvlist_t *oldconfig, *newconfig;
2017 nvlist_t *oldnvroot, *newnvroot;
2019 newconfig = zpool_get_config(zhp, &oldconfig);
2021 if (cb->cb_iteration == 1)
2024 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2027 if (oldconfig == NULL)
2030 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2034 * Print out the statistics for the pool.
2036 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2039 print_iostat_separator(cb);
2045 get_namewidth(zpool_handle_t *zhp, void *data)
2047 iostat_cbdata_t *cb = data;
2048 nvlist_t *config, *nvroot;
2050 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2051 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2053 if (!cb->cb_verbose)
2054 cb->cb_namewidth = strlen(zpool_get_name(zhp));
2056 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
2060 * The width must fall into the range [10,38]. The upper limit is the
2061 * maximum we can have and still fit in 80 columns.
2063 if (cb->cb_namewidth < 10)
2064 cb->cb_namewidth = 10;
2065 if (cb->cb_namewidth > 38)
2066 cb->cb_namewidth = 38;
2072 * zpool iostat [-v] [pool] ... [interval [count]]
2074 * -v Display statistics for individual vdevs
2076 * This command can be tricky because we want to be able to deal with pool
2077 * creation/destruction as well as vdev configuration changes. The bulk of this
2078 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
2079 * on pool_list_update() to detect the addition of new pools. Configuration
2080 * changes are all handled within libzfs.
2083 zpool_do_iostat(int argc, char **argv)
2088 unsigned long interval = 0, count = 0;
2090 boolean_t verbose = B_FALSE;
2094 while ((c = getopt(argc, argv, "v")) != -1) {
2100 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2110 * Determine if the last argument is an integer or a pool name
2112 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2116 interval = strtoul(argv[argc - 1], &end, 10);
2118 if (*end == '\0' && errno == 0) {
2119 if (interval == 0) {
2120 (void) fprintf(stderr, gettext("interval "
2121 "cannot be zero\n"));
2126 * Ignore the last parameter
2131 * If this is not a valid number, just plow on. The
2132 * user will get a more informative error message later
2140 * If the last argument is also an integer, then we have both a count
2143 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2148 interval = strtoul(argv[argc - 1], &end, 10);
2150 if (*end == '\0' && errno == 0) {
2151 if (interval == 0) {
2152 (void) fprintf(stderr, gettext("interval "
2153 "cannot be zero\n"));
2158 * Ignore the last parameter
2167 * Construct the list of all interesting pools.
2170 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2173 if (pool_list_count(list) == 0 && argc != 0) {
2174 pool_list_free(list);
2178 if (pool_list_count(list) == 0 && interval == 0) {
2179 pool_list_free(list);
2180 (void) fprintf(stderr, gettext("no pools available\n"));
2185 * Enter the main iostat loop.
2188 cb.cb_verbose = verbose;
2189 cb.cb_iteration = 0;
2190 cb.cb_namewidth = 0;
2193 pool_list_update(list);
2195 if ((npools = pool_list_count(list)) == 0)
2199 * Refresh all statistics. This is done as an explicit step
2200 * before calculating the maximum name width, so that any
2201 * configuration changes are properly accounted for.
2203 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2206 * Iterate over all pools to determine the maximum width
2207 * for the pool / device name column across all pools.
2209 cb.cb_namewidth = 0;
2210 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2213 * If it's the first time, or verbose mode, print the header.
2215 if (++cb.cb_iteration == 1 || verbose)
2216 print_iostat_header(&cb);
2218 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2221 * If there's more than one pool, and we're not in verbose mode
2222 * (which prints a separator for us), then print a separator.
2224 if (npools > 1 && !verbose)
2225 print_iostat_separator(&cb);
2228 (void) printf("\n");
2231 * Flush the output so that redirection to a file isn't buffered
2234 (void) fflush(stdout);
2239 if (count != 0 && --count == 0)
2242 (void) sleep(interval);
2245 pool_list_free(list);
2250 typedef struct list_cbdata {
2251 boolean_t cb_scripted;
2253 zprop_list_t *cb_proplist;
2257 * Given a list of columns to display, output appropriate headers for each one.
2260 print_header(zprop_list_t *pl)
2263 boolean_t first = B_TRUE;
2264 boolean_t right_justify;
2266 for (; pl != NULL; pl = pl->pl_next) {
2267 if (pl->pl_prop == ZPROP_INVAL)
2275 header = zpool_prop_column_name(pl->pl_prop);
2276 right_justify = zpool_prop_align_right(pl->pl_prop);
2278 if (pl->pl_next == NULL && !right_justify)
2279 (void) printf("%s", header);
2280 else if (right_justify)
2281 (void) printf("%*s", pl->pl_width, header);
2283 (void) printf("%-*s", pl->pl_width, header);
2286 (void) printf("\n");
2290 * Given a pool and a list of properties, print out all the properties according
2291 * to the described layout.
2294 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2296 boolean_t first = B_TRUE;
2297 char property[ZPOOL_MAXPROPLEN];
2299 boolean_t right_justify;
2302 for (; pl != NULL; pl = pl->pl_next) {
2305 (void) printf("\t");
2312 right_justify = B_FALSE;
2313 if (pl->pl_prop != ZPROP_INVAL) {
2314 if (zpool_get_prop(zhp, pl->pl_prop, property,
2315 sizeof (property), NULL) != 0)
2320 right_justify = zpool_prop_align_right(pl->pl_prop);
2325 width = pl->pl_width;
2328 * If this is being called in scripted mode, or if this is the
2329 * last column and it is left-justified, don't include a width
2332 if (scripted || (pl->pl_next == NULL && !right_justify))
2333 (void) printf("%s", propstr);
2334 else if (right_justify)
2335 (void) printf("%*s", width, propstr);
2337 (void) printf("%-*s", width, propstr);
2340 (void) printf("\n");
2344 * Generic callback function to list a pool.
2347 list_callback(zpool_handle_t *zhp, void *data)
2349 list_cbdata_t *cbp = data;
2351 if (cbp->cb_first) {
2352 if (!cbp->cb_scripted)
2353 print_header(cbp->cb_proplist);
2354 cbp->cb_first = B_FALSE;
2357 print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2363 * zpool list [-H] [-o prop[,prop]*] [pool] ...
2365 * -H Scripted mode. Don't display headers, and separate properties
2367 * -o List of properties to display. Defaults to
2368 * "name,size,used,available,capacity,health,altroot"
2370 * List all pools in the system, whether or not they're healthy. Output space
2371 * statistics for each one, as well as health status summary.
2374 zpool_do_list(int argc, char **argv)
2378 list_cbdata_t cb = { 0 };
2379 static char default_props[] =
2380 "name,size,used,available,capacity,health,altroot";
2381 char *props = default_props;
2384 while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2387 cb.cb_scripted = B_TRUE;
2393 (void) fprintf(stderr, gettext("missing argument for "
2394 "'%c' option\n"), optopt);
2398 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2407 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2410 cb.cb_first = B_TRUE;
2412 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2413 list_callback, &cb);
2415 zprop_free_list(cb.cb_proplist);
2417 if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2418 (void) printf(gettext("no pools available\n"));
2426 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2433 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2434 &child, &children) != 0) {
2435 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2436 if (strncmp(name, "/dev/dsk/", 9) == 0)
2438 if (strncmp(path, "/dev/dsk/", 9) == 0)
2440 if (strcmp(name, path) == 0)
2445 for (c = 0; c < children; c++)
2446 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2453 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2455 boolean_t force = B_FALSE;
2458 char *poolname, *old_disk, *new_disk;
2459 zpool_handle_t *zhp;
2463 while ((c = getopt(argc, argv, "f")) != -1) {
2469 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2478 /* get pool name and check number of arguments */
2480 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2487 (void) fprintf(stderr,
2488 gettext("missing <device> specification\n"));
2496 (void) fprintf(stderr,
2497 gettext("missing <new_device> specification\n"));
2500 new_disk = old_disk;
2510 (void) fprintf(stderr, gettext("too many arguments\n"));
2514 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2517 if (zpool_get_config(zhp, NULL) == NULL) {
2518 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2524 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2526 if (nvroot == NULL) {
2531 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2533 nvlist_free(nvroot);
2540 * zpool replace [-f] <pool> <device> <new_device>
2542 * -f Force attach, even if <new_device> appears to be in use.
2544 * Replace <device> with <new_device>.
2548 zpool_do_replace(int argc, char **argv)
2550 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2554 * zpool attach [-f] <pool> <device> <new_device>
2556 * -f Force attach, even if <new_device> appears to be in use.
2558 * Attach <new_device> to the mirror containing <device>. If <device> is not
2559 * part of a mirror, then <device> will be transformed into a mirror of
2560 * <device> and <new_device>. In either case, <new_device> will begin life
2561 * with a DTL of [0, now], and will immediately begin to resilver itself.
2564 zpool_do_attach(int argc, char **argv)
2566 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2570 * zpool detach [-f] <pool> <device>
2572 * -f Force detach of <device>, even if DTLs argue against it
2573 * (not supported yet)
2575 * Detach a device from a mirror. The operation will be refused if <device>
2576 * is the last device in the mirror, or if the DTLs indicate that this device
2577 * has the only valid copy of some data.
2581 zpool_do_detach(int argc, char **argv)
2584 char *poolname, *path;
2585 zpool_handle_t *zhp;
2589 while ((c = getopt(argc, argv, "f")) != -1) {
2593 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2602 /* get pool name and check number of arguments */
2604 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2609 (void) fprintf(stderr,
2610 gettext("missing <device> specification\n"));
2617 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2620 ret = zpool_vdev_detach(zhp, path);
2628 * zpool online <pool> <device> ...
2631 zpool_do_online(int argc, char **argv)
2635 zpool_handle_t *zhp;
2637 vdev_state_t newstate;
2641 while ((c = getopt(argc, argv, "et")) != -1) {
2644 flags |= ZFS_ONLINE_EXPAND;
2648 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2657 /* get pool name and check number of arguments */
2659 (void) fprintf(stderr, gettext("missing pool name\n"));
2663 (void) fprintf(stderr, gettext("missing device name\n"));
2669 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2672 for (i = 1; i < argc; i++) {
2673 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
2674 if (newstate != VDEV_STATE_HEALTHY) {
2675 (void) printf(gettext("warning: device '%s' "
2676 "onlined, but remains in faulted state\n"),
2678 if (newstate == VDEV_STATE_FAULTED)
2679 (void) printf(gettext("use 'zpool "
2680 "clear' to restore a faulted "
2683 (void) printf(gettext("use 'zpool "
2684 "replace' to replace devices "
2685 "that are no longer present\n"));
2698 * zpool offline [-ft] <pool> <device> ...
2700 * -f Force the device into the offline state, even if doing
2701 * so would appear to compromise pool availability.
2702 * (not supported yet)
2704 * -t Only take the device off-line temporarily. The offline
2705 * state will not be persistent across reboots.
2709 zpool_do_offline(int argc, char **argv)
2713 zpool_handle_t *zhp;
2715 boolean_t istmp = B_FALSE;
2718 while ((c = getopt(argc, argv, "ft")) != -1) {
2725 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2734 /* get pool name and check number of arguments */
2736 (void) fprintf(stderr, gettext("missing pool name\n"));
2740 (void) fprintf(stderr, gettext("missing device name\n"));
2746 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2749 for (i = 1; i < argc; i++) {
2750 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2760 * zpool clear <pool> [device]
2762 * Clear all errors associated with a pool or a particular device.
2765 zpool_do_clear(int argc, char **argv)
2768 zpool_handle_t *zhp;
2769 char *pool, *device;
2772 (void) fprintf(stderr, gettext("missing pool name\n"));
2777 (void) fprintf(stderr, gettext("too many arguments\n"));
2782 device = argc == 3 ? argv[2] : NULL;
2784 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
2787 if (zpool_clear(zhp, device) != 0)
2795 typedef struct scrub_cbdata {
2802 scrub_callback(zpool_handle_t *zhp, void *data)
2804 scrub_cbdata_t *cb = data;
2808 * Ignore faulted pools.
2810 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2811 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2812 "currently unavailable\n"), zpool_get_name(zhp));
2816 err = zpool_scrub(zhp, cb->cb_type);
2822 * zpool scrub [-s] <pool> ...
2824 * -s Stop. Stops any in-progress scrub.
2827 zpool_do_scrub(int argc, char **argv)
2832 cb.cb_type = POOL_SCRUB_EVERYTHING;
2835 while ((c = getopt(argc, argv, "s")) != -1) {
2838 cb.cb_type = POOL_SCRUB_NONE;
2841 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2853 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2857 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2860 typedef struct status_cbdata {
2862 boolean_t cb_allpools;
2863 boolean_t cb_verbose;
2864 boolean_t cb_explain;
2869 * Print out detailed scrub status.
2872 print_scrub_status(nvlist_t *nvroot)
2876 time_t start, end, now;
2877 double fraction_done;
2878 uint64_t examined, total, minutes_left, minutes_taken;
2881 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2882 (uint64_t **)&vs, &vsc) == 0);
2885 * If there's never been a scrub, there's not much to say.
2887 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2888 (void) printf(gettext("none requested\n"));
2892 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2893 "resilver" : "scrub";
2895 start = vs->vs_scrub_start;
2896 end = vs->vs_scrub_end;
2898 examined = vs->vs_scrub_examined;
2899 total = vs->vs_alloc;
2902 minutes_taken = (uint64_t)((end - start) / 60);
2904 (void) printf(gettext("%s %s after %lluh%um with %llu errors "
2906 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2907 (u_longlong_t)(minutes_taken / 60),
2908 (uint_t)(minutes_taken % 60),
2909 (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2915 if (examined > total)
2918 fraction_done = (double)examined / total;
2919 minutes_left = (uint64_t)((now - start) *
2920 (1 - fraction_done) / fraction_done / 60);
2921 minutes_taken = (uint64_t)((now - start) / 60);
2923 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2924 "%lluh%um to go\n"),
2925 scrub_type, (u_longlong_t)(minutes_taken / 60),
2926 (uint_t)(minutes_taken % 60), 100 * fraction_done,
2927 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2931 print_error_log(zpool_handle_t *zhp)
2933 nvlist_t *nverrlist = NULL;
2936 size_t len = MAXPATHLEN * 2;
2938 if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2939 (void) printf("errors: List of errors unavailable "
2940 "(insufficient privileges)\n");
2944 (void) printf("errors: Permanent errors have been "
2945 "detected in the following files:\n\n");
2947 pathname = safe_malloc(len);
2949 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2951 uint64_t dsobj, obj;
2953 verify(nvpair_value_nvlist(elem, &nv) == 0);
2954 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2956 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2958 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2959 (void) printf("%7s %s\n", "", pathname);
2962 nvlist_free(nverrlist);
2966 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2975 (void) printf(gettext("\tspares\n"));
2977 for (i = 0; i < nspares; i++) {
2978 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2979 print_status_config(zhp, name, spares[i],
2980 namewidth, 2, B_TRUE);
2986 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2995 (void) printf(gettext("\tcache\n"));
2997 for (i = 0; i < nl2cache; i++) {
2998 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
2999 print_status_config(zhp, name, l2cache[i],
3000 namewidth, 2, B_FALSE);
3006 * Display a summary of pool status. Displays a summary such as:
3010 * reason: One or more devices ...
3011 * see: http://www.sun.com/msg/ZFS-xxxx-01
3017 * When given the '-v' option, we print out the complete config. If the '-e'
3018 * option is specified, then we print out error rate information as well.
3021 status_callback(zpool_handle_t *zhp, void *data)
3023 status_cbdata_t *cbp = data;
3024 nvlist_t *config, *nvroot;
3031 config = zpool_get_config(zhp, NULL);
3032 reason = zpool_get_status(zhp, &msgid);
3037 * If we were given 'zpool status -x', only report those pools with
3040 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3041 if (!cbp->cb_allpools) {
3042 (void) printf(gettext("pool '%s' is healthy\n"),
3043 zpool_get_name(zhp));
3045 cbp->cb_first = B_FALSE;
3051 cbp->cb_first = B_FALSE;
3053 (void) printf("\n");
3055 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3057 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3058 (uint64_t **)&vs, &c) == 0);
3059 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3061 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
3062 (void) printf(gettext(" state: %s\n"), health);
3065 case ZPOOL_STATUS_MISSING_DEV_R:
3066 (void) printf(gettext("status: One or more devices could not "
3067 "be opened. Sufficient replicas exist for\n\tthe pool to "
3068 "continue functioning in a degraded state.\n"));
3069 (void) printf(gettext("action: Attach the missing device and "
3070 "online it using 'zpool online'.\n"));
3073 case ZPOOL_STATUS_MISSING_DEV_NR:
3074 (void) printf(gettext("status: One or more devices could not "
3075 "be opened. There are insufficient\n\treplicas for the "
3076 "pool to continue functioning.\n"));
3077 (void) printf(gettext("action: Attach the missing device and "
3078 "online it using 'zpool online'.\n"));
3081 case ZPOOL_STATUS_CORRUPT_LABEL_R:
3082 (void) printf(gettext("status: One or more devices could not "
3083 "be used because the label is missing or\n\tinvalid. "
3084 "Sufficient replicas exist for the pool to continue\n\t"
3085 "functioning in a degraded state.\n"));
3086 (void) printf(gettext("action: Replace the device using "
3087 "'zpool replace'.\n"));
3090 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3091 (void) printf(gettext("status: One or more devices could not "
3092 "be used because the label is missing \n\tor invalid. "
3093 "There are insufficient replicas for the pool to "
3094 "continue\n\tfunctioning.\n"));
3095 (void) printf(gettext("action: Destroy and re-create the pool "
3096 "from a backup source.\n"));
3099 case ZPOOL_STATUS_FAILING_DEV:
3100 (void) printf(gettext("status: One or more devices has "
3101 "experienced an unrecoverable error. An\n\tattempt was "
3102 "made to correct the error. Applications are "
3104 (void) printf(gettext("action: Determine if the device needs "
3105 "to be replaced, and clear the errors\n\tusing "
3106 "'zpool clear' or replace the device with 'zpool "
3110 case ZPOOL_STATUS_OFFLINE_DEV:
3111 (void) printf(gettext("status: One or more devices has "
3112 "been taken offline by the administrator.\n\tSufficient "
3113 "replicas exist for the pool to continue functioning in "
3114 "a\n\tdegraded state.\n"));
3115 (void) printf(gettext("action: Online the device using "
3116 "'zpool online' or replace the device with\n\t'zpool "
3120 case ZPOOL_STATUS_RESILVERING:
3121 (void) printf(gettext("status: One or more devices is "
3122 "currently being resilvered. The pool will\n\tcontinue "
3123 "to function, possibly in a degraded state.\n"));
3124 (void) printf(gettext("action: Wait for the resilver to "
3128 case ZPOOL_STATUS_CORRUPT_DATA:
3129 (void) printf(gettext("status: One or more devices has "
3130 "experienced an error resulting in data\n\tcorruption. "
3131 "Applications may be affected.\n"));
3132 (void) printf(gettext("action: Restore the file in question "
3133 "if possible. Otherwise restore the\n\tentire pool from "
3137 case ZPOOL_STATUS_CORRUPT_POOL:
3138 (void) printf(gettext("status: The pool metadata is corrupted "
3139 "and the pool cannot be opened.\n"));
3140 (void) printf(gettext("action: Destroy and re-create the pool "
3141 "from a backup source.\n"));
3144 case ZPOOL_STATUS_VERSION_OLDER:
3145 (void) printf(gettext("status: The pool is formatted using an "
3146 "older on-disk format. The pool can\n\tstill be used, but "
3147 "some features are unavailable.\n"));
3148 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3149 "upgrade'. Once this is done, the\n\tpool will no longer "
3150 "be accessible on older software versions.\n"));
3153 case ZPOOL_STATUS_VERSION_NEWER:
3154 (void) printf(gettext("status: The pool has been upgraded to a "
3155 "newer, incompatible on-disk version.\n\tThe pool cannot "
3156 "be accessed on this system.\n"));
3157 (void) printf(gettext("action: Access the pool from a system "
3158 "running more recent software, or\n\trestore the pool from "
3162 case ZPOOL_STATUS_FAULTED_DEV_R:
3163 (void) printf(gettext("status: One or more devices are "
3164 "faulted in response to persistent errors.\n\tSufficient "
3165 "replicas exist for the pool to continue functioning "
3166 "in a\n\tdegraded state.\n"));
3167 (void) printf(gettext("action: Replace the faulted device, "
3168 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3171 case ZPOOL_STATUS_FAULTED_DEV_NR:
3172 (void) printf(gettext("status: One or more devices are "
3173 "faulted in response to persistent errors. There are "
3174 "insufficient replicas for the pool to\n\tcontinue "
3176 (void) printf(gettext("action: Destroy and re-create the pool "
3177 "from a backup source. Manually marking the device\n"
3178 "\trepaired using 'zpool clear' may allow some data "
3179 "to be recovered.\n"));
3182 case ZPOOL_STATUS_IO_FAILURE_WAIT:
3183 case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3184 (void) printf(gettext("status: One or more devices are "
3185 "faulted in response to IO failures.\n"));
3186 (void) printf(gettext("action: Make sure the affected devices "
3187 "are connected, then run 'zpool clear'.\n"));
3190 case ZPOOL_STATUS_BAD_LOG:
3191 (void) printf(gettext("status: An intent log record "
3192 "could not be read.\n"
3193 "\tWaiting for adminstrator intervention to fix the "
3194 "faulted pool.\n"));
3195 (void) printf(gettext("action: Either restore the affected "
3196 "device(s) and run 'zpool online',\n"
3197 "\tor ignore the intent log records by running "
3198 "'zpool clear'.\n"));
3203 * The remaining errors can't actually be generated, yet.
3205 assert(reason == ZPOOL_STATUS_OK);
3209 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
3212 if (config != NULL) {
3215 nvlist_t **spares, **l2cache;
3216 uint_t nspares, nl2cache;
3219 (void) printf(gettext(" scrub: "));
3220 print_scrub_status(nvroot);
3222 namewidth = max_width(zhp, nvroot, 0, 0);
3226 (void) printf(gettext("config:\n\n"));
3227 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
3228 "NAME", "STATE", "READ", "WRITE", "CKSUM");
3229 print_status_config(zhp, zpool_get_name(zhp), nvroot,
3230 namewidth, 0, B_FALSE);
3232 if (num_logs(nvroot) > 0)
3233 print_logs(zhp, nvroot, namewidth, B_TRUE);
3234 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3235 &l2cache, &nl2cache) == 0)
3236 print_l2cache(zhp, l2cache, nl2cache, namewidth);
3238 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3239 &spares, &nspares) == 0)
3240 print_spares(zhp, spares, nspares, namewidth);
3242 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3244 nvlist_t *nverrlist = NULL;
3247 * If the approximate error count is small, get a
3248 * precise count by fetching the entire log and
3249 * uniquifying the results.
3251 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3252 zpool_get_errlog(zhp, &nverrlist) == 0) {
3257 while ((elem = nvlist_next_nvpair(nverrlist,
3262 nvlist_free(nverrlist);
3264 (void) printf("\n");
3267 (void) printf(gettext("errors: No known data "
3269 else if (!cbp->cb_verbose)
3270 (void) printf(gettext("errors: %llu data "
3271 "errors, use '-v' for a list\n"),
3272 (u_longlong_t)nerr);
3274 print_error_log(zhp);
3277 (void) printf(gettext("config: The configuration cannot be "
3285 * zpool status [-vx] [pool] ...
3287 * -v Display complete error logs
3288 * -x Display only pools with potential problems
3290 * Describes the health status of all pools or some subset.
3293 zpool_do_status(int argc, char **argv)
3297 status_cbdata_t cb = { 0 };
3300 while ((c = getopt(argc, argv, "vx")) != -1) {
3303 cb.cb_verbose = B_TRUE;
3306 cb.cb_explain = B_TRUE;
3309 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3318 cb.cb_first = B_TRUE;
3321 cb.cb_allpools = B_TRUE;
3323 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3325 if (argc == 0 && cb.cb_count == 0)
3326 (void) printf(gettext("no pools available\n"));
3327 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3328 (void) printf(gettext("all pools are healthy\n"));
3333 typedef struct upgrade_cbdata {
3338 uint64_t cb_version;
3343 upgrade_cb(zpool_handle_t *zhp, void *arg)
3345 upgrade_cbdata_t *cbp = arg;
3350 config = zpool_get_config(zhp, NULL);
3351 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3354 if (!cbp->cb_newer && version < SPA_VERSION) {
3356 if (cbp->cb_first) {
3357 (void) printf(gettext("The following pools are "
3358 "out of date, and can be upgraded. After "
3359 "being\nupgraded, these pools will no "
3360 "longer be accessible by older software "
3362 (void) printf(gettext("VER POOL\n"));
3363 (void) printf(gettext("--- ------------\n"));
3364 cbp->cb_first = B_FALSE;
3367 (void) printf("%2llu %s\n", (u_longlong_t)version,
3368 zpool_get_name(zhp));
3370 cbp->cb_first = B_FALSE;
3371 ret = zpool_upgrade(zhp, cbp->cb_version);
3373 (void) printf(gettext("Successfully upgraded "
3374 "'%s'\n\n"), zpool_get_name(zhp));
3377 } else if (cbp->cb_newer && version > SPA_VERSION) {
3378 assert(!cbp->cb_all);
3380 if (cbp->cb_first) {
3381 (void) printf(gettext("The following pools are "
3382 "formatted using a newer software version and\n"
3383 "cannot be accessed on the current system.\n\n"));
3384 (void) printf(gettext("VER POOL\n"));
3385 (void) printf(gettext("--- ------------\n"));
3386 cbp->cb_first = B_FALSE;
3389 (void) printf("%2llu %s\n", (u_longlong_t)version,
3390 zpool_get_name(zhp));
3399 upgrade_one(zpool_handle_t *zhp, void *data)
3401 upgrade_cbdata_t *cbp = data;
3402 uint64_t cur_version;
3405 if (strcmp("log", zpool_get_name(zhp)) == 0) {
3406 (void) printf(gettext("'log' is now a reserved word\n"
3407 "Pool 'log' must be renamed using export and import"
3412 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3413 if (cur_version > cbp->cb_version) {
3414 (void) printf(gettext("Pool '%s' is already formatted "
3415 "using more current version '%llu'.\n"),
3416 zpool_get_name(zhp), cur_version);
3419 if (cur_version == cbp->cb_version) {
3420 (void) printf(gettext("Pool '%s' is already formatted "
3421 "using the current version.\n"), zpool_get_name(zhp));
3425 ret = zpool_upgrade(zhp, cbp->cb_version);
3428 (void) printf(gettext("Successfully upgraded '%s' "
3429 "from version %llu to version %llu\n\n"),
3430 zpool_get_name(zhp), (u_longlong_t)cur_version,
3431 (u_longlong_t)cbp->cb_version);
3440 * zpool upgrade [-V version] <-a | pool ...>
3442 * With no arguments, display downrev'd ZFS pool available for upgrade.
3443 * Individual pools can be upgraded by specifying the pool, and '-a' will
3444 * upgrade all pools.
3447 zpool_do_upgrade(int argc, char **argv)
3450 upgrade_cbdata_t cb = { 0 };
3452 boolean_t showversions = B_FALSE;
3457 while ((c = getopt(argc, argv, ":avV:")) != -1) {
3463 showversions = B_TRUE;
3466 cb.cb_version = strtoll(optarg, &end, 10);
3467 if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3468 cb.cb_version < SPA_VERSION_1) {
3469 (void) fprintf(stderr,
3470 gettext("invalid version '%s'\n"), optarg);
3475 (void) fprintf(stderr, gettext("missing argument for "
3476 "'%c' option\n"), optopt);
3480 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3491 if (cb.cb_version == 0) {
3492 cb.cb_version = SPA_VERSION;
3493 } else if (!cb.cb_all && argc == 0) {
3494 (void) fprintf(stderr, gettext("-V option is "
3495 "incompatible with other arguments\n"));
3500 if (cb.cb_all || argc != 0) {
3501 (void) fprintf(stderr, gettext("-v option is "
3502 "incompatible with other arguments\n"));
3505 } else if (cb.cb_all) {
3507 (void) fprintf(stderr, gettext("-a option should not "
3508 "be used along with a pool name\n"));
3513 (void) printf(gettext("This system is currently running "
3514 "ZFS pool version %llu.\n\n"), SPA_VERSION);
3515 cb.cb_first = B_TRUE;
3517 (void) printf(gettext("The following versions are "
3519 (void) printf(gettext("VER DESCRIPTION\n"));
3520 (void) printf("--- -----------------------------------------"
3521 "---------------\n");
3522 (void) printf(gettext(" 1 Initial ZFS version\n"));
3523 (void) printf(gettext(" 2 Ditto blocks "
3524 "(replicated metadata)\n"));
3525 (void) printf(gettext(" 3 Hot spares and double parity "
3527 (void) printf(gettext(" 4 zpool history\n"));
3528 (void) printf(gettext(" 5 Compression using the gzip "
3530 (void) printf(gettext(" 6 bootfs pool property\n"));
3531 (void) printf(gettext(" 7 Separate intent log devices\n"));
3532 (void) printf(gettext(" 8 Delegated administration\n"));
3533 (void) printf(gettext(" 9 refquota and refreservation "
3535 (void) printf(gettext(" 10 Cache devices\n"));
3536 (void) printf(gettext(" 11 Improved scrub performance\n"));
3537 (void) printf(gettext(" 12 Snapshot properties\n"));
3538 (void) printf(gettext(" 13 snapused property\n"));
3539 (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
3540 (void) printf(gettext(" 15 user/group space accounting\n"));
3541 (void) printf(gettext(" 16 stmf property support\n"));
3542 (void) printf(gettext("For more information on a particular "
3543 "version, including supported releases, see:\n\n"));
3544 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3546 (void) printf(gettext("Where 'N' is the version number.\n"));
3547 } else if (argc == 0) {
3550 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3551 notfound = cb.cb_first;
3553 if (!cb.cb_all && ret == 0) {
3555 (void) printf("\n");
3556 cb.cb_first = B_TRUE;
3557 cb.cb_newer = B_TRUE;
3558 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3561 (void) printf("\n");
3567 (void) printf(gettext("All pools are formatted "
3568 "using this version.\n"));
3569 else if (!cb.cb_all)
3570 (void) printf(gettext("Use 'zpool upgrade -v' "
3571 "for a list of available versions and "
3572 "their associated\nfeatures.\n"));
3575 ret = for_each_pool(argc, argv, B_FALSE, NULL,
3582 typedef struct hist_cbdata {
3588 char *hist_event_table[LOG_END] = {
3604 "pool property set",
3608 "destroy_begin_sync",
3612 "permission update",
3613 "permission remove",
3614 "permission who remove",
3623 "filesystem version upgrade",
3625 "refreservation set",
3630 * Print out the command history for a specific pool.
3633 get_history_one(zpool_handle_t *zhp, void *data)
3649 char internalstr[MAXPATHLEN];
3650 hist_cbdata_t *cb = (hist_cbdata_t *)data;
3654 cb->first = B_FALSE;
3656 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3658 if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3661 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3662 &records, &numrecords) == 0);
3663 for (i = 0; i < numrecords; i++) {
3664 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3668 /* is it an internal event or a standard event? */
3669 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3671 if (cb->internal == 0)
3674 if (nvlist_lookup_uint64(records[i],
3675 ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3677 verify(nvlist_lookup_uint64(records[i],
3678 ZPOOL_HIST_TXG, &txg) == 0);
3679 verify(nvlist_lookup_string(records[i],
3680 ZPOOL_HIST_INT_STR, &pathstr) == 0);
3681 if (ievent >= LOG_END)
3683 (void) snprintf(internalstr,
3684 sizeof (internalstr),
3685 "[internal %s txg:%lld] %s",
3686 hist_event_table[ievent], txg,
3688 cmdstr = internalstr;
3691 (void) localtime_r(&tsec, &t);
3692 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3693 (void) printf("%s %s", tbuf, cmdstr);
3696 (void) printf("\n");
3699 (void) printf(" [");
3700 if (nvlist_lookup_uint64(records[i],
3701 ZPOOL_HIST_WHO, &who) == 0) {
3702 pwd = getpwuid((uid_t)who);
3704 (void) printf("user %s on",
3707 (void) printf("user %d on",
3710 (void) printf(gettext("no info]\n"));
3713 if (nvlist_lookup_string(records[i],
3714 ZPOOL_HIST_HOST, &hostname) == 0) {
3715 (void) printf(" %s", hostname);
3717 if (nvlist_lookup_string(records[i],
3718 ZPOOL_HIST_ZONE, &zonename) == 0) {
3719 (void) printf(":%s", zonename);
3723 (void) printf("\n");
3725 (void) printf("\n");
3732 * zpool history <pool>
3734 * Displays the history of commands that modified pools.
3739 zpool_do_history(int argc, char **argv)
3741 hist_cbdata_t cbdata = { 0 };
3745 cbdata.first = B_TRUE;
3747 while ((c = getopt(argc, argv, "li")) != -1) {
3753 cbdata.internal = 1;
3756 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3764 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
3767 if (argc == 0 && cbdata.first == B_TRUE) {
3768 (void) printf(gettext("no pools available\n"));
3776 get_callback(zpool_handle_t *zhp, void *data)
3778 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3779 char value[MAXNAMELEN];
3780 zprop_source_t srctype;
3783 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3786 * Skip the special fake placeholder. This will also skip
3787 * over the name property when 'all' is specified.
3789 if (pl->pl_prop == ZPOOL_PROP_NAME &&
3790 pl == cbp->cb_proplist)
3793 if (zpool_get_prop(zhp, pl->pl_prop,
3794 value, sizeof (value), &srctype) != 0)
3797 zprop_print_one_property(zpool_get_name(zhp), cbp,
3798 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3804 zpool_do_get(int argc, char **argv)
3806 zprop_get_cbdata_t cb = { 0 };
3807 zprop_list_t fake_name = { 0 };
3813 cb.cb_first = B_TRUE;
3814 cb.cb_sources = ZPROP_SRC_ALL;
3815 cb.cb_columns[0] = GET_COL_NAME;
3816 cb.cb_columns[1] = GET_COL_PROPERTY;
3817 cb.cb_columns[2] = GET_COL_VALUE;
3818 cb.cb_columns[3] = GET_COL_SOURCE;
3819 cb.cb_type = ZFS_TYPE_POOL;
3821 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
3822 ZFS_TYPE_POOL) != 0)
3825 if (cb.cb_proplist != NULL) {
3826 fake_name.pl_prop = ZPOOL_PROP_NAME;
3827 fake_name.pl_width = strlen(gettext("NAME"));
3828 fake_name.pl_next = cb.cb_proplist;
3829 cb.cb_proplist = &fake_name;
3832 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3835 if (cb.cb_proplist == &fake_name)
3836 zprop_free_list(fake_name.pl_next);
3838 zprop_free_list(cb.cb_proplist);
3843 typedef struct set_cbdata {
3846 boolean_t cb_any_successful;
3850 set_callback(zpool_handle_t *zhp, void *data)
3853 set_cbdata_t *cb = (set_cbdata_t *)data;
3855 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3858 cb->cb_any_successful = B_TRUE;
3864 zpool_do_set(int argc, char **argv)
3866 set_cbdata_t cb = { 0 };
3869 if (argc > 1 && argv[1][0] == '-') {
3870 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3876 (void) fprintf(stderr, gettext("missing property=value "
3882 (void) fprintf(stderr, gettext("missing pool name\n"));
3887 (void) fprintf(stderr, gettext("too many pool names\n"));
3891 cb.cb_propname = argv[1];
3892 cb.cb_value = strchr(cb.cb_propname, '=');
3893 if (cb.cb_value == NULL) {
3894 (void) fprintf(stderr, gettext("missing value in "
3895 "property=value argument\n"));
3899 *(cb.cb_value) = '\0';
3902 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3909 find_command_idx(char *command, int *idx)
3913 for (i = 0; i < NCOMMAND; i++) {
3914 if (command_table[i].name == NULL)
3917 if (strcmp(command, command_table[i].name) == 0) {
3926 main(int argc, char **argv)
3932 (void) setlocale(LC_ALL, "");
3933 (void) textdomain(TEXT_DOMAIN);
3935 if ((g_zfs = libzfs_init()) == NULL) {
3936 (void) fprintf(stderr, gettext("internal error: failed to "
3937 "initialize ZFS library\n"));
3941 libzfs_print_on_error(g_zfs, B_TRUE);
3946 * Make sure the user has specified some command.
3949 (void) fprintf(stderr, gettext("missing command\n"));
3958 if (strcmp(cmdname, "-?") == 0)
3961 zpool_set_history_str("zpool", argc, argv, history_str);
3962 verify(zpool_stage_history(g_zfs, history_str) == 0);
3965 * Run the appropriate command.
3967 if (find_command_idx(cmdname, &i) == 0) {
3968 current_command = &command_table[i];
3969 ret = command_table[i].func(argc - 1, argv + 1);
3970 } else if (strchr(cmdname, '=')) {
3971 verify(find_command_idx("set", &i) == 0);
3972 current_command = &command_table[i];
3973 ret = command_table[i].func(argc, argv);
3974 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3976 * 'freeze' is a vile debugging abomination, so we treat
3980 int fd = open(ZFS_DEV, O_RDWR);
3981 (void) strcpy((void *)buf, argv[2]);
3982 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3984 (void) fprintf(stderr, gettext("unrecognized "
3985 "command '%s'\n"), cmdname);
3992 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3993 * for the purposes of running ::findleaks.
3995 if (getenv("ZFS_ABORT") != NULL) {
3996 (void) printf("dumping core by request\n");