librbd::mirror_mode_set(m_local_io_ctx, RBD_MIRROR_MODE_IMAGE);
m_deleter = new rbd::mirror::ImageDeleter(_rados,
- m_threads->timer, &m_threads->timer_lock);
+ m_threads->work_queue, m_threads->timer, &m_threads->timer_lock);
EXPECT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, 1 << 20));
ImageCtx *ictx = new ImageCtx(m_image_name, "", "", m_local_io_ctx,
#include "common/admin_socket.h"
#include "common/debug.h"
#include "common/errno.h"
+#include "common/WorkQueue.h"
#include "librbd/internal.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
Commands commands;
};
-ImageDeleter::ImageDeleter(RadosRef local_cluster, SafeTimer *timer,
- Mutex *timer_lock)
+ImageDeleter::ImageDeleter(RadosRef local_cluster, ContextWQ *work_queue,
+ SafeTimer *timer, Mutex *timer_lock)
: m_local(local_cluster),
m_running(1),
+ m_work_queue(work_queue),
m_delete_lock("rbd::mirror::ImageDeleter::Delete"),
m_image_deleter_thread(this),
m_failed_timer(timer),
void ImageDeleter::wait_for_scheduled_deletion(const std::string& image_name,
Context *ctx,
bool notify_on_failed_retry) {
- {
- Mutex::Locker l(m_delete_lock);
- auto del_info = find_delete_info(image_name);
- if (del_info) {
- (*del_info)->on_delete = ctx;
- (*del_info)->notify_on_failed_retry = notify_on_failed_retry;
- return;
- }
+ ctx = new FunctionContext([this, ctx](int r) {
+ m_work_queue->queue(ctx, r);
+ });
+
+ Mutex::Locker l(m_delete_lock);
+ auto del_info = find_delete_info(image_name);
+ if (!del_info) {
+ // image not scheduled for deletion
+ ctx->complete(0);
+ return;
}
- // image not scheduled for deletion
- ctx->complete(0);
+ (*del_info)->on_delete = ctx;
+ (*del_info)->notify_on_failed_retry = notify_on_failed_retry;
}
bool ImageDeleter::process_image_delete() {
void ImageDeleter::DeleteInfo::notify(int r) {
if (on_delete) {
dout(20) << "executing image deletion handler r=" << r << dendl;
- on_delete->complete(r);
+
+ Context *ctx = on_delete;
on_delete = nullptr;
+ ctx->complete(r);
}
}
#include "common/Timer.h"
#include "types.h"
+class ContextWQ;
+
namespace rbd {
namespace mirror {
public:
static const int EISPRM = 1000;
- ImageDeleter(RadosRef local_cluster, SafeTimer *timer, Mutex *timer_lock);
+ ImageDeleter(RadosRef local_cluster, ContextWQ *work_queue,
+ SafeTimer *timer, Mutex *timer_lock);
~ImageDeleter();
ImageDeleter(const ImageDeleter&) = delete;
ImageDeleter& operator=(const ImageDeleter&) = delete;
RadosRef m_local;
atomic_t m_running;
+ ContextWQ *m_work_queue;
+
std::deque<std::unique_ptr<DeleteInfo> > m_delete_queue;
Mutex m_delete_lock;
Cond m_delete_queue_cond;
// TODO: make interval configurable
m_local_cluster_watcher.reset(new ClusterWatcher(m_local, m_lock));
- m_image_deleter.reset(new ImageDeleter(m_local, m_threads->timer,
+ m_image_deleter.reset(new ImageDeleter(m_local, m_threads->work_queue,
+ m_threads->timer,
&m_threads->timer_lock));
m_image_sync_throttler.reset(new ImageSyncThrottler<>());