*id = payload.async_request_id;
}
return true;
+ case NOTIFY_OP_REBUILD_OBJECT_MAP:
+ {
+ RebuildObjectMapPayload payload;
+ payload.decode(2, iter);
+ *id = payload.async_request_id;
+ }
+ return true;
default:
break;
}
}
};
+struct RebuildObjectMapTask {
+ librbd::ImageCtx *ictx;
+ ProgressContext *progress_context;
+ int result;
+
+ RebuildObjectMapTask(librbd::ImageCtx *ictx_, ProgressContext *ctx)
+ : ictx(ictx_), progress_context(ctx), result(0) {}
+
+ void operator()() {
+ RWLock::RLocker l(ictx->owner_lock);
+ result = ictx->image_watcher->notify_rebuild_object_map(0, *progress_context);
+ }
+};
+
TEST_F(TestImageWatcher, IsLockSupported) {
REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
ASSERT_EQ(0, resize_task.result);
}
+TEST_F(TestImageWatcher, NotifyRebuildObjectMap) {
+ REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ ASSERT_EQ(0, register_image_watch(*ictx));
+ ASSERT_EQ(0, lock_image(*ictx, LOCK_EXCLUSIVE,
+ "auto " + stringify(m_watch_ctx->get_handle())));
+
+ m_notify_acks = boost::assign::list_of(
+ std::make_pair(NOTIFY_OP_REBUILD_OBJECT_MAP, create_response_message(0)));
+
+ ProgressContext progress_context;
+ RebuildObjectMapTask rebuild_task(ictx, &progress_context);
+ boost::thread thread(boost::ref(rebuild_task));
+
+ ASSERT_TRUE(wait_for_notifies(*ictx));
+
+ NotifyOps expected_notify_ops;
+ expected_notify_ops += NOTIFY_OP_REBUILD_OBJECT_MAP;
+ ASSERT_EQ(expected_notify_ops, m_notifies);
+
+ AsyncRequestId async_request_id;
+ ASSERT_TRUE(extract_async_request_id(NOTIFY_OP_REBUILD_OBJECT_MAP,
+ &async_request_id));
+
+ ASSERT_EQ(0, notify_async_progress(ictx, async_request_id, 10, 20));
+ ASSERT_TRUE(progress_context.wait(ictx, 10, 20));
+
+ ASSERT_EQ(0, notify_async_complete(ictx, async_request_id, 0));
+
+ ASSERT_TRUE(thread.timed_join(boost::posix_time::seconds(10)));
+ ASSERT_EQ(0, rebuild_task.result);
+}
+
TEST_F(TestImageWatcher, NotifySnapCreate) {
REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);