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