887953
From 85da98b9c54889139822b5c3d351a0249abf75b0 Mon Sep 17 00:00:00 2001
887953
From: Kotresh HR <khiremat@redhat.com>
887953
Date: Fri, 26 Oct 2018 03:45:46 -0400
887953
Subject: [PATCH 437/444] geo-rep: Add more intelligence to automatic error
887953
 handling
887953
887953
Geo-rep's automatic error handling does gfid conflict
887953
resolution. But if there are ENOENT errors because the
887953
parent is not synced to slave, it doesn' handle them.
887953
This patch adds the intelligence to create missing
887953
parent directories on slave. It can create the missing
887953
directories upto the depth of 10.
887953
887953
Backport of:
887953
 > Patch: https://review.gluster.org/21498
887953
 > fixes: bz#1643402
887953
 > Change-Id: Ic97ed1fa5899c087e404d559e04f7963ed7bb54c
887953
 > Signed-off-by: Kotresh HR <khiremat@redhat.com>
887953
887953
BUG: 1638069
887953
Change-Id: Ic97ed1fa5899c087e404d559e04f7963ed7bb54c
887953
Signed-off-by: Kotresh HR <khiremat@redhat.com>
887953
Reviewed-on: https://code.engineering.redhat.com/gerrit/155039
887953
Tested-by: RHGS Build Bot <nigelb@redhat.com>
887953
Reviewed-by: Aravinda Vishwanathapura Krishna Murthy <avishwan@redhat.com>
887953
Reviewed-by: Sunny Kumar <sunkumar@redhat.com>
887953
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
887953
---
887953
 geo-replication/syncdaemon/master.py | 68 ++++++++++++++++++++++++------------
887953
 1 file changed, 46 insertions(+), 22 deletions(-)
887953
887953
diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py
887953
index cd135df..bdb4da2 100644
887953
--- a/geo-replication/syncdaemon/master.py
887953
+++ b/geo-replication/syncdaemon/master.py
887953
@@ -693,7 +693,7 @@ class GMasterChangelogMixin(GMasterCommon):
887953
     TYPE_ENTRY = "E "
887953
 
887953
     MAX_EF_RETRIES = 10
887953
-    MAX_OE_RETRIES = 5
887953
+    MAX_OE_RETRIES = 10
887953
 
887953
     # flat directory hierarchy for gfid based access
887953
     FLAT_DIR_HIERARCHY = '.'
887953
@@ -836,11 +836,12 @@ class GMasterChangelogMixin(GMasterCommon):
887953
                     # The file exists on master but with different name.
887953
                     # Probably renamed and got missed during xsync crawl.
887953
                     elif failure[2]['slave_isdir']:
887953
-                        realpath = os.readlink(os.path.join(gconf.local_path,
887953
-                                                            ".glusterfs",
887953
-                                                            slave_gfid[0:2],
887953
-                                                            slave_gfid[2:4],
887953
-                                                            slave_gfid))
887953
+                        realpath = os.readlink(os.path.join(
887953
+                                               gconf.local_path,
887953
+                                               ".glusterfs",
887953
+                                               slave_gfid[0:2],
887953
+                                               slave_gfid[2:4],
887953
+                                               slave_gfid))
887953
                         dst_entry = os.path.join(pfx, realpath.split('/')[-2],
887953
                                                  realpath.split('/')[-1])
887953
                         src_entry = pbname
887953
@@ -881,25 +882,37 @@ class GMasterChangelogMixin(GMasterCommon):
887953
                                  gfid=failure[2]['slave_gfid'],
887953
                                  entry=pbname))
887953
             elif failure[1] == ENOENT:
887953
-                # Ignore ENOENT error for fix_entry_ops aka retry_count > 1
887953
-                if retry_count > 1:
887953
-                    logging.info(lf('ENOENT error while fixing entry ops. '
887953
-                                    'Safe to ignore, take out entry',
887953
+                if op in ['RENAME']:
887953
+                    pbname = failure[0]['entry1']
887953
+                else:
887953
+                    pbname = failure[0]['entry']
887953
+
887953
+                pargfid = pbname.split('/')[1]
887953
+                st = lstat(os.path.join(pfx, pargfid))
887953
+                # Safe to ignore the failure as master doesn't contain
887953
+                # parent directory.
887953
+                if isinstance(st, int):
887953
+                    logging.info(lf('Fixing ENOENT error in slave. Parent '
887953
+                                    'does not exist on master. Safe to '
887953
+                                    'ignore, take out entry',
887953
                                     retry_count=retry_count,
887953
                                     entry=repr(failure)))
887953
                     entries.remove(failure[0])
887953
-                elif op in ('MKNOD', 'CREATE', 'MKDIR'):
887953
-                    pargfid = pbname.split('/')[1]
887953
-                    st = lstat(os.path.join(pfx, pargfid))
887953
-                    # Safe to ignore the failure as master doesn't contain
887953
-                    # parent directory.
887953
-                    if isinstance(st, int):
887953
-                        logging.info(lf('Fixing ENOENT error in slave. Parent '
887953
-                                        'does not exist on master. Safe to '
887953
-                                        'ignore, take out entry',
887953
-                                        retry_count=retry_count,
887953
-                                        entry=repr(failure)))
887953
-                        entries.remove(failure[0])
887953
+                else:
887953
+                    logging.info(lf('Fixing ENOENT error in slave. Create '
887953
+                                    'parent directory on slave.',
887953
+                                    retry_count=retry_count,
887953
+                                    entry=repr(failure)))
887953
+                    realpath = os.readlink(os.path.join(gconf.local_path,
887953
+                                                        ".glusterfs",
887953
+                                                        pargfid[0:2],
887953
+                                                        pargfid[2:4],
887953
+                                                        pargfid))
887953
+                    dir_entry = os.path.join(pfx, realpath.split('/')[-2],
887953
+                                             realpath.split('/')[-1])
887953
+                    fix_entry_ops.append(
887953
+                        edct('MKDIR', gfid=pargfid, entry=dir_entry,
887953
+                             mode=st.st_mode, uid=st.st_uid, gid=st.st_gid))
887953
 
887953
         if fix_entry_ops:
887953
             # Process deletions of entries whose gfids are mismatched
887953
@@ -1077,6 +1090,11 @@ class GMasterChangelogMixin(GMasterCommon):
887953
                         os.path.join(pfx, ec[self.POS_ENTRY1 - 1]))
887953
                     entries.append(edct(ty, gfid=gfid, entry=e1, entry1=en,
887953
                                         stat=st, link=rl))
887953
+                    # If src doesn't exist while doing rename, destination
887953
+                    # is created. If data is not followed by rename, this
887953
+                    # remains zero byte file on slave. Hence add data entry
887953
+                    # for renames
887953
+                    datas.add(os.path.join(pfx, gfid))
887953
                 else:
887953
                     # stat() to get mode and other information
887953
                     if not matching_disk_gfid(gfid, en):
887953
@@ -1100,6 +1118,12 @@ class GMasterChangelogMixin(GMasterCommon):
887953
                                 rl = None
887953
                         entries.append(edct(ty, stat=st, entry=en, gfid=gfid,
887953
                                        link=rl))
887953
+                        # If src doesn't exist while doing link, destination
887953
+                        # is created based on file type. If data is not
887953
+                        # followed by link, this remains zero byte file on
887953
+                        # slave. Hence add data entry for links
887953
+                        if rl is None:
887953
+                            datas.add(os.path.join(pfx, gfid))
887953
                     elif ty == 'SYMLINK':
887953
                         rl = errno_wrap(os.readlink, [en], [ENOENT],
887953
                                         [ESTALE, EINTR])
887953
-- 
887953
1.8.3.1
887953