1*86d7f5d3SJohn Marino#!/bin/bash 2*86d7f5d3SJohn Marino# 3*86d7f5d3SJohn Marino# lvm2create_initrd 4*86d7f5d3SJohn Marino# 5*86d7f5d3SJohn Marino# Miguel Cabeca 6*86d7f5d3SJohn Marino# cabeca (at) ist (dot) utl (dot) pt 7*86d7f5d3SJohn Marino# 8*86d7f5d3SJohn Marino# Inspiration to write this script came from various sources 9*86d7f5d3SJohn Marino# 10*86d7f5d3SJohn Marino# Original LVM lvmcreate_initrd: ftp://ftp.sistina.com/pub/LVM/1.0/ 11*86d7f5d3SJohn Marino# Kernel initrd.txt: http://www.kernel.org/ 12*86d7f5d3SJohn Marino# EVMS INSTALL.initrd & linuxrc: http://evms.sourceforge.net/ 13*86d7f5d3SJohn Marino# Jeffrey Layton's lvm2create_initrd: http://poochiereds.net/svn/lvm2create_initrd/ 14*86d7f5d3SJohn Marino# Christophe Saout's initrd & linuxrc: http://www.saout.de/misc/ 15*86d7f5d3SJohn Marino# 16*86d7f5d3SJohn Marino# This script was only tested with kernel 2.6 with everything required to boot 17*86d7f5d3SJohn Marino# the root filesystem built-in (not as modules). Ex: SCSI or IDE, RAID, device mapper 18*86d7f5d3SJohn Marino# It does not support devfs as it is deprecated in the 2.6 kernel series 19*86d7f5d3SJohn Marino# 20*86d7f5d3SJohn Marino# It needs lvm2 tools, busybox, pivot_root, MAKEDEV 21*86d7f5d3SJohn Marino# 22*86d7f5d3SJohn Marino# It has been tested on Debian sid (unstable) only 23*86d7f5d3SJohn Marino# 24*86d7f5d3SJohn Marino# Changelog 25*86d7f5d3SJohn Marino# 26/02/2004 Initial release -- Miguel Cabeca 26*86d7f5d3SJohn Marino# 27/02/2004 Removed the BUSYBOXSYMLINKS var. The links are now determined at runtime. 27*86d7f5d3SJohn Marino# some changes in init script to call a shell if something goes wrong. -- Miguel Cabeca 28*86d7f5d3SJohn Marino# 19/04/2004 Several small changes. Pass args to init so single user mode works. Add some 29*86d7f5d3SJohn Marino# PATH entries to /sbin/init shell script so chroot works without /usr mounted. Remove 30*86d7f5d3SJohn Marino# mkdir /initrd so we don't cause problems if root filesystem is corrupted. -- Jeff Layton 31*86d7f5d3SJohn Marino# 15/05/2004 initial support for modules, create lvm.conf from lvm dumpconfig, other cleanups -- Jeff Layton 32*86d7f5d3SJohn Marino# 14/11/2006 Update handling of ldd output to handle hardcoded library links and virtual dll linux-gate. 33*86d7f5d3SJohn Marino# Add support for Gentoo-style MAKEDEV. Remove hardcoded BINUTILS paths -- Douglas Mayle 34*86d7f5d3SJohn Marino# 35*86d7f5d3SJohn Marino# Copyright Miguel Cabeca, Jeffrey Layton, 2004 36*86d7f5d3SJohn Marino# 37*86d7f5d3SJohn Marino# This program is free software; you can redistribute it and/or modify 38*86d7f5d3SJohn Marino# it under the terms of the GNU General Public License as published by 39*86d7f5d3SJohn Marino# the Free Software Foundation; either version 2 of the License, or 40*86d7f5d3SJohn Marino# (at your option) any later version. 41*86d7f5d3SJohn Marino# 42*86d7f5d3SJohn Marino# This program is distributed in the hope that it will be useful, 43*86d7f5d3SJohn Marino# but WITHOUT ANY WARRANTY; without even the implied warranty of 44*86d7f5d3SJohn Marino# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 45*86d7f5d3SJohn Marino# GNU General Public License for more details. 46*86d7f5d3SJohn Marino# 47*86d7f5d3SJohn Marino# You should have received a copy of the GNU General Public License 48*86d7f5d3SJohn Marino# along with this program; if not, write to the Free Software 49*86d7f5d3SJohn Marino# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 50*86d7f5d3SJohn Marino# 51*86d7f5d3SJohn Marino# $Id: lvm2create_initrd,v 1.1.1.1 2008/12/22 00:18:58 haad Exp $ 52*86d7f5d3SJohn Marino 53*86d7f5d3SJohn MarinoTMPMNT=/tmp/mnt.$$ 54*86d7f5d3SJohn MarinoDEVRAM=/tmp/initrd.$$ 55*86d7f5d3SJohn Marino 56*86d7f5d3SJohn Marino# set defaults 57*86d7f5d3SJohn MarinoBINFILES=${BINFILES:-"`which lvm` `which bash` `which busybox` `which pivot_root`"} 58*86d7f5d3SJohn MarinoBASICDEVICES=${BASICDEVICES:-"std consoleonly fd"} 59*86d7f5d3SJohn MarinoBLOCKDEVICES=${BLOCKDEVICES:-"md hda hdb hdc hdd sda sdb sdc sdd"} 60*86d7f5d3SJohn MarinoMAKEDEV=${MAKEDEV:-"debian"} 61*86d7f5d3SJohn Marino 62*86d7f5d3SJohn Marino# Uncomment this if you want to disable automatic size detection 63*86d7f5d3SJohn Marino#INITRDSIZE=4096 64*86d7f5d3SJohn Marino 65*86d7f5d3SJohn MarinoPATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH 66*86d7f5d3SJohn Marino 67*86d7f5d3SJohn Marinousage () { 68*86d7f5d3SJohn Marino echo "Create an initial ramdisk image for LVM2 root filesystem" 69*86d7f5d3SJohn Marino echo "$cmd: [-h] [-v] [-c lvm.conf] [-m modulelist] [-e extrafiles] -r [raiddevs] [-R mdadm.conf] [-M style] [kernel version]" 70*86d7f5d3SJohn Marino echo " -h|--help print this usage message" 71*86d7f5d3SJohn Marino echo " -v|--verbose verbose progress messages" 72*86d7f5d3SJohn Marino echo " -c|--lvmconf path to lvm.conf (/etc/lvm/lvm.conf)" 73*86d7f5d3SJohn Marino echo " -m|--modules modules to copy to initrd image" 74*86d7f5d3SJohn Marino echo " -e|--extra extra files to add to initrd" 75*86d7f5d3SJohn Marino echo " -r|--raid raid devices to start in initrd" 76*86d7f5d3SJohn Marino echo " -R|--raidconf location of mdadm.conf file to include" 77*86d7f5d3SJohn Marino echo " -M|--makedev set MAKEDEV type (debian or redhat)" 78*86d7f5d3SJohn Marino} 79*86d7f5d3SJohn Marino 80*86d7f5d3SJohn Marinoverbose () { 81*86d7f5d3SJohn Marino [ "$VERBOSE" ] && echo "`echo $cmd | tr '[a-z0-9/_]' ' '` -- $1" || true 82*86d7f5d3SJohn Marino} 83*86d7f5d3SJohn Marino 84*86d7f5d3SJohn Marinocleanup () { 85*86d7f5d3SJohn Marino [ "`mount | grep $DEVRAM`" ] && verbose "unmounting $DEVRAM" && umount $DEVRAM 86*86d7f5d3SJohn Marino [ -f $DEVRAM ] && verbose "removing $DEVRAM" && rm $DEVRAM 87*86d7f5d3SJohn Marino [ -d $TMPMNT ] && verbose "removing $TMPMNT" && rmdir $TMPMNT 88*86d7f5d3SJohn Marino verbose "exit with code $1" 89*86d7f5d3SJohn Marino exit $1 90*86d7f5d3SJohn Marino} 91*86d7f5d3SJohn Marino 92*86d7f5d3SJohn Marinotrap " 93*86d7f5d3SJohn Marino verbose 'Caught interrupt' 94*86d7f5d3SJohn Marino echo 'Bye bye...' 95*86d7f5d3SJohn Marino cleanup 1 96*86d7f5d3SJohn Marino" 1 2 3 15 97*86d7f5d3SJohn Marino 98*86d7f5d3SJohn Marinocreate_init () { 99*86d7f5d3SJohn Marino cat << 'INIT' > $TMPMNT/sbin/init 100*86d7f5d3SJohn Marino#!/bin/bash 101*86d7f5d3SJohn Marino 102*86d7f5d3SJohn Marino# include in the path some dirs from the real root filesystem 103*86d7f5d3SJohn Marino# for chroot, blockdev 104*86d7f5d3SJohn MarinoPATH="/sbin:/bin:/usr/sbin:/usr/bin:/lib/lvm-200:/initrd/bin:/initrd/sbin" 105*86d7f5d3SJohn MarinoPRE="initrd:" 106*86d7f5d3SJohn Marino 107*86d7f5d3SJohn Marinodo_shell(){ 108*86d7f5d3SJohn Marino /bin/echo 109*86d7f5d3SJohn Marino /bin/echo "*** Entering LVM2 rescue shell. Exit shell to continue booting. ***" 110*86d7f5d3SJohn Marino /bin/echo 111*86d7f5d3SJohn Marino /bin/bash 112*86d7f5d3SJohn Marino} 113*86d7f5d3SJohn Marino 114*86d7f5d3SJohn Marinoecho "$PRE Remounting / read/write" 115*86d7f5d3SJohn Marinomount -t ext2 -o remount,rw /dev/ram0 / 116*86d7f5d3SJohn Marino 117*86d7f5d3SJohn Marino 118*86d7f5d3SJohn Marino# We need /proc for device mapper 119*86d7f5d3SJohn Marinoecho "$PRE Mounting /proc" 120*86d7f5d3SJohn Marinomount -t proc none /proc 121*86d7f5d3SJohn Marino 122*86d7f5d3SJohn Marino# plug in modules listed in /etc/modules 123*86d7f5d3SJohn Marinoif [ -f /etc/modules ]; then 124*86d7f5d3SJohn Marino echo -n "$PRE plugging in kernel modules:" 125*86d7f5d3SJohn Marino cat /etc/modules | 126*86d7f5d3SJohn Marino while read module; do 127*86d7f5d3SJohn Marino echo -n " $module" 128*86d7f5d3SJohn Marino modprobe $module 129*86d7f5d3SJohn Marino done 130*86d7f5d3SJohn Marino echo '.' 131*86d7f5d3SJohn Marinofi 132*86d7f5d3SJohn Marino 133*86d7f5d3SJohn Marino# start raid devices if raid_autostart file exists 134*86d7f5d3SJohn Marinoif [ -f /etc/raid_autostart ]; then 135*86d7f5d3SJohn Marino if [ ! -f /etc/mdadm/mdadm.conf ]; then 136*86d7f5d3SJohn Marino mdoptions='--super-minor=dev' 137*86d7f5d3SJohn Marino fi 138*86d7f5d3SJohn Marino cat /etc/raid_autostart| 139*86d7f5d3SJohn Marino while read dev; do 140*86d7f5d3SJohn Marino echo "Starting RAID device $dev" 141*86d7f5d3SJohn Marino /sbin/mdadm --assemble $dev $mdoptions 142*86d7f5d3SJohn Marino done 143*86d7f5d3SJohn Marinofi 144*86d7f5d3SJohn Marino 145*86d7f5d3SJohn Marino# Create the /dev/mapper/control device for the ioctl 146*86d7f5d3SJohn Marino# interface using the major and minor numbers that have been allocated 147*86d7f5d3SJohn Marino# dynamically. 148*86d7f5d3SJohn Marino 149*86d7f5d3SJohn Marinoecho -n "$PRE Finding device mapper major and minor numbers " 150*86d7f5d3SJohn Marino 151*86d7f5d3SJohn MarinoMAJOR=$(sed -n 's/^ *\([0-9]\+\) \+misc$/\1/p' /proc/devices) 152*86d7f5d3SJohn MarinoMINOR=$(sed -n 's/^ *\([0-9]\+\) \+device-mapper$/\1/p' /proc/misc) 153*86d7f5d3SJohn Marinoif test -n "$MAJOR" -a -n "$MINOR" ; then 154*86d7f5d3SJohn Marino mkdir -p -m 755 /dev/mapper 155*86d7f5d3SJohn Marino mknod -m 600 /dev/mapper/control c $MAJOR $MINOR 156*86d7f5d3SJohn Marinofi 157*86d7f5d3SJohn Marino 158*86d7f5d3SJohn Marinoecho "($MAJOR,$MINOR)" 159*86d7f5d3SJohn Marino 160*86d7f5d3SJohn Marino# Device-Mapper dynamically allocates all device numbers. This means it is possible 161*86d7f5d3SJohn Marino# that the root volume specified to LILO or Grub may have a different number when the 162*86d7f5d3SJohn Marino# initrd runs than when the system was last running. In order to make sure the 163*86d7f5d3SJohn Marino# correct volume is mounted as root, the init script must determine what the 164*86d7f5d3SJohn Marino# desired root volume name is by getting the LVM2 root volume name from the kernel command line. In order for 165*86d7f5d3SJohn Marino# this to work correctly, "lvm2root=/dev/Volume_Group_Name/Root_Volume_Name" needs to be passed 166*86d7f5d3SJohn Marino# to the kernel command line (where Root_Volume_Name is replaced by your actual 167*86d7f5d3SJohn Marino# root volume's name. 168*86d7f5d3SJohn Marinofor arg in `cat /proc/cmdline`; do 169*86d7f5d3SJohn Marino echo $arg | grep '^lvm2root=' > /dev/null 170*86d7f5d3SJohn Marino if [ $? -eq 0 ]; then 171*86d7f5d3SJohn Marino rootvol=${arg#lvm2root=} 172*86d7f5d3SJohn Marino break 173*86d7f5d3SJohn Marino fi 174*86d7f5d3SJohn Marinodone 175*86d7f5d3SJohn Marino 176*86d7f5d3SJohn Marinoecho "$PRE Activating LVM2 volumes" 177*86d7f5d3SJohn Marino 178*86d7f5d3SJohn Marino 179*86d7f5d3SJohn Marino# run a shell if we're passed lvm2rescue on commandline 180*86d7f5d3SJohn Marinogrep lvm2rescue /proc/cmdline 1>/dev/null 2>&1 181*86d7f5d3SJohn Marinoif [ $? -eq 0 ]; then 182*86d7f5d3SJohn Marino lvm vgchange --ignorelockingfailure -P -a y 183*86d7f5d3SJohn Marino do_shell 184*86d7f5d3SJohn Marinoelse 185*86d7f5d3SJohn Marino lvm vgchange --ignorelockingfailure -a y 186*86d7f5d3SJohn Marinofi 187*86d7f5d3SJohn Marino 188*86d7f5d3SJohn Marinoecho "$PRE Mounting root filesystem $rootvol ro" 189*86d7f5d3SJohn Marinomkdir /rootvol 190*86d7f5d3SJohn Marinoif ! mount -t auto -o ro $rootvol /rootvol; then 191*86d7f5d3SJohn Marino echo "\t*FAILED*"; 192*86d7f5d3SJohn Marino do_shell 193*86d7f5d3SJohn Marinofi 194*86d7f5d3SJohn Marino 195*86d7f5d3SJohn Marinoecho "$PRE Umounting /proc" 196*86d7f5d3SJohn Marinoumount /proc 197*86d7f5d3SJohn Marino 198*86d7f5d3SJohn Marinoecho "$PRE Changing roots" 199*86d7f5d3SJohn Marinocd /rootvol 200*86d7f5d3SJohn Marinoif ! pivot_root . initrd ; then 201*86d7f5d3SJohn Marino echo "\t*FAILED*" 202*86d7f5d3SJohn Marino do_shell 203*86d7f5d3SJohn Marinofi 204*86d7f5d3SJohn Marino 205*86d7f5d3SJohn Marinoecho "$PRE Proceeding with boot..." 206*86d7f5d3SJohn Marino 207*86d7f5d3SJohn Marinoexec chroot . /bin/sh -c "umount /initrd; blockdev --flushbufs /dev/ram0 ; exec /sbin/init $*" < dev/console > dev/console 2>&1 208*86d7f5d3SJohn Marino 209*86d7f5d3SJohn MarinoINIT 210*86d7f5d3SJohn Marino chmod 555 $TMPMNT/sbin/init 211*86d7f5d3SJohn Marino} 212*86d7f5d3SJohn Marino 213*86d7f5d3SJohn Marino# create lvm.conf file from dumpconfig. Just use filter options 214*86d7f5d3SJohn Marinocreate_lvmconf () { 215*86d7f5d3SJohn Marino echo 'devices {' > $TMPMNT/etc/lvm/lvm.conf 216*86d7f5d3SJohn Marino lvm dumpconfig | grep 'filter=' >> $TMPMNT/etc/lvm/lvm.conf 217*86d7f5d3SJohn Marino echo '}' >> $TMPMNT/etc/lvm/lvm.conf 218*86d7f5d3SJohn Marino} 219*86d7f5d3SJohn Marino 220*86d7f5d3SJohn Marino# 221*86d7f5d3SJohn Marino# Main 222*86d7f5d3SJohn Marino# 223*86d7f5d3SJohn Marino 224*86d7f5d3SJohn Marinocmd=`basename $0` 225*86d7f5d3SJohn Marino 226*86d7f5d3SJohn MarinoVERSION=`uname -r` 227*86d7f5d3SJohn Marino 228*86d7f5d3SJohn Marinowhile [ $# -gt 0 ]; do 229*86d7f5d3SJohn Marino case $1 in 230*86d7f5d3SJohn Marino -h|--help) usage; exit 0;; 231*86d7f5d3SJohn Marino -v|--verbose) VERBOSE="y";; 232*86d7f5d3SJohn Marino -c|--lvmconf) LVMCONF=$2; shift;; 233*86d7f5d3SJohn Marino -m|--modules) MODULES=$2; shift;; 234*86d7f5d3SJohn Marino -e|--extra) EXTRAFILES=$2; shift;; 235*86d7f5d3SJohn Marino -r|--raid) RAID=$2; shift;; 236*86d7f5d3SJohn Marino -R|--raidconf) RAIDCONF=$2; shift;; 237*86d7f5d3SJohn Marino -M|--makedev) MAKEDEV=$2; shift;; 238*86d7f5d3SJohn Marino [2-9].[0-9]*.[0-9]*) VERSION=$1;; 239*86d7f5d3SJohn Marino *) echo "$cmd -- invalid option '$1'"; usage; exit 0;; 240*86d7f5d3SJohn Marino esac 241*86d7f5d3SJohn Marino shift 242*86d7f5d3SJohn Marinodone 243*86d7f5d3SJohn Marino 244*86d7f5d3SJohn MarinoINITRD=${INITRD:-"/boot/initrd-lvm2-$VERSION.gz"} 245*86d7f5d3SJohn Marino 246*86d7f5d3SJohn Marinoecho "$cmd -- make LVM initial ram disk $INITRD" 247*86d7f5d3SJohn Marinoecho "" 248*86d7f5d3SJohn Marino 249*86d7f5d3SJohn Marinoif [ -n "$RAID" ]; then 250*86d7f5d3SJohn Marino BINFILES="$BINFILES /sbin/mdadm" 251*86d7f5d3SJohn Marino RAIDCONF=${RAIDCONF:-"/etc/mdadm/mdadm.conf"} 252*86d7f5d3SJohn Marino if [ -r $RAIDCONF ]; then 253*86d7f5d3SJohn Marino EXTRAFILES="$EXTRAFILES $RAIDCONF" 254*86d7f5d3SJohn Marino else 255*86d7f5d3SJohn Marino echo "$cmd -- WARNING: No $RAIDCONF! Your RAID device minor numbers must match their superblock values!" 256*86d7f5d3SJohn Marino fi 257*86d7f5d3SJohn Marinofi 258*86d7f5d3SJohn Marino 259*86d7f5d3SJohn Marino# add modprobe if we declared any modules 260*86d7f5d3SJohn Marinoif [ -n "$MODULES" ]; then 261*86d7f5d3SJohn Marino BINFILES="$BINFILES /sbin/modprobe /sbin/insmod /sbin/rmmod" 262*86d7f5d3SJohn Marinofi 263*86d7f5d3SJohn Marino 264*86d7f5d3SJohn Marinofor a in $BINFILES $EXTRAFILES; do 265*86d7f5d3SJohn Marino if [ ! -r "$a" ] ; then 266*86d7f5d3SJohn Marino echo "$cmd -- ERROR: you need $a" 267*86d7f5d3SJohn Marino exit 1; 268*86d7f5d3SJohn Marino fi; 269*86d7f5d3SJohn Marinodone 270*86d7f5d3SJohn Marino 271*86d7f5d3SJohn Marino# Figure out which shared libraries we actually need in our initrd 272*86d7f5d3SJohn Marinoecho "$cmd -- finding required shared libraries" 273*86d7f5d3SJohn Marinoverbose "BINFILES: `echo $BINFILES`" 274*86d7f5d3SJohn Marino 275*86d7f5d3SJohn Marino# We need to strip certain lines from ldd output. This is the full output of an example ldd: 276*86d7f5d3SJohn Marino#lvmhost~ # ldd /sbin/lvm /bin/bash 277*86d7f5d3SJohn Marino#/sbin/lvm: 278*86d7f5d3SJohn Marino# not a dynamic executable 279*86d7f5d3SJohn Marino#/bin/bash: 280*86d7f5d3SJohn Marino# linux-gate.so.1 => (0xbfffe000) 281*86d7f5d3SJohn Marino# libncurses.so.5 => /lib/libncurses.so.5 (0xb7ee3000) 282*86d7f5d3SJohn Marino# libdl.so.2 => /lib/libdl.so.2 (0xb7edf000) 283*86d7f5d3SJohn Marino# libc.so.6 => /lib/libc.so.6 (0xb7dc1000) 284*86d7f5d3SJohn Marino# /lib/ld-linux.so.2 (0xb7f28000) 285*86d7f5d3SJohn Marino# 286*86d7f5d3SJohn Marino# 1) Lines with a ":" contain the name of the original binary we're examining, and so are unnecessary. 287*86d7f5d3SJohn Marino# We need to strip them because they contain "/", and can be confused with links with a hardcoded path. 288*86d7f5d3SJohn Marino# 2) The linux-gate library is a virtual dll that does not exist on disk, but is instead loaded automatically 289*86d7f5d3SJohn Marino# into the process space, and can't be copied to the ramdisk 290*86d7f5d3SJohn Marino# 291*86d7f5d3SJohn Marino# After these lines have been stripped, we're interested in the lines remaining if they 292*86d7f5d3SJohn Marino# 1) Contain "=>" because they are pathless links, and the value following the token is the path on the disk 293*86d7f5d3SJohn Marino# 2) Contain "/" because it's a link with a hardcoded path, and so we're interested in the link itself. 294*86d7f5d3SJohn MarinoLIBFILES=`ldd $BINFILES 2>/dev/null |grep -v -E \(linux-gate\|:\) | awk '{if (/=>/) { print $3 } else if (/\//) { print $1 }}' | sort -u` 295*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 296*86d7f5d3SJohn Marino echo "$cmd -- ERROR figuring out needed shared libraries" 297*86d7f5d3SJohn Marino exit 1 298*86d7f5d3SJohn Marinofi 299*86d7f5d3SJohn Marino 300*86d7f5d3SJohn Marinoverbose "Shared libraries needed: `echo $LIBFILES`" 301*86d7f5d3SJohn Marino 302*86d7f5d3SJohn MarinoINITRDFILES="$BINFILES $LIBFILES $MODULES $EXTRAFILES" 303*86d7f5d3SJohn Marino 304*86d7f5d3SJohn Marino# tack on stuff for modules if we declared any and the files exist 305*86d7f5d3SJohn Marinoif [ -n "$MODULES" ]; then 306*86d7f5d3SJohn Marino if [ -f "/etc/modprobe.conf" ]; then 307*86d7f5d3SJohn Marino INITRDFILES="$INITRDFILES /etc/modprobe.conf" 308*86d7f5d3SJohn Marino fi 309*86d7f5d3SJohn Marino if [ -f "/lib/modules/modprobe.conf" ]; then 310*86d7f5d3SJohn Marino INITRDFILES="$INITRDFILES /lib/modules/modprobe.conf" 311*86d7f5d3SJohn Marino fi 312*86d7f5d3SJohn Marinofi 313*86d7f5d3SJohn Marino 314*86d7f5d3SJohn Marino# Calculate the the size of the ramdisk image. 315*86d7f5d3SJohn Marino# Don't forget that inodes take up space too, as does the filesystem metadata. 316*86d7f5d3SJohn Marinoecho "$cmd -- calculating initrd filesystem parameters" 317*86d7f5d3SJohn Marinoif [ -z "$INITRDSIZE" ]; then 318*86d7f5d3SJohn Marino echo "$cmd -- calculating loopback file size" 319*86d7f5d3SJohn Marino verbose "finding size" 320*86d7f5d3SJohn Marino INITRDSIZE="`du -Lck $INITRDFILES | tail -1 | cut -f 1`" 321*86d7f5d3SJohn Marino verbose "minimum: $INITRDSIZE kB for files + inodes + filesystem metadata" 322*86d7f5d3SJohn Marino INITRDSIZE=`expr $INITRDSIZE + 512` # enough for ext2 fs + a bit 323*86d7f5d3SJohn Marinofi 324*86d7f5d3SJohn Marino 325*86d7f5d3SJohn Marinoecho "$cmd -- making loopback file ($INITRDSIZE kB)" 326*86d7f5d3SJohn Marinoverbose "using $DEVRAM as a temporary loopback file" 327*86d7f5d3SJohn Marinodd if=/dev/zero of=$DEVRAM count=$INITRDSIZE bs=1024 > /dev/null 2>&1 328*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 329*86d7f5d3SJohn Marino echo "$cmd -- ERROR creating loopback file" 330*86d7f5d3SJohn Marino cleanup 1 331*86d7f5d3SJohn Marinofi 332*86d7f5d3SJohn Marino 333*86d7f5d3SJohn Marinoecho "$cmd -- making ram disk filesystem" 334*86d7f5d3SJohn Marinoverbose "mke2fs -F -m0 -L LVM-$VERSION $DEVRAM $INITRDSIZE" 335*86d7f5d3SJohn Marino[ "$VERBOSE" ] && OPT_Q="" || OPT_Q="-q" 336*86d7f5d3SJohn Marinomke2fs $OPT_Q -F -m0 -L LVM-$VERSION $DEVRAM $INITRDSIZE 337*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 338*86d7f5d3SJohn Marino echo "$cmd -- ERROR making ram disk filesystem" 339*86d7f5d3SJohn Marino echo "$cmd -- ERROR you need to use mke2fs >= 1.14 or increase INITRDSIZE" 340*86d7f5d3SJohn Marino cleanup 1 341*86d7f5d3SJohn Marinofi 342*86d7f5d3SJohn Marino 343*86d7f5d3SJohn Marinoverbose "creating mountpoint $TMPMNT" 344*86d7f5d3SJohn Marinomkdir $TMPMNT 345*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 346*86d7f5d3SJohn Marino echo "$cmd -- ERROR making $TMPMNT" 347*86d7f5d3SJohn Marino cleanup 1 348*86d7f5d3SJohn Marinofi 349*86d7f5d3SJohn Marino 350*86d7f5d3SJohn Marinoecho "$cmd -- mounting ram disk filesystem" 351*86d7f5d3SJohn Marinoverbose "mount -o loop $DEVRAM $TMPMNT" 352*86d7f5d3SJohn Marinomount -oloop $DEVRAM $TMPMNT 353*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 354*86d7f5d3SJohn Marino echo "$cmd -- ERROR mounting $DEVRAM on $TMPMNT" 355*86d7f5d3SJohn Marino cleanup 1 356*86d7f5d3SJohn Marinofi 357*86d7f5d3SJohn Marino 358*86d7f5d3SJohn Marinoverbose "creating basic set of directories in $TMPMNT" 359*86d7f5d3SJohn Marino(cd $TMPMNT; mkdir bin dev etc lib proc sbin var) 360*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 361*86d7f5d3SJohn Marino echo "$cmd -- ERROR creating directories in $TMPMNT" 362*86d7f5d3SJohn Marino cleanup 1 363*86d7f5d3SJohn Marinofi 364*86d7f5d3SJohn Marino 365*86d7f5d3SJohn Marino# Add some /dev files. We have to handle different types of MAKEDEV invocations 366*86d7f5d3SJohn Marino# here, so this is rather messy. 367*86d7f5d3SJohn MarinoRETCODE=0 368*86d7f5d3SJohn Marinoecho "$cmd -- adding required /dev files" 369*86d7f5d3SJohn Marinoverbose "BASICDEVICES: `echo $BASICDEVICES`" 370*86d7f5d3SJohn Marinoverbose "BLOCKDEVICES: `echo $BLOCKDEVICES`" 371*86d7f5d3SJohn Marino[ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q="" 372*86d7f5d3SJohn Marinocase "$MAKEDEV" in 373*86d7f5d3SJohn Marinodebian) 374*86d7f5d3SJohn Marino (cd $TMPMNT/dev; /dev/MAKEDEV $OPT_Q $BASICDEVICES $BLOCKDEVICES) 375*86d7f5d3SJohn Marino RETCODE=$? 376*86d7f5d3SJohn Marino ;; 377*86d7f5d3SJohn Marinoredhat) 378*86d7f5d3SJohn Marino (cd $TMPMNT/dev; /dev/MAKEDEV $OPT_Q -d $TMPMNT/dev -m 2) 379*86d7f5d3SJohn Marino RETCODE=$? 380*86d7f5d3SJohn Marino ;; 381*86d7f5d3SJohn Marinogentoo) 382*86d7f5d3SJohn Marino (cd $TMPMNT/dev; /usr/sbin/MAKEDEV $OPT_Q $BASICDEVICES $BLOCKDEVICES) 383*86d7f5d3SJohn Marino RETCODE=$? 384*86d7f5d3SJohn Marino ;; 385*86d7f5d3SJohn Marino*) 386*86d7f5d3SJohn Marino echo "$cmd -- ERROR: $MAKEDEV is not a known MAKEDEV style." 387*86d7f5d3SJohn Marino RETCODE=1 388*86d7f5d3SJohn Marino ;; 389*86d7f5d3SJohn Marinoesac 390*86d7f5d3SJohn Marino 391*86d7f5d3SJohn Marino 392*86d7f5d3SJohn Marinoif [ $RETCODE -ne 0 ]; then 393*86d7f5d3SJohn Marino echo "$cmd -- ERROR adding /dev files" 394*86d7f5d3SJohn Marino cleanup 1 395*86d7f5d3SJohn Marinofi 396*86d7f5d3SJohn Marino 397*86d7f5d3SJohn Marino 398*86d7f5d3SJohn Marino# copy necessary files to ram disk 399*86d7f5d3SJohn Marinoecho "$cmd -- copying initrd files to ram disk" 400*86d7f5d3SJohn Marino[ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q="--quiet" 401*86d7f5d3SJohn Marinoverbose "find \$INITRDFILES | cpio -pdmL $OPT_Q $TMPMNT" 402*86d7f5d3SJohn Marinofind $INITRDFILES | cpio -pdmL $OPT_Q $TMPMNT 403*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 404*86d7f5d3SJohn Marino echo "$cmd -- ERROR cpio to ram disk" 405*86d7f5d3SJohn Marino cleanup 1 406*86d7f5d3SJohn Marinofi 407*86d7f5d3SJohn Marino 408*86d7f5d3SJohn Marino 409*86d7f5d3SJohn Marinoecho "$cmd -- creating symlinks to busybox" 410*86d7f5d3SJohn Marinoshopt -s extglob 411*86d7f5d3SJohn Marino[ "$VERBOSE" ] && OPT_Q="-v" || OPT_Q="" 412*86d7f5d3SJohn MarinoBUSYBOXSYMLINKS=`busybox 2>&1| awk '/^Currently defined functions:$/ {i++;next} i'|tr ',\t\n' ' '` 413*86d7f5d3SJohn Marinofor link in ${BUSYBOXSYMLINKS//@(linuxrc|init|busybox)}; do 414*86d7f5d3SJohn Marino ln -s $OPT_Q busybox $TMPMNT/bin/$link; 415*86d7f5d3SJohn Marinodone 416*86d7f5d3SJohn Marinoshopt -u extglob 417*86d7f5d3SJohn Marino 418*86d7f5d3SJohn Marinoecho "$cmd -- creating new $TMPMNT/sbin/init" 419*86d7f5d3SJohn Marinocreate_init 420*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 421*86d7f5d3SJohn Marino echo "$cmd -- ERROR creating init" 422*86d7f5d3SJohn Marino cleanup 423*86d7f5d3SJohn Marino exit 1 424*86d7f5d3SJohn Marinofi 425*86d7f5d3SJohn Marino 426*86d7f5d3SJohn Marino# copy LVMCONF into place or create a stripped down one from lvm dumpconfig 427*86d7f5d3SJohn Marinomkdir -p $TMPMNT/etc/lvm 428*86d7f5d3SJohn Marinoif [ -n "$LVMCONF" ]; then 429*86d7f5d3SJohn Marino echo "$cmd -- copying $LVMCONF to $TMPMNT/etc/lvm/lvm.conf" 430*86d7f5d3SJohn Marino if [ -f "$LVMCONF" ]; then 431*86d7f5d3SJohn Marino cp $LVMCONF $TMPMNT/etc/lvm/lvm.conf 432*86d7f5d3SJohn Marino else 433*86d7f5d3SJohn Marino echo "$cmd -- ERROR: $LVMCONF does not exist!" 434*86d7f5d3SJohn Marino cleanup 435*86d7f5d3SJohn Marino exit 1 436*86d7f5d3SJohn Marino fi 437*86d7f5d3SJohn Marinoelse 438*86d7f5d3SJohn Marino echo "$cmd -- creating new $TMPMNT/etc/lvm/lvm.conf" 439*86d7f5d3SJohn Marino create_lvmconf 440*86d7f5d3SJohn Marinofi 441*86d7f5d3SJohn Marino 442*86d7f5d3SJohn Marinoif [ -n "$RAID" ]; then 443*86d7f5d3SJohn Marino RAIDLIST="$TMPMNT/etc/raid_autostart" 444*86d7f5d3SJohn Marino echo "$cmd -- creating $RAIDLIST file." 445*86d7f5d3SJohn Marino for device in $RAID; do 446*86d7f5d3SJohn Marino echo $device >> $RAIDLIST 447*86d7f5d3SJohn Marino done 448*86d7f5d3SJohn Marinofi 449*86d7f5d3SJohn Marino 450*86d7f5d3SJohn Marino# create modules.dep and /etc/modules files if needed 451*86d7f5d3SJohn Marinoif [ -n "$MODULES" ]; then 452*86d7f5d3SJohn Marino echo "$cmd -- creating $MODDIR/modules.dep file and $TMPMNT/etc/modules" 453*86d7f5d3SJohn Marino depmod -b $TMPMNT $VERSION 454*86d7f5d3SJohn Marino for module in $MODULES; do 455*86d7f5d3SJohn Marino basename $module | sed 's/\.k\{0,1\}o$//' >> $TMPMNT/etc/modules 456*86d7f5d3SJohn Marino done 457*86d7f5d3SJohn Marinofi 458*86d7f5d3SJohn Marino 459*86d7f5d3SJohn Marinoverbose "removing $TMPMNT/lost+found" 460*86d7f5d3SJohn Marinormdir $TMPMNT/lost+found 461*86d7f5d3SJohn Marino 462*86d7f5d3SJohn Marinoecho "$cmd -- ummounting ram disk" 463*86d7f5d3SJohn Marinoumount $DEVRAM 464*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 465*86d7f5d3SJohn Marino echo "$cmd -- ERROR umounting $DEVRAM" 466*86d7f5d3SJohn Marino cleanup 1 467*86d7f5d3SJohn Marinofi 468*86d7f5d3SJohn Marino 469*86d7f5d3SJohn Marinoecho "$cmd -- creating compressed initrd $INITRD" 470*86d7f5d3SJohn Marinoverbose "dd if=$DEVRAM bs=1k count=$INITRDSIZE | gzip -9" 471*86d7f5d3SJohn Marinodd if=$DEVRAM bs=1k count=$INITRDSIZE 2>/dev/null | gzip -9 > $INITRD 472*86d7f5d3SJohn Marinoif [ $? -ne 0 ]; then 473*86d7f5d3SJohn Marino echo "$cmd -- ERROR creating $INITRD" 474*86d7f5d3SJohn Marino cleanup 1 475*86d7f5d3SJohn Marinofi 476*86d7f5d3SJohn Marino 477*86d7f5d3SJohn Marino 478*86d7f5d3SJohn Marinocat << FINALTXT 479*86d7f5d3SJohn Marino-------------------------------------------------------- 480*86d7f5d3SJohn MarinoYour initrd is ready in $INITRD 481*86d7f5d3SJohn Marino 482*86d7f5d3SJohn MarinoDon't forget to set root=/dev/ram0 in kernel parameters 483*86d7f5d3SJohn MarinoDon't forget to set lvm2root=/dev/VG/LV in kernel parameters, where LV is your root volume 484*86d7f5d3SJohn MarinoIf you use lilo try adding/modifying an entry similar to this one in lilo.conf: 485*86d7f5d3SJohn Marino 486*86d7f5d3SJohn Marinoimage=/boot/vmlinuz-lvm2-$VERSION 487*86d7f5d3SJohn Marino label="ramdisk_LVM" 488*86d7f5d3SJohn Marino initrd=/boot/initrd-lvm2-$VERSION.gz 489*86d7f5d3SJohn Marino append="root=/dev/ram0 lvm2root=/dev/system/root <other parameters>" 490*86d7f5d3SJohn Marino 491*86d7f5d3SJohn MarinoIf using grub try adding/modifying an entry similar to this one in menu.lst 492*86d7f5d3SJohn Marino 493*86d7f5d3SJohn Marinotitle ramdisk LVM 494*86d7f5d3SJohn Marino kernel /boot/vmlinuz-lvm2-$VERSION root=/dev/ram0 lvm2root=/dev/system/root <other parameters> 495*86d7f5d3SJohn Marino initrd /boot/initrd-lvm2-$VERSION.gz 496*86d7f5d3SJohn Marino 497*86d7f5d3SJohn MarinoYou can also pass lvm2rescue to the kernel to get a shell 498*86d7f5d3SJohn Marino-------------------------------------------------------- 499*86d7f5d3SJohn MarinoFINALTXT 500*86d7f5d3SJohn Marino 501*86d7f5d3SJohn Marinocleanup 0 502*86d7f5d3SJohn Marino 503