diff options
author | ahrens <none@none> | 2007-12-22 14:50:27 -0800 |
---|---|---|
committer | ahrens <none@none> | 2007-12-22 14:50:27 -0800 |
commit | c391e322108d10533bc61ba3ef7099b302214341 (patch) | |
tree | b63be41e4121dfe6c38d2404978e71cdb0885f15 /usr/src/lib/libzfs/common/libzfs_dataset.c | |
parent | f8919bdadda3ebb97bd55cc14a16e0271ed57615 (diff) | |
download | illumos-joyent-c391e322108d10533bc61ba3ef7099b302214341.tar.gz |
PSARC/2007/699 zfs rollback -f operative
6641210 zfs rollback -R fails with EBUSY if there is a clone
Diffstat (limited to 'usr/src/lib/libzfs/common/libzfs_dataset.c')
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_dataset.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 347faa485c..5459514662 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -3331,8 +3331,9 @@ zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive) typedef struct rollback_data { const char *cb_target; /* the snapshot */ uint64_t cb_create; /* creation time reference */ - int cb_error; + boolean_t cb_error; boolean_t cb_dependent; + boolean_t cb_force; } rollback_data_t; static int @@ -3358,7 +3359,22 @@ rollback_destroy(zfs_handle_t *zhp, void *data) zhp->zfs_hdl->libzfs_log_str = logstr; } } else { - cbp->cb_error |= zfs_destroy(zhp); + /* We must destroy this clone; first unmount it */ + prop_changelist_t *clp; + + clp = changelist_gather(zhp, ZFS_PROP_NAME, + cbp->cb_force ? MS_FORCE: 0); + if (clp == NULL || changelist_prefix(clp) != 0) { + cbp->cb_error = B_TRUE; + zfs_close(zhp); + return (0); + } + if (zfs_destroy(zhp) != 0) + cbp->cb_error = B_TRUE; + else + changelist_remove(clp, zhp->zfs_name); + changelist_postfix(clp); + changelist_free(clp); } zfs_close(zhp); @@ -3373,7 +3389,7 @@ rollback_destroy(zfs_handle_t *zhp, void *data) * their dependents. */ int -zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap) +zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force) { rollback_data_t cb = { 0 }; int err; @@ -3388,12 +3404,13 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap) /* * Destroy all recent snapshots and its dependends. */ + cb.cb_force = force; cb.cb_target = snap->zfs_name; cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG); (void) zfs_iter_children(zhp, rollback_destroy, &cb); - if (cb.cb_error != 0) - return (cb.cb_error); + if (cb.cb_error) + return (-1); /* * Now that we have verified that the snapshot is the latest, |