Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[HOWTO] lvm2 for root, swap and software suspend2 (edit)
View unanswered posts
View posts from last 24 hours

Goto page 1, 2, 3, 4, 5, 6  Next  
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Mon Jul 17, 2006 3:00 am    Post subject: [HOWTO] lvm2 for root, swap and software suspend2 (edit) Reply with quote

Let me state up front that it will be an automatic deduction of 10 geek
points for anyone who asks me why.

Some day I might find a good boot loader with lvm2 support built in but,
for now, I will be using grub with a small boot partition not part of
lvm2. Everything else (root, swap, etc.) will all be in lvm2.

The basic steps are to

1) Configure your system with a small boot partition at the front and
add the rest of your disk space into lvm2. There is plenty of details
out there for setting up lvm2 so I will not go into it here.

2) Create logical partitions for root (/), and for swap and for anything
else you feel like having logical partitions for.

3) Install your system onto the lvm2 logical volumes.

4) Compile your kernel (suspend2 sources to use hibernate) with dm-mod
(either in kernel or as a module) and with ramdisk and initial ramdisk
support. The ram disk can't be compiled as a module.

5) Create your initial ram disk with the script provided in this how to.

6) Setup grub (that's what I use, if you use lilo it will work, but you
won't find the directions here) pointing to your kernel with parameters
lvm2root and lvm2resume2 pointing to your lvm2 root logical volume and
your lvm2 swap logical volume respectively

7) Enjoy the coolness of a fully lvm2 system with all that flexibility
and software suspend.

CONFIGURING THE DISK

I make my boot partition 50Megs. That gives me room for about 20 kernels
before I need to start cleaning things up. You can make yours any size
your want, just put it at the front of the disk and give it a partition
type of 83.

I made the rest of the disk (partition 2) with a type of 8e. That is
certainly not the only way to do it, but it works and makes pretty good
sense. There is no reason you can't add a second disk with 1 (or more)
partitions of type 8e and use them as part of this setup.

CREATING LOGICAL VOLUMES

With LVM2 you can use a different strategy than you might be used
to. Instead of building your partitions big enough for anything you
might throw at them, you want to build your logical volumes so that they
are pretty close to full. Leave enough room for day to day operations
but since you can grow the space any time you need to, don't lock it
into a partition until you really need it.

For example, 4G for slash on my laptop is good and snug. If you
separated out /usr/portage into another logical partition, I could make
that even smaller. Your swap partition can me made nice and small (just
enough room to run the larger programs you normally run) maybe less than
your current memory size. If you want to run something big that will
actually use a lot of swap, just create a second swap volume and add it
in on the fly.

INSTALLING YOUR SYSTEM

The install goes just the way it would on a normal system. Once you
chroot into your logical volumes, you won't be able to tell the
difference. Just be sure to install the lvm2 package.

COMPILING YOUR KERNEL

I would suggest using the suspend2-sources. While you can use the
vanilla-sources and patch it yourself, that loses it's charm after
about the second kernel upgrade.

The only things you need to have above and beyond what you need for
your system and for setting up the software suspend2 stuff is the
device mapper and initial ram disk. You can find the device mapper in
drivers->multi device and you can either compile it in the kernel or
add it as a module. You can find the ram disk support in devices->block
devices and you must compile it in the kernel. You also need to select
initial ram disk support.

Compile and install your kernel in the normal fashion.

CREATING THE INITIAL RAMDISK

This is the tricky part. Your initial ramdisk will need to activate
lvm2, initialize software suspend2 functionality and switch to the lvm2
root filesystem. For software suspend2 to work, it has to do all that
without using a read/write filesystem on your ramdisk.

I started with the lvm2create_initrd script that comes the lvm2 sources
and added Gentoo specific changes (such as using the full featured
statically compiled busybox in Gentoo called bb) and then added in
changes to deal with not mounting the ramdisk read/write.

This script will calculate the size of ramdisk needed to hold the
required utilities (currently /sbin/lvm and /bin/bb) as well as any
additional modules and then it creates the ramdisk and copies everything
needed into it.

The script also builds an /sbin/init script for the ramdisk that will
deal with activating lvm2 and setting up software suspend2.

Creating the ramdisk got a little tricky because busybox on Gentoo
compiles in so many of the applets that I ran out of inoes when linking
in all of the command names. The script now specified the number of
indoes needed as 500 and that seems to cover the current needs.

Creating a /sbin/init script that meets the requirements of lvm2 and
software suspend2 was also tricky. In order for software suspend2
to be willing to resume from a suspend, no device backed filesystem
can be mounted rw before the resume. The ram disk is a device backed
filesystem. In order to activate lvm2, the device mapper has to be
loaded and device files need to be created matching the current device
major and minor numbers. Those files can't be created in the /dev in the
ramdisk or you break the read/write rule. The solution turned out to be
mounting a tmpfs filesystem over /dev (tmpfs has no device associated
with it) and re-creating dev there and then building the rest of what is
needed.

Due to the dynamic nature of the device mapper's major and minor
numbers, there is no way for the kernel to deal with the normal
parameters of root= and resume2= while booting. For this reason,
the /sbin/init script will look for the parameters lvm2root= and
lvm2resume2= and use them to define the root and resume partitions after
lvm2 is activated.

To activate software suspend2, you need to provide a value for
resume2 in /proc/suspend2/resume2 and then create the file
/proc/suspend2/do_resume. This will not make any sense to the kernel
until after lvm2 is activated.

EDIT: As of 1.94-r3 of the hibernate scrips, I have had to put the line

EDIT: Added support for tuxonice (thanks to Heinzi)

EDIT: 3/19/08 Increased number of indoes in mke2fs command.

EDIT: 4/18/08 Re-worked script to use cpio based initrd instead of ramdisk.

EDIT: 4/19/08 Use switch_root for better cleanup.

EDIT: 5/27/08 Added flag for baselayout 2 (also needs makedev package installed) Also, xen support.

EDIT: 11/22/08 Added ability to create filesystems from rescue mode.

EDIT: 12/20/09 Move sysfs mount to make things work better with lvm update.

EDIT: 1/4/10 A little cleanup and version change.

EDIT: 8/26/10 Better module handling (looks up dependencies, does not need full path).

EDIT: 5/9/11 Fix issue with baselayout 2 and sysfs.

EDIT: 5/12/11 Deal with new version of modprobe

EDIT: 4/12/13 Added luks encryption and kernel suspend support

Code:

SuspendDevice /dev/vg00/swap


in my hibernate.conf in order for hibernate to work. Seems they have added some sanity checking code that does not take what we are doing here into account.

My modified script follows: (EDIT: Found some bugs when adding non static executables)
Code:

#!/bin/bash
#
# lvm2create_initrd: Version 3.0
#
# Blatantly stolen from code written by
#
# Miguel Cabeca cabeca (at) ist (dot) utl (dot) pt
#
# and modified for Gentoo and my own nefarious purposes. Don't blame the
# original author or even bug him about this script. If you have
# problems, try posting to the Gentoo forums
#
# Raffi

TMPMNT=/tmp/mnt.$$
DEVRAM=/tmp/initrd.$$

# set defaults
BINFILES=${BINFILES:-"/sbin/lvm /bin/bb"}
BASICDEVICES=${BASICDEVICES:-"std console fd"}
BLOCKDEVICES=${BLOCKDEVICES:-"md hda hdb hdc hdd sda sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl"}
MAKEDEV=${MAKEDEV:-"gentoo-b2"}

# Uncomment this if you want to disable automatic size detection

PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH

usage () {
        echo "Create an initial ramdisk image for LVM2 root filesystem"
        echo "$cmd: [-h] [-v] [-c lvm.conf] [-m modulelist] [-e extrafiles] [-f fstypes] -r [raiddevs] [-R mdadm.conf] [-M style] [kernel version]"
        echo "      -h|--help      print this usage message"
        echo "      -v|--verbose   verbose progress messages"
        echo "      -c|--lvmconf   path to lvm.conf (/etc/lvm/lvm.conf)"
        echo "      -k|--keyfile   Keyfile for luks"
        echo "      -l|--luks      Add support for luks encrypted disks"
        echo "      -m|--modules   modules to copy to initrd image"
        echo "      -e|--extra     extra files to add to initrd"
        echo "      -f|--fstools   Add filesystem tools"
        echo "      -r|--raid      raid devices to start in initrd"
        echo "      -R|--raidconf  location of mdadm.conf file to include"
        echo "      -M|--makedev   set MAKEDEV type (gentoo, debian or redhat)"
        echo "      -x|--xen       Add xen device support"
}

verbose () {
        [ "$VERBOSE" ] && echo "`echo $cmd | tr '[a-z0-9/_]' ' '` -- $1" || true
}

cleanup () {
        [ "`mount | grep $DEVRAM`" ] && verbose "unmounting $DEVRAM" && umount $DEVRAM
        [ -f $DEVRAM ] && verbose "removing $DEVRAM" && rm $DEVRAM
        [ -d $TMPMNT ] && verbose "removing $TMPMNT" && rmdir $TMPMNT
        verbose "exit with code $1"
        exit $1
}

trap "
        verbose 'Caught interrupt'
        echo 'Bye bye...'
        cleanup 1
" 1 2 3 15

create_init () {
        cat << 'INIT' > $TMPMNT/init
#!/bin/ash

# include in the path some dirs from the real root filesystem
# for chroot, blockdev
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/lib/lvm-200:/initrd/bin:/initrd/sbin"
PRE="initrd:"

do_shell(){
        /bin/echo
        /bin/echo "*** Entering LVM2 rescue shell. Exit shell to continue booting. ***"
        /bin/echo
        /bin/setsid /bin/cttyhack /bin/ash
}

# We need /proc for device mapper and reading cmdline
echo "$PRE Mounting /proc"
mount -n -t proc none /proc
mount -n -t sysfs none /sys

# Read command line arguments.
#
# Device-Mapper dynamically allocates all device numbers. This means
# it is possible that the root volume specified to LILO or Grub may
# have a different number when the initrd runs than when the system
# was last running. In order to make sure the correct volume is
# mounted as root, the init script must determine what the desired
# root volume name is by getting the LVM2 root volume name from
# the kernel command line. In order for this to work correctly,
# "lvm2root=/dev/Volume_Group_Name/Root_Volume_Name" needs to be passed
# to the kernel command line (where Root_Volume_Name is replaced by your
# actual root volume's name. The same problem exists for resume2 and is
# fixed by passing "lvm2resume2=..."

for arg in `cat /proc/cmdline`; do
        case "$arg" in
        luks=*)
                encrypted=${arg#luks=}
        ;;
        lvm2root=*)
                rootvol=${arg#lvm2root=}
        ;;
        root=*)
                rootvol=${arg#root=}
        ;;
        lvm2usr=*)
                usrvol=${arg#lvm2usr=}
        ;;
        lvm2resume2=*)
                resume2=${arg#lvm2resume2=}
        ;;
        lvm2rescue)
                rescue="YES"
        ;;
esac
done

mount -o remount,rw rootfs /

# plug in modules listed in /etc/modules
if [ -f /etc/modules ]; then
        echo -n "$PRE plugging in kernel modules:"
        cat /etc/modules |
        while read module; do
                echo -n " $module"
                modprobe $module
        done
        echo '.'
fi

# start raid devices if raid_autostart file exists
if [ -f /etc/raid_autostart ]; then
        if [ ! -f /etc/mdadm/mdadm.conf ]; then
                #mdoptions='--super-minor=dev'
                # Remove super-minor. It does not work with metadata after .90
                mdoptions=
        fi
        cat /etc/raid_autostart|
        while read dev; do
                echo "Starting RAID device $dev"
                /sbin/mdadm --assemble $dev $mdoptions
        done
fi

# Create the /dev/mapper/control device for the ioctl
# interface using the major and minor numbers that have been allocated
# dynamically.

echo -n "$PRE Finding device mapper major and minor numbers "

MAJOR=$(sed -n 's/^ *\([0-9]\+\) \+misc$/\1/p' /proc/devices)
MINOR=$(sed -n 's/^ *\([0-9]\+\) \+device-mapper$/\1/p' /proc/misc)

if test -n "$MAJOR" -a -n "$MINOR" ; then
        mkdir -p -m 755 /dev/mapper
        mknod -m 600 /dev/mapper/control c $MAJOR $MINOR
fi

echo "($MAJOR,$MINOR)"

if grep -q xvd /proc/devices ; then
        echo "$PRE Adding xen block disk support"

        for dev in a b c d; do

                case $dev in
                a)
                        MINOR=0
                        ;;
                b)
                        MINOR=16
                        ;;
                c)
                        MINOR=32
                        ;;
                d)
                        MINOR=48
                        ;;
                esac

# Create xvd disk node
                device="/dev/xvd$dev"
                mknod -m 600 $device b 202 $MINOR

# Create partition nodes for each partition found.
                fdisk -l $device | sed -n "s|$device\([0-9][0-9]*\).*|\1|p" |
                while read part; do
                        mknod -m 600 $device$part b 202 `expr $MINOR + $part`
                done

        done

fi

for d in `echo $encrypted | sed 's/,/ /g'`; do
        DEV=`echo $d | sed 's/:.*//'`
        CNAM=`echo $d | sed 's/.*://'`
        [ "$CNAM" = "$DEV" ] && CNAM="`basename $DEV`-clear"

        if [ -f /.lukskey ]; then
                cryptsetup --key-file /.lukskey luksOpen $DEV $CNAM
        else
                cryptsetup luksOpen $DEV $CNAM
        fi

        if [ $? != 0 ]; then
                echo "\t*FAILED*";
                do_shell
        fi

done

echo "$PRE Activating LVM2 volumes"
lvm vgscan

# run a shell if we're passed lvm2rescue on commandline
if [ "$rescue" = "YES" ]; then
        lvm vgchange --ignorelockingfailure -P -a y
        do_shell
else
        lvm vgchange --ignorelockingfailure -a y
fi

# Setup software suspend2

if [ -n "$resume2" ]; then

        # Create kernel swapsuspend device

        if [ -f /sys/class/misc/snapshot/dev ]; then
                MAJOR=$(sed -n 's/^\([0-9]\+\):.*/\1/p' /sys/class/misc/snapshot/dev)
                MINOR=$(sed -n 's/^.*:\([0-9]\+\)$/\1/p' /sys/class/misc/snapshot/dev)
                mknod -m 600 /dev/snapshot c $MAJOR $MINOR
        fi

        if [ -f /etc/suspend.conf -a -f /usr/lib64/suspend/resume ]; then
                echo "Setup kernel hibernation"
                /usr/lib64/suspend/resume -r "$resume2"
        elif [ -f /proc/suspend2/resume2 ]; then
                echo "Setup suspen2 hibernation"
                echo $resume2 >/proc/suspend2/resume2
                echo > /proc/suspend2/do_resume
        elif [ -f /sys/power/suspend2/resume2 ]; then
                echo "Setup suspen2 hibernation"
                echo $resume2 >/sys/power/suspend2/resume2
                echo > /sys/power/suspend2/do_resume
        elif [ -f /sys/power/tuxonice/resume ]; then
                echo "Setup suspen2 hibernation"
                echo $resume2 >/sys/power/tuxonice/resume
                echo > /sys/power/tuxonice/do_resume     
                else
                echo "Can't resume!"
        fi

fi

echo "$PRE Mounting root filesystem $rootvol ro"
if ! mount -n -t auto -o ro $rootvol /rootvol; then
        echo "\t*FAILED*";
        do_shell
fi

# Mount usr if separate and specified.

if [ -n "$usrvol" ]; then
        echo "$PRE Mounting usr filesystem $usrvol ro"

        if ! mount -n -t auto -o ro $usrvol /rootvol/usr; then
                echo "\t*FAILED*";
                do_shell
        fi

fi

echo "$PRE Umounting /proc"
umount /proc
echo "$PRE Umounting /sys"
umount /sys

echo "$PRE Changing roots and proceeding with boot..."

exec switch_root -c /dev/console /rootvol /sbin/init $*

INIT
        chmod 555 $TMPMNT/init
}

# create lvm.conf file from dumpconfig. Just use filter options
create_lvmconf () {
        echo 'devices {' > $TMPMNT/etc/lvm/lvm.conf
        lvm dumpconfig | grep 'filter=' >> $TMPMNT/etc/lvm/lvm.conf
        [ "$XEN" = "y" ] && echo '      types = ["xvd", 16]' >>$TMPMNT/etc/lvm/lvm.conf
        echo '}' >> $TMPMNT/etc/lvm/lvm.conf
}

#
# Main
#

cmd=`basename $0`

VERSION=`uname -r`

while [ $# -gt 0 ]; do
        case $1 in
        -h|--help) usage; exit 0;;
        -v|--verbose)  VERBOSE="y";;
        -c|--lvmconf)  LVMCONF=$2; shift;;
        -k|--keyfile)  KEYFILE=$2; shift;;
        -l|--luks)     BINFILES="$BINFILES /sbin/cryptsetup";;
        -m|--modules)  MODULES=$2; shift;;
        -e|--extra)    EXTRAFILES=$2; shift;;
        -f|--fstools)  FS=$2; shift;;
        -r|--raid)     RAID=$2; shift;;
        -R|--raidconf) RAIDCONF=$2; shift;;
        -M|--makedev)  MAKEDEV=$2; shift;;
        -x|--xen)      XEN="y";;
        [2-9].[0-9]*.[0-9]*) VERSION=$1;;
        *) echo "$cmd -- invalid option '$1'"; usage; exit 0;;
        esac
        shift
done

INITRD=${INITRD:-"/boot/initrd-$VERSION.gz"}

echo "$cmd -- make LVM initial ram disk $INITRD"
echo ""

if [ -n "$RAID" ]; then
        BINFILES="$BINFILES /sbin/mdadm"
        RAIDCONF=${RAIDCONF:-"/etc/mdadm.conf"}
        if [ -r $RAIDCONF ]; then
                EXTRAFILES="$EXTRAFILES $RAIDCONF"
        else
                echo "$cmd -- WARNING: No $RAIDCONF! Your RAID device minor numbers must match their superblock values!"
        fi
fi

if [ -n "$FS" ]; then

        for fstype in $FS; do

                case "$fstype" in
                btrfs)
                        BINFILES="$BINFILES /sbin/btrfs /sbin/btrfs-convert /sbin/btrfsck /sbin/mkfs.btrfs"
                        ;;
                reiser*)
                        BINFILES="$BINFILES /sbin/reiserfsck /sbin/resize_reiserfs /sbin/mkreiserfs"
                ;;
                ext*)
                        BINFILES="$BINFILES /sbin/resize2fs /sbin/e2fsck /sbin/mke2fs"
                ;;
                xfs*)
                        BINFILES="$BINFILES /usr/sbin/xfs_check /usr/sbin/xfs_growfs /sbin/xfs_repair /usr/sbin/xfs_db /sbin/mkfs.xfs"
                ;;
                esac

        done

fi

# Kernel swap suspend executable

if [ -f /usr/lib64/suspend/resume ]; then
        BINFILES="$BINFILES /usr/lib64/suspend/resume"
fi

for a in $BINFILES $EXTRAFILES; do
        if [ ! -r "$a" ] ; then
                echo "$cmd -- ERROR: you need $a"
                exit 1;
        fi;
done

# Figure out which shared libraries we actually need in our initrd
echo "$cmd -- finding required shared libraries"
verbose "BINFILES: `echo $BINFILES`"
LIBFILES=`ldd $BINFILES 2>/dev/null | awk '/=>.*lib/ {print $3} /ld-linux/ {print $1}' | sort -u`
if [ $? -ne 0 ]; then
        echo "$cmd -- ERROR figuring out needed shared libraries"
        exit 1
fi

verbose "Shared libraries needed: `echo $LIBFILES`"

INITRDFILES="$BINFILES $LIBFILES $EXTRAFILES"

# tack on stuff for modules if we declared any and the files exist
if [ -n "$MODULES" ]; then
        if [ -f "/etc/modprobe.conf" ]; then
                INITRDFILES="$INITRDFILES /etc/modprobe.conf"
        fi
        if [ -f "/lib/modules/modprobe.conf" ]; then
                INITRDFILES="$INITRDFILES /lib/modules/modprobe.conf"
        fi


        INITRDFILES="$INITRDFILES
        `for module in $MODULES; do

                modprobe --ignore-install --show-depends --set-version $VERSION $module | grep '^insmod' |
                while read cmd; do
                        echo $cmd | sed 's/insmod //'
                done

        done | sort -u`"

fi

# Copy kernel suspend config
if [ -f "/etc/suspend.conf" ]; then
        INITRDFILES="$INITRDFILES /etc/suspend.conf"
fi

INITRDFILES="$INITRDFILES /lib/modules/$VERSION/modules.order /lib/modules/$VERSION/modules.builtin"

verbose "Add the following files to ramdisk"
verbose "$INITRDFILES"
verbose "creating mountpoint $TMPMNT"
mkdir $TMPMNT
if [ $? -ne 0 ]; then
        echo "$cmd -- ERROR making $TMPMNT"
        cleanup 1
fi

verbose "creating basic set of directories in $TMPMNT"
(cd $TMPMNT; mkdir bin dev etc lib proc sbin var)
if [ $? -ne 0 ]; then
        echo "$cmd -- ERROR creating directories in $TMPMNT"
        cleanup 1
fi

if echo $LIBFILES | grep -q /lib64/; then
        (cd $TMPMNT; ln -s lib lib64)

        if [ $? -ne 0 ]; then
                echo "$cmd -- ERROR creating lib64 link in $TMPMNT"
                cleanup 1
        fi
fi
# Add some /dev files. We have to handle different types of MAKEDEV invocations
# here, so this is rather messy.
RETCODE=0
echo "$cmd -- adding required /dev files"
verbose "BASICDEVICES: `echo $BASICDEVICES`"
verbose "BLOCKDEVICES: `echo $BLOCKDEVICES`"
[ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q=""
case "$MAKEDEV" in
gentoo)
        (cd $TMPMNT/dev; /usr/sbin/MAKEDEV $OPT_Q $BASICDEVICES $BLOCKDEVICES)
        RETCODE=$?
        ;;
gentoo-b2)
        (/sbin/MAKEDEV -d $TMPMNT/dev $OPT_Q $BASICDEVICES $BLOCKDEVICES)
        RETCODE=$?
        ;;
debian)
        (cd $TMPMNT/dev; /dev/MAKEDEV $OPT_Q $BASICDEVICES $BLOCKDEVICES)
        RETCODE=$?
        ;;
redhat)
        (cd $TMPMNT/dev; /dev/MAKEDEV $OPT_Q -d $TMPMNT/dev -m 2)
        RETCODE=$?
        ;;
*)
        echo "$cmd -- ERROR: $MAKEDEV is not a known MAKEDEV style."
        RETCODE=1
        ;;
esac


if [ $RETCODE -ne 0 ]; then
        echo "$cmd -- ERROR adding /dev files"
        cleanup 1
fi

mkdir $TMPMNT/rootvol
mkdir $TMPMNT/sys

# copy necessary files to ram disk
echo "$cmd -- copying initrd files to ram disk"
[ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q="--quiet"
verbose "find \$INITRDFILES | cpio -pdmL $OPT_Q $TMPMNT"
find $INITRDFILES | cpio -pdmL $OPT_Q $TMPMNT
if [ $? -ne 0 ]; then
        echo "$cmd -- ERROR cpio to ram disk"
        cleanup 1
fi

# Rename bb as busybox to use the gentoo static compiled busybox.

if [ -f $TMPMNT/bin/bb -a ! -f $TMPMNT/bin/busybox ]; then
        mv $TMPMNT/bin/bb $TMPMNT/bin/busybox
fi

echo "$cmd -- creating symlinks to busybox"
shopt -s extglob
[ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q=""
BUSYBOXSYMLINKS=`busybox 2>&1| awk '/^Currently defined functions:$/ {i++;next} i'|tr ',\t\n' ' '`
for link in ${BUSYBOXSYMLINKS//@(linuxrc|init|busybox)}; do
        ln -s $OPT_Q busybox $TMPMNT/bin/$link;
done
shopt -u extglob

echo "$cmd -- creating new $TMPMNT/sbin/init"
create_init
if [ $? -ne 0 ]; then
        echo "$cmd -- ERROR creating init"
        cleanup
        exit 1
fi

# copy LVMCONF into place or create a stripped down one from lvm dumpconfig
mkdir -p $TMPMNT/etc/lvm
if [ -n "$LVMCONF" ]; then
        echo "$cmd -- copying $LVMCONF to $TMPMNT/etc/lvm/lvm.conf"
        if [ -f "$LVMCONF" ]; then
                cp $LVMCONF $TMPMNT/etc/lvm/lvm.conf
        else
                echo "$cmd -- ERROR: $LVMCONF does not exist!"
                cleanup
                exit 1
        fi
else
        echo "$cmd -- creating new $TMPMNT/etc/lvm/lvm.conf"
        create_lvmconf
fi

if [ -n "$RAID" ]; then
        RAIDLIST="$TMPMNT/etc/raid_autostart"
        echo "$cmd -- creating $RAIDLIST file."
        for device in $RAID; do
                echo $device >> $RAIDLIST
        done
fi

# create modules.dep and /etc/modules files if needed
if [ -n "$MODULES" ]; then
        echo "$cmd -- creating $MODDIR/modules.dep file and $TMPMNT/etc/modules"
        depmod -b $TMPMNT $VERSION
        # The individual modules are probably already in the correct form, but this
        # code does not hurt them. Might even add functionality of specifying paths.
        for module in $MODULES; do
                basename $module | sed 's/\.k\{0,1\}o$//' >> $TMPMNT/etc/modules
        done
fi

# Copy luks keyfile is luks setup and keyfile provide.

if [ -f $TMPMNT/sbin/cryptsetup -a -n "$KEYFILE" ]; then
        cp "$KEYFILE" $TMPMNT/.lukskey
fi

umask 077
(cd $TMPMNT && find . -print | cpio -H newc -o ) | gzip -n -9 > $INITRD
rm -r $TMPMNT

if [ $? -ne 0 ]; then
        echo "$cmd -- ERROR creating $INITRD"
        cleanup 1
fi

cat << FINALTXT
--------------------------------------------------------
Your initrd is ready in $INITRD

Don't forget to set lvm2root=/dev/VG/LV in kernel parameters, where LV is
your root volume. If you use lilo try adding/modifying an entry similar to
this one in lilo.conf:

image=/boot/vmlinuz-lvm2-$VERSION
        label="ramdisk_LVM"
        initrd=/boot/initrd-lvm2-$VERSION.gz
        append="lvm2root=/dev/system/root <other parameters>"

If using grub try adding/modifying an entry similar to this one in menu.lst

title ramdisk LVM
        kernel /boot/vmlinuz-lvm2-$VERSION lvm2root=/dev/system/root <other parameters>
        initrd /boot/initrd-lvm2-$VERSION.gz

You can also pass lvm2rescue to the kernel to get a shell
--------------------------------------------------------
FINALTXT

cleanup 0


To use the script, make sure you have the loopback device compiled into
your kernel or load it via
Code:
modprobe loop
and then run the
script. If you (like me) have not compiled the device mapper into the
kernel, you will need to do something like

Code:

./lvm2create_initrd -m /lib/modules/2.6.17-suspend2-r2/kernel/drivers/md/dm-mod.
ko 2.6.17-suspend2-r2


This should create the file initrd-lvm2-2.6.17-suspend2-r2.gz in your
/boot directory (be sure it is mounted first).

SETTING UP GRUB

You will need to provide a few non standard options to the kernel by
appending them on the kernel command line in grub. You will also need
to change the standard root= to be root=/dev/ram0, while I believe that
should be the default when using a initial ramdisk, I have had much
better luck when specifying it explicitly on the command line. Also, it
won't hurt to add ro to be sure your ramdisk is mounted read only.

The first non standard option to add is lvm2root. Have this point to
your root partition in lvm2 for example, mine is

Code:

lvm2root=/dev/vg00/root


The second non standard option is lvm2resume2. This should point to your
swap partition in lvm2.

You can also add lvm2rescue to drop into a shell after activating lvm2
so that you can do any system maintenance or repair before finishing the
boot.

Your kernel line should look something like

Code:

kernel /suspend2-2.6.x ro root=/dev/ram0 lvm2root=/dev/v00/root lvm2resume2=/dev
/vg00/swap


Your initrd should simply point to the initial ramdisk created in the
previous step.

Code:

initrd /initrd-lvm2-2.6.x-suspend2.gz


ENJOY

Now sit back and bask in the flexibility (and uber geekyness) of a fully
lvm2 system including software suspend2 to an lvm swap partition.


Last edited by Raffi on Fri Apr 12, 2013 7:45 pm; edited 20 times in total
Back to top
View user's profile Send private message
lixer
n00b
n00b


Joined: 02 Sep 2004
Posts: 6

PostPosted: Mon Jul 17, 2006 5:57 am    Post subject: Reply with quote

Bookmarked!! :D . It will come handy on my next rebuild 8) Thanks for putting in the hard work :D
Back to top
View user's profile Send private message
Mounir Lamouri
Retired Dev
Retired Dev


Joined: 23 Jul 2006
Posts: 13
Location: Montreal, QC

PostPosted: Sun Jul 23, 2006 6:49 pm    Post subject: Reply with quote

I've an issue with my initrd for lvm2. I don't use suspend because it is for a server but I used the following script and follow instructions as I can.

So, my issue is about pivot_root. I've the following output when my server boot :
Quote:
pivot_root: pivot_root : No such file or directory
\t *FAILED*

*** Entering lvm2 rescue shell. Exit shell to continue booting. ***
/bin/ash : can't access tty ; job control turned off

So, there, I exit the shell and my box boot as usual, but I notice, I got :
Quote:
umount: /initrd not found


To fix it, I taked many ways.
In a first time, I add pivot_root with the -e option. I also use $BINUTILS variable to add it. But this doesn't resolv anything.
After that, I verfiy if pivot_root was on my initrd and it is. There is a symlink to busybox bin. So, I turn my attention to busybox and I try to emerge it with static use flag. And like you can imagine, if I've always this issue : this doesn't change anything.

So, is there someone who may help me ?
Thanks by advance.
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Sun Jul 23, 2006 7:46 pm    Post subject: Reply with quote

I assume your pivot_root looks something like
Code:

pivot_root /lvmroot /initrd

You need to have an initrd directory in the root your are pivoting to. Otherwise, it can't mount the old root on it.
Back to top
View user's profile Send private message
Mounir Lamouri
Retired Dev
Retired Dev


Joined: 23 Jul 2006
Posts: 13
Location: Montreal, QC

PostPosted: Sun Jul 23, 2006 8:03 pm    Post subject: Reply with quote

I'm so stupid ! I was thinking /initrd was optional...
Where could I hide ?

Now, my server boot perfectly ! Thanks to you and your script, you save me to genkernel ;)
Back to top
View user's profile Send private message
huhn_m
n00b
n00b


Joined: 21 Aug 2006
Posts: 24

PostPosted: Wed Aug 23, 2006 6:47 pm    Post subject: Reply with quote

Are you sure the updated script works?

I tried it and it says unexpected end of file!

The original version worked however. I don't actually see where the error should be, so could you
please verify if it also exists on your machine? If there is a mistake please correct it, since I built my machine
on your script. It is verry nice, but I need it after kernel updates for the system to come up with the new kernel (and ramdisk!)

Thank you verry much for your work. it is much appreciated.
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Wed Aug 23, 2006 6:50 pm    Post subject: Reply with quote

The script that I wrote works. Did my cut and paste? Not sure. Let me try pasting it back and see what happens.
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Wed Aug 23, 2006 6:52 pm    Post subject: Reply with quote

I grabbed the script, pasted back to my system and did a diff -b with the original. No diffs. Can you cut and paste the output you got? Are you sure you copied the entire thing?
Back to top
View user's profile Send private message
huhn_m
n00b
n00b


Joined: 21 Aug 2006
Posts: 24

PostPosted: Thu Aug 24, 2006 5:48 am    Post subject: Reply with quote

Here is the output I get from running the script:

Code:

localhost ~ # ./lvm2create_initrd --help
./lvm2create_initrd: line 512: syntax error: unexpected end of file


I really don't know what I do wrong.

I copied the whole script once again and still get the same error.
Here is the script I do use:

Code:


#!/bin/bash
 #
 # lvm2create_initrd
 #
 # Blatantly stolen from code written by
 #
 # Miguel Cabeca cabeca (at) ist (dot) utl (dot) pt
 #
 # and modified for Gentoo and my own nefarious purposes. Don't blame the
 # original author or even bug him about this script. If you have
 # problems, try posting to the Gentoo forums
 #
 # Raffi

 TMPMNT=/tmp/mnt.$$
 DEVRAM=/tmp/initrd.$$

 # set defaults
 BINFILES=${BINFILES:-"/sbin/lvm /bin/bb"}
 BASICDEVICES=${BASICDEVICES:-"std consoleonly fd"}
 BLOCKDEVICES=${BLOCKDEVICES:-"md hda hdb hdc hdd sda sdb sdc sdd"}
 MAKEDEV=${MAKEDEV:-"gentoo"}

 # Uncomment this if you want to disable automatic size detection
 #INITRDSIZE=4096

 PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH

 usage () {
         echo "Create an initial ramdisk image for LVM2 root filesystem"
         echo "$cmd: [-h] [-v] [-c lvm.conf] [-m modulelist] [-e extrafiles] [-f fstypes] -r [raiddevs] [-R mdadm.conf] [-M style] [kernel version]"
         echo "      -h|--help      print this usage message"
         echo "      -v|--verbose   verbose progress messages"
         echo "      -c|--lvmconf   path to lvm.conf (/etc/lvm/lvm.conf)"
         echo "      -m|--modules   modules to copy to initrd image"
         echo "      -e|--extra     extra files to add to initrd"
         echo "      -f|--fstools   Add filesystem tools"
         echo "      -r|--raid      raid devices to start in initrd"
         echo "      -R|--raidconf  location of mdadm.conf file to include"
         echo "      -M|--makedev   set MAKEDEV type (gentoo, debian or redhat)"
 }

 verbose () {
    [ "$VERBOSE" ] && echo "`echo $cmd | tr '[a-z0-9/_]' ' '` -- $1" || true
 }

 cleanup () {
   [ "`mount | grep $DEVRAM`" ] && verbose "unmounting $DEVRAM" && umount $DEVRAM
   [ -f $DEVRAM ] && verbose "removing $DEVRAM" && rm $DEVRAM
   [ -d $TMPMNT ] && verbose "removing $TMPMNT" && rmdir $TMPMNT
   verbose "exit with code $1"
   exit $1
 }

 trap "
   verbose 'Caught interrupt'
   echo 'Bye bye...'
   cleanup 1
 " 1 2 3 15

 create_init () {
    cat << 'INIT' > $TMPMNT/sbin/init
 #!/bin/ash

 # include in the path some dirs from the real root filesystem
 # for chroot, blockdev
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/lib/lvm-200:/initrd/bin:/initrd/sbin"
 PRE="initrd:"

 do_shell(){
     /bin/echo
     /bin/echo "*** Entering LVM2 rescue shell. Exit shell to continue booting. ***"
     /bin/echo
     /bin/ash
 }

 # We need /proc for device mapper and reading cmdline
 echo "$PRE Mounting /proc"
 mount -n -t proc none /proc

 # Read command line arguments.
 #
 # Device-Mapper dynamically allocates all device numbers. This means
 # it is possible that the root volume specified to LILO or Grub may
 # have a different number when the initrd runs than when the system
 # was last running. In order to make sure the correct volume is
 # mounted as root, the init script must determine what the desired
 # root volume name is by getting the LVM2 root volume name from
 # the kernel command line. In order for this to work correctly,
 # "lvm2root=/dev/Volume_Group_Name/Root_Volume_Name" needs to be passed
 # to the kernel command line (where Root_Volume_Name is replaced by your
 # actual root volume's name. The same problem exists for resume2 and is
 # fixed by passing "lvm2resume2=..."

 for arg in `cat /proc/cmdline`; do
         case "$arg" in
         lvm2root=*)
                 rootvol=${arg#lvm2root=}
                 ;;
         lvm2resume2=*)
                 resume2=${arg#lvm2resume2=}
                 ;;
         lvm2rescue)
                 rescue="YES"
                 ;;
         esac
 done

 # Only worry about rw state of ramdisk if using software suspend.

 if [ -n "$resume2" ]; then
         mount -n -t tmpfs none /dev
         (cd /dev; cpio -im </dev.cpio)
 else
         echo "$PRE Remounting / read/write"
         mount -t ext2 -o remount,rw /dev/ram0 /
 fi

 # plug in modules listed in /etc/modules
 if [ -f /etc/modules ]; then
     echo -n "$PRE plugging in kernel modules:"
     cat /etc/modules |
     while read module; do
         echo -n " $module"
         modprobe $module
     done
     echo '.'
 fi

 # start raid devices if raid_autostart file exists
 if [ -f /etc/raid_autostart ]; then
     if [ ! -f /etc/mdadm/mdadm.conf ]; then
         mdoptions='--super-minor=dev'
     fi
     cat /etc/raid_autostart|
     while read dev; do
         echo "Starting RAID device $dev"
         /sbin/mdadm --assemble $dev $mdoptions
     done
 fi

 # Create the /dev/mapper/control device for the ioctl
 # interface using the major and minor numbers that have been allocated
 # dynamically.

 echo -n "$PRE Finding device mapper major and minor numbers "

 MAJOR=$(sed -n 's/^ *\([0-9]\+\) \+misc$/\1/p' /proc/devices)
 MINOR=$(sed -n 's/^ *\([0-9]\+\) \+device-mapper$/\1/p' /proc/misc)

 if test -n "$MAJOR" -a -n "$MINOR" ; then
         mkdir -p -m 755 /dev/mapper
         mknod -m 600 /dev/mapper/control c $MAJOR $MINOR
 fi

 echo "($MAJOR,$MINOR)"

 echo "$PRE Activating LVM2 volumes"
 lvm vgscan

 # run a shell if we're passed lvm2rescue on commandline
 if [ "$rescue" = "YES" ]; then
     lvm vgchange --ignorelockingfailure -P -a y
     do_shell
 else
     lvm vgchange --ignorelockingfailure -a y
 fi

 # Setup software suspend2

 if [ -n "$resume2" ]; then
         echo "Setup suspen2 hibernation"
         echo $resume2 >/proc/suspend2/resume2
         echo > /proc/suspend2/do_resume
 fi

 echo "$PRE Mounting root filesystem $rootvol ro"
 if ! mount -n -t auto -o ro $rootvol /rootvol; then
         echo "\t*FAILED*";
         do_shell
 fi

 echo "$PRE Umounting /proc"
 umount /proc

 echo "$PRE Changing roots"
 cd /rootvol

 if ! pivot_root . initrd ; then
         echo "\t*FAILED*"
         do_shell
 fi

 if [ -n "$resume2" ]; then
         umount /initrd/dev
 fi

 echo "$PRE Proceeding with boot..."

 exec chroot . /bin/sh -c "umount /initrd; blockdev --flushbufs /dev/ram0 ; exec /sbin/init $*" < dev/console > dev/console 2>&1

 INIT
    chmod 555 $TMPMNT/sbin/init
 }

 # create lvm.conf file from dumpconfig. Just use filter options
 create_lvmconf () {
     echo 'devices {' > $TMPMNT/etc/lvm/lvm.conf
     lvm dumpconfig | grep 'filter=' >> $TMPMNT/etc/lvm/lvm.conf
     echo '}' >> $TMPMNT/etc/lvm/lvm.conf
 }

 #
 # Main
 #

 cmd=`basename $0`

 VERSION=`uname -r`

 while [ $# -gt 0 ]; do
    case $1 in
    -h|--help) usage; exit 0;;
    -v|--verbose)  VERBOSE="y";;
    -c|--lvmconf)  LVMCONF=$2; shift;;
    -m|--modules)  MODULES=$2; shift;;
    -e|--extra)    EXTRAFILES=$2; shift;;
    -f|--fstools)  FS=$2; shift;;
    -r|--raid)     RAID=$2; shift;;
    -R|--raidconf) RAIDCONF=$2; shift;;
    -M|--makedev)  MAKEDEV=$2; shift;;
    [2-9].[0-9]*.[0-9]*) VERSION=$1;;
    *) echo "$cmd -- invalid option '$1'"; usage; exit 0;;
    esac
    shift
 done

 INITRD=${INITRD:-"/boot/initrd-lvm2-$VERSION.gz"}

 echo "$cmd -- make LVM initial ram disk $INITRD"
 echo ""

 if [ -n "$RAID" ]; then
     BINFILES="$BINFILES /sbin/mdadm"
     RAIDCONF=${RAIDCONF:-"/etc/mdadm.conf"}
     if [ -r $RAIDCONF ]; then
         EXTRAFILES="$EXTRAFILES $RAIDCONF"
     else
         echo "$cmd -- WARNING: No $RAIDCONF! Your RAID device minor numbers must match their superblock values!"
     fi
 fi

 if [ -n "$FS" ]; then

         for fstype in $FS; do

                 case "$fstype" in
                 reiser*)
                         BINFILES="$BINFILES /sbin/reiserfsck /sbin/resize_reiserfs"
                         ;;
                 ext*)
                         BINFILES="$BINFILES /sbin/resize2fs"
                         ;;
                 xfs*)
                         BINFILES="$BINFILES /usr/sbin/xfs_check /usr/sbin/xfs_growfs"
                         ;;
                 esac

         done

 fi

 for a in $BINFILES $EXTRAFILES; do
     if [ ! -r "$a" ] ; then
         echo "$cmd -- ERROR: you need $a"
         exit 1;
     fi;
 done

 # Figure out which shared libraries we actually need in our initrd
 echo "$cmd -- finding required shared libraries"
 verbose "BINFILES: `echo $BINFILES`"
 LIBFILES=`ldd $BINFILES 2>/dev/null | awk '/=>.*lib/ {print $3} /ld-linux/ {print $1}' | sort -u`
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR figuring out needed shared libraries"
    exit 1
 fi

 verbose "Shared libraries needed: `echo $LIBFILES`"

 INITRDFILES="$BINFILES $LIBFILES $MODULES $EXTRAFILES"

 # tack on stuff for modules if we declared any and the files exist
 if [ -n "$MODULES" ]; then
     if [ -f "/etc/modprobe.conf" ]; then
         INITRDFILES="$INITRDFILES /etc/modprobe.conf"
     fi
     if [ -f "/lib/modules/modprobe.conf" ]; then
         INITRDFILES="$INITRDFILES /lib/modules/modprobe.conf"
     fi
 fi

 # Calculate the the size of the ramdisk image.
 # Don't forget that inodes take up space too, as does the filesystem metadata.
 echo "$cmd -- calculating initrd filesystem parameters"
 if [ -z "$INITRDSIZE" ]; then
    echo "$cmd -- calculating loopback file size"
    verbose "finding size"
    INITRDSIZE="`du -Lck $INITRDFILES | tail -1 | cut -f 1`"
    verbose "minimum: $INITRDSIZE kB for files + inodes + filesystem metadata"
    INITRDSIZE=`expr $INITRDSIZE + 512`  # enough for ext2 fs + a bit
 fi

 echo "$cmd -- making loopback file ($INITRDSIZE kB)"
 verbose "using $DEVRAM as a temporary loopback file"
 dd if=/dev/zero of=$DEVRAM count=$INITRDSIZE bs=1024 > /dev/null 2>&1
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR creating loopback file"
    cleanup 1
 fi

 echo "$cmd -- making ram disk filesystem"
 verbose "mke2fs -F -m0 -L LVM-$VERSION -N 500 $DEVRAM $INITRDSIZE"
 [ "$VERBOSE" ] && OPT_Q="" || OPT_Q="-q"
 mke2fs $OPT_Q -F -m0 -L LVM-$VERSION -N 500 $DEVRAM $INITRDSIZE
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR making ram disk filesystem"
    echo "$cmd -- ERROR you need to use mke2fs >= 1.14 or increase INITRDSIZE"
    cleanup 1
 fi

 verbose "creating mountpoint $TMPMNT"
 mkdir $TMPMNT
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR making $TMPMNT"
    cleanup 1
 fi

 if [ ! -d /dev/loop ]; then
    verbose "Loading loopback module"
    modprobe loop
    sleep 1
 fi

 echo "$cmd -- mounting ram disk filesystem"
 verbose "mount -o loop $DEVRAM $TMPMNT"
 mount -oloop $DEVRAM $TMPMNT
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR mounting $DEVRAM on $TMPMNT"
    cleanup 1
 fi

 verbose "creating basic set of directories in $TMPMNT"
 (cd $TMPMNT; mkdir bin dev etc lib proc sbin var)
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR creating directories in $TMPMNT"
    cleanup 1
 fi

 if echo $LIBFILES | grep -q /lib64/; then
         (cd $TMPMNT; ln -s lib lib64)

         if [ $? -ne 0 ]; then
            echo "$cmd -- ERROR creating lib64 link in $TMPMNT"
            cleanup 1
         fi
 fi
 # Add some /dev files. We have to handle different types of MAKEDEV invocations
 # here, so this is rather messy.
 RETCODE=0
 echo "$cmd -- adding required /dev files"
 verbose "BASICDEVICES: `echo $BASICDEVICES`"
 verbose "BLOCKDEVICES: `echo $BLOCKDEVICES`"
 [ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q=""
 case "$MAKEDEV" in
 gentoo)
     (cd $TMPMNT/dev; /usr/sbin/MAKEDEV $OPT_Q $BASICDEVICES $BLOCKDEVICES)
     RETCODE=$?
     ;;
 debian)
     (cd $TMPMNT/dev; /dev/MAKEDEV $OPT_Q $BASICDEVICES $BLOCKDEVICES)
     RETCODE=$?
     ;;
 redhat)
     (cd $TMPMNT/dev; /dev/MAKEDEV $OPT_Q -d $TMPMNT/dev -m 2)
     RETCODE=$?
     ;;
 *)
     echo "$cmd -- ERROR: $MAKEDEV is not a known MAKEDEV style."
     RETCODE=1
     ;;
 esac


 if [ $RETCODE -ne 0 ]; then
    echo "$cmd -- ERROR adding /dev files"
    cleanup 1
 fi

 (cd $TMPMNT/dev; find . -print | cpio -H newc -o >$TMPMNT/dev.cpio)
 mkdir $TMPMNT/rootvol

 # copy necessary files to ram disk
 echo "$cmd -- copying initrd files to ram disk"
 [ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q="--quiet"
 verbose "find \$INITRDFILES | cpio -pdmL $OPT_Q $TMPMNT"
 find $INITRDFILES | cpio -pdmL $OPT_Q $TMPMNT
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR cpio to ram disk"
    cleanup 1
 fi

 # Rename bb as busybox to use the gentoo static compiled busybox.

 if [ -f $TMPMNT/bin/bb -a ! -f $TMPMNT/bin/busybox ]; then
    mv $TMPMNT/bin/bb $TMPMNT/bin/busybox
 fi

 echo "$cmd -- creating symlinks to busybox"
 shopt -s extglob
 [ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q=""
 BUSYBOXSYMLINKS=`busybox 2>&1| awk '/^Currently defined functions:$/ {i++;next} i'|tr ',\t\n' ' '`
 for link in ${BUSYBOXSYMLINKS//@(linuxrc|init|busybox)}; do
         ln -s $OPT_Q busybox $TMPMNT/bin/$link;
 done
 shopt -u extglob

 echo "$cmd -- creating new $TMPMNT/sbin/init"
 create_init
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR creating init"
    cleanup
    exit 1
 fi

 # copy LVMCONF into place or create a stripped down one from lvm dumpconfig
 mkdir -p $TMPMNT/etc/lvm
 if [ -n "$LVMCONF" ]; then
     echo "$cmd -- copying $LVMCONF to $TMPMNT/etc/lvm/lvm.conf"
     if [ -f "$LVMCONF" ]; then
         cp $LVMCONF $TMPMNT/etc/lvm/lvm.conf
     else
         echo "$cmd -- ERROR: $LVMCONF does not exist!"
         cleanup
         exit 1
     fi
 else
     echo "$cmd -- creating new $TMPMNT/etc/lvm/lvm.conf"
     create_lvmconf
 fi

 if [ -n "$RAID" ]; then
     RAIDLIST="$TMPMNT/etc/raid_autostart"
     echo "$cmd -- creating $RAIDLIST file."
     for device in $RAID; do
         echo $device >> $RAIDLIST
     done
 fi

 # create modules.dep and /etc/modules files if needed
 if [ -n "$MODULES" ]; then
     echo "$cmd -- creating $MODDIR/modules.dep file and $TMPMNT/etc/modules"
     depmod -b $TMPMNT $VERSION
     for module in $MODULES; do
         basename $module | sed 's/\.k\{0,1\}o$//' >> $TMPMNT/etc/modules
     done
 fi

 verbose "removing $TMPMNT/lost+found"
 rmdir $TMPMNT/lost+found

 echo "$cmd -- ummounting ram disk"
 umount $DEVRAM
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR umounting $DEVRAM"
    cleanup 1
 fi

 echo "$cmd -- creating compressed initrd $INITRD"
 verbose "dd if=$DEVRAM bs=1k count=$INITRDSIZE | gzip -9"
 dd if=$DEVRAM bs=1k count=$INITRDSIZE 2>/dev/null | gzip -9 > $INITRD
 if [ $? -ne 0 ]; then
    echo "$cmd -- ERROR creating $INITRD"
    cleanup 1
 fi


 cat << FINALTXT
 --------------------------------------------------------
 Your initrd is ready in $INITRD

 Don't forget to set root=/dev/ram0 in kernel parameters
 Don't forget to set lvm2root=/dev/VG/LV in kernel parameters, where LV is your root volume
 If you use lilo try adding/modifying an entry similar to this one in lilo.conf:

 image=/boot/vmlinuz-lvm2-$VERSION
         label="ramdisk_LVM"
         initrd=/boot/initrd-lvm2-$VERSION.gz
         append="root=/dev/ram0 lvm2root=/dev/system/root ramdisk_size=$INITRDSIZE <other parameters>"

 If using grub try adding/modifying an entry similar to this one in menu.lst

 title ramdisk LVM
         kernel /boot/vmlinuz-lvm2-$VERSION root=/dev/ram0 lvm2root=/dev/system/root ramdisk_size=$INITRDSIZE <other parameters>
         initrd /boot/initrd-lvm2-$VERSION.gz

 You can also pass lvm2rescue to the kernel to get a shell
 --------------------------------------------------------
 FINALTXT

 cleanup 0


The whitespace at the beginning of each line does not matter. konqueror inserts them upon cutting (whyever it does this) but removing them does not solve the problem at all..
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Thu Aug 24, 2006 11:24 am    Post subject: Reply with quote

I copied what you posted, it gets the same error. I removed the white space at the front (shifted left with vi), it worked. Looks like the white space is the problem.
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Mon Oct 23, 2006 9:34 pm    Post subject: lvm2 not recognizing my partitions!!! :-( Reply with quote

Congratulations for this scrips as I was looking for a guide on how to set up root on lvm.

however is just working half way through. I created the initrd like this:

Quote:
/lvm2create_initrd -c /etc/lvm/lvm.conf (kernerl version)


I don't know if this is scrip is only for a current installation or one from scratch. Perhaps my error is because I am building a new installation.

Also I build busybox and lvm2 with like this:

Quote:
USE="static -nolvmstatic" emerge busybox lvm2


Although you don't mention emerging lvm2 statically.

Before I use to get

Quote:
No volumes found


Now it appears this, I don't know whether is an improvement or not:

Quote:
Locking type 1 initialisation failed.
Locking type 1 initialisation failed.


Quote:
vFS: Mounted root (ext2 filesystem) readonly
Freeind unused kernel memory: 228k feed
initrd: Mounting /proc
cpio: extract_archive: .: File exists
48 blocks
initrd: Finding device mapper major and minor numbers 910.63)
initrd: Activating LVM@ volumes
Locking type 1 initialisation failed.
Locking type 1 initialisation failed.
Setup suspend2 hibernation
/sbin/init: /sbin/init: 113: cannot create /proc/suspend/resume2: Directory non-existent
/sbin/init: /sbin/init: 113: cannot create /proc/suspend/resume2: Directory non-existent
initrd: Mounting root filesystem /dev/kewl/root ro
mount: Mounting /dev/kewl/root on /rootvol failed: No such file or directory
\t*FAILEd*

*** Entering LVM2 rescue shell. Exit shell to continue. ***


I found on google that a possible repair is this"

Quote:
The simple fix is to add --ignorelockingfailure to the vgchange command


I do this in LVM2 rescue shell and I get:

Quote:
No volume groups found


But I can activate them regularly with LiveCD in order to chroot and try different workarounds.

Also I've palyed around with modifying your scrip in here:

Quote:
echo "$PRE Activating LVM2 volumes"
lvm vgscan

# run a shell if we're passed lvm2rescue on commandline
if [ "$rescue" = "YES" ]; then
lvm vgchange --ignorelockingfailure -P -a y
do_shell
else
lvm vgchange --ignorelockingfailure -a y
fi


And change:

Quote:
echo "$PRE Activating LVM2 volumes"
lvm vgscan

# run a shell if we're passed lvm2rescue on commandline
if [ "$rescue" = "YES" ]; then
lvm vgchange --ignorelockingfailure -P -a y
do_shell
else
lvm vgchange --ignorelockingfailure -a y
fi


for

Quote:
echo "$PRE Activating LVM2 volumes"
lvm vgscan --ignorelockingfailure -a y

# run a shell if we're passed lvm2rescue on commandline
if [ "$rescue" = "YES" ]; then
lvm vgchange --ignorelockingfailure -P -a y
do_shell
else
lvm vgchange --ignorelockingfailure -a y
fi


And adding with --mknodes because Gentoo LVM2 guide mentions that if the installation has been interrupted, as is in my case many times, that need to be added using LiveCD. So I put it on the scripe as well.

Quote:
echo "$PRE Activating LVM2 volumes"
lvm vgscan --mknodes --ignorelockingfailure -a y

# run a shell if we're passed lvm2rescue on commandline
if [ "$rescue" = "YES" ]; then
lvm vgchange --ignorelockingfailure -P -a y
do_shell
else
lvm vgchange --ignorelockingfailure -a y
fi


Finally I created swap with mkswap /dev/vg/swap. It gave me some error but then i did mkswap -f .... Now I have this message when boot and when activating swap partition...

Quote:
BIT FAT WARNING!! Failed to translate "/dev/kewl/swap" into a device id.


I can't put swap type with fdisk because I need to put as lvm2.

Thanks in advanced...

bye


Last edited by nato.Otan on Mon Oct 23, 2006 10:11 pm; edited 1 time in total
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Mon Oct 23, 2006 9:44 pm    Post subject: Reply with quote

Do you have the device mapper compiled into your kernel or is it a module? If it is a modules, you will need to specify the path to that modules using the -m flag.

There is no need to compile either busybox or lvm2 statically. Lvm2 will ignore the flag and compile itself statically anyway and busybox on gentoo always puts a static copy call bb in /bin.

As far as the swap problem goes, what error did you get when you made your swap partition?
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Mon Oct 23, 2006 10:26 pm    Post subject: thanks for the prompt response!! Reply with quote

hi,

I've compiled everything in kernel nothing as modules.

Some people suggested me to create the /rootvol directory in response to this error message:

Quote:
initrd: Mounting root filesystem /dev/kewl/root ro
mount: Mounting /dev/kewl/root on /rootvol failed: No such file or directory



and apparently this time it did recognize the volume!!

Quote:
mount: Mounting /dev/kewl/root on..


but why do I get this message?

Quote:
Locking type 1 initialisation failed.
Locking type 1 initialisation failed.


This is the the message when I do:

Quote:
mkswap /dev/kewl/swap
Setting up swapspace version 1, size = 511700 kB
no label, UUID=(long number)


I wonder whether this is related to:

Quote:
BIT FAT WARNING!! Failed to translate "/dev/kewl/swap" into a device id.


Maybe because I didn't set it with fdisk?
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Mon Oct 23, 2006 10:44 pm    Post subject: Reply with quote

I'm not sure I'm understanding the problem you are having. What kernel options are you feeding to grub?
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Mon Oct 23, 2006 10:49 pm    Post subject: pondering on the issue... Reply with quote

me again... I was thinking why I am the only one getting this message about;

Quote:
mount: Mounting /dev/kewl/root on /rootvol failed: No such file or directory


I thought it was supposed to use /initrd directory in / . Where does /rootvol need to be located?
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Mon Oct 23, 2006 10:54 pm    Post subject: Reply with quote

I believe my main PROBLEM is due to this one because there is where it stops:

Quote:
initrd: Mounting root filesystem /dev/kewl/root ro
mount: Mounting /dev/kewl/root on /rootvol failed: No such file or directory
\t*FAILEd*


And this is grub:

Quote:
kernel /boot/vmlinuz-2.6.18-no2 ro root=/dev/ram0 lvm2root=/dev/kewl/root ramdisk_size=4096 lvm2resume2=dev/kewl/swap
initrd /boot/initrd-lvm2-2.6.18-no2
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Mon Oct 23, 2006 11:35 pm    Post subject: Reply with quote

/rootvol is part of the initrd image. If it is not there, your image might be bad. This brings me to your ramdisk size, I find the 4096 suspect. Mine is 5152. The script that creates the ramdisk tells you what size to use. What did it say?
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Mon Oct 23, 2006 11:41 pm    Post subject: aha!! Reply with quote

I am most likely to be at fault. :oops:

Because I saw in the scrip this:

Quote:
# Uncomment this if you want to disable automatic size detection
#INITRDSIZE=4096


And in my kernel was set to that number as well I thought I should've uncommented it. But if the size is greatet than 4096 what about the kernel? Should I change the kernel and put more? And what multiple should I use?

Well now I am not sure what to follow next, whether uncomment that line first and re-run the scrip or change the kernel value to something higher.
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Mon Oct 23, 2006 11:44 pm    Post subject: Reply with quote

The script will spit out a suggested command line that you can modify the way you want. I don't change the size in the kernel config since I won't know the size until after I copy in what I need and that might change from time to time.
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Mon Oct 23, 2006 11:57 pm    Post subject: Reply with quote

For some reason I thought anything above the kernel's value won't work unless recompiling the kernel again with a higher number.

Ok, so whatever the scrip suggests I would have to put in the kernel after beind done with script? For instance if you said you have 5152, then you went on changing the kernel value to EXACTLY 5152?

I am confused now :? , perhaps I shouldn't have thouched the script to begin with.
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Tue Oct 24, 2006 12:08 am    Post subject: Reply with quote

The kernel config option is for the default size. You can override it on the command line. When the script suggested 5152, I added ramdisk_size=5152 to the kernel command line.

Nothing that you said you did looked like it would damage anything.
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Tue Oct 24, 2006 1:06 am    Post subject: grateful Reply with quote

Raffi thank very much for your support I will try this right now and see the results. This is an excellent script I wish instalation on LVM2 would be mainstream instead of a dark practice. Also I have a proposal to add this into Gentoo's LVM2 guide and put in the wiki, with your permision if you agree of course. Perhaps give directions on how to set up the script for laptops and a section for desktops. The Gentoo LVM2 installation has a resources section where they provide an appaling and pathetic link on how to set up root on LVM. It just doesn't make any sense, while Gentoo's guide explicitly talks about LVM2 which now is at version LVM2-2.02.10, the outdated link, "Date: Fri, 20 Oct 2000 23:41:44 +0200" is using LVM 0.7 . To make matters worst it only talks about setting lilo and the freaking guy doesn't even run Gentoo!!!

Quote:
I was using a SuSE 6.4 install


WTF??!!

What do you think about proposing this to the people in charge of LVM2 guide?

Author: Avi Schwartz
Contributor: Rajiv Manglani
Editor: Xavier Neys
Back to top
View user's profile Send private message
Raffi
l33t
l33t


Joined: 17 Mar 2003
Posts: 731
Location: Moscow, Id.

PostPosted: Tue Oct 24, 2006 2:07 am    Post subject: Reply with quote

I have thought about updating the wiki, but I wanted the script to get a bit of use by more people than just me first.

The lack of information in the wiki is why I wrote this script and howto.
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Thu Oct 26, 2006 6:49 pm    Post subject: Solved!!! Reply with quote

hi Raffi,

I did solve the problem, just by doing what the message spitted out:

Quote:
initrd: Mounting root filesystem /dev/kewl/root ro
mount: Mounting /dev/kewl/root on /rootvol failed: No such file or directory
\t*FAILEd*


So I created in / this directory:

Quote:
#mkdir rootvol


This solve everything and I was able to boot without an issue. Now this left me scratching my head over the reason why the script didn't give you this problem and why it did for me. Although I am not a coder I peered inside your script in order to see if I could relate something to that failed message. These are the parts where I found rootvol and I did not see "mkdir rootvol" anywhere.

Quote:
for arg in `cat /proc/cmdline`; do
case "$arg" in
lvm2root=*)
rootvol=${arg#lvm2root=}
;;
lvm2resume2=*)
resume2=${arg#lvm2resume2=}
;;
lvm2rescue)
rescue="YES"
;;
esac
done


and,

Quote:
echo "$PRE Mounting root filesystem $rootvol ro"
if ! mount -n -t auto -o ro $rootvol /rootvol; then
echo "\t*FAILED*";
do_shell
fi



I thought the initrd directory in / would be used by the script.

And in order to avoid the following message during boot,

Quote:
initrd: Finding device mapper major and minor numbers 910.63)
initrd: Activating LVM@ volumes
Locking type 1 initialisation failed.
Locking type 1 initialisation failed.


I added to your scrip what's highlited,

Quote:
echo "$PRE Activating LVM2 volumes"
lvm vgscan --ignorelockingfailure -a y

# run a shell if we're passed lvm2rescue on commandline
if [ "$rescue" = "YES" ]; then
lvm vgchange --ignorelockingfailure -P -a y
do_shell
else
lvm vgchange --ignorelockingfailure -a y
fi


After this everyhting went smoothly. I hope this helps in order to refine the script!

And again thank you very much :-)

PD: One last question, is there a way to boot in verbose mode and latter on look at the log? This would be interesting in order to check how the script is acting.
Back to top
View user's profile Send private message
nato.Otan
n00b
n00b


Joined: 23 Oct 2006
Posts: 12

PostPosted: Thu Oct 26, 2006 7:03 pm    Post subject: Desperate for help!!! Reply with quote

sorry I am here again...

:cry: :cry: :cry: :cry: :cry:

I just rebuild system and world and re-compiled the kernel 'cause I wanted new features. Then I rebuild the initrd image with lvm2create_initrd. The kernel boots and when it's done I get this message:

Quote:
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 224k freed
Kernel panic - not syncing: Not init found. Try passing ini= option to kernel


I did pass several combinations of options in the kernel including "noapic", because googling had a solution doing this, however it stops all the after kernel boot with that message!!!

Are there general rules for re-compiling the system/world/kernel in order to create the initrd image?

Googling actually didn't yield any meaningful results for this that applies to Gentoo.

Thanks

[EDIT] I just wanted to make sure that it doesn't matter whether lvm2 and busybox aren't compiled with the STATICALLY. You said before that busybox automatically creates a static version of itself.

[EDIT 2] By the way something really weird happened, when I used LiveCD and mounted / I went to check /proc directory and it was completely empty!!! As far as I know that there's been always stuff on /proc directory. I am truly perplexed as to what might've cause this!!!
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Goto page 1, 2, 3, 4, 5, 6  Next
Page 1 of 6

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum