Fsck imprévu au reboot d'un serveur? Ma solution...

Fsck imprévu au reboot d'un serveur? Ma solution... - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 29-06-2010 à 10:39:05    

:hello:

 

Ça vous ai sûrement déjà arrivé... On tape reboot sur un serveur et... rien. 5 min après il n'est toujours pas up... Mais que se passe-t-il ? Rien en fait, ext3/4 a juste décidé de faire un fsck sur une partition de 250Go :lol:
Malheureusement on ne peut pas vraiment s'en passer, je vous propose donc une solution qui vous permettra d'être prévenu en cas de reboot/shutdown/halt et d'annuler la commande si un fsck va être prévu.

 

Il s'agit donc d'un script qui détecte les partitions ext montées et va vérifier les cas suivants:

  • État du filesystem différent de clean
  • Nombre de montage supérieur ou égal au nombre max de montage avant vérification
  • Date butoir de la prochaine vérification inférieure ou égale à now (+10min pour laisser le temps de l'extinction/démarrage)
  • Date de dernier montage dans le futur


Il suffit ensuite de jouer avec "alias" pour wrapper les commandes reboot/halt/shutdown à travers mon script. Celui-ci restera donc parfaitement silencieux si tout va bien mais vous demandera une confirmation si il détecte qu'un des filesystem sera vérifié au prochain boot.

 

Pour les utilisateur de sudo, un alias supplémentaire est nécessaire pour que sudo autorise l'utilisation des alias.

 

Tout est indiqué dans les commentaires de l'entête du script disponible ici:
http://dedibox.le-vert.net/divers/fsck-or-not.sh

  


Annexe: Le script en question:


#!/bin/sh
#
# Copyright (c) 2010 Adam Cécile (Le_Vert) <gandalf@le-vert.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

 

# How to use it:
#
# Copy this file to /usr/bin
# Create aliases for all commands that may make you suffer from fsck.
#
# In example, on Debian, add the following lines to /etc/bash.bashrc
# and /etc/profile:
# # Reboot/Halt/Shutdown aliases
# alias shutdown='/usr/bin/fsck-or-not.sh shutdown'
# alias halt='/usr/bin/fsck-or-not.sh halt'
# alias reboot='/usr/bin/fsck-or-not.sh reboot'
#
# If you want to make it works with sudo too, edit /etc/bash.bashrc
# and /etc/profile again to add:
# alias sudo='sudo '
#
# Here is an extract from bash manpage that explains the needs of
# this sudo alias:
# If the last character of the alias value is a blank, then the next
# command word following the alias is also checked for alias expansion.
#
# Each time you tape either shutdown, halt or reboot, this script
# will check if any currently mounted EXT filesystem requires fsck
# and thus, will ask you for confirmation before running the real
# command.

 

# Initialize a global variable set to 1 if at least fs needs fsck
globalneedfsck=0

 

# Check currently mounted ext2/3/4 filesystems
for fs in `mount | grep -E ' ext[234] ' | cut -d' ' -f1`; do
  # Initialize a variable to store fs state
  needfsck=0

 

 # Get filesystem state
  state=`tune2fs -l ${fs} | grep -E '^Filesystem state:[[:space:]]+' | cut -d':' -f2 | sed 's/[[:space:]]*//'`
  # Get current mount count
  mountcount=`tune2fs -l ${fs} | grep -E '^Mount count:[[:space:]]+' | cut -d':' -f2 | sed 's/[[:space:]]*//'`
  # Get maximum mount count
  maximummountcount=`tune2fs -l ${fs} | grep -E '^Maximum mount count:[[:space:]]+' | cut -d':' -f2 | sed 's/[[:space:]]*//'`
  # Get next check date
  nextcheck=`tune2fs -l ${fs} | grep -E '^Next check after:[[:space:]]+' | awk -F': ' '{ print $2 }' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//'`
  # Get last mount date (to check "last mount in future)
  lastmount=`tune2fs -l ${fs} | grep -E '^Last mount time:[[:space:]]+' | awk -F': ' '{ print $2 }' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//'`
  # Convert next check date to timestamp
  nextchecktimestamp=`LANG=C date "+%s" -d "${nextcheck}"`
  # Convert last mount time into timestamp
  lastmounttimestamp=`LANG=C date "+%s" -d "${lastmount}"`
  # Get current date as timestamp and add 10 minutes (time to stop+time to boot)
  nowtimestamp=`LANG=C date -d "+10 minutes" "+%s"`
  # Get current mount point
  mountpoint=`mount | grep -E "^${fs}" | sed 's/^.* on \(.*\) type .*$/\1/'`

 

 # Here we go...
  # State is not clean => fsck
  if [ "${state}" != "clean" ]; then
    needfsck=1
  fi
  # Current mount count >= maximum mount count => fsck
  if [ ${mountcount} -ge ${maximummountcount} ]; then
    needfsck=1
  fi
  # Current date +10minutes >= next check date => fsck
  if [ ${nowtimestamp} -ge ${nextchecktimestamp} ]; then
    needfsck=1
  fi
  # Last mount time in future => fsck
  if [ ${lastmounttimestamp} -gt ${nowtimestamp} ]; then
    needfsck=1
  fi
 
  # Print a warning and set global variable to 1
  if [ ${needfsck} -eq 1 ]; then
    echo "Device ${fs} mounted on ${mountpoint} will be checked at next boot."
    globalneedfsck=1
  fi
done

 

# Global warning and confirmation question
if [ ${globalneedfsck} -eq 1 ]; then
  echo
  echo "At least one filesystem will be check at next boot."
  echo "Are you sure you want to continue? (N/y)"
  read answer
  case ${answer} in
    y* | Y* )
      # Exec parameters
      exec "$@"
    ;;
  esac
# No fsck needed, run the command passed as argument
else
  exec "$@"
fi

 

A vos feedbacks ! :)


Message édité par M300A le 30-06-2010 à 09:56:51

---------------
:wq
Reply

Marsh Posté le 29-06-2010 à 10:39:05   

Reply

Marsh Posté le 29-06-2010 à 19:37:40    

J'ai encore vécu ce phénomène il y a deux jours mais d'un autre  coté je m'y attends désormais :)


---------------
Intermittent du GNU
Reply

Marsh Posté le 29-06-2010 à 19:46:37    

C'est un peu brutal comme méthode (c'est pas pour rien qu'un fsck est programmé et lancé), mais merci pour l'astuce :jap:

Reply

Marsh Posté le 29-06-2010 à 20:47:57    

:hello:  
 
 
Concernant cette partie du code :

# Check currently mounted ext2/3/4 filesystems
for fs in `mount | grep -E ' ext[345] ' | cut -d' ' -f1`; do


Ce serait pas plutôt :

# Check currently mounted ext2/3/4 filesystems
for fs in `mount | grep -E ' ext[234] ' | cut -d' ' -f1`; do


?
 
 
Bonne idée ce script, j'y vois surtout un net intérêt sur tous les périphs mobiles où des fsck indésirables ont toujours tendance à s'exécuter lorsqu'on à besoin de démarrer rapidement.  :)  
 
Sinon au boulot, sur les machines qu'on administre, on laisse en général le fsck s'exécuter (d'autant plus vrai avec lors de reboot de machines qui ont un uptime prolongé) ; du point de vue des clients importants, le service est de toute façon redondé, ce qui passe inaperçu. Après, pour les cas particuliers, ça se zappe soit à coup de tune2fs, soit en mettant temporairement le champ 'pass' à 0 dans /etc/fstab pour les fs qui ne doivent pas être vérifiés lors d'un reboot ponctuel.
 
Pour les plus gros volumes (dizaines de To et plus), comme sur les serveurs de stockage/sauvegarde, on utilise quasi-systématiquement du XFS, notamment en raison de cet aspect là. J'imagine qu'avec l'ext4 c'est un peu moins problématique maintenant, mais bon j'ai pas encore eu l'occasion de le tester sérieusement avec de large volumes de données.


---------------
THRAK (def.) : 1) A sudden and precise impact moving from intention, direction and commitment, in service of an aim. 2) 117 guitars almost striking the same chord simultaneously.
Reply

Marsh Posté le 30-06-2010 à 09:52:56    

Bien vu THRAK pour la typo :p
 
Ça n'a rien de brutal, ça permet juste de prévenir pour éventuellement délayer le reboot.
Sinon +1, j'utilise globalement XFS presque partout...


---------------
:wq
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed