#include "librbd/Utils.h"
#include "ImageReplayer.h"
#include "InstanceReplayer.h"
+#include "ServiceDaemon.h"
#include "Threads.h"
#define dout_context g_ceph_context
namespace rbd {
namespace mirror {
+namespace {
+
+const std::string SERVICE_DAEMON_ASSIGNED_COUNT_KEY("image_assigned_count");
+const std::string SERVICE_DAEMON_WARNING_COUNT_KEY("image_warning_count");
+const std::string SERVICE_DAEMON_ERROR_COUNT_KEY("image_error_count");
+
+} // anonymous namespace
+
using librbd::util::create_async_context_callback;
using librbd::util::create_context_callback;
template <typename I>
InstanceReplayer<I>::InstanceReplayer(
- Threads<I> *threads, std::shared_ptr<ImageDeleter> image_deleter,
- RadosRef local_rados, const std::string &local_mirror_uuid,
- int64_t local_pool_id)
- : m_threads(threads), m_image_deleter(image_deleter),
- m_local_rados(local_rados), m_local_mirror_uuid(local_mirror_uuid),
- m_local_pool_id(local_pool_id),
+ Threads<I> *threads, ServiceDaemon<I>* service_daemon,
+ ImageDeleter<I>* image_deleter, RadosRef local_rados,
+ const std::string &local_mirror_uuid, int64_t local_pool_id)
+ : m_threads(threads), m_service_daemon(service_daemon),
+ m_image_deleter(image_deleter), m_local_rados(local_rados),
+ m_local_mirror_uuid(local_mirror_uuid), m_local_pool_id(local_pool_id),
m_lock("rbd::mirror::InstanceReplayer " + stringify(local_pool_id)) {
}
[this, image_replayer, on_finish] (int r) {
auto global_image_id = image_replayer->get_global_image_id();
m_image_deleter->schedule_image_delete(
- m_local_rados, m_local_pool_id, global_image_id);
+ m_local_rados, m_local_pool_id, global_image_id, false);
on_finish->complete(0);
});
}
}
template <typename I>
-void InstanceReplayer<I>::start_image_replayers() {
+void InstanceReplayer<I>::queue_start_image_replayers() {
dout(20) << dendl;
- Context *ctx = new FunctionContext(
- [this] (int r) {
- Mutex::Locker locker(m_lock);
- m_async_op_tracker.finish_op();
- if (m_on_shut_down != nullptr) {
- return;
- }
- for (auto &it : m_image_replayers) {
- start_image_replayer(it.second);
- }
- });
-
+ Context *ctx = create_context_callback<
+ InstanceReplayer, &InstanceReplayer<I>::start_image_replayers>(this);
m_async_op_tracker.start_op();
m_threads->work_queue->queue(ctx, 0);
}
+template <typename I>
+void InstanceReplayer<I>::start_image_replayers(int r) {
+ dout(20) << dendl;
+
+ Mutex::Locker locker(m_lock);
+ if (m_on_shut_down != nullptr) {
+ return;
+ }
+
+ size_t image_count = 0;
+ size_t warning_count = 0;
+ size_t error_count = 0;
+ for (auto &it : m_image_replayers) {
+ ++image_count;
+ auto health_state = it.second->get_health_state();
+ if (health_state == image_replayer::HEALTH_STATE_WARNING) {
+ ++warning_count;
+ } else if (health_state == image_replayer::HEALTH_STATE_ERROR) {
+ ++error_count;
+ }
+
+ start_image_replayer(it.second);
+ }
+
+ m_service_daemon->add_or_update_attribute(
+ m_local_pool_id, SERVICE_DAEMON_ASSIGNED_COUNT_KEY, image_count);
+ m_service_daemon->add_or_update_attribute(
+ m_local_pool_id, SERVICE_DAEMON_WARNING_COUNT_KEY, warning_count);
+ m_service_daemon->add_or_update_attribute(
+ m_local_pool_id, SERVICE_DAEMON_ERROR_COUNT_KEY, error_count);
+
+ m_async_op_tracker.finish_op();
+}
template <typename I>
void InstanceReplayer<I>::stop_image_replayer(ImageReplayer<I> *image_replayer,
assert(m_threads->timer_lock.is_locked());
m_image_state_check_task = nullptr;
schedule_image_state_check_task();
- start_image_replayers();
+ queue_start_image_replayers();
});
- int after =
- max(1, g_ceph_context->_conf->rbd_mirror_image_state_check_interval);
+ int after = g_ceph_context->_conf->rbd_mirror_image_state_check_interval;
dout(20) << "scheduling image state check after " << after << " sec (task "
<< m_image_state_check_task << ")" << dendl;