whitespace cleanup
[mapsector.git] / lib / 10_map_raid.sh
1 detect_raid()
2 {
3     which mdadm >/dev/null 2>&1 && mdadm -Q $device | grep -qF -- "--examine"
4 }
5
6 describe_raid()
7 {
8     echo "    RAID level 1/5"
9 }
10
11 do_raid()
12 {
13     local mddevice
14     local mdlevel
15     local mdlayout
16
17     echo "# $device: RAID detected" 1>&2
18
19     mddevice="`mdadm -Q $device | sed -ne 's/.*\(raid[0-9] \/dev\/[^.]*\).*/\1/' -eT -ep`"
20
21     if [ -z "$mddevice" ]; then
22         echo "! raid master device for raid componentn device $device not found" 1>&2
23         exit 1
24     fi
25
26     mdlevel="${mddevice% *}"
27     mddevice="${mddevice#* }"
28
29     echo "device $mddevice md"
30     echo "raidlevel $mdlevel"
31
32     case "$mdlevel" in
33         raid1) ;;
34         raid5) do_raid_raid5 $mddevice ;;
35         *)
36             echo "! unsopported raid level $mdlevel" 1>&2
37             exit 1
38             ;;
39     esac
40
41     echo "sector $sector"
42     device="$mddevice"
43
44     return 1
45 }
46
47 raid5_leftsymmetric_calc()
48 {
49     local ndrives="$1"
50     local drive="$2" # range 0..$ndrives-1
51     local chunk="$3"
52
53     # Algorithm:
54     #
55     # block = chunk / ndrives
56     # blockrow = chunk % ndrives
57     # if blockrow == ndrives-drive-1:
58     #     return 'parity'
59     # else:
60     #     if drive > ndrives-blockrow-1:
61     #         blockrow = blockrow - 1
62     #     return block*ndrives*(ndrives-1) + blockrow*ndrives + drive
63
64     dc  -e "$chunk $ndrives ~ d $ndrives $drive - 1 - [q]sa=a" \
65         -e "d $ndrives r - 1 - $drive [1-]sa<a" \
66         -e "$ndrives * $drive + r $ndrives * $ndrives 1 - * + p"
67 }
68
69 do_raid_raid5()
70 {
71     local mddevice="$1"
72     local mdlayout
73     local mdcalc
74     local mdchunksize
75     local mddrives
76     local mddrive
77     local chunk
78     local mdchunk
79
80     mdlayout="`mdadm -D $mddevice | awk '/Layout :/{print $3}'`"
81     echo "raidlayout $mdlayout"
82     case "$mdlayout" in
83         left-symmetric) mdcalc="raid5_leftsymmetric_calc" ;;
84         *)
85             echo "! unsopported raid layout $mdlayout" 1>&2
86             exit 1
87             ;;
88     esac
89
90     mdchunksize="`mdadm -D $mddevice | awk '/Chunk Size :/{print $4}'`"
91     mdchunksize="`dc -e "${mdchunksize%K} 2 * p"`"
92     mddrives="`mdadm -D $mddevice | awk '/Raid Devices :/{print $4}'`"
93     mddrive="`mdadm -D $mddevice | awk "/${device##*/}"'$/{print $4}'`"
94
95     echo "raiddrives $mddrives"
96     echo "raiddrive $mddrive"
97     echo "chunksize $mdchunksize"
98
99     chunk="`dc -e "$sector $mdchunksize ~ n [ ] n p"`"
100     subsector="${chunk% *}"
101     chunk="${chunk#* }"
102
103     echo "chunk $chunk"
104     echo "subsector $subsector"
105
106     mdchunk="`$mdcalc $mddrives $mddrive $chunk`"
107     if [ -z "$mdchunk" ]; then
108         echo "chunktype parity"
109         echo "! no parity chunk support"
110         exit 1
111     fi
112
113     echo "chunktype data"
114     echo "raidchunk $mdchunk"
115
116     sector="`dc -e "$mdchunk $mdchunksize * $subsector + p"`"
117 }
118
119 register_mapper "raid"