From 5d99eea1a574ad4030d66ae9448ad02c523d2adf Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 30 Aug 2015 16:29:46 +0200 Subject: myraid : extract the math part in a separate file, make it re-usable --- myraidmaths.py | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 myraidmaths.py (limited to 'myraidmaths.py') diff --git a/myraidmaths.py b/myraidmaths.py new file mode 100644 index 0000000..c0d3b8b --- /dev/null +++ b/myraidmaths.py @@ -0,0 +1,139 @@ +#!/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 numpy + +class MyRaidMaths(): + """Auxiliary class, managing RAID layer, mathematics algorithms""" + + @staticmethod + def xor_blocks(fd_list, offset, size): + """Compute bitwise XOR against a bunch of disks slice""" + logging.info("Enter xor_blocks(fd_list(%i),0x%011x,%d)"%(len(fd_list), offset, size)) + + if size % 8 != 0: + raise ValueError('xor_blocks : size must be multiple of 8') + dt = numpy.dtype('= par_disk: + data_disk = data_disk + 1 + + off_disk = raid_start + stripe_no * raid_chunk_size + segment_off + # Note : could make error-free shorter reads than asked but convince the reader to be chunck aligned, which is great for perf + aligned_read_size = min(wanted_read_size, (segment_no+1) * raid_chunk_size - wanted_raid_offset) + + elif raid_type == '5+0': + subraid_disk_count = raid_disk_count / nested_subraid + segment_no = wanted_raid_offset / raid_chunk_size + segment_off = wanted_raid_offset % raid_chunk_size + stripe_no = segment_no / (raid_disk_count - nested_subraid) + subraid_no = (segment_no / (subraid_disk_count-1) ) % nested_subraid + + if raid_layout in ['ls','la']: + subraid_par_disk = (subraid_disk_count-1) - (stripe_no % subraid_disk_count) + else: # raid_layout in ['rs','ra']: + subraid_par_disk = stripe_no % subraid_disk_count + + if raid_layout in ['ls','rs']: + subraid_data_disk = (subraid_par_disk+1 + (segment_no % (subraid_disk_count-1)) ) % subraid_disk_count + else: # raid_layout in ['la','ra']: + subraid_data_disk = segment_no % (subraid_disk_count-1) + if subraid_data_disk >= subraid_par_disk: + subraid_data_disk = subraid_data_disk + 1 + + par_disk = subraid_no * subraid_disk_count + subraid_par_disk + data_disk = subraid_no * subraid_disk_count + subraid_data_disk + + off_disk = raid_start + stripe_no * raid_chunk_size + segment_off + # Note : could make error-free shorter reads than asked but convince the reader to be chunck aligned, which is great for perf + aligned_read_size = min(wanted_read_size, (segment_no+1) * raid_chunk_size - wanted_raid_offset) + + return (segment_no, segment_off, stripe_no, subraid_no, par_disk, data_disk, off_disk, aligned_read_size) -- cgit v1.2.3