Advertisement
Guest User

init with backstore noloop

a guest
Mar 14th, 2011
372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 41.92 KB | None | 0 0
  1. #!/bin/sh
  2. # Copyright 2003-2006 Gentoo Foundation
  3. # Copyright 2006-2010 Francois Dupoux
  4. # Distributed under the terms of the GNU General Public License v2
  5.  
  6. good_msg()
  7. {
  8.     msg_string=$1
  9.     msg_string="${msg_string:-...}"
  10.     [ "$2" != 1 ] && echo -e "${GOOD}>>${NORMAL} ${msg_string} ${NORMAL}"
  11. }
  12.  
  13. bad_msg()
  14. {
  15.     msg_string=$1
  16.     msg_string="${msg_string:-...}"
  17.     [ "$2" != 1 ] && echo -e "${BAD}!!${NORMAL} ${msg_string} ${NORMAL}"
  18. }
  19.  
  20. parse_opt()
  21. {
  22.     case "$1" in
  23.         *\=*)
  24.         local key_name="`echo "$1" | cut -f1 -d=`"
  25.         local key_len=${#key_name}
  26.         local value_start=$((key_len+2))
  27.         echo "$1" | cut -c ${value_start}-
  28.         ;;
  29.     esac
  30. }
  31.  
  32. sysresccd_expand_alldevices()
  33. {
  34.     for curdev in $*
  35.     do
  36.         echo ${curdev}
  37.     done
  38. }
  39.  
  40. sysresccd_expand_removable()
  41. {
  42.     # Look for the value of 1 in the file /sys/block/sd*/removable
  43.     for curdev in $*
  44.     do
  45.         devroot=$(echo ${curdev} | awk -F / '{sub(/[0-9]+$/,"",$NF); print $NF}')
  46.         removable_f="/sys/block/${devroot}/removable"
  47.         [ -f "${removable_f}" ] && grep -q ^1 ${removable_f} && echo ${curdev}
  48.     done
  49. }
  50.  
  51. sysresccd_runshell()
  52. {
  53.     if [ -n "$1" ] && [ -x "$1" ]
  54.     then
  55.         exec "$1"
  56.     else
  57.         exec /bin/sh
  58.     fi
  59.     exit 1
  60. }
  61.  
  62. sysresccd_panic()
  63. {
  64.     bad_msg "$@"
  65.     bad_msg "Running a mini shell (cannot complete the boot process)"
  66.     sleep 2
  67.     sysresccd_runshell
  68. }
  69.  
  70. sysresccd_setup_keymap()
  71. {
  72.     if [ -z "$SETKMAP" ]
  73.     then
  74.         if [ ! -e /dev/vc/0 -a ! -e /dev/tty0 ]
  75.         then
  76.             DEVBIND=1
  77.             mount -o bind ${NEWROOT}/dev /dev
  78.         fi
  79.         [ ! -e /dev/tty0 ] && ln -s /dev/tty1 /dev/tty0
  80.  
  81.         sysresccd_chooseKeymap
  82.  
  83.         [ "${DEVBIND:-0}" -eq '1' ] && umount /dev
  84.     else # "setkmap=xx" option was used
  85.         sysresccd_useKeymap $SETKMAP
  86.     fi
  87. }
  88.  
  89. sysresccd_useKeymap()
  90. {
  91.     keymap=$1
  92.  
  93.     if [ -e /lib/keymaps/${keymap}.map ]
  94.     then
  95.         good_msg "Loading the ''${keymap}'' keymap"
  96.         loadkmap < /lib/keymaps/${keymap}.map
  97.         xkeymap=${keymap}
  98.         echo ${keymap} | grep -e "[0-9]+" >/dev/null 2>&1
  99.         if [ "$?" -eq '0'  ]
  100.         then
  101.             xkeymap=`tail -n 7 /lib/keymaps/keymapList | grep ${keymap} | sed -r "s/.*\s+${keymap}\s+([a-z-]+).*/\1/g" | grep -v 1`
  102.         fi
  103.         mkdir -p /etc/sysconfig
  104.         echo "XKEYBOARD=${xkeymap}" > /etc/sysconfig/keyboard
  105.     elif [ "$keymap" = '' ]
  106.     then
  107.         echo
  108.         good_msg "Keeping default keymap"
  109.     else
  110.         bad_msg "Sorry, but keymap ''${keymap}'' is invalid!"
  111.         sysresccd_chooseKeymap
  112.     fi
  113. }
  114.  
  115. sysresccd_chooseKeymap()
  116. {
  117.     good_msg "Loading keymaps"
  118.     cat /lib/keymaps/keymapList
  119.     echo "default choice (US keymap) will be used if no action within 20 seconds"
  120.     read -t 20 -p '<< Load keymap (Enter for default): ' keymap
  121.     sysresccd_useKeymap $keymap
  122. }
  123.  
  124. sysresccd_terminal()
  125. {
  126.     /bin/consolechars -f /usr/share/consolefonts/ter-v16b.psf
  127.     kbd_mode -u
  128. }
  129.  
  130. sysresccd_debug()
  131. {
  132.     # Run debug shell if requested with "minishell" in cmdline
  133.     if [ "${MINISHELL}" = '1' ]
  134.     then
  135.         good_msg "Running a mini shell (as requested by the command line)"
  136.         sysresccd_runshell ${MINISHELL}
  137.     fi
  138. }
  139.  
  140. # ---- convert a short netmask (eg: '/24') to a long one ----
  141. netmask_shorttolong() # eg: '24' ==> '255.255.255.0'
  142. {
  143.     mask="$1"
  144.     if [ -n "${mask}" ]
  145.     then
  146.         [ "${mask}" -gt '32' ] && mask='32'
  147.         [ "${mask}" -lt '0' ] && mask='0'
  148.         bit=0
  149.         for i in 0 1 2 3
  150.         do
  151.             curbyte=0
  152.             for j in 0 1 2 3 4 5 6 7
  153.             do
  154.                 curbit=0 ; [ "$bit" -lt "$mask" ] && curbit=1
  155.                 curbyte=$((curbyte*2))
  156.                 curbyte=$((curbyte+curbit))
  157.                 bit=$((bit+1))
  158.             done
  159.             echo -n "$curbyte"
  160.             [ "$i" -lt '3' ] && echo -n '.'
  161.         done
  162.     fi
  163. }
  164.  
  165. # configure an interface: eg: $1='192.168.1.1/24' $2='eth0'
  166. netconfig_setip()
  167. {
  168.     ethip=$1
  169.     cureth=$2
  170.     ipaddrbase=${ethip%%/*} # '192.168.1.1/24' --> '192.168.1.1'
  171.  
  172.     if echo "${ethip}" | grep -q -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/([0-9]{1,2})$'
  173.     then
  174.         ipaddrmask=${ethip#*/} # '192.168.1.1/24' --> '24'
  175.     else
  176.         ipaddrmask=''
  177.     fi
  178.  
  179.     if [ -n "${ipaddrmask}" ]
  180.     then
  181.         iplongmask=$(netmask_shorttolong $ipaddrmask  2>/dev/null)
  182.         maskopt="netmask ${iplongmask}"
  183.         echo "netconfig1: netmask_shorttolong($ipaddrmask)=$iplongmask"
  184.     else
  185.         iplongmask=''
  186.         maskopt=''
  187.     fi
  188.  
  189.     echo "netconfig1: configure ${cureth} to ${ethip}"
  190.     ipcmd_add="ifconfig ${cureth} ${ipaddrbase} ${maskopt}"
  191.     ${ipcmd_add} ; res=$?
  192.     echo "netconfig1: ${ipcmd_add} --> ${res}"
  193. }
  194.  
  195. sysresccd_speakup()
  196. {
  197.     if [ -n "${SPEAKUP}" ]
  198.     then
  199.         OPTLIST="$(echo ${SPEAKUP} | sed -e 's!,! !g')"
  200.  
  201.         for curopt in ${OPTLIST}
  202.         do
  203.             for x in ${curopt}
  204.             do
  205.                 case "${x}" in
  206.                     quiet\=*)
  207.                         SPEAKUP_QUIET=`parse_opt "${x}"`
  208.                         ;;
  209.                     synth\=*)
  210.                         SPEAKUP_SYNTH=`parse_opt "${x}"`
  211.                         ;;
  212.                     port\=*)
  213.                         SPEAKUP_PORT=`parse_opt "${x}"`
  214.                         SPEAKUP_OPTIONS="${SPEAKUP_OPTIONS} port=${SPEAKUP_PORT}"
  215.                         ;;
  216.                     ser\=*)
  217.                         SPEAKUP_SER=`parse_opt "${x}"`
  218.                         SPEAKUP_OPTIONS="${SPEAKUP_OPTIONS} ser=${SPEAKUP_SER}"
  219.                         ;;
  220.                 esac
  221.             done
  222.         done
  223.  
  224.         if [ -n "${SPEAKUP_QUIET}" ]
  225.         then
  226.             cmd="/sbin/modprobe -b speakup quiet=${SPEAKUP_QUIET}"
  227.             ${cmd}
  228.         fi
  229.  
  230.         if [ -n "${SPEAKUP_SYNTH}" ]
  231.         then
  232.             cmd="/sbin/modprobe -b speakup_${SPEAKUP_SYNTH} ${SPEAKUP_OPTIONS} start=1"
  233.             ${cmd}
  234.         fi
  235.     fi
  236. }
  237.  
  238. sysresccd_udev_start()
  239. {
  240.     good_msg "Loading modules..."
  241.  
  242.     echo '0' > /proc/sys/kernel/printk
  243.  
  244.     # show name of modules being loaded
  245.     touch /showmodprobe
  246.  
  247.     # Note that this only becomes /dev on the real filesystem if udev's scripts
  248.     # are used; which they will be, but it's worth pointing out
  249.     tmpfs_size="10M"
  250.     if [ -e /etc/udev/udev.conf ]; then
  251.         . /etc/udev/udev.conf
  252.     fi
  253.     mount -t tmpfs -o size=$tmpfs_size,mode=0755 udev /dev
  254.     [ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1
  255.     [ -e /dev/null ] || mknod /dev/null c 1 3
  256.     > /dev/.initramfs-tools
  257.     mkdir /dev/.initramfs
  258.  
  259.     # process module dependencies
  260.     depmod -a
  261.  
  262.     # load custom modules
  263.     for modname in ${MODLOAD}
  264.     do
  265.         /sbin/modprobe.sh -b ${modname}
  266.         if [ $? -eq 0 ]
  267.         then
  268.             good_msg "modprobe ${modname} successful"
  269.         else
  270.             bad_msg "modprobe ${modname} failed (res=$?)"
  271.         fi
  272.     done
  273.  
  274.     # write blacklist to modprobe.d
  275.     for modname in ${BLACKLIST}
  276.     do
  277.         echo "blacklist ${modname}" >> /etc/modprobe.d/initramfs.conf
  278.         good_msg "module ${modname} has been blacklisted"
  279.     done
  280.  
  281.     # run udevd and let it process uevents
  282.     echo > /sys/kernel/uevent_helper
  283.     mkdir -p /dev/.udev/db/
  284.     udevd --daemon --resolve-names=never
  285.     mkdir -p /dev/.udev/queue/ /dev/.udev/rules.d/
  286.     udevadm trigger
  287.     udevadm settle || true
  288.  
  289.     # if the scandelay parameter has been set, we wait a bit for devices
  290.     sleep 3 # sleep 3 seconds anyway: most USB devices just need it to initialize
  291.     [ -n "${SCANDELAY}" ] && good_msg "Waiting ${SCANDELAY} seconds..." && sleep ${SCANDELAY}
  292.  
  293.     # reload the tg3 driver (https://bugzilla.redhat.com/show_bug.cgi?id=525966#c19)
  294.     if grep -q ^tg3 /proc/modules && grep -q reload /proc/cmdline
  295.     then
  296.         echo "Reloading module tg3 ..."
  297.         modprobe -r tg3
  298.         modprobe broadcom
  299.         modprobe tg3
  300.         echo "Module tg3 has been reloaded"
  301.     fi
  302.    
  303.     # hide name of modules being loaded
  304.     rm -f /showmodprobe
  305. }
  306.  
  307. sysresccd_udev_stop()
  308. {
  309.     # Stop udevd, we'll miss a few events while we run init, but we catch up
  310.     for proc in /proc/[0-9]*
  311.     do
  312.         [ -x $proc/exe ] || continue
  313.         [ "$(busybox readlink $proc/exe)" != /sbin/udevd ] || kill ${proc#/proc/}
  314.     done
  315.     echo '6' > /proc/sys/kernel/printk
  316. }
  317.  
  318. sysresccd_netconfig()
  319. {
  320.     good_msg "Performing the network configuration..."
  321.  
  322.     # configure the loopback network interface anyway
  323.     /sbin/ifconfig lo 127.0.0.1
  324.  
  325.     # ---- force dhcp if booting via pxe and no static configuration specified
  326.     if [ "${NETCONFIG}" = '1' ] && [ -z "${SETETHX}${NODHCP}${DODHCP}" ]
  327.     then
  328.         DODHCP='all'
  329.     fi
  330.  
  331.     # ---- create the /etc/nsswitch.conf file (it must exist for both dns and static) ----
  332.     rm -f /etc/nsswitch.conf /etc/host.conf
  333.     echo "hosts: files dns" > /etc/nsswitch.conf
  334.  
  335.     # ---- set the name of the network interfaces if requested on the boot argv
  336.     if grep -q -E 'nameif=[0-9,!:a-fA-F]*' /proc/cmdline
  337.     then
  338.         good_msg "Renaming the network interfaces (option 'nameif' was used)"
  339.         ethlist="$(/sbin/ifconfig -a | grep 'HWaddr' | grep '^eth[0-9]*' | awk '{print $1}')"
  340.         maclist="$(/sbin/ifconfig -a | grep 'HWaddr' | grep '^eth[0-9]*' | awk '{print $5}')"
  341.  
  342.         # ---- get the option from the boot command line # eg: "nameif=eth0!00:11:22:33:44:55,eth1!00:22:33:44:55:aa"
  343.         BOOTIF=''
  344.         CMDLINE="$(cat /proc/cmdline)"
  345.         for x in ${CMDLINE}
  346.         do
  347.             if echo "${x}" | grep -q -E 'BOOTIF=..-..-..-..-..-..-..'
  348.             then
  349.                 BOOTIF="$(echo ${x} | cut -d= -f2 | sed -e 's#^01-##;s#-#:#g')"
  350.             fi
  351.         done
  352.  
  353.         NAMEIFOPT=''
  354.         for x in $(cat /proc/cmdline)
  355.         do
  356.             if echo "${x}" | grep -q -E 'nameif=[0-9,!:a-fA-F]*'
  357.             then
  358.                 NAMEIFOPT="$(echo ${x} | cut -d= -f2 | sed -e 's!,! !g')"
  359.                 test -n "${BOOTIF}" && NAMEIFOPT=$(echo $NAMEIFOPT | sed -e "s!BOOTIF!${BOOTIF}!g")
  360.             fi
  361.         done
  362.  
  363.         # ---- rename all the network interfaces so that each name is free for another interface
  364.         pos=0
  365.         for curmac in ${maclist}
  366.         do
  367.             cmd="busybox nameif iftmp${pos} ${curmac}"
  368.             ${cmd}
  369.             echo "netconfig1: ${cmd} --> $?"
  370.             pos=$((pos+1))
  371.         done
  372.  
  373.         # ---- rename the interfaces with the name requested on the boot command
  374.         for val in ${NAMEIFOPT}
  375.         do
  376.             for opt in ${val}
  377.             do
  378.                 name="$(echo ${opt} | cut -d! -f1)"
  379.                 mac="$(echo ${opt} | cut -d! -f2)"
  380.  
  381.                 cmd="busybox nameif $name $mac"
  382.                 ${cmd}
  383.                 echo "netconfig1: ${cmd} --> $?"
  384.                 sleep 1
  385.             done
  386.         done
  387.  
  388.         # ---- attribute the remaining names to the remaining network interfaces
  389.         maclist="$(/sbin/ifconfig -a | grep 'HWaddr' | grep '^iftmp[0-9]*' | awk '{print $5}')"
  390.         for curmac in ${maclist}
  391.         do
  392.             pos=0
  393.             ifdone=0
  394.             while [ "${pos}" -lt 99 ] && [ "$ifdone" = '0' ]
  395.             do
  396.                 curif="eth${pos}"
  397.                 if ! /sbin/ifconfig -a | grep 'HWaddr' | grep -q "^${curif}"
  398.                 then
  399.                     cmd="busybox nameif $curif $curmac"
  400.                     ${cmd}
  401.                     echo "netconfig1: ${cmd} --> $?"
  402.                     ifdone=1
  403.                     sleep 1
  404.                 fi
  405.                 pos=$((pos+1))
  406.             done
  407.         done
  408.     fi
  409.  
  410.     if [ "${NETCONFIG}" = '1' ] # show interfaces detected with the new name
  411.     then
  412.         ethlist="$(/sbin/ifconfig -a | grep 'HWaddr' | grep '^eth[0-9]*' | awk '{print $1}')"
  413.  
  414.         if [ -z "${ethlist}" ]
  415.         then
  416.             echo "No ethernet interfaces found on your system, PXE boot won't work."
  417.             sleep 2
  418.         else
  419.             echo "Here are the ethernet interfaces found on your system:"
  420.  
  421.             # ---- get the option from the boot command line # eg: "nameif=eth0!00:11:22:33:44:55,eth1!00:22:33:44:55:aa"
  422.             for cureth in ${ethlist}
  423.             do
  424.                 #cureth="${ethlist[curpos]}"
  425.                 curmac="$(/sbin/ifconfig ${cureth} | grep 'HWaddr' | grep '^eth[0-9]*' | awk '{print $5}')"
  426.                 echo "* ${cureth}: ${curmac}"
  427.                 ifconfig ${cureth} up
  428.             done
  429.         fi
  430.     fi
  431.  
  432.     # ---- configure the ethernet interfaces if requested by 'ethx=ip' ----
  433.     if [ -n "${SETETHX}" ]
  434.     then
  435.         echo "netconfig1: found option ethx=${SETETHX}"
  436.         ethlist="$(/sbin/ifconfig -a | grep 'eth' | awk '{print $1}' | busybox xargs)" # (eg: eth0 eth1 eth2)
  437.         for cureth in ${ethlist}
  438.         do
  439.             netconfig_setip ${SETETHX} ${cureth}
  440.         done
  441.     fi
  442.  
  443.     # ---- configure individual ethernet interfaces ----
  444.     if cat /proc/cmdline | grep -q -E 'eth[0-9]{1,2}=[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
  445.     then
  446.         # parse the command line for individual ethernet interfaces settings
  447.         for x in $(cat /proc/cmdline)
  448.         do
  449.             if echo "${x}" | grep -q -E 'eth[0-9]{1,2}=[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
  450.             then
  451.                 iface=$(echo ${x} | cut -d= -f1)
  452.                 ipaddr=$(echo ${x} | cut -d= -f2)
  453.                 echo "netconfig1: found option ${x}"
  454.                 netconfig_setip ${ipaddr} ${iface}
  455.             fi
  456.         done
  457.     fi
  458.  
  459.     # ---- configure the network via dhcp ----
  460.     if [ -n "${DODHCP}" ]
  461.     then
  462.         if [ "${DODHCP}" = 'all' ]
  463.         then
  464.             ethlist="$(/sbin/ifconfig -a | grep 'eth' | awk '{print $1}' | busybox xargs)" # (eg: eth0 eth1 eth2)
  465.         else
  466.             ethlist="$(echo ${DODHCP} | sed -e 's!,! !g')" # (eg: eth0 eth2)
  467.         fi
  468.  
  469.         dhcpstate=''
  470.         while [ "${dhcpstate}" != 'ok' ] # retry until we get a dhcp address on at least one interface
  471.         do
  472.             for cureth in ${ethlist}
  473.             do
  474.                 # Try to find whether or not the link is connected
  475.                 mac=$(ifconfig ${cureth} | grep HWaddr | awk '{print $5}')
  476.                 linkstate=''
  477.                 if [ -z "${linkstate}" ] && [ -f /sbin/ethtool ] && /sbin/ethtool ${cureth} 2>/dev/null | grep -qiF 'Link detected: yes'
  478.                 then
  479.                     linkstate='link-ok'
  480.                 fi
  481.                 if [ -z "${linkstate}" ] && [ -f /sbin/mii-tool ] && /sbin/mii-tool ${cureth} 2>/dev/null | grep -qiF 'link ok'
  482.                 then
  483.                     linkstate='link-ok'
  484.                 fi
  485.                 if [ -z "${linkstate}" ] && [ -f /sbin/mii-tool ] && /sbin/mii-tool ${cureth} 2>/dev/null | grep -qiF 'no link'
  486.                 then
  487.                     linkstate='no-link'
  488.                 fi
  489.                 if [ -z "${linkstate}" ]
  490.                 then
  491.                     linkstate='unknown'
  492.                 fi
  493.                 echo "--- ${cureth}: link=${linkstate}, mac=${mac}"
  494.  
  495.                 # If the link is up, then try (even if another interface already has a dhcp address)
  496.                 if [ "${linkstate}" != 'no-link' ]
  497.                 then
  498.                     good_msg "Attempting to get a DHCP address on ${cureth}..."
  499.                     [ -n "${DHCPHOSTNAME}" ] && hostnameopt="-H ${DHCPHOSTNAME}"
  500.                     cmd="busybox udhcpc -n -i ${cureth} ${hostnameopt}"
  501.                     ${cmd} ; res="$?"
  502.                     echo "${cmd} --> ${res}"
  503.                     [ "${res}" = '0' ] && dhcpstate='ok'
  504.                 fi
  505.             done
  506.  
  507.             if [ "${dhcpstate}" != 'ok' ]
  508.             then
  509.                 echo "Cannot get a DHCP address. Check the cables on the ethernet interfaces."
  510.                 sleep 2
  511.             fi
  512.         done
  513.     fi
  514.  
  515.     # ---- configure the gateway if requested on cmdline ----
  516.     if [ -n "${SETGW}" ]
  517.     then
  518.         while route del default gw 0.0.0.0 2>&-
  519.         do
  520.             echo "netconfig1: removing old default route"
  521.         done
  522.         echo "netconfig1: set new default route to ${SETGW}"
  523.         route add default gw ${SETGW}
  524.     fi
  525.  
  526.     # ---- configure the nameserver if requested on cmdline ----
  527.     if [ -n "${SETDNS}" ]
  528.     then
  529.         rm -f /etc/resolv.conf 2>/dev/null
  530.         echo "netconfig1: set nameserver to ${SETDNS}"
  531.         echo "nameserver ${SETDNS}" > /etc/resolv.conf
  532.     fi
  533. }
  534.  
  535. sysresccd_setup_volumes()
  536. {
  537.     # Setup dmraid for fake raid devices
  538.     if [ -x "/sbin/dmraid-activate" ] && ! grep -q 'nodmraid' /proc/cmdline
  539.     then
  540.         good_msg "Activating dmraid (fake hardware raid)..."
  541.         if devices=$(dmraid -r -c)
  542.         then
  543.             for dev in $devices
  544.             do
  545.                 dmraid-activate $dev
  546.             done
  547.         fi
  548.     fi
  549.  
  550.     # Setup mdadm for linux software raid
  551.     if [ -x "/sbin/mdadm" ] && ! grep -q 'nomdadm' /proc/cmdline
  552.     then
  553.         good_msg "Loading MD modules for software raid..."
  554.         for mod in linear multipath raid0 raid1 raid456 raid5 raid6 raid10
  555.         do
  556.             /sbin/modprobe -b ${mod}
  557.         done
  558.         good_msg "Starting mdadm (linux software raid)"
  559.         /sbin/mdadm -Es > /etc/mdadm.conf
  560.         /sbin/mdadm -As
  561.     fi
  562.  
  563.     # Setup the Logical Volume Manager
  564.     if [ -x "/sbin/lvm" ] && ! grep 'nolvm' /proc/cmdline
  565.     then
  566.         good_msg 'Setting up the Logical Volume Manager'
  567.         /sbin/lvm vgscan --ignorelockingfailure --mknodes 2>/dev/null
  568.         /sbin/lvm vgchange -ay --ignorelockingfailure 2>/dev/null
  569.     fi
  570. }
  571.  
  572. # ============================================================================================================
  573.  
  574. sysresccd_chroot()
  575. {
  576.     # check the kernel is able to execute /sbin/init
  577.     good_msg "Checking ${INITPROG} can be executed by the current kernel..."
  578.     inittype="$(readelf -h ${NEWROOT}${INITPROG} | grep Class | awk '{print $2}')"
  579.     archtype="$(uname -m)"
  580.     echo "   ${INITPROG} on the root filesystem is an ${inittype} binary"
  581.     echo "   The current running kernel architecture is ${archtype}"
  582.     if [ "${inittype}" = 'ELF64' ] && [ "${archtype}" != 'x86_64' ]
  583.     then
  584.         sysresccd_panic "You must boot with a 64bit kernel such as rescue64 to run ${INITPROG}"
  585.     fi
  586.  
  587.     # move /dev to the new root filesystem
  588.     mount -n -o move /dev ${NEWROOT}/dev
  589.     nuke /dev
  590.     ln -s ${NEWROOT}/dev /dev
  591.  
  592.     if [ ! -x ${NEWROOT}${INITPROG} ]
  593.     then
  594.         sysresccd_panic "${INITPROG} not found on root filesystem"
  595.     fi
  596.  
  597.     umount /proc
  598.     umount /sys
  599.  
  600.     good_msg "Executing ${INITPROG} from the root filesystem..."
  601.     exec run-init ${NEWROOT} ${INITPROG} <${NEWROOT}/dev/console >${NEWROOT}/dev/console
  602.  
  603.     # ------------------------------- minishell -------------------------------
  604.     sysresccd_panic "Failed to run run-init ${NEWROOT} ${INITPROG}"
  605. }
  606.  
  607. # ============================================================================================================
  608. # ============================================================================================================
  609.  
  610. sysresccd_stage1_http()
  611. {
  612.     if ! mount -t tmpfs -o ${CACHESIZE} tmpfs ${BOOTPATH}
  613.     then
  614.         sysresccd_panic "Cannot create tmpfs on ${BOOTPATH}"
  615.     fi
  616.  
  617.     if ! echo "${HTTPBOOT}" | grep -q '^http://'
  618.     then
  619.         sysresccd_panic "You requested an http boot, the address is not a valid http:// url."
  620.     fi
  621.  
  622.     good_msg "Downloading ${LOOPDAT} from ${HTTPBOOT}"
  623.     BOOTMD5=$(echo ${HTTPBOOT} | sed -e "s/${LOOPDAT}/${LOOPMD5}/g") # URL of the md5 file
  624.     for attempt in 0 1 2 3 4 5 6 7 8 9
  625.     do
  626.         /bin/busybox wget ${BOOTMD5} -O /dev/null && break
  627.         echo "Failed to download ${BOOTMD5} (attempt ${attempt}), retrying..."
  628.         sleep 1
  629.     done
  630.     /bin/busybox wget ${BOOTMD5} -O ${BOOTPATH}/${LOOPMD5}
  631.     res1=$?
  632.     /bin/busybox wget ${HTTPBOOT} -O ${BOOTPATH}/${LOOPDAT}
  633.     res2=$?
  634.  
  635.     if [ ${res1} -ne 0 ] || [ ${res2} -ne 0 ]
  636.     then
  637.         sysresccd_panic "Cannot download the files: wget failed. May be due to lack of memory"
  638.     fi
  639.  
  640.     if [ ! -f "${BOOTPATH}/${LOOPDAT}" ]
  641.     then
  642.         sysresccd_panic "Cannot download the \"${LOOPDAT}\" boot file."
  643.     fi
  644.  
  645.     md5now=$(/bin/busybox md5sum ${BOOTPATH}/${LOOPDAT} | cut -d ' ' -f1)
  646.     md5orig=$(cat ${BOOTPATH}/${LOOPMD5} | cut -d ' ' -f1)
  647.     if [ "$md5now" = "$md5orig" ]
  648.     then
  649.         good_msg "Downloaded boot file to \"${BOOTPATH}/${LOOPDAT}\""
  650.     else
  651.         sysresccd_panic "The root filesystem image is invalid: md5sum failed"
  652.     fi
  653. }
  654.  
  655. sysresccd_stage1_tftp()
  656. {
  657.     if ! mount -t tmpfs -o ${CACHESIZE} tmpfs ${BOOTPATH}
  658.     then
  659.         sysresccd_panic "Cannot create tmpfs on ${BOOTPATH}"
  660.     fi
  661.  
  662.     if ! echo "${TFTPBOOT}" | grep -q '^tftp://'
  663.     then
  664.         sysresccd_panic "You requested an tftp boot, the address is not a valid tftp:// url."
  665.     fi
  666.  
  667.     good_msg "Downloading ${LOOPDAT} from ${TFTPBOOT}"
  668.     url="$(echo ${TFTPBOOT} | sed 's!tftp://!!g')" # remote the 'tftp://' prefix
  669.     tftpip="${url%%/*}"
  670.     tftpurl="/${url#*/}"
  671.     BOOTMD5=$(echo ${tftpurl} | sed -e "s/${LOOPDAT}/${LOOPMD5}/g") # URL of the md5 file
  672.     cmd1="/bin/busybox tftp -g -r ${BOOTMD5} -l ${BOOTPATH}/${LOOPMD5} ${tftpip}"
  673.     echo "$cmd1"
  674.     ${cmd1} ; res1="$?"
  675.     cmd2="/bin/busybox tftp -g -r ${tftpurl} -l ${BOOTPATH}/${LOOPDAT} ${tftpip}"
  676.     echo "$cmd2"
  677.     ${cmd2} ; res2="$?"
  678.  
  679.     if [ "$res1" != '0' ] || [ "$res2" != '0' ]
  680.     then
  681.         sysresccd_panic "Cannot download the files, wget failed. May be due to lack of memory"
  682.     fi
  683.  
  684.     if [ ! -f "${BOOTPATH}/${LOOPDAT}" ]
  685.     then
  686.         sysresccd_panic "Cannot download the \"${LOOPDAT}\" boot file."
  687.     fi
  688.  
  689.     md5now=$(/bin/busybox md5sum ${BOOTPATH}/${LOOPDAT} | cut -d ' ' -f1)
  690.     md5orig=$(cat ${BOOTPATH}/${LOOPMD5} | cut -d ' ' -f1)
  691.     if [ "$md5now" = "$md5orig" ]
  692.     then
  693.         good_msg "Downloaded boot file to \"${BOOTPATH}/${LOOPDAT}\""
  694.     else
  695.         sysresccd_panic "The root filesystem image is invalid: md5sum failed"
  696.     fi
  697. }
  698.  
  699. sysresccd_stage1_nfs()
  700. {
  701.     nfsurl=$(echo ${NFSBOOT} | sed -e 's!nfs://!!g')
  702.  
  703.     good_msg "Mouting the NFS filesystem from ${NFSBOOT}"
  704.     cmd="mount -t nfs -o intr,nolock ${nfsurl} ${BOOTPATH}"
  705.     if ! ${cmd}
  706.     then
  707.         sysresccd_panic "Cannot mount NFS: ${cmd}"
  708.     fi
  709.     good_msg "Successfully mounted the NFS filesystem"
  710.  
  711.     if [ ! -f "${BOOTPATH}/${SUBDIR}/${LOOPDAT}" ]
  712.     then
  713.         sysresccd_panic "Cannot find the \"${SUBDIR}/${LOOPDAT}\" boot file."
  714.     fi
  715.  
  716.     md5now=$(/bin/busybox md5sum ${BOOTPATH}/${SUBDIR}/${LOOPDAT} | cut -d ' ' -f1)
  717.     md5orig=$(cat ${BOOTPATH}/${SUBDIR}/${LOOPMD5} | cut -d ' ' -f1)
  718.     if [ "$md5now" = "$md5orig" ]
  719.     then
  720.         good_msg "Successfully checked md5 sum of ${BOOTPATH}/${LOOPDAT}"
  721.     else
  722.         sysresccd_panic "md5sum checksum is invalid on the root filesystem image"
  723.     fi
  724. }
  725.  
  726. sysresccd_find_devices() # $1=devtype
  727. {
  728.     devtype="$1"
  729.  
  730.     case "${devtype}" in
  731.     auto) # all devices
  732.         searchdevices=$(sysresccd_expand_alldevices ${BLKDEVICES})
  733.         ;;
  734.     rmdev) # removable devices only
  735.         searchdevices=$(sysresccd_expand_removable ${BLKDEVICES})
  736.         ;;
  737.     UUID\=*) # find file on filesystem having the speficed UUID
  738.         uuid=`parse_opt "${devtype}"`
  739.         target="$(/bin/readlink -f /dev/disk/by-uuid/${uuid})"
  740.         if [ -b "${target}" ]
  741.         then
  742.             searchdevices="${target}"
  743.         elif [ -b "/dev/disk/by-uuid/${uuid}" ]
  744.         then
  745.             searchdevices="/dev/disk/by-uuid/${uuid}"
  746.         fi
  747.         ;;
  748.     LABEL\=*) # find file on filesystem having the speficed LABEL
  749.         label=`parse_opt "${devtype}"`
  750.         target="$(/bin/readlink -f /dev/disk/by-label/${label})"
  751.         if [ -b "${target}" ]
  752.         then
  753.             searchdevices="${target}"
  754.         elif [ -b "/dev/disk/by-label/${label}" ]
  755.         then
  756.             searchdevices="/dev/disk/by-label/${label}"
  757.         fi
  758.         ;;
  759.     *) # specific device name (eg: "/dev/sda1")
  760.         searchdevices="${devtype}"
  761.         ;;
  762.     esac
  763.    
  764.     echo "${searchdevices}"
  765.     return 1
  766. }
  767.  
  768. # find the device that contains a file with that path: ${SUBDIR}/${LOOPDAT}
  769. sysresccd_find_file() # $1=devtype, $2=filepath $3=mountdir, $4=mode
  770. {
  771.     devtype="$1"   # on which devices should we search that file
  772.     filepath="$2"  # path of the file we are looking for (eg: "/sysrcd.dat")
  773.     mountdir="$3"  # where to mount the device if we find it
  774.     mountmode="$4" # mount mode: either 'ro' or 'rw'
  775.  
  776.     searchdevices="$(sysresccd_find_devices ${devtype})"
  777.  
  778.     SEARCHDEVICE='' # result returned
  779.     mkdir -p ${mountdir}
  780.     for curdev in ${searchdevices}
  781.     do
  782.         if [ -b "${curdev}" ] # Check for a block device to mount
  783.         then
  784.             # check the 'skipmount=/dev/xxx' option (use it with a failing hard drive)
  785.             # compare with a space at the end so that "/dev/sda1" and "/dev/sda11" don't match
  786.             if echo "$(cat /proc/cmdline) " | grep -F -q "skipmount=${curdev} "
  787.             then
  788.                 good_msg "Skipping mount on device: ${curdev}"
  789.             else
  790.                 good_msg "Attempting to mount device: ${curdev}"
  791.  
  792.                 for curfs in vfat msdos iso9660 ntfs auto
  793.                 do
  794.                     case "${curfs}" in
  795.                         iso9660)
  796.                             mntopt='-o mode=0644'
  797.                             ;;
  798.                         vfat)
  799.                             mntopt='-o fmask=0133'
  800.                             ;;
  801.                         *)
  802.                             mntopt=''
  803.                             ;;
  804.                     esac
  805.  
  806.                     if mount -r -t ${curfs} ${curdev} ${mountdir} ${mntopt} >/dev/null 2>&1
  807.                     then
  808.                         if [ -e ${mountdir}/${filepath} ]
  809.                         then
  810.                             SEARCHDEVICE="${curdev}"
  811.                             good_msg "File ${filepath} found on device ${curdev}"
  812.                             if [ "${mountmode}" = 'rw' ] && ! mount -o remount,rw,noatime ${mountdir}
  813.                             then
  814.                                 sysresccd_panic "Cannot remount ${curdev} in read-write mode"
  815.                             fi
  816.                             return 0
  817.                         else
  818.                             umount ${mountdir} >/dev/null 2>&1
  819.                         fi
  820.                     fi
  821.                 done
  822.             fi
  823.         fi
  824.     done
  825.     return 1
  826. }
  827.  
  828. # find the device which contains sysrcd.dat and mount it on ${BOOTPATH}
  829. sysresccd_stage1_normal()
  830. {
  831.     good_msg "Searching for ${SUBDIR}/${LOOPDAT} on devices..."
  832.     filefound=''
  833.     for attempts in 1 2 3 4 5
  834.     do
  835.         [ ${attempts} -gt 1 ] && sleep 3 && bad_msg "Cannot find device with ${SUBDIR}/${LOOPDAT}. Retrying..."
  836.         if sysresccd_find_file 'auto' ${SUBDIR}/${LOOPDAT} ${BOOTPATH} 'ro'
  837.         then
  838.             if [ "${DOCHECK}" = '1' ] # don't run checksum by default on slow medias (cdrom, usb, ...)
  839.             then
  840.                 if [ ! -f "${BOOTPATH}/${SUBDIR}/${LOOPMD5}" ]
  841.                 then
  842.                     bad_msg "Cannot find md5 checksum file: ${LOOPMD5}"
  843.                 else
  844.                     md5now=$(/bin/busybox md5sum ${BOOTPATH}/${SUBDIR}/${LOOPDAT} | cut -d ' ' -f1)
  845.                     md5orig=$(cat ${BOOTPATH}/${SUBDIR}/${LOOPMD5} | cut -d ' ' -f1)
  846.                     if [ "$md5now" = "$md5orig" ]
  847.                     then
  848.                         good_msg "md5 checksum of ${LOOPDAT} successfully checked"
  849.                     else
  850.                         sysresccd_panic "md5sum checksum is invalid on the root filesystem image"
  851.                     fi
  852.                 fi
  853.             fi
  854.             filefound='1'
  855.             break
  856.         fi
  857.     done
  858.  
  859.     if [ -z "${filefound}" ]
  860.     then
  861.         sysresccd_panic "Cannot find ${SUBDIR}/${LOOPDAT} on devices"
  862.     fi
  863.  
  864.     if [ "${DOCACHE}" = '1' ]
  865.     then
  866.         good_msg "Creating tmpfs for caching in ${CACHEDIR}"
  867.         if ! mount -t tmpfs -o ${CACHESIZE} tmpfs ${CACHEDIR}
  868.         then
  869.             sysresccd_panic "Cannot mount tmpfs filesystem on ${CACHEDIR} for caching"
  870.         fi
  871.  
  872.         # --------------- Get loopfile size
  873.         squashfspath="${BOOTPATH}/${SUBDIR}/${LOOPDAT}"
  874.         squashfssize=$(ls -l "$squashfspath" | sed -e ":a;s/  / /g;ta" | cut -f 5 -d ' ') # size in bytes
  875.         squashfssizekb=$(( $squashfssize / 1024 )) # size in kilo-bytes
  876.  
  877.         # --------------- Cache autorun files
  878.         autoruns="$(ls -d ${BOOTPATH}/${SUBDIR}/autorun* 2>/dev/null)"
  879.         [ "$autoruns" != "" ] && cp $autoruns ${CACHEDIR}/
  880.  
  881.         # --------------- Cache main loop file
  882.         cp -a ${BOOTPATH}/${SUBDIR}/version ${CACHEDIR}/ 2>/dev/null
  883.         cp -a ${BOOTPATH}/${SUBDIR}/${LOOPMD5} ${CACHEDIR}/${LOOPMD5} 2>/dev/null
  884.         good_msg "Copying ${LOOPDAT} file for caching (size: $squashfssizekb KB)..."
  885.         if [ -x /bin/pv ]
  886.         then
  887.             /bin/pv -p < ${BOOTPATH}/${SUBDIR}/${LOOPDAT} > ${CACHEDIR}/${LOOPDAT}
  888.             #/bin/rsync -aP ${BOOTPATH}/${SUBDIR}/${LOOPDAT} ${CACHEDIR}/${LOOPDAT}
  889.         else
  890.             cp -a ${BOOTPATH}/${SUBDIR}/${LOOPDAT} ${CACHEDIR}/${LOOPDAT} 2>/dev/null
  891.         fi
  892.  
  893.         # --------------- Check main loop file
  894.         expectedsize=$(/bin/busybox stat -c%s "${BOOTPATH}/${SUBDIR}/${LOOPDAT}")
  895.         copiedsize=$(/bin/busybox stat -c%s "${CACHEDIR}/${LOOPDAT}")
  896.  
  897.         if [ "${copiedsize}" != "${expectedsize}" ] # Was the copy completed successfully ?
  898.         then # docache failed
  899.             bad_msg "Caching failed. Likely due to lack of memory"
  900.             rm -f "${CACHEDIR}/${LOOPDAT}"
  901.             umount ${CACHEDIR} 2>/dev/null
  902.             sleep 3
  903.         else # docache successful
  904.             good_msg "File ${LOOPDAT} successfully cached"
  905.             SUBDIR=''
  906.  
  907.             # cache other files if possible
  908.             if [ -z "${LOWMEM}" ] && [ -d ${BOOTPATH}/${SUBDIR}/bootdisk ] && [ -d ${BOOTPATH}/${SUBDIR}/ntpasswd ]
  909.             then
  910.                 good_msg "Copying isolinux/syslinux + bootdisk + ntpasswd + usb_inst for caching..."
  911.                 if ! cp -a ${BOOTPATH}/${SUBDIR}/???linux ${BOOTPATH}/${SUBDIR}/bootdisk \
  912.                     ${BOOTPATH}/${SUBDIR}/ntpasswd ${BOOTPATH}/${SUBDIR}/usb_inst* ${CACHEDIR}/
  913.                 then
  914.                     rm -rf ${CACHEDIR}/???linux ${CACHEDIR}/bootdisk ${CACHEDIR}/ntpasswd ${CACHEDIR}/usb_inst*
  915.                     bad_msg "Cannot cache these directories (required only for pxebootsrv). Likely due to lack of memory"
  916.                 fi
  917.             fi
  918.  
  919.             # unmount the media if possible
  920.             if umount ${BOOTPATH}
  921.             then
  922.                 good_msg "The original media has been unmounted"
  923.                 cmd="mount -n --move ${CACHEDIR} ${BOOTPATH}"
  924.                 if ! ${cmd}
  925.                 then
  926.                     bad_msg "${cmd} --> ${res}" && sleep 3
  927.                 fi
  928.             else
  929.                 bad_msg "Cannot unmount the original media"
  930.             fi
  931.  
  932.             # unmount isostore if necessary
  933.             if cat /proc/mounts | awk '{print $2}' | grep -q "^${ISOSTORE}$"
  934.             then
  935.                 if losetup -d /dev/loop0
  936.                 then
  937.                     umount ${ISOSTORE} && good_msg "Unmounted ${ISOSTORE}" || bad_msg "Cannot unmount ${ISOSTORE}"
  938.                 fi
  939.             fi
  940.         fi
  941.     fi
  942. }
  943.  
  944. sysresccd_stage2_nbd()
  945. {
  946.     nbdurl=$(echo ${NBDBOOT} | sed -e 's!nbd://!!g')
  947.     NBD_SERVER=$(echo "${nbdurl}" | sed 's/:.*//')
  948.     NBD_PORT=$(echo "${nbdurl}" | sed 's/.*://')
  949.  
  950.     REAL_ROOT="nbd"
  951.     NBD_DEVICE="/dev/nbd0"
  952.     NBD_PROG="/sbin/nbd-client"
  953.  
  954.     if [ ! -x "${NBD_PROG}" ]
  955.     then
  956.         sysresccd_panic "Error: program ${NBD_PROG} not found"
  957.     fi
  958.  
  959.     if ! /sbin/modprobe -b nbd
  960.     then
  961.         sysresccd_panic "Error: cannot load nbd kernel module"
  962.     fi
  963.  
  964.     good_msg "Setting up the NBD boot device..."
  965.     if ! ${NBD_PROG} "${NBD_SERVER}" "${NBD_PORT}" "${NBD_DEVICE}" -persist
  966.     then
  967.         sysresccd_panic "Error: nbd-client failed to connect to ${NBD_SERVER}:${NBD_PORT}"
  968.     else
  969.         good_msg "nbd-client successfully connected to ${NBD_SERVER}:${NBD_PORT}"
  970.     fi
  971.  
  972.     cmd="mount -t squashfs -o ro ${NBD_DEVICE} ${SQUASHFSMNT}"
  973.     if ! ${cmd}
  974.     then
  975.         sysresccd_panic "ERROR: Cannot mount ${NBD_DEVICE}. ${cmd}"
  976.     else
  977.         good_msg "successfully mounted ${NBD_DEVICE} on ${SQUASHFSMNT}"
  978.     fi
  979. }
  980.  
  981. sysresccd_stage2_normal() # mount ${BOOTPATH}/sysrcd.dat on ${SQUASHFSMNT}
  982. {
  983.     good_msg "Mounting the squashfs root filesystem on ${SQUASHFSMNT}"
  984.  
  985.     mountok=''
  986.     squashfsimg="${BOOTPATH}/${SUBDIR}/${LOOPDAT}"
  987.     for fs in '-t squashfs' ''
  988.     do
  989.         if [ "$mountok" != "ok" ]
  990.         then
  991.             mount ${fs} ${squashfsopt} -o ro ${squashfsimg} ${SQUASHFSMNT} 2>/dev/null && mountok='ok'
  992.         fi
  993.     done
  994.  
  995.     if [ "$mountok" != "ok" ]
  996.     then
  997.         sysresccd_panic "ERROR: Cannot mount ${LOOPDAT}. Kernel version [$(uname -a)]"
  998.     fi
  999. }
  1000.  
  1001. sysresccd_stage3_normal() # "backstore" + "aufs" + "mount --move"
  1002. {
  1003.     # 1. search for a backstore file ("sysrcd.bs" by default)
  1004.     BACKSTORE_FOUND=''
  1005.     if [ "${BACKSTORE_CMD}" != 'off' ]
  1006.     then
  1007.         BACKSTORE_DEVTYPE='rmdev' # by default search backstores only on removable devices
  1008.         BACKSTORE_NOLOOP=''
  1009.         for curopt in $(echo ${BACKSTORE_CMD} | sed -e 's!,! !g')
  1010.         do
  1011.             case "${curopt}" in
  1012.                 alldev)
  1013.                     BACKSTORE_DEVTYPE='auto' # search for backstores on all types of devices
  1014.                     ;;
  1015.                 UUID\=*)
  1016.                     BACKSTORE_DEVTYPE=${curopt}
  1017.                     ;;
  1018.                 LABEL\=*)
  1019.                     BACKSTORE_DEVTYPE=${curopt}
  1020.                     ;;
  1021.                 noloop)
  1022.                     BACKSTORE_NOLOOP='1' # uses a device as backstore
  1023.                     ;;
  1024.                 *)
  1025.                     BACKSTORE_DAT=${curopt} # search for backstores on that particular device
  1026.                     ;;
  1027.             esac
  1028.         done
  1029.  
  1030.         if [ -n "${BACKSTORE_NOLOOP}" ]
  1031.         then
  1032.             case "${BACKSTORE_DEVTYPE}" in
  1033.                 UUID\=* | LABEL\=* )
  1034.                     good_msg "Mounting device ${BACKSTORE_DEVTYPE} as backing store"
  1035.                     BACKSTORE_DEV="$(sysresccd_find_devices ${BACKSTORE_DEVTYPE})"
  1036.                     if ! mount ${BACKSTORE_DEV} ${BACKSTORE_MEM}
  1037.                     then
  1038.                         sysresccd_panic "Cannot mount the backstore device ${BACKSTORE_DEV}"
  1039.                     fi
  1040.                     BACKSTORE_FOUND='1'
  1041.                     ;;
  1042.                 rmdev | auto | * )
  1043.                     sysresccd_panic "UUID or LABEL needed to mount a block device as backing store"
  1044.                     ;;
  1045.             esac
  1046.         else
  1047.             good_msg "Searching for ${SUBDIR}/${BACKSTORE_DAT} on devices..."
  1048.             if sysresccd_find_file ${BACKSTORE_DEVTYPE} ${SUBDIR}/${BACKSTORE_DAT} ${BACKSTORE_MNT} 'rw'
  1049.             then
  1050.                 good_msg "Backing store ${SUBDIR}/${BACKSTORE_DAT} found on ${SEARCHDEVICE}"
  1051.                 if ! mount ${BACKSTORE_MNT}/${SUBDIR}/${BACKSTORE_DAT} ${BACKSTORE_MEM}
  1052.                 then
  1053.                     sysresccd_panic "Cannot mount the loopback backstore file ${SUBDIR}/${BACKSTORE_DAT}"
  1054.                 fi
  1055.                 BACKSTORE_FOUND='1'
  1056.             fi
  1057.         fi
  1058.  
  1059.     fi
  1060.  
  1061.     # 2. store modifications in a tmpfs filesystem if there is no backstore
  1062.     if [ -z "${BACKSTORE_FOUND}" ] && ! mount -t tmpfs tmpfs ${BACKSTORE_MEM}
  1063.     then
  1064.         sysresccd_panic "Fatal error: cannot mount tmpfs on ${BACKSTORE_MEM}"
  1065.     fi
  1066.  
  1067.     # 3. create the aufs filesystem
  1068.     if ! grep -q aufs /proc/filesystems
  1069.     then
  1070.         sysresccd_panic "Fatal error: aufs filesystem not supported by the kernel."
  1071.     fi
  1072.     if mount -t aufs none ${NEWROOT} -o dirs=${BACKSTORE_MEM}=rw:${SQUASHFSMNT}=ro -o noatime
  1073.     then
  1074.         good_msg "The aufs filesystem has been created"
  1075.     else
  1076.         sysresccd_panic "Fatal error: cannot mount the aufs filesystem."
  1077.     fi
  1078.  
  1079.     # 4. copy cached autorun scripts
  1080.     autoruns="$(ls -d ${CACHEDIR}/autorun* 2>/dev/null)"
  1081.     [ "$autoruns" != "" ] && cp $autoruns ${NEWROOT}/var/autorun/cdrom
  1082.  
  1083.     # 5. create the aufs filesystem for /tftpboot
  1084.     TFTPBOOT_MEM='/tftpmem'
  1085.     TFTPBOOT_DIR='/tftpboot'
  1086.     mkdir -p ${TFTPBOOT_MEM}
  1087.     mkdir -p ${TFTPBOOT_DIR}
  1088.     if ! mount -t tmpfs tmpfs ${TFTPBOOT_MEM} -o size=512m
  1089.     then
  1090.         sysresccd_panic "Fatal error: cannot mount tmp filesystem on ${TFTPBOOT_MEM}"
  1091.     fi
  1092.  
  1093.     if ! mount -t aufs none ${TFTPBOOT_DIR} -o dirs=${TFTPBOOT_MEM}=rw:${BOOTPATH}=ro
  1094.     then
  1095.         bad_msg "Cannot prepare ${TFTPBOOT_DIR} for pxebootsrv"
  1096.     fi
  1097.  
  1098.     if [ -f ${BOOTPATH}/isolinux/isolinux.cfg ]
  1099.     then
  1100.         isolinux_dir="isolinux"
  1101.     elif [ -f ${BOOTPATH}/syslinux/syslinux.cfg ]
  1102.     then
  1103.         isolinux_dir="syslinux"
  1104.     fi
  1105.  
  1106.     if [ -n "${isolinux_dir}" ]
  1107.     then
  1108.         for curfile in initram.igz rescuecd rescue64 altker32 altker64
  1109.         do
  1110.             ln -s ${isolinux_dir}/${curfile} ${TFTPBOOT_DIR}/${curfile}
  1111.         done
  1112.     fi
  1113.  
  1114.     # 5. move filesystems mount points to the newroot
  1115.     for mntdir in ${BOOTPATH} ${SQUASHFSMNT} ${BACKSTORE_MNT} ${BACKSTORE_MEM} ${ISOSTORE} ${TFTPBOOT_MEM}
  1116.     do
  1117.         targetdir="${NEWROOT}/livemnt/${mntdir}"
  1118.         if cat /proc/mounts | awk '{print $2}' | grep -q "^${mntdir}$"
  1119.         then
  1120.             mkdir -p ${targetdir} 2>/dev/null
  1121.             cmd="mount -n --move ${mntdir} ${targetdir}"
  1122.             if ! ${cmd}
  1123.             then
  1124.                 sysresccd_panic "${cmd} failed"
  1125.             fi
  1126.         fi
  1127.     done
  1128.    
  1129.     if ! mount -n --move ${TFTPBOOT_DIR} ${NEWROOT}${TFTPBOOT_DIR}
  1130.     then
  1131.         bad_msg "Cannot move [${TFTPBOOT_DIR}] -> [${NEWROOT}${TFTPBOOT_DIR}]"
  1132.     fi
  1133.  
  1134.     # make directories
  1135.     for curdir in /mnt/custom /mnt/gentoo /mnt/windows /mnt/floppy /mnt/backup \
  1136.         /var/run/iptraf /var/log/iptraf /var/spool/cron /var/run/samba \
  1137.         /var/log/samba /var/cache/samba /var/log/clamav /var/run/clamav \
  1138.         /var/cache/hald /var/run/hald
  1139.     do
  1140.         mkdir -p "${NEWROOT}${curdir}"
  1141.     done
  1142.  
  1143.     if [ -e /etc/sysconfig/keyboard ]
  1144.     then
  1145.         mkdir -p ${NEWROOT}/etc/sysconfig/
  1146.         cp /etc/sysconfig/keyboard ${NEWROOT}/etc/sysconfig/keyboard
  1147.     fi
  1148.  
  1149.     # if option "lowmem" was enabled then do not start these initscripts
  1150.     if [ "${LOWMEM}" = '1' ]
  1151.     then
  1152.         for initscr in sshd nfs portmap
  1153.         do
  1154.             rm -f "${NEWROOT}/etc/runlevels/default/${initscr}"
  1155.         done
  1156.     fi
  1157.  
  1158.     # blacklist modules passed to "noload=mod1,mod2,mod3"
  1159.     for modname in ${BLACKLIST}
  1160.     do
  1161.         echo "blacklist ${modname}" >> ${NEWROOT}/etc/modprobe.d/blacklist.conf
  1162.     done
  1163.  
  1164.     # prevent fbcon module from loading (console could become unusable)
  1165.     echo "blacklist fbcon" >> ${NEWROOT}/etc/modprobe.d/blacklist.conf
  1166.  
  1167.     # manage services
  1168.     [ -n "${NONETMGR}" ] && chroot ${NEWROOT} /sbin/rc-update del NetworkManager default >/dev/null 2>&1
  1169.     chroot ${NEWROOT} /sbin/rc-update del spind default >/dev/null 2>&1
  1170.     chroot ${NEWROOT} /sbin/rc-update del autoconfig default >/dev/null 2>&1
  1171.     rm -f ${NEWROOT}/etc/init.d/crypto-loop
  1172.     rm -f ${NEWROOT}/etc/init.d/drbd
  1173. }
  1174.  
  1175. sysresccd_stage3_rootsys() # mount the root partition on ${SQUASHFSMNT}
  1176. {
  1177.     good_msg "Searching a root filesystem having ${INITPROG}"
  1178.  
  1179.     filefound=''
  1180.     for attempts in 1 2 3 4 5
  1181.     do
  1182.         [ ${attempts} -gt 1 ] && sleep 3 && bad_msg "Cannot find device with ${INITPROG}. Retrying..."
  1183.         if sysresccd_find_file ${ROOTOPT} ${INITPROG} ${NEWROOT} 'rw'
  1184.         then
  1185.             filefound='1'
  1186.             break
  1187.         fi
  1188.     done
  1189.  
  1190.     if [ -z "${filefound}" ]
  1191.     then
  1192.         sysresccd_panic "Cannot find a valid root filesystem (partition having ${INITPROG})"
  1193.     fi
  1194.  
  1195.     #NEWKERMODS="${NEWROOT}/lib/modules/$(uname -r)"
  1196.     #mkdir -p ${NEWKERMODS}
  1197.     #mount -t tmpfs tmpfs ${NEWKERMODS}
  1198.     #cp -a /lib/modules/$(uname -r)/* ${NEWKERMODS}/
  1199. }
  1200.  
  1201. sysresccd_stage0_isoloop() # losetup the iso image on /dev/loop0
  1202. {
  1203.     good_msg "Searching for ${SUBDIR}/${ISOLOOP} on devices..."
  1204.     filefound=''
  1205.     for attempts in 1 2 3 4 5
  1206.     do
  1207.         [ ${attempts} -gt 1 ] && sleep 3 && bad_msg "Cannot find device with ${SUBDIR}/${ISOLOOP}. Retrying..."
  1208.         if sysresccd_find_file 'auto' ${SUBDIR}/${ISOLOOP} ${ISOSTORE} 'ro'
  1209.         then
  1210.             filefound='1'
  1211.             break
  1212.         fi
  1213.     done
  1214.  
  1215.     if [ -z "${filefound}" ]
  1216.     then
  1217.         sysresccd_panic "Cannot find device with ${SUBDIR}/${ISOLOOP}"
  1218.     fi
  1219.  
  1220.     if losetup /dev/loop0 ${ISOSTORE}/${SUBDIR}/${ISOLOOP}
  1221.     then
  1222.         good_msg "Loopback device configured with ${ISOSTORE}/${SUBDIR}/${ISOLOOP}"
  1223.         BLKDEVICES="$BLKDEVICES /dev/loop0"
  1224.     else
  1225.         bad_msg "Cannot configure /dev/loop0 with ${ISOSTORE}/${SUBDIR}/${ISOLOOP}"
  1226.     fi
  1227. }
  1228.  
  1229. # =============================================================================
  1230.  
  1231. sysresccd_stage0() # special preparations for isoroot
  1232. {
  1233.     case "${STAGE0}" in
  1234.         isoloop)
  1235.             sysresccd_stage0_isoloop
  1236.             STAGE1='normal'
  1237.             ;;
  1238.         *)
  1239.             STAGE1="${STAGE0}"
  1240.             ;;
  1241.     esac
  1242. }
  1243.  
  1244. sysresccd_stage1() # find sysrcd.dat and put it in ${BOOTPATH}
  1245. {
  1246.     case "${STAGE1}" in
  1247.         rootsys)
  1248.             STAGE2="rootsys"
  1249.             ;;
  1250.         nbd)
  1251.             STAGE2="nbd"
  1252.             ;;
  1253.         http)
  1254.             sysresccd_stage1_http
  1255.             STAGE2="normal"
  1256.             ;;
  1257.         tftp)
  1258.             sysresccd_stage1_tftp
  1259.             STAGE2="normal"
  1260.             ;;
  1261.         nfs)
  1262.             sysresccd_stage1_nfs
  1263.             STAGE2="normal"
  1264.             ;;
  1265.         normal)
  1266.             sysresccd_stage1_normal
  1267.             STAGE2="normal"
  1268.             ;;
  1269.     esac
  1270. }
  1271.  
  1272. sysresccd_stage2() # mount ${BOOTPATH}/sysrcd.dat on ${SQUASHFSMNT}
  1273. {
  1274.     case "${STAGE2}" in
  1275.         rootsys)
  1276.             STAGE3="rootsys"
  1277.             ;;
  1278.         nbd)
  1279.             sysresccd_stage2_nbd
  1280.             STAGE3="normal"
  1281.             ;;
  1282.         normal)
  1283.             sysresccd_stage2_normal
  1284.             STAGE3="normal"
  1285.             ;;
  1286.     esac
  1287. }
  1288.  
  1289. sysresccd_stage3() # ${NEWROOT}=aufs
  1290. {
  1291.     case "${STAGE3}" in
  1292.         rootsys)
  1293.             sysresccd_stage3_rootsys
  1294.             ;;
  1295.         normal)
  1296.             sysresccd_stage3_normal
  1297.             ;;
  1298.     esac
  1299. }
  1300.  
  1301. # =============================================================================
  1302.  
  1303. sysresccd_parsecmdline()
  1304. {
  1305.     for x in $(cat /proc/cmdline)
  1306.     do
  1307.         case "${x}" in
  1308.         init\=*)
  1309.             INITPROG=`parse_opt "${x}"`
  1310.             ;;
  1311.         dodhcp)
  1312.             DODHCP='all'
  1313.             SETETHX=''
  1314.             NETCONFIG='1'
  1315.             NONETMGR='1'
  1316.             ;;
  1317.         dodhcp\=*)
  1318.             DODHCP=`parse_opt "${x}"`
  1319.             SETETHX=''
  1320.             NETCONFIG='1'
  1321.             NONETMGR='1'
  1322.             ;;
  1323.         nodhcp)
  1324.             NODHCP='1'
  1325.             ;;
  1326.         ethx\=*)
  1327.             SETETHX=`parse_opt "${x}"`
  1328.             DODHCP=''
  1329.             NETCONFIG='1'
  1330.             NONETMGR='1'
  1331.             ;;
  1332.         dns\=*)
  1333.             SETDNS=`parse_opt "${x}"`
  1334.             NETCONFIG='1'
  1335.             NONETMGR='1'
  1336.             ;;
  1337.         gw\=*)
  1338.             SETGW=`parse_opt "${x}"`
  1339.             NETCONFIG='1'
  1340.             NONETMGR='1'
  1341.             ;;
  1342.         gateway\=*)
  1343.             SETGW=`parse_opt "${x}"`
  1344.             NETCONFIG='1'
  1345.             NONETMGR='1'
  1346.             ;;
  1347.         dhcphostname\=*)
  1348.             DHCPHOSTNAME=`parse_opt "${x}"`
  1349.             NETCONFIG='1'
  1350.             ;;
  1351.         netboot\=http://*)
  1352.             HTTPBOOT=`parse_opt "${x}"`
  1353.             STAGE0='http'
  1354.             NETCONFIG='1'
  1355.             NONETMGR='1'
  1356.             ;;
  1357.         netboot\=tftp://*)
  1358.             TFTPBOOT=`parse_opt "${x}"`
  1359.             STAGE0='tftp'
  1360.             NETCONFIG='1'
  1361.             NONETMGR='1'
  1362.             ;;
  1363.         netboot\=nfs://*)
  1364.             NFSBOOT=`parse_opt "${x}"`
  1365.             STAGE0='nfs'
  1366.             NETCONFIG='1'
  1367.             NONETMGR='1'
  1368.             ;;
  1369.         netboot\=nbd://*)
  1370.             NBDBOOT=`parse_opt "${x}"`
  1371.             STAGE0='nbd'
  1372.             NETCONFIG='1'
  1373.             NONETMGR='1'
  1374.             ;;
  1375.         root\=*)
  1376.             ROOTOPT=`parse_opt "${x}"`
  1377.             STAGE0='rootsys'
  1378.             ;;
  1379.         isoloop\=*)
  1380.             ISOLOOP=`parse_opt "${x}"`
  1381.             STAGE0='isoloop'
  1382.             ;;
  1383.         docache)
  1384.             DOCACHE='1'
  1385.             ;;
  1386.         subdir\=*)
  1387.             SUBDIR=`parse_opt "${x}"`
  1388.             ;;
  1389.         speakup\=*)
  1390.             SPEAKUP=`parse_opt "${x}"`
  1391.             ;;
  1392.         backstore\=*)
  1393.             BACKSTORE_CMD=`parse_opt "${x}"`
  1394.             ;;
  1395.         setkmap\=*)
  1396.             SETKMAP=`parse_opt "${x}"`
  1397.             ;;
  1398.         scandelay\=*)
  1399.             SCANDELAY=`parse_opt "${x}"`
  1400.             ;;
  1401.         scandelay)
  1402.             SCANDELAY=10
  1403.             ;;
  1404.         doload\=*)
  1405.             MODLOAD=`parse_opt "${x}"`
  1406.             MODLOAD="`echo ${MODLOAD} | sed -e \"s/,/ /g\"`"
  1407.             ;;
  1408.         nodetect)
  1409.             NODETECT='1'
  1410.             ;;
  1411.         noload\=*)
  1412.             BLACKLIST=`parse_opt "${x}"`
  1413.             BLACKLIST="`echo ${BLACKLIST} | sed -e \"s/,/ /g\"`"
  1414.             ;;
  1415.         CONSOLE\=*)
  1416.             CONSOLE=`parse_opt "${x}"`
  1417.             exec >${CONSOLE} <${CONSOLE} 2>&1
  1418.             ;;
  1419.         docheck)
  1420.             DOCHECK='1'
  1421.             ;;
  1422.         lowmem)
  1423.             LOWMEM='1'
  1424.             ;;
  1425.         minishell)
  1426.             MINISHELL='1'
  1427.             ;;
  1428.         nonm)
  1429.             NONETMGR='1'
  1430.             ;;
  1431.         nonetman)
  1432.             NONETMGR='1'
  1433.             ;;
  1434.         httpboot\=*) # for compatibility only
  1435.             HTTPBOOT=`parse_opt "${x}"`
  1436.             STAGE0='http'
  1437.             NETCONFIG='1'
  1438.             NONETMGR='1'
  1439.             ;;
  1440.         tftpboot\=*) # for compatibility only
  1441.             TFTPBOOT=`parse_opt "${x}"`
  1442.             STAGE0='tftp'
  1443.             NETCONFIG='1'
  1444.             NONETMGR='1'
  1445.             ;;
  1446.         boothttp\=*) # for compatibility only
  1447.             HTTPBOOT=`parse_opt "${x}"`
  1448.             STAGE0='http'
  1449.             NETCONFIG='1'
  1450.             NONETMGR='1'
  1451.             ;;
  1452.         boottftp\=*) # for compatibility only
  1453.             TFTPBOOT=`parse_opt "${x}"`
  1454.             STAGE0='tftp'
  1455.             NETCONFIG='1'
  1456.             NONETMGR='1'
  1457.             ;;
  1458.         nfsboot\=*) # for compatibility only
  1459.             ARG=`parse_opt "${x}"`
  1460.             NFSBOOT="nfs://${ARG}"
  1461.             STAGE0='nfs'
  1462.             NETCONFIG='1'
  1463.             NONETMGR='1'
  1464.             ;;
  1465.         nbdboot\=*) # for compatibility only
  1466.             ARG=`parse_opt "${x}"`
  1467.             NBDBOOT="nbd://${ARG}"
  1468.             STAGE0='nbd'
  1469.             NETCONFIG='1'
  1470.             NONETMGR='1'
  1471.             ;;
  1472.         esac
  1473.     done
  1474. }
  1475.  
  1476. # =============================================================================
  1477.  
  1478. sysresccd_init()
  1479. {
  1480.     export PATH=/bin:/usr/bin:/sbin:/usr/sbin
  1481.  
  1482.     # only run as an init program
  1483.     if [ "$$" != '1' ]
  1484.     then
  1485.         echo '/init has to be run as the init process as the one'
  1486.         echo 'with a PID of 1. Try adding init="/init" to the'
  1487.         echo 'kernel command line or running "exec /init".'
  1488.         exit 1
  1489.     fi
  1490.  
  1491.     # create system directories
  1492.     [ -d /dev ] || mkdir -m 0755 /dev
  1493.     [ -d /root ] || mkdir -m 0700 /root
  1494.     [ -d /sys ] || mkdir /sys
  1495.     [ -d /proc ] || mkdir /proc
  1496.     [ -d /tmp ] || mkdir /tmp
  1497.     [ -d /selinux ] || mkdir /selinux
  1498.     [ -d /var/lock ] || mkdir -p /var/lock
  1499.     [ -d /usr/bin ] || mkdir -p /usr/bin
  1500.     [ -d /usr/sbin ] || mkdir -p /usr/sbin
  1501.     [ -d ${SQUASHFSMNT} ] || mkdir -p ${SQUASHFSMNT}
  1502.     [ -d ${BOOTPATH} ] || mkdir -p ${BOOTPATH}
  1503.     [ -d ${NEWROOT} ] || mkdir -p ${NEWROOT}
  1504.     [ -d ${BACKSTORE_MNT} ] || mkdir -p ${BACKSTORE_MNT}
  1505.     [ -d ${BACKSTORE_MEM} ] || mkdir -p ${BACKSTORE_MEM}
  1506.     [ -d ${ISOSTORE} ] || mkdir -p ${ISOSTORE}
  1507.     [ -d ${CACHEDIR} ] || mkdir -p ${CACHEDIR}
  1508.  
  1509.     # mount virtual filesystems
  1510.     /bin/busybox mount -t sysfs -o nodev,noexec,nosuid none /sys
  1511.     /bin/busybox mount -t proc -o nodev,noexec,nosuid none /proc
  1512.  
  1513.     # setup busybox
  1514.     /bin/busybox --install -s
  1515. }
  1516.  
  1517. # =============================================================================
  1518.  
  1519. NORMAL="\033[0m"
  1520. WARN="\033[33;1m"
  1521. BAD="\033[31;1m"
  1522. BOLD="\033[1m"
  1523. GOOD="\033[32;1m"
  1524.  
  1525. DOCACHE=''
  1526. SETKMAP=''
  1527. MINISHELL=''
  1528. NETCONFIG=''
  1529. DHCPHOSTNAME=''
  1530. DOCHECK=''
  1531. LOWMEM=''
  1532. SETGW=''
  1533. SETDNS=''
  1534. SETETHX=''
  1535. NETBOOT=''
  1536. NFSBOOT=''
  1537. NBDBOOT=''
  1538. ISOLOOP=''
  1539. ISOLOOPDEV=''
  1540. DODHCP=''
  1541. NODHCP=''
  1542. ROOTFS=''
  1543. SUBDIR=''
  1544. SPEAKUP=''
  1545. STAGE0='normal'
  1546. BOOTPATH='/boot'
  1547. NEWROOT='/newroot'
  1548. SQUASHFSMNT='/squashfs'
  1549. ISOSTORE='/isostore'
  1550. BACKSTORE_CMD=''
  1551. BACKSTORE_MNT='/backstore'
  1552. BACKSTORE_MEM='/memory'
  1553. BACKSTORE_DAT='sysrcd.bs'
  1554. LOOPDAT='sysrcd.dat'
  1555. LOOPMD5='sysrcd.md5'
  1556. INITPROG='/sbin/init'
  1557. CONSOLE='/dev/console'
  1558. CACHEDIR='/cache'
  1559. CACHESIZE='size=512m'
  1560. NONETMGR=''
  1561.  
  1562. # Start with an empty list
  1563. BLKDEVICES=""
  1564. # CDROM DEVICES
  1565. BLKDEVICES="$BLKDEVICES /dev/cdroms/* /dev/ide/cd/* /dev/sr*"
  1566. # USB Keychain/Storage
  1567. BLKDEVICES="$BLKDEVICES /dev/sd*"
  1568. # IDE devices
  1569. BLKDEVICES="$BLKDEVICES /dev/hd*"
  1570. # USB Block Driver
  1571. BLKDEVICES="$BLKDEVICES /dev/ubd* /dev/ubd/*"
  1572. # iSeries devices
  1573. BLKDEVICES="$BLKDEVICES /dev/iseries/vcd*"
  1574. # HP Smart Array
  1575. BLKDEVICES="$BLKDEVICES /dev/cciss* /dev/cciss/*"
  1576. # devmapper
  1577. BLKDEVICES="$BLKDEVICES /dev/dm* /dev/mapper/*"
  1578. # md raid
  1579. BLKDEVICES="$BLKDEVICES /dev/md* /dev/md/*"
  1580.  
  1581. # =============================================================================
  1582.  
  1583. sysresccd_init
  1584. sysresccd_parsecmdline
  1585. sysresccd_terminal
  1586. sysresccd_udev_start
  1587. sysresccd_speakup
  1588. sysresccd_setup_keymap
  1589. sysresccd_setup_volumes
  1590. sysresccd_netconfig
  1591. sysresccd_debug
  1592. sysresccd_stage0
  1593. sysresccd_stage1
  1594. sysresccd_stage2
  1595. sysresccd_stage3
  1596. sysresccd_udev_stop
  1597. sysresccd_chroot
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement