home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / etc / init.d / checkroot.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  2006-08-23  |  9.5 KB  |  404 lines

  1. #! /bin/sh
  2. ### BEGIN INIT INFO
  3. # Provides:          checkroot
  4. # Required-Start:    mountdevsubfs
  5. # Required-Stop:     
  6. # Should-Start:      keymap hwclockfirst
  7. # Should-stop:
  8. # Default-Start:     S
  9. # Default-Stop:
  10. # Short-Description: Check to root file system.
  11. ### END INIT INFO
  12.  
  13. PATH=/lib/init:/sbin:/bin
  14. FSCK_LOGFILE=/var/log/fsck/checkroot
  15. [ "$FSCKFIX" ] || FSCKFIX=no
  16. [ "$SULOGIN" ] || SULOGIN=no
  17. . /lib/init/vars.sh
  18.  
  19. . /lib/lsb/init-functions
  20.  
  21. do_start () {
  22.     #
  23.     # Set SULOGIN in /etc/default/rcS to yes if you want a sulogin to
  24.     # be spawned from this script *before anything else* with a timeout,
  25.     # like sysv does.
  26.     #
  27.     [ "$SULOGIN" = yes ] && sulogin -t 30 $CONSOLE
  28.  
  29.     KERNEL="$(uname -s)"
  30.     MACHINE="$(uname -m)"
  31.  
  32.     #
  33.     # Read /etc/fstab, looking for:
  34.     # 1) The root filesystem, resolving LABEL=*|UUID=* entries to the
  35.     #     device node,
  36.     # 2) Swap that is on a md device or a file that may be on a md 
  37.     #     device,
  38.     # 3) The mount parameters for a devfs filesystem.
  39.     #
  40.  
  41.     exec 9<&0 </etc/fstab
  42.  
  43.     fstabroot=/dev/root
  44.     rootdev=none
  45.     roottype=none
  46.     rootopts=defaults
  47.     rootmode=rw
  48.     rootcheck=no
  49.     swap_on_lv=no
  50.     swap_on_file=no
  51.     devfs=
  52.  
  53.     while read DEV MTPT FSTYPE OPTS DUMP PASS JUNK
  54.     do
  55.         case "$DEV" in
  56.           ""|\#*)
  57.             continue;
  58.             ;;
  59.           /dev/mapper/*)
  60.             [ "$FSTYPE" = "swap" ] && swap_on_lv=yes
  61.             ;;
  62.           /dev/*)
  63.             ;;
  64.           LABEL=*|UUID=*)
  65.             if [ "$MTPT" = "/" ] && which findfs >/dev/null 2>&1
  66.             then
  67.                 DEV="$(findfs "$DEV")"
  68.             fi
  69.             ;;
  70.           /*)
  71.             [ "$FSTYPE" = "swap" ] && swap_on_file=yes
  72.             ;;
  73.           *)
  74.             # Devfs definition ?
  75.             if [ "$FSTYPE" = "devfs" ] && [ "$MTPT" = "/dev" ] && mountpoint -q /dev
  76.             then
  77.                 devfs="-t $FSTYPE $DEV $MTPT"
  78.             fi
  79.             ;;
  80.         esac
  81.         [ "$MTPT" != "/" ] && continue
  82.         rootdev="$DEV"
  83.         fstabroot="$DEV"
  84.         rootopts="$OPTS"
  85.         roottype="$FSTYPE"
  86.         ( [ "$PASS" != 0 ] && [ "$PASS" != "" ]   ) && rootcheck=yes
  87.         ( [ "$FSTYPE" = "nfs" ] || [ "$FSTYPE" = "nfs4" ] ) && rootcheck=no
  88.         case "$OPTS" in
  89.           ro|ro,*|*,ro|*,ro,*)
  90.             rootmode=ro
  91.             ;;
  92.         esac
  93.     done
  94.  
  95.     exec 0<&9 9<&-
  96.  
  97.     #
  98.     # Activate the swap device(s) in /etc/fstab. This needs to be done
  99.     # before fsck, since fsck can be quite memory-hungry.
  100.     #
  101.     ENABLE_SWAP=no
  102.     case "$KERNEL" in
  103.       Linux)
  104.         if [ "$swap_on_lv" = yes ]
  105.         then
  106.             [ "$VERBOSE" = no ] || log_warning_msg "Not activating swap on logical volume."
  107.         elif [ "$swap_on_file" = yes ]
  108.         then
  109.             [ "$VERBOSE" = no ] || log_warning_msg "Not activating swap on swapfile."
  110.         else
  111.             ENABLE_SWAP=yes
  112.         fi
  113.         ;;
  114.       *)
  115.         ENABLE_SWAP=yes
  116.         ;;
  117.     esac
  118.     if [ "$ENABLE_SWAP" = yes ]
  119.     then
  120.         if [ "$VERBOSE" = no ]
  121.         then
  122.             log_action_begin_msg "Activating swap"
  123.             swapon -a -e >/dev/null 2>&1
  124.             log_action_end_msg $?
  125.         else
  126.             log_action_msg "Will now activate swap"
  127.             swapon -a -v
  128.             ES=$?
  129.             if [ "$ES" = 0 ]
  130.             then
  131.                 log_success_msg "Done activating swap."
  132.             else
  133.                 log_failure_msg "Swap activation failed with error code ${ES}."
  134.             fi
  135.         fi
  136.     fi
  137.  
  138.     #
  139.     # Does the root device in /etc/fstab match with the actual device ?
  140.     # If not we try to use the /dev/root alias device, and if that
  141.     # fails we create a temporary node in /dev/shm.
  142.     #
  143.     if [ "$rootcheck" = yes ]
  144.     then
  145.         ddev="$(mountpoint -qx $rootdev)"
  146.         rdev="$(mountpoint -d /)"
  147.         if [ "$ddev" != "$rdev" ] && [ "$ddev" != "4:0" ]
  148.         then
  149.             if [ "$(mountpoint -qx /dev/root)" = "4:0" ]
  150.             then
  151.                 rootdev=/dev/root
  152.             else
  153.                 if \
  154.                     rm -f /dev/shm/root \
  155.                     && mknod -m 600 /dev/shm/root b ${rdev%:*} ${rdev#*:} \
  156.                     && [ -e /dev/shm/root ]
  157.                 then
  158.                     rootdev=/dev/shm/root
  159.                 else
  160.                     rootfatal=yes
  161.                 fi
  162.             fi
  163.         fi
  164.     fi
  165.  
  166.     #
  167.     # Bother, said Pooh.
  168.     #
  169.     if [ "$rootfatal" = yes ]
  170.     then
  171.         log_failure_msg "The device node $rootdev for the root filesystem is missing or incorrect 
  172. or there is no entry for the root filesystem listed in /etc/fstab. 
  173. The system is also unable to create a temporary node in /dev/shm. 
  174. This means you have to fix the problem manually."
  175.         log_warning_msg "A maintenance shell will now be started. 
  176. CONTROL-D will terminate this shell and restart the system."
  177.         # Start a single user shell on the console
  178.         if ! sulogin $CONSOLE
  179.         then
  180.             log_failure_msg "Attempt to start maintenance shell failed. 
  181. Will restart in 5 seconds."
  182.             sleep 5
  183.         fi
  184.         [ "$VERBOSE" = no ] || log_action_msg "Will now restart"
  185.         reboot -f
  186.     fi
  187.  
  188.     # See if we're on AC Power
  189.     # If not, we're not gonna run our check
  190.     if which on_ac_power >/dev/null 2>&1 && [ "$rootcheck" = yes ]
  191.     then
  192.         on_ac_power >/dev/null 2>&1
  193.         if [ "$?" -eq 1 ]
  194.         then
  195.             log_warning_msg "On battery power, so skipping file system check."
  196.             rootcheck=no
  197.         fi
  198.     fi
  199.  
  200.     #
  201.     # See if we want to check the root file system.
  202.     #
  203.     FSCKCODE=0
  204.     if [ -f /fastboot ]
  205.     then
  206.         [ "$rootcheck" = yes ] && log_warning_msg "Fast boot enabled, so skipping file system check."
  207.         rootcheck=no
  208.     fi
  209.  
  210.     if [ "$rootcheck" = yes ]
  211.     then
  212.         #
  213.         # Ensure that root is quiescent and read-only before fsck'ing.
  214.         #
  215.         # mount -n -o remount,ro / would be the correct syntax but
  216.         # mount can get confused when there is a "bind" mount defined
  217.         # in fstab that bind-mounts "/" somewhere else.
  218.         #
  219.         # So we use mount -n -o remount,ro $rootdev / but that can
  220.         # fail on older kernels on sparc64/alpha architectures due
  221.         # to a bug in sys_mount().
  222.         #
  223.         # As a compromise we try both.
  224.         #
  225.         if \
  226.             ! mount    -n -o remount,ro              $rootdev /              \
  227.             && ! mount -n -o remount,ro -t dummytype $rootdev /  2>/dev/null \
  228.             && ! mount -n -o remount,ro                       /  2>/dev/null
  229.         then
  230.             log_failure_msg "Cannot check root file system because it is not mounted read-only."
  231.             rootcheck=no
  232.         fi
  233.     fi
  234.  
  235.     #
  236.     # The actual checking is done here.
  237.     #
  238.     if [ "$rootcheck" = yes ]
  239.     then
  240.         if [ -f /forcefsck ]
  241.         then
  242.             force="-f"
  243.         else
  244.             force=""
  245.         fi
  246.  
  247.         if [ "$FSCKFIX" = yes ]
  248.         then
  249.             fix="-y"
  250.         else
  251.             fix="-a"
  252.         fi
  253.  
  254.         spinner="-C"
  255.         case "$TERM" in
  256.           dumb|network|unknown|"")
  257.             spinner="" ;;
  258.         esac
  259.         # This Linux/s390 special case should go away.
  260.         if [ "${KERNEL}:${MACHINE}" = Linux:s390 ]
  261.         then
  262.             spinner=""
  263.         fi
  264.         
  265.         if [ "$VERBOSE" = no ]
  266.         then
  267.             log_action_begin_msg "Checking root file system"
  268.             logsave -s $FSCK_LOGFILE fsck $spinner $force $fix -t $roottype $rootdev
  269.             FSCKCODE=$?
  270.             if [ "$FSCKCODE" = 0 ]
  271.             then
  272.                 log_action_end_msg 0
  273.             else
  274.                 log_action_end_msg 1 "code $FSCKCODE"
  275.             fi
  276.         else
  277.             log_action_msg "Will now check root file system"
  278.             logsave -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t $roottype $rootdev
  279.             FSCKCODE=$?
  280.             if [ "$FSCKCODE" = 0 ]
  281.             then
  282.                 log_success_msg "Done checking root file system. 
  283. A log will be saved in ${FSCK_LOGFILE} if that location is writable."
  284.             else
  285.                 log_failure_msg "Root file system check failed with error code ${FSCKCODE}. 
  286. A log is being saved in ${FSCK_LOGFILE} if that location is writable."
  287.             fi
  288.         fi
  289.     fi
  290.  
  291.     #
  292.     # If there was a failure, drop into single-user mode.
  293.     #
  294.     # NOTE: "failure" is defined as exiting with a return code of
  295.     # 4 or larger. A return code of 1 indicates that file system
  296.     # errors were corrected but that the boot may proceed. A return
  297.     # code of 2 or 3 indicates that the system should immediately reboot.
  298.     #
  299.     if [ "$FSCKCODE" -gt 3 ]
  300.     then
  301.         # Surprise! Re-directing from a HERE document (as in "cat << EOF")
  302.         # does not work because the root is currently read-only.
  303.         log_failure_msg "An automatic file system check (fsck) of the root filesystem failed. 
  304. A manual fsck must be performed, then the system restarted. 
  305. The fsck should be performed in maintenance mode with the 
  306. root filesystem mounted in read-only mode."
  307.         log_warning_msg "The root filesystem is currently mounted in read-only mode. 
  308. A maintenance shell will now be started. 
  309. After performing system maintenance, press CONTROL-D 
  310. to terminate the maintenance shell and restart the system."
  311.         # Start a single user shell on the console
  312.         if ! sulogin $CONSOLE
  313.         then
  314.             log_failure_msg "Attempt to start maintenance shell failed. 
  315. Will restart in 5 seconds."
  316.             sleep 5
  317.         fi
  318.         [ "$VERBOSE" = no ] || log_action_msg "Will now restart"
  319.         reboot -f
  320.     elif [ "$FSCKCODE" -gt 1 ]
  321.     then
  322.         log_failure_msg "The file system check corrected errors on the root partition 
  323. but requested that the system be restarted."
  324.         log_warning_msg "The system will be restarted in 5 seconds."
  325.         sleep 5
  326.         [ "$VERBOSE" = no ] || log_action_msg "Will now restart"
  327.         reboot -f
  328.     fi
  329.  
  330.     #
  331.     # Remount root to final mode (rw or ro).
  332.     #
  333.     # See the comments above at the previous "mount -o remount"
  334.     # for an explanation why we try this twice.
  335.     #
  336.     if ! mount -n -o remount,$rootopts,$rootmode $fstabroot / 2>/dev/null
  337.     then
  338.         mount -n -o remount,$rootopts,$rootmode /
  339.     fi
  340.  
  341.     #
  342.     # We only create/modify /etc/mtab if the location where it is
  343.     # stored is writable. If /etc/mtab is a symlink into /proc/
  344.     # then it is not writable.
  345.     #
  346.     INIT_MTAB_FILE=no
  347.     MTAB_PATH="$(readlink -f /etc/mtab || :)"
  348.     case "$MTAB_PATH" in
  349.       /proc/*)
  350.         ;;
  351.       /*)
  352.         if touch "$MTAB_PATH" >/dev/null 2>&1
  353.         then
  354.             :> "$MTAB_PATH"
  355.             rm -f ${MTAB_PATH}~
  356.             INIT_MTAB_FILE=yes
  357.         fi
  358.         ;;
  359.       "")
  360.         [ -L /etc/mtab ] && MTAB_PATH="$(readlink /etc/mtab)"
  361.         if [ "$MTAB_PATH" ]
  362.         then
  363.             log_failure_msg "Cannot initialize ${MTAB_PATH}."
  364.         else
  365.             log_failure_msg "Cannot initialize /etc/mtab."
  366.         fi
  367.         ;;
  368.       *)
  369.         log_failure_msg "Illegal mtab location '${MTAB_PATH}'."
  370.         ;;
  371.     esac
  372.  
  373.     if [ "$INIT_MTAB_FILE" = yes ]
  374.     then
  375.         [ "$roottype" != none ] &&
  376.             mount -f -o $rootopts -t $roottype $fstabroot /
  377.         [ "$devfs" ] && mount -f $devfs
  378.     fi
  379.  
  380.     #
  381.     # Remove /dev/shm/root if we created it.
  382.     #
  383.     rm -f /dev/shm/root
  384. }
  385.  
  386. case "$1" in
  387.   start|"")
  388.     do_start
  389.     ;;
  390.   restart|reload|force-reload)
  391.     echo "Error: argument '$1' not supported" >&2
  392.     exit 3
  393.     ;;
  394.   stop)
  395.     # No-op
  396.     ;;
  397.   *)
  398.     echo "Usage: checkroot.sh [start|stop]" >&2
  399.     exit 3
  400.     ;;
  401. esac
  402.  
  403. :
  404.