e7a346
From 77d79754d914ce7d15d02d5fc9d9785609094850 Mon Sep 17 00:00:00 2001
e7a346
From: Kotresh HR <khiremat@redhat.com>
e7a346
Date: Thu, 7 Jun 2018 06:32:36 -0400
e7a346
Subject: [PATCH 305/305] geo-rep: Fix geo-rep for older versions of unshare
e7a346
e7a346
Geo-rep mounts are private to worker. It uses
e7a346
mount namespace using unshare command to achieve
e7a346
the same. Well, the unshare command has to support
e7a346
'--propagation' option. So geo-rep breaks on the
e7a346
systems with older unshare version. The patch
e7a346
makes it fall back to lazy umount behaviour if
e7a346
the unshare does not support propagation option.
e7a346
e7a346
Backpor of:
e7a346
  > Patch: https://review.gluster.org/20221
e7a346
  > fixes: bz#1589782
e7a346
  > Change-Id: Ia614f068aede288d63ac62fea4461b1865066054
e7a346
  > Signed-off-by: Kotresh HR <khiremat@redhat.com>
e7a346
e7a346
BUG: 1569312
e7a346
Change-Id: Ia614f068aede288d63ac62fea4461b1865066054
e7a346
Signed-off-by: Kotresh HR <khiremat@redhat.com>
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/142613
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
Reviewed-by: Aravinda Vishwanathapura Krishna Murthy <avishwan@redhat.com>
e7a346
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
---
e7a346
 geo-replication/syncdaemon/gsyncd.py     |  1 +
e7a346
 geo-replication/syncdaemon/monitor.py    | 15 +++++++++++----
e7a346
 geo-replication/syncdaemon/resource.py   | 21 ++++++++++++++++++---
e7a346
 geo-replication/syncdaemon/syncdutils.py | 18 ++++++++++++++++++
e7a346
 4 files changed, 48 insertions(+), 7 deletions(-)
e7a346
e7a346
diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py
e7a346
index b0ed0ae..fff193b 100644
e7a346
--- a/geo-replication/syncdaemon/gsyncd.py
e7a346
+++ b/geo-replication/syncdaemon/gsyncd.py
e7a346
@@ -775,6 +775,7 @@ def main_i():
e7a346
     elif remote:
e7a346
         # master
e7a346
         gconf.label = gconf.local_path
e7a346
+        gconf.worker = True
e7a346
     else:
e7a346
         gconf.label = 'slave'
e7a346
     startup(go_daemon=go_daemon, log_file=log_file, label=gconf.label)
e7a346
diff --git a/geo-replication/syncdaemon/monitor.py b/geo-replication/syncdaemon/monitor.py
e7a346
index 55f8330..9245572 100644
e7a346
--- a/geo-replication/syncdaemon/monitor.py
e7a346
+++ b/geo-replication/syncdaemon/monitor.py
e7a346
@@ -29,7 +29,7 @@ from syncdutils import gf_event, EVENT_GEOREP_FAULTY
e7a346
 from syncdutils import Volinfo, Popen
e7a346
 
e7a346
 from gsyncdstatus import GeorepStatus, set_monitor_status
e7a346
-
e7a346
+from syncdutils import unshare_propagation_supported
e7a346
 
e7a346
 ParseError = XET.ParseError if hasattr(XET, 'ParseError') else SyntaxError
e7a346
 
e7a346
@@ -247,9 +247,16 @@ class Monitor(object):
e7a346
                 if access_mount:
e7a346
                     os.execv(sys.executable, args_to_worker)
e7a346
                 else:
e7a346
-                    unshare_cmd = ['unshare', '-m', '--propagation', 'private']
e7a346
-                    cmd = unshare_cmd + args_to_worker
e7a346
-                    os.execvp("unshare", cmd)
e7a346
+                    if unshare_propagation_supported():
e7a346
+                        logging.debug("Worker would mount volume privately")
e7a346
+                        unshare_cmd = ['unshare', '-m', '--propagation',
e7a346
+                                       'private']
e7a346
+                        cmd = unshare_cmd + args_to_worker
e7a346
+                        os.execvp("unshare", cmd)
e7a346
+                    else:
e7a346
+                        logging.debug("Mount is not private. It would be lazy"
e7a346
+                                      " umounted")
e7a346
+                        os.execv(sys.executable, args_to_worker)
e7a346
 
e7a346
             cpids.add(cpid)
e7a346
             agents.add(apid)
e7a346
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
e7a346
index c4b5b53..00e62b7 100644
e7a346
--- a/geo-replication/syncdaemon/resource.py
e7a346
+++ b/geo-replication/syncdaemon/resource.py
e7a346
@@ -40,6 +40,7 @@ from gsyncdstatus import GeorepStatus
e7a346
 from syncdutils import get_master_and_slave_data_from_args
e7a346
 from syncdutils import lf, Popen, sup, Volinfo
e7a346
 from syncdutils import Xattr, matching_disk_gfid, get_gfid_from_mnt
e7a346
+from syncdutils import unshare_propagation_supported
e7a346
 
e7a346
 UrlRX = re.compile('\A(\w+)://([^ *?[]*)\Z')
e7a346
 HostRX = re.compile('[a-zA-Z\d](?:[a-zA-Z\d.-]*[a-zA-Z\d])?', re.I)
e7a346
@@ -1302,15 +1303,29 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
e7a346
                         assert(mntdata[-1] == '\0')
e7a346
                         mntpt = mntdata[:-1]
e7a346
                         assert(mntpt)
e7a346
-                        if mounted and gconf.label == 'slave' \
e7a346
+
e7a346
+                        umount_master = False
e7a346
+                        umount_slave = False
e7a346
+                        master_access_mount = getattr(gconf, 'access_mount',
e7a346
+                                                      False)
e7a346
+                        worker = getattr(gconf, 'worker', None)
e7a346
+
e7a346
+                        if worker \
e7a346
+                           and not unshare_propagation_supported() \
e7a346
+                           and not boolify(master_access_mount):
e7a346
+                            umount_master = True
e7a346
+                        if gconf.label == 'slave' \
e7a346
                            and not boolify(gconf.slave_access_mount):
e7a346
+                            umount_slave = True
e7a346
+
e7a346
+                        if mounted and (umount_master or umount_slave):
e7a346
                             po = self.umount_l(mntpt)
e7a346
                             po.terminate_geterr(fail_on_err=False)
e7a346
                             if po.returncode != 0:
e7a346
                                 po.errlog()
e7a346
                                 rv = po.returncode
e7a346
-                        if gconf.label == 'slave' \
e7a346
-                           and not boolify(gconf.slave_access_mount):
e7a346
+                            logging.debug("Lazy umount done: %s" % mntpt)
e7a346
+                        if umount_master or umount_slave:
e7a346
                             self.cleanup_mntpt(mntpt)
e7a346
                 except:
e7a346
                     logging.exception('mount cleanup failure:')
e7a346
diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py
e7a346
index a493c37..6dafb0a 100644
e7a346
--- a/geo-replication/syncdaemon/syncdutils.py
e7a346
+++ b/geo-replication/syncdaemon/syncdutils.py
e7a346
@@ -76,6 +76,7 @@ CHANGELOG_AGENT_SERVER_VERSION = 1.0
e7a346
 CHANGELOG_AGENT_CLIENT_VERSION = 1.0
e7a346
 NodeID = None
e7a346
 rsync_version = None
e7a346
+unshare_mnt_propagation = None
e7a346
 SPACE_ESCAPE_CHAR = "%20"
e7a346
 NEWLINE_ESCAPE_CHAR = "%0A"
e7a346
 PERCENTAGE_ESCAPE_CHAR = "%25"
e7a346
@@ -637,6 +638,23 @@ def get_master_and_slave_data_from_args(args):
e7a346
     return (master_name, slave_data)
e7a346
 
e7a346
 
e7a346
+def unshare_propagation_supported():
e7a346
+    global unshare_mnt_propagation
e7a346
+    if unshare_mnt_propagation is not None:
e7a346
+        return unshare_mnt_propagation
e7a346
+
e7a346
+    unshare_mnt_propagation = False
e7a346
+    p = subprocess.Popen(["unshare", "--help"],
e7a346
+                         stderr=subprocess.PIPE,
e7a346
+                         stdout=subprocess.PIPE)
e7a346
+    out, err = p.communicate()
e7a346
+    if p.returncode == 0:
e7a346
+        if "propagation" in out:
e7a346
+            unshare_mnt_propagation = True
e7a346
+
e7a346
+    return unshare_mnt_propagation
e7a346
+
e7a346
+
e7a346
 def get_rsync_version(rsync_cmd):
e7a346
     global rsync_version
e7a346
     if rsync_version is not None:
e7a346
-- 
e7a346
1.8.3.1
e7a346