summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--myraid.py110
-rwxr-xr-xraidguessfs.py26
2 files changed, 79 insertions, 57 deletions
diff --git a/myraid.py b/myraid.py
index 785b514..c7dbf31 100644
--- a/myraid.py
+++ b/myraid.py
@@ -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
diff --git a/raidguessfs.py b/raidguessfs.py
index 6b78a7d..c9c3833 100755
--- a/raidguessfs.py
+++ b/raidguessfs.py
@@ -87,8 +87,7 @@ class RaidGuessFS(fuse.Fuse):
for raid_type in self.raid.raid_types:
self.dentries.update( {
- # TODO : all type of raid don't need the same pseudo files
- '/raid/%s'%raid_type: [ fuse.Direntry(name) for name in ['result','data_xor','parity'] ],
+ '/raid/%s'%raid_type: [ fuse.Direntry(name) for name in ['disk_parity','disk_xor','raid_result'] ],
}
)
logging.debug("Exit. RaidGuessFS.__init__()")
@@ -118,9 +117,9 @@ class RaidGuessFS(fuse.Fuse):
logging.debug("Enter _refresh_raid_fattr()")
for raid_type in self.raid.raid_types:
- self.fattr['/raid/%s/data_xor'%raid_type].st_size = 0 # self.raid.raid_size
- self.fattr['/raid/%s/parity'%raid_type].st_size = min(self.d.disks_size) / self.raid.raid_sector_size * 16
- self.fattr['/raid/%s/result'%raid_type].st_size = self.raid.get_raid_size(raid_type)
+ self.fattr['/raid/%s/disk_parity'%raid_type].st_size = self.raid.sizeof_disk_parity(raid_type)
+ self.fattr['/raid/%s/disk_xor' %raid_type].st_size = self.raid.sizeof_disk_xor (raid_type)
+ self.fattr['/raid/%s/raid_result'%raid_type].st_size = self.raid.sizeof_raid_result(raid_type)
logging.debug("Exit. _refresh_raid_fattr()")
@@ -210,9 +209,9 @@ class RaidGuessFS(fuse.Fuse):
}
for raid_type in self.raid.raid_types:
self.fattr.update( {
- '/raid/%s/data_xor'%raid_type: self.st.make_fake_file(0),
- '/raid/%s/parity'%raid_type: self.st.make_fake_file(0),
- '/raid/%s/result'%raid_type: self.st.make_fake_file(0),
+ '/raid/%s/disk_parity'%raid_type: self.st.make_fake_file(0),
+ '/raid/%s/disk_xor'%raid_type: self.st.make_fake_file(0),
+ '/raid/%s/raid_result'%raid_type: self.st.make_fake_file(0),
})
self.d.set_disks_path([getattr(self.parser.values,'disk%02d'%d) for d in range(self.d.max_disks)])
@@ -280,10 +279,12 @@ class RaidGuessFS(fuse.Fuse):
if path_chuncks[0] == 'raid':
raid_type=path_chuncks[2]
if raid_type in self.raid.raid_types:
- if path_chuncks[4] == 'result':
- return self.raid.read_data(raid_type,self.d.disks,offset,size)
- if path_chuncks[4] == 'parity':
- return self.raid.check_data(raid_type,self.d.disks,offset,size)
+ if path_chuncks[4] == 'disk_parity':
+ return self.raid.read_disk_parity(raid_type,self.d.disks,offset,size)
+ if path_chuncks[4] == 'disk_xor':
+ return self.raid.read_disk_xor(raid_type,self.d.disks,offset,size)
+ if path_chuncks[4] == 'raid_result':
+ return self.raid.read_raid_result(raid_type,self.d.disks,offset,size)
except Exception as e:
logging.exception(e)
@@ -334,6 +335,7 @@ RaidGuessFS is a pseudo-filesystem that allows to guess parameters and disk orde
server.multithreaded = False
cwd = os.getcwd()
+ # TODO : only 2 parameters, but taking a parametrized string
for num in range(server.d.max_disks):
server.parser.add_option(
mountopt="disk%02d"%num,