summaryrefslogtreecommitdiffstats
path: root/initramfs/initrd-stuff/init
diff options
context:
space:
mode:
Diffstat (limited to 'initramfs/initrd-stuff/init')
-rwxr-xr-xinitramfs/initrd-stuff/init527
1 files changed, 527 insertions, 0 deletions
diff --git a/initramfs/initrd-stuff/init b/initramfs/initrd-stuff/init
new file mode 100755
index 00000000..55ee6de9
--- /dev/null
+++ b/initramfs/initrd-stuff/init
@@ -0,0 +1,527 @@
+#!/bin/sh
+# main script for new type of initial ramdisk for OpenSLX linux diskless
+# clients version 4
+#
+# Dirk von Suchodoletz <dirk@goe.net>, 07-09-2006
+#
+# (c) 2006 - RZ Universitaet Freiburg
+# (c) 2006 - OpenSLX.ORG project
+
+# functions common for all distros, messages contains all error and info
+# output
+. /etc/messages
+. /etc/functions || ( echo -e $init_mff && exit 1 )
+. /etc/distro-functions || ( echo -e $init_dff && exit 1 )
+# configuration settings (several file and directory variables)
+. /etc/sysconfig/config || ( echo -e $init_dscf && exit 1 )
+
+export PATH=/bin:/sbin:/usr/bin/:/usr/sbin
+export date="@@@DATE@@@"
+
+export DEBUGLEVEL=0
+export KERNEL="@@@KERNVER@@@"
+export NWMODULES="@@@NWMODULES@@@"
+export DISTRO="@@@DISTRO@@@"
+
+# do not use dnbd cache file
+nodnbdcache="yes"
+
+# device files get their own filesystem (to be move mounted later)
+DEVDIR="/dev"
+mount -n -t tmpfs -o 'size=25%,mode=0755' initramfsdevs ${DEVDIR}
+
+# copy basic device files into dev (later udev will handle that)
+cp -a /tmp/null /tmp/console /dev
+mkdir -p ${DEVDIR}/pts
+mkdir -p ${DEVDIR}/shm
+mkdir -p ${DEVDIR}/.udevdb
+
+# mount the important standard directories
+[ ! -f /proc/cpuinfo ] && mount -n -t proc proc /proc
+echo 256 > /proc/sys/kernel/real-root-dev
+[ ! -d /sys/class ] && mount -n -t sysfs sysfs /sys
+
+# redirect console (after /dev/console is available, and /dev mounted)
+exec < /dev/console > /dev/console 2>&1
+
+# set defaults for some important variables, might be overwritten via
+# kernel commandline
+TMPFSSIZE="50%"
+COWSIZE="50%"
+RWDIR=/dev/shm
+NFSRO="nfs"
+
+# run pre init script and user defined preinit.local, copied by mkdxsinitrd
+# from /var/lib/openslx/config/... in stage2
+preinit
+[ -x /bin/preinit.local ] && /bin/preinit.local
+
+# start device auto discovery service - distro specific function
+udev_hotplug
+
+# switch off the several configuration methods, will be switched on
+# according to kernel commandline settings
+echo "noldap" > /tmp/ldap-done
+echo "nodhcp" > /tmp/dhcp-done
+echo "nofile" > /tmp/file-done
+# read kernel commandline
+read KCMDLINE < /proc/cmdline
+export KCMDLINE
+for opts in ${KCMDLINE} ; do
+ case ${opts} in
+ # localization
+ country=*)
+ COUNTRY=${opts#country=}
+ echo -e "\n# localization information gotten via kernel command line \
+in $0\ncountry=\"${COUNTRY}\"" >> /etc/machine-setup
+ ;;
+ # single token for debugging ...
+ debug)
+ DEBUGLEVEL=1;;
+ # ... or a specified debug level
+ debug=*)
+ DEBUGLEVEL=${opts#debug=}
+ # Handle empty, extremly large or non-numeric input
+ [ -z "$DEBUGLEVEL" ] && DEBUGLEVEL=0
+ [ $DEBUGLEVEL -eq 8 ] && echo "** SLX init started near $(sysup)"
+ ;;
+ # if configuration should be gathered by dhcp client
+ dhcp)
+ DHCP="yes"
+ rm /tmp/dhcp-done
+ ;;
+ # if ldap configuration should be triggered
+ ldap)
+ LDAP="yes"
+ rm /tmp/ldap-done
+ ;;
+ # ldap configuration with host and port to contact (base)
+ ldap=*)
+ LDAP="yes"
+ rm /tmp/ldap-done
+ ;;
+ # if (external, via tftp) configuration file retrieval should be
+ # triggered, if no source is given try dhcp server and predefined
+ # standard path (~/tftpboot/client-conf/ ...)
+ file)
+ FILE="yes"
+ rm /tmp/file-done
+ ;;
+ # file source with tftp server and file location on the server
+ file=*)
+ FILE="yes"
+ FILESRC=${opts#file=}
+ rm /tmp/file-done
+ ;;
+ # if ld.so.cache should not be generated
+ noldsc)
+ NOLDSC=yes;;
+ # additional source to unify root filesystem with
+ union=*)
+ UNIONFS=1
+ UNIONDIRS=${opts#union=}
+ ;;
+ # if unionfs should be used over the complete root filesystem
+ unionfs)
+ UNIONFS=1;;
+ # if cowloop should be used, only ontop of network block device and in
+ # combination with classical fs, like ext2 useful
+ cowloop=*)
+ COWLOOP=1
+ #COWSIZE=${opts#cowloop=}
+ ;;
+ # rootfs will void the variables (d)nbdroot, nfsroot ...
+ # fixme: allow multiple rootfs sources to be unioned!?
+ # if strinstr " " "$ROOTFS" ...
+ rootfs=*)
+ ROOTFS=${opts#rootfs=}
+ srvproto=$(uri_token $ROOTFS prot)
+ case $srvproto in
+ nfs)
+ NFSROOT=$(uri_token $ROOTFS server)":/"$(uri_token $ROOTFS path)
+ echo -e "\n# nfs root information gotten via kernel command \
+line in $0\nnfsroot=\"${NFSROOT}\"\n" >> /etc/machine-setup
+ ;;
+ *nbd)
+ nbdmod=$srvproto
+ # get settings for nbd-client, filesystem equals to path in URI
+ # notation
+ nbdhost=$(uri_token $ROOTFS server)
+ nbdport=$(uri_token $ROOTFS port)
+ nbdrfst=$(uri_token $ROOTFS path)
+ ;;
+ aoe)
+ echo "Not implemented yet"
+ ;;
+ iscsi)
+ echo "Not implemented yet"
+ ;;
+ esac
+ ;;
+ # size of cache dnbd should use within ram
+ dcsize=*)
+ DNBDCACHESIZE=${opts#dcsize=};;
+ # ip configuration client-ip:server-ip:gateway:netmask
+ ip=*)
+ IPINFO=${opts#ip=};;
+ # deprecated: nfs server and path (will be removed soon)
+ nfsroot=*)
+ NFSROOT=${opts#nfsroot=}
+ echo -e "\n# nfs root information gotten via kernel command line in $0\n\
+nfsroot=\"${NFSROOT}\"\n" >> /etc/machine-setup
+ ;;
+ # size of tempfs if not max. 50% of RAM should be used
+ tmpfssize=*)
+ TMPFSSIZE=${opts#tmpfssize=};;
+ # vendor code identifier for dhcp requests, that way odlx clients could
+ # be distinguished from other (dhcp) clients
+ vci=*)
+ VCI=${opts#vci=};;
+ esac
+done
+# check if at least one type of IP configuration is availabe
+if [ -z "$DHCP" -a -z "$LDAP" -a -z "$IPINFO" ] ; then
+ echo -e "# You did not specify any advanced configuration mode for your \
+clients. You\n# might want to add the token 'dhcp' for DHCP configuration, \
+'file(=source)'\n# for config file get via TFTP or 'ldap(=source)' for LDAP \
+configuration to\n# your kernel command line." >> /etc/machine-setup
+ if strinfile "clientip" /etc/machine-setup ; then
+ # IP configuration seems to be present in machine-setup file
+ . /etc/machine-setup
+ IPINFO="ip=$clientip:$serverip:$gateway:$subnet_mask"
+ else
+ error "$init_errip"
+ fi
+fi
+# for ldap configuration at least basic IP setup is needed to contact the
+# server
+[ -z "$DHCP" -a -n "$LDAP" -a -z "$IPINFO" ] && error "$init_errldap"
+# set debug level and logfile
+echo "Setting debuglevel to ${DEBUGLEVEL}"
+export MODPRV=" "
+export LOGFILE
+if [ "${DEBUGLEVEL}" -gt 0 -a "${DEBUGLEVEL}" != 8 ] ; then
+ # if LOGFILE should be used within initial ramdisk add '/mnt' in front
+ # of the variable
+ LOGFILE="/var/log/dxs-boot.log"
+ echo "1 4 1 7" >/proc/sys/kernel/printk
+ [ "${DEBUGLEVEL}" -ge 2 ] && MODPRV="-v"
+ [ "${DEBUGLEVEL}" -gt 3 ] && {
+ set -x
+ # and the kernel too
+ echo "7 7 7 7" >/proc/sys/kernel/printk; }
+ [ "${DEBUGLEVEL}" -gt 10 ] && set +x
+else
+ # switch off most of kernel debug output
+ echo "0 0 0 0" >/proc/sys/kernel/printk
+ # modprobe should stay quiet
+ MODPRV="-q"
+ LOGFILE="/dev/null"
+fi
+# load network adaptor modules
+for mod in ${NWMODULES}; do
+ modprobe ${MODPRV} $mod || error "$init_errnwad"
+done
+# set up loopback networking (ipsetup - function defined in /etc/functions)
+ipsetup 127.0.0.1 255.0.0.0 0.0.0.0 127.255.255.255 lo
+# analyze ip information from the kernel command line and put parts
+# of it into several variables
+if [ -n "$IPINFO" ] ; then
+ getip () {
+ val=$IPINFO; i=$(expr $1 - 1);
+ while [ $i -gt 0 ] ; do
+ val=${val#*:} ; i=$(expr $i - 1);
+ done;
+ echo $val|sed "s/:.*//"; }
+ clientip=$(getip 1)
+ serverip=$(getip 2)
+ gateway=$(getip 3)
+ subnet_mask=$(getip 4)
+ echo -e "# ip configuration written by $0 script\nclientip=$clientip\n\
+subnet_mask=$sub_netmask\ngateway=$gateway\nserverip=$serverip" \
+ >>/etc/machine-setup
+ # set static ip address via function ipsetup
+ ipsetup $clientip $subnet_mask $gateway 255.255.255.255 eth0
+else
+ noipyet="yes"
+fi
+# get configuration data via dhcp (with vendor code identifier if present
+# in ${VCI} (from kernel command line) ...
+[ -n "$DHCP" ] && rundhcp ${VCI} &
+if [ -n "$noipyet" ] ; then
+ waitfor /tmp/dhcp-done 20000
+ . /etc/machine-setup
+ [ -f /tmp/confviadhcp ] && . /tmp/confviadhcp
+ [ -z "$clientip" -o -z "$subnet_mask" -o -z "$gateway" \
+ -o -z "$broadcast_address" ] && error "$init_errdhcp"
+ ipsetup $clientip $subnet_mask $gateway $broadcast_address eth0
+fi
+# ... or ldap if available (in background)
+[ -n "$LDAP" ] && ldapconf &
+# ... or via tftp file get (in background)
+[ -n "$FILE" ] && fileget &
+
+# if root filesystem should be imported via (d) network block device
+if [ -n "${nbdmod}" ] ; then
+ # load block device driver if needed
+ modprobe ${MODPRV} ${nbdmod} || error "$init_errnbd"
+ [ -z "$nbdrfst" ] && nbdrfst=ext2
+ echo "Diskless client using ${nbdmod} on $nbdhost:$nbdport with $nbdrfst"
+ # fixme: check for fs in /proc/filesystems before trying to load the module
+ modprobe ${MODPRV} ${nbdrfst} || error "$init_errnbd" nonfatal
+
+ case "${nbdmod}" in
+ # network block device present in standard kernel
+ nbd)
+ RDEV=/dev/nbd0
+ waitfor "${RDEV}" 30000 || error "$init_nbddev"
+ echo "0" > /sys/block/nbd0/queue/read_ahead_kb
+ nbd-client $nbdhost $nbdport ${RDEV} || error "$init_nbdcl"
+ usleep 10
+ # switch off unneeded block read ahead
+ echo "0" > /sys/block/nbd0/queue/read_ahead_kb
+ ;;
+ # dnbd by Thorsten Zitterell
+ dnbd)
+ if [ -z $nodnbdcache ] ; then # variable not really used yet
+ mkdir /dnbd
+ mount -n -o 'size=10%' -t tmpfs tmpfs /dnbd
+ ( cat /dev/zero > /dnbd/cache 2>/dev/null || echo "ok" >/tmp/cache ) &
+ clientopt="-c /dnbd/cache"
+ waitfor /tmp/cache 10000
+ fi
+ waitfor /dev/dnbd0 10000 || error "$init_nbddev"
+ while ! dnbd-client -b $nbdhost -d /dev/dnbd0 $clientopt ; do
+ usleep 20
+ done
+ echo "0" > /sys/block/dnbd0/queue/read_ahead_kb
+ RDEV=/dev/dnbd0
+ ;;
+ esac
+ RWRO="ro"
+ if [ -n "${COWLOOP}" -a -x /bin/cowdev ] ; then
+ modprobe ${MODPRV} cowloop || {
+ error "$init_loadcow" nonfatal
+ COWLOOP=""; }
+ fi
+ if [ -n "${COWLOOP}" ] ; then
+ if [ -n "${UNIONFS}" ] ; then
+ error "$init_cownonbd"
+ UNIONFS="";
+ fi
+ echo "Using Copy-on-Write block device for rw access"
+ mount -n -t tmpfs -o size=${COWSIZE} ramfs ${RWDIR}
+ mkdir /dev/cow && cp -a /tmp/ctl /dev/cow
+ usleep 10
+ ln -s /dev/cowloop0 /dev/cow/0
+ cowdev -a /dev/nbd0 ${RWDIR}/nbd.cow
+ usleep 10
+ RWRO="rw"
+ RDEV=/dev/cow/0
+ # run ldconfig if not switched off via kernel command line
+ ldcfg
+ else
+ # use normal UnionFS behaviour because rootfs is not NFS
+ NFSRO=""
+ fi
+ # finally mount the block device
+ for i in 5 40 60 ; do
+ usleep $i
+ mount -n -t $nbdrfst -o $RWRO $RDEV /mnt 2>/dev/null && break
+ done
+fi
+
+# if no type of root filesystem is passed via kernel command line try
+# information gathered from dhcp process
+if [ -z "${nbdmod}" -a -z "${nbdhost}" -a -z "${NFSROOT}" ] ; then
+ # information has to be read from dhcp configuration
+ if [ -z "$noipyet" ] ; then
+ waitfor /tmp/dhcp-done 20000
+ fi
+ waitfor /tmp/ldap-done 20000
+ . /etc/machine-setup
+ NFSROOT=${serverip}:${root_path}
+fi
+# call function for nfs mounts
+if [ -z "${nbdmod}" -a -z "${nbdserver}" ] ; then
+ nfsmnt ${NFSROOT} || error "$init_nfs"
+fi
+
+# get the complete collection of kernel modules available
+mount -n --bind /mnt/lib/modules/${KERNEL} /lib/modules/${KERNEL} || \
+ error "$init_moddir"
+# start hardware configuration as background process
+hwautocfg &
+
+# try to use unionfs for rw access if available
+if [ -n "${UNIONFS}" -o -n "${UNION}" ] ; then
+ modprobe ${MODPRV} unionfs || {
+ error "$init_loadufs" nonfatal
+ UNIONFS=""; }
+fi
+
+
+# setup of client root filesystem dependent on the availability of UnionFS
+if [ -n "${UNIONFS}" ] ; then
+ echo "Using UnionFS for rw access"
+ mkdir -p ${RWDIR}/union ${RWDIR}/uniontmp /rorootfs
+ mount -n -t tmpfs none ${RWDIR}/uniontmp
+ # hack for handling unionfs with patched run-init
+ mount -n --move /mnt /rorootfs
+ mount -n -t unionfs -o dirs=${RWDIR}/uniontmp:/rorootfs=${NFSRO}ro \
+ none /mnt
+ mkdir -p /mnt/uniontmp
+ mount -n --move ${RWDIR}/uniontmp /mnt/uniontmp
+ # if additional sources should be used for a combined root filesystem
+ # probably more sources should be merged into union (${UNION} is defined)
+ # allow more than one union??
+ if [ -n "${UNION}" ] ; then
+ # for dir in "${UNION}"; do
+ # testmkd /unionadd/$dir
+ # mount $dir unionadd/$dir
+ # unionctl mnt --add --after /mnt --mode ro /unionadd/$dir
+ # most probably it is a good idea to run ldconfig, so enable it
+ unset NOLDSC
+ fi
+ # run ldconfig if not switched off via kernel command line
+ ldcfg
+elif [ -z "$COWLOOP" ] ; then
+ echo "Using bind mounts to ramdisk for rw access"
+ mount -n -t tmpfs -o size=${TMPFSSIZE} ramfs ${RWDIR}
+ for path in ${D_BINDMPTS} ; do
+ mkdir -p ${RWDIR}/${path} >/dev/null 2>&1
+ mount -n --bind ${RWDIR}/${path} /mnt/${path}
+ [ ${DEBUGLEVEL} -gt 1 -a ${DEBUGLEVEL} != 8 ] && \
+ echo "Created ${RWDIR}/${path} and mounted it to /mnt/$path"
+ done
+ # see above ...
+ ldcfg
+ # Save the RO Directories mentioned in the distro-specific
+ # config to a temporary directory. They will lateron be restored
+ for path in ${D_RODIRSINRW}; do
+ if [ -d /mnt/${path} ] ; then
+ LIST=${path}" "$LIST
+ # exclude them from etc copy process too
+ echo ${path}|sed -e "s,/root/,," >>/tmp/etc.exclude
+ mkdir -p /root/${path} >/dev/null 2>&1
+ mount -n --bind /mnt/${path} /root/${path} >/dev/null 2>&1
+ fi
+ done
+ for path in /etc/${D_SYSCONFDIR} ${D_DIRINBINDMNT} ${LIST}; do
+ mkdir -p ${RWDIR}/${path}
+ done
+ testmkd ${RWDIR}/var/tmp
+ chmod a+rwxt ${RWDIR}/var/tmp >/dev/null 2>&1
+ echo -e "${D_ETCEXCL} @@@COMETCEXCL@@@" >>/tmp/etc.exclude
+ # if ld.so.cache is to be generated then do not copy the file
+ [ -z "${NOLDSC}" ] && echo -e "ld.so.cache*" >>/tmp/etc.exclude
+ # for tar exclude lists might be used, more difficult for cp
+ cd /mnt
+ tar -X /tmp/etc.exclude -cp etc/* | \
+ tar -xp -C ${RWDIR} 2>/dev/null ;
+ cd /
+ mount -n --bind ${RWDIR}/etc /mnt/etc
+ mount -n --bind ${RWDIR}/var /mnt/var
+ # get the "covered" mounts back into filesystem structure
+ for i in ${LIST}; do
+ mount -n --move /root/$i /mnt/$i #>>$LOGFILE 2>&1
+ done
+ #rm -rf /root/* >/dev/null 2>&1
+ # run some specific stuff !?
+fi
+# script for stuff to execute during early bootup
+d_mkrlscript init boot.ld "Running configuration postponed from InitRD"
+echo "fs complete" >/tmp/fscmpl
+
+# write debug file information after filesystem setup completed
+echo -e "# /etc${D_SYSCONFDIR}/logfile - file created by $0 (initramfs \
+from $date)\n#\n# logfile \
+for linux diskless client specific debugging output\nLOGFILE=\"$LOGFILE\"\n#\
+\n# debug level\nDEBUGLEVEL=\"$DEBUGLEVEL\"" \
+ > /mnt/etc/${D_SYSCONFDIR}/logfile || error "$init_errlog"
+
+# run distribution independent and dependent configuration of files and
+# services
+servconfig &
+
+for path in @@@COMDIRINDXS@@@ ${D_DIRINDXS} ${D_DIRINBINDMNT} ; do
+ testmkd /mnt/${path}
+done
+# Needed writable subdirs nested in readonly subdirs of writable one
+for path in ${D_RWDIRSINRO}; do
+ mount -n -t tmpfs none /mnt/${path}
+done
+for i in /var/run/utmp /var/log/wtmp /var/log/lastlog /etc/mtab ; do
+ echo -n > /mnt/$i
+done
+chmod a+rwxt /mnt/tmp /mnt/tmp/scratch 2>/dev/null &
+chown 65534:0 /mnt/var/lib/nobody &
+echo -e "# /etc/fstab - file generated by $0 (initramfs from $date)\n#\
+\tDirk von \
+Suchodoletz, dirk@goe.net\n\nrootfs\t\t/\t\trootfs\t\tro\t\t 0 0\n\
+proc\t\t/proc\t\tproc\t\tdefaults\t 0 0\ninitramdevs\t/dev\t\ttmpfs\
+\t\trw\t\t 0 0\ndevpts\t\t/dev/pts\tdevpts\t\tmode=0620,gid=5\t 0 0\n\
+usbfs\t\t/proc/bus/usb\tusbfs\t\tnoauto\t\t 0 0" >/mnt/etc/fstab || \
+ error "$init_fstab"
+echo -e "rootfs / rootfs rw 0 0\ninitramdevs /dev tmpfs rw\
+ 0 0" > /mnt/etc/mtab
+
+# copy library cache if generated
+if [ -z "${NOLDSC}" ] ; then
+ if waitfor /tmp/ldcfg 50000 ; then
+ test -s /mnt/tmp/ld.so.cache && {
+ cp /mnt/tmp/ld.so.cache /mnt/etc/ld.so.cache
+ rm /mnt/tmp/ld.so.cache; }
+ else
+ error "$init_errldcfg"
+ fi
+else
+ error "$init_infldcfg" nonfatal
+fi
+# copy machine configuration (from global settings, additions made within
+# here and from dhcp/ldap sources) to client /etc for later checks
+waitfor /tmp/hwcfg 20000 || error "$init_errhw"
+waitfor /tmp/svcfg 20000 || error "$init_errsw"
+# IP configuration is made and should not be updated automatically, udevd
+# should be killed if started within init
+killall -9 dhcpcd dhclient pump 2>/dev/null
+cp /etc/machine-setup /mnt/etc
+
+# post init for some distro specific (fixme!! more elegant solution)
+postinit
+[ -s /initramfs/postinit.local ] && \
+ cp /initramfs/postinit.local /bin/postinit.local
+[ -x /bin/postinit.local ] && {
+ echo "Running postinit.local - if boot stops here, check the script!"
+ /bin/postinit.local; }
+
+# start a debug shell in higher debug levels
+[ $DEBUGLEVEL -gt 2 -a $DEBUGLEVEL != 8 ] && /bin/sh
+
+# unmount the bind mounted modules directory
+for i in 0 40 100 200 300 500 800 1000 1200; do
+ usleep $i && umount -n /lib/modules/${KERNEL} 2>/dev/null && break
+ error "$init_wait" nonfatal
+done
+
+[ $i -gt 1000 ] && error "$init_errumnt"
+# check for inittab file
+test -f /mnt/etc/inittab || error "$init_erritab"
+# close runlevel script for stuff to execute during early bootup
+d_mkrlscript close boot.ld ""
+# put /tmp into stage4 mtab
+sed -n "s,/mnt,,;/\/tmp /p" /proc/mounts >> /mnt/etc/mtab
+# preparations to leave initrd - umounting ...
+umount -n /sys || error "$init_errsys" nonfatal
+umount -n /proc/bus/usb >/dev/null 2>&1
+mount -n --move /dev /mnt/dev
+killall -9 udevd 2>/dev/null
+[ $DEBUGLEVEL -eq 8 ] && echo "** SLX init ended near $(sysup)"
+umount -n /proc
+# unset old environment variables
+unset debug date initrd ip dnbdroot nbdroot nfsroot vci vga
+unset BOOT_IMAGE KCMDLINE KERNEL MODPRV NWMODULES OLDPWD UDEVD_EVENT_TIMEOUT \
+ UDEVD_EXPECTED_SEQNUM
+#strinstr "bash" "$(ls -la /bin/sh)" && EE="-c"
+# new style of pivoting (exec -c would set an empty environment in bash)
+exec run-init -c dev/console /mnt /sbin/init || error "$init_runinit"