]> git.pld-linux.org Git - projects/geninitrd.git/blobdiff - mod-lvm.sh
- swsusp support from mis@pld-linux
[projects/geninitrd.git] / mod-lvm.sh
index 3fef638179a89844e52d9ce8dca2df5ffd6a59a3..99abd4225132cf17f3a765abefdfcdb0c56df72b 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/sh
-#
 # geninitrd mod: LVM
+USE_LVM=${USE_LVM:-yes}
 
 # if we should init LVM at boot
 have_lvm=no
@@ -8,28 +8,38 @@ have_lvm=no
 # LVM volumes that are needed to activate
 # VG for root dev
 # @internal
-ROOTVG=""
+LVM_ROOTVG=""
 
 # VG for suspend resume dev
-SUSPENDVG=""
+LVM_SUSPENDVG=""
 
-VGVOLUMES=""
+LVM_VGVOLUMES=""
 
 # LVM version. Autodetected if not set.
 # Values: 1|2
 LVMTOOLSVERSION=
 
-lvm=$(find_tool $initrd_dir/lvm /sbin/initrd-lvm)
-if [ -x /sbin/lvm -a -x "$lvm" ]; then
-       USE_LVM=yes
-else
-       USE_LVM=no
-fi
-
 # LVM devices that should not be included in vgscan on initrd.
 # @internal
 lvm_ignore_devices=''
 
+# setup geninitrd module
+# @access      public
+setup_mod_lvm() {
+       lvm=$(find_tool $initrd_dir/lvm /sbin/initrd-lvm)
+
+       if [ ! -x "$lvm" ]; then
+               USE_LVM=no
+       fi
+
+       if is_yes "$USE_LVM" && [ -z "$LVMTOOLSVERSION" ]; then
+               LVMTOOLSVERSION=$(LC_ALL=C $lvm vgchange --version 2>/dev/null | awk '/LVM version:/{if ($3 >= 2) print "2"}')
+               if [ -z "$LVMTOOLSVERSION" ]; then
+                       die "Can't determine LVM tools version (is /sys mounted?). Please set LVMTOOLSVERSION and rerun $PROGRAM."
+               fi
+       fi
+}
+
 # return true if node is lvm node
 # @param       string $node device node to be examined
 # @access      public
@@ -55,11 +65,11 @@ is_lvm() {
                return 0
        fi
 
-       /sbin/lvm lvdisplay "$node" > /dev/null 2>&1
+       $lvm lvdisplay "$node" > /dev/null 2>&1
        rc=$?
        if [ $rc -gt 127 ]; then
                # lvdisplay terminated by signal! most likely it segfaulted.
-               die "Unexpected exit from 'lvdisplay $node': $rc - are your lvm tools broken?"
+               die "Unexpected exit from '$lvm lvdisplay $node': $rc - are your lvm tools broken?"
        fi
 
        return $rc
@@ -71,25 +81,14 @@ is_lvm() {
 find_modules_lvm() {
        local devpath="$1"
 
-       debug "LVM: $devpath is LVM node"
-
-       if [ ! -x $lvm -o ! -x /sbin/lvdisplay -o ! -x /sbin/pvdisplay ]; then
-               die "root on LVM but /sbin/lvdisplay or /sbin/pvdisplay not found. Please install lvm(2) and lvm(2)-initrd package and rerun $PROGRAM."
-       fi
-
-       if [ -z "$LVMTOOLSVERSION" ]; then
-               LVMTOOLSVERSION=$(LC_ALL=C $lvm vgchange --version 2>/dev/null | awk '/LVM version:/{if ($3 >= 2) print "2"}')
-               if [ -z "$LVMTOOLSVERSION" ]; then
-                       die "Can't determine LVM tools version. Please set LVMTOOLSVERSION and rerun $PROGRAM."
-               fi
-       fi
+       verbose "LVM: $devpath is LVM node"
 
        local vg=$(find_lvm_vg "$devpath")
-       debug "LVM VG for $devpath: $vg"
-       VGVOLUMES=$(echo $VGVOLUMES $vg | tr ' ' '\n' | sort -u)
+       verbose "LVM VG for $devpath: $vg"
+       LVM_VGVOLUMES=$(echo $LVM_VGVOLUMES $vg | tr ' ' '\n' | sort -u)
 
        local pv=$(find_lvm_pv "$vg")
-       debug "LVM PV for $vg: $pv"
+       verbose "LVM PV for $vg: $pv"
        PVDEVICES=$(echo $PVDEVICES $pv | tr ' ' '\n' | sort -u)
 
        if [ -n "$PVDEVICES" ]; then
@@ -97,7 +96,7 @@ find_modules_lvm() {
                        find_modules_for_devpath $device
                done
        else
-               die "I wasn't able to find PV (via lvdisplay and pvdisplay). You can try to set PVDEVICES in /etc/sysconfig/geninitrd."
+               die "I wasn't able to find PV. You can try to set PVDEVICES in /etc/sysconfig/geninitrd."
        fi
 
        if [ "$LVMTOOLSVERSION" = "2" ]; then
@@ -109,7 +108,7 @@ find_modules_lvm() {
                die "LVM version $LVMTOOLSVERSION is not supported."
        fi
 
-       debug "LVM v$LVMTOOLSVERSION enabled"
+       verbose "LVM v$LVMTOOLSVERSION enabled"
        have_lvm=yes
 }
 
@@ -117,7 +116,11 @@ find_modules_lvm() {
 # generate initrd fragment for lvm
 # @access      public
 initrd_gen_lvm() {
-       debug "Adding LVM support to initrd"
+       if ! is_yes "$have_lvm"; then
+               return
+       fi
+
+       verbose "Adding LVM support to initrd"
        inst_d /tmp /newroot
        inst_exec $lvm /bin/lvm.static
 
@@ -128,7 +131,7 @@ initrd_gen_lvm() {
 
        if ! is_yes "$dev_mounted"; then
                inst_d /dev/mapper
-               mknod $DESTDIR/dev/mapper/control c 10 63
+               mknod -m 600 $DESTDIR/dev/mapper/control c 10 63
                for device in $PVDEVICES; do
                        # if LVM on RAID then device might be copied already in gen_md
                        [ -e "$DESTDIR/dev/$(basename $device)" ] && continue
@@ -136,24 +139,25 @@ initrd_gen_lvm() {
                done
        fi
 
-       mount_tmp
+       mount_sys
        if [ "$LVMTOOLSVERSION" = "1" ]; then
                add_linuxrc <<-EOF
                        lvm vgscan -T
-                       for vg in $VGVOLUMES; do
+                       for vg in $LVM_VGVOLUMES; do
                                lvm vgchange -T -a y $vg
                        done
                EOF
        else
-               echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc
-               echo "global {" > "$DESTDIR/etc/lvm.conf"
-               echo "  locking_type = 0" >> "$DESTDIR/etc/lvm.conf"
-               echo "  locking_dir = \"/tmp\"" >> "$DESTDIR/etc/lvm.conf"
-               echo "}" >> "$DESTDIR/etc/lvm.conf"
-               echo "devices {" >> "$DESTDIR/etc/lvm.conf"
-               echo "  sysfs_scan=0" >> "$DESTDIR/etc/lvm.conf"
+               cat <<-EOF > "$DESTDIR/etc/lvm.conf"
+               global {
+                       locking_type = 0
+                       locking_dir = "/tmp"
+               }
+               devices {
+                       sysfs_scan=0
+               EOF
                if is_yes "$have_md"; then
-                       echo "  md_component_detection = 1" >> "$DESTDIR/etc/lvm.conf"
+                       echo "  md_component_detection=1" >> "$DESTDIR/etc/lvm.conf"
                fi
                if is_yes "$have_dmraid" || is_yes "$have_multipath"; then
                        echo '  types = [ "device-mapper", 254 ]' >> "$DESTDIR/etc/lvm.conf"
@@ -163,43 +167,64 @@ initrd_gen_lvm() {
                        echo '  filter = [' >> "$DESTDIR/etc/lvm.conf"
                        local dev
                        for dev in $lvm_ignore_devices; do
-                               debug "LVM v2: ignore device $dev"
+                               verbose "LVM v2: ignore device $dev"
                                printf '  "r|^%s.*|",\n' $dev
                        done >> "$DESTDIR/etc/lvm.conf"
                        echo ']' >> "$DESTDIR/etc/lvm.conf"
                fi
                # XXX filter= must be on one line!
-               lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf"
+               $lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf"
                echo "}" >> "$DESTDIR/etc/lvm.conf"
 
+               echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc
+
                initrd_gen_devices
 
                add_linuxrc <<-EOF
-                       export ROOTDEV=$rootdev
-                       export ROOTVG="$VGVOLUMES"
-                       export SUSPENDVG=$SUSPENDVG
+                       ROOTDEV=$rootdev
+                       LVM_ROOTVG="$LVM_VGVOLUMES"
+                       LVM_SUSPENDVG="$LVM_SUSPENDVG"
                EOF
+
+               # need awk for "s/--/-/g" subst when parsing kernel root commandline
+               busybox_applet awk
                add_linuxrc <<-'EOF'
                        # parse rootdev from kernel commandline if it begins with /
                        case "$ROOT" in
                                /*)
+
+                               # rewrite:
+                               # /dev/mapper/sys-rootfs -> /dev/sys/rootfs
+                               # /dev/mapper/blodnatt-blah--bleh -> /dev/blodnatt/blah-bleh
+                               # /dev/mapper/vg--meaw-root -> /dev/vg-meaw/root
+                               case "$ROOT" in
+                                       /dev/mapper/*-*)
+                                               # change "--" to / (as "/" is impossible in LV name)
+                                               local dev=$(awk -vdev="${ROOT#/dev/mapper/}" 'BEGIN{gsub(/--/, "/", dev); print dev}')
+                                               local VG=$(awk -vdev="$dev" 'BEGIN{split(dev, v, "-"); gsub("/", "-", v[1]); print v[1]}')
+                                               local LV=$(awk -vdev="$dev" 'BEGIN{split(dev, v, "-"); gsub("/", "-", v[2]); print v[2]}')
+                                               ROOT=/dev/$VG/$LV
+                                       ;;
+                               esac
+
                                if [ "$ROOT" != "$ROOTDEV" ]; then
                                        ROOTDEV=$ROOT
+
                                        echo "LVM: Using 'root=$ROOTDEV' from kernel commandline"
                                        local tmp=${ROOTDEV#/dev/}
                                        if [ "$tmp" != "$ROOTDEV" ]; then
-                                               ROOTVG=${tmp%/*}
-                                               echo "LVM: Using Volume Group '$ROOTVG' for rootfs"
+                                               LVM_ROOTVG=${tmp%/*}
+                                               echo "LVM: Using Volume Group '$LVM_ROOTVG' for rootfs"
                                        fi
                                fi
                                ;;
                        esac
 
                        # skip duplicate VG
-                       if [ "$SUSPENDVG" = "$ROOTVG" ]; then
-                               export VGVOLUMES="$ROOTVG"
+                       if [ "$LVM_SUSPENDVG" = "$LVM_ROOTVG" ]; then
+                               LVM_VGVOLUMES="$LVM_ROOTVG"
                        else
-                               export VGVOLUMES="$SUSPENDVG $ROOTVG"
+                               LVM_VGVOLUMES="$LVM_SUSPENDVG $LVM_ROOTVG"
                        fi
 
                        # disable noise from LVM accessing devices that aren't ready.
@@ -209,18 +234,22 @@ initrd_gen_lvm() {
                        fi
 
                        export LVM_SYSTEM_DIR=/tmp
+
                        : 'Scanning for Volume Groups'
-                       lvm.static vgscan --mknodes --ignorelockingfailure 2>/dev/null
+                       lvm.static vgscan --mknodes --ignorelockingfailure
 
                        : 'Activating Volume Groups'
-                       for vol in $VGVOLUMES; do
-                               lvm.static vgchange --ignorelockingfailure -a y $vol 2>/dev/null
+                       for vol in $LVM_VGVOLUMES; do
+                               lvm.static vgchange --ignorelockingfailure -a y $vol --noudevsync
                        done
 
+                       : 'Extra call to make device nodes for non lvm2-initrd (dynamic lvm2)'
+                       lvm.static vgmknodes --ignorelockingfailure
+
                        echo "$printk" > /proc/sys/kernel/printk
 
                        # Find out major/minor
-                       attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV 2>/dev/null)"
+                       attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV)"
                        if [ "$attrs" ]; then
                                majmin="${attrs#*$ROOTDEV*:*:*:*:*:*:*:*:*:*:*:*}"
                                if [ "$majmin" != "$attrs" ]; then
@@ -232,12 +261,10 @@ initrd_gen_lvm() {
                        if [ "$major" -a "$minor" ]; then
                                # Pass it to kernel
                                echo $((256 * $major + $minor)) > /proc/sys/kernel/real-root-dev
-                       else
-                               echo 2>&1 "Error figuring out real root device for $ROOTDEV!"
-                               echo 2>&1 "System will not most likely boot up! So dropping you to a shell!"
-                               echo 2>&1 ""
-                               sh
                        fi
+
+                       debugshell
+                       unset LVM_SYSTEM_DIR
                EOF
        fi
 }
@@ -251,7 +278,7 @@ initrd_gen_lvm() {
 find_lvm_pv() {
        local vg="$1"
 
-       local pv=$(/sbin/vgs --noheadings -o pv_name  "$vg")
+       local pv=$($lvm vgs --noheadings -o pv_name  "$vg")
        echo $pv
 }
 
@@ -261,6 +288,6 @@ find_lvm_pv() {
 find_lvm_vg() {
        local devnode="$1"
 
-       local vg=$(/sbin/lvs --noheadings -o vg_name  "$devnode")
+       local vg=$($lvm lvs --noheadings -o vg_name  "$devnode")
        echo $vg
 }
This page took 0.335594 seconds and 4 git commands to generate.