# 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.