]> git.pld-linux.org Git - projects/geninitrd.git/blame - mod-lvm.sh
- LVM: rewrite /dev/mapper/sys-rootfs -> /dev/sys/rootfs
[projects/geninitrd.git] / mod-lvm.sh
CommitLineData
67aa84bd
ER
1#!/bin/sh
2#
3# geninitrd mod: LVM
6e49b0b1 4USE_LVM=${USE_LVM:-yes}
67aa84bd
ER
5
6# if we should init LVM at boot
7have_lvm=no
8
9# LVM volumes that are needed to activate
10# VG for root dev
11# @internal
12ROOTVG=""
13
14# VG for suspend resume dev
15SUSPENDVG=""
16
17VGVOLUMES=""
18
f0ef5219
ER
19# LVM version. Autodetected if not set.
20# Values: 1|2
21LVMTOOLSVERSION=
22
67aa84bd
ER
23# LVM devices that should not be included in vgscan on initrd.
24# @internal
25lvm_ignore_devices=''
26
c124d0cf
ER
27# setup geninitrd module
28# @access public
29setup_mod_lvm() {
30 lvm=$(find_tool $initrd_dir/lvm /sbin/initrd-lvm)
c124d0cf 31
728b5283 32 if [ ! -x "$lvm" ]; then
6e49b0b1
ER
33 USE_LVM=no
34 fi
35
36 if is_yes "$USE_LVM" && [ -z "$LVMTOOLSVERSION" ]; then
37 LVMTOOLSVERSION=$(LC_ALL=C $lvm vgchange --version 2>/dev/null | awk '/LVM version:/{if ($3 >= 2) print "2"}')
c124d0cf 38 if [ -z "$LVMTOOLSVERSION" ]; then
074b295e 39 die "Can't determine LVM tools version (is /sys mounted?). Please set LVMTOOLSVERSION and rerun $PROGRAM."
c124d0cf
ER
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
728b5283 69 $lvm lvdisplay "$node" > /dev/null 2>&1
67aa84bd
ER
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
67aa84bd
ER
87 local vg=$(find_lvm_vg "$devpath")
88 debug "LVM VG for $devpath: $vg"
89 VGVOLUMES=$(echo $VGVOLUMES $vg | tr ' ' '\n' | sort -u)
90
91 local pv=$(find_lvm_pv "$vg")
92 debug "LVM PV for $vg: $pv"
93 PVDEVICES=$(echo $PVDEVICES $pv | tr ' ' '\n' | sort -u)
94
95 if [ -n "$PVDEVICES" ]; then
96 for device in $PVDEVICES; do
97 find_modules_for_devpath $device
98 done
99 else
728b5283 100 die "I wasn't able to find PV. You can try to set PVDEVICES in /etc/sysconfig/geninitrd."
67aa84bd
ER
101 fi
102
103 if [ "$LVMTOOLSVERSION" = "2" ]; then
b02a6b13 104 find_module "-dm-mod"
67aa84bd 105 elif [ "$LVMTOOLSVERSION" = "1" ]; then
b02a6b13
ER
106 find_module "-lvm"
107 find_module "-lvm-mod"
67aa84bd 108 else
f0ef5219 109 die "LVM version $LVMTOOLSVERSION is not supported."
67aa84bd
ER
110 fi
111
112 debug "LVM v$LVMTOOLSVERSION enabled"
113 have_lvm=yes
114}
115
116
117# generate initrd fragment for lvm
118# @access public
119initrd_gen_lvm() {
120 debug "Adding LVM support to initrd"
121 inst_d /tmp /newroot
684d5d2a 122 inst_exec $lvm /bin/lvm.static
67aa84bd
ER
123
124 # always make /dev on tmpfs for LVM2
125 if [ "$LVMTOOLSVERSION" = "2" ]; then
126 mount_dev
127 fi
128
129 if ! is_yes "$dev_mounted"; then
130 inst_d /dev/mapper
131 mknod $DESTDIR/dev/mapper/control c 10 63
132 for device in $PVDEVICES; do
133 # if LVM on RAID then device might be copied already in gen_md
134 [ -e "$DESTDIR/dev/$(basename $device)" ] && continue
135 inst $device /dev
136 done
137 fi
138
139 mount_tmp
7170bd62 140 mount_sys
67aa84bd
ER
141 if [ "$LVMTOOLSVERSION" = "1" ]; then
142 add_linuxrc <<-EOF
143 lvm vgscan -T
144 for vg in $VGVOLUMES; do
145 lvm vgchange -T -a y $vg
146 done
147 EOF
148 else
149 echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc
150 echo "global {" > "$DESTDIR/etc/lvm.conf"
151 echo " locking_type = 0" >> "$DESTDIR/etc/lvm.conf"
152 echo " locking_dir = \"/tmp\"" >> "$DESTDIR/etc/lvm.conf"
153 echo "}" >> "$DESTDIR/etc/lvm.conf"
154 echo "devices {" >> "$DESTDIR/etc/lvm.conf"
155 echo " sysfs_scan=0" >> "$DESTDIR/etc/lvm.conf"
156 if is_yes "$have_md"; then
157 echo " md_component_detection = 1" >> "$DESTDIR/etc/lvm.conf"
158 fi
159 if is_yes "$have_dmraid" || is_yes "$have_multipath"; then
160 echo ' types = [ "device-mapper", 254 ]' >> "$DESTDIR/etc/lvm.conf"
161 fi
162 if [ "$lvm_ignore_devices" ]; then
163 # TODO: think of merging with lvm dumpconfig output
164 echo ' filter = [' >> "$DESTDIR/etc/lvm.conf"
165 local dev
166 for dev in $lvm_ignore_devices; do
167 debug "LVM v2: ignore device $dev"
168 printf ' "r|^%s.*|",\n' $dev
169 done >> "$DESTDIR/etc/lvm.conf"
170 echo ']' >> "$DESTDIR/etc/lvm.conf"
171 fi
172 # XXX filter= must be on one line!
728b5283 173 $lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf"
67aa84bd
ER
174 echo "}" >> "$DESTDIR/etc/lvm.conf"
175
176 initrd_gen_devices
177
178 add_linuxrc <<-EOF
179 export ROOTDEV=$rootdev
180 export ROOTVG="$VGVOLUMES"
181 export SUSPENDVG=$SUSPENDVG
182 EOF
183 add_linuxrc <<-'EOF'
184 # parse rootdev from kernel commandline if it begins with /
185 case "$ROOT" in
186 /*)
2ade15a8
ER
187
188 # rewrite /dev/mapper/sys-rootfs -> /dev/sys/rootfs
189 case "$ROOT" in
190 /dev/mapper/*-*)
191 ROOT=${ROOT#/dev/mapper/}
192 local VG=${ROOT%%-*}
193 local LV=${ROOT#*-}
194 ROOT=/dev/$VG/$LV
195 ;;
196 esac
197
67aa84bd
ER
198 if [ "$ROOT" != "$ROOTDEV" ]; then
199 ROOTDEV=$ROOT
2ade15a8 200
67aa84bd
ER
201 echo "LVM: Using 'root=$ROOTDEV' from kernel commandline"
202 local tmp=${ROOTDEV#/dev/}
203 if [ "$tmp" != "$ROOTDEV" ]; then
204 ROOTVG=${tmp%/*}
205 echo "LVM: Using Volume Group '$ROOTVG' for rootfs"
206 fi
207 fi
208 ;;
209 esac
210
211 # skip duplicate VG
212 if [ "$SUSPENDVG" = "$ROOTVG" ]; then
213 export VGVOLUMES="$ROOTVG"
214 else
215 export VGVOLUMES="$SUSPENDVG $ROOTVG"
216 fi
217
218 # disable noise from LVM accessing devices that aren't ready.
219 read printk < /proc/sys/kernel/printk
220 if [ ! "$DEBUGINITRD" ]; then
221 echo 0 > /proc/sys/kernel/printk
222 fi
223
224 export LVM_SYSTEM_DIR=/tmp
225 : 'Scanning for Volume Groups'
226 lvm.static vgscan --mknodes --ignorelockingfailure 2>/dev/null
227
228 : 'Activating Volume Groups'
229 for vol in $VGVOLUMES; do
230 lvm.static vgchange --ignorelockingfailure -a y $vol 2>/dev/null
231 done
232
233 echo "$printk" > /proc/sys/kernel/printk
234
235 # Find out major/minor
236 attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV 2>/dev/null)"
237 if [ "$attrs" ]; then
238 majmin="${attrs#*$ROOTDEV*:*:*:*:*:*:*:*:*:*:*:*}"
239 if [ "$majmin" != "$attrs" ]; then
240 major="${majmin%:*}"
241 minor="${majmin#*:}"
242 fi
243 fi
244
245 if [ "$major" -a "$minor" ]; then
246 # Pass it to kernel
247 echo $((256 * $major + $minor)) > /proc/sys/kernel/real-root-dev
248 else
249 echo 2>&1 "Error figuring out real root device for $ROOTDEV!"
250 echo 2>&1 "System will not most likely boot up! So dropping you to a shell!"
251 echo 2>&1 ""
252 sh
253 fi
254 EOF
255 fi
256}
257
258
259# PRIVATE METHODS
260
261# find PV names from given VG name
262# @param string $vg Volume Group name
263# @access private
264find_lvm_pv() {
265 local vg="$1"
266
728b5283 267 local pv=$($lvm vgs --noheadings -o pv_name "$vg")
67aa84bd
ER
268 echo $pv
269}
270
271# find VG name from given devnode
272# @param string $devnode device node to be examined
273# @access private
274find_lvm_vg() {
275 local devnode="$1"
276
728b5283 277 local vg=$($lvm lvs --noheadings -o vg_name "$devnode")
67aa84bd
ER
278 echo $vg
279}
This page took 0.158021 seconds and 4 git commands to generate.