]>
Commit | Line | Data |
---|---|---|
c3b54060 | 1 | #!/bin/sh |
c3b54060 | 2 | # geninitrd mod: dm-multipath |
6e49b0b1 | 3 | USE_MULTIPATH=${USE_MULTIPATH:-yes} |
c3b54060 ER |
4 | |
5 | # if we should init dm-multipath at boot | |
6 | have_multipath=no | |
7 | ||
c3b54060 ER |
8 | # dm-multipath wwid which is used for rootfs |
9 | MPATH_WWID= | |
10 | ||
c124d0cf ER |
11 | # setup geninitrd module |
12 | # @access public | |
13 | setup_mod_multipath() { | |
6e49b0b1 | 14 | if [ ! -x /sbin/multipath ]; then |
c124d0cf ER |
15 | USE_MULTIPATH=no |
16 | fi | |
17 | } | |
18 | ||
c3b54060 ER |
19 | # return true if node is multipath controlled |
20 | # @param string $node device node to be examined | |
21 | # @access public | |
22 | is_multipath() { | |
23 | local devpath="$1" | |
24 | ||
25 | # multipath disabled | |
ecd7bf46 | 26 | if is_no "$USE_MULTIPATH"; then |
c3b54060 ER |
27 | return 1 |
28 | fi | |
29 | ||
30 | # multipath nodes are under device mapper | |
31 | if [[ "$devpath" != /dev/mapper/* ]]; then | |
32 | return 1 | |
33 | fi | |
34 | ||
35 | DM_NAME= | |
36 | eval $(dm_export "$devpath") | |
37 | if [ -z "$DM_NAME" ]; then | |
5d51e3e9 | 38 | die "Couldn't extract DM_NAME from $devpath" |
c3b54060 ER |
39 | fi |
40 | ||
41 | local MPATH_WWID=${DM_UUID##*-} | |
e2c75552 ER |
42 | |
43 | # just check if it is valid. | |
c3b54060 ER |
44 | local info=$(multipath -l $MPATH_WWID) |
45 | if [ -z "$info" ]; then | |
46 | return 1 | |
47 | fi | |
48 | ||
49 | return 0 | |
50 | } | |
51 | ||
52 | # find modules for $devpath | |
53 | # @param $devpath device to be examined | |
54 | # @access public | |
55 | # find dm-multipath modules for $devpath | |
56 | # returns false if $devpath is not dm-multipath | |
57 | find_modules_multipath() { | |
58 | local devpath="$1" | |
59 | ||
60 | DM_NAME= | |
61 | eval $(dm_export "$devpath") | |
62 | if [ -z "$DM_NAME" ]; then | |
ecd7bf46 | 63 | die "Couldn't extract DM_NAME from $devpath" |
c3b54060 ER |
64 | fi |
65 | ||
66 | # Partition: | |
67 | # DM_NAME=LUN-28p1 | |
68 | # DM_UUID=part1-mpath-36006016002c11800a0aa05fbfae0db11 | |
69 | # Disk: | |
70 | # DM_NAME=LUN-28 | |
71 | # DM_UUID=mpath-36006016002c11800a0aa05fbfae0db11 | |
72 | MPATH_WWID=${DM_UUID##*-} | |
73 | ||
74 | local info=$(multipath -l $MPATH_WWID) | |
75 | if [ -z "$info" ]; then | |
76 | return 1 | |
77 | fi | |
78 | ||
02ba8ab7 | 79 | verbose "Finding modules for dm-multipath (WWID=$MPATH_WWID)" |
c3b54060 | 80 | have_multipath=yes |
e2c75552 ER |
81 | |
82 | local p list | |
83 | list=$(mp_parse_devs "$info") | |
84 | for p in $list; do | |
85 | find_modules_for_devpath $p | |
86 | lvm_ignore_devices="$lvm_ignore_devices $p" | |
c3b54060 ER |
87 | done |
88 | ||
ddc299f5 | 89 | list=$(mp_parse_hwhandler "$info") |
e2c75552 | 90 | for p in $list; do |
ddc299f5 | 91 | find_module "$p" |
c3b54060 ER |
92 | done |
93 | ||
e2c75552 ER |
94 | list=$(mp_parse_policy "$info") |
95 | for p in $list; do | |
96 | find_module "dm-$p" | |
c3b54060 ER |
97 | done |
98 | ||
b02a6b13 | 99 | find_module "dm-mod" |
c3b54060 ER |
100 | return 0 |
101 | } | |
102 | ||
103 | # generate initrd fragment | |
104 | # @access public | |
105 | initrd_gen_multipath() { | |
1b481849 ER |
106 | if ! is_yes "$have_multipath"; then |
107 | return | |
108 | fi | |
109 | ||
c3b54060 ER |
110 | inst_d /sbin /lib/udev /etc/multipath |
111 | inst_exec /sbin/kpartx /sbin | |
112 | inst_exec /sbin/multipath /sbin | |
113 | ||
114 | # for udev callouts | |
54c9f5ee | 115 | local scsi_id=$(find_tool $(get_libdir /LIBDIR/udev/scsi_id) /lib/udev/scsi_id /sbin/scsi_id) |
e2c75552 ER |
116 | inst_exec $scsi_id /lib/udev |
117 | ||
54c9f5ee AM |
118 | local installed=0 |
119 | for _lib in $(get_libdir LIBDIR); do | |
120 | if [ -d /$_lib/multipath ]; then | |
121 | inst_d /$_lib/multipath | |
122 | inst_exec /$_lib/multipath/* /$_lib/multipath | |
123 | installed=1 | |
91e0b060 | 124 | break |
54c9f5ee AM |
125 | fi |
126 | done | |
127 | if [ "$installed" -eq 0 ]; then | |
e2c75552 ER |
128 | inst_exec /sbin/mpath* /sbin |
129 | fi | |
130 | ||
e871f497 | 131 | grep -Ev '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf |
c3b54060 ER |
132 | |
133 | if [ -f /etc/multipath/bindings ]; then | |
e871f497 | 134 | grep -Ev '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings |
c3b54060 ER |
135 | else |
136 | touch $DESTDIR/etc/multipath/bindings | |
137 | fi | |
138 | ||
139 | mount_dev | |
140 | initrd_gen_devices | |
141 | ||
142 | mount_sys | |
143 | echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc | |
144 | add_linuxrc <<-'EOF' | |
145 | # parse mpath_wwid= from kernel commandline | |
146 | for arg in $CMDLINE; do | |
147 | if [ "${arg##mpath_wwid=}" != "${arg}" ]; then | |
148 | MPATH_WWID=${arg##mpath_wwid=} | |
149 | if [ "$MPATH_WWID" = "*" ]; then | |
150 | # '*' would mean activate all WWID-s | |
151 | MPATH_WWID= | |
152 | echo "multipath: Activating all WWID-s" | |
153 | else | |
154 | echo "multipath: Activating WWID=$WWID" | |
155 | fi | |
156 | fi | |
157 | done | |
158 | ||
159 | debugshell | |
160 | /sbin/multipath -v 0 $MPATH_WWID | |
161 | ||
162 | for a in /dev/mapper/*; do | |
163 | [ $a = /dev/mapper/control ] && continue | |
164 | /sbin/kpartx -a -p p $a | |
165 | done | |
166 | debugshell | |
167 | EOF | |
168 | } | |
6ae2e4d0 ER |
169 | |
170 | ||
171 | # PRIVATE METHODS | |
172 | # export info from dmsetup | |
173 | # param can be: | |
174 | # - MAJOR:MINOR | |
175 | # - /dev/dm-MINOR | |
176 | # - /dev/mapper/DM_NAME | |
177 | dm_export() { | |
178 | local arg="$1" | |
179 | ||
180 | case "$arg" in | |
181 | *:*) | |
182 | local maj=${arg%:*} min=${arg#*:} | |
183 | dmsetup -j $maj -m $min export | |
184 | ;; | |
185 | /dev/dm-*) | |
186 | local min=${arg#*dm-} | |
187 | local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices) | |
188 | dm_export $maj:$min | |
189 | ;; | |
190 | /dev/mapper/*) | |
191 | local dm_name=${arg#/dev/mapper/} | |
192 | dmsetup export $dm_name | |
193 | ;; | |
194 | *) | |
195 | die "dm_export: unexpected $arg" | |
196 | ;; | |
197 | esac | |
198 | } | |
199 | ||
e2c75552 ER |
200 | # parse blockdevices behind multipath device |
201 | # takes 'multipath -l' output as input | |
202 | mp_parse_devs() { | |
203 | local info="$1" | |
204 | ||
205 | # parse "0:0:1:0 sdf" -> /dev/sdf | |
206 | # | |
207 | # multipath-tools-0.4.8-0.12.amd64 | |
208 | # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10 | |
209 | # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc] | |
210 | # \_ round-robin 0 [prio=0][active] | |
211 | # \_ 0:0:0:0 sda 8:0 [active][undef] | |
212 | # \_ round-robin 0 [prio=0][enabled] | |
213 | # \_ 0:0:1:0 sdf 8:80 [active][undef] | |
214 | # | |
215 | # multipath-tools-0.4.8-9.x86_64 | |
216 | # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 , | |
217 | # size=7.0G features='0' hwhandler='0' wp=rw | |
218 | # |-+- policy='round-robin 0' prio=-1 status=enabled | |
219 | # | `- #:#:#:# sde 8:64 failed undef running | |
220 | # `-+- policy='round-robin 0' prio=-1 status=active | |
221 | # `- #:#:#:# sdb 8:16 active undef running | |
222 | ||
223 | echo "$info" | awk '{ | |
224 | if (match($0, /[#0-9]+:[#0-9]+:[#0-9]+:[#0-9]+ [^ ]+ [0-9]+:[0-9]/)) { | |
225 | # take whole matched part into "l" variable | |
226 | l = substr($0, RSTART, RLENGTH); | |
227 | split(l, a, " "); | |
228 | printf("/dev/%s\n", a[2]) | |
229 | } | |
230 | }' | |
231 | } | |
232 | ||
233 | # parse policy output for each device | |
234 | # takes 'multipath -l' output as input | |
235 | mp_parse_policy() { | |
236 | local info="$1" | |
237 | ||
238 | # multipath-tools-0.4.8-0.12.amd64 | |
239 | # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10 | |
240 | # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc] | |
241 | # \_ round-robin 0 [prio=0][active] | |
242 | # \_ 0:0:0:0 sda 8:0 [active][undef] | |
243 | # \_ round-robin 0 [prio=0][enabled] | |
244 | # \_ 0:0:1:0 sdf 8:80 [active][undef] | |
245 | # | |
246 | # multipath-tools-0.4.8-9.x86_64 | |
247 | # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 , | |
248 | # size=7.0G features='0' hwhandler='0' wp=rw | |
249 | # |-+- policy='round-robin 0' prio=-1 status=enabled | |
250 | # | `- #:#:#:# sde 8:64 failed undef running | |
251 | # `-+- policy='round-robin 0' prio=-1 status=active | |
252 | # `- #:#:#:# sdb 8:16 active undef running | |
253 | ||
254 | echo "$info" | awk ' | |
255 | # multipath-tools-0.4.8-0.12.amd64 | |
256 | /\[prio=/{ | |
257 | print $2 | |
258 | } | |
259 | # multipath-tools-0.4.8-9.x86_64 | |
260 | /policy=/{ | |
261 | if (match($0, /policy=[^ ]+/)) { | |
262 | # take whole matched part into "l" variable | |
263 | l = substr($0, RSTART, RLENGTH); | |
264 | # remove policy= and single quote, | |
265 | # which we can not use in this awk inline script, therefore the %c hack | |
266 | sub(sprintf("^policy=%c?", 39), "", l); | |
267 | print l | |
268 | } | |
269 | } | |
270 | ' | sort -u | |
271 | } | |
ddc299f5 ER |
272 | |
273 | # parse hwhandler from multipath output | |
274 | # takes 'multipath -l' output as input | |
275 | mp_parse_hwhandler() { | |
276 | local info="$1" | |
277 | ||
278 | # TODO: actually the dm-emc vs scsi-dh-emc is dependant on kernel version | |
279 | # not version of the tools installed | |
280 | ||
281 | # multipath-tools-0.4.8-0.12.amd64 | |
282 | # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc] | |
283 | # | |
284 | # multipath-tools-0.4.8-11.x86_64 | |
285 | # size=7.0G features='0' hwhandler='0' wp=rw | |
286 | # size=2.0G features='1 queue_if_no_path' hwhandler='1 emc' wp=rw | |
287 | echo "$info" | sed -ne " | |
9802850b ER |
288 | # multipath-tools-0.4.8-0.12.amd64 |
289 | /\[hwhandler=1/{ | |
290 | s,^.*\[hwhandler=1 \([^]]*\)\].*$,dm-\1, | |
291 | p | |
292 | } | |
ddc299f5 | 293 | # multipath-tools-0.4.8-11.x86_64 |
9802850b ER |
294 | /hwhandler='1/{ |
295 | s,^.*hwhandler='1 \([^']*\)'.*$,scsi-dh-\1, | |
296 | p | |
297 | } | |
298 | " | sort -u | |
ddc299f5 | 299 | } |