From 194b65f14adf2b442c3a8c4ed3a85d4472b09df8 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Wed, 17 Jun 2015 20:19:09 +0200 Subject: Small improvements * keep refs to disks fd list in MyRaid * add raid_end as configurable parameter * allow raid_disk_order to have less disks than disk_count (for failed) * updates raid pseudo-files length on raid_disk_order change --- myraid.py | 36 +++++++++++++++++++++++------------- raidguessfs.py | 27 +++++++++++++++++---------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/myraid.py b/myraid.py index c7dbf31..5b44fc4 100644 --- a/myraid.py +++ b/myraid.py @@ -24,6 +24,7 @@ class MyRaid(): """Auxiliary class, managing RAID layer""" def __init__(self, *args, **kwargs): + self.disks = [] self.raid_start = 0 self.raid_end = 0 self.raid_sector_size = 512 @@ -35,6 +36,9 @@ class MyRaid(): def get_raid_start(self): return self.raid_start + def get_raid_end(self): + return self.raid_end + def get_raid_chunk_size(self): return self.raid_chunk_size @@ -44,6 +48,9 @@ class MyRaid(): def get_raid_disk_order_str(self): return ' '.join(map(str,self.raid_disk_order)) + def set_disks(self, disks): + self.disks = disks + def set_raid_start(self, new_raid_start): """Update the start offset of raid data on underlying disks""" self.raid_start = new_raid_start @@ -58,7 +65,7 @@ class MyRaid(): def set_raid_disk_order(self, new_raid_disk_order): """Update the raid logical disk order""" - card=len(new_raid_disk_order) + card=len(self.disks) check=[0]*card for item in new_raid_disk_order: d = int(item) @@ -67,8 +74,8 @@ class MyRaid(): check[d]=check[d]+1 for d in range(card): - if check[d]!=1: - raise ValueError('Disk %i appears %i times (must be 1)'%(d,check[d])) + if check[d] != 1 and check[d] != 0: + raise ValueError('Disk %i appears %i times (must be 0 or 1)'%(d,check[d])) self.raid_disk_order = new_raid_disk_order self.raid_disk_count = len(new_raid_disk_order) @@ -139,15 +146,14 @@ class MyRaid(): #logging.warn(binascii.hexlify(numpy_b1)) return (result,numpy_b1) - def read_disk_parity(self,raid_type,disks,offset,size): + def read_disk_parity(self,raid_type,offset,size): """TODO""" logging.warn("Enter check_data(%s,disks,%d,%d)"%(raid_type,offset,size)) - # TODO donner des offests RAID et pas disques - #result = ''.join([ '0x%011x %c\n'%( (offset/16+i)*self.raid_sector_size, self.xor_blocks(disks, (offset/16+i)*self.raid_sector_size, self.raid_sector_size)) for i in range(size/16) ]) + raid_disks = [ self.disks[i] for i in self.raid_disk_order ] start = self.raid_start + offset * self.raid_sector_size / 16 end = start + size * self.raid_sector_size / 16 result = ''.join( - [ '0x%011x %c\n'%( addr, self.xor_blocks(disks, addr, self.raid_sector_size)[0]) + [ '0x%011x %c\n'%( addr, self.xor_blocks(raid_disks, addr, self.raid_sector_size)[0]) for addr in range(start, end, self.raid_sector_size) ]) @@ -155,15 +161,19 @@ class MyRaid(): return result - def read_disk_xor(self,raid_type,disks,offset,size): - return self.xor_blocks(disks,offset,size)[1].tostring() + def read_disk_xor(self,raid_type,offset,size): + raid_disks = [ self.disks[i] for i in self.raid_disk_order ] + return self.xor_blocks(raid_disks,offset,size)[1].tostring() - def read_raid_result(self,raid_type,disks,offset,size): + def read_raid_result(self,raid_type,offset,size): """TODO""" - disk_count = len(self.raid_disk_order) + disk_count = len(self.raid_disk_order) # TODO doublon ? + raid_disks = [ self.disks[i] for i in self.raid_disk_order ] # A garder en attribut ? # This code is RAID 5 only (left-assymetric) + if disk_count < 3: + return None slice_no = offset / self.raid_chunk_size slice_off = offset % self.raid_chunk_size @@ -177,13 +187,13 @@ class MyRaid(): logging.info("raid.read_result(%s): offset=%d,slice_no=%d,slice_off=%d,segment=%d,par_disk=%d,data_disk=%d,off_disk=%d,size2=%d,slice_off+size2=%d" % (raid_type,offset,slice_no,slice_off,segment,par_disk,data_disk,off_disk,size2,slice_off+size2) ) - data_fd = disks[self.raid_disk_order[data_disk]] + data_fd = raid_disks[data_disk] data_fd.seek(off_disk) data = data_fd.read(size2) # This kills performance but don't make short reads before EOF #if size2 < size: - # data += self.read_result(self,raid_type,disks,offset+size2,size-size2) + # data += self.read_result(self,raid_type,offset+size2,size-size2) return data diff --git a/raidguessfs.py b/raidguessfs.py index c9c3833..fba2187 100755 --- a/raidguessfs.py +++ b/raidguessfs.py @@ -61,19 +61,19 @@ class RaidGuessFS(fuse.Fuse): self.settings = [ 'disk_count', - 'raid_start', 'raid_chunk_size', 'raid_disk_order', + 'raid_start', 'raid_end', 'raid_chunk_size', 'raid_disk_order', 'bmp_height', 'bmp_width', 'bmp_start_offset' ] self.settings_getters = [ self.d.get_disk_count, - self.raid.get_raid_start, self.raid.get_raid_chunk_size, self.raid.get_raid_disk_order_str, + self.raid.get_raid_start, self.raid.get_raid_end, self.raid.get_raid_chunk_size, self.raid.get_raid_disk_order_str, self.bmp.get_bmp_height, self.bmp.get_bmp_width, self.bmp.get_bmp_start_offset ] self.settings_updaters = [ self.update_disk_count, - self.update_raid_start, self.update_raid_chunk_size, self.update_raid_disk_order, + self.update_raid_start, self.update_raid_end, self.update_raid_chunk_size, self.update_raid_disk_order, self.update_bmp_height, self.update_bmp_width, self.update_bmp_start_offset ] @@ -137,9 +137,9 @@ class RaidGuessFS(fuse.Fuse): self.d.set_disk_count(i) self.d.open_disks() self._refresh_disk_dentries() + self.raid.set_disks(self.d.disks) self.raid.set_raid_end(min(self.d.disks_size)-1) self.update_raid_disk_order(range(i)) - self._refresh_raid_fattr() def update_bmp_start_offset(self, arg): i = int(arg) @@ -168,6 +168,12 @@ class RaidGuessFS(fuse.Fuse): self.raid.set_raid_start(i) self._refresh_raid_fattr() + def update_raid_end(self, arg): + i = int(arg) + assert (i >= 0), "Negative value make no sense here" + self.raid.set_raid_end(i) + self._refresh_raid_fattr() + def update_raid_chunk_size(self, arg): i = int(arg) assert (i > 0), "Non-positive value make no sense here" @@ -176,17 +182,18 @@ class RaidGuessFS(fuse.Fuse): def update_raid_disk_order(self, arg): logging.debug("Enter update_raid_disk_order(%s)"%arg) if type(arg) is str: - l = arg.split() + l = map(int,arg.split()) elif type(arg) is list: l = arg else: raise TypeError('update_raid_disk_order() wants a list or str') logging.debug("==> %s (%d/%d)"%(l,len(l),self.d.disk_count)) - if len(l) != self.d.disk_count: - raise ValueError('Value count does not match disk count') + #if len(l) != self.d.disk_count: + # raise ValueError('Value count does not match disk count') self.raid.set_raid_disk_order(l) + self._refresh_raid_fattr() logging.debug("Exit. update_raid_disk_order(%s)"%arg) @@ -280,11 +287,11 @@ class RaidGuessFS(fuse.Fuse): raid_type=path_chuncks[2] if raid_type in self.raid.raid_types: if path_chuncks[4] == 'disk_parity': - return self.raid.read_disk_parity(raid_type,self.d.disks,offset,size) + return self.raid.read_disk_parity(raid_type,offset,size) if path_chuncks[4] == 'disk_xor': - return self.raid.read_disk_xor(raid_type,self.d.disks,offset,size) + return self.raid.read_disk_xor(raid_type,offset,size) if path_chuncks[4] == 'raid_result': - return self.raid.read_raid_result(raid_type,self.d.disks,offset,size) + return self.raid.read_raid_result(raid_type,offset,size) except Exception as e: logging.exception(e) -- cgit v1.2.3