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