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 # TODO: handle newer multipath-tools:
91 # size=7.0G features='0' hwhandler='0' wp=rw
92 list=$(echo "$info" | awk '/hwhandler=1/{sub(/.*hwhandler=1 /, ""); sub(/\]$/, ""); print}')
97 list=$(mp_parse_policy "$info")
106 # generate initrd fragment
108 initrd_gen_multipath() {
109 inst_d /sbin /lib/udev /etc/multipath
110 inst_exec /sbin/kpartx /sbin
111 inst_exec /sbin/multipath /sbin
114 local scsi_id=$(find_tool /lib/udev/scsi_id /sbin/scsi_id)
115 inst_exec $scsi_id /lib/udev
117 if [ -d /lib/multipath ]; then
118 inst_d /lib/multipath
119 inst_exec /lib/multipath/* /lib/multipath
121 inst_exec /sbin/mpath* /sbin
124 egrep -v '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
126 if [ -f /etc/multipath/bindings ]; then
127 egrep -v '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
129 touch $DESTDIR/etc/multipath/bindings
136 echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
138 # parse mpath_wwid= from kernel commandline
139 for arg in $CMDLINE; do
140 if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
141 MPATH_WWID=${arg##mpath_wwid=}
142 if [ "$MPATH_WWID" = "*" ]; then
143 # '*' would mean activate all WWID-s
145 echo "multipath: Activating all WWID-s"
147 echo "multipath: Activating WWID=$WWID"
153 /sbin/multipath -v 0 $MPATH_WWID
155 for a in /dev/mapper/*; do
156 [ $a = /dev/mapper/control ] && continue
157 /sbin/kpartx -a -p p $a
165 # export info from dmsetup
169 # - /dev/mapper/DM_NAME
175 local maj=${arg%:*} min=${arg#*:}
176 dmsetup -j $maj -m $min export
179 local min=${arg#*dm-}
180 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
184 local dm_name=${arg#/dev/mapper/}
185 dmsetup export $dm_name
188 die "dm_export: unexpected $arg"
193 # parse blockdevices behind multipath device
194 # takes 'multipath -l' output as input
198 # parse "0:0:1:0 sdf" -> /dev/sdf
200 # multipath-tools-0.4.8-0.12.amd64
201 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
202 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
203 # \_ round-robin 0 [prio=0][active]
204 # \_ 0:0:0:0 sda 8:0 [active][undef]
205 # \_ round-robin 0 [prio=0][enabled]
206 # \_ 0:0:1:0 sdf 8:80 [active][undef]
208 # multipath-tools-0.4.8-9.x86_64
209 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
210 # size=7.0G features='0' hwhandler='0' wp=rw
211 # |-+- policy='round-robin 0' prio=-1 status=enabled
212 # | `- #:#:#:# sde 8:64 failed undef running
213 # `-+- policy='round-robin 0' prio=-1 status=active
214 # `- #:#:#:# sdb 8:16 active undef running
216 echo "$info" | awk '{
217 if (match($0, /[#0-9]+:[#0-9]+:[#0-9]+:[#0-9]+ [^ ]+ [0-9]+:[0-9]/)) {
218 # take whole matched part into "l" variable
219 l = substr($0, RSTART, RLENGTH);
221 printf("/dev/%s\n", a[2])
226 # parse policy output for each device
227 # takes 'multipath -l' output as input
231 # multipath-tools-0.4.8-0.12.amd64
232 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
233 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
234 # \_ round-robin 0 [prio=0][active]
235 # \_ 0:0:0:0 sda 8:0 [active][undef]
236 # \_ round-robin 0 [prio=0][enabled]
237 # \_ 0:0:1:0 sdf 8:80 [active][undef]
239 # multipath-tools-0.4.8-9.x86_64
240 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
241 # size=7.0G features='0' hwhandler='0' wp=rw
242 # |-+- policy='round-robin 0' prio=-1 status=enabled
243 # | `- #:#:#:# sde 8:64 failed undef running
244 # `-+- policy='round-robin 0' prio=-1 status=active
245 # `- #:#:#:# sdb 8:16 active undef running
248 # multipath-tools-0.4.8-0.12.amd64
252 # multipath-tools-0.4.8-9.x86_64
254 if (match($0, /policy=[^ ]+/)) {
255 # take whole matched part into "l" variable
256 l = substr($0, RSTART, RLENGTH);
257 # remove policy= and single quote,
258 # which we can not use in this awk inline script, therefore the %c hack
259 sub(sprintf("^policy=%c?", 39), "", l);