]> git.pld-linux.org Git - projects/geninitrd.git/blame - mod-lvm.sh
- just in case quote init args
[projects/geninitrd.git] / mod-lvm.sh
CommitLineData
67aa84bd
ER
1#!/bin/sh
2#
3# geninitrd mod: LVM
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
11ROOTVG=""
12
13# VG for suspend resume dev
14SUSPENDVG=""
15
16VGVOLUMES=""
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)
30 if [ -x /sbin/lvm -a -x "$lvm" ]; then
31 USE_LVM=yes
32 else
33 USE_LVM=no
34 fi
35
36 if [ -z "$LVMTOOLSVERSION" ]; then
37 LVMTOOLSVERSION=$(LC_ALL=C $lvm vgchange --version 2>/dev/null | awk '/LVM version:/{if ($3 >= 2) print "2"}')
38 if [ -z "$LVMTOOLSVERSION" ]; then
39 die "Can't determine LVM tools version. Please set LVMTOOLSVERSION and rerun $PROGRAM."
40 fi
41 fi
42}
43
67aa84bd
ER
44# return true if node is lvm node
45# @param string $node device node to be examined
46# @access public
47is_lvm() {
48 local node="$1"
49
50 # LVM not wanted
51 if is_no "$USE_LVM"; then
52 return 1
53 fi
54
55 if [ ! -e "$node" ]; then
56 die "check_lvm(): node $node doesn't exist!"
57 return 1
58 fi
59
60 # block-major-58 is lvm1
61 ls -lL "$node" 2> /dev/null | awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'
62 rc=$?
63
64 if [ $rc = 0 ]; then
65 # is lvm1
66 return 0
67 fi
68
69 /sbin/lvm lvdisplay "$node" > /dev/null 2>&1
70 rc=$?
71 if [ $rc -gt 127 ]; then
72 # lvdisplay terminated by signal! most likely it segfaulted.
73 die "Unexpected exit from 'lvdisplay $node': $rc - are your lvm tools broken?"
74 fi
75
76 return $rc
77}
78
79# find modules for $devpath
80# @param $devpath device to be examined
81# @access public
82find_modules_lvm() {
83 local devpath="$1"
84
85 debug "LVM: $devpath is LVM node"
86
684d5d2a
ER
87 if [ ! -x $lvm -o ! -x /sbin/lvdisplay -o ! -x /sbin/pvdisplay ]; then
88 die "root on LVM but /sbin/lvdisplay or /sbin/pvdisplay not found. Please install lvm(2) and lvm(2)-initrd package and rerun $PROGRAM."
67aa84bd
ER
89 fi
90
67aa84bd
ER
91 local vg=$(find_lvm_vg "$devpath")
92 debug "LVM VG for $devpath: $vg"
93 VGVOLUMES=$(echo $VGVOLUMES $vg | tr ' ' '\n' | sort -u)
94
95 local pv=$(find_lvm_pv "$vg")
96 debug "LVM PV for $vg: $pv"
97 PVDEVICES=$(echo $PVDEVICES $pv | tr ' ' '\n' | sort -u)
98
99 if [ -n "$PVDEVICES" ]; then
100 for device in $PVDEVICES; do
101 find_modules_for_devpath $device
102 done
103 else
104 die "I wasn't able to find PV (via lvdisplay and pvdisplay). You can try to set PVDEVICES in /etc/sysconfig/geninitrd."
105 fi
106
107 if [ "$LVMTOOLSVERSION" = "2" ]; then
b02a6b13 108 find_module "-dm-mod"
67aa84bd 109 elif [ "$LVMTOOLSVERSION" = "1" ]; then
b02a6b13
ER
110 find_module "-lvm"
111 find_module "-lvm-mod"
67aa84bd 112 else
f0ef5219 113 die "LVM version $LVMTOOLSVERSION is not supported."
67aa84bd
ER
114 fi
115
116 debug "LVM v$LVMTOOLSVERSION enabled"
117 have_lvm=yes
118}
119
120
121# generate initrd fragment for lvm
122# @access public
123initrd_gen_lvm() {
124 debug "Adding LVM support to initrd"
125 inst_d /tmp /newroot
684d5d2a 126 inst_exec $lvm /bin/lvm.static
67aa84bd
ER
127
128 # always make /dev on tmpfs for LVM2
129 if [ "$LVMTOOLSVERSION" = "2" ]; then
130 mount_dev
131 fi
132
133 if ! is_yes "$dev_mounted"; then
134 inst_d /dev/mapper
135 mknod $DESTDIR/dev/mapper/control c 10 63
136 for device in $PVDEVICES; do
137 # if LVM on RAID then device might be copied already in gen_md
138 [ -e "$DESTDIR/dev/$(basename $device)" ] && continue
139 inst $device /dev
140 done
141 fi
142
143 mount_tmp
144 if [ "$LVMTOOLSVERSION" = "1" ]; then
145 add_linuxrc <<-EOF
146 lvm vgscan -T
147 for vg in $VGVOLUMES; do
148 lvm vgchange -T -a y $vg
149 done
150 EOF
151 else
152 echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc
153 echo "global {" > "$DESTDIR/etc/lvm.conf"
154 echo " locking_type = 0" >> "$DESTDIR/etc/lvm.conf"
155 echo " locking_dir = \"/tmp\"" >> "$DESTDIR/etc/lvm.conf"
156 echo "}" >> "$DESTDIR/etc/lvm.conf"
157 echo "devices {" >> "$DESTDIR/etc/lvm.conf"
158 echo " sysfs_scan=0" >> "$DESTDIR/etc/lvm.conf"
159 if is_yes "$have_md"; then
160 echo " md_component_detection = 1" >> "$DESTDIR/etc/lvm.conf"
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
170 debug "LVM v2: ignore device $dev"
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!
176 lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf"
177 echo "}" >> "$DESTDIR/etc/lvm.conf"
178
179 initrd_gen_devices
180
181 add_linuxrc <<-EOF
182 export ROOTDEV=$rootdev
183 export ROOTVG="$VGVOLUMES"
184 export SUSPENDVG=$SUSPENDVG
185 EOF
186 add_linuxrc <<-'EOF'
187 # parse rootdev from kernel commandline if it begins with /
188 case "$ROOT" in
189 /*)
190 if [ "$ROOT" != "$ROOTDEV" ]; then
191 ROOTDEV=$ROOT
192 echo "LVM: Using 'root=$ROOTDEV' from kernel commandline"
193 local tmp=${ROOTDEV#/dev/}
194 if [ "$tmp" != "$ROOTDEV" ]; then
195 ROOTVG=${tmp%/*}
196 echo "LVM: Using Volume Group '$ROOTVG' for rootfs"
197 fi
198 fi
199 ;;
200 esac
201
202 # skip duplicate VG
203 if [ "$SUSPENDVG" = "$ROOTVG" ]; then
204 export VGVOLUMES="$ROOTVG"
205 else
206 export VGVOLUMES="$SUSPENDVG $ROOTVG"
207 fi
208
209 # disable noise from LVM accessing devices that aren't ready.
210 read printk < /proc/sys/kernel/printk
211 if [ ! "$DEBUGINITRD" ]; then
212 echo 0 > /proc/sys/kernel/printk
213 fi
214
215 export LVM_SYSTEM_DIR=/tmp
216 : 'Scanning for Volume Groups'
217 lvm.static vgscan --mknodes --ignorelockingfailure 2>/dev/null
218
219 : 'Activating Volume Groups'
220 for vol in $VGVOLUMES; do
221 lvm.static vgchange --ignorelockingfailure -a y $vol 2>/dev/null
222 done
223
224 echo "$printk" > /proc/sys/kernel/printk
225
226 # Find out major/minor
227 attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV 2>/dev/null)"
228 if [ "$attrs" ]; then
229 majmin="${attrs#*$ROOTDEV*:*:*:*:*:*:*:*:*:*:*:*}"
230 if [ "$majmin" != "$attrs" ]; then
231 major="${majmin%:*}"
232 minor="${majmin#*:}"
233 fi
234 fi
235
236 if [ "$major" -a "$minor" ]; then
237 # Pass it to kernel
238 echo $((256 * $major + $minor)) > /proc/sys/kernel/real-root-dev
239 else
240 echo 2>&1 "Error figuring out real root device for $ROOTDEV!"
241 echo 2>&1 "System will not most likely boot up! So dropping you to a shell!"
242 echo 2>&1 ""
243 sh
244 fi
245 EOF
246 fi
247}
248
249
250# PRIVATE METHODS
251
252# find PV names from given VG name
253# @param string $vg Volume Group name
254# @access private
255find_lvm_pv() {
256 local vg="$1"
257
b034011e 258 local pv=$(/sbin/vgs --noheadings -o pv_name "$vg")
67aa84bd
ER
259 echo $pv
260}
261
262# find VG name from given devnode
263# @param string $devnode device node to be examined
264# @access private
265find_lvm_vg() {
266 local devnode="$1"
267
b034011e 268 local vg=$(/sbin/lvs --noheadings -o vg_name "$devnode")
67aa84bd
ER
269 echo $vg
270}
This page took 0.13466 seconds and 4 git commands to generate.