]>
Commit | Line | Data |
---|---|---|
67aa84bd | 1 | #!/bin/sh |
c34c6a69 | 2 | LVM_RCSID='$Revision$ $Date:: $' |
05c474b5 | 3 | |
67aa84bd | 4 | # geninitrd mod: LVM |
6e49b0b1 | 5 | USE_LVM=${USE_LVM:-yes} |
67aa84bd ER |
6 | |
7 | # if we should init LVM at boot | |
8 | have_lvm=no | |
9 | ||
10 | # LVM volumes that are needed to activate | |
11 | # VG for root dev | |
12 | # @internal | |
00afc695 | 13 | LVM_ROOTVG="" |
67aa84bd ER |
14 | |
15 | # VG for suspend resume dev | |
00afc695 | 16 | LVM_SUSPENDVG="" |
67aa84bd | 17 | |
00afc695 | 18 | LVM_VGVOLUMES="" |
67aa84bd | 19 | |
f0ef5219 ER |
20 | # LVM version. Autodetected if not set. |
21 | # Values: 1|2 | |
22 | LVMTOOLSVERSION= | |
23 | ||
67aa84bd ER |
24 | # LVM devices that should not be included in vgscan on initrd. |
25 | # @internal | |
26 | lvm_ignore_devices='' | |
27 | ||
c124d0cf ER |
28 | # setup geninitrd module |
29 | # @access public | |
30 | setup_mod_lvm() { | |
31 | lvm=$(find_tool $initrd_dir/lvm /sbin/initrd-lvm) | |
c124d0cf | 32 | |
728b5283 | 33 | if [ ! -x "$lvm" ]; then |
6e49b0b1 ER |
34 | USE_LVM=no |
35 | fi | |
36 | ||
37 | if is_yes "$USE_LVM" && [ -z "$LVMTOOLSVERSION" ]; then | |
38 | LVMTOOLSVERSION=$(LC_ALL=C $lvm vgchange --version 2>/dev/null | awk '/LVM version:/{if ($3 >= 2) print "2"}') | |
c124d0cf | 39 | if [ -z "$LVMTOOLSVERSION" ]; then |
074b295e | 40 | die "Can't determine LVM tools version (is /sys mounted?). Please set LVMTOOLSVERSION and rerun $PROGRAM." |
c124d0cf ER |
41 | fi |
42 | fi | |
43 | } | |
44 | ||
67aa84bd ER |
45 | # return true if node is lvm node |
46 | # @param string $node device node to be examined | |
47 | # @access public | |
48 | is_lvm() { | |
49 | local node="$1" | |
50 | ||
51 | # LVM not wanted | |
52 | if is_no "$USE_LVM"; then | |
53 | return 1 | |
54 | fi | |
55 | ||
56 | if [ ! -e "$node" ]; then | |
57 | die "check_lvm(): node $node doesn't exist!" | |
58 | return 1 | |
59 | fi | |
60 | ||
61 | # block-major-58 is lvm1 | |
62 | ls -lL "$node" 2> /dev/null | awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}' | |
63 | rc=$? | |
64 | ||
65 | if [ $rc = 0 ]; then | |
66 | # is lvm1 | |
67 | return 0 | |
68 | fi | |
69 | ||
728b5283 | 70 | $lvm lvdisplay "$node" > /dev/null 2>&1 |
67aa84bd ER |
71 | rc=$? |
72 | if [ $rc -gt 127 ]; then | |
73 | # lvdisplay terminated by signal! most likely it segfaulted. | |
74 | die "Unexpected exit from 'lvdisplay $node': $rc - are your lvm tools broken?" | |
75 | fi | |
76 | ||
77 | return $rc | |
78 | } | |
79 | ||
80 | # find modules for $devpath | |
81 | # @param $devpath device to be examined | |
82 | # @access public | |
83 | find_modules_lvm() { | |
84 | local devpath="$1" | |
85 | ||
02ba8ab7 | 86 | verbose "LVM: $devpath is LVM node" |
67aa84bd | 87 | |
67aa84bd | 88 | local vg=$(find_lvm_vg "$devpath") |
02ba8ab7 | 89 | verbose "LVM VG for $devpath: $vg" |
00afc695 | 90 | LVM_VGVOLUMES=$(echo $LVM_VGVOLUMES $vg | tr ' ' '\n' | sort -u) |
67aa84bd ER |
91 | |
92 | local pv=$(find_lvm_pv "$vg") | |
02ba8ab7 | 93 | verbose "LVM PV for $vg: $pv" |
67aa84bd ER |
94 | PVDEVICES=$(echo $PVDEVICES $pv | tr ' ' '\n' | sort -u) |
95 | ||
96 | if [ -n "$PVDEVICES" ]; then | |
97 | for device in $PVDEVICES; do | |
98 | find_modules_for_devpath $device | |
99 | done | |
100 | else | |
728b5283 | 101 | die "I wasn't able to find PV. You can try to set PVDEVICES in /etc/sysconfig/geninitrd." |
67aa84bd ER |
102 | fi |
103 | ||
104 | if [ "$LVMTOOLSVERSION" = "2" ]; then | |
b02a6b13 | 105 | find_module "-dm-mod" |
67aa84bd | 106 | elif [ "$LVMTOOLSVERSION" = "1" ]; then |
b02a6b13 ER |
107 | find_module "-lvm" |
108 | find_module "-lvm-mod" | |
67aa84bd | 109 | else |
f0ef5219 | 110 | die "LVM version $LVMTOOLSVERSION is not supported." |
67aa84bd ER |
111 | fi |
112 | ||
02ba8ab7 | 113 | verbose "LVM v$LVMTOOLSVERSION enabled" |
67aa84bd ER |
114 | have_lvm=yes |
115 | } | |
116 | ||
117 | ||
118 | # generate initrd fragment for lvm | |
119 | # @access public | |
120 | initrd_gen_lvm() { | |
1b481849 ER |
121 | if ! is_yes "$have_lvm"; then |
122 | return | |
123 | fi | |
124 | ||
02ba8ab7 | 125 | verbose "Adding LVM support to initrd" |
67aa84bd | 126 | inst_d /tmp /newroot |
684d5d2a | 127 | inst_exec $lvm /bin/lvm.static |
67aa84bd ER |
128 | |
129 | # always make /dev on tmpfs for LVM2 | |
130 | if [ "$LVMTOOLSVERSION" = "2" ]; then | |
131 | mount_dev | |
132 | fi | |
133 | ||
134 | if ! is_yes "$dev_mounted"; then | |
135 | inst_d /dev/mapper | |
6b45dd6c | 136 | mknod -m 600 $DESTDIR/dev/mapper/control c 10 63 |
67aa84bd ER |
137 | for device in $PVDEVICES; do |
138 | # if LVM on RAID then device might be copied already in gen_md | |
139 | [ -e "$DESTDIR/dev/$(basename $device)" ] && continue | |
140 | inst $device /dev | |
141 | done | |
142 | fi | |
143 | ||
144 | mount_tmp | |
7170bd62 | 145 | mount_sys |
67aa84bd ER |
146 | if [ "$LVMTOOLSVERSION" = "1" ]; then |
147 | add_linuxrc <<-EOF | |
148 | lvm vgscan -T | |
00afc695 | 149 | for vg in $LVM_VGVOLUMES; do |
67aa84bd ER |
150 | lvm vgchange -T -a y $vg |
151 | done | |
152 | EOF | |
153 | else | |
432641fe ER |
154 | cat <<-EOF > "$DESTDIR/etc/lvm.conf" |
155 | global { | |
156 | locking_type = 0 | |
157 | locking_dir = "/tmp" | |
158 | } | |
159 | devices { | |
160 | sysfs_scan=0 | |
161 | EOF | |
67aa84bd | 162 | if is_yes "$have_md"; then |
432641fe | 163 | echo " md_component_detection=1" >> "$DESTDIR/etc/lvm.conf" |
67aa84bd ER |
164 | fi |
165 | if is_yes "$have_dmraid" || is_yes "$have_multipath"; then | |
166 | echo ' types = [ "device-mapper", 254 ]' >> "$DESTDIR/etc/lvm.conf" | |
167 | fi | |
168 | if [ "$lvm_ignore_devices" ]; then | |
169 | # TODO: think of merging with lvm dumpconfig output | |
170 | echo ' filter = [' >> "$DESTDIR/etc/lvm.conf" | |
171 | local dev | |
172 | for dev in $lvm_ignore_devices; do | |
02ba8ab7 | 173 | verbose "LVM v2: ignore device $dev" |
67aa84bd ER |
174 | printf ' "r|^%s.*|",\n' $dev |
175 | done >> "$DESTDIR/etc/lvm.conf" | |
176 | echo ']' >> "$DESTDIR/etc/lvm.conf" | |
177 | fi | |
178 | # XXX filter= must be on one line! | |
728b5283 | 179 | $lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf" |
67aa84bd ER |
180 | echo "}" >> "$DESTDIR/etc/lvm.conf" |
181 | ||
432641fe ER |
182 | echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc |
183 | ||
67aa84bd ER |
184 | initrd_gen_devices |
185 | ||
186 | add_linuxrc <<-EOF | |
48d98595 | 187 | ROOTDEV=$rootdev |
00afc695 ER |
188 | LVM_ROOTVG="$LVM_VGVOLUMES" |
189 | LVM_SUSPENDVG="$LVM_SUSPENDVG" | |
67aa84bd | 190 | EOF |
57f48d51 ER |
191 | |
192 | # need awk for "s/--/-/g" subst when parsing kernel root commandline | |
193 | busybox_applet awk | |
67aa84bd ER |
194 | add_linuxrc <<-'EOF' |
195 | # parse rootdev from kernel commandline if it begins with / | |
196 | case "$ROOT" in | |
197 | /*) | |
2ade15a8 | 198 | |
57f48d51 | 199 | # rewrite: |
ea8d931d | 200 | # /dev/mapper/sys-rootfs -> /dev/sys/rootfs |
57f48d51 | 201 | # /dev/mapper/blodnatt-blah--bleh -> /dev/blodnatt/blah-bleh |
ea8d931d | 202 | # /dev/mapper/vg--meaw-root -> /dev/vg-meaw/root |
2ade15a8 ER |
203 | case "$ROOT" in |
204 | /dev/mapper/*-*) | |
ea8d931d ER |
205 | # change "--" to / (as "/" is impossible in LV name) |
206 | local dev=$(awk -vdev="${ROOT#/dev/mapper/}" 'BEGIN{gsub(/--/, "/", dev); print dev}') | |
207 | local VG=$(awk -vdev="$dev" 'BEGIN{split(dev, v, "-"); gsub("/", "-", v[1]); print v[1]}') | |
208 | local LV=$(awk -vdev="$dev" 'BEGIN{split(dev, v, "-"); gsub("/", "-", v[2]); print v[2]}') | |
2ade15a8 ER |
209 | ROOT=/dev/$VG/$LV |
210 | ;; | |
211 | esac | |
212 | ||
67aa84bd ER |
213 | if [ "$ROOT" != "$ROOTDEV" ]; then |
214 | ROOTDEV=$ROOT | |
2ade15a8 | 215 | |
67aa84bd ER |
216 | echo "LVM: Using 'root=$ROOTDEV' from kernel commandline" |
217 | local tmp=${ROOTDEV#/dev/} | |
218 | if [ "$tmp" != "$ROOTDEV" ]; then | |
00afc695 ER |
219 | LVM_ROOTVG=${tmp%/*} |
220 | echo "LVM: Using Volume Group '$LVM_ROOTVG' for rootfs" | |
67aa84bd ER |
221 | fi |
222 | fi | |
223 | ;; | |
224 | esac | |
225 | ||
226 | # skip duplicate VG | |
00afc695 ER |
227 | if [ "$LVM_SUSPENDVG" = "$LVM_ROOTVG" ]; then |
228 | LVM_VGVOLUMES="$LVM_ROOTVG" | |
67aa84bd | 229 | else |
00afc695 | 230 | LVM_VGVOLUMES="$LVM_SUSPENDVG $LVM_ROOTVG" |
67aa84bd ER |
231 | fi |
232 | ||
233 | # disable noise from LVM accessing devices that aren't ready. | |
234 | read printk < /proc/sys/kernel/printk | |
235 | if [ ! "$DEBUGINITRD" ]; then | |
236 | echo 0 > /proc/sys/kernel/printk | |
237 | fi | |
238 | ||
239 | export LVM_SYSTEM_DIR=/tmp | |
240 | : 'Scanning for Volume Groups' | |
f87179eb | 241 | lvm.static vgscan --mknodes --ignorelockingfailure |
67aa84bd ER |
242 | |
243 | : 'Activating Volume Groups' | |
00afc695 | 244 | for vol in $LVM_VGVOLUMES; do |
f87179eb | 245 | lvm.static vgchange --ignorelockingfailure -a y $vol |
67aa84bd ER |
246 | done |
247 | ||
eeb60f3f | 248 | : 'Extra call to make device nodes for non lvm2-initrd (dynamic lvm2)' |
78c426d2 ER |
249 | lvm.static vgmknodes --ignorelockingfailure |
250 | ||
67aa84bd ER |
251 | echo "$printk" > /proc/sys/kernel/printk |
252 | ||
253 | # Find out major/minor | |
f87179eb | 254 | attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV)" |
67aa84bd ER |
255 | if [ "$attrs" ]; then |
256 | majmin="${attrs#*$ROOTDEV*:*:*:*:*:*:*:*:*:*:*:*}" | |
257 | if [ "$majmin" != "$attrs" ]; then | |
258 | major="${majmin%:*}" | |
259 | minor="${majmin#*:}" | |
260 | fi | |
261 | fi | |
262 | ||
263 | if [ "$major" -a "$minor" ]; then | |
264 | # Pass it to kernel | |
265 | echo $((256 * $major + $minor)) > /proc/sys/kernel/real-root-dev | |
67aa84bd | 266 | fi |
48d98595 | 267 | |
f87179eb | 268 | debugshell |
48d98595 | 269 | unset LVM_SYSTEM_DIR |
67aa84bd ER |
270 | EOF |
271 | fi | |
272 | } | |
273 | ||
274 | ||
275 | # PRIVATE METHODS | |
276 | ||
277 | # find PV names from given VG name | |
278 | # @param string $vg Volume Group name | |
279 | # @access private | |
280 | find_lvm_pv() { | |
281 | local vg="$1" | |
282 | ||
728b5283 | 283 | local pv=$($lvm vgs --noheadings -o pv_name "$vg") |
67aa84bd ER |
284 | echo $pv |
285 | } | |
286 | ||
287 | # find VG name from given devnode | |
288 | # @param string $devnode device node to be examined | |
289 | # @access private | |
290 | find_lvm_vg() { | |
291 | local devnode="$1" | |
292 | ||
728b5283 | 293 | local vg=$($lvm lvs --noheadings -o vg_name "$devnode") |
67aa84bd ER |
294 | echo $vg |
295 | } |