diff options
author | Saravanakumar Arumugam <sarumuga@redhat.com> | 2015-12-29 19:22:36 +0530 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2016-05-23 01:13:58 -0700 |
commit | 9ace7ecc2a278ac06dd5a0744be9a85679d8ceca (patch) | |
tree | b226bc35015974f3b5bf3f1f79ddcb246af8384b /geo-replication | |
parent | 69fccb84bc2d84bb3b3fce32836e1aea805605a9 (diff) |
glusterd/geo-rep: slave volume uuid to identify a geo-rep session
Problem:
Currently, it is possible to create multiple geo-rep session from
the Master host to Slave host(s), where Slave host(s) belonging
to the same volume.
For example:
Consider Master Host M1 having volume tv1 and Slave volume tv2,
which spans across two Slave hosts S1 and S2.
Currently, it is possible to create geo-rep session from
M1(tv1) to S1(tv2) as well as from M1(tv1) to S2(tv2).
When the Slave Host is alone modified, it is identified as a new geo-rep
session (as slave host and slave volume together are identifying
Slave side).
Also, it is possible to create both root and non-root geo-rep session between
same Master volume and Slave volume. This should also be avoided.
Solution:
This multiple geo-rep session creation must be avoided and
in order to avoid, use Slave volume uuid to identify a Slave.
This way, we can identify whether a session is already created for
the same Slave volume and avoid creating again (using different host).
When the session creation is forced in the above scenario, rename
the existing geo-rep session directory with new Slave Host mentioned.
Change-Id: I9239759cbc0d15dad63c48b8cf62950bb687c7c8
BUG: 1336704
Signed-off-by: Saravanakumar Arumugam <sarumuga@redhat.com>
Signed-off-by: Aravinda VK <avishwan@redhat.com>
Reviewed-on: http://review.gluster.org/13111
Reviewed-by: Kotresh HR <khiremat@redhat.com>
Tested-by: Kotresh HR <khiremat@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
(cherry picked from commit a9128cda34b1f696b717ba09fa0ac5a929be8969)
Reviewed-on: http://review.gluster.org/14372
Diffstat (limited to 'geo-replication')
-rw-r--r-- | geo-replication/syncdaemon/configinterface.py.in | 12 | ||||
-rw-r--r-- | geo-replication/syncdaemon/gsyncd.py | 45 |
2 files changed, 57 insertions, 0 deletions
diff --git a/geo-replication/syncdaemon/configinterface.py.in b/geo-replication/syncdaemon/configinterface.py.in index f8df49935f1..0570061955f 100644 --- a/geo-replication/syncdaemon/configinterface.py.in +++ b/geo-replication/syncdaemon/configinterface.py.in @@ -64,6 +64,18 @@ CONFIGS = ( "ignore_deletes", "true", "false"), + ("peersrx . .", + "pid-file", + "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" + "${slavevol}/${eSlave}.pid", + "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" + "${slavevol}/monitor.pid"), + ("peersrx . .", + "state-file", + "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" + "${slavevol}/${eSlave}.status", + "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" + "${slavevol}/monitor.status"), ) diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py index fdb5348d363..1667e97b245 100644 --- a/geo-replication/syncdaemon/gsyncd.py +++ b/geo-replication/syncdaemon/gsyncd.py @@ -32,9 +32,14 @@ from syncdutils import GsyncdError, select, set_term_handler from configinterface import GConffile, upgrade_config_file import resource from monitor import monitor +import xml.etree.ElementTree as XET +from subprocess import PIPE +import subprocess from changelogagent import agent, Changelog from gsyncdstatus import set_monitor_status, GeorepStatus +ParseError = XET.ParseError if hasattr(XET, 'ParseError') else SyntaxError + class GLogger(Logger): @@ -112,6 +117,36 @@ class GLogger(Logger): gconf.log_exit = True +# Given slave host and its volume name, get corresponding volume uuid +def slave_vol_uuid_get(host, vol): + po = subprocess.Popen(['gluster', '--xml', '--remote-host=' + host, + 'volume', 'info', vol], bufsize=0, + stdin=None, stdout=PIPE, stderr=PIPE) + vix, err = po.communicate() + if po.returncode != 0: + logging.info("Volume info failed, unable to get " + "volume uuid of %s present in %s," + "returning empty string: %s" % + (vol, host, po.returncode)) + return "" + vi = XET.fromstring(vix) + if vi.find('opRet').text != '0': + logging.info("Unable to get volume uuid of %s, " + "present in %s returning empty string: %s" % + (vol, host, vi.find('opErrstr').text)) + return "" + + try: + voluuid = vi.find("volInfo/volumes/volume/id").text + except (ParseError, AttributeError, ValueError) as e: + logging.info("Parsing failed to volume uuid of %s, " + "present in %s returning empty string: %s" % + (vol, host, e)) + voluuid = "" + + return voluuid + + def startup(**kw): """set up logging, pidfile grabbing, daemonization""" if getattr(gconf, 'pid_file', None) and kw.get('go_daemon') != 'postconn': @@ -314,6 +349,8 @@ def main_i(): action='callback', callback=store_local_curry('dont')) op.add_option('--verify', type=str, dest="verify", action='callback', callback=store_local) + op.add_option('--slavevoluuid-get', type=str, dest="slavevoluuid_get", + action='callback', callback=store_local) op.add_option('--create', type=str, dest="create", action='callback', callback=store_local) op.add_option('--delete', dest='delete', action='callback', @@ -375,6 +412,14 @@ def main_i(): defaults = op.get_default_values() opts, args = op.parse_args(values=optparse.Values()) args_orig = args[:] + + voluuid_get = rconf.get('slavevoluuid_get') + if voluuid_get: + slave_host, slave_vol = voluuid_get.split("::") + svol_uuid = slave_vol_uuid_get(slave_host, slave_vol) + print svol_uuid + return + r = rconf.get('resource_local') if r: if len(args) == 0: |