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