|
|
d1681e |
From 9f4564e55b1e515743a1f80d18989681d5d3b59f Mon Sep 17 00:00:00 2001
|
|
|
d1681e |
From: Kotresh HR <khiremat@redhat.com>
|
|
|
d1681e |
Date: Thu, 15 Feb 2018 01:46:29 -0500
|
|
|
d1681e |
Subject: [PATCH 164/180] geo-rep: Remove lazy umount and use mount namespaces
|
|
|
d1681e |
|
|
|
d1681e |
Lazy umounting the master volume by worker causes
|
|
|
d1681e |
issues with rsync's usage of getcwd. Henc removing
|
|
|
d1681e |
the lazy umount and using private mount namespace
|
|
|
d1681e |
for the same. On the slave, the lazy umount is
|
|
|
d1681e |
retained as we can't use private namespace in non
|
|
|
d1681e |
root geo-rep setup because gsyncd is spawned as
|
|
|
d1681e |
non-privileged user.
|
|
|
d1681e |
|
|
|
d1681e |
Backport of https://review.gluster.org/#/c/19544/
|
|
|
d1681e |
|
|
|
d1681e |
Change-Id: I851e8dc2b8523dc5668a97e87ef619ab70471dfd
|
|
|
d1681e |
BUG: 1544382
|
|
|
d1681e |
Signed-off-by: Kotresh HR <khiremat@redhat.com>
|
|
|
d1681e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/130468
|
|
|
d1681e |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
d1681e |
Reviewed-by: Aravinda Vishwanathapura Krishna Murthy <avishwan@redhat.com>
|
|
|
d1681e |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
d1681e |
---
|
|
|
d1681e |
geo-replication/syncdaemon/gconf.py | 3 +++
|
|
|
d1681e |
geo-replication/syncdaemon/gsyncd.py | 13 ++++++-----
|
|
|
d1681e |
geo-replication/syncdaemon/monitor.py | 38 ++++++++++++++++++++------------
|
|
|
d1681e |
geo-replication/syncdaemon/resource.py | 20 ++++++++++++-----
|
|
|
d1681e |
geo-replication/syncdaemon/syncdutils.py | 12 +++++-----
|
|
|
d1681e |
glusterfs.spec.in | 4 ++++
|
|
|
d1681e |
6 files changed, 59 insertions(+), 31 deletions(-)
|
|
|
d1681e |
|
|
|
d1681e |
diff --git a/geo-replication/syncdaemon/gconf.py b/geo-replication/syncdaemon/gconf.py
|
|
|
d1681e |
index 97395b4..2280f44 100644
|
|
|
d1681e |
--- a/geo-replication/syncdaemon/gconf.py
|
|
|
d1681e |
+++ b/geo-replication/syncdaemon/gconf.py
|
|
|
d1681e |
@@ -28,5 +28,8 @@ class GConf(object):
|
|
|
d1681e |
active_earlier = False
|
|
|
d1681e |
passive_earlier = False
|
|
|
d1681e |
mgmt_lock_fd = None
|
|
|
d1681e |
+ mountbroker = False
|
|
|
d1681e |
+ mount_point = None
|
|
|
d1681e |
+ mbr_umount_cmd = []
|
|
|
d1681e |
|
|
|
d1681e |
gconf = GConf()
|
|
|
d1681e |
diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py
|
|
|
d1681e |
index d77b90f..629e8b7 100644
|
|
|
d1681e |
--- a/geo-replication/syncdaemon/gsyncd.py
|
|
|
d1681e |
+++ b/geo-replication/syncdaemon/gsyncd.py
|
|
|
d1681e |
@@ -276,6 +276,7 @@ def main_i():
|
|
|
d1681e |
op.add_option('--georep-session-working-dir', metavar='STATF',
|
|
|
d1681e |
type=str, action='callback', callback=store_abs)
|
|
|
d1681e |
op.add_option('--access-mount', default=False, action='store_true')
|
|
|
d1681e |
+ op.add_option('--slave-access-mount', default=False, action='store_true')
|
|
|
d1681e |
op.add_option('--ignore-deletes', default=False, action='store_true')
|
|
|
d1681e |
op.add_option('--isolated-slave', default=False, action='store_true')
|
|
|
d1681e |
op.add_option('--use-rsync-xattrs', default=False, action='store_true')
|
|
|
d1681e |
@@ -431,7 +432,7 @@ def main_i():
|
|
|
d1681e |
o.get_opt_string() not in ('--version', '--help'))]
|
|
|
d1681e |
remote_tunables = ['listen', 'go_daemon', 'timeout',
|
|
|
d1681e |
'session_owner', 'config_file', 'use_rsync_xattrs',
|
|
|
d1681e |
- 'local_id', 'local_node', 'access_mount']
|
|
|
d1681e |
+ 'local_id', 'local_node', 'slave_access_mount']
|
|
|
d1681e |
rq_remote_tunables = {'listen': True}
|
|
|
d1681e |
|
|
|
d1681e |
# precedence for sources of values: 1) commandline, 2) cfg file, 3)
|
|
|
d1681e |
@@ -768,15 +769,15 @@ def main_i():
|
|
|
d1681e |
else:
|
|
|
d1681e |
log_file = gconf.log_file
|
|
|
d1681e |
if be_monitor:
|
|
|
d1681e |
- label = 'monitor'
|
|
|
d1681e |
+ gconf.label = 'monitor'
|
|
|
d1681e |
elif be_agent:
|
|
|
d1681e |
- label = gconf.local_path
|
|
|
d1681e |
+ gconf.label = gconf.local_path
|
|
|
d1681e |
elif remote:
|
|
|
d1681e |
# master
|
|
|
d1681e |
- label = gconf.local_path
|
|
|
d1681e |
+ gconf.label = gconf.local_path
|
|
|
d1681e |
else:
|
|
|
d1681e |
- label = 'slave'
|
|
|
d1681e |
- startup(go_daemon=go_daemon, log_file=log_file, label=label)
|
|
|
d1681e |
+ gconf.label = 'slave'
|
|
|
d1681e |
+ startup(go_daemon=go_daemon, log_file=log_file, label=gconf.label)
|
|
|
d1681e |
resource.Popen.init_errhandler()
|
|
|
d1681e |
|
|
|
d1681e |
if be_agent:
|
|
|
d1681e |
diff --git a/geo-replication/syncdaemon/monitor.py b/geo-replication/syncdaemon/monitor.py
|
|
|
d1681e |
index 4da9330..0f43c4f 100644
|
|
|
d1681e |
--- a/geo-replication/syncdaemon/monitor.py
|
|
|
d1681e |
+++ b/geo-replication/syncdaemon/monitor.py
|
|
|
d1681e |
@@ -24,7 +24,7 @@ import random
|
|
|
d1681e |
from gconf import gconf
|
|
|
d1681e |
from syncdutils import select, waitpid, errno_wrap, lf
|
|
|
d1681e |
from syncdutils import set_term_handler, is_host_local, GsyncdError
|
|
|
d1681e |
-from syncdutils import escape, Thread, finalize, memoize
|
|
|
d1681e |
+from syncdutils import escape, Thread, finalize, memoize, boolify
|
|
|
d1681e |
from syncdutils import gf_event, EVENT_GEOREP_FAULTY
|
|
|
d1681e |
|
|
|
d1681e |
from gsyncdstatus import GeorepStatus, set_monitor_status
|
|
|
d1681e |
@@ -306,19 +306,29 @@ class Monitor(object):
|
|
|
d1681e |
os.close(pr)
|
|
|
d1681e |
os.close(ra)
|
|
|
d1681e |
os.close(wa)
|
|
|
d1681e |
- os.execv(sys.executable, argv + ['--feedback-fd', str(pw),
|
|
|
d1681e |
- '--local-path', w[0]['dir'],
|
|
|
d1681e |
- '--local-node', w[0]['host'],
|
|
|
d1681e |
- '--local-node-id',
|
|
|
d1681e |
- w[0]['uuid'],
|
|
|
d1681e |
- '--local-id',
|
|
|
d1681e |
- '.' + escape(w[0]['dir']),
|
|
|
d1681e |
- '--rpc-fd',
|
|
|
d1681e |
- ','.join([str(rw), str(ww),
|
|
|
d1681e |
- str(ra), str(wa)]),
|
|
|
d1681e |
- '--subvol-num', str(w[2])] +
|
|
|
d1681e |
- (['--is-hottier'] if w[3] else []) +
|
|
|
d1681e |
- ['--resource-remote', remote_host])
|
|
|
d1681e |
+ args_to_worker = argv + ['--feedback-fd', str(pw),
|
|
|
d1681e |
+ '--local-path', w[0]['dir'],
|
|
|
d1681e |
+ '--local-node', w[0]['host'],
|
|
|
d1681e |
+ '--local-node-id',
|
|
|
d1681e |
+ w[0]['uuid'],
|
|
|
d1681e |
+ '--local-id',
|
|
|
d1681e |
+ '.' + escape(w[0]['dir']),
|
|
|
d1681e |
+ '--rpc-fd',
|
|
|
d1681e |
+ ','.join([str(rw), str(ww),
|
|
|
d1681e |
+ str(ra), str(wa)]),
|
|
|
d1681e |
+ '--subvol-num', str(w[2])]
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if w[3]:
|
|
|
d1681e |
+ args_to_worker.append('--is-hottier')
|
|
|
d1681e |
+ args_to_worker += ['--resource-remote', remote_host]
|
|
|
d1681e |
+
|
|
|
d1681e |
+ access_mount = boolify(gconf.access_mount)
|
|
|
d1681e |
+ if access_mount:
|
|
|
d1681e |
+ os.execv(sys.executable, args_to_worker)
|
|
|
d1681e |
+ else:
|
|
|
d1681e |
+ unshare_cmd = ['unshare', '-m', '--propagation', 'private']
|
|
|
d1681e |
+ cmd = unshare_cmd + args_to_worker
|
|
|
d1681e |
+ os.execvp("unshare", cmd)
|
|
|
d1681e |
|
|
|
d1681e |
cpids.add(cpid)
|
|
|
d1681e |
agents.add(apid)
|
|
|
d1681e |
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
|
|
|
d1681e |
index 5ad5b97..4b2a266 100644
|
|
|
d1681e |
--- a/geo-replication/syncdaemon/resource.py
|
|
|
d1681e |
+++ b/geo-replication/syncdaemon/resource.py
|
|
|
d1681e |
@@ -43,7 +43,7 @@ from syncdutils import CHANGELOG_AGENT_CLIENT_VERSION
|
|
|
d1681e |
from syncdutils import GX_GFID_CANONICAL_LEN
|
|
|
d1681e |
from gsyncdstatus import GeorepStatus
|
|
|
d1681e |
from syncdutils import get_master_and_slave_data_from_args
|
|
|
d1681e |
-from syncdutils import mntpt_list, lf
|
|
|
d1681e |
+from syncdutils import lf
|
|
|
d1681e |
from syncdutils import Xattr, matching_disk_gfid, get_gfid_from_mnt
|
|
|
d1681e |
|
|
|
d1681e |
UrlRX = re.compile('\A(\w+)://([^ *?[]*)\Z')
|
|
|
d1681e |
@@ -1047,8 +1047,8 @@ class SlaveRemote(object):
|
|
|
d1681e |
extra_opts += ['--local-node', ln]
|
|
|
d1681e |
if boolify(gconf.use_rsync_xattrs):
|
|
|
d1681e |
extra_opts.append('--use-rsync-xattrs')
|
|
|
d1681e |
- if boolify(gconf.access_mount):
|
|
|
d1681e |
- extra_opts.append('--access-mount')
|
|
|
d1681e |
+ if boolify(gconf.slave_access_mount):
|
|
|
d1681e |
+ extra_opts.append('--slave-access-mount')
|
|
|
d1681e |
po = Popen(rargs + gconf.remote_gsyncd.split() + extra_opts +
|
|
|
d1681e |
['-N', '--listen', '--timeout', str(gconf.timeout),
|
|
|
d1681e |
slave],
|
|
|
d1681e |
@@ -1333,6 +1333,7 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
|
|
|
d1681e |
def __init__(self, params):
|
|
|
d1681e |
self.params = params
|
|
|
d1681e |
self.mntpt = None
|
|
|
d1681e |
+ self.umount_cmd = []
|
|
|
d1681e |
|
|
|
d1681e |
@classmethod
|
|
|
d1681e |
def get_glusterprog(cls):
|
|
|
d1681e |
@@ -1424,13 +1425,15 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
|
|
|
d1681e |
assert(mntdata[-1] == '\0')
|
|
|
d1681e |
mntpt = mntdata[:-1]
|
|
|
d1681e |
assert(mntpt)
|
|
|
d1681e |
- if mounted and not boolify(gconf.access_mount):
|
|
|
d1681e |
+ if mounted and gconf.label == 'slave' \
|
|
|
d1681e |
+ and not boolify(gconf.slave_access_mount):
|
|
|
d1681e |
po = self.umount_l(mntpt)
|
|
|
d1681e |
po.terminate_geterr(fail_on_err=False)
|
|
|
d1681e |
if po.returncode != 0:
|
|
|
d1681e |
po.errlog()
|
|
|
d1681e |
rv = po.returncode
|
|
|
d1681e |
- if not boolify(gconf.access_mount):
|
|
|
d1681e |
+ if gconf.label == 'slave' \
|
|
|
d1681e |
+ and not boolify(gconf.slave_access_mount):
|
|
|
d1681e |
self.cleanup_mntpt(mntpt)
|
|
|
d1681e |
except:
|
|
|
d1681e |
logging.exception('mount cleanup failure:')
|
|
|
d1681e |
@@ -1451,7 +1454,7 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
|
|
|
d1681e |
|
|
|
d1681e |
def make_mount_argv(self):
|
|
|
d1681e |
self.mntpt = tempfile.mkdtemp(prefix='gsyncd-aux-mount-')
|
|
|
d1681e |
- mntpt_list.append(self.mntpt)
|
|
|
d1681e |
+ gconf.mount_point = self.mntpt
|
|
|
d1681e |
return [self.get_glusterprog()] + \
|
|
|
d1681e |
['--' + p for p in self.params] + [self.mntpt]
|
|
|
d1681e |
|
|
|
d1681e |
@@ -1483,6 +1486,11 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
|
|
|
d1681e |
|
|
|
d1681e |
def handle_mounter(self, po):
|
|
|
d1681e |
self.mntpt = po.stdout.readline()[:-1]
|
|
|
d1681e |
+ gconf.mount_point = self.mntpt
|
|
|
d1681e |
+ gconf.mountbroker = True
|
|
|
d1681e |
+ self.umount_cmd = self.make_cli_argv() + ['umount']
|
|
|
d1681e |
+ gconf.mbr_umount_cmd = self.umount_cmd
|
|
|
d1681e |
+
|
|
|
d1681e |
po.stdout.close()
|
|
|
d1681e |
sup(self, po)
|
|
|
d1681e |
if po.returncode != 0:
|
|
|
d1681e |
diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py
|
|
|
d1681e |
index 269f301..2b57f83 100644
|
|
|
d1681e |
--- a/geo-replication/syncdaemon/syncdutils.py
|
|
|
d1681e |
+++ b/geo-replication/syncdaemon/syncdutils.py
|
|
|
d1681e |
@@ -23,7 +23,6 @@ from errno import EINTR, ENOENT, EPERM, ESTALE, EBUSY, errorcode
|
|
|
d1681e |
from signal import signal, SIGTERM
|
|
|
d1681e |
import select as oselect
|
|
|
d1681e |
from os import waitpid as owaitpid
|
|
|
d1681e |
-import subprocess
|
|
|
d1681e |
|
|
|
d1681e |
from conf import GLUSTERFS_LIBEXECDIR, UUID_FILE
|
|
|
d1681e |
sys.path.insert(1, GLUSTERFS_LIBEXECDIR)
|
|
|
d1681e |
@@ -209,7 +208,6 @@ def grabpidfile(fname=None, setpid=True):
|
|
|
d1681e |
|
|
|
d1681e |
final_lock = Lock()
|
|
|
d1681e |
|
|
|
d1681e |
-mntpt_list = []
|
|
|
d1681e |
def finalize(*a, **kw):
|
|
|
d1681e |
"""all those messy final steps we go trough upon termination
|
|
|
d1681e |
|
|
|
d1681e |
@@ -256,12 +254,16 @@ def finalize(*a, **kw):
|
|
|
d1681e |
pass
|
|
|
d1681e |
|
|
|
d1681e |
""" Unmount if not done """
|
|
|
d1681e |
- for mnt in mntpt_list:
|
|
|
d1681e |
- p0 = subprocess.Popen (["umount", "-l", mnt], stderr=subprocess.PIPE)
|
|
|
d1681e |
+ if gconf.mount_point:
|
|
|
d1681e |
+ if gconf.mountbroker:
|
|
|
d1681e |
+ umount_cmd = gconf.mbr_umount_cmd + [gconf.mount_point, 'lazy']
|
|
|
d1681e |
+ else:
|
|
|
d1681e |
+ umount_cmd = ['umount', '-l', gconf.mount_point]
|
|
|
d1681e |
+ p0 = subprocess.Popen(umount_cmd, stderr=subprocess.PIPE)
|
|
|
d1681e |
_, errdata = p0.communicate()
|
|
|
d1681e |
if p0.returncode == 0:
|
|
|
d1681e |
try:
|
|
|
d1681e |
- os.rmdir(mnt)
|
|
|
d1681e |
+ os.rmdir(gconf.mount_point)
|
|
|
d1681e |
except OSError:
|
|
|
d1681e |
pass
|
|
|
d1681e |
else:
|
|
|
d1681e |
diff --git a/glusterfs.spec.in b/glusterfs.spec.in
|
|
|
d1681e |
index 3181d72..8379f64 100644
|
|
|
d1681e |
--- a/glusterfs.spec.in
|
|
|
d1681e |
+++ b/glusterfs.spec.in
|
|
|
d1681e |
@@ -453,6 +453,7 @@ BuildRequires: python-ctypes
|
|
|
d1681e |
%endif
|
|
|
d1681e |
Requires: python2-gluster = %{version}-%{release}
|
|
|
d1681e |
Requires: rsync
|
|
|
d1681e |
+Requires: util-linux
|
|
|
d1681e |
|
|
|
d1681e |
%description geo-replication
|
|
|
d1681e |
GlusterFS is a distributed file-system capable of scaling to several
|
|
|
d1681e |
@@ -2147,6 +2148,9 @@ fi
|
|
|
d1681e |
%endif
|
|
|
d1681e |
|
|
|
d1681e |
%changelog
|
|
|
d1681e |
+* Thu Feb 22 2018 Kotresh HR <khiremat@redhat.com>
|
|
|
d1681e |
+- Added util-linux as dependency to georeplication rpm (#1544382)
|
|
|
d1681e |
+
|
|
|
d1681e |
* Wed Jan 17 2018 Milind Changire <mchangir@redhat.com>
|
|
|
d1681e |
- DOWNSTREAM ONLY - Removed pretrans script for glusterfs-ganesha - (#1410719)
|
|
|
d1681e |
|
|
|
d1681e |
--
|
|
|
d1681e |
1.8.3.1
|
|
|
d1681e |
|