]> git.pld-linux.org Git - projects/geninitrd.git/blame - mod-multipath.sh
Timeout here is not a good idea. rootfs cannot be mounted and kernel oopses due to...
[projects/geninitrd.git] / mod-multipath.sh
CommitLineData
c3b54060 1#!/bin/sh
c3b54060 2# geninitrd mod: dm-multipath
6e49b0b1 3USE_MULTIPATH=${USE_MULTIPATH:-yes}
c3b54060
ER
4
5# if we should init dm-multipath at boot
6have_multipath=no
7
c3b54060
ER
8# dm-multipath wwid which is used for rootfs
9MPATH_WWID=
10
c124d0cf
ER
11# setup geninitrd module
12# @access public
13setup_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
22is_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
57find_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
105initrd_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
177dm_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
202mp_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
235mp_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
275mp_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}
This page took 1.016786 seconds and 4 git commands to generate.