summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <lpouzenc@gmail.com>2015-06-17 20:19:09 +0200
committerLudovic Pouzenc <lpouzenc@gmail.com>2015-06-17 20:19:09 +0200
commit194b65f14adf2b442c3a8c4ed3a85d4472b09df8 (patch)
treee96e36ac1d18911323c4735fe7e551a50e50b59c
parente4f77ba251e6594f298d1ff91d941826a7b06534 (diff)
downloadraidguessfs-194b65f14adf2b442c3a8c4ed3a85d4472b09df8.tar.gz
raidguessfs-194b65f14adf2b442c3a8c4ed3a85d4472b09df8.tar.bz2
raidguessfs-194b65f14adf2b442c3a8c4ed3a85d4472b09df8.zip
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
-rw-r--r--myraid.py36
-rwxr-xr-xraidguessfs.py27
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)