# cat init #!/bin/busybox sh export PATH=/sbin:/bin DEBUG=0 rescue_shell() { echo "$@" echo "Something went wrong. Dropping you to a shell." busybox --install -s exec /bin/sh } # allow the use of UUIDs or filesystem lables uuidlabel_root() { for cmd in $(cat /proc/cmdline) ; do case ${cmd} in root=*) type=$(echo $cmd | cut -d= -f2) echo "Mounting rootfs" if [ ${type} == "LABEL" ] || [ ${type} == "UUID" ]; then uuid=$(echo $cmd | cut -d= -f3) mount -o ro $(findfs "${type}"="$uuid") /mnt/root else mount -o ro $(echo ${cmd} | cut -d= -f2) /mnt/root fi ;; esac done } check_filesystem() { # most of code coming from /etc/init.d/fsck local fsck_opts="" check_extra="" RC_UNAME=$(uname -s) local fs_type="$(grep $1 /mnt/root/etc/fstab | awk '{print 3}')" fsck_prefix="" # FIXME : get_bootparam forcefsck if [ -e /forcefsck ]; then fsck_opts="${fsck_opts} -f" check_extra="(check forced)" fi echo "Checking local filesystem $check_extra : $1" if [ "$RC_UNAME" = Linux ]; then case "${fs_type}" in reiserfs) fsck_opts="${fsck_opts} --check" fsck_prefix="echo Yes | " ;; ext4) fsck_opts="-p ${fsck_opts} -C0 -T" ;; *) rescue_shell "unknown fs type ${fs_type}" ;; esac fi trap : INT QUIT # using our own fsck, not the builtin one from busybox eval "${fsck_prefix}fsck.${fs_type} ${fsck_opts} $1" ret_val=$? case ${ret_val} in 0) return 0 ;; 1) echo "Filesystem repaired"; return 0 ;; 2|3) if [ "${RC_UNAME}" = Linux ]; then echo "Filesystem repaired, but reboot needed" reboot -f else rescue_shell "Filesystem still have errors; manual fsck required" fi ;; 4) if [ "${RC_UNAME}" = Linux ]; then rescue_shell "Fileystem errors left uncorrected, aborting" else echo "Filesystem repaired, but reboot needed" reboot fi ;; 8) echo "Operational error" return 0 ;; 16) echo "Use or Syntax Error" return 16 ;; 32) echo "fsck interrupted" ;; 127) echo "Shared Library Error" sleep 20 return 0 ;; *) echo ${ret_val} echo "Some random fsck error - continuing anyway" sleep 20 return 0 ;; esac # rescue_shell can't find tty so its broken rescue_shell } create_labels() { mkdir -p /dev/disk/by-label while read partition; do DEV="$(echo ${partition} | awk '{print $4}')" DEV_PATH="/dev/${DEV}" if [ -z "${DEV}" -o ! -e "${DEV_PATH}" ]; then continue fi LABEL=$(busybox blkid ${DEV_PATH} | tr ' ' '\n' | grep "LABEL=" | cut -d= -f2 | sed 's/"//g') if [ ! -z "${LABEL}" ]; then ln -s ${DEV_PATH} /dev/disk/by-label/${LABEL} fi done < "/proc/partitions" } # start for real here # temporarily mount proc and sys mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpfs none /dev CMDLINE="$(cat /proc/cmdline)" for param in ${CMDLINE}; do case "${param}" in rescue) echo "Rescue boot mode: invoking ash." rescue_shell "Rescue mode, dropping to shell" DEBUG=1 ;; debug) DEBUG=1 ;; esac done if [ ${DEBUG} -ne 0 ]; then # disable kernel messages from popping onto the screen echo 0 > /proc/sys/kernel/printk # clear the screen clear fi # assemble the raid set(s) - they got renumbered from md0, md1 and md2 mdadm --assemble --scan #scan for raid inner partitions mdadm --detail --scan create_labels # mounting rootfs on /mnt/root uuidlabel_root || rescue_shell "Error with uuidlabel_root" # space separated list of mountpoints that ... mountpoints="/usr /var" # ... we want to find in /etc/fstab ... ln -s /mnt/root/etc/fstab /etc/fstab # ... to check filesystems and mount our devices. for m in ${mountpoints}; do check_filesystem ${m} echo "Mounting ${m}" # mount the device and ... mount ${m} || rescue_shell "Error while mounting ${m}" # ... move the tree to its final location mount --move ${m} "/mnt/root"${m} || rescue_shell "Error while moving $m" done echo "All done. Switching to real root." if [ ${DEBUG} -ne 0 ]; then echo 1 > /proc/sys/kernel/printk fi rm -rf /dev/disk/by-label # clean up. The init process will remount proc sys and dev later umount /proc umount /sys umount /dev # switch to the real root and execute init exec switch_root /mnt/root /sbin/init # cat initramfs_list # directory structure dir /proc 755 0 0 dir /usr 755 0 0 dir /bin 755 0 0 dir /sys 755 0 0 dir /var 755 0 0 dir /lib64 755 0 0 dir /sbin 755 0 0 dir /mnt 755 0 0 dir /mnt/root 755 0 0 dir /etc 755 0 0 dir /root 700 0 0 dir /dev 755 0 0 # busybox file /bin/busybox /usr/src/initramfs/bin/busybox 755 0 0 # fsck bins file /sbin/fsck.reiserfs /sbin/fsck.reiserfs 755 0 0 file /sbin/fsck.ext4 /sbin/fsck.ext4 755 0 0 # mdadm file /sbin/mdadm /usr/src/initramfs/bin/mdadm 755 0 0 file /etc/mdadm.conf /etc/mdadm.conf 755 0 0 slink /lib /lib64 777 0 0 file /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 755 0 0 file /lib64/libuuid.so.1 /lib64/libuuid.so.1 755 0 0 file /lib64/libc.so.6 /lib64/libc.so.6 755 0 0 file /lib/libext2fs.so.2 /lib/libext2fs.so.2 755 0 0 file /lib/libcom_err.so.2 /lib/libcom_err.so.2 755 0 0 file /lib/libpthread.so.0 /lib/libpthread.so.0 755 0 0 file /lib/libblkid.so.1 /lib/libblkid.so.1 755 0 0 file /lib/libe2p.so.2 /lib/libe2p.so.2 755 0 0 # our init script file /init /usr/src/initramfs/init 755 0 0