From d740e60ab772af0051c0e032db210a95e6483649 Mon Sep 17 00:00:00 2001
From: Ludovic Pouzenc <ludovic@pouzenc.fr>
Date: Sun, 30 Aug 2015 19:57:15 +0200
Subject: mount-options : keep it simple and stupid + some refactoring

---
 mydisks.py     | 28 +++++++++++-----------------
 raidguessfs.py | 46 ++++++++++++++++++++--------------------------
 2 files changed, 31 insertions(+), 43 deletions(-)

diff --git a/mydisks.py b/mydisks.py
index 070c188..624e3a0 100644
--- a/mydisks.py
+++ b/mydisks.py
@@ -23,27 +23,16 @@ import os, sys, logging
 class MyDisks():
     """Auxiliary class, managing disk layer"""
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self):
         self.disks = []
-        self.disk_paths = []
         self.sector_size = 512
         self.disk_count = 0
         self.disks_size = [0]
-        self.max_disks = 16
 
     def get_disk_count(self):
         return self.disk_count
 
-    def set_disks_path(self,disk_path_list):
-        """Set the list of real filepath to disks or images"""
-        self.disk_paths = disk_path_list
-
-    def set_disk_count(self,new_disk_count):
-        """Update the number of attached disks on the fly"""
-        self.disk_count = min(new_disk_count,self.max_disks)
-        logging.info("MyDisks.set_disk_count(%d) : setting disk_count to %d" % (new_disk_count, self.disk_count))
-
-    def open_disks(self):
+    def open_disks(self, base_path, new_disk_count):
         """(re)open all disks"""
         logging.debug("Enter open_disks()")
         for fh in self.disks:
@@ -51,13 +40,16 @@ class MyDisks():
                 fh.close()
             except:
                 pass
-        self.disks = [ None for d in range(self.disk_count) ]
-        self.disks_size = [ 0 for d in range(self.disk_count) ]
 
-        for d in range(self.disk_count):
-            path = self.disk_paths[d]
+        self.disk_count = 0
+        self.disks = [ None for d in range(new_disk_count) ]
+        self.disks_size = [ 0 for d in range(new_disk_count) ]
+
+        for d in range(new_disk_count):
+            path = '%s/disk%02d.img'%(base_path,d)
             logging.debug("Try to open disk #%2d"%d)
             try:
+                # TODO : follow symlinks
                 fh = open(path, "rb")
                 self.disks_size[d] = os.lseek(fh.fileno(), 0, os.SEEK_END)
                 self.disks[d] = fh
@@ -70,6 +62,7 @@ class MyDisks():
                 logging.error("Can't open disk #%2d ('%s') : unhandled exception"%(d, path))
                 self.disks_size[d] = 0
                 logging.exception(e)
+            self.disk_count += 1
 
         logging.debug("Exit. open_disks()")
 
@@ -80,6 +73,7 @@ class MyDisks():
         #return random.randint(0,100) > 1 # FIXME : implement this (parse ddrescue log files)
 
     def read(self,disk_no,offset,size):
+        # XXX : Consider pread() ?
         self.disks[disk_no].seek(offset)
         return self.disks[disk_no].read(size)
 
diff --git a/raidguessfs.py b/raidguessfs.py
index bd256bf..5e8433a 100755
--- a/raidguessfs.py
+++ b/raidguessfs.py
@@ -144,8 +144,7 @@ class RaidGuessFS(fuse.Fuse):
 
     def update_disk_count(self,arg):
         i = self._aton(arg)
-        self.d.set_disk_count(i)
-        self.d.open_disks()
+        self.d.open_disks(getattr(self.parser.values,'source_path'), i)
         self._refresh_disk_dentries()
         self.raid.set_raid_end(min(self.d.disks_size)-1)
         self.update_raid_disk_order(range(i))
@@ -240,8 +239,7 @@ class RaidGuessFS(fuse.Fuse):
                 '/raid/%s'%s: self.st.make_fake_file(0) for s in ['disk_parity', 'disk_xor', 'raid_result']
             })
 
-            self.d.set_disks_path([getattr(self.parser.values,'disk%02d'%d) for d in range(self.d.max_disks)])
-            self.update_disk_count(len(self.d.disk_paths))
+            self.update_disk_count(getattr(self.parser.values,'disk_count'))
 
             self._refresh_disk_dentries()
             self._refresh_raid_fattr()
@@ -364,28 +362,24 @@ RaidGuessFS is a pseudo-filesystem that allows to guess parameters and disk orde
     fuse.fuse_python_api = (0, 2)
 
     LOG_FILENAME = "/tmp/raidguessfs.log"
-    #logging.basicConfig(filename=LOG_FILENAME,level=logging.WARN,)
-    #logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO,)
-    logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,)
-
-    server = RaidGuessFS(version="%prog " + fuse.__version__,usage=usage,dash_s_do='setsingle')
-    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,
-                metavar="ABS_PATH",
-                default="%s/disk%02d.img"%(cwd,num),
-                help="Disk #%d image file path [default: ./disk%02d.img]"%(num,num)
-        )
-        server.parser.add_option(
-                mountopt="logf%02d"%num,
-                metavar="ABS_PATH",
-                default="%s/disk%02d.log"%(cwd,num),
-                help="Disk #%d ddrescue log file [default: ./disk%02d.log]"%(num,num)
-        )
+    logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)  # WARN, INFO...
+
+    server = RaidGuessFS(version="%prog " + fuse.__version__, usage=usage, dash_s_do='setsingle')
+    server.multithreaded = False # Many part of the code is not re-entrant
+
+    server.parser.add_option(
+        mountopt="source_path",
+        metavar="PATH",
+        default="%s"%os.getcwd(),
+        help="Absolute path that contains source disks images (defaults to current dir)"
+    )
+
+    server.parser.add_option(
+        mountopt="disk_count",
+        metavar="N",
+        default="3",
+        help="Number of disks to try to open at mount time (also tunable at runtime)"
+    )
 
     server.parse(errex=1)
     server.main()
-- 
cgit v1.2.3