describe_raid()
{
- echo " RAID level 1"
+ echo " RAID level 1/5"
}
do_raid()
{
local mddevice
local mdlevel
+ local mdlayout
echo "# $device: RAID detected" 1>&2
mddevice="`mdadm -Q $device | sed -ne 's/.*\(raid[0-9] \/dev\/[^.]*\).*/\1/' -eT -ep`"
if [ -z "$mddevice" ]; then
- echo "! raid master device for raid componentn device $device not found" 1>&2
- exit 1
+ echo "! raid master device for raid componentn device $device not found" 1>&2
+ exit 1
fi
mdlevel="${mddevice% *}"
mddevice="${mddevice#* }"
-
+
echo "device $mddevice md"
echo "raidlevel $mdlevel"
- echo "sector $sector"
+ case "$mdlevel" in
+ raid1) ;;
+ raid5) do_raid_raid5 $mddevice ;;
+ *)
+ echo "! unsopported raid level $mdlevel" 1>&2
+ exit 1
+ ;;
+ esac
+
+ echo "sector $sector"
device="$mddevice"
return 1
}
+raid5_leftsymmetric_calc()
+{
+ local ndrives="$1"
+ local drive="$2" # range 0..$ndrives-1
+ local chunk="$3"
+
+ # Algorithm:
+ #
+ # block = chunk / ndrives
+ # blockrow = chunk % ndrives
+ # if blockrow == ndrives-drive-1:
+ # return 'parity'
+ # else:
+ # if drive > ndrives-blockrow-1:
+ # blockrow = blockrow - 1
+ # return block*ndrives*(ndrives-1) + blockrow*ndrives + drive
+
+ dc -e "$chunk $ndrives ~ d $ndrives $drive - 1 - [q]sa=a" \
+ -e "d $ndrives r - 1 - $drive [1-]sa<a" \
+ -e "$ndrives * $drive + r $ndrives * $ndrives 1 - * + p"
+}
+
+do_raid_raid5()
+{
+ local mddevice="$1"
+ local mdlayout
+ local mdcalc
+ local mdchunksize
+ local mddrives
+ local mddrive
+ local chunk
+ local mdchunk
+
+ mdlayout="`mdadm -D $mddevice | awk '/Layout :/{print $3}'`"
+ echo "raidlayout $mdlayout"
+ case "$mdlayout" in
+ left-symmetric) mdcalc="raid5_leftsymmetric_calc" ;;
+ *)
+ echo "! unsopported raid layout $mdlayout" 1>&2
+ exit 1
+ ;;
+ esac
+
+ mdchunksize="`mdadm -D $mddevice | awk '/Chunk Size :/{print $4}'`"
+ mdchunksize="`dc -e "${mdchunksize%K} 2 * p"`"
+ mddrives="`mdadm -D $mddevice | awk '/Raid Devices :/{print $4}'`"
+ mddrive="`mdadm -D $mddevice | awk "/${device##*/}"'$/{print $4}'`"
+
+ echo "raiddrives $mddrives"
+ echo "raiddrive $mddrive"
+ echo "chunksize $mdchunksize"
+
+ chunk="`dc -e "$sector $mdchunksize ~ n [ ] n p"`"
+ subsector="${chunk% *}"
+ chunk="${chunk#* }"
+
+ echo "chunk $chunk"
+ echo "subsector $subsector"
+
+ mdchunk="`$mdcalc $mddrives $mddrive $chunk`"
+ if [ -z "$mdchunk" ]; then
+ echo "chunktype parity"
+ echo "! no parity chunk support"
+ exit 1
+ fi
+
+ echo "chunktype data"
+ echo "raidchunk $mdchunk"
+
+ sector="`dc -e "$mdchunk $mdchunksize * $subsector + p"`"
+}
+
register_mapper "raid"