3 # geninitrd mod: dm-multipath
4 USE_MULTIPATH=${USE_MULTIPATH:-yes}
6 # if we should init dm-multipath at boot
9 # dm-multipath wwid which is used for rootfs
12 # setup geninitrd module
14 setup_mod_multipath() {
15 if [ ! -x /sbin/multipath ]; then
20 # return true if node is multipath controlled
21 # @param string $node device node to be examined
27 if is_no "$USE_MULTIPATH"; then
31 # multipath nodes are under device mapper
32 if [[ "$devpath" != /dev/mapper/* ]]; then
37 eval $(dm_export "$devpath")
38 if [ -z "$DM_NAME" ]; then
39 die "Couldn't extract DM_NAME from $devpath"
42 local MPATH_WWID=${DM_UUID##*-}
44 # just check if it is valid.
45 local info=$(multipath -l $MPATH_WWID)
46 if [ -z "$info" ]; then
53 # find modules for $devpath
54 # @param $devpath device to be examined
56 # find dm-multipath modules for $devpath
57 # returns false if $devpath is not dm-multipath
58 find_modules_multipath() {
62 eval $(dm_export "$devpath")
63 if [ -z "$DM_NAME" ]; then
64 die "Couldn't extract DM_NAME from $devpath"
69 # DM_UUID=part1-mpath-36006016002c11800a0aa05fbfae0db11
72 # DM_UUID=mpath-36006016002c11800a0aa05fbfae0db11
73 MPATH_WWID=${DM_UUID##*-}
75 local info=$(multipath -l $MPATH_WWID)
76 if [ -z "$info" ]; then
80 debug "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
84 list=$(mp_parse_devs "$info")
86 find_modules_for_devpath $p
87 lvm_ignore_devices="$lvm_ignore_devices $p"
90 list=$(mp_parse_hwhandler "$info")
95 list=$(mp_parse_policy "$info")
104 # generate initrd fragment
106 initrd_gen_multipath() {
107 inst_d /sbin /lib/udev /etc/multipath
108 inst_exec /sbin/kpartx /sbin
109 inst_exec /sbin/multipath /sbin
112 local scsi_id=$(find_tool /$_lib/udev/scsi_id /lib/udev/scsi_id /sbin/scsi_id)
113 inst_exec $scsi_id /lib/udev
115 if [ -d /$_lib/multipath ]; then
116 inst_d /$_lib/multipath
117 inst_exec /$_lib/multipath/* /$_lib/multipath
119 inst_exec /sbin/mpath* /sbin
122 egrep -v '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
124 if [ -f /etc/multipath/bindings ]; then
125 egrep -v '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
127 touch $DESTDIR/etc/multipath/bindings
134 echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
136 # parse mpath_wwid= from kernel commandline
137 for arg in $CMDLINE; do
138 if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
139 MPATH_WWID=${arg##mpath_wwid=}
140 if [ "$MPATH_WWID" = "*" ]; then
141 # '*' would mean activate all WWID-s
143 echo "multipath: Activating all WWID-s"
145 echo "multipath: Activating WWID=$WWID"
151 /sbin/multipath -v 0 $MPATH_WWID
153 for a in /dev/mapper/*; do
154 [ $a = /dev/mapper/control ] && continue
155 /sbin/kpartx -a -p p $a
163 # export info from dmsetup
167 # - /dev/mapper/DM_NAME
173 local maj=${arg%:*} min=${arg#*:}
174 dmsetup -j $maj -m $min export
177 local min=${arg#*dm-}
178 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
182 local dm_name=${arg#/dev/mapper/}
183 dmsetup export $dm_name
186 die "dm_export: unexpected $arg"
191 # parse blockdevices behind multipath device
192 # takes 'multipath -l' output as input
196 # parse "0:0:1:0 sdf" -> /dev/sdf
198 # multipath-tools-0.4.8-0.12.amd64
199 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
200 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
201 # \_ round-robin 0 [prio=0][active]
202 # \_ 0:0:0:0 sda 8:0 [active][undef]
203 # \_ round-robin 0 [prio=0][enabled]
204 # \_ 0:0:1:0 sdf 8:80 [active][undef]
206 # multipath-tools-0.4.8-9.x86_64
207 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
208 # size=7.0G features='0' hwhandler='0' wp=rw
209 # |-+- policy='round-robin 0' prio=-1 status=enabled
210 # | `- #:#:#:# sde 8:64 failed undef running
211 # `-+- policy='round-robin 0' prio=-1 status=active
212 # `- #:#:#:# sdb 8:16 active undef running
214 echo "$info" | awk '{
215 if (match($0, /[#0-9]+:[#0-9]+:[#0-9]+:[#0-9]+ [^ ]+ [0-9]+:[0-9]/)) {
216 # take whole matched part into "l" variable
217 l = substr($0, RSTART, RLENGTH);
219 printf("/dev/%s\n", a[2])
224 # parse policy output for each device
225 # takes 'multipath -l' output as input
229 # multipath-tools-0.4.8-0.12.amd64
230 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
231 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
232 # \_ round-robin 0 [prio=0][active]
233 # \_ 0:0:0:0 sda 8:0 [active][undef]
234 # \_ round-robin 0 [prio=0][enabled]
235 # \_ 0:0:1:0 sdf 8:80 [active][undef]
237 # multipath-tools-0.4.8-9.x86_64
238 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
239 # size=7.0G features='0' hwhandler='0' wp=rw
240 # |-+- policy='round-robin 0' prio=-1 status=enabled
241 # | `- #:#:#:# sde 8:64 failed undef running
242 # `-+- policy='round-robin 0' prio=-1 status=active
243 # `- #:#:#:# sdb 8:16 active undef running
246 # multipath-tools-0.4.8-0.12.amd64
250 # multipath-tools-0.4.8-9.x86_64
252 if (match($0, /policy=[^ ]+/)) {
253 # take whole matched part into "l" variable
254 l = substr($0, RSTART, RLENGTH);
255 # remove policy= and single quote,
256 # which we can not use in this awk inline script, therefore the %c hack
257 sub(sprintf("^policy=%c?", 39), "", l);
264 # parse hwhandler from multipath output
265 # takes 'multipath -l' output as input
266 mp_parse_hwhandler() {
269 # TODO: actually the dm-emc vs scsi-dh-emc is dependant on kernel version
270 # not version of the tools installed
272 # multipath-tools-0.4.8-0.12.amd64
273 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
275 # multipath-tools-0.4.8-11.x86_64
276 # size=7.0G features='0' hwhandler='0' wp=rw
277 # size=2.0G features='1 queue_if_no_path' hwhandler='1 emc' wp=rw
278 echo "$info" | sed -ne "
279 # multipath-tools-0.4.8-0.12.amd64
281 s,^.*\[hwhandler=1 \([^]]*\)\].*$,dm-\1,
284 # multipath-tools-0.4.8-11.x86_64
286 s,^.*hwhandler='1 \([^']*\)'.*$,scsi-dh-\1,