Update vendor-sys/illumos/dist to illumos-gate 13752:9f5f6c52ba19
Obtained from: ssh://anonhg@hg.illumos.org/illumos-gate
This commit is contained in:
parent
a33497a201
commit
4eca1cfa73
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -157,7 +158,11 @@ zfs_spa_version_map(int zpl_version)
|
||||
return (version);
|
||||
}
|
||||
|
||||
const char *zfs_history_event_names[LOG_END] = {
|
||||
/*
|
||||
* This is the table of legacy internal event names; it should not be modified.
|
||||
* The internal events are now stored in the history log as strings.
|
||||
*/
|
||||
const char *zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS] = {
|
||||
"invalid event",
|
||||
"pool create",
|
||||
"vdev add",
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ZFS_COMUTIL_H
|
||||
@ -37,7 +38,8 @@ extern void zpool_get_rewind_policy(nvlist_t *, zpool_rewind_policy_t *);
|
||||
|
||||
extern int zfs_zpl_version_map(int spa_version);
|
||||
extern int zfs_spa_version_map(int zpl_version);
|
||||
extern const char *zfs_history_event_names[LOG_END];
|
||||
#define ZFS_NUM_LEGACY_HISTORY_EVENTS 41
|
||||
extern const char *zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -22,6 +22,9 @@
|
||||
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common routines used by zfs and zpool property management.
|
||||
@ -129,7 +132,8 @@ zprop_register_hidden(int prop, const char *name, zprop_type_t type,
|
||||
zprop_attr_t attr, int objset_types, const char *colname)
|
||||
{
|
||||
zprop_register_impl(prop, name, type, 0, NULL, attr,
|
||||
objset_types, NULL, colname, B_FALSE, B_FALSE, NULL);
|
||||
objset_types, NULL, colname,
|
||||
type == PROP_TYPE_NUMBER, B_FALSE, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 2010 Robert Milkowski */
|
||||
@ -699,30 +700,33 @@ dmu_objset_create_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
spa_t *spa = dd->dd_pool->dp_spa;
|
||||
struct oscarg *oa = arg2;
|
||||
uint64_t obj;
|
||||
dsl_dataset_t *ds;
|
||||
blkptr_t *bp;
|
||||
|
||||
ASSERT(dmu_tx_is_syncing(tx));
|
||||
|
||||
obj = dsl_dataset_create_sync(dd, oa->lastname,
|
||||
oa->clone_origin, oa->flags, oa->cr, tx);
|
||||
|
||||
if (oa->clone_origin == NULL) {
|
||||
dsl_pool_t *dp = dd->dd_pool;
|
||||
dsl_dataset_t *ds;
|
||||
blkptr_t *bp;
|
||||
objset_t *os;
|
||||
|
||||
VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, obj, FTAG, &ds));
|
||||
bp = dsl_dataset_get_blkptr(ds);
|
||||
ASSERT(BP_IS_HOLE(bp));
|
||||
|
||||
os = dmu_objset_create_impl(spa, ds, bp, oa->type, tx);
|
||||
VERIFY3U(0, ==, dsl_dataset_hold_obj(dd->dd_pool, obj, FTAG, &ds));
|
||||
bp = dsl_dataset_get_blkptr(ds);
|
||||
if (BP_IS_HOLE(bp)) {
|
||||
objset_t *os =
|
||||
dmu_objset_create_impl(spa, ds, bp, oa->type, tx);
|
||||
|
||||
if (oa->userfunc)
|
||||
oa->userfunc(os, oa->userarg, oa->cr, tx);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
}
|
||||
|
||||
spa_history_log_internal(LOG_DS_CREATE, spa, tx, "dataset = %llu", obj);
|
||||
if (oa->clone_origin == NULL) {
|
||||
spa_history_log_internal_ds(ds, "create", tx, "");
|
||||
} else {
|
||||
char namebuf[MAXNAMELEN];
|
||||
dsl_dataset_name(oa->clone_origin, namebuf);
|
||||
spa_history_log_internal_ds(ds, "clone", tx,
|
||||
"origin=%s (%llu)", namebuf, oa->clone_origin->ds_object);
|
||||
}
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
}
|
||||
|
||||
int
|
||||
@ -799,34 +803,40 @@ dmu_objset_destroy(const char *name, boolean_t defer)
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct snaparg {
|
||||
dsl_sync_task_group_t *dstg;
|
||||
char *snapname;
|
||||
char *htag;
|
||||
char failed[MAXPATHLEN];
|
||||
boolean_t recursive;
|
||||
boolean_t needsuspend;
|
||||
boolean_t temporary;
|
||||
nvlist_t *props;
|
||||
struct dsl_ds_holdarg *ha; /* only needed in the temporary case */
|
||||
dsl_dataset_t *newds;
|
||||
};
|
||||
typedef struct snapallarg {
|
||||
dsl_sync_task_group_t *saa_dstg;
|
||||
boolean_t saa_needsuspend;
|
||||
nvlist_t *saa_props;
|
||||
|
||||
/* the following are used only if 'temporary' is set: */
|
||||
boolean_t saa_temporary;
|
||||
const char *saa_htag;
|
||||
struct dsl_ds_holdarg *saa_ha;
|
||||
dsl_dataset_t *saa_newds;
|
||||
} snapallarg_t;
|
||||
|
||||
typedef struct snaponearg {
|
||||
const char *soa_longname; /* long snap name */
|
||||
const char *soa_snapname; /* short snap name */
|
||||
snapallarg_t *soa_saa;
|
||||
} snaponearg_t;
|
||||
|
||||
static int
|
||||
snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
objset_t *os = arg1;
|
||||
struct snaparg *sn = arg2;
|
||||
snaponearg_t *soa = arg2;
|
||||
snapallarg_t *saa = soa->soa_saa;
|
||||
int error;
|
||||
|
||||
/* The props have already been checked by zfs_check_userprops(). */
|
||||
|
||||
error = dsl_dataset_snapshot_check(os->os_dsl_dataset,
|
||||
sn->snapname, tx);
|
||||
soa->soa_snapname, tx);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
if (sn->temporary) {
|
||||
if (saa->saa_temporary) {
|
||||
/*
|
||||
* Ideally we would just call
|
||||
* dsl_dataset_user_hold_check() and
|
||||
@ -844,12 +854,13 @@ snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
* Not checking number of tags because the tag will be
|
||||
* unique, as it will be the only tag.
|
||||
*/
|
||||
if (strlen(sn->htag) + MAX_TAG_PREFIX_LEN >= MAXNAMELEN)
|
||||
if (strlen(saa->saa_htag) + MAX_TAG_PREFIX_LEN >= MAXNAMELEN)
|
||||
return (E2BIG);
|
||||
|
||||
sn->ha = kmem_alloc(sizeof (struct dsl_ds_holdarg), KM_SLEEP);
|
||||
sn->ha->temphold = B_TRUE;
|
||||
sn->ha->htag = sn->htag;
|
||||
saa->saa_ha = kmem_alloc(sizeof (struct dsl_ds_holdarg),
|
||||
KM_SLEEP);
|
||||
saa->saa_ha->temphold = B_TRUE;
|
||||
saa->saa_ha->htag = saa->saa_htag;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
@ -859,24 +870,25 @@ snapshot_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
objset_t *os = arg1;
|
||||
dsl_dataset_t *ds = os->os_dsl_dataset;
|
||||
struct snaparg *sn = arg2;
|
||||
snaponearg_t *soa = arg2;
|
||||
snapallarg_t *saa = soa->soa_saa;
|
||||
|
||||
dsl_dataset_snapshot_sync(ds, sn->snapname, tx);
|
||||
dsl_dataset_snapshot_sync(ds, soa->soa_snapname, tx);
|
||||
|
||||
if (sn->props) {
|
||||
if (saa->saa_props != NULL) {
|
||||
dsl_props_arg_t pa;
|
||||
pa.pa_props = sn->props;
|
||||
pa.pa_props = saa->saa_props;
|
||||
pa.pa_source = ZPROP_SRC_LOCAL;
|
||||
dsl_props_set_sync(ds->ds_prev, &pa, tx);
|
||||
}
|
||||
|
||||
if (sn->temporary) {
|
||||
if (saa->saa_temporary) {
|
||||
struct dsl_ds_destroyarg da;
|
||||
|
||||
dsl_dataset_user_hold_sync(ds->ds_prev, sn->ha, tx);
|
||||
kmem_free(sn->ha, sizeof (struct dsl_ds_holdarg));
|
||||
sn->ha = NULL;
|
||||
sn->newds = ds->ds_prev;
|
||||
dsl_dataset_user_hold_sync(ds->ds_prev, saa->saa_ha, tx);
|
||||
kmem_free(saa->saa_ha, sizeof (struct dsl_ds_holdarg));
|
||||
saa->saa_ha = NULL;
|
||||
saa->saa_newds = ds->ds_prev;
|
||||
|
||||
da.ds = ds->ds_prev;
|
||||
da.defer = B_TRUE;
|
||||
@ -885,131 +897,180 @@ snapshot_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
static int
|
||||
dmu_objset_snapshot_one(const char *name, void *arg)
|
||||
snapshot_one_impl(const char *snapname, void *arg)
|
||||
{
|
||||
struct snaparg *sn = arg;
|
||||
char fsname[MAXPATHLEN];
|
||||
snapallarg_t *saa = arg;
|
||||
snaponearg_t *soa;
|
||||
objset_t *os;
|
||||
int err;
|
||||
char *cp;
|
||||
|
||||
/*
|
||||
* If the objset starts with a '%', then ignore it unless it was
|
||||
* explicitly named (ie, not recursive). These hidden datasets
|
||||
* are always inconsistent, and by not opening them here, we can
|
||||
* avoid a race with dsl_dir_destroy_check().
|
||||
*/
|
||||
cp = strrchr(name, '/');
|
||||
if (cp && cp[1] == '%' && sn->recursive)
|
||||
return (0);
|
||||
(void) strlcpy(fsname, snapname, sizeof (fsname));
|
||||
strchr(fsname, '@')[0] = '\0';
|
||||
|
||||
(void) strcpy(sn->failed, name);
|
||||
|
||||
/*
|
||||
* Check permissions if we are doing a recursive snapshot. The
|
||||
* permission checks for the starting dataset have already been
|
||||
* performed in zfs_secpolicy_snapshot()
|
||||
*/
|
||||
if (sn->recursive && (err = zfs_secpolicy_snapshot_perms(name, CRED())))
|
||||
return (err);
|
||||
|
||||
err = dmu_objset_hold(name, sn, &os);
|
||||
err = dmu_objset_hold(fsname, saa, &os);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
/*
|
||||
* If the objset is in an inconsistent state (eg, in the process
|
||||
* of being destroyed), don't snapshot it. As with %hidden
|
||||
* datasets, we return EBUSY if this name was explicitly
|
||||
* requested (ie, not recursive), and otherwise ignore it.
|
||||
* of being destroyed), don't snapshot it.
|
||||
*/
|
||||
if (os->os_dsl_dataset->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) {
|
||||
dmu_objset_rele(os, sn);
|
||||
return (sn->recursive ? 0 : EBUSY);
|
||||
dmu_objset_rele(os, saa);
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
if (sn->needsuspend) {
|
||||
if (saa->saa_needsuspend) {
|
||||
err = zil_suspend(dmu_objset_zil(os));
|
||||
if (err) {
|
||||
dmu_objset_rele(os, sn);
|
||||
dmu_objset_rele(os, saa);
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
dsl_sync_task_create(sn->dstg, snapshot_check, snapshot_sync,
|
||||
os, sn, 3);
|
||||
|
||||
soa = kmem_zalloc(sizeof (*soa), KM_SLEEP);
|
||||
soa->soa_saa = saa;
|
||||
soa->soa_longname = snapname;
|
||||
soa->soa_snapname = strchr(snapname, '@') + 1;
|
||||
|
||||
dsl_sync_task_create(saa->saa_dstg, snapshot_check, snapshot_sync,
|
||||
os, soa, 3);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The snapshots must all be in the same pool.
|
||||
*/
|
||||
int
|
||||
dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
|
||||
nvlist_t *props, boolean_t recursive, boolean_t temporary, int cleanup_fd)
|
||||
dmu_objset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors)
|
||||
{
|
||||
dsl_sync_task_t *dst;
|
||||
struct snaparg sn;
|
||||
snapallarg_t saa = { 0 };
|
||||
spa_t *spa;
|
||||
int rv = 0;
|
||||
int err;
|
||||
nvpair_t *pair;
|
||||
|
||||
pair = nvlist_next_nvpair(snaps, NULL);
|
||||
if (pair == NULL)
|
||||
return (0);
|
||||
|
||||
err = spa_open(nvpair_name(pair), &spa, FTAG);
|
||||
if (err)
|
||||
return (err);
|
||||
saa.saa_dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
|
||||
saa.saa_props = props;
|
||||
saa.saa_needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
|
||||
|
||||
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
|
||||
pair = nvlist_next_nvpair(snaps, pair)) {
|
||||
err = snapshot_one_impl(nvpair_name(pair), &saa);
|
||||
if (err != 0) {
|
||||
if (errors != NULL) {
|
||||
fnvlist_add_int32(errors,
|
||||
nvpair_name(pair), err);
|
||||
}
|
||||
rv = err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If any call to snapshot_one_impl() failed, don't execute the
|
||||
* sync task. The error handling code below will clean up the
|
||||
* snaponearg_t from any successful calls to
|
||||
* snapshot_one_impl().
|
||||
*/
|
||||
if (rv == 0)
|
||||
err = dsl_sync_task_group_wait(saa.saa_dstg);
|
||||
if (err != 0)
|
||||
rv = err;
|
||||
|
||||
for (dst = list_head(&saa.saa_dstg->dstg_tasks); dst;
|
||||
dst = list_next(&saa.saa_dstg->dstg_tasks, dst)) {
|
||||
objset_t *os = dst->dst_arg1;
|
||||
snaponearg_t *soa = dst->dst_arg2;
|
||||
if (dst->dst_err != 0) {
|
||||
if (errors != NULL) {
|
||||
fnvlist_add_int32(errors,
|
||||
soa->soa_longname, dst->dst_err);
|
||||
}
|
||||
rv = dst->dst_err;
|
||||
}
|
||||
|
||||
if (saa.saa_needsuspend)
|
||||
zil_resume(dmu_objset_zil(os));
|
||||
dmu_objset_rele(os, &saa);
|
||||
kmem_free(soa, sizeof (*soa));
|
||||
}
|
||||
|
||||
dsl_sync_task_group_destroy(saa.saa_dstg);
|
||||
spa_close(spa, FTAG);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
dmu_objset_snapshot_one(const char *fsname, const char *snapname)
|
||||
{
|
||||
int err;
|
||||
char *longsnap = kmem_asprintf("%s@%s", fsname, snapname);
|
||||
nvlist_t *snaps = fnvlist_alloc();
|
||||
|
||||
fnvlist_add_boolean(snaps, longsnap);
|
||||
err = dmu_objset_snapshot(snaps, NULL, NULL);
|
||||
fnvlist_free(snaps);
|
||||
strfree(longsnap);
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
dmu_objset_snapshot_tmp(const char *snapname, const char *tag, int cleanup_fd)
|
||||
{
|
||||
dsl_sync_task_t *dst;
|
||||
snapallarg_t saa = { 0 };
|
||||
spa_t *spa;
|
||||
minor_t minor;
|
||||
int err;
|
||||
|
||||
(void) strcpy(sn.failed, fsname);
|
||||
|
||||
err = spa_open(fsname, &spa, FTAG);
|
||||
err = spa_open(snapname, &spa, FTAG);
|
||||
if (err)
|
||||
return (err);
|
||||
saa.saa_dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
|
||||
saa.saa_htag = tag;
|
||||
saa.saa_needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
|
||||
saa.saa_temporary = B_TRUE;
|
||||
|
||||
if (temporary) {
|
||||
if (cleanup_fd < 0) {
|
||||
spa_close(spa, FTAG);
|
||||
return (EINVAL);
|
||||
}
|
||||
if ((err = zfs_onexit_fd_hold(cleanup_fd, &minor)) != 0) {
|
||||
spa_close(spa, FTAG);
|
||||
return (err);
|
||||
}
|
||||
if (cleanup_fd < 0) {
|
||||
spa_close(spa, FTAG);
|
||||
return (EINVAL);
|
||||
}
|
||||
if ((err = zfs_onexit_fd_hold(cleanup_fd, &minor)) != 0) {
|
||||
spa_close(spa, FTAG);
|
||||
return (err);
|
||||
}
|
||||
|
||||
sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
|
||||
sn.snapname = snapname;
|
||||
sn.htag = tag;
|
||||
sn.props = props;
|
||||
sn.recursive = recursive;
|
||||
sn.needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
|
||||
sn.temporary = temporary;
|
||||
sn.ha = NULL;
|
||||
sn.newds = NULL;
|
||||
|
||||
if (recursive) {
|
||||
err = dmu_objset_find(fsname,
|
||||
dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN);
|
||||
} else {
|
||||
err = dmu_objset_snapshot_one(fsname, &sn);
|
||||
}
|
||||
err = snapshot_one_impl(snapname, &saa);
|
||||
|
||||
if (err == 0)
|
||||
err = dsl_sync_task_group_wait(sn.dstg);
|
||||
err = dsl_sync_task_group_wait(saa.saa_dstg);
|
||||
|
||||
for (dst = list_head(&sn.dstg->dstg_tasks); dst;
|
||||
dst = list_next(&sn.dstg->dstg_tasks, dst)) {
|
||||
for (dst = list_head(&saa.saa_dstg->dstg_tasks); dst;
|
||||
dst = list_next(&saa.saa_dstg->dstg_tasks, dst)) {
|
||||
objset_t *os = dst->dst_arg1;
|
||||
dsl_dataset_t *ds = os->os_dsl_dataset;
|
||||
if (dst->dst_err) {
|
||||
dsl_dataset_name(ds, sn.failed);
|
||||
} else if (temporary) {
|
||||
dsl_register_onexit_hold_cleanup(sn.newds, tag, minor);
|
||||
}
|
||||
if (sn.needsuspend)
|
||||
dsl_register_onexit_hold_cleanup(saa.saa_newds, tag, minor);
|
||||
if (saa.saa_needsuspend)
|
||||
zil_resume(dmu_objset_zil(os));
|
||||
dmu_objset_rele(os, &sn);
|
||||
dmu_objset_rele(os, &saa);
|
||||
}
|
||||
|
||||
if (err)
|
||||
(void) strcpy(fsname, sn.failed);
|
||||
if (temporary)
|
||||
zfs_onexit_fd_rele(cleanup_fd);
|
||||
dsl_sync_task_group_destroy(sn.dstg);
|
||||
zfs_onexit_fd_rele(cleanup_fd);
|
||||
dsl_sync_task_group_destroy(saa.saa_dstg);
|
||||
spa_close(spa, FTAG);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dmu_objset_sync_dnodes(list_t *list, list_t *newlist, dmu_tx_t *tx)
|
||||
{
|
||||
|
@ -387,9 +387,48 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if 'earlier' is an earlier snapshot in 'later's timeline.
|
||||
* For example, they could both be snapshots of the same filesystem, and
|
||||
* 'earlier' is before 'later'. Or 'earlier' could be the origin of
|
||||
* 'later's filesystem. Or 'earlier' could be an older snapshot in the origin's
|
||||
* filesystem. Or 'earlier' could be the origin's origin.
|
||||
*/
|
||||
static boolean_t
|
||||
is_before(dsl_dataset_t *later, dsl_dataset_t *earlier)
|
||||
{
|
||||
dsl_pool_t *dp = later->ds_dir->dd_pool;
|
||||
int error;
|
||||
boolean_t ret;
|
||||
dsl_dataset_t *origin;
|
||||
|
||||
if (earlier->ds_phys->ds_creation_txg >=
|
||||
later->ds_phys->ds_creation_txg)
|
||||
return (B_FALSE);
|
||||
|
||||
if (later->ds_dir == earlier->ds_dir)
|
||||
return (B_TRUE);
|
||||
if (!dsl_dir_is_clone(later->ds_dir))
|
||||
return (B_FALSE);
|
||||
|
||||
rw_enter(&dp->dp_config_rwlock, RW_READER);
|
||||
if (later->ds_dir->dd_phys->dd_origin_obj == earlier->ds_object) {
|
||||
rw_exit(&dp->dp_config_rwlock);
|
||||
return (B_TRUE);
|
||||
}
|
||||
error = dsl_dataset_hold_obj(dp,
|
||||
later->ds_dir->dd_phys->dd_origin_obj, FTAG, &origin);
|
||||
rw_exit(&dp->dp_config_rwlock);
|
||||
if (error != 0)
|
||||
return (B_FALSE);
|
||||
ret = is_before(origin, earlier);
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
int outfd, vnode_t *vp, offset_t *off)
|
||||
dmu_send(objset_t *tosnap, objset_t *fromsnap, int outfd, vnode_t *vp,
|
||||
offset_t *off)
|
||||
{
|
||||
dsl_dataset_t *ds = tosnap->os_dsl_dataset;
|
||||
dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
|
||||
@ -402,30 +441,13 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
if (ds->ds_phys->ds_next_snap_obj == 0)
|
||||
return (EINVAL);
|
||||
|
||||
/* fromsnap must be an earlier snapshot from the same fs as tosnap */
|
||||
if (fromds && (ds->ds_dir != fromds->ds_dir ||
|
||||
fromds->ds_phys->ds_creation_txg >= ds->ds_phys->ds_creation_txg))
|
||||
/*
|
||||
* fromsnap must be an earlier snapshot from the same fs as tosnap,
|
||||
* or the origin's fs.
|
||||
*/
|
||||
if (fromds != NULL && !is_before(ds, fromds))
|
||||
return (EXDEV);
|
||||
|
||||
if (fromorigin) {
|
||||
dsl_pool_t *dp = ds->ds_dir->dd_pool;
|
||||
|
||||
if (fromsnap)
|
||||
return (EINVAL);
|
||||
|
||||
if (dsl_dir_is_clone(ds->ds_dir)) {
|
||||
rw_enter(&dp->dp_config_rwlock, RW_READER);
|
||||
err = dsl_dataset_hold_obj(dp,
|
||||
ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &fromds);
|
||||
rw_exit(&dp->dp_config_rwlock);
|
||||
if (err)
|
||||
return (err);
|
||||
} else {
|
||||
fromorigin = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drr = kmem_zalloc(sizeof (dmu_replay_record_t), KM_SLEEP);
|
||||
drr->drr_type = DRR_BEGIN;
|
||||
drr->drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
|
||||
@ -450,7 +472,7 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
drr->drr_u.drr_begin.drr_creation_time =
|
||||
ds->ds_phys->ds_creation_time;
|
||||
drr->drr_u.drr_begin.drr_type = tosnap->os_phys->os_type;
|
||||
if (fromorigin)
|
||||
if (fromds != NULL && ds->ds_dir != fromds->ds_dir)
|
||||
drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE;
|
||||
drr->drr_u.drr_begin.drr_toguid = ds->ds_phys->ds_guid;
|
||||
if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET)
|
||||
@ -462,8 +484,6 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
|
||||
if (fromds)
|
||||
fromtxg = fromds->ds_phys->ds_creation_txg;
|
||||
if (fromorigin)
|
||||
dsl_dataset_rele(fromds, FTAG);
|
||||
|
||||
dsp = kmem_zalloc(sizeof (dmu_sendarg_t), KM_SLEEP);
|
||||
|
||||
@ -521,8 +541,7 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
}
|
||||
|
||||
int
|
||||
dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
uint64_t *sizep)
|
||||
dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, uint64_t *sizep)
|
||||
{
|
||||
dsl_dataset_t *ds = tosnap->os_dsl_dataset;
|
||||
dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
|
||||
@ -534,27 +553,13 @@ dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
if (ds->ds_phys->ds_next_snap_obj == 0)
|
||||
return (EINVAL);
|
||||
|
||||
/* fromsnap must be an earlier snapshot from the same fs as tosnap */
|
||||
if (fromds && (ds->ds_dir != fromds->ds_dir ||
|
||||
fromds->ds_phys->ds_creation_txg >= ds->ds_phys->ds_creation_txg))
|
||||
/*
|
||||
* fromsnap must be an earlier snapshot from the same fs as tosnap,
|
||||
* or the origin's fs.
|
||||
*/
|
||||
if (fromds != NULL && !is_before(ds, fromds))
|
||||
return (EXDEV);
|
||||
|
||||
if (fromorigin) {
|
||||
if (fromsnap)
|
||||
return (EINVAL);
|
||||
|
||||
if (dsl_dir_is_clone(ds->ds_dir)) {
|
||||
rw_enter(&dp->dp_config_rwlock, RW_READER);
|
||||
err = dsl_dataset_hold_obj(dp,
|
||||
ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &fromds);
|
||||
rw_exit(&dp->dp_config_rwlock);
|
||||
if (err)
|
||||
return (err);
|
||||
} else {
|
||||
fromorigin = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get uncompressed size estimate of changed data. */
|
||||
if (fromds == NULL) {
|
||||
size = ds->ds_phys->ds_uncompressed_bytes;
|
||||
@ -562,8 +567,6 @@ dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
uint64_t used, comp;
|
||||
err = dsl_dataset_space_written(fromds, ds,
|
||||
&used, &comp, &size);
|
||||
if (fromorigin)
|
||||
dsl_dataset_rele(fromds, FTAG);
|
||||
if (err)
|
||||
return (err);
|
||||
}
|
||||
@ -662,8 +665,7 @@ recv_new_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
rbsa->ds, &rbsa->ds->ds_phys->ds_bp, rbsa->type, tx);
|
||||
}
|
||||
|
||||
spa_history_log_internal(LOG_DS_REPLAY_FULL_SYNC,
|
||||
dd->dd_pool->dp_spa, tx, "dataset = %lld", dsobj);
|
||||
spa_history_log_internal_ds(rbsa->ds, "receive new", tx, "");
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -764,8 +766,7 @@ recv_existing_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
|
||||
rbsa->ds = cds;
|
||||
|
||||
spa_history_log_internal(LOG_DS_REPLAY_INC_SYNC,
|
||||
dp->dp_spa, tx, "dataset = %lld", dsobj);
|
||||
spa_history_log_internal_ds(cds, "receive over existing", tx, "");
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
@ -1573,6 +1574,7 @@ recv_end_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_phys->ds_flags &= ~DS_FLAG_INCONSISTENT;
|
||||
spa_history_log_internal_ds(ds, "finished receiving", tx, "");
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -48,7 +48,7 @@ dmu_tx_create_dd(dsl_dir_t *dd)
|
||||
{
|
||||
dmu_tx_t *tx = kmem_zalloc(sizeof (dmu_tx_t), KM_SLEEP);
|
||||
tx->tx_dir = dd;
|
||||
if (dd)
|
||||
if (dd != NULL)
|
||||
tx->tx_pool = dd->dd_pool;
|
||||
list_create(&tx->tx_holds, sizeof (dmu_tx_hold_t),
|
||||
offsetof(dmu_tx_hold_t, txh_node));
|
||||
|
@ -914,7 +914,8 @@ dsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname,
|
||||
* The snapshots must all be in the same pool.
|
||||
*/
|
||||
int
|
||||
dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer, char *failed)
|
||||
dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer,
|
||||
nvlist_t *errlist)
|
||||
{
|
||||
int err;
|
||||
dsl_sync_task_t *dst;
|
||||
@ -949,7 +950,7 @@ dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer, char *failed)
|
||||
} else if (err == ENOENT) {
|
||||
err = 0;
|
||||
} else {
|
||||
(void) strcpy(failed, nvpair_name(pair));
|
||||
fnvlist_add_int32(errlist, nvpair_name(pair), err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -963,10 +964,12 @@ dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer, char *failed)
|
||||
dsl_dataset_t *ds = dsda->ds;
|
||||
|
||||
/*
|
||||
* Return the file system name that triggered the error
|
||||
* Return the snapshots that triggered the error.
|
||||
*/
|
||||
if (dst->dst_err) {
|
||||
dsl_dataset_name(ds, failed);
|
||||
if (dst->dst_err != 0) {
|
||||
char name[ZFS_MAXNAMELEN];
|
||||
dsl_dataset_name(ds, name);
|
||||
fnvlist_add_int32(errlist, name, dst->dst_err);
|
||||
}
|
||||
ASSERT3P(dsda->rm_origin, ==, NULL);
|
||||
dsl_dataset_disown(ds, dstg);
|
||||
@ -1045,7 +1048,6 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
|
||||
dsl_dir_t *dd;
|
||||
uint64_t obj;
|
||||
struct dsl_ds_destroyarg dsda = { 0 };
|
||||
dsl_dataset_t dummy_ds = { 0 };
|
||||
|
||||
dsda.ds = ds;
|
||||
|
||||
@ -1065,8 +1067,6 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
|
||||
}
|
||||
|
||||
dd = ds->ds_dir;
|
||||
dummy_ds.ds_dir = dd;
|
||||
dummy_ds.ds_object = ds->ds_object;
|
||||
|
||||
/*
|
||||
* Check for errors and mark this ds as inconsistent, in
|
||||
@ -1153,7 +1153,7 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
|
||||
dsl_sync_task_create(dstg, dsl_dataset_destroy_check,
|
||||
dsl_dataset_destroy_sync, &dsda, tag, 0);
|
||||
dsl_sync_task_create(dstg, dsl_dir_destroy_check,
|
||||
dsl_dir_destroy_sync, &dummy_ds, FTAG, 0);
|
||||
dsl_dir_destroy_sync, dd, FTAG, 0);
|
||||
err = dsl_sync_task_group_wait(dstg);
|
||||
dsl_sync_task_group_destroy(dstg);
|
||||
|
||||
@ -1328,14 +1328,12 @@ static void
|
||||
dsl_dataset_destroy_begin_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
dsl_pool_t *dp = ds->ds_dir->dd_pool;
|
||||
|
||||
/* Mark it as inconsistent on-disk, in case we crash */
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT;
|
||||
|
||||
spa_history_log_internal(LOG_DS_DESTROY_BEGIN, dp->dp_spa, tx,
|
||||
"dataset = %llu", ds->ds_object);
|
||||
spa_history_log_internal_ds(ds, "destroy begin", tx, "");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1660,9 +1658,13 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
|
||||
ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_phys->ds_flags |= DS_FLAG_DEFER_DESTROY;
|
||||
spa_history_log_internal_ds(ds, "defer_destroy", tx, "");
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need to log before removing it from the namespace. */
|
||||
spa_history_log_internal_ds(ds, "destroy", tx, "");
|
||||
|
||||
/* signal any waiters that this dataset is going away */
|
||||
mutex_enter(&ds->ds_lock);
|
||||
ds->ds_owner = dsl_reaper;
|
||||
@ -1957,8 +1959,6 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
|
||||
dsl_dataset_rele(ds_prev, FTAG);
|
||||
|
||||
spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx);
|
||||
spa_history_log_internal(LOG_DS_DESTROY, dp->dp_spa, tx,
|
||||
"dataset = %llu", ds->ds_object);
|
||||
|
||||
if (ds->ds_phys->ds_next_clones_obj != 0) {
|
||||
uint64_t count;
|
||||
@ -2006,7 +2006,7 @@ dsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
return (ENOSPC);
|
||||
|
||||
/*
|
||||
* Propogate any reserved space for this snapshot to other
|
||||
* Propagate any reserved space for this snapshot to other
|
||||
* snapshot checks in this sync group.
|
||||
*/
|
||||
if (asize > 0)
|
||||
@ -2016,10 +2016,9 @@ dsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
int
|
||||
dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dsl_dataset_snapshot_check(dsl_dataset_t *ds, const char *snapname,
|
||||
dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
const char *snapname = arg2;
|
||||
int err;
|
||||
uint64_t value;
|
||||
|
||||
@ -2031,7 +2030,7 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
return (EAGAIN);
|
||||
|
||||
/*
|
||||
* Check for conflicting name snapshot name.
|
||||
* Check for conflicting snapshot name.
|
||||
*/
|
||||
err = dsl_dataset_snap_lookup(ds, snapname, &value);
|
||||
if (err == 0)
|
||||
@ -2055,10 +2054,9 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
void
|
||||
dsl_dataset_snapshot_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dsl_dataset_snapshot_sync(dsl_dataset_t *ds, const char *snapname,
|
||||
dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
const char *snapname = arg2;
|
||||
dsl_pool_t *dp = ds->ds_dir->dd_pool;
|
||||
dmu_buf_t *dbuf;
|
||||
dsl_dataset_phys_t *dsphys;
|
||||
@ -2164,8 +2162,7 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
|
||||
dsl_dir_snap_cmtime_update(ds->ds_dir);
|
||||
|
||||
spa_history_log_internal(LOG_DS_SNAPSHOT, dp->dp_spa, tx,
|
||||
"dataset = %llu", dsobj);
|
||||
spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, "");
|
||||
}
|
||||
|
||||
void
|
||||
@ -2252,7 +2249,20 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
|
||||
{
|
||||
uint64_t refd, avail, uobjs, aobjs, ratio;
|
||||
|
||||
dsl_dir_stats(ds->ds_dir, nv);
|
||||
ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
|
||||
(ds->ds_phys->ds_uncompressed_bytes * 100 /
|
||||
ds->ds_phys->ds_compressed_bytes);
|
||||
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
|
||||
|
||||
if (dsl_dataset_is_snapshot(ds)) {
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
|
||||
ds->ds_phys->ds_unique_bytes);
|
||||
get_clones_stat(ds, nv);
|
||||
} else {
|
||||
dsl_dir_stats(ds->ds_dir, nv);
|
||||
}
|
||||
|
||||
dsl_dataset_space(ds, &refd, &avail, &uobjs, &aobjs);
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE, avail);
|
||||
@ -2297,22 +2307,6 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
|
||||
}
|
||||
}
|
||||
|
||||
ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
|
||||
(ds->ds_phys->ds_uncompressed_bytes * 100 /
|
||||
ds->ds_phys->ds_compressed_bytes);
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
|
||||
|
||||
if (ds->ds_phys->ds_next_snap_obj) {
|
||||
/*
|
||||
* This is a snapshot; override the dd's space used with
|
||||
* our unique space and compression ratio.
|
||||
*/
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
|
||||
ds->ds_phys->ds_unique_bytes);
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
|
||||
|
||||
get_clones_stat(ds, nv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2321,27 +2315,25 @@ dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat)
|
||||
stat->dds_creation_txg = ds->ds_phys->ds_creation_txg;
|
||||
stat->dds_inconsistent = ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT;
|
||||
stat->dds_guid = ds->ds_phys->ds_guid;
|
||||
if (ds->ds_phys->ds_next_snap_obj) {
|
||||
stat->dds_origin[0] = '\0';
|
||||
if (dsl_dataset_is_snapshot(ds)) {
|
||||
stat->dds_is_snapshot = B_TRUE;
|
||||
stat->dds_num_clones = ds->ds_phys->ds_num_children - 1;
|
||||
} else {
|
||||
stat->dds_is_snapshot = B_FALSE;
|
||||
stat->dds_num_clones = 0;
|
||||
}
|
||||
|
||||
/* clone origin is really a dsl_dir thing... */
|
||||
rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
|
||||
if (dsl_dir_is_clone(ds->ds_dir)) {
|
||||
dsl_dataset_t *ods;
|
||||
rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
|
||||
if (dsl_dir_is_clone(ds->ds_dir)) {
|
||||
dsl_dataset_t *ods;
|
||||
|
||||
VERIFY(0 == dsl_dataset_get_ref(ds->ds_dir->dd_pool,
|
||||
ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &ods));
|
||||
dsl_dataset_name(ods, stat->dds_origin);
|
||||
dsl_dataset_drop_ref(ods, FTAG);
|
||||
} else {
|
||||
stat->dds_origin[0] = '\0';
|
||||
VERIFY(0 == dsl_dataset_get_ref(ds->ds_dir->dd_pool,
|
||||
ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &ods));
|
||||
dsl_dataset_name(ods, stat->dds_origin);
|
||||
dsl_dataset_drop_ref(ods, FTAG);
|
||||
}
|
||||
rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
|
||||
}
|
||||
rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
@ -2458,8 +2450,8 @@ dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
ds->ds_snapname, 8, 1, &ds->ds_object, tx);
|
||||
ASSERT3U(err, ==, 0);
|
||||
|
||||
spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx,
|
||||
"dataset = %llu", ds->ds_object);
|
||||
spa_history_log_internal_ds(ds, "rename", tx,
|
||||
"-> @%s", newsnapname);
|
||||
dsl_dataset_rele(hds, FTAG);
|
||||
}
|
||||
|
||||
@ -2939,8 +2931,7 @@ dsl_dataset_promote_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
origin_ds->ds_phys->ds_unique_bytes = pa->unique;
|
||||
|
||||
/* log history record */
|
||||
spa_history_log_internal(LOG_DS_PROMOTE, dd->dd_pool->dp_spa, tx,
|
||||
"dataset = %llu", hds->ds_object);
|
||||
spa_history_log_internal_ds(hds, "promote", tx, "");
|
||||
|
||||
dsl_dir_close(odd, FTAG);
|
||||
}
|
||||
@ -3298,6 +3289,9 @@ dsl_dataset_clone_swap_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
csa->ohds->ds_phys->ds_deadlist_obj);
|
||||
|
||||
dsl_scan_ds_clone_swapped(csa->ohds, csa->cds, tx);
|
||||
|
||||
spa_history_log_internal_ds(csa->cds, "clone swap", tx,
|
||||
"parent=%s", csa->ohds->ds_dir->dd_myname);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3454,9 +3448,8 @@ dsl_dataset_set_quota_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_quota = effective_value;
|
||||
|
||||
spa_history_log_internal(LOG_DS_REFQUOTA,
|
||||
ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu ",
|
||||
(longlong_t)ds->ds_quota, ds->ds_object);
|
||||
spa_history_log_internal_ds(ds, "set refquota", tx,
|
||||
"refquota=%lld", (longlong_t)ds->ds_quota);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3561,9 +3554,8 @@ dsl_dataset_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
|
||||
mutex_exit(&ds->ds_dir->dd_lock);
|
||||
|
||||
spa_history_log_internal(LOG_DS_REFRESERV,
|
||||
ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu",
|
||||
(longlong_t)effective_value, ds->ds_object);
|
||||
spa_history_log_internal_ds(ds, "set refreservation", tx,
|
||||
"refreservation=%lld", (longlong_t)effective_value);
|
||||
}
|
||||
|
||||
int
|
||||
@ -3629,7 +3621,7 @@ dsl_dataset_user_hold_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
struct dsl_ds_holdarg *ha = arg2;
|
||||
char *htag = ha->htag;
|
||||
const char *htag = ha->htag;
|
||||
objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
|
||||
int error = 0;
|
||||
|
||||
@ -3663,7 +3655,7 @@ dsl_dataset_user_hold_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
struct dsl_ds_holdarg *ha = arg2;
|
||||
char *htag = ha->htag;
|
||||
const char *htag = ha->htag;
|
||||
dsl_pool_t *dp = ds->ds_dir->dd_pool;
|
||||
objset_t *mos = dp->dp_meta_objset;
|
||||
uint64_t now = gethrestime_sec();
|
||||
@ -3691,9 +3683,9 @@ dsl_dataset_user_hold_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
htag, &now, tx));
|
||||
}
|
||||
|
||||
spa_history_log_internal(LOG_DS_USER_HOLD,
|
||||
dp->dp_spa, tx, "<%s> temp = %d dataset = %llu", htag,
|
||||
(int)ha->temphold, ds->ds_object);
|
||||
spa_history_log_internal_ds(ds, "hold", tx,
|
||||
"tag = %s temp = %d holds now = %llu",
|
||||
htag, (int)ha->temphold, ds->ds_userrefs);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3900,7 +3892,6 @@ dsl_dataset_user_release_sync(void *arg1, void *tag, dmu_tx_t *tx)
|
||||
dsl_pool_t *dp = ds->ds_dir->dd_pool;
|
||||
objset_t *mos = dp->dp_meta_objset;
|
||||
uint64_t zapobj;
|
||||
uint64_t dsobj = ds->ds_object;
|
||||
uint64_t refs;
|
||||
int error;
|
||||
|
||||
@ -3923,9 +3914,8 @@ dsl_dataset_user_release_sync(void *arg1, void *tag, dmu_tx_t *tx)
|
||||
dsl_dataset_destroy_sync(&dsda, tag, tx);
|
||||
}
|
||||
|
||||
spa_history_log_internal(LOG_DS_USER_RELEASE,
|
||||
dp->dp_spa, tx, "<%s> %lld dataset = %llu",
|
||||
ra->htag, (longlong_t)refs, dsobj);
|
||||
spa_history_log_internal_ds(ds, "release", tx,
|
||||
"tag = %s refs now = %lld", ra->htag, (longlong_t)refs);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -181,10 +181,8 @@ dsl_deleg_set_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
|
||||
VERIFY(zap_update(mos, jumpobj,
|
||||
perm, 8, 1, &n, tx) == 0);
|
||||
spa_history_log_internal(LOG_DS_PERM_UPDATE,
|
||||
dd->dd_pool->dp_spa, tx,
|
||||
"%s %s dataset = %llu", whokey, perm,
|
||||
dd->dd_phys->dd_head_dataset_obj);
|
||||
spa_history_log_internal_dd(dd, "permission update", tx,
|
||||
"%s %s", whokey, perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,10 +211,8 @@ dsl_deleg_unset_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
(void) zap_remove(mos, zapobj, whokey, tx);
|
||||
VERIFY(0 == zap_destroy(mos, jumpobj, tx));
|
||||
}
|
||||
spa_history_log_internal(LOG_DS_PERM_WHO_REMOVE,
|
||||
dd->dd_pool->dp_spa, tx,
|
||||
"%s dataset = %llu", whokey,
|
||||
dd->dd_phys->dd_head_dataset_obj);
|
||||
spa_history_log_internal_dd(dd, "permission who remove",
|
||||
tx, "%s", whokey);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -234,10 +230,8 @@ dsl_deleg_unset_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
VERIFY(0 == zap_destroy(mos,
|
||||
jumpobj, tx));
|
||||
}
|
||||
spa_history_log_internal(LOG_DS_PERM_REMOVE,
|
||||
dd->dd_pool->dp_spa, tx,
|
||||
"%s %s dataset = %llu", whokey, perm,
|
||||
dd->dd_phys->dd_head_dataset_obj);
|
||||
spa_history_log_internal_dd(dd, "permission remove", tx,
|
||||
"%s %s", whokey, perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -524,12 +518,10 @@ dsl_load_user_sets(objset_t *mos, uint64_t zapobj, avl_tree_t *avl,
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if user has requested permission. If descendent is set, must have
|
||||
* descendent perms.
|
||||
* Check if user has requested permission.
|
||||
*/
|
||||
int
|
||||
dsl_deleg_access_impl(dsl_dataset_t *ds, boolean_t descendent, const char *perm,
|
||||
cred_t *cr)
|
||||
dsl_deleg_access_impl(dsl_dataset_t *ds, const char *perm, cred_t *cr)
|
||||
{
|
||||
dsl_dir_t *dd;
|
||||
dsl_pool_t *dp;
|
||||
@ -550,7 +542,7 @@ dsl_deleg_access_impl(dsl_dataset_t *ds, boolean_t descendent, const char *perm,
|
||||
SPA_VERSION_DELEGATED_PERMS)
|
||||
return (EPERM);
|
||||
|
||||
if (dsl_dataset_is_snapshot(ds) || descendent) {
|
||||
if (dsl_dataset_is_snapshot(ds)) {
|
||||
/*
|
||||
* Snapshots are treated as descendents only,
|
||||
* local permissions do not apply.
|
||||
@ -643,7 +635,7 @@ dsl_deleg_access(const char *dsname, const char *perm, cred_t *cr)
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = dsl_deleg_access_impl(ds, B_FALSE, perm, cr);
|
||||
error = dsl_deleg_access_impl(ds, perm, cr);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
|
||||
return (error);
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/dmu.h>
|
||||
@ -39,8 +40,8 @@
|
||||
#include "zfs_namecheck.h"
|
||||
|
||||
static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
|
||||
static void dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx);
|
||||
|
||||
static void dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd,
|
||||
uint64_t value, dmu_tx_t *tx);
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
@ -447,8 +448,7 @@ dsl_dir_create_sync(dsl_pool_t *dp, dsl_dir_t *pds, const char *name,
|
||||
int
|
||||
dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
dsl_dir_t *dd = ds->ds_dir;
|
||||
dsl_dir_t *dd = arg1;
|
||||
dsl_pool_t *dp = dd->dd_pool;
|
||||
objset_t *mos = dp->dp_meta_objset;
|
||||
int err;
|
||||
@ -477,24 +477,19 @@ dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
void
|
||||
dsl_dir_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
dsl_dir_t *dd = ds->ds_dir;
|
||||
dsl_dir_t *dd = arg1;
|
||||
objset_t *mos = dd->dd_pool->dp_meta_objset;
|
||||
dsl_prop_setarg_t psa;
|
||||
uint64_t value = 0;
|
||||
uint64_t obj;
|
||||
dd_used_t t;
|
||||
|
||||
ASSERT(RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock));
|
||||
ASSERT(dd->dd_phys->dd_head_dataset_obj == 0);
|
||||
|
||||
/* Remove our reservation. */
|
||||
dsl_prop_setarg_init_uint64(&psa, "reservation",
|
||||
(ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED),
|
||||
&value);
|
||||
psa.psa_effective_value = 0; /* predict default value */
|
||||
|
||||
dsl_dir_set_reservation_sync(ds, &psa, tx);
|
||||
/*
|
||||
* Remove our reservation. The impl() routine avoids setting the
|
||||
* actual property, which would require the (already destroyed) ds.
|
||||
*/
|
||||
dsl_dir_set_reservation_sync_impl(dd, 0, tx);
|
||||
|
||||
ASSERT3U(dd->dd_phys->dd_used_bytes, ==, 0);
|
||||
ASSERT3U(dd->dd_phys->dd_reserved, ==, 0);
|
||||
@ -1060,9 +1055,8 @@ dsl_dir_set_quota_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dd->dd_phys->dd_quota = effective_value;
|
||||
mutex_exit(&dd->dd_lock);
|
||||
|
||||
spa_history_log_internal(LOG_DS_QUOTA, dd->dd_pool->dp_spa,
|
||||
tx, "%lld dataset = %llu ",
|
||||
(longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj);
|
||||
spa_history_log_internal_dd(dd, "set quota", tx,
|
||||
"quota=%lld", (longlong_t)effective_value);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1149,25 +1143,17 @@ dsl_dir_set_reservation_check(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
static void
|
||||
dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
dsl_dir_t *dd = ds->ds_dir;
|
||||
dsl_prop_setarg_t *psa = arg2;
|
||||
uint64_t effective_value = psa->psa_effective_value;
|
||||
uint64_t used;
|
||||
int64_t delta;
|
||||
|
||||
dsl_prop_set_sync(ds, psa, tx);
|
||||
DSL_PROP_CHECK_PREDICTION(dd, psa);
|
||||
|
||||
dmu_buf_will_dirty(dd->dd_dbuf, tx);
|
||||
|
||||
mutex_enter(&dd->dd_lock);
|
||||
used = dd->dd_phys->dd_used_bytes;
|
||||
delta = MAX(used, effective_value) -
|
||||
MAX(used, dd->dd_phys->dd_reserved);
|
||||
dd->dd_phys->dd_reserved = effective_value;
|
||||
delta = MAX(used, value) - MAX(used, dd->dd_phys->dd_reserved);
|
||||
dd->dd_phys->dd_reserved = value;
|
||||
|
||||
if (dd->dd_parent != NULL) {
|
||||
/* Roll up this additional usage into our ancestors */
|
||||
@ -1175,10 +1161,24 @@ dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
delta, 0, 0, tx);
|
||||
}
|
||||
mutex_exit(&dd->dd_lock);
|
||||
}
|
||||
|
||||
spa_history_log_internal(LOG_DS_RESERVATION, dd->dd_pool->dp_spa,
|
||||
tx, "%lld dataset = %llu",
|
||||
(longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj);
|
||||
|
||||
static void
|
||||
dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_t *ds = arg1;
|
||||
dsl_dir_t *dd = ds->ds_dir;
|
||||
dsl_prop_setarg_t *psa = arg2;
|
||||
uint64_t value = psa->psa_effective_value;
|
||||
|
||||
dsl_prop_set_sync(ds, psa, tx);
|
||||
DSL_PROP_CHECK_PREDICTION(dd, psa);
|
||||
|
||||
dsl_dir_set_reservation_sync_impl(dd, value, tx);
|
||||
|
||||
spa_history_log_internal_dd(dd, "set reservation", tx,
|
||||
"reservation=%lld", (longlong_t)value);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1299,9 +1299,15 @@ dsl_dir_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dsl_pool_t *dp = dd->dd_pool;
|
||||
objset_t *mos = dp->dp_meta_objset;
|
||||
int err;
|
||||
char namebuf[MAXNAMELEN];
|
||||
|
||||
ASSERT(dmu_buf_refcount(dd->dd_dbuf) <= 2);
|
||||
|
||||
/* Log this before we change the name. */
|
||||
dsl_dir_name(ra->newparent, namebuf);
|
||||
spa_history_log_internal_dd(dd, "rename", tx,
|
||||
"-> %s/%s", namebuf, ra->mynewname);
|
||||
|
||||
if (ra->newparent != dd->dd_parent) {
|
||||
dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD,
|
||||
-dd->dd_phys->dd_used_bytes,
|
||||
@ -1341,8 +1347,6 @@ dsl_dir_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
dd->dd_myname, 8, 1, &dd->dd_object, tx);
|
||||
ASSERT3U(err, ==, 0);
|
||||
|
||||
spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa,
|
||||
tx, "dataset = %llu", dd->dd_phys->dd_head_dataset_obj);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
@ -702,11 +703,9 @@ dsl_prop_set_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
}
|
||||
}
|
||||
|
||||
spa_history_log_internal((source == ZPROP_SRC_NONE ||
|
||||
source == ZPROP_SRC_INHERITED) ? LOG_DS_INHERIT :
|
||||
LOG_DS_PROPSET, ds->ds_dir->dd_pool->dp_spa, tx,
|
||||
"%s=%s dataset = %llu", propname,
|
||||
(valstr == NULL ? "" : valstr), ds->ds_object);
|
||||
spa_history_log_internal_ds(ds, (source == ZPROP_SRC_NONE ||
|
||||
source == ZPROP_SRC_INHERITED) ? "inherit" : "set", tx,
|
||||
"%s=%s", propname, (valstr == NULL ? "" : valstr));
|
||||
|
||||
if (tbuf != NULL)
|
||||
kmem_free(tbuf, ZAP_MAXVALUELEN);
|
||||
@ -755,24 +754,6 @@ dsl_props_set_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dsl_dir_prop_set_uint64_sync(dsl_dir_t *dd, const char *name, uint64_t val,
|
||||
dmu_tx_t *tx)
|
||||
{
|
||||
objset_t *mos = dd->dd_pool->dp_meta_objset;
|
||||
uint64_t zapobj = dd->dd_phys->dd_props_zapobj;
|
||||
|
||||
ASSERT(dmu_tx_is_syncing(tx));
|
||||
|
||||
VERIFY(0 == zap_update(mos, zapobj, name, sizeof (val), 1, &val, tx));
|
||||
|
||||
dsl_prop_changed_notify(dd->dd_pool, dd->dd_object, name, val, TRUE);
|
||||
|
||||
spa_history_log_internal(LOG_DS_PROPSET, dd->dd_pool->dp_spa, tx,
|
||||
"%s=%llu dataset = %llu", name, (u_longlong_t)val,
|
||||
dd->dd_phys->dd_head_dataset_obj);
|
||||
}
|
||||
|
||||
int
|
||||
dsl_prop_set(const char *dsname, const char *propname, zprop_source_t source,
|
||||
int intsz, int numints, const void *buf)
|
||||
|
@ -228,7 +228,7 @@ dsl_scan_setup_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
|
||||
dsl_scan_sync_state(scn, tx);
|
||||
|
||||
spa_history_log_internal(LOG_POOL_SCAN, spa, tx,
|
||||
spa_history_log_internal(spa, "scan setup", tx,
|
||||
"func=%u mintxg=%llu maxtxg=%llu",
|
||||
*funcp, scn->scn_phys.scn_min_txg, scn->scn_phys.scn_max_txg);
|
||||
}
|
||||
@ -277,7 +277,7 @@ dsl_scan_done(dsl_scan_t *scn, boolean_t complete, dmu_tx_t *tx)
|
||||
else
|
||||
scn->scn_phys.scn_state = DSS_CANCELED;
|
||||
|
||||
spa_history_log_internal(LOG_POOL_SCAN_DONE, spa, tx,
|
||||
spa_history_log_internal(spa, "scan done", tx,
|
||||
"complete=%u", complete);
|
||||
|
||||
if (DSL_SCAN_IS_SCRUB_RESILVER(scn)) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/dmu.h>
|
||||
@ -85,17 +86,17 @@ dsl_sync_task_group_wait(dsl_sync_task_group_t *dstg)
|
||||
|
||||
/* Do a preliminary error check. */
|
||||
dstg->dstg_err = 0;
|
||||
#ifdef ZFS_DEBUG
|
||||
/*
|
||||
* Only check half the time, otherwise, the sync-context
|
||||
* check will almost never fail.
|
||||
*/
|
||||
if (spa_get_random(2) == 0)
|
||||
goto skip;
|
||||
#endif
|
||||
rw_enter(&dstg->dstg_pool->dp_config_rwlock, RW_READER);
|
||||
for (dst = list_head(&dstg->dstg_tasks); dst;
|
||||
dst = list_next(&dstg->dstg_tasks, dst)) {
|
||||
#ifdef ZFS_DEBUG
|
||||
/*
|
||||
* Only check half the time, otherwise, the sync-context
|
||||
* check will almost never fail.
|
||||
*/
|
||||
if (spa_get_random(2) == 0)
|
||||
continue;
|
||||
#endif
|
||||
dst->dst_err =
|
||||
dst->dst_checkfunc(dst->dst_arg1, dst->dst_arg2, tx);
|
||||
if (dst->dst_err)
|
||||
@ -107,6 +108,7 @@ dsl_sync_task_group_wait(dsl_sync_task_group_t *dstg)
|
||||
dmu_tx_commit(tx);
|
||||
return (dstg->dstg_err);
|
||||
}
|
||||
skip:
|
||||
|
||||
/*
|
||||
* We don't generally have many sync tasks, so pay the price of
|
||||
|
@ -22,6 +22,9 @@
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/rrwlock.h>
|
||||
@ -262,3 +265,13 @@ rrw_held(rrwlock_t *rrl, krw_t rw)
|
||||
|
||||
return (held);
|
||||
}
|
||||
|
||||
void
|
||||
rrw_tsd_destroy(void *arg)
|
||||
{
|
||||
rrw_node_t *rn = arg;
|
||||
if (rn != NULL) {
|
||||
panic("thread %p terminating with rrw lock %p held",
|
||||
(void *)curthread, (void *)rn->rn_rrl);
|
||||
}
|
||||
}
|
||||
|
@ -2544,6 +2544,12 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
|
||||
vdev_resilver_needed(rvd, NULL, NULL))
|
||||
spa_async_request(spa, SPA_ASYNC_RESILVER);
|
||||
|
||||
/*
|
||||
* Log the fact that we booted up (so that we can detect if
|
||||
* we rebooted in the middle of an operation).
|
||||
*/
|
||||
spa_history_log_version(spa, "open");
|
||||
|
||||
/*
|
||||
* Delete any inconsistent datasets.
|
||||
*/
|
||||
@ -3220,7 +3226,7 @@ spa_l2cache_drop(spa_t *spa)
|
||||
*/
|
||||
int
|
||||
spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
const char *history_str, nvlist_t *zplprops)
|
||||
nvlist_t *zplprops)
|
||||
{
|
||||
spa_t *spa;
|
||||
char *altroot = NULL;
|
||||
@ -3439,9 +3445,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
|
||||
spa_config_sync(spa, B_FALSE, B_TRUE);
|
||||
|
||||
if (version >= SPA_VERSION_ZPOOL_HISTORY && history_str != NULL)
|
||||
(void) spa_history_log(spa, history_str, LOG_CMD_POOL_CREATE);
|
||||
spa_history_log_version(spa, LOG_POOL_CREATE);
|
||||
spa_history_log_version(spa, "create");
|
||||
|
||||
spa->spa_minref = refcount_count(&spa->spa_refcount);
|
||||
|
||||
@ -3641,7 +3645,6 @@ spa_import_rootpool(char *devpath, char *devid)
|
||||
}
|
||||
|
||||
error = 0;
|
||||
spa_history_log_version(spa, LOG_POOL_IMPORT);
|
||||
out:
|
||||
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
|
||||
vdev_free(rvd);
|
||||
@ -3703,7 +3706,7 @@ spa_import(const char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||
spa_config_sync(spa, B_FALSE, B_TRUE);
|
||||
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_history_log_version(spa, LOG_POOL_IMPORT);
|
||||
spa_history_log_version(spa, "import");
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -3834,7 +3837,7 @@ spa_import(const char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||
spa_async_request(spa, SPA_ASYNC_AUTOEXPAND);
|
||||
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_history_log_version(spa, LOG_POOL_IMPORT);
|
||||
spa_history_log_version(spa, "import");
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -4372,7 +4375,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
|
||||
*/
|
||||
(void) spa_vdev_exit(spa, newrootvd, dtl_max_txg, 0);
|
||||
|
||||
spa_history_log_internal(LOG_POOL_VDEV_ATTACH, spa, NULL,
|
||||
spa_history_log_internal(spa, "vdev attach", NULL,
|
||||
"%s vdev=%s %s vdev=%s",
|
||||
replacing && newvd_isspare ? "spare in" :
|
||||
replacing ? "replace" : "attach", newvdpath,
|
||||
@ -4589,7 +4592,7 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
|
||||
|
||||
error = spa_vdev_exit(spa, vd, txg, 0);
|
||||
|
||||
spa_history_log_internal(LOG_POOL_VDEV_DETACH, spa, NULL,
|
||||
spa_history_log_internal(spa, "detach", NULL,
|
||||
"vdev=%s", vdpath);
|
||||
spa_strfree(vdpath);
|
||||
|
||||
@ -4858,9 +4861,8 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
|
||||
if (vml[c] != NULL) {
|
||||
vdev_split(vml[c]);
|
||||
if (error == 0)
|
||||
spa_history_log_internal(LOG_POOL_VDEV_DETACH,
|
||||
spa, tx, "vdev=%s",
|
||||
vml[c]->vdev_path);
|
||||
spa_history_log_internal(spa, "detach", tx,
|
||||
"vdev=%s", vml[c]->vdev_path);
|
||||
vdev_free(vml[c]);
|
||||
}
|
||||
}
|
||||
@ -4875,8 +4877,8 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
|
||||
zio_handle_panic_injection(spa, FTAG, 3);
|
||||
|
||||
/* split is complete; log a history record */
|
||||
spa_history_log_internal(LOG_POOL_SPLIT, newspa, NULL,
|
||||
"split new pool %s from pool %s", newname, spa_name(spa));
|
||||
spa_history_log_internal(newspa, "split", NULL,
|
||||
"from pool %s", spa_name(spa));
|
||||
|
||||
kmem_free(vml, children * sizeof (vdev_t *));
|
||||
|
||||
@ -5462,8 +5464,7 @@ spa_async_thread(spa_t *spa)
|
||||
* then log an internal history event.
|
||||
*/
|
||||
if (new_space != old_space) {
|
||||
spa_history_log_internal(LOG_POOL_VDEV_ONLINE,
|
||||
spa, NULL,
|
||||
spa_history_log_internal(spa, "vdev online", NULL,
|
||||
"pool '%s' size: %llu(+%llu)",
|
||||
spa_name(spa), new_space, new_space - old_space);
|
||||
}
|
||||
@ -5699,6 +5700,7 @@ spa_sync_version(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
|
||||
spa->spa_uberblock.ub_version = version;
|
||||
vdev_config_dirty(spa->spa_root_vdev);
|
||||
spa_history_log_internal(spa, "set", tx, "version=%lld", version);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5733,6 +5735,8 @@ spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
VERIFY3U(0, ==, zfeature_lookup_name(fname, &feature));
|
||||
|
||||
spa_feature_enable(spa, feature, tx);
|
||||
spa_history_log_internal(spa, "set", tx,
|
||||
"%s=enabled", nvpair_name(elem));
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_VERSION:
|
||||
@ -5772,6 +5776,8 @@ spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
*/
|
||||
if (tx->tx_txg != TXG_INITIAL)
|
||||
vdev_config_dirty(spa->spa_root_vdev);
|
||||
spa_history_log_internal(spa, "set", tx,
|
||||
"%s=%s", nvpair_name(elem), strval);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
@ -5794,7 +5800,8 @@ spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
VERIFY(zap_update(mos,
|
||||
spa->spa_pool_props_object, propname,
|
||||
1, strlen(strval) + 1, strval, tx) == 0);
|
||||
|
||||
spa_history_log_internal(spa, "set", tx,
|
||||
"%s=%s", nvpair_name(elem), strval);
|
||||
} else if (nvpair_type(elem) == DATA_TYPE_UINT64) {
|
||||
VERIFY(nvpair_value_uint64(elem, &intval) == 0);
|
||||
|
||||
@ -5806,6 +5813,8 @@ spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
VERIFY(zap_update(mos,
|
||||
spa->spa_pool_props_object, propname,
|
||||
8, 1, &intval, tx) == 0);
|
||||
spa_history_log_internal(spa, "set", tx,
|
||||
"%s=%lld", nvpair_name(elem), intval);
|
||||
} else {
|
||||
ASSERT(0); /* not allowed */
|
||||
}
|
||||
@ -5834,13 +5843,6 @@ spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
}
|
||||
}
|
||||
|
||||
/* log internal history if this is not a zpool create */
|
||||
if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY &&
|
||||
tx->tx_txg != TXG_INITIAL) {
|
||||
spa_history_log_internal(LOG_POOL_PROPSET,
|
||||
spa, tx, "%s %lld %s",
|
||||
nvpair_name(elem), intval, spa_name(spa));
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&spa->spa_props_lock);
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/spa.h>
|
||||
@ -30,9 +30,12 @@
|
||||
#include <sys/dsl_synctask.h>
|
||||
#include <sys/dmu_tx.h>
|
||||
#include <sys/dmu_objset.h>
|
||||
#include <sys/dsl_dataset.h>
|
||||
#include <sys/dsl_dir.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/cmn_err.h>
|
||||
#include <sys/sunddi.h>
|
||||
#include <sys/cred.h>
|
||||
#include "zfs_comutil.h"
|
||||
#ifdef _KERNEL
|
||||
#include <sys/zone.h>
|
||||
@ -176,12 +179,14 @@ spa_history_write(spa_t *spa, void *buf, uint64_t len, spa_history_phys_t *shpp,
|
||||
}
|
||||
|
||||
static char *
|
||||
spa_history_zone()
|
||||
spa_history_zone(void)
|
||||
{
|
||||
#ifdef _KERNEL
|
||||
if (INGLOBALZONE(curproc))
|
||||
return (NULL);
|
||||
return (curproc->p_zone->zone_name);
|
||||
#else
|
||||
return ("global");
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -193,14 +198,12 @@ static void
|
||||
spa_history_log_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
{
|
||||
spa_t *spa = arg1;
|
||||
history_arg_t *hap = arg2;
|
||||
const char *history_str = hap->ha_history_str;
|
||||
nvlist_t *nvl = arg2;
|
||||
objset_t *mos = spa->spa_meta_objset;
|
||||
dmu_buf_t *dbp;
|
||||
spa_history_phys_t *shpp;
|
||||
size_t reclen;
|
||||
uint64_t le_len;
|
||||
nvlist_t *nvrecord;
|
||||
char *record_packed = NULL;
|
||||
int ret;
|
||||
|
||||
@ -230,46 +233,35 @@ spa_history_log_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
}
|
||||
#endif
|
||||
|
||||
VERIFY(nvlist_alloc(&nvrecord, NV_UNIQUE_NAME, KM_SLEEP) == 0);
|
||||
VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_TIME,
|
||||
gethrestime_sec()) == 0);
|
||||
VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_WHO, hap->ha_uid) == 0);
|
||||
if (hap->ha_zone != NULL)
|
||||
VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_ZONE,
|
||||
hap->ha_zone) == 0);
|
||||
fnvlist_add_uint64(nvl, ZPOOL_HIST_TIME, gethrestime_sec());
|
||||
#ifdef _KERNEL
|
||||
VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_HOST,
|
||||
utsname.nodename) == 0);
|
||||
fnvlist_add_string(nvl, ZPOOL_HIST_HOST, utsname.nodename);
|
||||
#endif
|
||||
if (hap->ha_log_type == LOG_CMD_POOL_CREATE ||
|
||||
hap->ha_log_type == LOG_CMD_NORMAL) {
|
||||
VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_CMD,
|
||||
history_str) == 0);
|
||||
|
||||
zfs_dbgmsg("command: %s", history_str);
|
||||
} else {
|
||||
VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_INT_EVENT,
|
||||
hap->ha_event) == 0);
|
||||
VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_TXG,
|
||||
tx->tx_txg) == 0);
|
||||
VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_INT_STR,
|
||||
history_str) == 0);
|
||||
|
||||
zfs_dbgmsg("internal %s pool:%s txg:%llu %s",
|
||||
zfs_history_event_names[hap->ha_event], spa_name(spa),
|
||||
(longlong_t)tx->tx_txg, history_str);
|
||||
|
||||
if (nvlist_exists(nvl, ZPOOL_HIST_CMD)) {
|
||||
zfs_dbgmsg("command: %s",
|
||||
fnvlist_lookup_string(nvl, ZPOOL_HIST_CMD));
|
||||
} else if (nvlist_exists(nvl, ZPOOL_HIST_INT_NAME)) {
|
||||
if (nvlist_exists(nvl, ZPOOL_HIST_DSNAME)) {
|
||||
zfs_dbgmsg("txg %lld %s %s (id %llu) %s",
|
||||
fnvlist_lookup_uint64(nvl, ZPOOL_HIST_TXG),
|
||||
fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_NAME),
|
||||
fnvlist_lookup_string(nvl, ZPOOL_HIST_DSNAME),
|
||||
fnvlist_lookup_uint64(nvl, ZPOOL_HIST_DSID),
|
||||
fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_STR));
|
||||
} else {
|
||||
zfs_dbgmsg("txg %lld %s %s",
|
||||
fnvlist_lookup_uint64(nvl, ZPOOL_HIST_TXG),
|
||||
fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_NAME),
|
||||
fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_STR));
|
||||
}
|
||||
} else if (nvlist_exists(nvl, ZPOOL_HIST_IOCTL)) {
|
||||
zfs_dbgmsg("ioctl %s",
|
||||
fnvlist_lookup_string(nvl, ZPOOL_HIST_IOCTL));
|
||||
}
|
||||
|
||||
VERIFY(nvlist_size(nvrecord, &reclen, NV_ENCODE_XDR) == 0);
|
||||
record_packed = kmem_alloc(reclen, KM_SLEEP);
|
||||
|
||||
VERIFY(nvlist_pack(nvrecord, &record_packed, &reclen,
|
||||
NV_ENCODE_XDR, KM_SLEEP) == 0);
|
||||
record_packed = fnvlist_pack(nvl, &reclen);
|
||||
|
||||
mutex_enter(&spa->spa_history_lock);
|
||||
if (hap->ha_log_type == LOG_CMD_POOL_CREATE)
|
||||
VERIFY(shpp->sh_eof == shpp->sh_pool_create_len);
|
||||
|
||||
/* write out the packed length as little endian */
|
||||
le_len = LE_64((uint64_t)reclen);
|
||||
@ -277,33 +269,42 @@ spa_history_log_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
||||
if (!ret)
|
||||
ret = spa_history_write(spa, record_packed, reclen, shpp, tx);
|
||||
|
||||
if (!ret && hap->ha_log_type == LOG_CMD_POOL_CREATE) {
|
||||
shpp->sh_pool_create_len += sizeof (le_len) + reclen;
|
||||
shpp->sh_bof = shpp->sh_pool_create_len;
|
||||
/* The first command is the create, which we keep forever */
|
||||
if (ret == 0 && shpp->sh_pool_create_len == 0 &&
|
||||
nvlist_exists(nvl, ZPOOL_HIST_CMD)) {
|
||||
shpp->sh_pool_create_len = shpp->sh_bof = shpp->sh_eof;
|
||||
}
|
||||
|
||||
mutex_exit(&spa->spa_history_lock);
|
||||
nvlist_free(nvrecord);
|
||||
kmem_free(record_packed, reclen);
|
||||
fnvlist_pack_free(record_packed, reclen);
|
||||
dmu_buf_rele(dbp, FTAG);
|
||||
|
||||
strfree(hap->ha_history_str);
|
||||
if (hap->ha_zone != NULL)
|
||||
strfree(hap->ha_zone);
|
||||
kmem_free(hap, sizeof (history_arg_t));
|
||||
fnvlist_free(nvl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out a history event.
|
||||
*/
|
||||
int
|
||||
spa_history_log(spa_t *spa, const char *history_str, history_log_type_t what)
|
||||
spa_history_log(spa_t *spa, const char *msg)
|
||||
{
|
||||
int err;
|
||||
nvlist_t *nvl = fnvlist_alloc();
|
||||
|
||||
fnvlist_add_string(nvl, ZPOOL_HIST_CMD, msg);
|
||||
err = spa_history_log_nvl(spa, nvl);
|
||||
fnvlist_free(nvl);
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
spa_history_log_nvl(spa_t *spa, nvlist_t *nvl)
|
||||
{
|
||||
history_arg_t *ha;
|
||||
int err = 0;
|
||||
dmu_tx_t *tx;
|
||||
nvlist_t *nvarg;
|
||||
|
||||
ASSERT(what != LOG_INTERNAL);
|
||||
if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY)
|
||||
return (EINVAL);
|
||||
|
||||
tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||
err = dmu_tx_assign(tx, TXG_WAIT);
|
||||
@ -312,19 +313,21 @@ spa_history_log(spa_t *spa, const char *history_str, history_log_type_t what)
|
||||
return (err);
|
||||
}
|
||||
|
||||
ha = kmem_alloc(sizeof (history_arg_t), KM_SLEEP);
|
||||
ha->ha_history_str = strdup(history_str);
|
||||
ha->ha_zone = strdup(spa_history_zone());
|
||||
ha->ha_log_type = what;
|
||||
ha->ha_uid = crgetuid(CRED());
|
||||
nvarg = fnvlist_dup(nvl);
|
||||
if (spa_history_zone() != NULL) {
|
||||
fnvlist_add_string(nvarg, ZPOOL_HIST_ZONE,
|
||||
spa_history_zone());
|
||||
}
|
||||
fnvlist_add_uint64(nvarg, ZPOOL_HIST_WHO, crgetruid(CRED()));
|
||||
|
||||
/* Kick this off asynchronously; errors are ignored. */
|
||||
dsl_sync_task_do_nowait(spa_get_dsl(spa), NULL,
|
||||
spa_history_log_sync, spa, ha, 0, tx);
|
||||
spa_history_log_sync, spa, nvarg, 0, tx);
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
/* spa_history_log_sync will free ha and strings */
|
||||
/* spa_history_log_sync will free nvl */
|
||||
return (err);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -341,7 +344,7 @@ spa_history_get(spa_t *spa, uint64_t *offp, uint64_t *len, char *buf)
|
||||
int err;
|
||||
|
||||
/*
|
||||
* If the command history doesn't exist (older pool),
|
||||
* If the command history doesn't exist (older pool),
|
||||
* that's ok, just return ENOENT.
|
||||
*/
|
||||
if (!spa->spa_history)
|
||||
@ -424,11 +427,14 @@ spa_history_get(spa_t *spa, uint64_t *offp, uint64_t *len, char *buf)
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* The nvlist will be consumed by this call.
|
||||
*/
|
||||
static void
|
||||
log_internal(history_internal_events_t event, spa_t *spa,
|
||||
log_internal(nvlist_t *nvl, const char *operation, spa_t *spa,
|
||||
dmu_tx_t *tx, const char *fmt, va_list adx)
|
||||
{
|
||||
history_arg_t *ha;
|
||||
char *msg;
|
||||
|
||||
/*
|
||||
* If this is part of creating a pool, not everything is
|
||||
@ -437,28 +443,25 @@ log_internal(history_internal_events_t event, spa_t *spa,
|
||||
if (tx->tx_txg == TXG_INITIAL)
|
||||
return;
|
||||
|
||||
ha = kmem_alloc(sizeof (history_arg_t), KM_SLEEP);
|
||||
ha->ha_history_str = kmem_alloc(vsnprintf(NULL, 0, fmt, adx) + 1,
|
||||
KM_SLEEP);
|
||||
msg = kmem_alloc(vsnprintf(NULL, 0, fmt, adx) + 1, KM_SLEEP);
|
||||
(void) vsprintf(msg, fmt, adx);
|
||||
fnvlist_add_string(nvl, ZPOOL_HIST_INT_STR, msg);
|
||||
strfree(msg);
|
||||
|
||||
(void) vsprintf(ha->ha_history_str, fmt, adx);
|
||||
|
||||
ha->ha_log_type = LOG_INTERNAL;
|
||||
ha->ha_event = event;
|
||||
ha->ha_zone = NULL;
|
||||
ha->ha_uid = 0;
|
||||
fnvlist_add_string(nvl, ZPOOL_HIST_INT_NAME, operation);
|
||||
fnvlist_add_uint64(nvl, ZPOOL_HIST_TXG, tx->tx_txg);
|
||||
|
||||
if (dmu_tx_is_syncing(tx)) {
|
||||
spa_history_log_sync(spa, ha, tx);
|
||||
spa_history_log_sync(spa, nvl, tx);
|
||||
} else {
|
||||
dsl_sync_task_do_nowait(spa_get_dsl(spa), NULL,
|
||||
spa_history_log_sync, spa, ha, 0, tx);
|
||||
spa_history_log_sync, spa, nvl, 0, tx);
|
||||
}
|
||||
/* spa_history_log_sync() will free ha and strings */
|
||||
/* spa_history_log_sync() will free nvl */
|
||||
}
|
||||
|
||||
void
|
||||
spa_history_log_internal(history_internal_events_t event, spa_t *spa,
|
||||
spa_history_log_internal(spa_t *spa, const char *operation,
|
||||
dmu_tx_t *tx, const char *fmt, ...)
|
||||
{
|
||||
dmu_tx_t *htx = tx;
|
||||
@ -474,7 +477,7 @@ spa_history_log_internal(history_internal_events_t event, spa_t *spa,
|
||||
}
|
||||
|
||||
va_start(adx, fmt);
|
||||
log_internal(event, spa, htx, fmt, adx);
|
||||
log_internal(fnvlist_alloc(), operation, spa, htx, fmt, adx);
|
||||
va_end(adx);
|
||||
|
||||
/* if we didn't get a tx from the caller, commit the one we made */
|
||||
@ -483,21 +486,56 @@ spa_history_log_internal(history_internal_events_t event, spa_t *spa,
|
||||
}
|
||||
|
||||
void
|
||||
spa_history_log_version(spa_t *spa, history_internal_events_t event)
|
||||
spa_history_log_internal_ds(dsl_dataset_t *ds, const char *operation,
|
||||
dmu_tx_t *tx, const char *fmt, ...)
|
||||
{
|
||||
va_list adx;
|
||||
char namebuf[MAXNAMELEN];
|
||||
nvlist_t *nvl = fnvlist_alloc();
|
||||
|
||||
ASSERT(tx != NULL);
|
||||
|
||||
dsl_dataset_name(ds, namebuf);
|
||||
fnvlist_add_string(nvl, ZPOOL_HIST_DSNAME, namebuf);
|
||||
fnvlist_add_uint64(nvl, ZPOOL_HIST_DSID, ds->ds_object);
|
||||
|
||||
va_start(adx, fmt);
|
||||
log_internal(nvl, operation, dsl_dataset_get_spa(ds), tx, fmt, adx);
|
||||
va_end(adx);
|
||||
}
|
||||
|
||||
void
|
||||
spa_history_log_internal_dd(dsl_dir_t *dd, const char *operation,
|
||||
dmu_tx_t *tx, const char *fmt, ...)
|
||||
{
|
||||
va_list adx;
|
||||
char namebuf[MAXNAMELEN];
|
||||
nvlist_t *nvl = fnvlist_alloc();
|
||||
|
||||
ASSERT(tx != NULL);
|
||||
|
||||
dsl_dir_name(dd, namebuf);
|
||||
fnvlist_add_string(nvl, ZPOOL_HIST_DSNAME, namebuf);
|
||||
fnvlist_add_uint64(nvl, ZPOOL_HIST_DSID,
|
||||
dd->dd_phys->dd_head_dataset_obj);
|
||||
|
||||
va_start(adx, fmt);
|
||||
log_internal(nvl, operation, dd->dd_pool->dp_spa, tx, fmt, adx);
|
||||
va_end(adx);
|
||||
}
|
||||
|
||||
void
|
||||
spa_history_log_version(spa_t *spa, const char *operation)
|
||||
{
|
||||
#ifdef _KERNEL
|
||||
uint64_t current_vers = spa_version(spa);
|
||||
|
||||
if (current_vers >= SPA_VERSION_ZPOOL_HISTORY) {
|
||||
spa_history_log_internal(event, spa, NULL,
|
||||
"pool spa %llu; zfs spa %llu; zpl %d; uts %s %s %s %s",
|
||||
(u_longlong_t)current_vers, SPA_VERSION, ZPL_VERSION,
|
||||
utsname.nodename, utsname.release, utsname.version,
|
||||
utsname.machine);
|
||||
}
|
||||
cmn_err(CE_CONT, "!%s version %llu pool %s using %llu",
|
||||
event == LOG_POOL_IMPORT ? "imported" :
|
||||
event == LOG_POOL_CREATE ? "created" : "accessed",
|
||||
spa_history_log_internal(spa, operation, NULL,
|
||||
"pool version %llu; software version %llu/%d; uts %s %s %s %s",
|
||||
(u_longlong_t)current_vers, SPA_VERSION, ZPL_VERSION,
|
||||
utsname.nodename, utsname.release, utsname.version,
|
||||
utsname.machine);
|
||||
cmn_err(CE_CONT, "!%s version %llu pool %s using %llu", operation,
|
||||
(u_longlong_t)current_vers, spa_name(spa), SPA_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/cred.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -216,16 +217,6 @@ typedef enum dmu_object_type {
|
||||
DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE),
|
||||
} dmu_object_type_t;
|
||||
|
||||
typedef enum dmu_objset_type {
|
||||
DMU_OST_NONE,
|
||||
DMU_OST_META,
|
||||
DMU_OST_ZFS,
|
||||
DMU_OST_ZVOL,
|
||||
DMU_OST_OTHER, /* For testing only! */
|
||||
DMU_OST_ANY, /* Be careful! */
|
||||
DMU_OST_NUMTYPES
|
||||
} dmu_objset_type_t;
|
||||
|
||||
void byteswap_uint64_array(void *buf, size_t size);
|
||||
void byteswap_uint32_array(void *buf, size_t size);
|
||||
void byteswap_uint16_array(void *buf, size_t size);
|
||||
@ -270,9 +261,11 @@ int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
|
||||
int dmu_objset_clone(const char *name, struct dsl_dataset *clone_origin,
|
||||
uint64_t flags);
|
||||
int dmu_objset_destroy(const char *name, boolean_t defer);
|
||||
int dmu_snapshots_destroy_nvl(struct nvlist *snaps, boolean_t defer, char *);
|
||||
int dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
|
||||
struct nvlist *props, boolean_t recursive, boolean_t temporary, int fd);
|
||||
int dmu_snapshots_destroy_nvl(struct nvlist *snaps, boolean_t defer,
|
||||
struct nvlist *errlist);
|
||||
int dmu_objset_snapshot(struct nvlist *snaps, struct nvlist *, struct nvlist *);
|
||||
int dmu_objset_snapshot_one(const char *fsname, const char *snapname);
|
||||
int dmu_objset_snapshot_tmp(const char *, const char *, int);
|
||||
int dmu_objset_rename(const char *name, const char *newname,
|
||||
boolean_t recursive);
|
||||
int dmu_objset_find(char *name, int func(const char *, void *), void *arg,
|
||||
@ -789,10 +782,9 @@ typedef void (*dmu_traverse_cb_t)(objset_t *os, void *arg, struct blkptr *bp,
|
||||
void dmu_traverse_objset(objset_t *os, uint64_t txg_start,
|
||||
dmu_traverse_cb_t cb, void *arg);
|
||||
|
||||
int dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
|
||||
int dmu_send(objset_t *tosnap, objset_t *fromsnap,
|
||||
int outfd, struct vnode *vp, offset_t *off);
|
||||
int dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorign,
|
||||
uint64_t *sizep);
|
||||
int dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, uint64_t *sizep);
|
||||
|
||||
typedef struct dmu_recv_cookie {
|
||||
/*
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 2010 Robert Milkowski */
|
||||
@ -137,24 +138,14 @@ void dmu_objset_rele(objset_t *os, void *tag);
|
||||
void dmu_objset_disown(objset_t *os, void *tag);
|
||||
int dmu_objset_from_ds(struct dsl_dataset *ds, objset_t **osp);
|
||||
|
||||
int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
|
||||
void (*func)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx), void *arg);
|
||||
int dmu_objset_clone(const char *name, struct dsl_dataset *clone_origin,
|
||||
uint64_t flags);
|
||||
int dmu_objset_destroy(const char *name, boolean_t defer);
|
||||
int dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
|
||||
struct nvlist *props, boolean_t recursive, boolean_t temporary, int fd);
|
||||
void dmu_objset_stats(objset_t *os, nvlist_t *nv);
|
||||
void dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat);
|
||||
void dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp,
|
||||
uint64_t *usedobjsp, uint64_t *availobjsp);
|
||||
uint64_t dmu_objset_fsid_guid(objset_t *os);
|
||||
int dmu_objset_find(char *name, int func(const char *, void *), void *arg,
|
||||
int flags);
|
||||
int dmu_objset_find_spa(spa_t *spa, const char *name,
|
||||
int func(spa_t *, uint64_t, const char *, void *), void *arg, int flags);
|
||||
int dmu_objset_prefetch(const char *name, void *arg);
|
||||
void dmu_objset_byteswap(void *buf, size_t size);
|
||||
int dmu_objset_evict_dbufs(objset_t *os);
|
||||
timestruc_t dmu_objset_snap_cmtime(objset_t *os);
|
||||
|
||||
|
@ -180,7 +180,7 @@ struct dsl_ds_destroyarg {
|
||||
|
||||
struct dsl_ds_holdarg {
|
||||
dsl_sync_task_group_t *dstg;
|
||||
char *htag;
|
||||
const char *htag;
|
||||
char *snapname;
|
||||
boolean_t recursive;
|
||||
boolean_t gotone;
|
||||
@ -215,12 +215,11 @@ uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname,
|
||||
uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
|
||||
uint64_t flags, dmu_tx_t *tx);
|
||||
int dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer);
|
||||
int dsl_snapshots_destroy(char *fsname, char *snapname, boolean_t defer);
|
||||
dsl_checkfunc_t dsl_dataset_destroy_check;
|
||||
dsl_syncfunc_t dsl_dataset_destroy_sync;
|
||||
dsl_checkfunc_t dsl_dataset_snapshot_check;
|
||||
dsl_syncfunc_t dsl_dataset_snapshot_sync;
|
||||
dsl_syncfunc_t dsl_dataset_user_hold_sync;
|
||||
int dsl_dataset_snapshot_check(dsl_dataset_t *ds, const char *, dmu_tx_t *tx);
|
||||
void dsl_dataset_snapshot_sync(dsl_dataset_t *ds, const char *, dmu_tx_t *tx);
|
||||
int dsl_dataset_rename(char *name, const char *newname, boolean_t recursive);
|
||||
int dsl_dataset_promote(const char *name, char *conflsnap);
|
||||
int dsl_dataset_clone_swap(dsl_dataset_t *clone, dsl_dataset_t *origin_head,
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_DSL_DELEG_H
|
||||
@ -65,8 +65,7 @@ extern "C" {
|
||||
int dsl_deleg_get(const char *ddname, nvlist_t **nvp);
|
||||
int dsl_deleg_set(const char *ddname, nvlist_t *nvp, boolean_t unset);
|
||||
int dsl_deleg_access(const char *ddname, const char *perm, cred_t *cr);
|
||||
int dsl_deleg_access_impl(struct dsl_dataset *ds, boolean_t descendent,
|
||||
const char *perm, cred_t *cr);
|
||||
int dsl_deleg_access_impl(struct dsl_dataset *ds, const char *perm, cred_t *cr);
|
||||
void dsl_deleg_set_create_perms(dsl_dir_t *dd, dmu_tx_t *tx, cred_t *cr);
|
||||
int dsl_deleg_can_allow(char *ddname, nvlist_t *nvp, cred_t *cr);
|
||||
int dsl_deleg_can_unallow(char *ddname, nvlist_t *nvp, cred_t *cr);
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_DSL_PROP_H
|
||||
@ -89,8 +90,6 @@ dsl_syncfunc_t dsl_props_set_sync;
|
||||
int dsl_prop_set(const char *ddname, const char *propname,
|
||||
zprop_source_t source, int intsz, int numints, const void *buf);
|
||||
int dsl_props_set(const char *dsname, zprop_source_t source, nvlist_t *nvl);
|
||||
void dsl_dir_prop_set_uint64_sync(dsl_dir_t *dd, const char *name, uint64_t val,
|
||||
dmu_tx_t *tx);
|
||||
|
||||
void dsl_prop_setarg_init_uint64(dsl_prop_setarg_t *psa, const char *propname,
|
||||
zprop_source_t source, uint64_t *value);
|
||||
|
@ -22,12 +22,13 @@
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_RR_RW_LOCK_H
|
||||
#define _SYS_RR_RW_LOCK_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -69,6 +70,7 @@ void rrw_destroy(rrwlock_t *rrl);
|
||||
void rrw_enter(rrwlock_t *rrl, krw_t rw, void *tag);
|
||||
void rrw_exit(rrwlock_t *rrl, void *tag);
|
||||
boolean_t rrw_held(rrwlock_t *rrl, krw_t rw);
|
||||
void rrw_tsd_destroy(void *arg);
|
||||
|
||||
#define RRW_READ_HELD(x) rrw_held(x, RW_READER)
|
||||
#define RRW_WRITE_HELD(x) rrw_held(x, RW_WRITER)
|
||||
|
@ -52,6 +52,7 @@ typedef struct spa_aux_vdev spa_aux_vdev_t;
|
||||
typedef struct ddt ddt_t;
|
||||
typedef struct ddt_entry ddt_entry_t;
|
||||
struct dsl_pool;
|
||||
struct dsl_dataset;
|
||||
|
||||
/*
|
||||
* General-purpose 32-bit and 64-bit bitfield encodings.
|
||||
@ -418,7 +419,7 @@ extern int spa_open_rewind(const char *pool, spa_t **, void *tag,
|
||||
extern int spa_get_stats(const char *pool, nvlist_t **config, char *altroot,
|
||||
size_t buflen);
|
||||
extern int spa_create(const char *pool, nvlist_t *config, nvlist_t *props,
|
||||
const char *history_str, nvlist_t *zplprops);
|
||||
nvlist_t *zplprops);
|
||||
extern int spa_import_rootpool(char *devpath, char *devid);
|
||||
extern int spa_import(const char *pool, nvlist_t *config, nvlist_t *props,
|
||||
uint64_t flags);
|
||||
@ -632,31 +633,20 @@ extern boolean_t spa_writeable(spa_t *spa);
|
||||
extern int spa_mode(spa_t *spa);
|
||||
extern uint64_t strtonum(const char *str, char **nptr);
|
||||
|
||||
/* history logging */
|
||||
typedef enum history_log_type {
|
||||
LOG_CMD_POOL_CREATE,
|
||||
LOG_CMD_NORMAL,
|
||||
LOG_INTERNAL
|
||||
} history_log_type_t;
|
||||
|
||||
typedef struct history_arg {
|
||||
char *ha_history_str;
|
||||
history_log_type_t ha_log_type;
|
||||
history_internal_events_t ha_event;
|
||||
char *ha_zone;
|
||||
uid_t ha_uid;
|
||||
} history_arg_t;
|
||||
|
||||
extern char *spa_his_ievent_table[];
|
||||
|
||||
extern void spa_history_create_obj(spa_t *spa, dmu_tx_t *tx);
|
||||
extern int spa_history_get(spa_t *spa, uint64_t *offset, uint64_t *len_read,
|
||||
char *his_buf);
|
||||
extern int spa_history_log(spa_t *spa, const char *his_buf,
|
||||
history_log_type_t what);
|
||||
extern void spa_history_log_internal(history_internal_events_t event,
|
||||
spa_t *spa, dmu_tx_t *tx, const char *fmt, ...);
|
||||
extern void spa_history_log_version(spa_t *spa, history_internal_events_t evt);
|
||||
extern int spa_history_log(spa_t *spa, const char *his_buf);
|
||||
extern int spa_history_log_nvl(spa_t *spa, nvlist_t *nvl);
|
||||
extern void spa_history_log_version(spa_t *spa, const char *operation);
|
||||
extern void spa_history_log_internal(spa_t *spa, const char *operation,
|
||||
dmu_tx_t *tx, const char *fmt, ...);
|
||||
extern void spa_history_log_internal_ds(struct dsl_dataset *ds, const char *op,
|
||||
dmu_tx_t *tx, const char *fmt, ...);
|
||||
extern void spa_history_log_internal_dd(dsl_dir_t *dd, const char *operation,
|
||||
dmu_tx_t *tx, const char *fmt, ...);
|
||||
|
||||
/* error handling */
|
||||
struct zbookmark;
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZFS_IOCTL_H
|
||||
@ -40,6 +41,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The structures in this file are passed between userland and the
|
||||
* kernel. Userland may be running a 32-bit process, while the kernel
|
||||
* is 64-bit. Therefore, these structures need to compile the same in
|
||||
* 32-bit and 64-bit. This means not using type "long", and adding
|
||||
* explicit padding so that the 32-bit structure will not be packed more
|
||||
* tightly than the 64-bit structure (which requires 64-bit alignment).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Property values for snapdir
|
||||
*/
|
||||
@ -256,22 +266,29 @@ typedef enum zfs_case {
|
||||
} zfs_case_t;
|
||||
|
||||
typedef struct zfs_cmd {
|
||||
char zc_name[MAXPATHLEN];
|
||||
char zc_name[MAXPATHLEN]; /* name of pool or dataset */
|
||||
uint64_t zc_nvlist_src; /* really (char *) */
|
||||
uint64_t zc_nvlist_src_size;
|
||||
uint64_t zc_nvlist_dst; /* really (char *) */
|
||||
uint64_t zc_nvlist_dst_size;
|
||||
boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */
|
||||
int zc_pad2;
|
||||
|
||||
/*
|
||||
* The following members are for legacy ioctls which haven't been
|
||||
* converted to the new method.
|
||||
*/
|
||||
uint64_t zc_history; /* really (char *) */
|
||||
char zc_value[MAXPATHLEN * 2];
|
||||
char zc_string[MAXNAMELEN];
|
||||
char zc_top_ds[MAXPATHLEN];
|
||||
uint64_t zc_guid;
|
||||
uint64_t zc_nvlist_conf; /* really (char *) */
|
||||
uint64_t zc_nvlist_conf_size;
|
||||
uint64_t zc_nvlist_src; /* really (char *) */
|
||||
uint64_t zc_nvlist_src_size;
|
||||
uint64_t zc_nvlist_dst; /* really (char *) */
|
||||
uint64_t zc_nvlist_dst_size;
|
||||
uint64_t zc_cookie;
|
||||
uint64_t zc_objset_type;
|
||||
uint64_t zc_perm_action;
|
||||
uint64_t zc_history; /* really (char *) */
|
||||
uint64_t zc_history_len;
|
||||
uint64_t zc_history_len;
|
||||
uint64_t zc_history_offset;
|
||||
uint64_t zc_obj;
|
||||
uint64_t zc_iflags; /* internal to zfs(7fs) */
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -749,8 +750,7 @@ zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp,
|
||||
return (err);
|
||||
|
||||
if (err == 0) {
|
||||
err = dmu_objset_snapshot(name, dirname, NULL, NULL,
|
||||
B_FALSE, B_FALSE, -1);
|
||||
err = dmu_objset_snapshot_one(name, dirname);
|
||||
if (err)
|
||||
return (err);
|
||||
err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 2010 Robert Milkowski */
|
||||
@ -2248,9 +2249,8 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers)
|
||||
sa_register_update_callback(os, zfs_sa_upgrade);
|
||||
}
|
||||
|
||||
spa_history_log_internal(LOG_DS_UPGRADE,
|
||||
dmu_objset_spa(os), tx, "oldver=%llu newver=%llu dataset = %llu",
|
||||
zfsvfs->z_version, newvers, dmu_objset_id(os));
|
||||
spa_history_log_internal_ds(dmu_objset_ds(os), "upgrade", tx,
|
||||
"from %llu to %llu", zfsvfs->z_version, newvers);
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
* Portions Copyright 2010 Robert Milkowski
|
||||
*
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -135,7 +136,7 @@ typedef struct zvol_state {
|
||||
int zvol_maxphys = DMU_MAX_ACCESS/2;
|
||||
|
||||
extern int zfs_set_prop_nvlist(const char *, zprop_source_t,
|
||||
nvlist_t *, nvlist_t **);
|
||||
nvlist_t *, nvlist_t *);
|
||||
static int zvol_remove_zv(zvol_state_t *);
|
||||
static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio);
|
||||
static int zvol_dumpify(zvol_state_t *zv);
|
||||
@ -1885,7 +1886,7 @@ zvol_dumpify(zvol_state_t *zv)
|
||||
|
||||
if (zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE,
|
||||
8, 1, &dumpsize) != 0 || dumpsize != zv->zv_volsize) {
|
||||
boolean_t resize = (dumpsize > 0) ? B_TRUE : B_FALSE;
|
||||
boolean_t resize = (dumpsize > 0);
|
||||
|
||||
if ((error = zvol_dump_init(zv, resize)) != 0) {
|
||||
(void) zvol_dump_fini(zv);
|
||||
|
@ -27,8 +27,6 @@
|
||||
#ifndef _SYS_FEATURE_TESTS_H
|
||||
#define _SYS_FEATURE_TESTS_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <sys/ccompile.h>
|
||||
#include <sys/isa_defs.h>
|
||||
|
||||
@ -365,7 +363,7 @@ extern "C" {
|
||||
* compiler is used. This allows for the use of single prototype
|
||||
* declarations regardless of compiler version.
|
||||
*/
|
||||
#if (defined(__STDC__) && defined(_STDC_C99))
|
||||
#if (defined(__STDC__) && defined(_STDC_C99)) && !defined(__cplusplus)
|
||||
#define _RESTRICT_KYWD restrict
|
||||
#else
|
||||
#define _RESTRICT_KYWD
|
||||
|
@ -52,6 +52,16 @@ typedef enum {
|
||||
ZFS_TYPE_POOL = 0x8
|
||||
} zfs_type_t;
|
||||
|
||||
typedef enum dmu_objset_type {
|
||||
DMU_OST_NONE,
|
||||
DMU_OST_META,
|
||||
DMU_OST_ZFS,
|
||||
DMU_OST_ZVOL,
|
||||
DMU_OST_OTHER, /* For testing only! */
|
||||
DMU_OST_ANY, /* Be careful! */
|
||||
DMU_OST_NUMTYPES
|
||||
} dmu_objset_type_t;
|
||||
|
||||
#define ZFS_TYPE_DATASET \
|
||||
(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME | ZFS_TYPE_SNAPSHOT)
|
||||
|
||||
@ -744,10 +754,10 @@ typedef struct ddt_histogram {
|
||||
/*
|
||||
* /dev/zfs ioctl numbers.
|
||||
*/
|
||||
#define ZFS_IOC ('Z' << 8)
|
||||
|
||||
typedef enum zfs_ioc {
|
||||
ZFS_IOC_POOL_CREATE = ZFS_IOC,
|
||||
ZFS_IOC_FIRST = ('Z' << 8),
|
||||
ZFS_IOC = ZFS_IOC_FIRST,
|
||||
ZFS_IOC_POOL_CREATE = ZFS_IOC_FIRST,
|
||||
ZFS_IOC_POOL_DESTROY,
|
||||
ZFS_IOC_POOL_IMPORT,
|
||||
ZFS_IOC_POOL_EXPORT,
|
||||
@ -806,10 +816,15 @@ typedef enum zfs_ioc {
|
||||
ZFS_IOC_OBJ_TO_STATS,
|
||||
ZFS_IOC_SPACE_WRITTEN,
|
||||
ZFS_IOC_SPACE_SNAPS,
|
||||
ZFS_IOC_DESTROY_SNAPS_NVL,
|
||||
ZFS_IOC_DESTROY_SNAPS,
|
||||
ZFS_IOC_POOL_REGUID,
|
||||
ZFS_IOC_POOL_REOPEN,
|
||||
ZFS_IOC_SEND_PROGRESS
|
||||
ZFS_IOC_SEND_PROGRESS,
|
||||
ZFS_IOC_LOG_HISTORY,
|
||||
ZFS_IOC_SEND_NEW,
|
||||
ZFS_IOC_SEND_SPACE,
|
||||
ZFS_IOC_CLONE,
|
||||
ZFS_IOC_LAST
|
||||
} zfs_ioc_t;
|
||||
|
||||
/*
|
||||
@ -846,6 +861,12 @@ typedef enum {
|
||||
#define ZPOOL_HIST_TXG "history txg"
|
||||
#define ZPOOL_HIST_INT_EVENT "history internal event"
|
||||
#define ZPOOL_HIST_INT_STR "history internal str"
|
||||
#define ZPOOL_HIST_INT_NAME "internal_name"
|
||||
#define ZPOOL_HIST_IOCTL "ioctl"
|
||||
#define ZPOOL_HIST_INPUT_NVL "in_nvl"
|
||||
#define ZPOOL_HIST_OUTPUT_NVL "out_nvl"
|
||||
#define ZPOOL_HIST_DSNAME "dsname"
|
||||
#define ZPOOL_HIST_DSID "dsid"
|
||||
|
||||
/*
|
||||
* Flags for ZFS_IOC_VDEV_SET_STATE
|
||||
@ -891,56 +912,6 @@ typedef enum {
|
||||
#define ZFS_EV_VDEV_PATH "vdev_path"
|
||||
#define ZFS_EV_VDEV_GUID "vdev_guid"
|
||||
|
||||
/*
|
||||
* Note: This is encoded on-disk, so new events must be added to the
|
||||
* end, and unused events can not be removed. Be sure to edit
|
||||
* libzfs_pool.c: hist_event_table[].
|
||||
*/
|
||||
typedef enum history_internal_events {
|
||||
LOG_NO_EVENT = 0,
|
||||
LOG_POOL_CREATE,
|
||||
LOG_POOL_VDEV_ADD,
|
||||
LOG_POOL_REMOVE,
|
||||
LOG_POOL_DESTROY,
|
||||
LOG_POOL_EXPORT,
|
||||
LOG_POOL_IMPORT,
|
||||
LOG_POOL_VDEV_ATTACH,
|
||||
LOG_POOL_VDEV_REPLACE,
|
||||
LOG_POOL_VDEV_DETACH,
|
||||
LOG_POOL_VDEV_ONLINE,
|
||||
LOG_POOL_VDEV_OFFLINE,
|
||||
LOG_POOL_UPGRADE,
|
||||
LOG_POOL_CLEAR,
|
||||
LOG_POOL_SCAN,
|
||||
LOG_POOL_PROPSET,
|
||||
LOG_DS_CREATE,
|
||||
LOG_DS_CLONE,
|
||||
LOG_DS_DESTROY,
|
||||
LOG_DS_DESTROY_BEGIN,
|
||||
LOG_DS_INHERIT,
|
||||
LOG_DS_PROPSET,
|
||||
LOG_DS_QUOTA,
|
||||
LOG_DS_PERM_UPDATE,
|
||||
LOG_DS_PERM_REMOVE,
|
||||
LOG_DS_PERM_WHO_REMOVE,
|
||||
LOG_DS_PROMOTE,
|
||||
LOG_DS_RECEIVE,
|
||||
LOG_DS_RENAME,
|
||||
LOG_DS_RESERVATION,
|
||||
LOG_DS_REPLAY_INC_SYNC,
|
||||
LOG_DS_REPLAY_FULL_SYNC,
|
||||
LOG_DS_ROLLBACK,
|
||||
LOG_DS_SNAPSHOT,
|
||||
LOG_DS_UPGRADE,
|
||||
LOG_DS_REFQUOTA,
|
||||
LOG_DS_REFRESERV,
|
||||
LOG_POOL_SCAN_DONE,
|
||||
LOG_DS_USER_HOLD,
|
||||
LOG_DS_USER_RELEASE,
|
||||
LOG_POOL_SPLIT,
|
||||
LOG_END
|
||||
} history_internal_events_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user