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 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
46 #include <sys/fs/zfs.h>
52 #include "zpool_util.h"
54 static int zpool_do_create(int, char **);
55 static int zpool_do_destroy(int, char **);
57 static int zpool_do_add(int, char **);
58 static int zpool_do_remove(int, char **);
60 static int zpool_do_list(int, char **);
61 static int zpool_do_iostat(int, char **);
62 static int zpool_do_status(int, char **);
64 static int zpool_do_online(int, char **);
65 static int zpool_do_offline(int, char **);
66 static int zpool_do_clear(int, char **);
68 static int zpool_do_attach(int, char **);
69 static int zpool_do_detach(int, char **);
70 static int zpool_do_replace(int, char **);
72 static int zpool_do_scrub(int, char **);
74 static int zpool_do_import(int, char **);
75 static int zpool_do_export(int, char **);
77 static int zpool_do_upgrade(int, char **);
79 static int zpool_do_history(int, char **);
81 static int zpool_do_get(int, char **);
82 static int zpool_do_set(int, char **);
85 * These libumem hooks provide a reasonable set of defaults for the allocator's
86 * debugging facilities.
89 _umem_debug_init(void)
91 return ("default,verbose"); /* $UMEM_DEBUG setting */
95 _umem_logging_init(void)
97 return ("fail,contents"); /* $UMEM_LOGGING setting */
124 typedef struct zpool_command {
126 int (*func)(int, char **);
131 * Master command table. Each ZFS command has a name, associated function, and
132 * usage message. The usage messages need to be internationalized, so we have
133 * to have a function to return the usage message based on a command index.
135 * These commands are organized according to how they are displayed in the usage
136 * message. An empty command (one with a NULL name) indicates an empty line in
137 * the generic usage message.
139 static zpool_command_t command_table[] = {
140 { "create", zpool_do_create, HELP_CREATE },
141 { "destroy", zpool_do_destroy, HELP_DESTROY },
143 { "add", zpool_do_add, HELP_ADD },
144 { "remove", zpool_do_remove, HELP_REMOVE },
146 { "list", zpool_do_list, HELP_LIST },
147 { "iostat", zpool_do_iostat, HELP_IOSTAT },
148 { "status", zpool_do_status, HELP_STATUS },
150 { "online", zpool_do_online, HELP_ONLINE },
151 { "offline", zpool_do_offline, HELP_OFFLINE },
152 { "clear", zpool_do_clear, HELP_CLEAR },
154 { "attach", zpool_do_attach, HELP_ATTACH },
155 { "detach", zpool_do_detach, HELP_DETACH },
156 { "replace", zpool_do_replace, HELP_REPLACE },
158 { "scrub", zpool_do_scrub, HELP_SCRUB },
160 { "import", zpool_do_import, HELP_IMPORT },
161 { "export", zpool_do_export, HELP_EXPORT },
162 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
164 { "history", zpool_do_history, HELP_HISTORY },
165 { "get", zpool_do_get, HELP_GET },
166 { "set", zpool_do_set, HELP_SET },
169 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
171 zpool_command_t *current_command;
174 get_usage(zpool_help_t idx) {
177 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
179 return (gettext("\tattach [-f] <pool> <device> "
182 return (gettext("\tclear <pool> [device]\n"));
184 return (gettext("\tcreate [-fn] [-R root] [-m mountpoint] "
185 "<pool> <vdev> ...\n"));
187 return (gettext("\tdestroy [-f] <pool>\n"));
189 return (gettext("\tdetach <pool> <device>\n"));
191 return (gettext("\texport [-f] <pool> ...\n"));
193 return (gettext("\thistory [<pool>]\n"));
195 return (gettext("\timport [-d dir] [-D]\n"
196 "\timport [-d dir] [-D] [-f] [-o opts] [-R root] -a\n"
197 "\timport [-d dir] [-D] [-f] [-o opts] [-R root ]"
198 " <pool | id> [newpool]\n"));
200 return (gettext("\tiostat [-v] [pool] ... [interval "
203 return (gettext("\tlist [-H] [-o field[,field]*] "
206 return (gettext("\toffline [-t] <pool> <device> ...\n"));
208 return (gettext("\tonline <pool> <device> ...\n"));
210 return (gettext("\treplace [-f] <pool> <device> "
213 return (gettext("\tremove <pool> <device>\n"));
215 return (gettext("\tscrub [-s] <pool> ...\n"));
217 return (gettext("\tstatus [-vx] [pool] ...\n"));
219 return (gettext("\tupgrade\n"
221 "\tupgrade <-a | pool>\n"));
223 return (gettext("\tget <all | property[,property]...> "
226 return (gettext("\tset <property=value> <pool> \n"));
234 * Fields available for 'zpool list'.
240 ZPOOL_FIELD_AVAILABLE,
241 ZPOOL_FIELD_CAPACITY,
246 #define MAX_FIELDS 10
248 typedef struct column_def {
249 const char *cd_title;
257 static column_def_t column_table[] = {
258 { "NAME", 20, left_justify },
259 { "SIZE", 6, right_justify },
260 { "USED", 6, right_justify },
261 { "AVAIL", 6, right_justify },
262 { "CAP", 5, right_justify },
263 { "HEALTH", 9, left_justify },
264 { "ALTROOT", 15, left_justify }
267 static char *column_subopts[] = {
279 * Callback routine that will print out a pool property value.
282 print_prop_cb(zpool_prop_t prop, void *cb)
286 (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
288 if (zpool_prop_values(prop) == NULL)
289 (void) fprintf(fp, "-\n");
291 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
293 return (ZFS_PROP_CONT);
297 * Display usage message. If we're inside a command, display only the usage for
298 * that command. Otherwise, iterate over the entire command table and display
299 * a complete usage message.
302 usage(boolean_t requested)
305 FILE *fp = requested ? stdout : stderr;
307 if (current_command == NULL) {
310 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
312 gettext("where 'command' is one of the following:\n\n"));
314 for (i = 0; i < NCOMMAND; i++) {
315 if (command_table[i].name == NULL)
316 (void) fprintf(fp, "\n");
318 (void) fprintf(fp, "%s",
319 get_usage(command_table[i].usage));
322 (void) fprintf(fp, gettext("usage:\n"));
323 (void) fprintf(fp, "%s", get_usage(current_command->usage));
325 if (strcmp(current_command->name, "list") == 0) {
326 (void) fprintf(fp, gettext("\nwhere 'field' is one "
327 "of the following:\n\n"));
329 for (i = 0; column_subopts[i] != NULL; i++)
330 (void) fprintf(fp, "\t%s\n", column_subopts[i]);
334 if (current_command != NULL &&
335 ((strcmp(current_command->name, "set") == 0) ||
336 (strcmp(current_command->name, "get") == 0))) {
339 gettext("\nthe following properties are supported:\n"));
341 (void) fprintf(fp, "\n\t%-13s %s\n\n",
342 "PROPERTY", "VALUES");
344 /* Iterate over all properties */
345 (void) zpool_prop_iter(print_prop_cb, fp, B_FALSE);
349 * See comments at end of main().
351 if (getenv("ZFS_ABORT") != NULL) {
352 (void) printf("dumping core by request\n");
356 exit(requested ? 0 : 2);
360 state_to_health(int vs_state)
363 case VDEV_STATE_CLOSED:
364 case VDEV_STATE_CANT_OPEN:
365 case VDEV_STATE_OFFLINE:
366 return (dgettext(TEXT_DOMAIN, "FAULTED"));
367 case VDEV_STATE_DEGRADED:
368 return (dgettext(TEXT_DOMAIN, "DEGRADED"));
369 case VDEV_STATE_HEALTHY:
370 return (dgettext(TEXT_DOMAIN, "ONLINE"));
373 return (dgettext(TEXT_DOMAIN, "UNKNOWN"));
377 state_to_name(vdev_stat_t *vs)
379 switch (vs->vs_state) {
380 case VDEV_STATE_CLOSED:
381 case VDEV_STATE_CANT_OPEN:
382 if (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)
383 return (gettext("FAULTED"));
385 return (gettext("UNAVAIL"));
386 case VDEV_STATE_OFFLINE:
387 return (gettext("OFFLINE"));
388 case VDEV_STATE_DEGRADED:
389 return (gettext("DEGRADED"));
390 case VDEV_STATE_HEALTHY:
391 return (gettext("ONLINE"));
394 return (gettext("UNKNOWN"));
398 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent)
405 (void) printf("\t%*s%s\n", indent, "", name);
407 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
408 &child, &children) != 0)
411 for (c = 0; c < children; c++) {
412 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
413 print_vdev_tree(zhp, vname, child[c], indent + 2);
419 * zpool add [-fn] <pool> <vdev> ...
421 * -f Force addition of devices, even if they appear in use
422 * -n Do not add the devices, but display the resulting layout if
423 * they were to be added.
425 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
426 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
430 zpool_do_add(int argc, char **argv)
432 boolean_t force = B_FALSE;
433 boolean_t dryrun = B_FALSE;
442 while ((c = getopt(argc, argv, "fn")) != -1) {
451 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
460 /* get pool name and check number of arguments */
462 (void) fprintf(stderr, gettext("missing pool name argument\n"));
466 (void) fprintf(stderr, gettext("missing vdev specification\n"));
475 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
478 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
479 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
485 /* pass off to get_vdev_spec for processing */
486 nvroot = make_root_vdev(config, force, !force, B_FALSE, argc, argv);
487 if (nvroot == NULL) {
493 nvlist_t *poolnvroot;
495 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
498 (void) printf(gettext("would update '%s' to the following "
499 "configuration:\n"), zpool_get_name(zhp));
501 print_vdev_tree(zhp, poolname, poolnvroot, 0);
502 print_vdev_tree(zhp, NULL, nvroot, 0);
506 ret = (zpool_add(zhp, nvroot) != 0);
508 zpool_log_history(g_zfs, argc + 1 + optind,
509 argv - 1 - optind, poolname, B_TRUE, B_FALSE);
520 * zpool remove <pool> <vdev>
522 * Removes the given vdev from the pool. Currently, this only supports removing
523 * spares from the pool. Eventually, we'll want to support removing leaf vdevs
524 * (as an alias for 'detach') as well as toplevel vdevs.
527 zpool_do_remove(int argc, char **argv)
536 /* get pool name and check number of arguments */
538 (void) fprintf(stderr, gettext("missing pool name argument\n"));
542 (void) fprintf(stderr, gettext("missing device\n"));
548 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
551 ret = (zpool_vdev_remove(zhp, argv[1]) != 0);
553 zpool_log_history(g_zfs, ++argc, --argv, poolname, B_TRUE,
561 * zpool create [-fn] [-R root] [-m mountpoint] <pool> <dev> ...
563 * -f Force creation, even if devices appear in use
564 * -n Do not create the pool, but display the resulting layout if it
565 * were to be created.
566 * -R Create a pool under an alternate root
567 * -m Set default mountpoint for the root dataset. By default it's
570 * Creates the named pool according to the given vdev specification. The
571 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
572 * we get the nvlist back from get_vdev_spec(), we either print out the contents
573 * (if '-n' was specified), or pass it to libzfs to do the creation.
576 zpool_do_create(int argc, char **argv)
578 boolean_t force = B_FALSE;
579 boolean_t dryrun = B_FALSE;
584 char *altroot = NULL;
585 char *mountpoint = NULL;
590 while ((c = getopt(argc, argv, ":fnR:m:")) != -1) {
605 (void) fprintf(stderr, gettext("missing argument for "
606 "'%c' option\n"), optopt);
610 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
619 /* get pool name and check number of arguments */
621 (void) fprintf(stderr, gettext("missing pool name argument\n"));
625 (void) fprintf(stderr, gettext("missing vdev specification\n"));
632 * As a special case, check for use of '/' in the name, and direct the
633 * user to use 'zfs create' instead.
635 if (strchr(poolname, '/') != NULL) {
636 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
637 "character '/' in pool name\n"), poolname);
638 (void) fprintf(stderr, gettext("use 'zfs create' to "
639 "create a dataset\n"));
643 /* pass off to get_vdev_spec for bulk processing */
644 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1,
649 /* make_root_vdev() allows 0 toplevel children if there are spares */
650 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
651 &child, &children) == 0);
653 (void) fprintf(stderr, gettext("invalid vdev "
654 "specification: at least one toplevel vdev must be "
660 if (altroot != NULL && altroot[0] != '/') {
661 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
662 "must be an absolute path\n"), altroot);
668 * Check the validity of the mountpoint and direct the user to use the
669 * '-m' mountpoint option if it looks like its in use.
671 if (mountpoint == NULL ||
672 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
673 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
674 char buf[MAXPATHLEN];
675 struct stat64 statbuf;
677 if (mountpoint && mountpoint[0] != '/') {
678 (void) fprintf(stderr, gettext("invalid mountpoint "
679 "'%s': must be an absolute path, 'legacy', or "
680 "'none'\n"), mountpoint);
685 if (mountpoint == NULL) {
687 (void) snprintf(buf, sizeof (buf), "%s/%s",
690 (void) snprintf(buf, sizeof (buf), "/%s",
694 (void) snprintf(buf, sizeof (buf), "%s%s",
695 altroot, mountpoint);
697 (void) snprintf(buf, sizeof (buf), "%s",
701 if (stat64(buf, &statbuf) == 0 &&
702 statbuf.st_nlink != 2) {
703 if (mountpoint == NULL)
704 (void) fprintf(stderr, gettext("default "
705 "mountpoint '%s' exists and is not "
708 (void) fprintf(stderr, gettext("mountpoint "
709 "'%s' exists and is not empty\n"), buf);
710 (void) fprintf(stderr, gettext("use '-m' "
711 "option to provide a different default\n"));
720 * For a dry run invocation, print out a basic message and run
721 * through all the vdevs in the list and print out in an
722 * appropriate hierarchy.
724 (void) printf(gettext("would create '%s' with the "
725 "following layout:\n\n"), poolname);
727 print_vdev_tree(NULL, poolname, nvroot, 0);
733 * Hand off to libzfs.
735 if (zpool_create(g_zfs, poolname, nvroot, altroot) == 0) {
736 zfs_handle_t *pool = zfs_open(g_zfs, poolname,
737 ZFS_TYPE_FILESYSTEM);
739 if (mountpoint != NULL)
740 verify(zfs_prop_set(pool,
742 ZFS_PROP_MOUNTPOINT),
744 if (zfs_mount(pool, NULL, 0) == 0)
745 ret = zfs_share_nfs(pool);
748 zpool_log_history(g_zfs, argc + optind, argv - optind,
749 poolname, B_TRUE, B_TRUE);
750 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
751 (void) fprintf(stderr, gettext("pool name may have "
762 * zpool destroy <pool>
764 * -f Forcefully unmount any datasets
766 * Destroy the given pool. Automatically unmounts any datasets in the pool.
769 zpool_do_destroy(int argc, char **argv)
771 boolean_t force = B_FALSE;
778 while ((c = getopt(argc, argv, "f")) != -1) {
784 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
793 /* check arguments */
795 (void) fprintf(stderr, gettext("missing pool argument\n"));
799 (void) fprintf(stderr, gettext("too many arguments\n"));
805 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
807 * As a special case, check for use of '/' in the name, and
808 * direct the user to use 'zfs destroy' instead.
810 if (strchr(pool, '/') != NULL)
811 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
812 "destroy a dataset\n"));
816 if (zpool_disable_datasets(zhp, force) != 0) {
817 (void) fprintf(stderr, gettext("could not destroy '%s': "
818 "could not unmount datasets\n"), zpool_get_name(zhp));
822 zpool_log_history(g_zfs, argc + optind, argv - optind, pool, B_TRUE,
825 ret = (zpool_destroy(zhp) != 0);
833 * zpool export [-f] <pool> ...
835 * -f Forcefully unmount datasets
837 * Export the given pools. By default, the command will attempt to cleanly
838 * unmount any active datasets within the pool. If the '-f' flag is specified,
839 * then the datasets will be forcefully unmounted.
842 zpool_do_export(int argc, char **argv)
844 boolean_t force = B_FALSE;
851 while ((c = getopt(argc, argv, "f")) != -1) {
857 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
866 /* check arguments */
868 (void) fprintf(stderr, gettext("missing pool argument\n"));
873 for (i = 0; i < argc; i++) {
874 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
879 if (zpool_disable_datasets(zhp, force) != 0) {
885 zpool_log_history(g_zfs, argc + optind, argv - optind, argv[i],
888 if (zpool_export(zhp) != 0)
898 * Given a vdev configuration, determine the maximum width needed for the device
902 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
904 char *name = zpool_vdev_name(g_zfs, zhp, nv);
909 if (strlen(name) + depth > max)
910 max = strlen(name) + depth;
914 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
915 &child, &children) == 0) {
916 for (c = 0; c < children; c++)
917 if ((ret = max_width(zhp, child[c], depth + 2,
922 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
923 &child, &children) == 0) {
924 for (c = 0; c < children; c++)
925 if ((ret = max_width(zhp, child[c], depth + 2,
936 * Print the configuration of an exported pool. Iterate over all vdevs in the
937 * pool, printing out the name and status for each one.
940 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
947 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
948 if (strcmp(type, VDEV_TYPE_MISSING) == 0)
951 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
952 (uint64_t **)&vs, &c) == 0);
954 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
956 if (vs->vs_aux != 0) {
957 (void) printf(" %-8s ", state_to_name(vs));
959 switch (vs->vs_aux) {
960 case VDEV_AUX_OPEN_FAILED:
961 (void) printf(gettext("cannot open"));
964 case VDEV_AUX_BAD_GUID_SUM:
965 (void) printf(gettext("missing device"));
968 case VDEV_AUX_NO_REPLICAS:
969 (void) printf(gettext("insufficient replicas"));
972 case VDEV_AUX_VERSION_NEWER:
973 (void) printf(gettext("newer version"));
977 (void) printf(gettext("corrupted data"));
981 (void) printf(" %s", state_to_name(vs));
985 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
986 &child, &children) != 0)
989 for (c = 0; c < children; c++) {
990 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
991 print_import_config(vname, child[c],
992 namewidth, depth + 2);
996 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
997 &child, &children) != 0)
1000 (void) printf(gettext("\tspares\n"));
1001 for (c = 0; c < children; c++) {
1002 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1003 (void) printf("\t %s\n", vname);
1009 * Display the status for the given pool.
1012 show_import(nvlist_t *config)
1014 uint64_t pool_state;
1025 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1027 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1029 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1031 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1034 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
1035 (uint64_t **)&vs, &vsc) == 0);
1036 health = state_to_health(vs->vs_state);
1038 reason = zpool_import_status(config, &msgid);
1040 (void) printf(gettext(" pool: %s\n"), name);
1041 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
1042 (void) printf(gettext(" state: %s"), health);
1043 if (pool_state == POOL_STATE_DESTROYED)
1044 (void) printf(gettext(" (DESTROYED)"));
1045 (void) printf("\n");
1048 case ZPOOL_STATUS_MISSING_DEV_R:
1049 case ZPOOL_STATUS_MISSING_DEV_NR:
1050 case ZPOOL_STATUS_BAD_GUID_SUM:
1051 (void) printf(gettext("status: One or more devices are missing "
1052 "from the system.\n"));
1055 case ZPOOL_STATUS_CORRUPT_LABEL_R:
1056 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1057 (void) printf(gettext("status: One or more devices contains "
1058 "corrupted data.\n"));
1061 case ZPOOL_STATUS_CORRUPT_DATA:
1062 (void) printf(gettext("status: The pool data is corrupted.\n"));
1065 case ZPOOL_STATUS_OFFLINE_DEV:
1066 (void) printf(gettext("status: One or more devices "
1067 "are offlined.\n"));
1070 case ZPOOL_STATUS_CORRUPT_POOL:
1071 (void) printf(gettext("status: The pool metadata is "
1075 case ZPOOL_STATUS_VERSION_OLDER:
1076 (void) printf(gettext("status: The pool is formatted using an "
1077 "older on-disk version.\n"));
1080 case ZPOOL_STATUS_VERSION_NEWER:
1081 (void) printf(gettext("status: The pool is formatted using an "
1082 "incompatible version.\n"));
1085 case ZPOOL_STATUS_HOSTID_MISMATCH:
1086 (void) printf(gettext("status: The pool was last accessed by "
1087 "another system.\n"));
1091 * No other status can be seen when importing pools.
1093 assert(reason == ZPOOL_STATUS_OK);
1097 * Print out an action according to the overall state of the pool.
1099 if (vs->vs_state == VDEV_STATE_HEALTHY) {
1100 if (reason == ZPOOL_STATUS_VERSION_OLDER)
1101 (void) printf(gettext("action: The pool can be "
1102 "imported using its name or numeric identifier, "
1103 "though\n\tsome features will not be available "
1104 "without an explicit 'zpool upgrade'.\n"));
1105 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1106 (void) printf(gettext("action: The pool can be "
1107 "imported using its name or numeric "
1108 "identifier and\n\tthe '-f' flag.\n"));
1110 (void) printf(gettext("action: The pool can be "
1111 "imported using its name or numeric "
1113 } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1114 (void) printf(gettext("action: The pool can be imported "
1115 "despite missing or damaged devices. The\n\tfault "
1116 "tolerance of the pool may be compromised if imported.\n"));
1119 case ZPOOL_STATUS_VERSION_NEWER:
1120 (void) printf(gettext("action: The pool cannot be "
1121 "imported. Access the pool on a system running "
1122 "newer\n\tsoftware, or recreate the pool from "
1125 case ZPOOL_STATUS_MISSING_DEV_R:
1126 case ZPOOL_STATUS_MISSING_DEV_NR:
1127 case ZPOOL_STATUS_BAD_GUID_SUM:
1128 (void) printf(gettext("action: The pool cannot be "
1129 "imported. Attach the missing\n\tdevices and try "
1133 (void) printf(gettext("action: The pool cannot be "
1134 "imported due to damaged devices or data.\n"));
1139 * If the state is "closed" or "can't open", and the aux state
1140 * is "corrupt data":
1142 if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1143 (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1144 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1145 if (pool_state == POOL_STATE_DESTROYED)
1146 (void) printf(gettext("\tThe pool was destroyed, "
1147 "but can be imported using the '-Df' flags.\n"));
1148 else if (pool_state != POOL_STATE_EXPORTED)
1149 (void) printf(gettext("\tThe pool may be active on "
1150 "on another system, but can be imported using\n\t"
1151 "the '-f' flag.\n"));
1155 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
1158 (void) printf(gettext("config:\n\n"));
1160 namewidth = max_width(NULL, nvroot, 0, 0);
1163 print_import_config(name, nvroot, namewidth, 0);
1165 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1166 (void) printf(gettext("\n\tAdditional devices are known to "
1167 "be part of this pool, though their\n\texact "
1168 "configuration cannot be determined.\n"));
1173 * Perform the import for the given configuration. This passes the heavy
1174 * lifting off to zpool_import(), and then mounts the datasets contained within
1178 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1179 const char *altroot, int force, int argc, char **argv)
1181 zpool_handle_t *zhp;
1186 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1189 verify(nvlist_lookup_uint64(config,
1190 ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1191 verify(nvlist_lookup_uint64(config,
1192 ZPOOL_CONFIG_VERSION, &version) == 0);
1193 if (version > ZFS_VERSION) {
1194 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1195 "is formatted using a newer ZFS version\n"), name);
1197 } else if (state != POOL_STATE_EXPORTED && !force) {
1200 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1202 if ((unsigned long)hostid != gethostid()) {
1207 verify(nvlist_lookup_string(config,
1208 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1209 verify(nvlist_lookup_uint64(config,
1210 ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0);
1212 (void) fprintf(stderr, gettext("cannot import "
1213 "'%s': pool may be in use from other "
1214 "system, it was last accessed by %s "
1215 "(hostid: 0x%lx) on %s"), name, hostname,
1216 (unsigned long)hostid,
1217 asctime(localtime(&t)));
1218 (void) fprintf(stderr, gettext("use '-f' to "
1219 "import anyway\n"));
1223 (void) fprintf(stderr, gettext("cannot import '%s': "
1224 "pool may be in use from other system\n"), name);
1225 (void) fprintf(stderr, gettext("use '-f' to import "
1231 if (zpool_import(g_zfs, config, newname, altroot) != 0)
1234 if (newname != NULL)
1235 name = (char *)newname;
1237 zpool_log_history(g_zfs, argc, argv, name, B_TRUE, B_FALSE);
1239 verify((zhp = zpool_open(g_zfs, name)) != NULL);
1241 if (zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1251 * zpool import [-d dir] [-D]
1252 * import [-R root] [-D] [-d dir] [-f] -a
1253 * import [-R root] [-D] [-d dir] [-f] <pool | id> [newpool]
1255 * -d Scan in a specific directory, other than /dev/dsk. More than
1256 * one directory can be specified using multiple '-d' options.
1258 * -D Scan for previously destroyed pools or import all or only
1259 * specified destroyed pools.
1261 * -R Temporarily import the pool, with all mountpoints relative to
1262 * the given root. The pool will remain exported when the machine
1265 * -f Force import, even if it appears that the pool is active.
1267 * -a Import all pools found.
1269 * The import command scans for pools to import, and import pools based on pool
1270 * name and GUID. The pool can also be renamed as part of the import process.
1273 zpool_do_import(int argc, char **argv)
1275 char **searchdirs = NULL;
1280 boolean_t do_all = B_FALSE;
1281 boolean_t do_destroyed = B_FALSE;
1282 char *altroot = NULL;
1283 char *mntopts = NULL;
1284 boolean_t do_force = B_FALSE;
1287 uint64_t searchguid;
1289 nvlist_t *found_config;
1291 uint64_t pool_state;
1294 while ((c = getopt(argc, argv, ":Dfd:R:ao:")) != -1) {
1300 if (searchdirs == NULL) {
1301 searchdirs = safe_malloc(sizeof (char *));
1303 char **tmp = safe_malloc((nsearch + 1) *
1305 bcopy(searchdirs, tmp, nsearch *
1310 searchdirs[nsearch++] = optarg;
1313 do_destroyed = B_TRUE;
1325 (void) fprintf(stderr, gettext("missing argument for "
1326 "'%c' option\n"), optopt);
1330 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1339 if (searchdirs == NULL) {
1340 searchdirs = safe_malloc(sizeof (char *));
1341 searchdirs[0] = "/dev";
1345 /* check argument count */
1348 (void) fprintf(stderr, gettext("too many arguments\n"));
1353 (void) fprintf(stderr, gettext("too many arguments\n"));
1358 * Check for the SYS_CONFIG privilege. We do this explicitly
1359 * here because otherwise any attempt to discover pools will
1362 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1363 (void) fprintf(stderr, gettext("cannot "
1364 "discover pools: permission denied\n"));
1370 if ((pools = zpool_find_import(g_zfs, nsearch, searchdirs)) == NULL) {
1376 * We now have a list of all available pools in the given directories.
1377 * Depending on the arguments given, we do one of the following:
1379 * <none> Iterate through all pools and display information about
1382 * -a Iterate through all pools and try to import each one.
1384 * <id> Find the pool that corresponds to the given GUID/pool
1385 * name and import that one.
1387 * -D Above options applies only to destroyed pools.
1393 searchguid = strtoull(argv[0], &endptr, 10);
1394 if (errno != 0 || *endptr != '\0')
1395 searchname = argv[0];
1398 found_config = NULL;
1404 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1406 verify(nvpair_value_nvlist(elem, &config) == 0);
1408 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1410 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1412 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1419 (void) printf("\n");
1422 err |= do_import(config, NULL, mntopts,
1423 altroot, do_force, argc + optind,
1426 show_import(config);
1427 } else if (searchname != NULL) {
1431 * We are searching for a pool based on name.
1433 verify(nvlist_lookup_string(config,
1434 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1436 if (strcmp(name, searchname) == 0) {
1437 if (found_config != NULL) {
1438 (void) fprintf(stderr, gettext(
1439 "cannot import '%s': more than "
1440 "one matching pool\n"), searchname);
1441 (void) fprintf(stderr, gettext(
1442 "import by numeric ID instead\n"));
1445 found_config = config;
1451 * Search for a pool by guid.
1453 verify(nvlist_lookup_uint64(config,
1454 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1456 if (guid == searchguid)
1457 found_config = config;
1462 * If we were searching for a specific pool, verify that we found a
1463 * pool, and then do the import.
1465 if (argc != 0 && err == 0) {
1466 if (found_config == NULL) {
1467 (void) fprintf(stderr, gettext("cannot import '%s': "
1468 "no such pool available\n"), argv[0]);
1471 err |= do_import(found_config, argc == 1 ? NULL :
1472 argv[1], mntopts, altroot, do_force, argc + optind,
1478 * If we were just looking for pools, report an error if none were
1481 if (argc == 0 && first)
1482 (void) fprintf(stderr,
1483 gettext("no pools available to import\n"));
1488 return (err ? 1 : 0);
1491 typedef struct iostat_cbdata {
1492 zpool_list_t *cb_list;
1499 print_iostat_separator(iostat_cbdata_t *cb)
1503 for (i = 0; i < cb->cb_namewidth; i++)
1505 (void) printf(" ----- ----- ----- ----- ----- -----\n");
1509 print_iostat_header(iostat_cbdata_t *cb)
1511 (void) printf("%*s capacity operations bandwidth\n",
1512 cb->cb_namewidth, "");
1513 (void) printf("%-*s used avail read write read write\n",
1514 cb->cb_namewidth, "pool");
1515 print_iostat_separator(cb);
1519 * Display a single statistic.
1522 print_one_stat(uint64_t value)
1526 zfs_nicenum(value, buf, sizeof (buf));
1527 (void) printf(" %5s", buf);
1531 * Print out all the statistics for the given vdev. This can either be the
1532 * toplevel configuration, or called recursively. If 'name' is NULL, then this
1533 * is a verbose output, and we don't want to display the toplevel pool stats.
1536 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1537 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1539 nvlist_t **oldchild, **newchild;
1541 vdev_stat_t *oldvs, *newvs;
1542 vdev_stat_t zerovs = { 0 };
1547 if (oldnv != NULL) {
1548 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1549 (uint64_t **)&oldvs, &c) == 0);
1554 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1555 (uint64_t **)&newvs, &c) == 0);
1557 if (strlen(name) + depth > cb->cb_namewidth)
1558 (void) printf("%*s%s", depth, "", name);
1560 (void) printf("%*s%s%*s", depth, "", name,
1561 (int)(cb->cb_namewidth - strlen(name) - depth), "");
1563 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1568 scale = (double)NANOSEC / tdelta;
1570 /* only toplevel vdevs have capacity stats */
1571 if (newvs->vs_space == 0) {
1572 (void) printf(" - -");
1574 print_one_stat(newvs->vs_alloc);
1575 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1578 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1579 oldvs->vs_ops[ZIO_TYPE_READ])));
1581 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1582 oldvs->vs_ops[ZIO_TYPE_WRITE])));
1584 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1585 oldvs->vs_bytes[ZIO_TYPE_READ])));
1587 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1588 oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1590 (void) printf("\n");
1592 if (!cb->cb_verbose)
1595 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1596 &newchild, &children) != 0)
1599 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1600 &oldchild, &c) != 0)
1603 for (c = 0; c < children; c++) {
1604 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1605 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1606 newchild[c], cb, depth + 2);
1612 refresh_iostat(zpool_handle_t *zhp, void *data)
1614 iostat_cbdata_t *cb = data;
1618 * If the pool has disappeared, remove it from the list and continue.
1620 if (zpool_refresh_stats(zhp, &missing) != 0)
1624 pool_list_remove(cb->cb_list, zhp);
1630 * Callback to print out the iostats for the given pool.
1633 print_iostat(zpool_handle_t *zhp, void *data)
1635 iostat_cbdata_t *cb = data;
1636 nvlist_t *oldconfig, *newconfig;
1637 nvlist_t *oldnvroot, *newnvroot;
1639 newconfig = zpool_get_config(zhp, &oldconfig);
1641 if (cb->cb_iteration == 1)
1644 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1647 if (oldconfig == NULL)
1650 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1654 * Print out the statistics for the pool.
1656 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1659 print_iostat_separator(cb);
1665 get_namewidth(zpool_handle_t *zhp, void *data)
1667 iostat_cbdata_t *cb = data;
1668 nvlist_t *config, *nvroot;
1670 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1671 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1673 if (!cb->cb_verbose)
1674 cb->cb_namewidth = strlen(zpool_get_name(zhp));
1676 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1680 * The width must fall into the range [10,38]. The upper limit is the
1681 * maximum we can have and still fit in 80 columns.
1683 if (cb->cb_namewidth < 10)
1684 cb->cb_namewidth = 10;
1685 if (cb->cb_namewidth > 38)
1686 cb->cb_namewidth = 38;
1692 * zpool iostat [-v] [pool] ... [interval [count]]
1694 * -v Display statistics for individual vdevs
1696 * This command can be tricky because we want to be able to deal with pool
1697 * creation/destruction as well as vdev configuration changes. The bulk of this
1698 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
1699 * on pool_list_update() to detect the addition of new pools. Configuration
1700 * changes are all handled within libzfs.
1703 zpool_do_iostat(int argc, char **argv)
1708 unsigned long interval = 0, count = 0;
1710 boolean_t verbose = B_FALSE;
1714 while ((c = getopt(argc, argv, "v")) != -1) {
1720 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1730 * Determine if the last argument is an integer or a pool name
1732 if (argc > 0 && isdigit(argv[argc - 1][0])) {
1736 interval = strtoul(argv[argc - 1], &end, 10);
1738 if (*end == '\0' && errno == 0) {
1739 if (interval == 0) {
1740 (void) fprintf(stderr, gettext("interval "
1741 "cannot be zero\n"));
1746 * Ignore the last parameter
1751 * If this is not a valid number, just plow on. The
1752 * user will get a more informative error message later
1760 * If the last argument is also an integer, then we have both a count
1763 if (argc > 0 && isdigit(argv[argc - 1][0])) {
1768 interval = strtoul(argv[argc - 1], &end, 10);
1770 if (*end == '\0' && errno == 0) {
1771 if (interval == 0) {
1772 (void) fprintf(stderr, gettext("interval "
1773 "cannot be zero\n"));
1778 * Ignore the last parameter
1787 * Construct the list of all interesting pools.
1790 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
1793 if (pool_list_count(list) == 0 && argc != 0) {
1794 pool_list_free(list);
1798 if (pool_list_count(list) == 0 && interval == 0) {
1799 pool_list_free(list);
1800 (void) fprintf(stderr, gettext("no pools available\n"));
1805 * Enter the main iostat loop.
1808 cb.cb_verbose = verbose;
1809 cb.cb_iteration = 0;
1810 cb.cb_namewidth = 0;
1813 pool_list_update(list);
1815 if ((npools = pool_list_count(list)) == 0)
1819 * Refresh all statistics. This is done as an explicit step
1820 * before calculating the maximum name width, so that any
1821 * configuration changes are properly accounted for.
1823 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1826 * Iterate over all pools to determine the maximum width
1827 * for the pool / device name column across all pools.
1829 cb.cb_namewidth = 0;
1830 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
1833 * If it's the first time, or verbose mode, print the header.
1835 if (++cb.cb_iteration == 1 || verbose)
1836 print_iostat_header(&cb);
1838 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
1841 * If there's more than one pool, and we're not in verbose mode
1842 * (which prints a separator for us), then print a separator.
1844 if (npools > 1 && !verbose)
1845 print_iostat_separator(&cb);
1848 (void) printf("\n");
1851 * Flush the output so that redirection to a file isn't buffered
1854 (void) fflush(stdout);
1859 if (count != 0 && --count == 0)
1862 (void) sleep(interval);
1865 pool_list_free(list);
1870 typedef struct list_cbdata {
1871 boolean_t cb_scripted;
1873 int cb_fields[MAX_FIELDS];
1878 * Given a list of columns to display, output appropriate headers for each one.
1881 print_header(int *fields, size_t count)
1887 for (i = 0; i < count; i++) {
1888 col = &column_table[fields[i]];
1891 if (col->cd_justify == left_justify)
1896 (void) printf(fmt, i == count - 1 ? strlen(col->cd_title) :
1897 col->cd_width, col->cd_title);
1900 (void) printf("\n");
1904 list_callback(zpool_handle_t *zhp, void *data)
1906 list_cbdata_t *cbp = data;
1909 char buf[ZPOOL_MAXNAMELEN];
1915 if (cbp->cb_first) {
1916 if (!cbp->cb_scripted)
1917 print_header(cbp->cb_fields, cbp->cb_fieldcount);
1918 cbp->cb_first = B_FALSE;
1921 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
1924 config = zpool_get_config(zhp, NULL);
1925 total = zpool_get_space_total(zhp);
1926 used = zpool_get_space_used(zhp);
1929 for (i = 0; i < cbp->cb_fieldcount; i++) {
1931 if (cbp->cb_scripted)
1932 (void) printf("\t");
1937 col = &column_table[cbp->cb_fields[i]];
1939 switch (cbp->cb_fields[i]) {
1940 case ZPOOL_FIELD_NAME:
1941 (void) strlcpy(buf, zpool_get_name(zhp), sizeof (buf));
1944 case ZPOOL_FIELD_SIZE:
1946 (void) strlcpy(buf, "-", sizeof (buf));
1948 zfs_nicenum(total, buf, sizeof (buf));
1951 case ZPOOL_FIELD_USED:
1953 (void) strlcpy(buf, "-", sizeof (buf));
1955 zfs_nicenum(used, buf, sizeof (buf));
1958 case ZPOOL_FIELD_AVAILABLE:
1960 (void) strlcpy(buf, "-", sizeof (buf));
1962 zfs_nicenum(total - used, buf, sizeof (buf));
1965 case ZPOOL_FIELD_CAPACITY:
1966 if (config == NULL) {
1967 (void) strlcpy(buf, "-", sizeof (buf));
1969 uint64_t capacity = (total == 0 ? 0 :
1970 (used * 100 / total));
1971 (void) snprintf(buf, sizeof (buf), "%llu%%",
1972 (u_longlong_t)capacity);
1976 case ZPOOL_FIELD_HEALTH:
1977 if (config == NULL) {
1978 (void) strlcpy(buf, "FAULTED", sizeof (buf));
1984 verify(nvlist_lookup_nvlist(config,
1985 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
1986 verify(nvlist_lookup_uint64_array(nvroot,
1987 ZPOOL_CONFIG_STATS, (uint64_t **)&vs,
1989 (void) strlcpy(buf, state_to_name(vs),
1994 case ZPOOL_FIELD_ROOT:
1996 (void) strlcpy(buf, "-", sizeof (buf));
1997 else if (zpool_get_root(zhp, buf, sizeof (buf)) != 0)
1998 (void) strlcpy(buf, "-", sizeof (buf));
2002 if (cbp->cb_scripted)
2003 (void) printf("%s", buf);
2005 if (col->cd_justify == left_justify)
2010 (void) printf(fmt, i == cbp->cb_fieldcount - 1 ?
2011 strlen(buf) : col->cd_width, buf);
2015 (void) printf("\n");
2021 * zpool list [-H] [-o field[,field]*] [pool] ...
2023 * -H Scripted mode. Don't display headers, and separate fields by
2025 * -o List of fields to display. Defaults to all fields, or
2026 * "name,size,used,available,capacity,health,root"
2028 * List all pools in the system, whether or not they're healthy. Output space
2029 * statistics for each one, as well as health status summary.
2032 zpool_do_list(int argc, char **argv)
2036 list_cbdata_t cb = { 0 };
2037 static char default_fields[] =
2038 "name,size,used,available,capacity,health,root";
2039 char *fields = default_fields;
2043 while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2046 cb.cb_scripted = B_TRUE;
2052 (void) fprintf(stderr, gettext("missing argument for "
2053 "'%c' option\n"), optopt);
2057 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2066 while (*fields != '\0') {
2067 if (cb.cb_fieldcount == MAX_FIELDS) {
2068 (void) fprintf(stderr, gettext("too many "
2069 "properties given to -o option\n"));
2073 if ((cb.cb_fields[cb.cb_fieldcount] = getsubopt(&fields,
2074 column_subopts, &value)) == -1) {
2075 (void) fprintf(stderr, gettext("invalid property "
2084 cb.cb_first = B_TRUE;
2086 ret = for_each_pool(argc, argv, B_TRUE, NULL, list_callback, &cb);
2088 if (argc == 0 && cb.cb_first) {
2089 (void) printf(gettext("no pools available\n"));
2097 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2104 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2105 &child, &children) != 0) {
2106 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2107 if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2108 name += sizeof(_PATH_DEV)-1;
2109 if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2110 path += sizeof(_PATH_DEV)-1;
2111 if (strcmp(name, path) == 0)
2116 for (c = 0; c < children; c++)
2117 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2124 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2126 boolean_t force = B_FALSE;
2129 char *poolname, *old_disk, *new_disk;
2130 zpool_handle_t *zhp;
2137 while ((c = getopt(argc, argv, "f")) != -1) {
2143 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2154 /* get pool name and check number of arguments */
2156 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2163 (void) fprintf(stderr,
2164 gettext("missing <device> specification\n"));
2172 (void) fprintf(stderr,
2173 gettext("missing <new_device> specification\n"));
2176 new_disk = old_disk;
2186 (void) fprintf(stderr, gettext("too many arguments\n"));
2190 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2193 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
2194 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2200 nvroot = make_root_vdev(config, force, B_FALSE, replacing, argc, argv);
2201 if (nvroot == NULL) {
2206 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2209 zpool_log_history(g_zfs, log_argc, log_argv, poolname, B_TRUE,
2213 nvlist_free(nvroot);
2220 * zpool replace [-f] <pool> <device> <new_device>
2222 * -f Force attach, even if <new_device> appears to be in use.
2224 * Replace <device> with <new_device>.
2228 zpool_do_replace(int argc, char **argv)
2230 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2234 * zpool attach [-f] <pool> <device> <new_device>
2236 * -f Force attach, even if <new_device> appears to be in use.
2238 * Attach <new_device> to the mirror containing <device>. If <device> is not
2239 * part of a mirror, then <device> will be transformed into a mirror of
2240 * <device> and <new_device>. In either case, <new_device> will begin life
2241 * with a DTL of [0, now], and will immediately begin to resilver itself.
2244 zpool_do_attach(int argc, char **argv)
2246 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2250 * zpool detach [-f] <pool> <device>
2252 * -f Force detach of <device>, even if DTLs argue against it
2253 * (not supported yet)
2255 * Detach a device from a mirror. The operation will be refused if <device>
2256 * is the last device in the mirror, or if the DTLs indicate that this device
2257 * has the only valid copy of some data.
2261 zpool_do_detach(int argc, char **argv)
2264 char *poolname, *path;
2265 zpool_handle_t *zhp;
2269 while ((c = getopt(argc, argv, "f")) != -1) {
2273 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2282 /* get pool name and check number of arguments */
2284 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2289 (void) fprintf(stderr,
2290 gettext("missing <device> specification\n"));
2297 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2300 ret = zpool_vdev_detach(zhp, path);
2303 zpool_log_history(g_zfs, argc + optind, argv - optind, poolname,
2312 * zpool online <pool> <device> ...
2316 zpool_do_online(int argc, char **argv)
2320 zpool_handle_t *zhp;
2324 while ((c = getopt(argc, argv, "t")) != -1) {
2328 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2337 /* get pool name and check number of arguments */
2339 (void) fprintf(stderr, gettext("missing pool name\n"));
2343 (void) fprintf(stderr, gettext("missing device name\n"));
2349 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2352 for (i = 1; i < argc; i++)
2353 if (zpool_vdev_online(zhp, argv[i]) == 0)
2354 (void) printf(gettext("Bringing device %s online\n"),
2360 zpool_log_history(g_zfs, argc + optind, argv - optind, poolname,
2369 * zpool offline [-ft] <pool> <device> ...
2371 * -f Force the device into the offline state, even if doing
2372 * so would appear to compromise pool availability.
2373 * (not supported yet)
2375 * -t Only take the device off-line temporarily. The offline
2376 * state will not be persistent across reboots.
2380 zpool_do_offline(int argc, char **argv)
2384 zpool_handle_t *zhp;
2386 boolean_t istmp = B_FALSE;
2389 while ((c = getopt(argc, argv, "ft")) != -1) {
2396 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2405 /* get pool name and check number of arguments */
2407 (void) fprintf(stderr, gettext("missing pool name\n"));
2411 (void) fprintf(stderr, gettext("missing device name\n"));
2417 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2420 for (i = 1; i < argc; i++)
2421 if (zpool_vdev_offline(zhp, argv[i], istmp) == 0)
2422 (void) printf(gettext("Bringing device %s offline\n"),
2428 zpool_log_history(g_zfs, argc + optind, argv - optind, poolname,
2437 * zpool clear <pool> [device]
2439 * Clear all errors associated with a pool or a particular device.
2442 zpool_do_clear(int argc, char **argv)
2445 zpool_handle_t *zhp;
2446 char *pool, *device;
2449 (void) fprintf(stderr, gettext("missing pool name\n"));
2454 (void) fprintf(stderr, gettext("too many arguments\n"));
2459 device = argc == 3 ? argv[2] : NULL;
2461 if ((zhp = zpool_open(g_zfs, pool)) == NULL)
2464 if (zpool_clear(zhp, device) != 0)
2468 zpool_log_history(g_zfs, argc, argv, pool, B_TRUE, B_FALSE);
2474 typedef struct scrub_cbdata {
2481 scrub_callback(zpool_handle_t *zhp, void *data)
2483 scrub_cbdata_t *cb = data;
2487 * Ignore faulted pools.
2489 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2490 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2491 "currently unavailable\n"), zpool_get_name(zhp));
2495 err = zpool_scrub(zhp, cb->cb_type);
2498 zpool_log_history(g_zfs, cb->cb_argc, cb->cb_argv,
2499 zpool_get_name(zhp), B_TRUE, B_FALSE);
2506 * zpool scrub [-s] <pool> ...
2508 * -s Stop. Stops any in-progress scrub.
2511 zpool_do_scrub(int argc, char **argv)
2516 cb.cb_type = POOL_SCRUB_EVERYTHING;
2519 while ((c = getopt(argc, argv, "s")) != -1) {
2522 cb.cb_type = POOL_SCRUB_NONE;
2525 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2537 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2541 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2544 typedef struct status_cbdata {
2546 boolean_t cb_allpools;
2547 boolean_t cb_verbose;
2548 boolean_t cb_explain;
2553 * Print out detailed scrub status.
2556 print_scrub_status(nvlist_t *nvroot)
2560 time_t start, end, now;
2561 double fraction_done;
2562 uint64_t examined, total, minutes_left;
2565 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2566 (uint64_t **)&vs, &vsc) == 0);
2569 * If there's never been a scrub, there's not much to say.
2571 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2572 (void) printf(gettext("none requested\n"));
2576 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2577 "resilver" : "scrub";
2579 start = vs->vs_scrub_start;
2580 end = vs->vs_scrub_end;
2582 examined = vs->vs_scrub_examined;
2583 total = vs->vs_alloc;
2586 (void) printf(gettext("%s %s with %llu errors on %s"),
2587 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2588 (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2594 if (examined > total)
2597 fraction_done = (double)examined / total;
2598 minutes_left = (uint64_t)((now - start) *
2599 (1 - fraction_done) / fraction_done / 60);
2601 (void) printf(gettext("%s in progress, %.2f%% done, %lluh%um to go\n"),
2602 scrub_type, 100 * fraction_done,
2603 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2606 typedef struct spare_cbdata {
2608 zpool_handle_t *cb_zhp;
2612 find_vdev(nvlist_t *nv, uint64_t search)
2618 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2622 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2623 &child, &children) == 0) {
2624 for (c = 0; c < children; c++)
2625 if (find_vdev(child[c], search))
2633 find_spare(zpool_handle_t *zhp, void *data)
2635 spare_cbdata_t *cbp = data;
2636 nvlist_t *config, *nvroot;
2638 config = zpool_get_config(zhp, NULL);
2639 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2642 if (find_vdev(nvroot, cbp->cb_guid)) {
2652 * Print out configuration state as requested by status_callback.
2655 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2656 int namewidth, int depth, boolean_t isspare)
2661 char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2663 uint64_t notpresent;
2667 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2668 (uint64_t **)&vs, &c) == 0);
2670 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2671 &child, &children) != 0)
2674 state = state_to_name(vs);
2677 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2680 if (vs->vs_aux == VDEV_AUX_SPARED)
2682 else if (vs->vs_state == VDEV_STATE_HEALTHY)
2686 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
2690 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2691 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2692 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2693 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2696 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2697 ¬present) == 0) {
2699 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2700 (void) printf(" was %s", path);
2701 } else if (vs->vs_aux != 0) {
2704 switch (vs->vs_aux) {
2705 case VDEV_AUX_OPEN_FAILED:
2706 (void) printf(gettext("cannot open"));
2709 case VDEV_AUX_BAD_GUID_SUM:
2710 (void) printf(gettext("missing device"));
2713 case VDEV_AUX_NO_REPLICAS:
2714 (void) printf(gettext("insufficient replicas"));
2717 case VDEV_AUX_VERSION_NEWER:
2718 (void) printf(gettext("newer version"));
2721 case VDEV_AUX_SPARED:
2722 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2724 if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2725 if (strcmp(zpool_get_name(cb.cb_zhp),
2726 zpool_get_name(zhp)) == 0)
2727 (void) printf(gettext("currently in "
2730 (void) printf(gettext("in use by "
2732 zpool_get_name(cb.cb_zhp));
2733 zpool_close(cb.cb_zhp);
2735 (void) printf(gettext("currently in use"));
2740 (void) printf(gettext("corrupted data"));
2743 } else if (vs->vs_scrub_repaired != 0 && children == 0) {
2745 * Report bytes resilvered/repaired on leaf devices.
2747 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2748 (void) printf(gettext(" %s %s"), repaired,
2749 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2750 "resilvered" : "repaired");
2753 (void) printf("\n");
2755 for (c = 0; c < children; c++) {
2756 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2757 print_status_config(zhp, vname, child[c],
2758 namewidth, depth + 2, isspare);
2764 print_error_log(zpool_handle_t *zhp)
2766 nvlist_t *nverrlist;
2769 size_t len = MAXPATHLEN * 2;
2771 if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2772 (void) printf("errors: List of errors unavailable "
2773 "(insufficient privileges)\n");
2777 (void) printf("errors: Permanent errors have been "
2778 "detected in the following files:\n\n");
2780 pathname = safe_malloc(len);
2782 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2784 uint64_t dsobj, obj;
2786 verify(nvpair_value_nvlist(elem, &nv) == 0);
2787 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2789 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2791 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2792 (void) printf("%7s %s\n", "", pathname);
2795 nvlist_free(nverrlist);
2799 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2808 (void) printf(gettext("\tspares\n"));
2810 for (i = 0; i < nspares; i++) {
2811 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2812 print_status_config(zhp, name, spares[i],
2813 namewidth, 2, B_TRUE);
2819 * Display a summary of pool status. Displays a summary such as:
2823 * reason: One or more devices ...
2824 * see: http://www.sun.com/msg/ZFS-xxxx-01
2830 * When given the '-v' option, we print out the complete config. If the '-e'
2831 * option is specified, then we print out error rate information as well.
2834 status_callback(zpool_handle_t *zhp, void *data)
2836 status_cbdata_t *cbp = data;
2837 nvlist_t *config, *nvroot;
2844 config = zpool_get_config(zhp, NULL);
2845 reason = zpool_get_status(zhp, &msgid);
2850 * If we were given 'zpool status -x', only report those pools with
2853 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
2854 if (!cbp->cb_allpools) {
2855 (void) printf(gettext("pool '%s' is healthy\n"),
2856 zpool_get_name(zhp));
2858 cbp->cb_first = B_FALSE;
2864 cbp->cb_first = B_FALSE;
2866 (void) printf("\n");
2868 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2870 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2871 (uint64_t **)&vs, &c) == 0);
2872 health = state_to_name(vs);
2874 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
2875 (void) printf(gettext(" state: %s\n"), health);
2878 case ZPOOL_STATUS_MISSING_DEV_R:
2879 (void) printf(gettext("status: One or more devices could not "
2880 "be opened. Sufficient replicas exist for\n\tthe pool to "
2881 "continue functioning in a degraded state.\n"));
2882 (void) printf(gettext("action: Attach the missing device and "
2883 "online it using 'zpool online'.\n"));
2886 case ZPOOL_STATUS_MISSING_DEV_NR:
2887 (void) printf(gettext("status: One or more devices could not "
2888 "be opened. There are insufficient\n\treplicas for the "
2889 "pool to continue functioning.\n"));
2890 (void) printf(gettext("action: Attach the missing device and "
2891 "online it using 'zpool online'.\n"));
2894 case ZPOOL_STATUS_CORRUPT_LABEL_R:
2895 (void) printf(gettext("status: One or more devices could not "
2896 "be used because the label is missing or\n\tinvalid. "
2897 "Sufficient replicas exist for the pool to continue\n\t"
2898 "functioning in a degraded state.\n"));
2899 (void) printf(gettext("action: Replace the device using "
2900 "'zpool replace'.\n"));
2903 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2904 (void) printf(gettext("status: One or more devices could not "
2905 "be used because the label is missing \n\tor invalid. "
2906 "There are insufficient replicas for the pool to "
2907 "continue\n\tfunctioning.\n"));
2908 (void) printf(gettext("action: Destroy and re-create the pool "
2909 "from a backup source.\n"));
2912 case ZPOOL_STATUS_FAILING_DEV:
2913 (void) printf(gettext("status: One or more devices has "
2914 "experienced an unrecoverable error. An\n\tattempt was "
2915 "made to correct the error. Applications are "
2917 (void) printf(gettext("action: Determine if the device needs "
2918 "to be replaced, and clear the errors\n\tusing "
2919 "'zpool clear' or replace the device with 'zpool "
2923 case ZPOOL_STATUS_OFFLINE_DEV:
2924 (void) printf(gettext("status: One or more devices has "
2925 "been taken offline by the administrator.\n\tSufficient "
2926 "replicas exist for the pool to continue functioning in "
2927 "a\n\tdegraded state.\n"));
2928 (void) printf(gettext("action: Online the device using "
2929 "'zpool online' or replace the device with\n\t'zpool "
2933 case ZPOOL_STATUS_RESILVERING:
2934 (void) printf(gettext("status: One or more devices is "
2935 "currently being resilvered. The pool will\n\tcontinue "
2936 "to function, possibly in a degraded state.\n"));
2937 (void) printf(gettext("action: Wait for the resilver to "
2941 case ZPOOL_STATUS_CORRUPT_DATA:
2942 (void) printf(gettext("status: One or more devices has "
2943 "experienced an error resulting in data\n\tcorruption. "
2944 "Applications may be affected.\n"));
2945 (void) printf(gettext("action: Restore the file in question "
2946 "if possible. Otherwise restore the\n\tentire pool from "
2950 case ZPOOL_STATUS_CORRUPT_POOL:
2951 (void) printf(gettext("status: The pool metadata is corrupted "
2952 "and the pool cannot be opened.\n"));
2953 (void) printf(gettext("action: Destroy and re-create the pool "
2954 "from a backup source.\n"));
2957 case ZPOOL_STATUS_VERSION_OLDER:
2958 (void) printf(gettext("status: The pool is formatted using an "
2959 "older on-disk format. The pool can\n\tstill be used, but "
2960 "some features are unavailable.\n"));
2961 (void) printf(gettext("action: Upgrade the pool using 'zpool "
2962 "upgrade'. Once this is done, the\n\tpool will no longer "
2963 "be accessible on older software versions.\n"));
2966 case ZPOOL_STATUS_VERSION_NEWER:
2967 (void) printf(gettext("status: The pool has been upgraded to a "
2968 "newer, incompatible on-disk version.\n\tThe pool cannot "
2969 "be accessed on this system.\n"));
2970 (void) printf(gettext("action: Access the pool from a system "
2971 "running more recent software, or\n\trestore the pool from "
2977 * The remaining errors can't actually be generated, yet.
2979 assert(reason == ZPOOL_STATUS_OK);
2983 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
2986 if (config != NULL) {
2993 (void) printf(gettext(" scrub: "));
2994 print_scrub_status(nvroot);
2996 namewidth = max_width(zhp, nvroot, 0, 0);
3000 (void) printf(gettext("config:\n\n"));
3001 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
3002 "NAME", "STATE", "READ", "WRITE", "CKSUM");
3003 print_status_config(zhp, zpool_get_name(zhp), nvroot,
3004 namewidth, 0, B_FALSE);
3006 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3007 &spares, &nspares) == 0)
3008 print_spares(zhp, spares, nspares, namewidth);
3010 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3012 nvlist_t *nverrlist = NULL;
3015 * If the approximate error count is small, get a
3016 * precise count by fetching the entire log and
3017 * uniquifying the results.
3019 if (nerr < 100 && !cbp->cb_verbose &&
3020 zpool_get_errlog(zhp, &nverrlist) == 0) {
3025 while ((elem = nvlist_next_nvpair(nverrlist,
3030 nvlist_free(nverrlist);
3032 (void) printf("\n");
3035 (void) printf(gettext("errors: No known data "
3037 else if (!cbp->cb_verbose)
3038 (void) printf(gettext("errors: %llu data "
3039 "errors, use '-v' for a list\n"),
3040 (u_longlong_t)nerr);
3042 print_error_log(zhp);
3045 (void) printf(gettext("config: The configuration cannot be "
3053 * zpool status [-vx] [pool] ...
3055 * -v Display complete error logs
3056 * -x Display only pools with potential problems
3058 * Describes the health status of all pools or some subset.
3061 zpool_do_status(int argc, char **argv)
3065 status_cbdata_t cb = { 0 };
3068 while ((c = getopt(argc, argv, "vx")) != -1) {
3071 cb.cb_verbose = B_TRUE;
3074 cb.cb_explain = B_TRUE;
3077 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3086 cb.cb_first = B_TRUE;
3089 cb.cb_allpools = B_TRUE;
3091 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3093 if (argc == 0 && cb.cb_count == 0)
3094 (void) printf(gettext("no pools available\n"));
3095 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3096 (void) printf(gettext("all pools are healthy\n"));
3101 typedef struct upgrade_cbdata {
3110 upgrade_cb(zpool_handle_t *zhp, void *arg)
3112 upgrade_cbdata_t *cbp = arg;
3117 config = zpool_get_config(zhp, NULL);
3118 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3121 if (!cbp->cb_newer && version < ZFS_VERSION) {
3123 if (cbp->cb_first) {
3124 (void) printf(gettext("The following pools are "
3125 "out of date, and can be upgraded. After "
3126 "being\nupgraded, these pools will no "
3127 "longer be accessible by older software "
3129 (void) printf(gettext("VER POOL\n"));
3130 (void) printf(gettext("--- ------------\n"));
3131 cbp->cb_first = B_FALSE;
3134 (void) printf("%2llu %s\n", (u_longlong_t)version,
3135 zpool_get_name(zhp));
3137 cbp->cb_first = B_FALSE;
3138 ret = zpool_upgrade(zhp);
3140 zpool_log_history(g_zfs, cbp->cb_argc,
3141 cbp->cb_argv, zpool_get_name(zhp), B_TRUE,
3143 (void) printf(gettext("Successfully upgraded "
3144 "'%s'\n"), zpool_get_name(zhp));
3147 } else if (cbp->cb_newer && version > ZFS_VERSION) {
3148 assert(!cbp->cb_all);
3150 if (cbp->cb_first) {
3151 (void) printf(gettext("The following pools are "
3152 "formatted using a newer software version and\n"
3153 "cannot be accessed on the current system.\n\n"));
3154 (void) printf(gettext("VER POOL\n"));
3155 (void) printf(gettext("--- ------------\n"));
3156 cbp->cb_first = B_FALSE;
3159 (void) printf("%2llu %s\n", (u_longlong_t)version,
3160 zpool_get_name(zhp));
3169 upgrade_one(zpool_handle_t *zhp, void *data)
3174 upgrade_cbdata_t *cbp = data;
3176 config = zpool_get_config(zhp, NULL);
3177 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3180 if (version == ZFS_VERSION) {
3181 (void) printf(gettext("Pool '%s' is already formatted "
3182 "using the current version.\n"), zpool_get_name(zhp));
3186 ret = zpool_upgrade(zhp);
3189 zpool_log_history(g_zfs, cbp->cb_argc, cbp->cb_argv,
3190 zpool_get_name(zhp), B_TRUE, B_FALSE);
3191 (void) printf(gettext("Successfully upgraded '%s' "
3192 "from version %llu to version %llu\n"), zpool_get_name(zhp),
3193 (u_longlong_t)version, (u_longlong_t)ZFS_VERSION);
3202 * zpool upgrade <-a | pool>
3204 * With no arguments, display downrev'd ZFS pool available for upgrade.
3205 * Individual pools can be upgraded by specifying the pool, and '-a' will
3206 * upgrade all pools.
3209 zpool_do_upgrade(int argc, char **argv)
3212 upgrade_cbdata_t cb = { 0 };
3214 boolean_t showversions = B_FALSE;
3217 while ((c = getopt(argc, argv, "av")) != -1) {
3223 showversions = B_TRUE;
3226 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3238 if (cb.cb_all || argc != 0) {
3239 (void) fprintf(stderr, gettext("-v option is "
3240 "incompatible with other arguments\n"));
3243 } else if (cb.cb_all) {
3245 (void) fprintf(stderr, gettext("-a option is "
3246 "incompatible with other arguments\n"));
3251 (void) printf(gettext("This system is currently running ZFS version "
3252 "%llu.\n\n"), ZFS_VERSION);
3253 cb.cb_first = B_TRUE;
3255 (void) printf(gettext("The following versions are "
3257 (void) printf(gettext("VER DESCRIPTION\n"));
3258 (void) printf("--- -----------------------------------------"
3259 "---------------\n");
3260 (void) printf(gettext(" 1 Initial ZFS version\n"));
3261 (void) printf(gettext(" 2 Ditto blocks "
3262 "(replicated metadata)\n"));
3263 (void) printf(gettext(" 3 Hot spares and double parity "
3265 (void) printf(gettext(" 4 zpool history\n"));
3266 (void) printf(gettext(" 5 Compression using the gzip "
3268 (void) printf(gettext(" 6 bootfs pool property "));
3269 (void) printf(gettext("\nFor more information on a particular "
3270 "version, including supported releases, see:\n\n"));
3271 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3273 (void) printf(gettext("Where 'N' is the version number.\n"));
3274 } else if (argc == 0) {
3277 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3278 notfound = cb.cb_first;
3280 if (!cb.cb_all && ret == 0) {
3282 (void) printf("\n");
3283 cb.cb_first = B_TRUE;
3284 cb.cb_newer = B_TRUE;
3285 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3288 (void) printf("\n");
3294 (void) printf(gettext("All pools are formatted "
3295 "using this version.\n"));
3296 else if (!cb.cb_all)
3297 (void) printf(gettext("Use 'zpool upgrade -v' "
3298 "for a list of available versions and "
3299 "their associated\nfeatures.\n"));
3302 ret = for_each_pool(argc, argv, B_FALSE, NULL,
3310 * Print out the command history for a specific pool.
3313 get_history_one(zpool_handle_t *zhp, void *data)
3325 *(boolean_t *)data = B_FALSE;
3327 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3329 if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3332 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3333 &records, &numrecords) == 0);
3334 for (i = 0; i < numrecords; i++) {
3335 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3337 verify(nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3340 (void) localtime_r(&tsec, &t);
3341 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3342 (void) printf("%s %s\n", tbuf, cmdstr);
3345 (void) printf("\n");
3352 * zpool history <pool>
3354 * Displays the history of commands that modified pools.
3357 zpool_do_history(int argc, char **argv)
3359 boolean_t first = B_TRUE;
3365 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
3368 if (argc == 0 && first == B_TRUE) {
3369 (void) printf(gettext("no pools available\n"));
3377 get_callback(zpool_handle_t *zhp, void *data)
3379 libzfs_get_cbdata_t *cbp = (libzfs_get_cbdata_t *)data;
3380 char value[MAXNAMELEN];
3381 zfs_source_t srctype;
3382 zpool_proplist_t *pl;
3384 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3387 * Skip the special fake placeholder.
3389 if (pl->pl_prop == ZFS_PROP_NAME &&
3390 pl == cbp->cb_proplist)
3393 if (zpool_get_prop(zhp, pl->pl_prop,
3394 value, sizeof (value), &srctype) != 0)
3397 libzfs_print_one_property(zpool_get_name(zhp), cbp,
3398 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3404 zpool_do_get(int argc, char **argv)
3406 libzfs_get_cbdata_t cb = { 0 };
3407 zpool_proplist_t fake_name = { 0 };
3413 cb.cb_first = B_TRUE;
3414 cb.cb_sources = ZFS_SRC_ALL;
3415 cb.cb_columns[0] = GET_COL_NAME;
3416 cb.cb_columns[1] = GET_COL_PROPERTY;
3417 cb.cb_columns[2] = GET_COL_VALUE;
3418 cb.cb_columns[3] = GET_COL_SOURCE;
3420 if (zpool_get_proplist(g_zfs, argv[1], &cb.cb_proplist) != 0)
3423 if (cb.cb_proplist != NULL) {
3424 fake_name.pl_prop = ZFS_PROP_NAME;
3425 fake_name.pl_width = strlen(gettext("NAME"));
3426 fake_name.pl_next = cb.cb_proplist;
3427 cb.cb_proplist = &fake_name;
3430 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3433 if (cb.cb_proplist == &fake_name)
3434 zfs_free_proplist(fake_name.pl_next);
3436 zfs_free_proplist(cb.cb_proplist);
3441 typedef struct set_cbdata {
3444 boolean_t cb_any_successful;
3448 set_callback(zpool_handle_t *zhp, void *data)
3451 set_cbdata_t *cb = (set_cbdata_t *)data;
3453 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3456 cb->cb_any_successful = B_TRUE;
3462 zpool_do_set(int argc, char **argv)
3464 set_cbdata_t cb = { 0 };
3467 if (argc > 1 && argv[1][0] == '-') {
3468 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3474 (void) fprintf(stderr, gettext("missing property=value "
3480 (void) fprintf(stderr, gettext("missing pool name\n"));
3485 (void) fprintf(stderr, gettext("too many pool names\n"));
3489 cb.cb_propname = argv[1];
3490 cb.cb_value = strchr(cb.cb_propname, '=');
3491 if (cb.cb_value == NULL) {
3492 (void) fprintf(stderr, gettext("missing value in "
3493 "property=value argument\n"));
3497 *(cb.cb_value) = '\0';
3500 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3503 if (cb.cb_any_successful) {
3504 *(cb.cb_value - 1) = '=';
3505 zpool_log_history(g_zfs, argc, argv, argv[2], B_FALSE, B_FALSE);
3512 find_command_idx(char *command, int *idx)
3516 for (i = 0; i < NCOMMAND; i++) {
3517 if (command_table[i].name == NULL)
3520 if (strcmp(command, command_table[i].name) == 0) {
3529 main(int argc, char **argv)
3536 (void) setlocale(LC_ALL, "");
3537 (void) textdomain(TEXT_DOMAIN);
3539 if ((g_zfs = libzfs_init()) == NULL) {
3540 (void) fprintf(stderr, gettext("internal error: failed to "
3541 "initialize ZFS library\n"));
3545 libzfs_print_on_error(g_zfs, B_TRUE);
3550 * Make sure the user has specified some command.
3553 (void) fprintf(stderr, gettext("missing command\n"));
3562 if (strcmp(cmdname, "-?") == 0)
3566 * Run the appropriate command.
3568 if (find_command_idx(cmdname, &i) == 0) {
3569 current_command = &command_table[i];
3570 ret = command_table[i].func(argc - 1, argv + 1);
3575 * 'freeze' is a vile debugging abomination, so we treat it as such.
3577 if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3579 int fd = open(ZFS_DEV, O_RDWR);
3580 (void) strcpy((void *)buf, argv[2]);
3581 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3585 (void) fprintf(stderr, gettext("unrecognized "
3586 "command '%s'\n"), cmdname);
3593 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3594 * for the purposes of running ::findleaks.
3596 if (getenv("ZFS_ABORT") != NULL) {
3597 (void) printf("dumping core by request\n");