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.