Blob Blame History Raw
From 370ed7bc3ee003bbc0cc88af7e470e170370e255 Mon Sep 17 00:00:00 2001
From: Milind Changire <mchangir@redhat.com>
Date: Wed, 30 May 2018 14:49:17 +0530
Subject: [PATCH 661/675] Revert "Revert "geo-rep: Remove lazy umount and use
 mount namespaces""

This reverts commit 367d7f814114df2be19b743409d998d73aa893c0.

BUG: 1556680
Change-Id: I2cb350b399576836a9ad3e046c794ae014167c7a
Signed-off-by: Milind Changire <mchangir@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/140230
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 geo-replication/syncdaemon/gconf.py      |  3 +++
 geo-replication/syncdaemon/gsyncd.py     | 14 +++++++-----
 geo-replication/syncdaemon/monitor.py    | 38 ++++++++++++++++++++------------
 geo-replication/syncdaemon/resource.py   | 16 ++++++++++++--
 geo-replication/syncdaemon/syncdutils.py | 18 ++++++++++++++-
 glusterfs.spec.in                        |  4 ++++
 6 files changed, 70 insertions(+), 23 deletions(-)

diff --git a/geo-replication/syncdaemon/gconf.py b/geo-replication/syncdaemon/gconf.py
index 97395b4..2280f44 100644
--- a/geo-replication/syncdaemon/gconf.py
+++ b/geo-replication/syncdaemon/gconf.py
@@ -28,5 +28,8 @@ class GConf(object):
     active_earlier = False
     passive_earlier = False
     mgmt_lock_fd = None
+    mountbroker = False
+    mount_point = None
+    mbr_umount_cmd = []
 
 gconf = GConf()
diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py
index f9471e4..96256cf 100644
--- a/geo-replication/syncdaemon/gsyncd.py
+++ b/geo-replication/syncdaemon/gsyncd.py
@@ -269,6 +269,8 @@ def main_i():
                   type=str, action='callback', callback=store_abs)
     op.add_option('--georep-session-working-dir', metavar='STATF',
                   type=str, action='callback', callback=store_abs)
+    op.add_option('--access-mount', default=False, action='store_true')
+    op.add_option('--slave-access-mount', default=False, action='store_true')
     op.add_option('--ignore-deletes', default=False, action='store_true')
     op.add_option('--isolated-slave', default=False, action='store_true')
     op.add_option('--use-rsync-xattrs', default=False, action='store_true')
@@ -414,7 +416,7 @@ def main_i():
                     o.get_opt_string() not in ('--version', '--help'))]
     remote_tunables = ['listen', 'go_daemon', 'timeout',
                        'session_owner', 'config_file', 'use_rsync_xattrs',
-                       'local_id', 'local_node']
+                       'local_id', 'local_node', 'slave_access_mount']
     rq_remote_tunables = {'listen': True}
 
     # precedence for sources of values: 1) commandline, 2) cfg file, 3)
@@ -748,15 +750,15 @@ def main_i():
     else:
         log_file = gconf.log_file
     if be_monitor:
-        label = 'monitor'
+        gconf.label = 'monitor'
     elif be_agent:
-        label = gconf.local_path
+        gconf.label = gconf.local_path
     elif remote:
         # master
-        label = gconf.local_path
+        gconf.label = gconf.local_path
     else:
-        label = 'slave'
-    startup(go_daemon=go_daemon, log_file=log_file, label=label)
+        gconf.label = 'slave'
+    startup(go_daemon=go_daemon, log_file=log_file, label=gconf.label)
     resource.Popen.init_errhandler()
 
     if be_agent:
diff --git a/geo-replication/syncdaemon/monitor.py b/geo-replication/syncdaemon/monitor.py
index dc0211e..087a202 100644
--- a/geo-replication/syncdaemon/monitor.py
+++ b/geo-replication/syncdaemon/monitor.py
@@ -24,7 +24,7 @@ import random
 from gconf import gconf
 from syncdutils import select, waitpid, errno_wrap
 from syncdutils import set_term_handler, is_host_local, GsyncdError
-from syncdutils import escape, Thread, finalize, memoize
+from syncdutils import escape, Thread, finalize, memoize, boolify
 from syncdutils import gf_event, EVENT_GEOREP_FAULTY
 
 from gsyncdstatus import GeorepStatus, set_monitor_status
@@ -301,19 +301,29 @@ class Monitor(object):
                 os.close(pr)
                 os.close(ra)
                 os.close(wa)
-                os.execv(sys.executable, argv + ['--feedback-fd', str(pw),
-                                                 '--local-path', w[0]['dir'],
-                                                 '--local-node', w[0]['host'],
-                                                 '--local-node-id',
-                                                 w[0]['uuid'],
-                                                 '--local-id',
-                                                 '.' + escape(w[0]['dir']),
-                                                 '--rpc-fd',
-                                                 ','.join([str(rw), str(ww),
-                                                           str(ra), str(wa)]),
-                                                 '--subvol-num', str(w[2])] +
-                         (['--is-hottier'] if w[3] else []) +
-                         ['--resource-remote', remote_host])
+                args_to_worker = argv + ['--feedback-fd', str(pw),
+                                         '--local-path', w[0]['dir'],
+                                         '--local-node', w[0]['host'],
+                                         '--local-node-id',
+                                         w[0]['uuid'],
+                                         '--local-id',
+                                         '.' + escape(w[0]['dir']),
+                                         '--rpc-fd',
+                                         ','.join([str(rw), str(ww),
+                                         str(ra), str(wa)]),
+                                         '--subvol-num', str(w[2])]
+
+                if w[3]:
+                    args_to_worker.append('--is-hottier')
+                args_to_worker += ['--resource-remote', remote_host]
+
+                access_mount = boolify(gconf.access_mount)
+                if access_mount:
+                    os.execv(sys.executable, args_to_worker)
+                else:
+                    unshare_cmd = ['unshare', '-m', '--propagation', 'private']
+                    cmd = unshare_cmd + args_to_worker
+                    os.execvp("unshare", cmd)
 
             cpids.add(cpid)
             agents.add(apid)
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
index 943e3ec..39d537b 100644
--- a/geo-replication/syncdaemon/resource.py
+++ b/geo-replication/syncdaemon/resource.py
@@ -989,6 +989,8 @@ class SlaveRemote(object):
             extra_opts += ['--local-node', ln]
         if boolify(gconf.use_rsync_xattrs):
             extra_opts.append('--use-rsync-xattrs')
+        if boolify(gconf.slave_access_mount):
+            extra_opts.append('--slave-access-mount')
         po = Popen(rargs + gconf.remote_gsyncd.split() + extra_opts +
                    ['-N', '--listen', '--timeout', str(gconf.timeout),
                     slave],
@@ -1258,6 +1260,7 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
         def __init__(self, params):
             self.params = params
             self.mntpt = None
+            self.umount_cmd = []
 
         @classmethod
         def get_glusterprog(cls):
@@ -1348,13 +1351,16 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
                         assert(mntdata[-1] == '\0')
                         mntpt = mntdata[:-1]
                         assert(mntpt)
-                        if mounted:
+                        if mounted and gconf.label == 'slave' \
+                           and not boolify(gconf.slave_access_mount):
                             po = self.umount_l(mntpt)
                             po.terminate_geterr(fail_on_err=False)
                             if po.returncode != 0:
                                 po.errlog()
                                 rv = po.returncode
-                        self.cleanup_mntpt(mntpt)
+                        if gconf.label == 'slave' \
+                           and not boolify(gconf.slave_access_mount):
+                            self.cleanup_mntpt(mntpt)
                 except:
                     logging.exception('mount cleanup failure:')
                     rv = 200
@@ -1374,6 +1380,7 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
 
         def make_mount_argv(self):
             self.mntpt = tempfile.mkdtemp(prefix='gsyncd-aux-mount-')
+            gconf.mount_point = self.mntpt
             return [self.get_glusterprog()] + \
                 ['--' + p for p in self.params] + [self.mntpt]
 
@@ -1405,6 +1412,11 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
 
         def handle_mounter(self, po):
             self.mntpt = po.stdout.readline()[:-1]
+            gconf.mount_point = self.mntpt
+            gconf.mountbroker = True
+            self.umount_cmd = self.make_cli_argv() + ['umount']
+            gconf.mbr_umount_cmd = self.umount_cmd
+
             po.stdout.close()
             sup(self, po)
             if po.returncode != 0:
diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py
index a22289e..8dc6c96 100644
--- a/geo-replication/syncdaemon/syncdutils.py
+++ b/geo-replication/syncdaemon/syncdutils.py
@@ -16,6 +16,7 @@ import fcntl
 import shutil
 import logging
 import socket
+import subprocess
 from threading import Lock, Thread as baseThread
 from errno import EACCES, EAGAIN, EPIPE, ENOTCONN, ECONNABORTED
 from errno import EINTR, ENOENT, EPERM, ESTALE, EBUSY, errorcode
@@ -188,7 +189,6 @@ def grabpidfile(fname=None, setpid=True):
 
 final_lock = Lock()
 
-
 def finalize(*a, **kw):
     """all those messy final steps we go trough upon termination
 
@@ -233,6 +233,22 @@ def finalize(*a, **kw):
             if sys.exc_info()[0] == OSError:
                 pass
 
+    """ Unmount if not done """
+    if gconf.mount_point:
+        if gconf.mountbroker:
+            umount_cmd = gconf.mbr_umount_cmd + [gconf.mount_point, 'lazy']
+        else:
+            umount_cmd = ['umount', '-l', gconf.mount_point]
+        p0 = subprocess.Popen(umount_cmd, stderr=subprocess.PIPE)
+        _, errdata = p0.communicate()
+        if p0.returncode == 0:
+            try:
+                os.rmdir(gconf.mount_point)
+            except OSError:
+                pass
+        else:
+            pass
+
     if gconf.log_exit:
         logging.info("exiting.")
     sys.stdout.flush()
diff --git a/glusterfs.spec.in b/glusterfs.spec.in
index fc9125b..d1aa3ea 100644
--- a/glusterfs.spec.in
+++ b/glusterfs.spec.in
@@ -439,6 +439,7 @@ Requires:         %{name}%{?_isa} = %{version}-%{release}
 Requires:         %{name}-server%{?_isa} = %{version}-%{release}
 Requires:         python python-ctypes
 Requires:         rsync
+Requires:         util-linux
 
 %description geo-replication
 GlusterFS is a distributed file-system capable of scaling to several
@@ -2067,6 +2068,9 @@ fi
 %endif
 
 %changelog
+* Thu Mar 22 2018 Kotresh HR <khiremat@redhat.com>
+- Added util-linux as dependency to georeplication rpm (#1544382)
+
 * Wed Dec 20 2017 Milind Changire <mchangir@redhat.com>
 - Remove ExclusiveArch directive to help building on non-x86_64 arches (#1527772)
 
-- 
1.8.3.1