def test_ec_version_nonfop(self): # pylint: disable=too-many-statements,too-many-branches,too-many-locals # get the bricks from the volume g.log.info("Fetching bricks for the volume : %s", self.volname) bricks_list = get_all_bricks(self.mnode, self.volname) g.log.info("Brick List : %s", bricks_list) # Creating dir1 on the mountpoint cmd = ('mkdir %s/dir1' % self.mounts[0].mountpoint) ret, _, _ = g.run(self.mounts[0].client_system, cmd) self.assertEqual(ret, 0, "Failed to create directory dir1") g.log.info("Directory dir1 on %s created successfully", self.mounts[0]) ec_version_before_nonfops = [] ec_version_after_nonfops = [] # Getting the EC version of the directory for brick in bricks_list: brick_node, brick_path = brick.split(":") target_file = brick_path + "/dir1" dir_attribute = get_extended_attributes_info( brick_node, [target_file]) ec_version_before_nonfops.append( dir_attribute[target_file]['trusted.ec.version']) # chmod of dir1 once cmd = ('chmod 777 %s/dir1' % (self.mounts[0].mountpoint)) g.run(self.mounts[0].client_system, cmd) # chmod of dir1 twice cmd = ('chmod 777 %s/dir1' % (self.mounts[0].mountpoint)) g.run(self.mounts[0].client_system, cmd) # Getting the EC version of the directory # After changing mode of the directory for brick in bricks_list: brick_node, brick_path = brick.split(":") target_file = brick_path + "/dir1" dir_attribute = get_extended_attributes_info( brick_node, [target_file]) ec_version_after_nonfops.append( dir_attribute[target_file]['trusted.ec.version']) # Comparing the EC version before and after non data FOP self.assertEqual(ec_version_before_nonfops, ec_version_after_nonfops, "EC version updated for non data FOP") g.log.info("EC version is same for before and after non data FOP" "%s", self.volname)
def is_file_bad(mnode, filename): """Verifies if scrubber identifies bad file Args: filename (str): absolute path of the file in mnode mnode (str): Node on which cmd has to be executed. Returns: True on success, False otherwise Example: is_file_bad("abc.xyz.com", "/bricks/file1") """ ret = True count = 0 flag = 0 while (count < SCRUBBER_TIMEOUT): attr_info = get_extended_attributes_info(mnode, [filename]) if attr_info is None: ret = False if 'trusted.bit-rot.bad-file' in attr_info[filename]: flag = 1 break time.sleep(10) count = count + 10 if not flag: g.log.error("Scrubber failed to identify bad file") ret = False return ret
def _check_dirty_xattr(self, filename): """Get trusted.ec.dirty xattr value to validate eagerlock behavior""" # Find the hashed subvol of the file created # for distributed disperse case subvols_info = get_subvols(self.mnode, self.volname) subvols_info = subvols_info['volume_subvols'] if len(subvols_info) > 1: _, hashed_subvol = find_hashed_subvol(subvols_info, '', filename) if hashed_subvol is None: g.log.error("Error in finding hash value of %s", filename) return None else: hashed_subvol = 0 # Collect ec.dirty xattr value from each brick result = [] for subvol in subvols_info[hashed_subvol]: host, brickpath = subvol.split(':') brickpath = brickpath + '/' + filename ret = get_extended_attributes_info(host, [brickpath], encoding='hex', attr_name='trusted.ec.dirty') ret = ret[brickpath]['trusted.ec.dirty'] result.append(ret) # Check if xattr values are same across all bricks if result.count(result[0]) == len(result): return ret g.log.error( "trusted.ec.dirty value is not consistent across the " "disperse set %s", result) return None
def _get_dirty_xattr_value(ret, hashed_subvol, objectname): """Get trusted.ec.dirty xattr value to validate eagerlock behavior""" # Collect ec.dirty xattr value from each brick hashvals = [] for subvol in ret[hashed_subvol]: host, brickpath = subvol.split(':') brickpath = brickpath + '/' + objectname ret = get_extended_attributes_info(host, [brickpath], encoding='hex', attr_name='trusted.ec.dirty') ret = ret[brickpath]['trusted.ec.dirty'] hashvals.append(ret) # Check if xattr values are same across all bricks if hashvals.count(hashvals[0]) == len(hashvals): del hashvals return ret g.log.error( "trusted.ec.dirty value is not consistent across the " "disperse set %s", hashvals) return None
def validate_xattr_on_all_bricks(bricks_list, file_path, xattr): """Checks if the xattr of the file/dir is same on all bricks. Args: bricks_list (list): List of bricks. file_path (str): The path to the file/dir. xattr (str): The file attribute to get from file. Returns: True if the xattr is same on all the fqpath. False otherwise Example: validate_xattr_on_all_bricks("bricks_list", "dir1/file1", "xattr") """ time_counter = 250 g.log.info("The heal monitoring timeout is : %d minutes", (time_counter // 60)) while time_counter > 0: attr_vals = {} for brick in bricks_list: brick_node, brick_path = brick.split(":") attr_vals[brick] = ( get_extended_attributes_info(brick_node, ["{0}/{1}".format(brick_path, file_path)], attr_name=xattr)) ec_version_vals = [list(val.values())[0][xattr] for val in list(attr_vals.values())] if len(set(ec_version_vals)) == 1: return True else: time.sleep(120) time_counter -= 120 return False
def is_file_signed(mnode, filename, volname, expected_file_version=None): """Verifies if the given file is signed Args: mnode (str): Node on which cmd has to be executed. filename (str): relative path of filename to be verified volname (str): volume name Kwargs: expected_file_version (str): file version to check with getfattr output If this option is set, this function will check file versioning as part of signing verification. If this option is set to None, function will not check for file versioning. Defaults to None. Returns: True on success, False otherwise Example: is_file_signed("abc.com", 'file1', "testvol", expected_file_version='2') """ # Getting file path in the rhs node file_location = get_pathinfo(mnode, filename, volname) if file_location is None: g.log.error("Failed to get backend file path in is_file_signed()") return False path_info = file_location[0].split(':') expected_file_signature = (calculate_checksum( path_info[0], [path_info[1]])[path_info[1]]) attr_info = get_extended_attributes_info(path_info[0], [path_info[1]]) if attr_info is None: g.log.error("Failed to get attribute info in is_file_signed()") return False if 'trusted.bit-rot.signature' in attr_info[path_info[1]]: file_signature = attr_info[path_info[1]]['trusted.bit-rot.signature'] else: g.log.error("trusted.bit-rot.signature attribute not present " " for file %s" % filename) return False if expected_file_version is not None: expected_file_version = ('{0:02d}'.format( int(expected_file_version))).ljust(16, '0') actual_signature_file_version = re.findall('.{16}', file_signature[4:]).pop(0) # Verifying file version after signing if actual_signature_file_version != expected_file_version: g.log.error("File version mismatch in signature.Filename: %s ." "Expected file version: %s.Actual file version: %s" % (filename, expected_file_version, actual_signature_file_version)) return False actual_file_signature = ''.join( re.findall('.{16}', file_signature[4:])[1:]) # Verifying file signature if actual_file_signature != expected_file_signature: g.log.error("File signature mismatch. File name: %s . Expected " "file signature: %s. Actual file signature: %s" % (filename, expected_file_signature, actual_file_signature)) return False return True
def validate_xattr_values(self, dirname, ctime=True): """Validate existence and consistency of a specific xattr value across replica set Args: dirname (str): parent directory name Kwargs: ctime(bool): ctime feature enablement """ # pylint: disable=too-many-branches # Fetch all replica sets(subvols) in the volume ret = get_subvols(self.mnode, self.volname) # Iterating through each subvol(replicaset) for subvol in ret['volume_subvols']: brick_host_list = {} # Dict for storing host,brickpath pairs for each in subvol: # Fetching each replica in replica set # Splitting to brick,hostname pairs host, brick_path = each.split(':') brick_host_list[host] = brick_path # Fetch Complete parent directory path directory = brick_path + '/' + dirname # Fetching all entries recursively in a replicaset entry_list = get_dir_contents(host, directory, recursive=True) for each in entry_list: xattr_value = [] # list to store xattr value # Logic to get xattr values for host, brickpath in brick_host_list.items(): # Remove the prefix brick_path from entry-name each = sub(brick_path, '', each) # Adding the right brickpath name for fetching xattrval brick_entry_path = brickpath + each ret = get_extended_attributes_info(host, [brick_entry_path], encoding='hex', attr_name='trusted' '.glusterfs.' 'mdata') if ret: ret = ret[brick_entry_path]['trusted.glusterfs.mdata'] g.log.info("mdata xattr value of %s is %s", brick_entry_path, ret) else: pass if ctime: self.assertIsNotNone( ret, "glusterfs.mdata not set on" " {}".format(brick_entry_path)) g.log.info( "mdata xattr %s is set on the back-end" " bricks", ret) else: self.assertIsNone( ret, "trusted.glusterfs.mdata seen " " on {}".format(brick_entry_path)) g.log.info( "mdata xattr %s is not set on the back-end" " bricks", ret) xattr_value.append(ret) voltype = get_volume_type_info(self.mnode, self.volname) if voltype['volume_type_info']['arbiterCount'] == '0': ret = bool( xattr_value.count(xattr_value[0]) == len(xattr_value)) elif voltype['volume_type_info']['arbiterCount'] == '1': ret = bool(((xattr_value.count(xattr_value[0])) or (xattr_value.count(xattr_value[1])) > 1)) else: g.log.error("Arbiter value is neither 0 nor 1") if ctime: self.assertTrue( ret, 'trusted.glusterfs.mdata' + ' value not same across bricks for ' 'entry ' + each) else: self.assertTrue( ret, 'trusted.glusterfs.mdata' + ' seems to be set on some bricks for ' + each)