summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <lpouzenc@gmail.com>2015-06-14 22:30:48 +0200
committerLudovic Pouzenc <lpouzenc@gmail.com>2015-06-14 22:30:48 +0200
commit8847a025b334ea0d9814215291e8f546dd5f1e7e (patch)
tree9bcb8a853168db91d76cc7ac35df4cbc655a0480
parent5943acb92ce0159e9f482748e4fa4aadddae6851 (diff)
downloadraidguessfs-8847a025b334ea0d9814215291e8f546dd5f1e7e.tar.gz
raidguessfs-8847a025b334ea0d9814215291e8f546dd5f1e7e.tar.bz2
raidguessfs-8847a025b334ea0d9814215291e8f546dd5f1e7e.zip
Various minor improovements
* Log full stacktraces on exceptions * Compute correctly raid_size * Do all needed sanity checks on raid_disk_order
-rw-r--r--myraid.py32
-rwxr-xr-xraidguessfs.py27
2 files changed, 40 insertions, 19 deletions
diff --git a/myraid.py b/myraid.py
index 60e8b28..785b514 100644
--- a/myraid.py
+++ b/myraid.py
@@ -26,17 +26,23 @@ class MyRaid():
def __init__(self, *args, **kwargs):
self.raid_start = 0
self.raid_end = 0
- self.raid_size = 0
self.raid_sector_size = 512
self.raid_chunk_size = 65536
- self.raid_disk_order = range(15)
+ self.raid_disk_order = []
+ self.raid_disk_count = 0
self.raid_types = [ '0', '1', '5', '5+0' ]
- def _update_raid_size(self):
- if self.raid_end > self.raid_start:
- self.raid_size = self.raid_end - self.raid_start
+ def get_raid_size(self, raid_type):
+ size = self.raid_end - self.raid_start
+ if size <= 0:
+ return 0
else:
- self.raid_size = 0
+ 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
@@ -53,12 +59,10 @@ class MyRaid():
def set_raid_start(self, new_raid_start):
"""Update the start offset of raid data on underlying disks"""
self.raid_start = new_raid_start
- self._update_raid_size()
def set_raid_end(self, new_raid_end):
"""Update the end offset of raid data on underlying disks"""
self.raid_end = new_raid_end
- self._update_raid_size()
def set_raid_chunk_size(self, new_raid_chunk_size):
"""Update the size of chucks of data (or slice size)"""
@@ -66,7 +70,19 @@ class MyRaid():
def set_raid_disk_order(self, new_raid_disk_order):
"""Update the raid logical disk order"""
+ card=len(new_raid_disk_order)
+ check=[0]*card
+ for item in new_raid_disk_order:
+ d = int(item)
+ if not 0 <= d < card:
+ raise ValueError('Value out of range : %i [0,%i]'%(d,card-1))
+ 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]))
self.raid_disk_order = new_raid_disk_order
+ self.raid_disk_count = len(new_raid_disk_order)
def read_data(self,raid_type,disks,offset,size):
diff --git a/raidguessfs.py b/raidguessfs.py
index ffb0912..6b78a7d 100755
--- a/raidguessfs.py
+++ b/raidguessfs.py
@@ -120,7 +120,7 @@ class RaidGuessFS(fuse.Fuse):
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.raid_size
+ self.fattr['/raid/%s/result'%raid_type].st_size = self.raid.get_raid_size(raid_type)
logging.debug("Exit. _refresh_raid_fattr()")
@@ -178,10 +178,15 @@ class RaidGuessFS(fuse.Fuse):
logging.debug("Enter update_raid_disk_order(%s)"%arg)
if type(arg) is str:
l = arg.split()
- else:
+ elif type(arg) is list:
l = arg
- # TODO : sanity checks (every disk number below disk count, len(list) below disk count, no double...)
+ 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')
+
self.raid.set_raid_disk_order(l)
logging.debug("Exit. update_raid_disk_order(%s)"%arg)
@@ -195,7 +200,7 @@ class RaidGuessFS(fuse.Fuse):
"""Make some run-time initalisations after argument parsing"""
logging.info("Mounting filesystem...")
# WARNING : this method is called by FUSE in a context that don't show fatal exceptions,
- # even with -d[ebug] flag set, so log all exceptions stupidly
+ # even with -d[ebug] flag set, so log all exceptions
try:
self.dattr = {
path: self.st.make_fake_dir() for path in self.dentries.keys()
@@ -218,7 +223,7 @@ class RaidGuessFS(fuse.Fuse):
logging.info("Mounted.")
except Exception as e:
- logging.error(e)
+ logging.exception(e)
def getattr(self, path):
logging.info("getattr: %s" % path)
@@ -281,7 +286,7 @@ class RaidGuessFS(fuse.Fuse):
return self.raid.check_data(raid_type,self.d.disks,offset,size)
except Exception as e:
- logging.error(e)
+ logging.exception(e)
return -errno.ENOENT
logging.error("Unimplemented read of '%s' (%s)"%(path, str(path_chuncks)))
@@ -297,14 +302,14 @@ class RaidGuessFS(fuse.Fuse):
# TODO take care here
idx = self.settings.index(path_chuncks[1])
try:
- self.settings_updaters[idx](buf)
+ self.settings_updaters[idx](buf.rstrip())
return len(buf)
except Exception as e:
- logging.error(e)
+ logging.exception(e)
return -errno.EIO
except Exception as e:
- logging.error(e)
+ logging.exception(e)
return -errno.ENOENT
logging.error("Unimplemented write of '%s' (%s)"%(path, str(path_chuncks)))
@@ -321,9 +326,9 @@ RaidGuessFS is a pseudo-filesystem that allows to guess parameters and disk orde
fuse.fuse_python_api = (0, 2)
LOG_FILENAME = "raidguessfs.log"
- logging.basicConfig(filename=LOG_FILENAME,level=logging.WARN,)
+ #logging.basicConfig(filename=LOG_FILENAME,level=logging.WARN,)
#logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO,)
- #logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,)
+ logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,)
server = RaidGuessFS(version="%prog " + fuse.__version__,usage=usage,dash_s_do='setsingle')
server.multithreaded = False