Building an init-ramdisk to use with EVMS
EVMS versions 1.9.0 and later perform volume discovery in user space and
communicate with kernel drivers to activate the volumes. This process presents
a problem with having the root file system on an EVMS volume. In order for the
root file system volume to be activated, the EVMS tools must be running. However,
in order to access the EVMS tools, the root file system must be mounted.
The solution to this dilemma is to use an initial ramdisk (initrd). An initrd is a
ram-based device that acts as a temporary root file system at boot time and provides
the ability to run programs and load modules that are necessary to activate the true
root file system. Thus, in order to have your root file system on an EVMS volume, you
need to create and use an initrd.
The following sections provide instructions for creating a new initrd image for use
with EVMS.
Build and install EVMS
Follow the normal EVMS installation instructions for configuring your kernel
and building the EVMS tools. See or the INSTALL file in
the EVMS package for more information.
Kernel support for initrd
Before you can start creating the initrd, make sure your kernel
supports ramdisks. You can verify that your kernel supports ramdisks
when the kernel is being configured; if it does not support ramdisks, you
change the settings so that the kernel does support ramdisks.
Start the kernel configuration:
cd /usr/src/linux
make xconfig
On the Main Menu screen, under the section for Block Devices, check
to see if "RAM disk support" and "Initial RAM disk (initrd) support"
are supported (a "Y" should be in the field before each entry).
If they are not supported, enter a "Y" for "RAM disk support" and
"Initial RAM disk (initrd) support."
Main Menu
-Block Devices
<Y>RAM disk support
<Y>Initial RAM disk (initrd) support
This support must be built statically into the kernel. Building RAM disk support
as a module will not work. The "Default RAM disk size" option is not important at
this time, because it can be modified with a command-line option to the kernel.
Save your kernel configuration and rebuild and reinstall your kernel.
Build the initrd image
The next step is to build the actual ramdisk image, which is
described in the following subsections.
The important thing to remember is that any program that needs to
run from the initrd needs to be copied to the initrd.
In addition, any shared libraries that are needed by programs that run
from the initrd need to be copied to the initrd as well.
Create a new, blank initrd
Start by creating a new initrd image with an ext2 file system.
The following example creates the initrd image at
/boot/initrd-evms.
You can choose to use a different file name if you wish.
The size of the initrd in the following example is 16 MB.
You can make the initrd larger or smaller by adjusting the "count"
value.
The minimum size needed for all the required EVMS tools and supporting
libraries is about 11 MB.
If you are installing kernel modules to your initrd (see step 3-H below)
or other non-EVMS programs, the size might need to be increased.
dd if=/dev/zero of=/boot/initrd-evms bs=1M count=16
mke2fs -F -m 0 -b 1024 /boot/initrd-evms
Mount the initrd
In order to copy all the required files to the initrd, the initrd must be mounted
through a loopback device. To mount the initrd through a loopback device requires
that you have loopback support compiled in your kernel (or as a kernel module).
See the "Block Devices" menu in the kernel configuration for more information
about loopback.
mkdir /mnt/initrd
mount -t ext2 -o loop /boot/initrd-evms /mnt/initrd
Set up the basic directory structure
Use the following commands to create several basic directories that
are required on the initrd:
cd /mnt/initrd
mkdir bin dev etc lib proc sbin var
cd var
mkdir lock log
Copy helpful utilities
The script that runs in the initrd requires a few common command-line utilities, which
you can create with the following commands:
cd /bin
cp -a bash cat echo expr grep mount sh umount /mnt/initrd/bin
cd /etc
cp fstab /mnt/initrd/etc
Copy supporting libraries
The utilities from the previous step, along with the EVMS tools, require a few
common shared libraries. You can create these shared libraries with the following
commands:
cd /lib
cp -a ld-* /mnt/initrd/lib
cp -a libc-* libc.* /mnt/initrd/lib
cp -a libdl-* libdl.* /mnt/initrd/lib
cp -a libpthread* /mnt/initrd/lib
cp -a libtermcap* /mnt/initrd/lib
It is possible that some of the utilities (bash in particular) require additional
libraries. Use the ldd command to determine if you need additional
libraries copied to your initrd. For example, output from
the ldd /bin/bash command provides a list similar to the following:
libtermcap.so.2 => /lib/libtermcap.so.2 (0x40020000)
libdl.so.2 => /lib/libdl.so.2 (0x40024000)
libc.so.6 => /lib/libc.so.6 (0x40027000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x4000000)
All libraries listed by ldd need to be copied to the
/lib directory on the initrd.
Copy the EVMS tools
Several EVMS libraries and a couple of executables need to be copied
to the initrd.
First, you need to locate where the EVMS libraries were installed. By default,
these libraries are installed in /lib. If you specified a different
prefix or libdir when you configured EVMS, the libraries might be located in a
different directory. It is important that these libraries be installed in the same
location on the initrd as they are on your real system. For example, if the libraries
installed in /lib, the libraries need to be copied to /lib on the initrd;
If the libraries are installed in /usr/lib, they need to be copied to /usr/lib on the initrd.
The following example assumes the libraries are installed in /lib. Only
the shared libraries (.so) need to be copied. The static versions (.a) are not
needed on the initrd.
cd /lib
cp -a libevms*so* /mnt/initrd/lib
cp -a libdlist*so* /mnt/initrd/lib
Next, copy the plug-in libraries to the initrd. The plug-ins are always installed
in the evms subdirectory of the directory where libevms is installed.
Not all of the plug-ins need to be copied to the initrd. Several plug-ins are
only for interfacing with the file system utilities and are not necessary at boot time.
Other plug-ins are only for interfacing with clustering packages, which cannot be
started until the regular boot process.
The following is a list of the specific plug-ins that do not need to be installed:
csm
ext2
ha
jfs
reiser
replace
rsct
swap
xfs
Create and change directory to /lib/evms:
mkdir /mnt/initrd/lib/evms
cd /lib/evms
Copy the contents of the /lib/evms directory, minus the plug-ins
listed earlier that
do not need to be installed, to /mnt/initrd/lib/evms:
for foo in aix bbr bsd disk dos drivelink gpt lvm md os2 s390 snapshot sparse
do
cp -a *$foo* /mnt/initrd/lib/evms
done
Next, copy the activation program to the initrd. The full user interfaces are
not needed, because the only thing the initrd does is activate the volumes.
Unlike the EVMS libraries, the exact location of this program in the initrd is not
important, so it can simply go in sbin:
cd /sbin
cp evms_activate /mnt/initrd/sbin
cp get_dev_num /mnt/initrd/sbin
Finally, if you have an /etc/evms.conf file installed, you should copy it to
the initrd so that EVMS uses the correct options during activation. (However,
if you have an /etc/evms.conf file but have never modified it for your system, it should still have all the default values and does not necessarily need to
be installed on the initrd.)
cd /etc
cp evms.conf /mnt/initrd/etc
Set up disk devices
The initrd needs to be set up to reflect the disk devices that are on your system.
EVMS needs to find the disks in order to activate the volumes.
Before setting up the disk devices on the initrd, determine if you are
using devfs. If you are not sure, you can quickly check for the file
/dev/.devfsd. If /dev/.devfsd exists, you are running devfs.
You can also
check your kernel configuration in the "Filesystems" menu. If
"/dev file system support" and "Automatically mount at boot" are enabled, you are
running devfs.
devfs users
Because devfs runs automatically within the initrd, you do not need to
manually copy the device files to the initrd. However, devfs does need to be
mounted within the initrd for it to work properly. There are two ways to accomplish this:
In the kernel configuration, in the "Filesystems" menu, set the
"Automatically mount at boot time" option. With this option set, devfs will be
automatically mounted on /dev when the initrd is loaded.
Manually mount devfs from the linuxrc script before running
evms_activate. See for more details.
devfsd users
EVMS does not require devfs users to run devfsd.
However, if you do run
devfsd, you also need to run it on the initrd to ensure that all disks and segments
are discovered with the same names on both the initrd and the real system. Thus, if
you run devfsd, you need to copy the devfsd program and
config file to the initrd, as
follows:
cd /sbin
cp devfsd /mnt/initrd/sbin
cd /etc
cp devfsd.conf /mnt/initrd/etc
Next, examine the devfsd.conf file (the one you just copied to the ramdisk) with
a text editor. First look for a line like this:
LOOKUP.* MODLOAD
Also in the devfsd file, look for a line that begins with RESTORE. This line
specifies a directory where devfsd stores changes to
the /dev file system. Create this
directory in your initrd. For example, if your devfsd.conf file contains the line
"RESTORE /dev-state," issue the following commands to prevent error messages from
being generated when devfsd starts within the initrd:
cd /mnt/initrd
mkdir dev-state
Non-devfs users
Because devfs is not running and mounted within the initrd, you need to
manually copy the necessary device node files to the initrd. If you only have IDE
or SCSI disks, the following commands should be sufficient. If you specifically
know which disks are on your system, you can copy only those device files.
cd /dev
cp -a hd[a-z] /mnt/initrd/dev
In addition to the disk devices, you also need a console device:
cp -a console /mnt/initrd/dev
Copy kernel modules
If you have any kernel modules that need to be loaded in order for EVMS to
run, those modules need to be copied to the initrd. In particular, if you build your
IDE or SCSI drivers, the Device Mapper or MD/Software-RAID drivers, or any
required file systems as modules, they need to be present on the initrd so they
can be loaded before you run EVMS and try to mount the root file system.
If you build all of the necessary drivers and file systems statically into the
kernel, you can skip this step. Skipping this step is the recommended approach so
that you avoid any possible problems that might be caused by required modules missing
from the initrd.
When copying the kernel modules, it is probably safest to copy the entire
module directory so as not to miss any modules that might be needed on the initrd:
mkdir /mnt/initrd/lib/modules
cd /lib/modules
cp -a x.y.z /mnt/initrd/lib/modules
x.y.z is the version of the kernel that will be running EVMS and the initrd.
In addition, you will need the module-loading utilities, and probably the module
configuration file:
cd /sbin
cp modprobe /mnt/initrd/sbin
cd /etc
cp modules.conf /mnt/initrd/etc
Write the linuxrc script
At this point, all of the necessary files, programs, and libraries should be on
the initrd. The only thing remaining is the linuxrc script.
When the kernel mounts the initrd, it tries to run a script called linuxrc, in the root of
the initrd. This script performs all the actions necessary for the initrd, and prepares the
root device so that it can be mounted when the initrd exits.
A sample linuxrc script is provided in the doc directory of the EVMS source package.
You can use this script as a starting point.
Copy the linuxrc sample to your initrd:
cd /usr/src/evms-2.0.0/doc
cp linuxrc /mnt/initrd
Open the linuxrc sample script in your favorite text editor. The following paragraphs
provide a brief explanation of what the linuxrc does at boot time and offer suggestions for
modifying the script for your system.
The first section tries to mount devfs. You only need to
uncomment this section if you are running devfs and do not automatically mount
devfs on /dev (see for more details).
The next section tries to start the devfs daemon. If devfs
is not running or devfsd is not present, this section is skipped.
The next section mounts the proc file system.
EVMS looks in the /proc file system to find the location of the
Device Mapper driver. Also, later parts of the linuxrc script try to
access /proc in order to properly set the root file system device.
The next section loads the kernel modules. If you did not copy any
kernel modules to your initrd (), you can leave this section commented out.
If you need to load kernel modules from the initrd, this is the place to do it. Use
the modprobe command for each module that needs to be loaded.
A few examples have been provided within the section.
The next section is where EVMS runs and activates all of the volumes.
The next section examines the kernel command line for a parameter
that specifies the root volume. More information about how to set up this
parameter is included in . Device Mapper
dynamically allocates all device numbers, which means it is possible that the
root volume specified to LILO or GRUB might 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 linuxrc script must determine what the
desired root volume name is, determine the number for that device, and set
that value in the appropriate file in /proc.
Finally, the /proc file system can be unmounted.
Also, devfs
can be unmounted (but only if it was mounted at the start of the script).
When the linuxrc script completes, the kernel automatically tries to
mount the root file system, and the initrd is removed from memory.
Unmount the initrd image
The contents of the initrd should now be complete and you can unmount it.
Compress the initrd image
To conserve space, compress the initrd image:
gzip /boot/initrd-evms
Set up the boot loader
In order to actually use the initrd at boot time, the boot-loader must know the location
of the initrd so it can tell the kernel where to load it from. There are also some other changes
that the boot loader needs to know about in order to successfully mount your EVMS
volume as the root file system. The procedure is slightly different for LILO and GRUB, the
two main boot loaders used with Linux.
LILO procedure
LILO uses the file /etc/lilo.conf as its configuration file. Edit
the file with a text editor. If you have not already done so, add an image section
for the kernel you will be using with EVMS. The section should look something like this:
image = /boot/vmlinuz-2.4.20 # Replace with your kernel image
label = 2.4.20 #Any label you'd like to use
read-only
initrd = /boot/initrd-evms.gz # The compressed initrd you just created
append = "ramdisk=16384 root=/dev/evms/Root"
The last line (beginning with "append") in this section is very important. The line specifies
parameters that are passed to the kernel command line. The "ramdisk" option
overrides the default ramdisk size. This value is in kilobytes and needs to be
at least as big as the initrd image you created in step . Thus, if your initrd
image is 20 MB, you need to set this value to 20 * 1024 = 20480.
The "root" option in the "append" line is not only a parameter to the kernel
but also an indicator to the linuxrc script () so it can determine the name of
your root file system and use it to tell the kernel the actual root device after the
volumes have been activated. Obviously, you should set this option to the actual
name of your root volume.
After updating /etc/lilo.conf, run lilo to install the boot-loader.
GRUB procedure
GRUB uses the file /boot/grub/menu.lst as its configuration file.
Edit this file with a text editor. If you have not already, add a menu item for the kernel
you will be using with EVMS. The menu item should look something like this:
title 2.4.20 # Any label you'd like to use
kernel (hd0,0)/vmlinuz-2.4.20 root=/dev/evms/Root ramdisk=16384
# Replace with the name of your kernel image.
# See the Grub documentation for which (hdx,y)
# value to use.
initrd (hd0,0)/initrd-evms.gz # The compressed initrd image you just created
The extra information after the kernel image name is very important.
These are parameters that are passed to the kernel command line.
The "ramdisk" option
overrides the default ramdisk size. This value is in kilobytes and needs to be
at least as big as the initrd image you created in . Thus, if your initrd
image is 20 MB, you need to set this value to 20 * 1024 = 20480.
The "root" option in the "kernel" line is not only a parameter to the kernel
but also an indicator to the linuxrc script () so it can determine the name of
your root file system and use it to tell the kernel the actual root device after the
volumes have been activated. Obviously, you should set this option to the actual
name of your root volume.
Update the file system configuration
Because the goal of creating the initrd is to use an EVMS volume as your
root file system, you also need to update the fstab file. Edit /etc/fstab with a text editor.
There should be an entry in the file similar to the following:
/dev/evms/RootVolume / ext2 defaults 1 1
Replace RootVolume with the actual name of your root volume, and
ext2 with
the appropriate type for the root file system.
Reboot the system
The kernel has been built with the appropriate support, the initrd image has
been constructed, and the boot-loader has been configured. You are now
ready to reboot your system using your EVMS volume as the root file system.
In general, you should still run evms_activate during your regular boot scripts.
Even though the volumes will already be activated, running evms_activate
makes sure the device files in /dev/evms correctly reflect the device numbers
assigned by Device Mapper.