From 45e7b53b013999e4cc2f72c080651cc2ece5a346 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 28 Jun 2015 01:05:47 +0200 Subject: RAID 5 layout implementation (left/right (as)symmetric and RAID 0 impl. --- myraid.py | 122 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 40 deletions(-) (limited to 'myraid.py') diff --git a/myraid.py b/myraid.py index 5b44fc4..3706c36 100644 --- a/myraid.py +++ b/myraid.py @@ -22,6 +22,8 @@ import logging, numpy class MyRaid(): """Auxiliary class, managing RAID layer""" + RAID_TYPES = [ '0', '1', '5', '5+0' ] + RAID5_LAYOUTS = [ 'la', 'ra', 'ls', 'rs' ] def __init__(self, *args, **kwargs): self.disks = [] @@ -31,7 +33,7 @@ class MyRaid(): self.raid_chunk_size = 65536 self.raid_disk_order = [] self.raid_disk_count = 0 - self.raid_types = [ '0', '1', '5', '5+0' ] + self.raid_layout = 'ls' def get_raid_start(self): return self.raid_start @@ -48,6 +50,9 @@ class MyRaid(): def get_raid_disk_order_str(self): return ' '.join(map(str,self.raid_disk_order)) + def get_raid_layout(self): + return self.raid_layout + def set_disks(self, disks): self.disks = disks @@ -79,6 +84,12 @@ class MyRaid(): self.raid_disk_order = new_raid_disk_order self.raid_disk_count = len(new_raid_disk_order) + def set_raid_layout(self, new_raid_layout): + if new_raid_layout in MyRaid.RAID5_LAYOUTS: + self.raid_layout = new_raid_layout + else: + raise ValueError('raid_layout has to be one of %s'%' '.join(RAID_LAYOUTS)) + def sizeof_raid_result(self, raid_type): size = self.raid_end - self.raid_start if size <= 0 : @@ -86,14 +97,11 @@ class MyRaid(): else: return { '0' : size * self.raid_disk_count, - '1' : size, + '1' : size if self.raid_disk_count == 2 else 0, '5' : size * (self.raid_disk_count - 1) if self.raid_disk_count >= 3 else 0, '5+0': size * (self.raid_disk_count - 2) if self.raid_disk_count >= 6 and self.raid_disk_count % 2 == 0 else 0, }[raid_type] - def sizeof_disk_parity(self, raid_type): - return self.sizeof_disk_xor(raid_type) / self.raid_sector_size * 16 - def sizeof_disk_xor(self, raid_type): size = self.raid_end - self.raid_start if size <= 0: @@ -101,16 +109,20 @@ class MyRaid(): else: return { '0' : 0, # TODO Could contain some plain text error message - '1' : size, + '1' : size if self.raid_disk_count == 2 else 0, '5' : size if self.raid_disk_count >= 3 else 0, '5+0': size if self.raid_disk_count >= 6 and self.raid_disk_count % 2 == 0 else 0, }[raid_type] + def sizeof_disk_parity(self, raid_type): + return self.sizeof_disk_xor(raid_type) / self.raid_sector_size * 16 + def xor_blocks(self,fd_list, offset, size): - """TODO""" + """Compute bitwise XOR against a bunch of disks slice""" logging.info("Enter xor_blocks(fd_list,%d,%d)"%(offset, size)) - assert(size % 8 == 0), "Size must be multiple of 8" + if size % 8 != 0: + raise ValueError('xor_blocks : size must be multiple of 8') dt = numpy.dtype('= par_disk: + data_disk = data_disk + 1 + + off_disk = self.raid_start + stripe_no * self.raid_chunk_size + segment_off + size2 = min(size, (segment_no+1) * self.raid_chunk_size - offset) + + logging.info("raid.read_result(%s): offset=%d,segment_no=%d,segment_off=%d,stripe_no=%d,par_disk=%d,data_disk=%d,off_disk=%d,size2=%d,segment_off+size2=%d" + % (raid_type,offset,segment_no,segment_off,stripe_no,par_disk,data_disk,off_disk,size2,segment_off+size2) ) + + #TODO recorver from parity if damaged sectors in 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: + #if size2 > 0 and size2 < size: # data += self.read_result(self,raid_type,offset+size2,size-size2) return data -- cgit v1.2.3