CEPH_RBD_API void rbd_snap_list_end(rbd_snap_info_t *snaps);
CEPH_RBD_API int rbd_snap_create(rbd_image_t image, const char *snapname);
CEPH_RBD_API int rbd_snap_remove(rbd_image_t image, const char *snapname);
+CEPH_RBD_API int rbd_snap_remove2(rbd_image_t image, const char *snap_name, uint32_t flags,
+ librbd_progress_fn_t cb, void *cbdata);
CEPH_RBD_API int rbd_snap_rollback(rbd_image_t image, const char *snapname);
CEPH_RBD_API int rbd_snap_rollback_with_progress(rbd_image_t image,
const char *snapname,
int snap_exists2(const char *snapname, bool *exists);
int snap_create(const char *snapname);
int snap_remove(const char *snapname);
- int snap_remove2(const char *snapname, uint32_t flags);
+ int snap_remove2(const char *snapname, uint32_t flags, ProgressContext& pctx);
int snap_rollback(const char *snap_name);
int snap_rollback_with_progress(const char *snap_name, ProgressContext& pctx);
int snap_protect(const char *snap_name);
return 0;
}
- int flatten_children(ImageCtx *ictx, const char* snap_name)
+ int flatten_children(ImageCtx *ictx, const char* snap_name, ProgressContext& pctx)
{
CephContext *cct = ictx->cct;
ldout(cct, 20) << "children flatten " << ictx->name << dendl;
return r;
}
+ size_t size = image_info.size();
+ if (size == 0)
+ return 0;
+
+ size_t i = 0;
Rados rados(ictx->md_ctx);
for ( auto &info : image_info){
string pool = info.first.second;
}
imctx->state->close();
}
+ pctx.update_progress(++i, size);
+ assert(i <= size);
}
return 0;
return 0;
}
- int snap_remove(ImageCtx *ictx, const char *snap_name, uint32_t flags)
+ int snap_remove(ImageCtx *ictx, const char *snap_name, uint32_t flags, ProgressContext& pctx)
{
ldout(ictx->cct, 20) << "snap_remove " << ictx << " " << snap_name << " flags: " << flags << dendl;
return r;
if (flags & RBD_SNAP_REMOVE_FLATTEN) {
- r = flatten_children(ictx, snap_name);
+ r = flatten_children(ictx, snap_name, pctx);
if (r < 0) {
return r;
}
}
- if (flags & RBD_SNAP_REMOVE_UNPROTECT) {
+ bool is_protected;
+ r = snap_is_protected(ictx, snap_name, &is_protected);
+ if (r < 0) {
+ return r;
+ }
+
+ if (is_protected && flags & RBD_SNAP_REMOVE_UNPROTECT) {
r = ictx->operations->snap_unprotect(snap_name);
- if (r < 0)
+ if (r < 0) {
+ lderr(ictx->cct) << "failed to unprotect snapshot: " << snap_name << dendl;
return r;
+ }
+
+ r = snap_is_protected(ictx, snap_name, &is_protected);
+ if (r < 0) {
+ return r;
+ }
+ if (is_protected) {
+ lderr(ictx->cct) << "snapshot is still protected after unprotection" << dendl;
+ assert(0);
+ }
}
C_SaferCond ctx;
int snap_exists(ImageCtx *ictx, const char *snap_name, bool *exists);
int snap_get_limit(ImageCtx *ictx, uint64_t *limit);
int snap_set_limit(ImageCtx *ictx, uint64_t limit);
- int snap_remove(ImageCtx *ictx, const char *snap_name, uint32_t flags);
+ int snap_remove(ImageCtx *ictx, const char *snap_name, uint32_t flags, ProgressContext& pctx);
int snap_is_protected(ImageCtx *ictx, const char *snap_name,
bool *is_protected);
int copy(ImageCtx *ictx, IoCtx& dest_md_ctx, const char *destname,
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_remove_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_remove(ictx, snap_name, 0);
+ librbd::NoOpProgressContext prog_ctx;
+ int r = librbd::snap_remove(ictx, snap_name, 0, prog_ctx);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
- int Image::snap_remove2(const char *snap_name, uint32_t flags)
+ int Image::snap_remove2(const char *snap_name, uint32_t flags, ProgressContext& pctx)
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_remove2_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name, flags);
- int r = librbd::snap_remove(ictx, snap_name, flags);
+ int r = librbd::snap_remove(ictx, snap_name, flags, pctx);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
return r;
}
-extern "C" int rbd_snap_remove2(rbd_image_t image, const char *snap_name, uint32_t flags)
+extern "C" int rbd_snap_remove2(rbd_image_t image, const char *snap_name, uint32_t flags,
+ librbd_progress_fn_t cb, void *cbdata)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_remove2_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name, flags);
- int r = librbd::snap_remove(ictx, snap_name, flags);
+ librbd::CProgressContext prog_ctx(cb, cbdata);
+ int r = librbd::snap_remove(ictx, snap_name, flags, prog_ctx);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
void rbd_snap_list_end(rbd_snap_info_t *snaps)
int rbd_snap_create(rbd_image_t image, const char *snapname)
int rbd_snap_remove(rbd_image_t image, const char *snapname)
- int rbd_snap_remove2(rbd_image_t image, const char *snapname, uint32_t flags)
+ int rbd_snap_remove2(rbd_image_t image, const char *snapname, uint32_t flags,
+ librbd_progress_fn_t cb, void *cbdata)
int rbd_snap_rollback(rbd_image_t image, const char *snapname)
int rbd_snap_rename(rbd_image_t image, const char *snapname,
const char* dstsnapsname)
cdef:
char *_name = name
uint32_t _flags = flags
+ librbd_progress_fn_t prog_cb = &no_op_progress_callback
with nogil:
- ret = rbd_snap_remove2(self.image, _name, _flags)
+ ret = rbd_snap_remove2(self.image, _name, _flags, prog_cb, NULL)
if ret != 0:
raise make_ex(ret, 'error removing snapshot %s from %s with flags %llx' % (name, self.name, flags))
</stats>
# cleanup
- $ rbd snap remove rbd_other/deep-flatten-child@snap
- $ rbd snap remove rbd_other/child@snap
+ $ rbd snap remove --no-progress rbd_other/deep-flatten-child@snap
+ $ rbd snap remove --no-progress rbd_other/child@snap
$ rbd snap unprotect bar@snap
$ rbd snap purge bar 2> /dev/null
$ rbd snap purge foo 2> /dev/null
rbd help snap remove
usage: rbd snap remove [--pool <pool>] [--image <image>] [--snap <snap>]
- [--force]
+ [--no-progress] [--force]
<snap-spec>
Deletes a snapshot.
-p [ --pool ] arg pool name
--image arg image name
--snap arg snapshot name
+ --no-progress disable progress output
--force flatten children and unprotect snapshot if needed.
rbd help snap rename
return 0;
}
-int do_remove_snap(librbd::Image& image, const char *snapname, bool force)
+int do_remove_snap(librbd::Image& image, const char *snapname, bool force,
+ bool no_progress)
{
uint32_t flags = force? RBD_SNAP_REMOVE_FORCE : 0;
- int r = image.snap_remove2(snapname, flags);
- if (r < 0)
+ int r = 0;
+ utils::ProgressContext pc("Removing snap", no_progress);
+
+ r = image.snap_remove2(snapname, flags, pc);
+ if (r < 0) {
+ pc.fail();
return r;
+ }
+ pc.finish();
return 0;
}
void get_remove_arguments(po::options_description *positional,
po::options_description *options) {
at::add_snap_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
+ at::add_no_progress_option(options);
options->add_options()
("force", po::bool_switch(), "flatten children and unprotect snapshot if needed.");
return r;
}
- r = do_remove_snap(image, snap_name.c_str(), force);
+ r = do_remove_snap(image, snap_name.c_str(), force, vm[at::NO_PROGRESS].as<bool>());
if (r < 0) {
if (r == -EBUSY) {
std::cerr << "rbd: snapshot '" << snap_name << "' "