2 # geninitrd mod: dm-multipath
3 USE_MULTIPATH=${USE_MULTIPATH:-yes}
5 # if we should init dm-multipath at boot
8 # dm-multipath wwid which is used for rootfs
11 # setup geninitrd module
13 setup_mod_multipath() {
14 if [ ! -x /sbin/multipath ]; then
19 # return true if node is multipath controlled
20 # @param string $node device node to be examined
26 if is_no "$USE_MULTIPATH"; then
30 # multipath nodes are under device mapper
31 if [[ "$devpath" != /dev/mapper/* ]]; then
36 eval $(dm_export "$devpath")
37 if [ -z "$DM_NAME" ]; then
38 die "Couldn't extract DM_NAME from $devpath"
41 local MPATH_WWID=${DM_UUID##*-}
43 # just check if it is valid.
44 local info=$(multipath -l $MPATH_WWID)
45 if [ -z "$info" ]; then
52 # find modules for $devpath
53 # @param $devpath device to be examined
55 # find dm-multipath modules for $devpath
56 # returns false if $devpath is not dm-multipath
57 find_modules_multipath() {
61 eval $(dm_export "$devpath")
62 if [ -z "$DM_NAME" ]; then
63 die "Couldn't extract DM_NAME from $devpath"
68 # DM_UUID=part1-mpath-36006016002c11800a0aa05fbfae0db11
71 # DM_UUID=mpath-36006016002c11800a0aa05fbfae0db11
72 MPATH_WWID=${DM_UUID##*-}
74 local info=$(multipath -l $MPATH_WWID)
75 if [ -z "$info" ]; then
79 verbose "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
83 list=$(mp_parse_devs "$info")
85 find_modules_for_devpath $p
86 lvm_ignore_devices="$lvm_ignore_devices $p"
89 list=$(mp_parse_hwhandler "$info")
94 list=$(mp_parse_policy "$info")
103 # generate initrd fragment
105 initrd_gen_multipath() {
106 if ! is_yes "$have_multipath"; then
110 inst_d /sbin /lib/udev /etc/multipath
111 inst_exec /sbin/kpartx /sbin
112 inst_exec /sbin/multipath /sbin
115 local scsi_id=$(find_tool /$_lib/udev/scsi_id /lib/udev/scsi_id /sbin/scsi_id)
116 inst_exec $scsi_id /lib/udev
118 if [ -d /$_lib/multipath ]; then
119 inst_d /$_lib/multipath
120 inst_exec /$_lib/multipath/* /$_lib/multipath
122 inst_exec /sbin/mpath* /sbin
125 grep -Ev '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
127 if [ -f /etc/multipath/bindings ]; then
128 grep -Ev '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
130 touch $DESTDIR/etc/multipath/bindings
137 echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
139 # parse mpath_wwid= from kernel commandline
140 for arg in $CMDLINE; do
141 if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
142 MPATH_WWID=${arg##mpath_wwid=}
143 if [ "$MPATH_WWID" = "*" ]; then
144 # '*' would mean activate all WWID-s
146 echo "multipath: Activating all WWID-s"
148 echo "multipath: Activating WWID=$WWID"
154 /sbin/multipath -v 0 $MPATH_WWID
156 for a in /dev/mapper/*; do
157 [ $a = /dev/mapper/control ] && continue
158 /sbin/kpartx -a -p p $a
166 # export info from dmsetup
170 # - /dev/mapper/DM_NAME
176 local maj=${arg%:*} min=${arg#*:}
177 dmsetup -j $maj -m $min export
180 local min=${arg#*dm-}
181 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
185 local dm_name=${arg#/dev/mapper/}
186 dmsetup export $dm_name
189 die "dm_export: unexpected $arg"
194 # parse blockdevices behind multipath device
195 # takes 'multipath -l' output as input
199 # parse "0:0:1:0 sdf" -> /dev/sdf
201 # multipath-tools-0.4.8-0.12.amd64
202 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
203 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
204 # \_ round-robin 0 [prio=0][active]
205 # \_ 0:0:0:0 sda 8:0 [active][undef]
206 # \_ round-robin 0 [prio=0][enabled]
207 # \_ 0:0:1:0 sdf 8:80 [active][undef]
209 # multipath-tools-0.4.8-9.x86_64
210 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
211 # size=7.0G features='0' hwhandler='0' wp=rw
212 # |-+- policy='round-robin 0' prio=-1 status=enabled
213 # | `- #:#:#:# sde 8:64 failed undef running
214 # `-+- policy='round-robin 0' prio=-1 status=active
215 # `- #:#:#:# sdb 8:16 active undef running
217 echo "$info" | awk '{
218 if (match($0, /[#0-9]+:[#0-9]+:[#0-9]+:[#0-9]+ [^ ]+ [0-9]+:[0-9]/)) {
219 # take whole matched part into "l" variable
220 l = substr($0, RSTART, RLENGTH);
222 printf("/dev/%s\n", a[2])
227 # parse policy output for each device
228 # takes 'multipath -l' output as input
232 # multipath-tools-0.4.8-0.12.amd64
233 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
234 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
235 # \_ round-robin 0 [prio=0][active]
236 # \_ 0:0:0:0 sda 8:0 [active][undef]
237 # \_ round-robin 0 [prio=0][enabled]
238 # \_ 0:0:1:0 sdf 8:80 [active][undef]
240 # multipath-tools-0.4.8-9.x86_64
241 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
242 # size=7.0G features='0' hwhandler='0' wp=rw
243 # |-+- policy='round-robin 0' prio=-1 status=enabled
244 # | `- #:#:#:# sde 8:64 failed undef running
245 # `-+- policy='round-robin 0' prio=-1 status=active
246 # `- #:#:#:# sdb 8:16 active undef running
249 # multipath-tools-0.4.8-0.12.amd64
253 # multipath-tools-0.4.8-9.x86_64
255 if (match($0, /policy=[^ ]+/)) {
256 # take whole matched part into "l" variable
257 l = substr($0, RSTART, RLENGTH);
258 # remove policy= and single quote,
259 # which we can not use in this awk inline script, therefore the %c hack
260 sub(sprintf("^policy=%c?", 39), "", l);
267 # parse hwhandler from multipath output
268 # takes 'multipath -l' output as input
269 mp_parse_hwhandler() {
272 # TODO: actually the dm-emc vs scsi-dh-emc is dependant on kernel version
273 # not version of the tools installed
275 # multipath-tools-0.4.8-0.12.amd64
276 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
278 # multipath-tools-0.4.8-11.x86_64
279 # size=7.0G features='0' hwhandler='0' wp=rw
280 # size=2.0G features='1 queue_if_no_path' hwhandler='1 emc' wp=rw
281 echo "$info" | sed -ne "
282 # multipath-tools-0.4.8-0.12.amd64
284 s,^.*\[hwhandler=1 \([^]]*\)\].*$,dm-\1,
287 # multipath-tools-0.4.8-11.x86_64
289 s,^.*hwhandler='1 \([^']*\)'.*$,scsi-dh-\1,