zpool_main.c revision b7b97454b9b1f6625e7e655e9651e744a8dee09d
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * CDDL HEADER START
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * The contents of this file are subject to the terms of the
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Common Development and Distribution License (the "License").
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * You may not use this file except in compliance with the License.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * or http://www.opensolaris.org/os/licensing.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * See the License for the specific language governing permissions
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * and limitations under the License.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * CDDL HEADER END
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Use is subject to license terms.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#pragma ident "%Z%%M% %I% %E% SMI"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_create(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_destroy(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_add(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_remove(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_list(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_iostat(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_status(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_online(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_offline(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_clear(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_attach(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_detach(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_replace(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_scrub(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_import(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_export(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_upgrade(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_history(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_get(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int zpool_do_set(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * These libumem hooks provide a reasonable set of defaults for the allocator's
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * debugging facilities.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return ("default,verbose"); /* $UMEM_DEBUG setting */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return ("fail,contents"); /* $UMEM_LOGGING setting */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoretypedef enum {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoretypedef struct zpool_command {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int (*func)(int, char **);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Master command table. Each ZFS command has a name, associated function, and
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * usage message. The usage messages need to be internationalized, so we have
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * to have a function to return the usage message based on a command index.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * These commands are organized according to how they are displayed in the usage
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * message. An empty command (one with a NULL name) indicates an empty line in
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * the generic usage message.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore { "destroy", zpool_do_destroy, HELP_DESTROY },
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore { "offline", zpool_do_offline, HELP_OFFLINE },
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore { "replace", zpool_do_replace, HELP_REPLACE },
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore { "history", zpool_do_history, HELP_HISTORY },
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic const char *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (gettext("\tattach [-f] <pool> <device> "
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "<new-device>\n"));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (gettext("\tclear <pool> [device]\n"));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (gettext("\tcreate [-fn] [-o property=value] ... \n"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
case HELP_DETACH:
case HELP_EXPORT:
case HELP_HISTORY:
case HELP_IMPORT:
case HELP_IOSTAT:
case HELP_LIST:
case HELP_OFFLINE:
case HELP_ONLINE:
case HELP_REPLACE:
case HELP_REMOVE:
case HELP_SCRUB:
case HELP_STATUS:
case HELP_UPGRADE:
case HELP_GET:
case HELP_SET:
abort();
return (ZPROP_CONT);
for (i = 0; i < NCOMMAND; i++) {
abort();
char *vname;
for (c = 0; c < children; c++) {
&is_log);
B_FALSE);
char *strval;
propval) != 0) {
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 badusage;
optopt);
goto badusage;
goto badusage;
goto badusage;
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++) {
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:
switch (reason) {
msgid);
char *name;
int error = 0;
&name) == 0);
&hostid) == 0) {
char *hostname;
time_t t;
t = timestamp;
(unsigned long)hostid,
return (error);
int nsearch = 0;
int err;
char *searchname;
char *propval;
propval++;
goto error;
goto error;
&propval) == 0)
goto error;
optopt);
if (do_all) {
if (argc != 0) {
if (cachefile)
if (argc != 0) {
char *endptr;
errno = 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:
* Report bytes resilvered/repaired on leaf devices.
for (c = 0; c < children; c++) {
&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++) {
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:
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);