]> git.pld-linux.org Git - projects/geninitrd.git/blame - mod-multipath.sh
Use double quotes (more readable in this context)
[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
ddc299f5 90 list=$(mp_parse_hwhandler "$info")
e2c75552 91 for p in $list; do
ddc299f5 92 find_module "$p"
c3b54060
ER
93 done
94
e2c75552
ER
95 list=$(mp_parse_policy "$info")
96 for p in $list; do
97 find_module "dm-$p"
c3b54060
ER
98 done
99
b02a6b13 100 find_module "dm-mod"
c3b54060
ER
101 return 0
102}
103
104# generate initrd fragment
105# @access public
106initrd_gen_multipath() {
107 inst_d /sbin /lib/udev /etc/multipath
108 inst_exec /sbin/kpartx /sbin
109 inst_exec /sbin/multipath /sbin
110
111 # for udev callouts
07de5194 112 local scsi_id=$(find_tool /$_lib/udev/scsi_id /lib/udev/scsi_id /sbin/scsi_id)
e2c75552
ER
113 inst_exec $scsi_id /lib/udev
114
c1a60691
ER
115 if [ -d /$_lib/multipath ]; then
116 inst_d /$_lib/multipath
117 inst_exec /$_lib/multipath/* /$_lib/multipath
e2c75552
ER
118 else
119 inst_exec /sbin/mpath* /sbin
120 fi
121
c3b54060
ER
122 egrep -v '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
123
124 if [ -f /etc/multipath/bindings ]; then
125 egrep -v '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
126 else
127 touch $DESTDIR/etc/multipath/bindings
128 fi
129
130 mount_dev
131 initrd_gen_devices
132
133 mount_sys
134 echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
135 add_linuxrc <<-'EOF'
136 # parse mpath_wwid= from kernel commandline
137 for arg in $CMDLINE; do
138 if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
139 MPATH_WWID=${arg##mpath_wwid=}
140 if [ "$MPATH_WWID" = "*" ]; then
141 # '*' would mean activate all WWID-s
142 MPATH_WWID=
143 echo "multipath: Activating all WWID-s"
144 else
145 echo "multipath: Activating WWID=$WWID"
146 fi
147 fi
148 done
149
150 debugshell
151 /sbin/multipath -v 0 $MPATH_WWID
152
153 for a in /dev/mapper/*; do
154 [ $a = /dev/mapper/control ] && continue
155 /sbin/kpartx -a -p p $a
156 done
157 debugshell
158 EOF
159}
6ae2e4d0
ER
160
161
162# PRIVATE METHODS
163# export info from dmsetup
164# param can be:
165# - MAJOR:MINOR
166# - /dev/dm-MINOR
167# - /dev/mapper/DM_NAME
168dm_export() {
169 local arg="$1"
170
171 case "$arg" in
172 *:*)
173 local maj=${arg%:*} min=${arg#*:}
174 dmsetup -j $maj -m $min export
175 ;;
176 /dev/dm-*)
177 local min=${arg#*dm-}
178 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
179 dm_export $maj:$min
180 ;;
181 /dev/mapper/*)
182 local dm_name=${arg#/dev/mapper/}
183 dmsetup export $dm_name
184 ;;
185 *)
186 die "dm_export: unexpected $arg"
187 ;;
188 esac
189}
190
e2c75552
ER
191# parse blockdevices behind multipath device
192# takes 'multipath -l' output as input
193mp_parse_devs() {
194 local info="$1"
195
196 # parse "0:0:1:0 sdf" -> /dev/sdf
197 #
198 # multipath-tools-0.4.8-0.12.amd64
199 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
200 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
201 # \_ round-robin 0 [prio=0][active]
202 # \_ 0:0:0:0 sda 8:0 [active][undef]
203 # \_ round-robin 0 [prio=0][enabled]
204 # \_ 0:0:1:0 sdf 8:80 [active][undef]
205 #
206 # multipath-tools-0.4.8-9.x86_64
207 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
208 # size=7.0G features='0' hwhandler='0' wp=rw
209 # |-+- policy='round-robin 0' prio=-1 status=enabled
210 # | `- #:#:#:# sde 8:64 failed undef running
211 # `-+- policy='round-robin 0' prio=-1 status=active
212 # `- #:#:#:# sdb 8:16 active undef running
213
214 echo "$info" | awk '{
215 if (match($0, /[#0-9]+:[#0-9]+:[#0-9]+:[#0-9]+ [^ ]+ [0-9]+:[0-9]/)) {
216 # take whole matched part into "l" variable
217 l = substr($0, RSTART, RLENGTH);
218 split(l, a, " ");
219 printf("/dev/%s\n", a[2])
220 }
221 }'
222}
223
224# parse policy output for each device
225# takes 'multipath -l' output as input
226mp_parse_policy() {
227 local info="$1"
228
229 # multipath-tools-0.4.8-0.12.amd64
230 # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
231 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
232 # \_ round-robin 0 [prio=0][active]
233 # \_ 0:0:0:0 sda 8:0 [active][undef]
234 # \_ round-robin 0 [prio=0][enabled]
235 # \_ 0:0:1:0 sdf 8:80 [active][undef]
236 #
237 # multipath-tools-0.4.8-9.x86_64
238 # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
239 # size=7.0G features='0' hwhandler='0' wp=rw
240 # |-+- policy='round-robin 0' prio=-1 status=enabled
241 # | `- #:#:#:# sde 8:64 failed undef running
242 # `-+- policy='round-robin 0' prio=-1 status=active
243 # `- #:#:#:# sdb 8:16 active undef running
244
245 echo "$info" | awk '
246 # multipath-tools-0.4.8-0.12.amd64
247 /\[prio=/{
248 print $2
249 }
250 # multipath-tools-0.4.8-9.x86_64
251 /policy=/{
252 if (match($0, /policy=[^ ]+/)) {
253 # take whole matched part into "l" variable
254 l = substr($0, RSTART, RLENGTH);
255 # remove policy= and single quote,
256 # which we can not use in this awk inline script, therefore the %c hack
257 sub(sprintf("^policy=%c?", 39), "", l);
258 print l
259 }
260 }
261 ' | sort -u
262}
ddc299f5
ER
263
264# parse hwhandler from multipath output
265# takes 'multipath -l' output as input
266mp_parse_hwhandler() {
267 local info="$1"
268
269 # TODO: actually the dm-emc vs scsi-dh-emc is dependant on kernel version
270 # not version of the tools installed
271
272 # multipath-tools-0.4.8-0.12.amd64
273 # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
274 #
275 # multipath-tools-0.4.8-11.x86_64
276 # size=7.0G features='0' hwhandler='0' wp=rw
277 # size=2.0G features='1 queue_if_no_path' hwhandler='1 emc' wp=rw
278 echo "$info" | sed -ne "
9802850b
ER
279 # multipath-tools-0.4.8-0.12.amd64
280 /\[hwhandler=1/{
281 s,^.*\[hwhandler=1 \([^]]*\)\].*$,dm-\1,
282 p
283 }
ddc299f5 284 # multipath-tools-0.4.8-11.x86_64
9802850b
ER
285 /hwhandler='1/{
286 s,^.*hwhandler='1 \([^']*\)'.*$,scsi-dh-\1,
287 p
288 }
289 " | sort -u
ddc299f5 290}
This page took 0.057297 seconds and 4 git commands to generate.