diff options
Diffstat (limited to 'myraid.py')
-rw-r--r-- | myraid.py | 110 |
1 files changed, 65 insertions, 45 deletions
@@ -32,18 +32,6 @@ class MyRaid(): self.raid_disk_count = 0 self.raid_types = [ '0', '1', '5', '5+0' ] - def get_raid_size(self, raid_type): - size = self.raid_end - self.raid_start - if size <= 0: - return 0 - else: - return { - '0': size * self.raid_disk_count, - '1': size, - '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 get_raid_start(self): return self.raid_start @@ -84,34 +72,32 @@ class MyRaid(): self.raid_disk_order = new_raid_disk_order self.raid_disk_count = len(new_raid_disk_order) + def sizeof_raid_result(self, raid_type): + size = self.raid_end - self.raid_start + if size <= 0 : + return 0 + else: + return { + '0' : size * self.raid_disk_count, + '1' : size, + '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 read_data(self,raid_type,disks,offset,size): - """TODO""" - disk_count = len(self.raid_disk_order) - - # This code is RAID 5 only - - slice_no = offset / self.raid_chunk_size - slice_off = offset % self.raid_chunk_size - segment=slice_no/(disk_count-1) - par_disk=(disk_count-1) - (segment % disk_count) # TODO : equivalent a : segment-1 % disk_count ? - data_disk=( par_disk + 1 + (slice_no % (disk_count-1)) ) % disk_count - off_disk = self.raid_start + segment * self.raid_chunk_size + slice_off - - size2 = min(size, (slice_no+1) * self.raid_chunk_size - offset) - - logging.info("raid.read_data(%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) ) + def sizeof_disk_parity(self, raid_type): + return self.sizeof_disk_xor(raid_type) / self.raid_sector_size * 16 - data_fd = disks[self.raid_disk_order[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_data(self,raid_type,disks,offset+size2,size-size2) - - return data + def sizeof_disk_xor(self, raid_type): + size = self.raid_end - self.raid_start + if size <= 0: + return 0 + else: + return { + '0' : 0, # TODO Could contain some plain text error message + '1' : size, + '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 xor_blocks(self,fd_list, offset, size): """TODO""" @@ -149,22 +135,56 @@ class MyRaid(): result = 'b' logging.info("Exit. xor_blocks(fd_list,%d,%d)"%(offset, size)) - return result - - def check_data(self,raid_type,disks,offset,size): - """TODO""" - logging.warn("Enter check_data(%s,disks,%d,%d)"%(raid_type,offset,size)) #import binascii #logging.warn(binascii.hexlify(numpy_b1)) + return (result,numpy_b1) - #result = ''.join([ self.xor_blocks(disks, (offset+i)*self.raid_sector_size, self.raid_sector_size) for i in range(size)]) - 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) ]) + def read_disk_parity(self,raid_type,disks,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) ]) + 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]) + for addr in range(start, end, self.raid_sector_size) + ]) logging.warn("Exit. check_data(%s,disks,%d,%d)"%(raid_type,offset,size)) return result + def read_disk_xor(self,raid_type,disks,offset,size): + return self.xor_blocks(disks,offset,size)[1].tostring() + + def read_raid_result(self,raid_type,disks,offset,size): + """TODO""" + disk_count = len(self.raid_disk_order) + + # This code is RAID 5 only (left-assymetric) + + slice_no = offset / self.raid_chunk_size + slice_off = offset % self.raid_chunk_size + segment=slice_no/(disk_count-1) + par_disk=(disk_count-1) - (segment % disk_count) # TODO : equivalent a : segment-1 % disk_count ? + data_disk=( par_disk + 1 + (slice_no % (disk_count-1)) ) % disk_count + off_disk = self.raid_start + segment * self.raid_chunk_size + slice_off + + size2 = min(size, (slice_no+1) * self.raid_chunk_size - offset) + + 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.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) + + return data |