diff options
author | Aravinda Vishwanathapura <aravinda@kadalu.io> | 2020-07-12 12:42:36 +0530 |
---|---|---|
committer | Aravinda Vishwanathapura <aravinda@kadalu.io> | 2020-07-12 15:09:26 +0530 |
commit | 93598b2dd323e4ed20e3297bbab2a151c40a0595 (patch) | |
tree | 259e70e8bff461ee12af4adc74091d801937c960 | |
parent | f3df1a5d6e44f70c51a3cdbb4873c1c5a2fd0771 (diff) |
geo-replication: Fix IPv6 parsing
Brick paths in Volinfo used `:` as delimiter, Geo-rep uses split
based on `:` char. This will go wrong with IPv6.
This patch handles the IPv6 case and handles the split properly.
Fixes: #1366
Change-Id: I25e88d693744381c0ccf3c1dbf1541b84be2499d
Signed-off-by: Aravinda Vishwanathapura <aravinda@kadalu.io>
-rw-r--r-- | geo-replication/syncdaemon/master.py | 5 | ||||
-rw-r--r-- | geo-replication/syncdaemon/syncdutils.py | 43 |
2 files changed, 43 insertions, 5 deletions
diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py index 03d871415e6..9501aeae6b5 100644 --- a/geo-replication/syncdaemon/master.py +++ b/geo-replication/syncdaemon/master.py @@ -27,7 +27,8 @@ from rconf import rconf from syncdutils import (Thread, GsyncdError, escape_space_newline, unescape_space_newline, gauxpfx, escape, lstat, errno_wrap, FreeObject, lf, matching_disk_gfid, - NoStimeAvailable, PartialHistoryAvailable) + NoStimeAvailable, PartialHistoryAvailable, + host_brick_split) URXTIME = (-1, 0) @@ -1466,7 +1467,7 @@ class GMasterChangelogMixin(GMasterCommon): node = rconf.args.resource_remote node_data = node.split("@") node = node_data[-1] - remote_node_ip = node.split(":")[0] + remote_node_ip, _ = host_brick_split(node) self.status.set_slave_node(remote_node_ip) def changelogs_batch_process(self, changes): diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py index 6362c13d5e3..b3f3fd8a936 100644 --- a/geo-replication/syncdaemon/syncdutils.py +++ b/geo-replication/syncdaemon/syncdutils.py @@ -894,6 +894,19 @@ class Popen(subprocess.Popen): self.errfail() +def host_brick_split(value): + """ + IPv6 compatible way to split and get the host + and brick information. Example inputs: + node1.example.com:/exports/bricks/brick1/brick + fe80::af0f:df82:844f:ef66%utun0:/exports/bricks/brick1/brick + """ + parts = value.split(":") + brick = parts[-1] + hostparts = parts[0:-1] + return (":".join(hostparts), brick) + + class Volinfo(object): def __init__(self, vol, host='localhost', prelude=[], master=True): @@ -936,7 +949,7 @@ class Volinfo(object): @memoize def bricks(self): def bparse(b): - host, dirp = b.find("name").text.split(':', 2) + host, dirp = host_brick_split(b.find("name").text) return {'host': host, 'dir': dirp, 'uuid': b.find("hostUuid").text} return [bparse(b) for b in self.get('brick')] @@ -1012,6 +1025,16 @@ class VolinfoFromGconf(object): def is_hot(self, brickpath): return False + def is_uuid(self, value): + try: + uuid.UUID(value) + return True + except ValueError: + return False + + def possible_path(self, value): + return "/" in value + @property @memoize def bricks(self): @@ -1025,8 +1048,22 @@ class VolinfoFromGconf(object): out = [] for b in bricks_data: parts = b.split(":") - bpath = parts[2] if len(parts) == 3 else "" - out.append({"host": parts[1], "dir": bpath, "uuid": parts[0]}) + b_uuid = None + if self.is_uuid(parts[0]): + b_uuid = parts[0] + # Set all parts except first + parts = parts[1:] + + if self.possible_path(parts[-1]): + bpath = parts[-1] + # Set all parts except last + parts = parts[0:-1] + + out.append({ + "host": ":".join(parts), # if remaining parts are IPv6 name + "dir": bpath, + "uuid": b_uuid + }) return out |