zpool_main.c revision 4dea40f0101dd55f4d4edd657d138d57849fd36d
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Use is subject to license terms.
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_create(int, char **);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int zpool_do_destroy(int, char **);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int zpool_do_add(int, char **);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int zpool_do_remove(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_list(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_iostat(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_status(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_online(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_offline(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_clear(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_attach(int, char **);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic int zpool_do_detach(int, char **);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic int zpool_do_replace(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_scrub(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_import(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_export(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_upgrade(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_history(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_get(int, char **);
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic int zpool_do_set(int, char **);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * These libumem hooks provide a reasonable set of defaults for the allocator's
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * debugging facilities.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return ("default,verbose"); /* $UMEM_DEBUG setting */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return ("fail,contents"); /* $UMEM_LOGGING setting */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshtypedef enum {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshtypedef struct zpool_command {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int (*func)(int, char **);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Master command table. Each ZFS command has a name, associated function, and
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * usage message. The usage messages need to be internationalized, so we have
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh * to have a function to return the usage message based on a command index.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * These commands are organized according to how they are displayed in the usage
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * message. An empty command (one with a NULL name) indicates an empty line in
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * the generic usage message.
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh { "offline", zpool_do_offline, HELP_OFFLINE },
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh { "replace", zpool_do_replace, HELP_REPLACE },
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintoshstatic const char *
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh return (gettext("\tattach [-f] <pool> <device> "
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh "<new-device>\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tcreate [-fn] [-o property=value] ... \n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\t [-O file-system-property=value] ... \n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\thistory [-il] [<pool>] ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\timport [-o mntopts] [-o property=value] ... \n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\timport [-o mntopts] [-o property=value] ... \n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\t [-d dir | -c cachefile] [-D] [-f] [-R root] "
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "<pool | id> [newpool]\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tiostat [-v] [pool] ... [interval "
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "[count]]\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tlist [-H] [-o property[,...]] "
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "[pool] ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\toffline [-t] <pool> <device> ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tonline <pool> <device> ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\treplace [-f] <pool> <device> "
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "[new-device]\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tremove <pool> <device> ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tstatus [-vx] [pool] ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\tupgrade -v\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\tupgrade [-V version] <-a | pool ...>\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tget <\"all\" | property[,...]> "
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "<pool> ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (gettext("\tset <property=value> <pool> \n"));
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh /* NOTREACHED */
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh * Callback routine that will print out a pool property value.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Display usage message. If we're inside a command, display only the usage for
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh * that command. Otherwise, iterate over the entire command table and display
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * a complete usage message.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross gettext("where 'command' is one of the following:\n\n"));
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh for (i = 0; i < NCOMMAND; i++) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) fprintf(fp, "%s", get_usage(current_command->usage));
8d7e41661dc4633488e93b13363137523ce59977jose borrego (strcmp(current_command->name, "list") == 0))) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross gettext("\nthe following properties are supported:\n"));
8d7e41661dc4633488e93b13363137523ce59977jose borrego /* Iterate over all properties */
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
8d7e41661dc4633488e93b13363137523ce59977jose borrego * See comments at end of main().
8d7e41661dc4633488e93b13363137523ce59977jose borregoprint_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross for (c = 0; c < children; c++) {
&is_log);
B_FALSE);
const char *normnm;
char *strval;
if (poolprop) {
char *poolname;
int ret;
optopt);
argc--;
argv++;
poolname);
if (dryrun) {
&poolnvroot) == 0);
ret = 0;
return (ret);
char *poolname;
int i, ret = 0;
argc--;
argv++;
return (ret);
* bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
char *poolname;
char *propval;
goto errout;
&propval) == 0)
goto errout;
goto errout;
propval++;
goto errout;
goto errout;
propval++;
goto errout;
goto badusage;
optopt);
goto badusage;
goto badusage;
goto badusage;
goto errout;
goto errout;
goto errout;
goto errout;
goto errout;
poolname);
goto errout;
} else if (dirp) {
int count = 0;
count++;
goto errout;
if (dryrun) {
ret = 0;
mountpoint) == 0);
return (ret);
char *pool;
int ret;
optopt);
return (ret);
int ret;
optopt);
ret = 0;
for (i = 0; i < argc; i++) {
if (hardforce) {
return (ret);
int ret;
for (c = 0; c < children; c++)
for (c = 0; c < children; c++)
for (c = 0; c < children; c++)
return (max);
case VDEV_AUX_OPEN_FAILED:
case VDEV_AUX_BAD_GUID_SUM:
case VDEV_AUX_NO_REPLICAS:
case VDEV_AUX_VERSION_NEWER:
case VDEV_AUX_ERR_EXCEEDED:
for (c = 0; c < children; c++) {
&is_log);
for (c = 0; c < children; c++) {
for (c = 0; c < children; c++) {
char *name;
char *msgid;
int reason;
const char *health;
int namewidth;
&name) == 0);
&guid) == 0);
&pool_state) == 0);
&nvroot) == 0);
switch (reason) {
case ZPOOL_STATUS_OFFLINE_DEV:
case ZPOOL_STATUS_BAD_LOG:
switch (reason) {
msgid);
char *name;
int error = 0;
&name) == 0);
&hostid) == 0) {
char *hostname;
time_t t;
t = timestamp;
(unsigned long)hostid,
allowfaulted) != 0)
return (error);
int nsearch = 0;
int err;
char *propval;
propval++;
goto error;
goto error;
&propval) == 0)
goto error;
optopt);
if (do_all) {
if (argc != 0) {
if (argc != 0) {
char *endptr;
errno = 0;
if (cachefile) {
if (argc != 0) {
err = 0;
&pool_state) == 0);
if (argc == 0) {
if (first)
else if (!do_all)
if (do_all)
char *name;
typedef struct iostat_cbdata {
int cb_verbose;
int cb_iteration;
int cb_namewidth;
double scale;
char *vname;
if (tdelta == 0)
&oldchild, &c) != 0)
for (c = 0; c < children; c++) {
&oldchild, &c) != 0)
if (children > 0) {
for (c = 0; c < children; c++) {
if (missing)
&newnvroot) == 0);
&oldnvroot) == 0);
&nvroot) == 0);
* creation/destruction as well as vdev configuration changes. The bulk of this
* processing is handled by the pool_list_* routines in zpool_iter.c. We rely
int ret;
int npools;
optopt);
char *end;
errno = 0;
if (interval == 0) {
argc--;
interval = 0;
char *end;
errno = 0;
if (interval == 0) {
argc--;
interval = 0;
ret = 0;
if (verbose)
if (interval == 0)
return (ret);
typedef struct list_cbdata {
const char *header;
if (!first)
else if (right_justify)
char *propstr;
int width;
if (!first) {
if (scripted)
else if (right_justify)
int ret;
static char default_props[] =
optopt);
return (ret);
static nvlist_t *
char *path;
return (nv);
return (NULL);
for (c = 0; c < children; c++)
return (match);
return (NULL);
int ret;
optopt);
if (!replacing) {
poolname);
return (ret);
int ret;
optopt);
return (ret);
char *poolname;
int ret = 0;
optopt);
argv[i]);
return (ret);
char *poolname;
int ret = 0;
optopt);
return (ret);
int ret = 0;
return (ret);
typedef struct scrub_cbdata {
int cb_type;
int cb_argc;
char **cb_argv;
int err;
return (err != 0);
optopt);
typedef struct status_cbdata {
int cb_count;
double fraction_done;
char *scrub_type;
if (end != 0) {
if (examined == 0)
typedef struct spare_cbdata {
static boolean_t
return (B_TRUE);
for (c = 0; c < children; c++)
return (B_TRUE);
return (B_FALSE);
&nvroot) == 0);
char *vname;
char *state;
children = 0;
if (isspare) {
if (!isspare) {
¬present) == 0) {
char *path;
case VDEV_AUX_OPEN_FAILED:
case VDEV_AUX_BAD_GUID_SUM:
case VDEV_AUX_NO_REPLICAS:
case VDEV_AUX_VERSION_NEWER:
case VDEV_AUX_SPARED:
case VDEV_AUX_ERR_EXCEEDED:
case VDEV_AUX_IO_FAILURE:
case VDEV_AUX_BAD_LOG:
* Report bytes resilvered/repaired on leaf devices.
for (c = 0; c < children; c++) {
&is_log);
if (is_log)
char *pathname;
&dsobj) == 0);
&obj) == 0);
int namewidth)
uint_t i;
char *name;
if (nspares == 0)
for (i = 0; i < nspares; i++) {
int namewidth)
uint_t i;
char *name;
if (nl2cache == 0)
for (i = 0; i < nl2cache; i++) {
&children) != 0)
for (c = 0; c < children; c++) {
char *name;
&is_log);
if (!is_log)
char *msgid;
int reason;
const char *health;
uint_t c;
&nvroot) == 0);
switch (reason) {
case ZPOOL_STATUS_FAILING_DEV:
case ZPOOL_STATUS_OFFLINE_DEV:
case ZPOOL_STATUS_RESILVERING:
case ZPOOL_STATUS_BAD_LOG:
msgid);
int namewidth;
&nerr) == 0) {
nerr = 0;
nerr++;
if (nerr == 0)
int ret;
optopt);
if (argc == 0)
return (ret);
typedef struct upgrade_cbdata {
int cb_all;
int cb_first;
int cb_newer;
int cb_argc;
char **cb_argv;
int ret = 0;
&version) == 0);
if (!ret) {
return (ret);
int ret;
if (!ret) {
return (ret != 0);
int ret = 0;
char *end;
optopt);
if (showversions) {
if (argc != 0) {
if (showversions) {
} else if (argc == 0) {
int notfound;
if (ret == 0) {
if (notfound)
return (ret);
typedef struct hist_cbdata {
int longfmt;
int internal;
char *cmdstr;
char *pathstr;
struct tm t;
int ret, i;
char *hostname;
char *zonename;
return (ret);
for (i = 0; i < numrecords; i++) {
&dst_time) != 0)
&cmdstr) != 0) {
sizeof (internalstr),
pathstr);
if (pwd)
(int)who);
return (ret);
int ret;
optopt);
&cbdata);
return (ret);
int ret;
ZFS_TYPE_POOL) != 0)
return (ret);
typedef struct set_cbdata {
char *cb_propname;
char *cb_value;
} set_cbdata_t;
int error;
if (!error)
return (error);
int error;
return (error);
for (i = 0; i < NCOMMAND; i++) {
*idx = i;
int ret;
char *cmdname;
opterr = 0;
abort();
return (ret);