summaryrefslogtreecommitdiff
path: root/usr/src/lib/libzfs
diff options
context:
space:
mode:
authorLin Ling <Lin.Ling@Sun.COM>2010-05-03 14:54:08 -0700
committerLin Ling <Lin.Ling@Sun.COM>2010-05-03 14:54:08 -0700
commit3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5 (patch)
tree195b2b1fa9e897a41897e12fed9b0c6e58d8107e /usr/src/lib/libzfs
parent3113f7cee6785cfe8d9e78c535cf9e2a79283275 (diff)
downloadillumos-gate-3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5.tar.gz
6675946 'zpool status' should show the progress of resilvering for individual disk.
6683750 scrub -s have to wait until resilver completed? 6841252 Resilvering not restartable - causing an excess reboot delay 6855073 spa scrub stats (eg %done) are reset on reboot 6891824 7410 NAS head "continually resilvering" following HDD replacement 6899970 scrub/resilver percent complete reporting in zpool status can be overly optimistic 6940889 add interval (count) args to zpool list 6944623 dbuf_read_done() locking performance improvement 6946760 mutex problem in bplist_enqueue() 6391915 RFE: provide interval arg to zpool status to monitor resilvering 6946512 want zfs_send() to pass back debug info 6943992 'zpool scrub' should not restart the existing scrub silently 6878281 zpool should store the time of last scrub/resilver and other zpool status info in pool properties. 6935158 Assertion failed: used <= spa_get_dspace(dd->dd_pool->dp_spa) 6944388 dsl_dataset_snapshot_reserve_space() causes dp_write_limit=max --HG-- rename : usr/src/uts/common/fs/zfs/dsl_scrub.c => usr/src/uts/common/fs/zfs/dsl_scan.c
Diffstat (limited to 'usr/src/lib/libzfs')
-rw-r--r--usr/src/lib/libzfs/common/libzfs.h14
-rw-r--r--usr/src/lib/libzfs/common/libzfs_pool.c93
-rw-r--r--usr/src/lib/libzfs/common/libzfs_sendrecv.c32
-rw-r--r--usr/src/lib/libzfs/common/libzfs_status.c27
-rw-r--r--usr/src/lib/libzfs/common/libzfs_util.c8
-rw-r--r--usr/src/lib/libzfs/common/mapfile-vers7
6 files changed, 96 insertions, 85 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h
index 7a8d3d769a..6f7fed62c4 100644
--- a/usr/src/lib/libzfs/common/libzfs.h
+++ b/usr/src/lib/libzfs/common/libzfs.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _LIBZFS_H
@@ -119,6 +118,8 @@ enum {
EZFS_PIPEFAILED, /* pipe create failed */
EZFS_THREADCREATEFAILED, /* thread create failed */
EZFS_POSTSPLIT_ONLINE, /* onlining a disk after splitting it */
+ EZFS_SCRUBBING, /* currently scrubbing */
+ EZFS_NO_SCRUB, /* no active scrub */
EZFS_UNKNOWN
};
@@ -224,7 +225,7 @@ typedef struct splitflags {
/*
* Functions to manipulate pool and vdev state
*/
-extern int zpool_scrub(zpool_handle_t *, pool_scrub_type_t);
+extern int zpool_scan(zpool_handle_t *, pool_scan_func_t);
extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
@@ -354,7 +355,7 @@ extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *,
*/
struct zfs_cmd;
-extern const char *hist_event_table[LOG_END];
+extern const char *zfs_history_event_names[LOG_END];
extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *,
boolean_t verbose);
@@ -526,8 +527,9 @@ typedef struct sendflags {
typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
-extern int zfs_send(zfs_handle_t *, const char *, const char *,
- sendflags_t, int, snapfilter_cb_t, void *);
+extern int zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
+ sendflags_t flags, int outfd, snapfilter_cb_t filter_func,
+ void *cb_arg, nvlist_t **debugnvp);
extern int zfs_promote(zfs_handle_t *);
extern int zfs_hold(zfs_handle_t *, const char *, const char *, boolean_t,
diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c
index b212cdeddf..c35d6ab451 100644
--- a/usr/src/lib/libzfs/common/libzfs_pool.c
+++ b/usr/src/lib/libzfs/common/libzfs_pool.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <ctype.h>
@@ -43,50 +42,6 @@
#include "libzfs_impl.h"
#include "zfs_comutil.h"
-const char *hist_event_table[LOG_END] = {
- "invalid event",
- "pool create",
- "vdev add",
- "pool remove",
- "pool destroy",
- "pool export",
- "pool import",
- "vdev attach",
- "vdev replace",
- "vdev detach",
- "vdev online",
- "vdev offline",
- "vdev upgrade",
- "pool clear",
- "pool scrub",
- "pool property set",
- "create",
- "clone",
- "destroy",
- "destroy_begin_sync",
- "inherit",
- "property set",
- "quota set",
- "permission update",
- "permission remove",
- "permission who remove",
- "promote",
- "receive",
- "rename",
- "reservation set",
- "replay_inc_sync",
- "replay_full_sync",
- "rollback",
- "snapshot",
- "filesystem version upgrade",
- "refquota set",
- "refreservation set",
- "pool scrub done",
- "user hold",
- "user release",
- "pool split",
-};
-
static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
#if defined(__i386) || defined(__amd64)
@@ -334,7 +289,8 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
verify(nvlist_lookup_uint64_array(nvroot,
- ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &vsc) == 0);
+ ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
+ == 0);
(void) strlcpy(buf, zpool_state_to_name(intval,
vs->vs_aux), len);
@@ -1558,28 +1514,51 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
}
/*
- * Scrub the pool.
+ * Scan the pool.
*/
int
-zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type)
+zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
{
zfs_cmd_t zc = { 0 };
char msg[1024];
libzfs_handle_t *hdl = zhp->zpool_hdl;
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_cookie = type;
+ zc.zc_cookie = func;
- if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SCRUB, &zc) == 0)
+ if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SCAN, &zc) == 0 ||
+ (errno == ENOENT && func != POOL_SCAN_NONE))
return (0);
- (void) snprintf(msg, sizeof (msg),
- dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
+ if (func == POOL_SCAN_SCRUB) {
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
+ } else if (func == POOL_SCAN_NONE) {
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
+ zc.zc_name);
+ } else {
+ assert(!"unexpected result");
+ }
- if (errno == EBUSY)
- return (zfs_error(hdl, EZFS_RESILVERING, msg));
- else
+ if (errno == EBUSY) {
+ nvlist_t *nvroot;
+ pool_scan_stat_t *ps = NULL;
+ uint_t psc;
+
+ verify(nvlist_lookup_nvlist(zhp->zpool_config,
+ ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+ (void) nvlist_lookup_uint64_array(nvroot,
+ ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
+ if (ps && ps->pss_func == POOL_SCAN_SCRUB)
+ return (zfs_error(hdl, EZFS_SCRUBBING, msg));
+ else
+ return (zfs_error(hdl, EZFS_RESILVERING, msg));
+ } else if (errno == ENOENT) {
+ return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
+ } else {
return (zpool_standard_error(hdl, errno, msg));
+ }
}
/*
@@ -2987,7 +2966,7 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
* open a misbehaving device, which can have undesirable
* effects.
*/
- if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
+ if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
(uint64_t **)&vs, &vsc) != 0 ||
vs->vs_state >= VDEV_STATE_DEGRADED) &&
zhp != NULL &&
diff --git a/usr/src/lib/libzfs/common/libzfs_sendrecv.c b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
index 95031653eb..672e004ef5 100644
--- a/usr/src/lib/libzfs/common/libzfs_sendrecv.c
+++ b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
@@ -852,6 +852,7 @@ typedef struct send_dump_data {
avl_tree_t *fsavl;
snapfilter_cb_t *filter_cb;
void *filter_cb_arg;
+ nvlist_t *debugnv;
} send_dump_data_t;
/*
@@ -860,10 +861,11 @@ typedef struct send_dump_data {
*/
static int
dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
- int outfd, boolean_t enoent_ok, boolean_t *got_enoent)
+ int outfd, boolean_t enoent_ok, boolean_t *got_enoent, nvlist_t *debugnv)
{
zfs_cmd_t zc = { 0 };
libzfs_handle_t *hdl = zhp->zfs_hdl;
+ nvlist_t *thisdbg;
assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
assert(fromsnap == NULL || fromsnap[0] == '\0' || !fromorigin);
@@ -876,11 +878,24 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
*got_enoent = B_FALSE;
+ VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
+ if (fromsnap && fromsnap[0] != '\0') {
+ VERIFY(0 == nvlist_add_string(thisdbg,
+ "fromsnap", fromsnap));
+ }
+
if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SEND, &zc) != 0) {
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"warning: cannot send '%s'"), zhp->zfs_name);
+ VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
+ if (debugnv) {
+ VERIFY(0 == nvlist_add_nvlist(debugnv,
+ zhp->zfs_name, thisdbg));
+ }
+ nvlist_free(thisdbg);
+
switch (errno) {
case EXDEV:
@@ -920,6 +935,10 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
}
}
+ if (debugnv)
+ VERIFY(0 == nvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg));
+ nvlist_free(thisdbg);
+
return (0);
}
@@ -1000,7 +1019,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
err = dump_ioctl(zhp, sdd->prevsnap,
sdd->prevsnap[0] == '\0' && (sdd->fromorigin || sdd->replicate),
- sdd->outfd, B_TRUE, &got_enoent);
+ sdd->outfd, B_TRUE, &got_enoent, sdd->debugnv);
if (got_enoent)
err = 0;
@@ -1176,7 +1195,7 @@ again:
int
zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sendflags_t flags, int outfd, snapfilter_cb_t filter_func,
- void *cb_arg)
+ void *cb_arg, nvlist_t **debugnvp)
{
char errbuf[1024];
send_dump_data_t sdd = { 0 };
@@ -1276,7 +1295,10 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
err = nvlist_pack(hdrnv, &packbuf, &buflen,
NV_ENCODE_XDR, 0);
- nvlist_free(hdrnv);
+ if (debugnvp)
+ *debugnvp = hdrnv;
+ else
+ nvlist_free(hdrnv);
if (err) {
fsavl_destroy(fsavl);
nvlist_free(fss);
@@ -1351,6 +1373,8 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sdd.verbose = flags.verbose;
sdd.filter_cb = filter_func;
sdd.filter_cb_arg = cb_arg;
+ if (debugnvp)
+ sdd.debugnv = *debugnvp;
err = dump_filesystems(zhp, &sdd);
fsavl_destroy(fsavl);
nvlist_free(fss);
diff --git a/usr/src/lib/libzfs/common/libzfs_status.c b/usr/src/lib/libzfs/common/libzfs_status.c
index c4f907733f..24725ec044 100644
--- a/usr/src/lib/libzfs/common/libzfs_status.c
+++ b/usr/src/lib/libzfs/common/libzfs_status.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -138,7 +137,7 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
if (find_vdev_problem(child[c], func))
return (B_TRUE);
} else {
- verify(nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_STATS,
+ verify(nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
(uint64_t **)&vs, &c) == 0);
if (func(vs->vs_state, vs->vs_aux,
@@ -173,7 +172,8 @@ check_status(nvlist_t *config, boolean_t isimport)
{
nvlist_t *nvroot;
vdev_stat_t *vs;
- uint_t vsc;
+ pool_scan_stat_t *ps = NULL;
+ uint_t vsc, psc;
uint64_t nerr;
uint64_t version;
uint64_t stateval;
@@ -184,15 +184,24 @@ check_status(nvlist_t *config, boolean_t isimport)
&version) == 0);
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
- verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
+ verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
(uint64_t **)&vs, &vsc) == 0);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
&stateval) == 0);
- (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
+
+ /*
+ * Currently resilvering a vdev
+ */
+ (void) nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS,
+ (uint64_t **)&ps, &psc);
+ if (ps && ps->pss_func == POOL_SCAN_RESILVER &&
+ ps->pss_state == DSS_SCANNING)
+ return (ZPOOL_STATUS_RESILVERING);
/*
* Pool last accessed by another system.
*/
+ (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
if (hostid != 0 && (unsigned long)hostid != gethostid() &&
stateval == POOL_STATE_ACTIVE)
return (ZPOOL_STATUS_HOSTID_MISMATCH);
@@ -289,12 +298,6 @@ check_status(nvlist_t *config, boolean_t isimport)
return (ZPOOL_STATUS_REMOVED_DEV);
/*
- * Currently resilvering
- */
- if (!vs->vs_scrub_complete && vs->vs_scrub_type == POOL_SCRUB_RESILVER)
- return (ZPOOL_STATUS_RESILVERING);
-
- /*
* Outdated, but usable, version
*/
if (version < SPA_VERSION)
diff --git a/usr/src/lib/libzfs/common/libzfs_util.c b/usr/src/lib/libzfs/common/libzfs_util.c
index 98b56ff79a..2e73f76ea5 100644
--- a/usr/src/lib/libzfs/common/libzfs_util.c
+++ b/usr/src/lib/libzfs/common/libzfs_util.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -215,6 +214,11 @@ libzfs_error_description(libzfs_handle_t *hdl)
case EZFS_POSTSPLIT_ONLINE:
return (dgettext(TEXT_DOMAIN, "disk was split from this pool "
"into a new one"));
+ case EZFS_SCRUBBING:
+ return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
+ "use 'zpool scrub -s' to cancel current scrub"));
+ case EZFS_NO_SCRUB:
+ return (dgettext(TEXT_DOMAIN, "there is no active scrub"));
case EZFS_UNKNOWN:
return (dgettext(TEXT_DOMAIN, "unknown error"));
default:
diff --git a/usr/src/lib/libzfs/common/mapfile-vers b/usr/src/lib/libzfs/common/mapfile-vers
index 376f3ed985..dc68ed9bc2 100644
--- a/usr/src/lib/libzfs/common/mapfile-vers
+++ b/usr/src/lib/libzfs/common/mapfile-vers
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -45,7 +44,6 @@ SUNWprivate_1.1 {
fletcher_4_byteswap;
fletcher_4_incremental_native;
fletcher_4_incremental_byteswap;
- hist_event_table;
libzfs_errno;
libzfs_error_action;
libzfs_error_description;
@@ -73,6 +71,7 @@ SUNWprivate_1.1 {
zfs_get_pool_handle;
zfs_get_user_props;
zfs_get_type;
+ zfs_history_event_names;
zfs_hold;
zfs_hold_range;
zfs_is_mounted;
@@ -195,7 +194,7 @@ SUNWprivate_1.1 {
zpool_prop_values;
zpool_read_label;
zpool_refresh_stats;
- zpool_scrub;
+ zpool_scan;
zpool_search_import;
zpool_set_history_str;
zpool_set_prop;