]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools/cephfs_mirror: Fix failed-to-syncing state priority across metrics paths 68924/head
authorKotresh HR <khiremat@redhat.com>
Mon, 13 Jul 2026 07:58:10 +0000 (13:28 +0530)
committerKotresh HR <khiremat@redhat.com>
Thu, 9 Jul 2026 14:14:36 +0000 (19:44 +0530)
When a mirrored directory hits the consecutive failure threshold, the
failed flag stays set until the next successful sync. On retry, the
directory can be actively syncing while failed remains true, but
dump_sync_stat() and update_directory_current_sync_perf_counters()
checked failed before current_syncing_snap and kept reporting "failed".

Introduce get_dir_sync_state() and use it in peer_status, omap
persistence, and per-directory perf counters so syncing takes precedence
over the sticky failed flag.

Fixes: https://tracker.ceph.com/issues/76616
Signed-off-by: Kotresh HR <khiremat@redhat.com>
src/tools/cephfs_mirror/PeerReplayer.cc
src/tools/cephfs_mirror/PeerReplayer.h

index 8cb8dbdd183ba37b8d8802cb90d8c343e2762da9..f5189cde582740c9f9ca7e3b36beaef4589a33b6 100644 (file)
@@ -443,16 +443,17 @@ void PeerReplayer::update_directory_current_sync_perf_counters(
     perf->set(l_cephfs_mirror_directory_current_eta_seconds, 0);
   };
 
-  if (sync_stat.failed) {
+  switch (get_dir_sync_state(sync_stat)) {
+  case DirSyncState::Failed:
     perf->set(l_cephfs_mirror_directory_dir_state, 2);
     clear_current();
     return;
-  }
-
-  if (!sync_stat.current_syncing_snap) {
+  case DirSyncState::Idle:
     perf->set(l_cephfs_mirror_directory_dir_state, 0);
     clear_current();
     return;
+  case DirSyncState::Syncing:
+    break;
   }
 
   perf->set(l_cephfs_mirror_directory_dir_state, 1);
@@ -972,7 +973,8 @@ void PeerReplayer::remove_persisted_dir_sync_stat(const std::string &dir_root) {
 
 void PeerReplayer::add_live_sync_metrics_to_persist(json_spirit::mObject &obj,
                                                     SnapSyncStat &sync_stat) {
-  if (sync_stat.current_syncing_snap) {
+  switch (get_dir_sync_state(sync_stat)) {
+  case DirSyncState::Syncing: {
     json_spirit::mObject snap;
     snap["id"] =
       json_spirit::mValue(static_cast<boost::uint64_t>(sync_stat.current_syncing_snap->first));
@@ -1055,13 +1057,17 @@ void PeerReplayer::add_live_sync_metrics_to_persist(json_spirit::mObject &obj,
 
     obj["state"] = json_spirit::mValue("syncing");
     obj["current_syncing_snap"] = json_spirit::mValue(snap);
-  } else if (sync_stat.failed) {
+    break;
+  }
+  case DirSyncState::Failed:
     obj["state"] = json_spirit::mValue("failed");
     if (sync_stat.last_failed_reason) {
       obj["failure_reason"] = json_spirit::mValue(*sync_stat.last_failed_reason);
     }
-  } else {
+    break;
+  case DirSyncState::Idle:
     obj["state"] = json_spirit::mValue("idle");
+    break;
   }
 }
 
@@ -3736,14 +3742,17 @@ double PeerReplayer::compute_eta(const PeerReplayer::SnapSyncStat& sync_stat) {
 }
 
 void PeerReplayer::dump_sync_stat(Formatter *f, const SnapSyncStat &sync_stat) {
-  if (sync_stat.failed) {
+  switch (get_dir_sync_state(sync_stat)) {
+  case DirSyncState::Failed:
     f->dump_string("state", "failed");
     if (sync_stat.last_failed_reason) {
       f->dump_string("failure_reason", *sync_stat.last_failed_reason);
     }
-  } else if (!sync_stat.current_syncing_snap) {
+    break;
+  case DirSyncState::Idle:
     f->dump_string("state", "idle");
-  } else {
+    break;
+  case DirSyncState::Syncing:
     f->dump_string("state", "syncing");
     f->open_object_section("current_syncing_snap");
     f->dump_unsigned("id", (*sync_stat.current_syncing_snap).first);
@@ -3815,6 +3824,7 @@ void PeerReplayer::dump_sync_stat(Formatter *f, const SnapSyncStat &sync_stat) {
     else
       f->dump_string("eta", format_time(compute_eta(sync_stat)));
     f->close_section(); //current_syncing_snap
+    break;
   }
   if (sync_stat.last_synced_snap) {
     f->open_object_section("last_synced_snap");
index 0a12fe87d25fd2f6f4b22ae6c33b6ccb3c55c102..40f5cc637e718a3e45076318f1601622d1de2ce6 100644 (file)
@@ -440,6 +440,22 @@ private:
     boost::optional<monotime> datasync_queue_wait_start_time; // until first pop; for in-progress display
   };
 
+  enum class DirSyncState {
+    Idle,
+    Syncing,
+    Failed,
+  };
+
+  static DirSyncState get_dir_sync_state(const SnapSyncStat &sync_stat) {
+    if (sync_stat.current_syncing_snap) {
+      return DirSyncState::Syncing;
+    }
+    if (sync_stat.failed) {
+      return DirSyncState::Failed;
+    }
+    return DirSyncState::Idle;
+  }
+
   void _inc_failed_count(const std::string &dir_root) {
     auto max_failures = g_ceph_context->_conf.get_val<uint64_t>(
     "cephfs_mirror_max_consecutive_failures_per_directory");