From b2e077a3d660c70d0f189935d3bf36f08541e549 Mon Sep 17 00:00:00 2001 From: sayaleeraut Date: Wed, 22 Jan 2020 15:48:24 +0530 Subject: [LibFix] Adding code to fix issues caused by DHT pass-through The issue earlier was that whenever a TC called the _get_layout() and _is_complete() methods, it failed on Replicate/Arbiter/Disperse volume types because of DHT pass-through. The functions,get_layout() and is_complete() have been modified to check for the Gluster version and volume type before running, in order to fix the issue. About DHT pass-through : Please refer to- https://github.com/gluster/glusterfs/issues/405 for the details. Change-Id: I0b0dc0ac3cbdef070a20854fbc89442fee1da8b6 Signed-off-by: sayaleeraut --- glustolibs-gluster/glustolibs/gluster/layout.py | 119 +++++++++++++++--------- 1 file changed, 74 insertions(+), 45 deletions(-) (limited to 'glustolibs-gluster') diff --git a/glustolibs-gluster/glustolibs/gluster/layout.py b/glustolibs-gluster/glustolibs/gluster/layout.py index c1ddb40f8..8d7ae2d6f 100644 --- a/glustolibs-gluster/glustolibs/gluster/layout.py +++ b/glustolibs-gluster/glustolibs/gluster/layout.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2018 Red Hat, Inc. +# Copyright (C) 2018-2020 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ from glusto.core import Glusto as g from glustolibs.gluster.brickdir import BrickDir +from glustolibs.gluster.gluster_init import get_gluster_version class Layout(object): @@ -28,11 +29,26 @@ class Layout(object): """ def _get_layout(self): """Discover brickdir data and cache in instance for further use""" + # Adding here to avoid cyclic imports + from glustolibs.gluster.volume_libs import get_volume_type + self._brickdirs = [] for brickdir_path in self._pathinfo['brickdir_paths']: - brickdir = BrickDir(brickdir_path) - g.log.debug("%s: %s" % (brickdir.path, brickdir.hashrange)) - self._brickdirs.append(brickdir) + (host, _) = brickdir_path.split(':') + if get_gluster_version(host) >= 6.0: + ret = get_volume_type(brickdir_path) + if ret in ('Replicate', 'Disperse', 'Arbiter'): + g.log.info("Cannot get layout as volume under test is" + " Replicate/Disperse/Arbiter and DHT" + " pass-through was enabled after Gluster 6.") + else: + brickdir = BrickDir(brickdir_path) + if brickdir is None: + g.log.error("Failed to get the layout") + else: + g.log.debug("%s: %s" % (brickdir.path, + brickdir.hashrange)) + self._brickdirs.append(brickdir) def __init__(self, pathinfo): """Init the layout class @@ -59,48 +75,61 @@ class Layout(object): ends at 32-bits high, and has no holes or overlaps """ - joined_hashranges = [] - for brickdir in self.brickdirs: - # join all of the hashranges into a single list - joined_hashranges += brickdir.hashrange - g.log.debug("joined range list: %s" % joined_hashranges) - # remove duplicate hashes - collapsed_ranges = list(set(joined_hashranges)) - # sort the range list for good measure - collapsed_ranges.sort() - - # first hash in the list is 0? - if collapsed_ranges[0] != 0: - g.log.error('First hash in range (%d) is not zero' % - collapsed_ranges[0]) - return False - - # last hash in the list is 32-bits high? - if collapsed_ranges[-1] != int(0xffffffff): - g.log.error('Last hash in ranges (%s) is not 0xffffffff' % - hex(collapsed_ranges[-1])) - return False - - # remove the first and last hashes - clipped_ranges = collapsed_ranges[1:-1] - g.log.debug('clipped: %s' % clipped_ranges) - - # walk through the list in pairs and look for diff == 1 - iter_ranges = iter(clipped_ranges) - for first in iter_ranges: - second = next(iter_ranges) - hash_difference = second - first - g.log.debug('%d - %d = %d' % (second, first, hash_difference)) - if hash_difference > 1: - g.log.error("Layout has holes") - - return False - elif hash_difference < 1: - g.log.error("Layout has overlaps") - - return False + # Adding here to avoid cyclic imports + from glustolibs.gluster.volume_libs import get_volume_type - return True + for brickdir_path in self._pathinfo['brickdir_paths']: + (host, _) = brickdir_path.split(':') + if (get_gluster_version(host) >= 6.0 and + get_volume_type(brickdir_path) in ('Replicate', 'Disperse', + 'Arbiter')): + g.log.info("Cannot check for layout completeness as volume" + " under test is Replicate/Disperse/Arbiter and DHT" + " pass-though was enabled after Gluster 6.") + else: + joined_hashranges = [] + for brickdir in self.brickdirs: + # join all of the hashranges into a single list + joined_hashranges += brickdir.hashrange + g.log.debug("joined range list: %s" % joined_hashranges) + # remove duplicate hashes + collapsed_ranges = list(set(joined_hashranges)) + # sort the range list for good measure + collapsed_ranges.sort() + + # first hash in the list is 0? + if collapsed_ranges[0] != 0: + g.log.error('First hash in range (%d) is not zero' % + collapsed_ranges[0]) + return False + + # last hash in the list is 32-bits high? + if collapsed_ranges[-1] != int(0xffffffff): + g.log.error('Last hash in ranges (%s) is not 0xffffffff' % + hex(collapsed_ranges[-1])) + return False + + # remove the first and last hashes + clipped_ranges = collapsed_ranges[1:-1] + g.log.debug('clipped: %s' % clipped_ranges) + + # walk through the list in pairs and look for diff == 1 + iter_ranges = iter(clipped_ranges) + for first in iter_ranges: + second = next(iter_ranges) + hash_difference = second - first + g.log.debug('%d - %d = %d' % (second, first, + hash_difference)) + if hash_difference > 1: + g.log.error("Layout has holes") + + return False + elif hash_difference < 1: + g.log.error("Layout has overlaps") + + return False + + return True @property def has_zero_hashranges(self): -- cgit