2 LVM_RCSID='$Revision$ $Date:: $'
5 USE_LVM=${USE_LVM:-yes}
7 # if we should init LVM at boot
10 # LVM volumes that are needed to activate
15 # VG for suspend resume dev
20 # LVM version. Autodetected if not set.
24 # LVM devices that should not be included in vgscan on initrd.
28 # setup geninitrd module
31 lvm=$(find_tool $initrd_dir/lvm /sbin/initrd-lvm)
33 if [ ! -x "$lvm" ]; then
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"}')
39 if [ -z "$LVMTOOLSVERSION" ]; then
40 die "Can't determine LVM tools version (is /sys mounted?). Please set LVMTOOLSVERSION and rerun $PROGRAM."
45 # return true if node is lvm node
46 # @param string $node device node to be examined
52 if is_no "$USE_LVM"; then
56 if [ ! -e "$node" ]; then
57 die "check_lvm(): node $node doesn't exist!"
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; }}'
70 $lvm lvdisplay "$node" > /dev/null 2>&1
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?"
80 # find modules for $devpath
81 # @param $devpath device to be examined
86 verbose "LVM: $devpath is LVM node"
88 local vg=$(find_lvm_vg "$devpath")
89 verbose "LVM VG for $devpath: $vg"
90 LVM_VGVOLUMES=$(echo $LVM_VGVOLUMES $vg | tr ' ' '\n' | sort -u)
92 local pv=$(find_lvm_pv "$vg")
93 verbose "LVM PV for $vg: $pv"
94 PVDEVICES=$(echo $PVDEVICES $pv | tr ' ' '\n' | sort -u)
96 if [ -n "$PVDEVICES" ]; then
97 for device in $PVDEVICES; do
98 find_modules_for_devpath $device
101 die "I wasn't able to find PV. You can try to set PVDEVICES in /etc/sysconfig/geninitrd."
104 if [ "$LVMTOOLSVERSION" = "2" ]; then
105 find_module "-dm-mod"
106 elif [ "$LVMTOOLSVERSION" = "1" ]; then
108 find_module "-lvm-mod"
110 die "LVM version $LVMTOOLSVERSION is not supported."
113 verbose "LVM v$LVMTOOLSVERSION enabled"
118 # generate initrd fragment for lvm
121 if ! is_yes "$have_lvm"; then
125 verbose "Adding LVM support to initrd"
127 inst_exec $lvm /bin/lvm.static
129 # always make /dev on tmpfs for LVM2
130 if [ "$LVMTOOLSVERSION" = "2" ]; then
134 if ! is_yes "$dev_mounted"; then
136 mknod -m 600 $DESTDIR/dev/mapper/control c 10 63
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
146 if [ "$LVMTOOLSVERSION" = "1" ]; then
149 for vg in $LVM_VGVOLUMES; do
150 lvm vgchange -T -a y $vg
154 cat <<-EOF > "$DESTDIR/etc/lvm.conf"
162 if is_yes "$have_md"; then
163 echo " md_component_detection=1" >> "$DESTDIR/etc/lvm.conf"
165 if is_yes "$have_dmraid" || is_yes "$have_multipath"; then
166 echo ' types = [ "device-mapper", 254 ]' >> "$DESTDIR/etc/lvm.conf"
168 if [ "$lvm_ignore_devices" ]; then
169 # TODO: think of merging with lvm dumpconfig output
170 echo ' filter = [' >> "$DESTDIR/etc/lvm.conf"
172 for dev in $lvm_ignore_devices; do
173 verbose "LVM v2: ignore device $dev"
174 printf ' "r|^%s.*|",\n' $dev
175 done >> "$DESTDIR/etc/lvm.conf"
176 echo ']' >> "$DESTDIR/etc/lvm.conf"
178 # XXX filter= must be on one line!
179 $lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf"
180 echo "}" >> "$DESTDIR/etc/lvm.conf"
182 echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc
188 LVM_ROOTVG="$LVM_VGVOLUMES"
189 LVM_SUSPENDVG="$LVM_SUSPENDVG"
192 # need awk for "s/--/-/g" subst when parsing kernel root commandline
195 # parse rootdev from kernel commandline if it begins with /
200 # /dev/mapper/sys-rootfs -> /dev/sys/rootfs
201 # /dev/mapper/blodnatt-blah--bleh -> /dev/blodnatt/blah-bleh
202 # /dev/mapper/vg--meaw-root -> /dev/vg-meaw/root
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]}')
213 if [ "$ROOT" != "$ROOTDEV" ]; then
216 echo "LVM: Using 'root=$ROOTDEV' from kernel commandline"
217 local tmp=${ROOTDEV#/dev/}
218 if [ "$tmp" != "$ROOTDEV" ]; then
220 echo "LVM: Using Volume Group '$LVM_ROOTVG' for rootfs"
227 if [ "$LVM_SUSPENDVG" = "$LVM_ROOTVG" ]; then
228 LVM_VGVOLUMES="$LVM_ROOTVG"
230 LVM_VGVOLUMES="$LVM_SUSPENDVG $LVM_ROOTVG"
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
239 export LVM_SYSTEM_DIR=/tmp
241 : 'Scanning for Volume Groups'
242 lvm.static vgscan --mknodes --ignorelockingfailure
244 : 'Activating Volume Groups'
245 for vol in $LVM_VGVOLUMES; do
246 lvm.static vgchange --ignorelockingfailure -a y $vol --noudevsync
249 : 'Extra call to make device nodes for non lvm2-initrd (dynamic lvm2)'
250 lvm.static vgmknodes --ignorelockingfailure
252 echo "$printk" > /proc/sys/kernel/printk
254 # Find out major/minor
255 attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV)"
256 if [ "$attrs" ]; then
257 majmin="${attrs#*$ROOTDEV*:*:*:*:*:*:*:*:*:*:*:*}"
258 if [ "$majmin" != "$attrs" ]; then
264 if [ "$major" -a "$minor" ]; then
266 echo $((256 * $major + $minor)) > /proc/sys/kernel/real-root-dev
278 # find PV names from given VG name
279 # @param string $vg Volume Group name
284 local pv=$($lvm vgs --noheadings -o pv_name "$vg")
288 # find VG name from given devnode
289 # @param string $devnode device node to be examined
294 local vg=$($lvm lvs --noheadings -o vg_name "$devnode")