From: Venky Shankar Date: Wed, 24 Aug 2016 15:08:03 +0000 (+0530) Subject: librbd: use async image removal state machine X-Git-Tag: v12.0.1~282^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=dccb3c0045b997d3132699447bbbe0fb2d6bb44f;p=ceph.git librbd: use async image removal state machine Signed-off-by: Venky Shankar --- diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 703e496e259e..175fc862ba39 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -35,6 +35,7 @@ #include "librbd/exclusive_lock/AutomaticPolicy.h" #include "librbd/exclusive_lock/StandardPolicy.h" #include "librbd/image/CreateRequest.h" +#include "librbd/image/RemoveRequest.h" #include "librbd/managed_lock/Types.h" #include "librbd/mirror/DisableRequest.h" #include "librbd/mirror/EnableRequest.h" @@ -165,46 +166,6 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, return 0; } -void filter_out_mirror_watchers(ImageCtx *ictx, - std::list *watchers) { - if (watchers->empty()) { - return; - } - - if ((ictx->features & RBD_FEATURE_JOURNALING) == 0) { - return; - } - - cls::rbd::MirrorImage mirror_image; - int r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id, &mirror_image); - if (r < 0) { - if (r != -ENOENT) { - lderr(ictx->cct) << "failed to retrieve mirroring state: " - << cpp_strerror(r) << dendl; - } - return; - } - - if (mirror_image.state != cls::rbd::MIRROR_IMAGE_STATE_ENABLED) { - return; - } - - std::list mirror_watchers; - r = ictx->md_ctx.list_watchers(RBD_MIRRORING, &mirror_watchers); - if (r < 0) { - if (r != -ENOENT) { - lderr(ictx->cct) << "error listing mirroring watchers: " - << cpp_strerror(r) << dendl; - } - return; - } - for (auto &watcher : mirror_watchers) { - watchers->remove_if([watcher] (obj_watch_t &w) { - return (strncmp(w.addr, watcher.addr, sizeof(w.addr)) == 0); - }); - } -} - } // anonymous namespace int detect_format(IoCtx &io_ctx, const string &name, @@ -1660,218 +1621,18 @@ void filter_out_mirror_watchers(ImageCtx *ictx, ldout(cct, 20) << "remove " << &io_ctx << " " << (image_id.empty() ? image_name : image_id) << dendl; - std::string name(image_name); - std::string id(image_id); - bool old_format = false; - bool unknown_format = true; - ImageCtx *ictx = new ImageCtx( - (id.empty() ? name : std::string()), id, nullptr, io_ctx, false); - int r = ictx->state->open(true); - if (r < 0) { - ldout(cct, 2) << "error opening image: " << cpp_strerror(-r) << dendl; - delete ictx; - if (r != -ENOENT) { - return r; - } - } else { - string header_oid = ictx->header_oid; - old_format = ictx->old_format; - unknown_format = false; - name = ictx->name; - id = ictx->id; - - ictx->owner_lock.get_read(); - if (ictx->exclusive_lock != nullptr) { - if (force) { - // releasing read lock to avoid a deadlock when upgrading to - // write lock in the shut_down process - ictx->owner_lock.put_read(); - if (ictx->exclusive_lock != nullptr) { - C_SaferCond ctx; - ictx->exclusive_lock->shut_down(&ctx); - r = ctx.wait(); - if (r < 0) { - lderr(cct) << "error shutting down exclusive lock: " - << cpp_strerror(r) << dendl; - ictx->state->close(); - return r; - } - assert (ictx->exclusive_lock == nullptr); - ictx->owner_lock.get_read(); - } - } else { - r = ictx->operations->prepare_image_update(); - if (r < 0 || !ictx->exclusive_lock->is_lock_owner()) { - lderr(cct) << "cannot obtain exclusive lock - not removing" << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return -EBUSY; - } - } - } - - if (ictx->snaps.size()) { - lderr(cct) << "image has snapshots - not removing" << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return -ENOTEMPTY; - } - - std::list watchers; - r = io_ctx.list_watchers(header_oid, &watchers); - if (r < 0) { - lderr(cct) << "error listing watchers" << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return r; - } - - // If an image is being bootstrapped by rbd-mirror, it implies - // that the rbd-mirror daemon currently has the image open. - // Permit removal if this is the case. - filter_out_mirror_watchers(ictx, &watchers); - - if (watchers.size() > 1) { - lderr(cct) << "image has watchers - not removing" << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return -EBUSY; - } - - cls::rbd::GroupSpec s; - r = cls_client::image_get_group(&io_ctx, header_oid, &s); - if (r < 0 && r != -EOPNOTSUPP) { - lderr(cct) << "error querying consistency group" << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return r; - } else if (s.is_valid()) { - lderr(cct) << "image is in a consistency group - not removing" << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return -EMLINK; - } - - trim_image(ictx, 0, prog_ctx); - - ictx->parent_lock.get_read(); - // struct assignment - parent_info parent_info = ictx->parent_md; - ictx->parent_lock.put_read(); - - r = cls_client::remove_child(&ictx->md_ctx, RBD_CHILDREN, - parent_info.spec, id); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error removing child from children list" << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return r; - } - - if (!old_format) { - r = mirror_image_disable_internal(ictx, force, !force); - if (r < 0 && r != -EOPNOTSUPP) { - lderr(cct) << "error disabling image mirroring: " << cpp_strerror(r) - << dendl; - ictx->owner_lock.put_read(); - ictx->state->close(); - return r; - } - } - - ictx->owner_lock.put_read(); - ictx->state->close(); - - ldout(cct, 2) << "removing header..." << dendl; - r = io_ctx.remove(header_oid); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error removing header: " << cpp_strerror(-r) << dendl; - return r; - } - } - - if (old_format || unknown_format) { - ldout(cct, 2) << "removing rbd image from v1 directory..." << dendl; - r = tmap_rm(io_ctx, name); - old_format = (r == 0); - if (r < 0 && !unknown_format) { - if (r != -ENOENT) { - lderr(cct) << "error removing image from v1 directory: " - << cpp_strerror(-r) << dendl; - } - return r; - } - } - if (!old_format) { - if (id.empty()) { - ldout(cct, 5) << "attempting to determine image id" << dendl; - r = cls_client::dir_get_id(&io_ctx, RBD_DIRECTORY, name, &id); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error getting id of image" << dendl; - return r; - } - } else if (name.empty()) { - ldout(cct, 5) << "attempting to determine image name" << dendl; - r = cls_client::dir_get_name(&io_ctx, RBD_DIRECTORY, id, &name); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error getting name of image" << dendl; - return r; - } - } - - if (!id.empty()) { - ldout(cct, 2) << "removing header..." << dendl; - r = io_ctx.remove(util::header_name(id)); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error removing header: " << cpp_strerror(-r) << dendl; - return r; - } - - ldout(cct, 10) << "removing journal..." << dendl; - r = Journal<>::remove(io_ctx, id); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error removing image journal" << dendl; - return r; - } - - ldout(cct, 10) << "removing object map..." << dendl; - r = ObjectMap<>::remove(io_ctx, id); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error removing image object map" << dendl; - return r; - } - - ldout(cct, 10) << "removing image from rbd_mirroring object..." - << dendl; - r = cls_client::mirror_image_remove(&io_ctx, id); - if (r < 0 && r != -ENOENT && r != -EOPNOTSUPP) { - lderr(cct) << "failed to remove image from mirroring directory: " - << cpp_strerror(r) << dendl; - return r; - } - } - - ldout(cct, 2) << "removing id object..." << dendl; - r = io_ctx.remove(util::id_obj_name(name)); - if (r < 0 && r != -ENOENT) { - lderr(cct) << "error removing id object: " << cpp_strerror(r) - << dendl; - return r; - } + C_SaferCond cond; + ContextWQ op_work_queue("librbd::op_work_queue", + cct->_conf->rbd_op_thread_timeout, + ImageCtx::get_thread_pool_instance(cct)); + librbd::image::RemoveRequest<> *req = librbd::image::RemoveRequest<>::create( + io_ctx, image_name, image_id, force, prog_ctx, &op_work_queue, &cond); + req->send(); - ldout(cct, 2) << "removing rbd image from v2 directory..." << dendl; - r = cls_client::dir_remove_image(&io_ctx, RBD_DIRECTORY, name, id); - if (r < 0) { - if (r != -ENOENT) { - lderr(cct) << "error removing image from v2 directory: " - << cpp_strerror(-r) << dendl; - } - return r; - } - } + int r = cond.wait(); + op_work_queue.drain(); - ldout(cct, 2) << "done." << dendl; - return 0; + return r; } int snap_list(ImageCtx *ictx, vector& snaps)