887953
From f42b8789cdcd93cb9fa93f35ed067268ce75f789 Mon Sep 17 00:00:00 2001
887953
From: Kotresh HR <khiremat@redhat.com>
887953
Date: Thu, 25 Oct 2018 03:23:56 -0400
887953
Subject: [PATCH 436/444] geo-rep: Fix issue in gfid-conflict-resolution
887953
887953
Problem:
887953
During gfid-conflict-resolution, geo-rep crashes
887953
with 'ValueError: list.remove(x): x not in list'
887953
887953
Cause and Analysis:
887953
During gfid-conflict-resolution, the entry blob is
887953
passed back to master along with additional
887953
information to verify it's integrity. If everything
887953
looks fine, the entry creation is ignored and is
887953
deleted from the original list.  But it is crashing
887953
during removal of entry from the list saying entry
887953
not in list. The reason is that the stat information
887953
in the entry blob was modified and sent back to
887953
master if present.
887953
887953
Fix:
887953
Send back the correct stat information for
887953
gfid-conflict-resolution.
887953
887953
Backport of:
887953
 > Patch: https://review.gluster.org/21483
887953
 > fixes: bz#1642865
887953
 > Change-Id: I47a6aa60b2a495465aa9314eebcb4085f0b1c4fd
887953
 > Signed-off-by: Kotresh HR <khiremat@redhat.com>
887953
887953
BUG: 1640347
887953
Change-Id: I47a6aa60b2a495465aa9314eebcb4085f0b1c4fd
887953
Signed-off-by: Kotresh HR <khiremat@redhat.com>
887953
Reviewed-on: https://code.engineering.redhat.com/gerrit/155038
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/resource.py | 42 +++++++++++++++++++---------------
887953
 1 file changed, 24 insertions(+), 18 deletions(-)
887953
887953
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
887953
index b289b3b..f16066e 100644
887953
--- a/geo-replication/syncdaemon/resource.py
887953
+++ b/geo-replication/syncdaemon/resource.py
887953
@@ -456,7 +456,7 @@ class Server(object):
887953
                                st['uid'], st['gid'],
887953
                                gf, st['mode'], bn, lnk)
887953
 
887953
-        def entry_purge(op, entry, gfid, e):
887953
+        def entry_purge(op, entry, gfid, e, uid, gid):
887953
             # This is an extremely racy code and needs to be fixed ASAP.
887953
             # The GFID check here is to be sure that the pargfid/bname
887953
             # to be purged is the GFID gotten from the changelog.
887953
@@ -470,7 +470,7 @@ class Server(object):
887953
                 return
887953
 
887953
             if not matching_disk_gfid(gfid, entry):
887953
-                collect_failure(e, EEXIST)
887953
+                collect_failure(e, EEXIST, uid, gid)
887953
                 return
887953
 
887953
             if op == 'UNLINK':
887953
@@ -486,7 +486,7 @@ class Server(object):
887953
                 if er == ENOTEMPTY:
887953
                     return er
887953
 
887953
-        def collect_failure(e, cmd_ret, dst=False):
887953
+        def collect_failure(e, cmd_ret, uid, gid, dst=False):
887953
             slv_entry_info = {}
887953
             slv_entry_info['gfid_mismatch'] = False
887953
             slv_entry_info['name_mismatch'] = False
887953
@@ -499,6 +499,11 @@ class Server(object):
887953
             if cmd_ret is None:
887953
                 return False
887953
 
887953
+            if e.get("stat", {}):
887953
+                # Copy actual UID/GID value back to entry stat
887953
+                e['stat']['uid'] = uid
887953
+                e['stat']['gid'] = gid
887953
+
887953
             if cmd_ret == EEXIST:
887953
                 if dst:
887953
                     en = e['entry1']
887953
@@ -559,7 +564,7 @@ class Server(object):
887953
 
887953
             errno_wrap(os.rmdir, [path], [ENOENT, ESTALE], [EBUSY])
887953
 
887953
-        def rename_with_disk_gfid_confirmation(gfid, entry, en):
887953
+        def rename_with_disk_gfid_confirmation(gfid, entry, en, uid, gid):
887953
             if not matching_disk_gfid(gfid, entry):
887953
                 logging.error(lf("RENAME ignored: source entry does not match "
887953
                                  "with on-disk gfid",
887953
@@ -567,14 +572,13 @@ class Server(object):
887953
                                  gfid=gfid,
887953
                                  disk_gfid=get_gfid_from_mnt(entry),
887953
                                  target=en))
887953
-                collect_failure(e, EEXIST)
887953
+                collect_failure(e, EEXIST, uid, gid)
887953
                 return
887953
 
887953
             cmd_ret = errno_wrap(os.rename,
887953
                                  [entry, en],
887953
                                  [ENOENT, EEXIST], [ESTALE, EBUSY])
887953
-            collect_failure(e, cmd_ret)
887953
-
887953
+            collect_failure(e, cmd_ret, uid, gid)
887953
 
887953
         for e in entries:
887953
             blob = None
887953
@@ -595,7 +599,7 @@ class Server(object):
887953
             if op in ['RMDIR', 'UNLINK']:
887953
                 # Try once, if rmdir failed with ENOTEMPTY
887953
                 # then delete recursively.
887953
-                er = entry_purge(op, entry, gfid, e)
887953
+                er = entry_purge(op, entry, gfid, e, uid, gid)
887953
                 if isinstance(er, int):
887953
                     if er == ENOTEMPTY and op == 'RMDIR':
887953
                         # Retry if ENOTEMPTY, ESTALE
887953
@@ -632,7 +636,7 @@ class Server(object):
887953
                     cmd_ret = errno_wrap(os.link,
887953
                                          [slink, entry],
887953
                                          [ENOENT, EEXIST], [ESTALE])
887953
-                    collect_failure(e, cmd_ret)
887953
+                    collect_failure(e, cmd_ret, uid, gid)
887953
             elif op == 'MKDIR':
887953
                 en = e['entry']
887953
                 slink = os.path.join(pfx, gfid)
887953
@@ -676,7 +680,7 @@ class Server(object):
887953
                     cmd_ret = errno_wrap(os.link,
887953
                                          [slink, entry],
887953
                                          [ENOENT, EEXIST], [ESTALE])
887953
-                    collect_failure(e, cmd_ret)
887953
+                    collect_failure(e, cmd_ret, uid, gid)
887953
             elif op == 'SYMLINK':
887953
                 en = e['entry']
887953
                 st = lstat(entry)
887953
@@ -684,7 +688,7 @@ class Server(object):
887953
                     blob = entry_pack_symlink(gfid, bname, e['link'],
887953
                                               e['stat'])
887953
                 elif not matching_disk_gfid(gfid, en):
887953
-                    collect_failure(e, EEXIST)
887953
+                    collect_failure(e, EEXIST, uid, gid)
887953
             elif op == 'RENAME':
887953
                 en = e['entry1']
887953
                 # The matching disk gfid check validates two things
887953
@@ -704,7 +708,7 @@ class Server(object):
887953
                                 blob = entry_pack_symlink(gfid, bname,
887953
                                                           e['link'], e['stat'])
887953
                             elif not matching_disk_gfid(gfid, en):
887953
-                                collect_failure(e, EEXIST, True)
887953
+                                collect_failure(e, EEXIST, uid, gid, True)
887953
                         else:
887953
                             slink = os.path.join(pfx, gfid)
887953
                             st = lstat(slink)
887953
@@ -716,12 +720,13 @@ class Server(object):
887953
                             else:
887953
                                 cmd_ret = errno_wrap(os.link, [slink, en],
887953
                                                     [ENOENT, EEXIST], [ESTALE])
887953
-                                collect_failure(e, cmd_ret)
887953
+                                collect_failure(e, cmd_ret, uid, gid)
887953
                 else:
887953
                     st = lstat(entry)
887953
                     st1 = lstat(en)
887953
                     if isinstance(st1, int):
887953
-                        rename_with_disk_gfid_confirmation(gfid, entry, en)
887953
+                        rename_with_disk_gfid_confirmation(gfid, entry, en,
887953
+                                                           uid, gid)
887953
                     else:
887953
                         if st.st_ino == st1.st_ino:
887953
                             # we have a hard link, we can now unlink source
887953
@@ -746,15 +751,16 @@ class Server(object):
887953
                                 else:
887953
                                     raise
887953
                         elif not matching_disk_gfid(gfid, en):
887953
-                            collect_failure(e, EEXIST, True)
887953
+                            collect_failure(e, EEXIST, uid, gid, True)
887953
                         else:
887953
-                            rename_with_disk_gfid_confirmation(gfid, entry, en)
887953
+                            rename_with_disk_gfid_confirmation(gfid, entry, en,
887953
+                                                               uid, gid)
887953
             if blob:
887953
                 cmd_ret = errno_wrap(Xattr.lsetxattr,
887953
                                      [pg, 'glusterfs.gfid.newfile', blob],
887953
                                      [EEXIST, ENOENT],
887953
                                      [ESTALE, EINVAL, EBUSY])
887953
-                failed = collect_failure(e, cmd_ret)
887953
+                collect_failure(e, cmd_ret, uid, gid)
887953
 
887953
                 # If UID/GID is different than zero that means we are trying
887953
                 # create Entry with different UID/GID. Create Entry with
887953
@@ -763,7 +769,7 @@ class Server(object):
887953
                     path = os.path.join(pfx, gfid)
887953
                     cmd_ret = errno_wrap(os.lchown, [path, uid, gid], [ENOENT],
887953
                                          [ESTALE, EINVAL])
887953
-                    collect_failure(e, cmd_ret)
887953
+                    collect_failure(e, cmd_ret, uid, gid)
887953
 
887953
         return failures
887953
 
887953
-- 
887953
1.8.3.1
887953