From c0a4cd0c626f5d91c9c0f29799255bd20b2cac48 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 28 Jun 2015 18:32:04 +0200 Subject: New module to handle background / long tasks --- mytasks.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ raidguessfs.py | 54 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 mytasks.py diff --git a/mytasks.py b/mytasks.py new file mode 100644 index 0000000..6c03262 --- /dev/null +++ b/mytasks.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +# RaidGuessFS, a FUSE pseudo-filesystem to guess RAID parameters of a damaged device +# Copyright (C) 2015 Ludovic Pouzenc +# +# This file is part of RaidGuessFS. +# +# RaidGuessFS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# RaidGuessFS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with RaidGuessFS. If not, see + +import logging + +class MyTasks(): + """Auxiliary class, managing long or background tasks""" + + TASK_NAMES = [ 'find_bootsect', 'find_files' ] + + def __init__(self, *args, **kwargs): + self.tasks = [] + self.find_files_pathlist = [] + + def get_task_start(self): + return 'Write a task_name in this pseudo-file to start it\n' + + def get_task_kill(self): + return 'Write a task_name in this pseudo-file to kill it\n' + + def get_find_files_pathlist(self): + return self.find_files_pathlist + + def get_find_files_pathlist_str(self): + return '\n'.join(self.find_files_pathlist) + + def set_task_start(self, task_name): + raise Exception('Not yet implemented') + + def set_task_kill(self, task_name): + raise Exception('Not yet implemented') + + def set_find_files_pathlist(self, new_find_files_pathlist): + self.find_files_pathlist = new_find_files_pathlist + + def read_find_bootsect(self): + return 'This task is not started\n' + + def read_find_files(self): + return 'This task is not started\n' + diff --git a/raidguessfs.py b/raidguessfs.py index 807a2be..ac56278 100755 --- a/raidguessfs.py +++ b/raidguessfs.py @@ -33,7 +33,7 @@ # Standard modules import sys, os, errno, logging, re, fuse # Custom modules -import mystat, mydisks, mybinview, myraid +import mystat, mydisks, mybinview, myraid, mytasks if not hasattr(fuse, '__version__'): raise RuntimeError, \ @@ -53,6 +53,7 @@ class RaidGuessFS(fuse.Fuse): self.raid = myraid.MyRaid() self.bmp = mybinview.MyBinView() self.st = mystat.MyStat() + self.tasks = mytasks.MyTasks() self.bmp.refresh_bmp() @@ -61,29 +62,33 @@ class RaidGuessFS(fuse.Fuse): self.settings = [ 'disk_count', - 'raid_start', 'raid_end', 'raid_chunk_size', 'raid_disk_order', - 'raid_layout', - 'bmp_height', 'bmp_width', 'bmp_start_offset' + 'raid_start', 'raid_end', 'raid_chunk_size', + 'raid_disk_order', 'raid_layout', + 'bmp_height', 'bmp_width', 'bmp_start_offset', + 'task_start', 'task_kill', 'task_find_files_pathlist' ] self.settings_getters = [ self.d.get_disk_count, - self.raid.get_raid_start, self.raid.get_raid_end, self.raid.get_raid_chunk_size, self.raid.get_raid_disk_order_str, - self.raid.get_raid_layout, - self.bmp.get_bmp_height, self.bmp.get_bmp_width, self.bmp.get_bmp_start_offset + self.raid.get_raid_start, self.raid.get_raid_end, self.raid.get_raid_chunk_size, + self.raid.get_raid_disk_order_str, self.raid.get_raid_layout, + self.bmp.get_bmp_height, self.bmp.get_bmp_width, self.bmp.get_bmp_start_offset, + self.tasks.get_task_start, self.tasks.get_task_kill, self.tasks.get_find_files_pathlist_str, ] self.settings_updaters = [ self.update_disk_count, self.update_raid_start, self.update_raid_end, self.update_raid_chunk_size, self.update_raid_disk_order, self.raid.set_raid_layout, - self.update_bmp_height, self.update_bmp_width, self.update_bmp_start_offset + self.update_bmp_height, self.update_bmp_width, self.update_bmp_start_offset, + self.tasks.set_task_start, self.tasks.set_task_kill, self.update_task_find_files_pathlist, ] self.dentries = { - '/' : [ fuse.Direntry(name) for name in ['config','disk','raid','visual'] ], + '/' : [ fuse.Direntry(name) for name in ['config','disk','raid','tasks','visual'] ], '/config': [ fuse.Direntry(name) for name in self.settings ], '/raid' : [ fuse.Direntry(name) for name in myraid.MyRaid.RAID_TYPES ], + '/tasks' : [ fuse.Direntry(name) for name in self.tasks.TASK_NAMES ], '/disk' : [ ], # Filled in _refresh_disk_dentries() '/visual': [ ], # Filled in _refresh_disk_dentries() } @@ -193,13 +198,22 @@ class RaidGuessFS(fuse.Fuse): 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) self._refresh_raid_fattr() logging.debug("Exit. update_raid_disk_order(%s)"%arg) + def update_task_find_files_pathlist(self, arg): + logging.debug("Enter update_task_find_files_pathlist(%s)"%arg) + if type(arg) is str: + l = arg.split() + elif type(arg) is list: + l = arg + else: + raise TypeError('update_task_find_files_pathlist() wants a list or str') + + # FIXME : write() is usually called after each end line, so the previous path are destroyed + self.tasks.set_find_files_pathlist(l) + logging.debug("Exit. update_task_find_files_pathlist(%s)"%arg) ######################################################## # Actual File System operations implementation follows # @@ -216,8 +230,13 @@ class RaidGuessFS(fuse.Fuse): path: self.st.make_fake_dir() for path in self.dentries.keys() } self.fattr = { - '/config/%s'%s: self.st.make_fake_file(64,0666) for s in self.settings - } + '/config/%s'%s: self.st.make_fake_file(64,0666) for s in self.settings + } + + self.fattr.update( { + '/tasks/%s'%s: self.st.make_fake_file(512) for s in self.tasks.TASK_NAMES + }) + for raid_type in myraid.MyRaid.RAID_TYPES: self.fattr.update( { '/raid/%s/disk_parity'%raid_type: self.st.make_fake_file(0), @@ -225,6 +244,7 @@ class RaidGuessFS(fuse.Fuse): '/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)]) self.update_disk_count(len(self.d.disk_paths)) @@ -297,6 +317,12 @@ class RaidGuessFS(fuse.Fuse): if path_chuncks[4] == 'raid_result': return self.raid.read_raid_result(raid_type,offset,size) + if path_chuncks[0] == 'tasks': + if path_chuncks[1] == 'find_bootsect': + return self.tasks.read_find_bootsect()[offset:offset+size] + if path_chuncks[1] == 'find_files': + return self.tasks.read_find_files()[offset:offset+size] + except Exception as e: logging.exception(e) return -errno.ENOENT -- cgit v1.2.3