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