]> git.pld-linux.org Git - projects/geninitrd.git/blob - mod-multipath.sh
- setup modules _after_ parsing command-line args
[projects/geninitrd.git] / mod-multipath.sh
1 #!/bin/sh
2 #
3 # geninitrd mod: dm-multipath
4
5 # if we should init dm-multipath at boot
6 have_multipath=no
7
8 # dm-multipath wwid which is used for rootfs
9 MPATH_WWID=
10
11 # setup geninitrd module
12 # @access       public
13 setup_mod_multipath() {
14         if [ -x /sbin/multipath ]; then
15                 USE_MULTIPATH=yes
16         else
17                 USE_MULTIPATH=no
18         fi
19 }
20
21 # return true if node is multipath controlled
22 # @param        string $node device node to be examined
23 # @access       public
24 is_multipath() {
25         local devpath="$1"
26
27         # multipath disabled
28         if ! is_yes "$USE_MULTIPATH"; then
29                 return 1
30         fi
31
32         # multipath nodes are under device mapper
33         if [[ "$devpath" != /dev/mapper/* ]]; then
34                 return 1
35         fi
36
37         DM_NAME=
38         eval $(dm_export "$devpath")
39         if [ -z "$DM_NAME" ]; then
40                 die "dm_export failed unexpectedly"
41         fi
42
43         local MPATH_WWID=${DM_UUID##*-}
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
57 find_modules_multipath() {
58         local devpath="$1"
59
60         DM_NAME=
61         eval $(dm_export "$devpath")
62         if [ -z "$DM_NAME" ]; then
63                 die "dm_export failed unexpectedly"
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
79         debug "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
80         have_multipath=yes
81         local dev phydevs=$(echo "$info" | awk '$2 ~ /^[0-9]+:[0-9]+:[0-9]+:[0-9]+$/{printf("/dev/%s\n", $3)}')
82         for dev in $phydevs; do
83                 find_modules_for_devpath $dev
84                 lvm_ignore_devices="$lvm_ignore_devices $dev"
85         done
86
87         local hw hwhandlers=$(echo "$info" | awk '/hwhandler=1/{sub(/.*hwhandler=1 /, ""); sub(/\]$/, ""); print}')
88         for hw in $hwhandlers; do
89                 find_module "dm-$hw"
90         done
91
92         local target targets=$(echo "$info" | awk '/prio=/{print $2}' | sort -u)
93         for target in $targets; do
94                 find_module "dm-$target"
95         done
96
97         find_module "dm-mod"
98         return 0
99 }
100
101 # generate initrd fragment
102 # @access       public
103 initrd_gen_multipath() {
104         inst_d /sbin /lib/udev /etc/multipath
105         inst_exec /sbin/kpartx /sbin
106         inst_exec /sbin/multipath /sbin
107
108         # for udev callouts
109         inst_exec /sbin/scsi_id /lib/udev
110         inst_exec /sbin/mpath* /sbin
111         egrep -v '^([   ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
112
113         if [ -f /etc/multipath/bindings ]; then
114                 egrep -v '^([   ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
115         else
116                 touch $DESTDIR/etc/multipath/bindings
117         fi
118
119         mount_dev
120         initrd_gen_devices
121
122         mount_sys
123         echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
124         add_linuxrc <<-'EOF'
125                 # parse mpath_wwid= from kernel commandline
126                 for arg in $CMDLINE; do
127                         if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
128                                 MPATH_WWID=${arg##mpath_wwid=}
129                                 if [ "$MPATH_WWID" = "*" ]; then
130                                         # '*' would mean activate all WWID-s
131                                         MPATH_WWID=
132                                         echo "multipath: Activating all WWID-s"
133                                 else
134                                         echo "multipath: Activating WWID=$WWID"
135                                 fi
136                         fi
137                 done
138
139                 debugshell
140                 /sbin/multipath -v 0 $MPATH_WWID
141
142                 for a in /dev/mapper/*; do
143                         [ $a = /dev/mapper/control ] && continue
144                         /sbin/kpartx -a -p p $a
145                 done
146                 debugshell
147         EOF
148 }
149
150
151 # PRIVATE METHODS
152 # export info from dmsetup
153 # param can be:
154 # - MAJOR:MINOR
155 # - /dev/dm-MINOR
156 # - /dev/mapper/DM_NAME
157 dm_export() {
158         local arg="$1"
159
160         case "$arg" in
161         *:*)
162                 local maj=${arg%:*} min=${arg#*:}
163                 dmsetup -j $maj -m $min export
164                 ;;
165         /dev/dm-*)
166                 local min=${arg#*dm-}
167                 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
168                 dm_export $maj:$min
169                 ;;
170         /dev/mapper/*)
171                 local dm_name=${arg#/dev/mapper/}
172                 dmsetup export $dm_name
173                 ;;
174         *)
175                 die "dm_export: unexpected $arg"
176                 ;;
177         esac
178 }
179
This page took 0.069486 seconds and 4 git commands to generate.