]> git.pld-linux.org Git - projects/geninitrd.git/blame - mod-multipath.sh
- add --with-multipath=DEVPATH support
[projects/geninitrd.git] / mod-multipath.sh
CommitLineData
c3b54060
ER
1#!/bin/sh
2#
3# geninitrd mod: dm-multipath
6e49b0b1 4USE_MULTIPATH=${USE_MULTIPATH:-yes}
c3b54060
ER
5
6# if we should init dm-multipath at boot
7have_multipath=no
8
c3b54060
ER
9# dm-multipath wwid which is used for rootfs
10MPATH_WWID=
11
c124d0cf
ER
12# setup geninitrd module
13# @access public
14setup_mod_multipath() {
6e49b0b1 15 if [ ! -x /sbin/multipath ]; then
c124d0cf
ER
16 USE_MULTIPATH=no
17 fi
18}
19
c3b54060
ER
20# return true if node is multipath controlled
21# @param string $node device node to be examined
22# @access public
23is_multipath() {
24 local devpath="$1"
25
26 # multipath disabled
ecd7bf46 27 if is_no "$USE_MULTIPATH"; then
c3b54060
ER
28 return 1
29 fi
30
31 # multipath nodes are under device mapper
32 if [[ "$devpath" != /dev/mapper/* ]]; then
33 return 1
34 fi
35
36 DM_NAME=
37 eval $(dm_export "$devpath")
38 if [ -z "$DM_NAME" ]; then
5d51e3e9 39 die "Couldn't extract DM_NAME from $devpath"
c3b54060
ER
40 fi
41
42 local MPATH_WWID=${DM_UUID##*-}
e2c75552
ER
43
44 # just check if it is valid.
c3b54060
ER
45 local info=$(multipath -l $MPATH_WWID)
46 if [ -z "$info" ]; then
47 return 1
48 fi
49
50 return 0
51}
52
53# find modules for $devpath
54# @param $devpath device to be examined
55# @access public
56# find dm-multipath modules for $devpath
57# returns false if $devpath is not dm-multipath
58find_modules_multipath() {
59 local devpath="$1"
60
61 DM_NAME=
62 eval $(dm_export "$devpath")
63 if [ -z "$DM_NAME" ]; then
ecd7bf46 64 die "Couldn't extract DM_NAME from $devpath"
c3b54060
ER
65 fi
66
67 # Partition:
68 # DM_NAME=LUN-28p1
69 # DM_UUID=part1-mpath-36006016002c11800a0aa05fbfae0db11
70 # Disk:
71 # DM_NAME=LUN-28
72 # DM_UUID=mpath-36006016002c11800a0aa05fbfae0db11
73 MPATH_WWID=${DM_UUID##*-}
74
75 local info=$(multipath -l $MPATH_WWID)
76 if [ -z "$info" ]; then
77 return 1
78 fi
79
80 debug "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
81 have_multipath=yes
e2c75552
ER
82
83 local p list
84 list=$(mp_parse_devs "$info")
85 for p in $list; do
86 find_modules_for_devpath $p
87 lvm_ignore_devices="$lvm_ignore_devices $p"
c3b54060
ER
88 done
89
e2c75552
ER
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}')
93 for p in $list; do
94 find_module "dm-$p"
c3b54060
ER
95 done
96
e2c75552
ER
97 list=$(mp_parse_policy "$info")
98 for p in $list; do
99 find_module "dm-$p"
c3b54060
ER
100 done
101
b02a6b13 102 find_module "dm-mod"
c3b54060
ER
103 return 0
104}
105
106# generate initrd fragment
107# @access public
108initrd_gen_multipath() {
109 inst_d /sbin /lib/udev /etc/multipath
110 inst_exec /sbin/kpartx /sbin
111 inst_exec /sbin/multipath /sbin
112
113 # for udev callouts
e2c75552
ER
114 local scsi_id=$(find_tool /lib/udev/scsi_id /sbin/scsi_id)
115 inst_exec $scsi_id /lib/udev
116
117 if [ -d /lib/multipath ]; then
118 inst_d /lib/multipath
119 inst_exec /lib/multipath/* /lib/multipath
120 else
121 inst_exec /sbin/mpath* /sbin
122 fi
123
c3b54060
ER
124 egrep -v '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
125
126 if [ -f /etc/multipath/bindings ]; then
127 egrep -v '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
128 else
129 touch $DESTDIR/etc/multipath/bindings
130 fi
131
132 mount_dev
133 initrd_gen_devices
134
135 mount_sys
136 echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
137 add_linuxrc <<-'EOF'
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
144 MPATH_WWID=
145 echo "multipath: Activating all WWID-s"
146 else
147 echo "multipath: Activating WWID=$WWID"
148 fi
149 fi
150 done
151
152 debugshell
153 /sbin/multipath -v 0 $MPATH_WWID
154
155 for a in /dev/mapper/*; do
156 [ $a = /dev/mapper/control ] && continue
157 /sbin/kpartx -a -p p $a
158 done
159 debugshell
160 EOF
161}
6ae2e4d0
ER
162
163
164# PRIVATE METHODS
165# export info from dmsetup
166# param can be:
167# - MAJOR:MINOR
168# - /dev/dm-MINOR
169# - /dev/mapper/DM_NAME
170dm_export() {
171 local arg="$1"
172
173 case "$arg" in
174 *:*)
175 local maj=${arg%:*} min=${arg#*:}
176 dmsetup -j $maj -m $min export
177 ;;
178 /dev/dm-*)
179 local min=${arg#*dm-}
180 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
181 dm_export $maj:$min
182 ;;
183 /dev/mapper/*)
184 local dm_name=${arg#/dev/mapper/}
185 dmsetup export $dm_name
186 ;;
187 *)
188 die "dm_export: unexpected $arg"
189 ;;
190 esac
191}
192
e2c75552
ER
193# parse blockdevices behind multipath device
194# takes 'multipath -l' output as input
195mp_parse_devs() {
196 local info="$1"
197
198 # parse "0:0:1:0 sdf" -> /dev/sdf
199 #
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]
207 #
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
215
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);
220 split(l, a, " ");
221 printf("/dev/%s\n", a[2])
222 }
223 }'
224}
225
226# parse policy output for each device
227# takes 'multipath -l' output as input
228mp_parse_policy() {
229 local info="$1"
230
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]
238 #
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
246
247 echo "$info" | awk '
248 # multipath-tools-0.4.8-0.12.amd64
249 /\[prio=/{
250 print $2
251 }
252 # multipath-tools-0.4.8-9.x86_64
253 /policy=/{
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);
260 print l
261 }
262 }
263 ' | sort -u
264}
This page took 0.067292 seconds and 4 git commands to generate.