2 MULTIPATH_RCSID='$Revision$ $Date:: $'
4 # geninitrd mod: dm-multipath
5 USE_MULTIPATH=${USE_MULTIPATH:-yes}
7 # if we should init dm-multipath at boot
10 # dm-multipath wwid which is used for rootfs
13 # setup geninitrd module
15 setup_mod_multipath() {
16 if [ ! -x /sbin/multipath ]; then
21 # return true if node is multipath controlled
22 # @param string $node device node to be examined
28 if is_no "$USE_MULTIPATH"; then
32 # multipath nodes are under device mapper
33 if [[ "$devpath" != /dev/mapper/* ]]; then
38 eval $(dm_export "$devpath")
39 if [ -z "$DM_NAME" ]; then
40 die "Couldn't extract DM_NAME from $devpath"
43 local MPATH_WWID=${DM_UUID##*-}
45 # just check if it is valid.
46 local info=$(multipath -l $MPATH_WWID)
47 if [ -z "$info" ]; then
54 # find modules for $devpath
55 # @param $devpath device to be examined
57 # find dm-multipath modules for $devpath
58 # returns false if $devpath is not dm-multipath
59 find_modules_multipath() {
63 eval $(dm_export "$devpath")
64 if [ -z "$DM_NAME" ]; then
65 die "Couldn't extract DM_NAME from $devpath"
70 # DM_UUID=part1-mpath-36006016002c11800a0aa05fbfae0db11
73 # DM_UUID=mpath-36006016002c11800a0aa05fbfae0db11
74 MPATH_WWID=${DM_UUID##*-}
76 local info=$(multipath -l $MPATH_WWID)
77 if [ -z "$info" ]; then
81 verbose "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
85 list=$(mp_parse_devs "$info")
87 find_modules_for_devpath $p
88 lvm_ignore_devices="$lvm_ignore_devices $p"
91 list=$(mp_parse_hwhandler "$info")
96 list=$(mp_parse_policy "$info")
105 # generate initrd fragment
107 initrd_gen_multipath() {
108 if ! is_yes "$have_multipath"; then
112 inst_d /sbin /lib/udev /etc/multipath
113 inst_exec /sbin/kpartx /sbin
114 inst_exec /sbin/multipath /sbin
117 local scsi_id=$(find_tool /$_lib/udev/scsi_id /lib/udev/scsi_id /sbin/scsi_id)
118 inst_exec $scsi_id /lib/udev
120 if [ -d /$_lib/multipath ]; then
121 inst_d /$_lib/multipath
122 inst_exec /$_lib/multipath/* /$_lib/multipath
124 inst_exec /sbin/mpath* /sbin
127 grep -Ev '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
129 if [ -f /etc/multipath/bindings ]; then
130 grep -Ev '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
132 touch $DESTDIR/etc/multipath/bindings
139 echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
141 # parse mpath_wwid= from kernel commandline
142 for arg in $CMDLINE; do
143 if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
144 MPATH_WWID=${arg##mpath_wwid=}
145 if [ "$MPATH_WWID" = "*" ]; then
146 # '*' would mean activate all WWID-s
148 echo "multipath: Activating all WWID-s"
150 echo "multipath: Activating WWID=$WWID"
156 /sbin/multipath -v 0 $MPATH_WWID
158 for a in /dev/mapper/*; do
159 [ $a = /dev/mapper/control ] && continue
160 /sbin/kpartx -a -p p $a
168 # export info from dmsetup
172 # - /dev/mapper/DM_NAME
178 local maj=${arg%:*} min=${arg#*:}
179 dmsetup -j $maj -m $min export
182 local min=${arg#*dm-}
183 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
187 local dm_name=${arg#/dev/mapper/}
188 dmsetup export $dm_name
191 die "dm_export: unexpected $arg"
196 # parse blockdevices behind multipath device
197 # takes 'multipath -l' output as input
201 # parse "0:0:1:0 sdf" -> /dev/sdf
203 # multipath-tools-0.4.8-0.12.amd64
204 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
205 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
206 # \_ round-robin 0 [prio=0][active]
207 # \_ 0:0:0:0 sda 8:0 [active][undef]
208 # \_ round-robin 0 [prio=0][enabled]
209 # \_ 0:0:1:0 sdf 8:80 [active][undef]
211 # multipath-tools-0.4.8-9.x86_64
212 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
213 # size=7.0G features='0' hwhandler='0' wp=rw
214 # |-+- policy='round-robin 0' prio=-1 status=enabled
215 # | `- #:#:#:# sde 8:64 failed undef running
216 # `-+- policy='round-robin 0' prio=-1 status=active
217 # `- #:#:#:# sdb 8:16 active undef running
219 echo "$info" | awk '{
220 if (match($0, /[#0-9]+:[#0-9]+:[#0-9]+:[#0-9]+ [^ ]+ [0-9]+:[0-9]/)) {
221 # take whole matched part into "l" variable
222 l = substr($0, RSTART, RLENGTH);
224 printf("/dev/%s\n", a[2])
229 # parse policy output for each device
230 # takes 'multipath -l' output as input
234 # multipath-tools-0.4.8-0.12.amd64
235 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
236 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
237 # \_ round-robin 0 [prio=0][active]
238 # \_ 0:0:0:0 sda 8:0 [active][undef]
239 # \_ round-robin 0 [prio=0][enabled]
240 # \_ 0:0:1:0 sdf 8:80 [active][undef]
242 # multipath-tools-0.4.8-9.x86_64
243 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
244 # size=7.0G features='0' hwhandler='0' wp=rw
245 # |-+- policy='round-robin 0' prio=-1 status=enabled
246 # | `- #:#:#:# sde 8:64 failed undef running
247 # `-+- policy='round-robin 0' prio=-1 status=active
248 # `- #:#:#:# sdb 8:16 active undef running
251 # multipath-tools-0.4.8-0.12.amd64
255 # multipath-tools-0.4.8-9.x86_64
257 if (match($0, /policy=[^ ]+/)) {
258 # take whole matched part into "l" variable
259 l = substr($0, RSTART, RLENGTH);
260 # remove policy= and single quote,
261 # which we can not use in this awk inline script, therefore the %c hack
262 sub(sprintf("^policy=%c?", 39), "", l);
269 # parse hwhandler from multipath output
270 # takes 'multipath -l' output as input
271 mp_parse_hwhandler() {
274 # TODO: actually the dm-emc vs scsi-dh-emc is dependant on kernel version
275 # not version of the tools installed
277 # multipath-tools-0.4.8-0.12.amd64
278 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
280 # multipath-tools-0.4.8-11.x86_64
281 # size=7.0G features='0' hwhandler='0' wp=rw
282 # size=2.0G features='1 queue_if_no_path' hwhandler='1 emc' wp=rw
283 echo "$info" | sed -ne "
284 # multipath-tools-0.4.8-0.12.amd64
286 s,^.*\[hwhandler=1 \([^]]*\)\].*$,dm-\1,
289 # multipath-tools-0.4.8-11.x86_64
291 s,^.*hwhandler='1 \([^']*\)'.*$,scsi-dh-\1,