using util::create_async_context_callback;
using util::create_rados_ack_callback;
-static const std::string IMAGE_CLIENT_ID("");
-
template<typename I>
-RemoveRequest<I>::RemoveRequest(IoCtx &ioctx, const std::string &image_name, const std::string &image_id,
- bool force, ProgressContext &prog_ctx, ContextWQ *op_work_queue,
- Context *on_finish) :
- m_ioctx(ioctx), m_image_name(image_name), m_image_id(image_id), m_force(force),
- m_prog_ctx(prog_ctx), m_op_work_queue(op_work_queue), m_on_finish(on_finish) {
+RemoveRequest<I>::RemoveRequest(IoCtx &ioctx, const std::string &image_name,
+ const std::string &image_id, bool force,
+ ProgressContext &prog_ctx,
+ ContextWQ *op_work_queue, Context *on_finish)
+ : m_ioctx(ioctx), m_image_name(image_name), m_image_id(image_id),
+ m_force(force), m_prog_ctx(prog_ctx), m_op_work_queue(op_work_queue),
+ m_on_finish(on_finish) {
m_cct = reinterpret_cast<CephContext *>(m_ioctx.cct());
m_image_ctx = I::create((m_image_id.empty() ? m_image_name : std::string()),
ldout(m_cct, 20) << dendl;
using klass = RemoveRequest<I>;
- Context *ctx = create_context_callback<klass, &klass::handle_open_image>(this);
+ Context *ctx = create_context_callback<klass, &klass::handle_open_image>(
+ this);
m_image_ctx->state->open(true, ctx);
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if (*result < 0) {
+ m_image_ctx->destroy();
+ m_image_ctx = nullptr;
+
if (*result != -ENOENT) {
lderr(m_cct) << "error opening image: " << cpp_strerror(*result) << dendl;
+ return m_on_finish;
}
- m_ret_val = *result;
- switch_thread_context();
+
+ remove_image();
return nullptr;
}
using klass = RemoveRequest<I>;
if (m_force) {
- Context *ctx = create_context_callback<klass, &klass::handle_exclusive_lock_force>(this);
+ Context *ctx = create_context_callback<
+ klass, &klass::handle_exclusive_lock_force>(this);
m_image_ctx->exclusive_lock->shut_down(ctx);
} else {
- Context *ctx = create_context_callback<klass, &klass::handle_exclusive_lock>(this);
+ Context *ctx = create_context_callback<
+ klass, &klass::handle_exclusive_lock>(this);
RWLock::WLocker owner_lock(m_image_ctx->owner_lock);
m_image_ctx->exclusive_lock->try_acquire_lock(ctx);
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if (*result < 0) {
- lderr(m_cct) << "error shutting down exclusive lock" << cpp_strerror(*result)
- << dendl;
+ lderr(m_cct) << "error shutting down exclusive lock: "
+ << cpp_strerror(*result) << dendl;
send_close_image(*result);
return nullptr;
}
librados::AioCompletion *rados_completion =
create_rados_ack_callback<klass, &klass::handle_check_image_watchers>(this);
- int r = m_image_ctx->md_ctx.aio_operate(m_header_oid,
- rados_completion, &op, &m_out_bl);
+ int r = m_image_ctx->md_ctx.aio_operate(m_header_oid, rados_completion,
+ &op, &m_out_bl);
assert(r == 0);
rados_completion->release();
}
}
cls::rbd::MirrorImage mirror_image;
- int r = cls_client::mirror_image_get(&m_image_ctx->md_ctx, m_image_ctx->id, &mirror_image);
+ int r = cls_client::mirror_image_get(&m_image_ctx->md_ctx, m_image_ctx->id,
+ &mirror_image);
if (r < 0) {
if (r != -ENOENT) {
lderr(m_cct) << "failed to retrieve mirroring state: "
ldout(m_cct, 20) << ": r=" << *result << dendl;
if (*result < 0) {
- lderr(m_cct) << "error listing image watchers: " << cpp_strerror(*result) << dendl;
+ lderr(m_cct) << "error listing image watchers: " << cpp_strerror(*result)
+ << dendl;
send_close_image(*result);
return nullptr;
}
+
// 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.
librbd::cls_client::image_get_group_start(&op);
using klass = RemoveRequest<I>;
- librados::AioCompletion *rados_completion =
- create_rados_ack_callback<klass, &klass::handle_check_image_consistency_group>(this);
+ librados::AioCompletion *rados_completion = create_rados_ack_callback<
+ klass, &klass::handle_check_image_consistency_group>(this);
m_out_bl.clear();
- int r = m_image_ctx->md_ctx.aio_operate(m_header_oid,
- rados_completion, &op, &m_out_bl);
+ int r = m_image_ctx->md_ctx.aio_operate(m_header_oid, rados_completion, &op,
+ &m_out_bl);
assert(r == 0);
rados_completion->release();
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if (*result < 0) {
- lderr(m_cct) << "error fetching consistency group for image" << cpp_strerror(*result)
- << dendl;
+ lderr(m_cct) << "error fetching consistency group for image: "
+ << cpp_strerror(*result) << dendl;
send_close_image(*result);
return nullptr;
}
return nullptr;
}
if (s.is_valid()) {
- lderr(m_cct) << "image is in a consistency group - not removing" << dendl;
+ lderr(m_cct) << "image is in a group - not removing" << dendl;
send_close_image(-EMLINK);
return nullptr;
}
using klass = RemoveRequest<I>;
Context *ctx = create_async_context_callback(
- *m_image_ctx, create_context_callback<klass, &klass::handle_trim_image>(this));
+ *m_image_ctx, create_context_callback<
+ klass, &klass::handle_trim_image>(this));
RWLock::RLocker owner_lock(m_image_ctx->owner_lock);
- librbd::operation::TrimRequest<I> *req = librbd::operation::TrimRequest<I>::create(
+ auto req = librbd::operation::TrimRequest<I>::create(
*m_image_ctx, ctx, m_image_ctx->size, 0, m_prog_ctx);
req->send();
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if (*result < 0) {
- lderr(m_cct) << "warning: failed to remove some object(s): " << cpp_strerror(*result)
- << dendl;
+ lderr(m_cct) << "warning: failed to remove some object(s): "
+ << cpp_strerror(*result) << dendl;
}
if (m_old_format) {
if (*result == -ENOENT) {
*result = 0;
} else if (*result < 0) {
- lderr(m_cct) << "error removing child from children list" << cpp_strerror(*result)
- << dendl;
+ lderr(m_cct) << "error removing child from children list: "
+ << cpp_strerror(*result) << dendl;
send_close_image(*result);
return nullptr;
}
ldout(m_cct, 20) << dendl;
using klass = RemoveRequest<I>;
- Context *ctx = create_context_callback<klass, &klass::handle_disable_mirror>(this);
+ Context *ctx = create_context_callback<
+ klass, &klass::handle_disable_mirror>(this);
mirror::DisableRequest<I> *req =
mirror::DisableRequest<I>::create(m_image_ctx, m_force, !m_force, ctx);
Context *RemoveRequest<I>::handle_disable_mirror(int *result) {
ldout(m_cct, 20) << ": r=" << *result << dendl;
-
if (*result == -EOPNOTSUPP) {
*result = 0;
} else if (*result < 0) {
- lderr(m_cct) << "error disabling image mirroring: " << cpp_strerror(*result)
- << dendl;
+ lderr(m_cct) << "error disabling image mirroring: "
+ << cpp_strerror(*result) << dendl;
}
send_close_image(*result);
m_ret_val = r;
using klass = RemoveRequest<I>;
- Context *ctx = create_context_callback<klass, &klass::handle_send_close_image>(this);
+ Context *ctx = create_context_callback<
+ klass, &klass::handle_send_close_image>(this);
m_image_ctx->state->close(ctx);
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if (*result < 0) {
- lderr(m_cct) << "error encountered while closing image: " << cpp_strerror(*result)
- << dendl;
+ lderr(m_cct) << "error encountered while closing image: "
+ << cpp_strerror(*result) << dendl;
}
+ m_image_ctx->destroy();
+ m_image_ctx = nullptr;
if (m_ret_val < 0) {
- switch_thread_context();
- } else {
- remove_header();
+ *result = m_ret_val;
+ return m_on_finish;
}
+
+ remove_header();
return nullptr;
}
m_ret_val = *result;
}
- switch_thread_context();
- return nullptr;
-}
-
-template <typename I>
-void RemoveRequest<I>::switch_thread_context() {
- ldout(m_cct, 20) << dendl;
-
- using klass = RemoveRequest<I>;
-
- Context *ctx = create_context_callback<klass, &klass::handle_switch_thread_context>(this);
- m_op_work_queue->queue(ctx, 0);
-}
-
-template <typename I>
-void RemoveRequest<I>::handle_switch_thread_context(int r) {
- ldout(m_cct, 20) << ": r=" << r << dendl;
-
- m_image_ctx->destroy();
- m_image_ctx = nullptr;
-
- if (m_ret_val < 0 && m_ret_val != -ENOENT) {
- m_on_finish->complete(m_ret_val);
- return;
- }
-
remove_image();
- return;
+ return nullptr;
}
template<typename I>
ldout(m_cct, 20) << dendl;
using klass = RemoveRequest<I>;
- Context *ctx = create_context_callback<klass, &klass::handle_journal_remove>(this);
+ Context *ctx = create_context_callback<
+ klass, &klass::handle_journal_remove>(this);
journal::RemoveRequest<I> *req = journal::RemoveRequest<I>::create(
- m_ioctx, m_image_id, IMAGE_CLIENT_ID, m_op_work_queue, ctx);
+ m_ioctx, m_image_id, Journal<>::IMAGE_CLIENT_ID, m_op_work_queue, ctx);
req->send();
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if (*result < 0 && *result != -ENOENT && *result != -EOPNOTSUPP) {
- lderr(m_cct) << "failed to remove mirror image state: " << cpp_strerror(*result)
- << dendl;
+ lderr(m_cct) << "failed to remove mirror image state: "
+ << cpp_strerror(*result) << dendl;
return m_on_finish;
} else {
*result = 0;
}
m_on_finish->complete(r);
+ delete this;
return;
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if ((*result < 0) && (*result != -ENOENT)) {
- lderr(m_cct) << "error fetching image id: " << cpp_strerror(*result) << dendl;
+ lderr(m_cct) << "error fetching image id: " << cpp_strerror(*result)
+ << dendl;
return m_on_finish;
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if ((*result < 0) && (*result != -ENOENT)) {
- lderr(m_cct) << "error fetching image name: " << cpp_strerror(*result) << dendl;
+ lderr(m_cct) << "error fetching image name: " << cpp_strerror(*result)
+ << dendl;
return m_on_finish;
}
ldout(m_cct, 20) << ": r=" << *result << dendl;
if ((*result < 0) && (*result != -ENOENT)) {
- lderr(m_cct) << "error removing id object: " << cpp_strerror(*result) << dendl;
+ lderr(m_cct) << "error removing id object: " << cpp_strerror(*result)
+ << dendl;
return m_on_finish;
}
typedef ::librbd::image::TypeTraits<ImageCtxT> TypeTraits;
typedef typename TypeTraits::ContextWQ ContextWQ;
public:
- static RemoveRequest *create(librados::IoCtx &ioctx, const std::string &image_name, const std::string &image_id,
- bool force, ProgressContext &prog_ctx, ContextWQ *op_work_queue,
+ static RemoveRequest *create(librados::IoCtx &ioctx,
+ const std::string &image_name,
+ const std::string &image_id,
+ bool force, ProgressContext &prog_ctx,
+ ContextWQ *op_work_queue,
Context *on_finish) {
- return new RemoveRequest(ioctx, image_name, image_id, force, prog_ctx, op_work_queue, on_finish);
+ return new RemoveRequest(ioctx, image_name, image_id, force, prog_ctx,
+ op_work_queue, on_finish);
}
void send();
*
* <start>
* |
- * v
- * OPEN IMAGE-------------------
- * | |
+ * v
+ * OPEN IMAGE------------------\
+ * | |
* v |
- * error CHECK EXCLUSIVE LOCK---- |
- * _______<_______ | | |
- * | | v (aquired) |
- * | | AQUIRE EXCLUSIVE LOCK | |
- * | | / | | |
- * | |------<-------/ v | |
- * | | VALIDATE IMAGE REMOVAL<- |
+ * error CHECK EXCLUSIVE LOCK---\ |
+ * /-------<-------\ | | |
+ * | | | (acquired)|
+ * | | v | |
+ * | | AQUIRE EXCLUSIVE LOCK | |
+ * | | / | | |
+ * | |------<-------/ | | |
+ * | | v | |
+ * | | VALIDATE IMAGE REMOVAL<-/ |
* | | / | v
- * | |------<--------/ v |
+ * | \------<--------/ | |
+ * | v |
* | TRIM IMAGE |
* | | |
* v v |
* | REMOVE CHILD |
* | | |
* | v v
- * |--------->------------------>CLOSE IMAGE |
+ * \--------->------------------>CLOSE IMAGE |
* | |
* error v |
- * |------<--------| SWITCH THREAD CONTEXT<-----------
- * | | / |
- * | |-------<-------/ v
- * | | REMOVE HEADER
+ * /------<--------\ REMOVE HEADER<--------------/
* | | / |
- * | |-------<-------/ v
+ * | |-------<-------/ |
+ * | | v
* | | REMOVE JOURNAL
* | | / |
- * | |-------<-------/ v
+ * | |-------<-------/ |
+ * | | v
* v ^ REMOVE OBJECTMAP
* | | / |
- * | |-------<-------/ v
+ * | |-------<-------/ |
+ * | | v
* | | REMOVE MIRROR IMAGE
* | | / |
- * | |-------<-------/ v
+ * | |-------<-------/ |
+ * | | v
* | | REMOVE ID OBJECT
* | | / |
- * | |-------<-------/ v
+ * | |-------<-------/ |
+ * | | v
* | | REMOVE IMAGE
* | | / |
- * | |-------<-------/ v
- * ------------------->------------<finish>
+ * | \-------<-------/ |
+ * | v
+ * \------------------>------------<finish>
*
* @endverbatim
*/
- RemoveRequest(librados::IoCtx &ioctx, const std::string &image_name, const std::string &image_id,
- bool force, ProgressContext &prog_ctx, ContextWQ *op_work_queue, Context *on_finish);
+ RemoveRequest(librados::IoCtx &ioctx, const std::string &image_name,
+ const std::string &image_id, bool force,
+ ProgressContext &prog_ctx, ContextWQ *op_work_queue,
+ Context *on_finish);
librados::IoCtx &m_ioctx;
std::string m_image_name;
void send_close_image(int r);
Context *handle_send_close_image(int *result);
- void switch_thread_context();
- void handle_switch_thread_context(int r);
-
void remove_header();
Context *handle_remove_header(int *result);