]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs_mirror: avoid latest changes on the source fs to enable mirroring
authorJos Collin <jcollin@redhat.com>
Mon, 27 Jan 2025 12:42:34 +0000 (18:12 +0530)
committerVenky Shankar <vshankar@redhat.com>
Wed, 4 Jun 2025 14:52:56 +0000 (20:22 +0530)
This avoids considering latest changes from the source filesystem for
the mirroring of already existing snapshots. Thus the destination
filesystem and snapshots would be created based only on the source snapshots.
The destination fs would be a replica of the last snapshot taken.

Fixes: https://tracker.ceph.com/issues/68567
Signed-off-by: Jos Collin <jcollin@redhat.com>
(cherry picked from commit 23e4cd5756718ce0183688c9a6514ff53226d9d1)

src/tools/cephfs_mirror/PeerReplayer.cc

index 50610c7503a3bb0f377d84b8de0cc020997b3493..357821484ccc1c74acc0f9d9cd32e71e4d00083e 100644 (file)
@@ -68,12 +68,6 @@ std::string entry_path(const std::string &dir, const std::string &name) {
   return dir + "/" + name;
 }
 
-std::string entry_diff_path(const std::string &dir, const std::string &name) {
-  if (dir == ".")
-    return name;
-  return dir + "/" + name;
-}
-
 std::map<std::string, std::string> decode_snap_metadata(snap_metadata *snap_metadata,
                                                         size_t nr_snap_metadata) {
   std::map<std::string, std::string> metadata;
@@ -1446,7 +1440,7 @@ int PeerReplayer::do_synchronize(const std::string &dir_root, const Snapshot &cu
   std::queue<SyncEntry> sync_queue;
 
   //start with initial/default entry
-  std::string epath = ".", npath = "", nabs_path = "", nname = "";
+  std::string epath = ".", npath = "", nname = "";
   sync_queue.emplace(SyncEntry(epath, cstx));
 
   while (!sync_queue.empty()) {
@@ -1481,19 +1475,17 @@ int PeerReplayer::do_synchronize(const std::string &dir_root, const Snapshot &cu
       if ("." == nname || ".." == nname)
         continue;
       // create path for the newly found entry
-      npath = entry_diff_path(epath, nname);
-      nabs_path = entry_diff_path(dir_root, npath);
-
-      r = ceph_statx(sd_info.cmount, nabs_path.c_str(), &cstx,
-                     CEPH_STATX_MODE | CEPH_STATX_UID | CEPH_STATX_GID |
-                     CEPH_STATX_SIZE | CEPH_STATX_ATIME | CEPH_STATX_MTIME,
-                     AT_STATX_DONT_SYNC | AT_SYMLINK_NOFOLLOW);
+      npath = entry_path(epath, nname);
+      r = ceph_statxat(m_local_mount, fh.c_fd, npath.c_str(), &cstx,
+                       CEPH_STATX_MODE | CEPH_STATX_UID | CEPH_STATX_GID |
+                       CEPH_STATX_SIZE | CEPH_STATX_ATIME | CEPH_STATX_MTIME,
+                       AT_STATX_DONT_SYNC | AT_SYMLINK_NOFOLLOW);
       if (r < 0) {
         // can't stat, so it's a deleted entry.
         if (DT_DIR == sd_entry.dir_entry.d_type) { // is a directory
           r = cleanup_remote_dir(dir_root, npath, fh);
           if (r < 0) {
-            derr << ": failed to remove directory=" << nabs_path << dendl;
+            derr << ": failed to remove directory=" << npath << dendl;
             break;
           }
         }
@@ -1506,17 +1498,17 @@ int PeerReplayer::do_synchronize(const std::string &dir_root, const Snapshot &cu
       } else {
         // stat success, update the existing entry
         struct ceph_statx tstx;
-        int rstat_r = ceph_statx(m_remote_mount, nabs_path.c_str(), &tstx,
-                                 CEPH_STATX_MODE | CEPH_STATX_UID | CEPH_STATX_GID |
-                                 CEPH_STATX_SIZE | CEPH_STATX_ATIME | CEPH_STATX_MTIME,
-                                 AT_STATX_DONT_SYNC | AT_SYMLINK_NOFOLLOW);
+        int rstat_r = ceph_statxat(m_remote_mount, fh.r_fd_dir_root, npath.c_str(), &tstx,
+                                   CEPH_STATX_MODE | CEPH_STATX_UID | CEPH_STATX_GID |
+                                   CEPH_STATX_SIZE | CEPH_STATX_ATIME | CEPH_STATX_MTIME,
+                                   AT_STATX_DONT_SYNC | AT_SYMLINK_NOFOLLOW);
         if (S_ISDIR(cstx.stx_mode)) { // is a directory
           //cleanup if it's a file in the remotefs
           if ((0 == rstat_r) && !S_ISDIR(tstx.stx_mode)) {
             r = ceph_unlinkat(m_remote_mount, fh.r_fd_dir_root, npath.c_str(), 0);
             if (r < 0) {
               derr << ": Error in directory sync. Failed to remove file="
-                   << nabs_path << dendl;
+                   << npath << dendl;
               break;
             }
           }
@@ -1541,7 +1533,7 @@ int PeerReplayer::do_synchronize(const std::string &dir_root, const Snapshot &cu
               r = cleanup_remote_dir(dir_root, npath, fh);
               if (r < 0) {
                 derr << ": Error in file sync. Failed to remove remote directory="
-                     << nabs_path << dendl;
+                     << npath << dendl;
                 break;
               }
             }