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