Vérification disques démarrage Ubuntu : Différence entre versions
m |
(Aucune différence)
|
Version actuelle en date du 25 avril 2016 à 17:25
Sur une plateforme Ubuntu, les disques peuvent être automatiquement vérifiés lors d'un démarrage de la plateforme. Lors d'une connexion ssh, l'utilisateur est averti lors qu'une vérification sera effectuée lors du prochain redémarrage.
Cependant, il a été constaté que ce message continuait à être affiché même après des redémarrage. Cet article tente de présenter les mécanismes mis en place, sur une version 15.04
.
Le message affiché est le suivant.
*** /dev/sda10 will be checked for errors at next reboot *** *** /dev/sda1 will be checked for errors at next reboot ***
Votre avis
Nobody voted on this yet
|
|
Etude
Dans un premier, il est nécessaire de comprendre le mode de fonctionnement de ces vérifications. Lors de la connexion d'un utilisateur en ssh, les scripts dans le répertoire /etc/update-motd.d
sont exécutés. Il existe le script 98-fsck-at-reboot
.
#!/bin/sh
if [ -x /usr/lib/update-notifier/update-motd-fsck-at-reboot ]; then
exec /usr/lib/update-notifier/update-motd-fsck-at-reboot
Celui-ci exécute donc le script /usr/lib/update-notifier/update-motd-fsck-at-reboot
dont le contenu est le suivant.
#!/bin/sh
# Authors:
# Mads Chr. Olesen <mads@mchro.dk>
# Kees Cook <kees@ubuntu.com>
set -e
# poor mans force
if [ "$1" = "--force" ]; then
NEEDS_FSCK_CHECK=yes
fi
# check time when we did the last check
stamp="/var/lib/update-notifier/fsck-at-reboot"
if [ -e "$stamp" ]; then
stampt=$(stat -c %Y $stamp)
else
stampt=0
fi
# check time when we last booted
last_boot=$(date -d "now - $(awk '{print $1}' /proc/uptime) seconds" +%s)
now=$(date +%s)
if [ $(($stampt + 3600)) -lt $now ] || [ $stampt -gt $now ] \
|| [ $stampt -lt $last_boot ]
then
#echo $stampt $now need update
NEEDS_FSCK_CHECK=yes
fi
# output something for update-motd
if [ -n "$NEEDS_FSCK_CHECK" ]; then
{
check_occur_any=
ext_partitions=$(mount | awk '$5 ~ /^ext(2|3|4)$/ { print $1 }')
for part in $ext_partitions; do
dumpe2fs_out=$(dumpe2fs -h $part 2>/dev/null)
mount_count=$(echo "$dumpe2fs_out" | grep "^Mount count:"|cut -d':' -f 2-)
if [ -z "$mount_count" ]; then mount_count=0; fi
max_mount_count=$(echo "$dumpe2fs_out" | grep "^Maximum mount count:"|cut -d':' -f 2-)
if [ -z "$max_mount_count" ]; then max_mount_count=0; fi
check_interval=$(echo "$dumpe2fs_out" | grep "^Check interval:" | cut -d':' -f 2- | cut -d'(' -f 1)
if [ -z "$check_interval" ]; then check_interval=0; fi
next_check_date=$(echo "$dumpe2fs_out" | grep "^Next check after:" | cut -d':' -f 2-)
if [ -z "$next_check_interval" ]; then next_check_interval=0; fi
next_check_tstamp=$(date -d "$next_check_date" +%s)
#echo "next_check_date=\"$next_check_date\" next_check_tstamp=\"$next_check_tstamp\""
#echo "part=\"$part\" mount_count=\"$mount_count\" / max=\"$max_mount_count\" "
check_occur=
# Check based on mount counts?
if [ "$max_mount_count" -gt 0 -a \
"$mount_count" -ge "$max_mount_count" ]; then
check_occur=yes
fi
# Check based on time passed?
if [ "$check_interval" -gt 0 -a \
"$next_check_tstamp" -lt "$now" ]; then
check_occur=yes
fi
if [ -n "$check_occur" ]; then
check_occur_any=yes
mountpoint=$(mount | grep "^$part" | cut -d ' ' -f 3)
pass=$(grep -v '^#' /etc/fstab | tr -s ' ' '\t' | cut -s -f 2,6 | grep -w "$mountpoint" | cut -f 2)
if [ "$pass" = "0" ]; then
echo "*** $part should be checked for errors ***"
else
echo "*** $part will be checked for errors at next reboot ***"
fi
fi
done
if [ -n "$check_occur_any" ]; then
echo ""
fi
} > $stamp
fi
# output what we have (either cached or newly generated)
cat $stamp
A ce stade, cela n'est pas très compréhensible. Mais il est globalement assez simple.
Dans un premier temps, des calculs sont réalisés pour savoir si la vérification doit être lancée ou si il suffit d'afficher le contenu du fichier /var/lib/update-notifier/fsck-at-reboot
.
Globalement, la vérification est réalisée si :
- La date de modification du fichier date de plus d'une heure;
- La date de modification du fichier est dans le futur (étonnant, mais pourquoi pas);
- La date de modification du fichier est antérieure à la dernière connexion.
Si tel est le cas, les vérifications sont réalisées pour chacune des partitions, listées à l'aide de la commande suivante.
ext_partitions=$(mount | awk '$5 ~ /^ext(2|3|4)$/ { print $1 }')
Pour l'analyse, nous prendrons comme exemple la patition /dev/sda10
.
Sur chacune des partitions, la commande dumpe2fs
est exécutée afin de récupérer un ensemble d'information pour la partition. Dans le cadre de cet exemple, elle peut produire quelque chose comme ceci.
Filesystem volume name: <none> Last mounted on: / Filesystem UUID: 4b116dd4-8bae-475f-9bf1-8344e5844a08 Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize Filesystem flags: signed_directory_hash Default mount options: (none) Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 5562368 Block count: 22234368 Reserved block count: 1111718 Free blocks: 21548758 Free inodes: 5530964 First block: 0 Block size: 4096 Fragment size: 4096 Reserved GDT blocks: 1018 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 8192 Inode blocks per group: 512 Flex block group size: 16 Filesystem created: Sun Dec 12 09:49:07 2010 Last mount time: Sat Apr 23 17:08:21 2016 Last write time: Sat Apr 23 17:08:16 2016 Mount count: 30 Maximum mount count: 30 Last checked: Fri Jul 17 00:11:26 2015 Check interval: 15552000 (6 months) Next check after: Tue Jan 12 23:11:26 2016 Lifetime writes: 98 GB Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 Required extra isize: 28 Desired extra isize: 28 Journal inode: 8 Default directory hash: half_md4 Directory Hash Seed: 7db1cabc-eba2-4095-bb2c-8a16a78ea693 Journal backup: inode blocks Fonctionalités du journal : journal_incompat_revoke Taille du journal : 128M Longueur du journal : 32768 Séquence du journal : 0x00044879 Début du journal : 1
Puis un ensemble d'extraction est réalisé sur ce résultat afin d'obtenir les informations utiles.
- Mount count;
- Maximum mount count;
- Check interval;
- Next check after;
Les instructions d'extraction sont un peu différente pour la valeur de Check interval
, mais cela produit le résultat suivant.
Paramètre | Valeur |
---|---|
Mount count | 30 |
Maximum mount count | 30 |
Check interval | 15552000 |
Next check after | Tue Jan 12 23:11:26 2016 |
Enfin deux conditions sont vérifiées pour savoir si une vérification doit être réalisée.
- Le nombre de montage réalisés est supérieurs ou égale au nombre maximum de montage "autorisés", si ce dernier n'est pas égal à 0;
- La date de prochaine vérification est inférieur à la date du jour, si la valeur de
check_interval
n'est pas également à 0.
Si tel est le cas, un message de vérification est construit en fonction d'une valeur récupérée depuis /etc/fstab
et en fonction de son point de montage avec les deux commandes suivantes.
mountpoint=$(mount | grep "^$part" | cut -d ' ' -f 3)
pass=$(grep -v '^#' /etc/fstab | tr -s ' ' '\t' | cut -s -f 2,6 | grep -w "$mountpoint" | cut -f 2)
Dans le cadre de cet article, le résultat des commandes est le suivant.
#mount | grep "^/dev/sda10" | cut -d ' ' -f 3 /
#grep -v '^#' /etc/fstab | tr -s ' ' '\t' | cut -s -f 2,6 | grep -w "/" | cut -f 2 1
La dernière nécessite peut être un peu plus de pas à pas pour bien comprendre.
#grep -v '^#' /etc/fstab proc /proc proc nodev,noexec,nosuid 0 0 UUID=4b116dd4-8bae-475f-9bf1-8344e5844a08 / ext4 errors=remount-ro 0 1 UUID=4fee39df-8166-4af3-8036-8bf48c59ddc7 /boot ext4 defaults 0 2 UUID=b11ca971-924e-45a0-9be9-59ce1efdc8ec /opt ext4 defaults 0 2 UUID=96d9be39-cc11-46f0-bf43-f451ff0eb9fc /srv ext4 defaults 0 2 UUID=ff94cff0-2e8e-449f-9473-da7caa63a93f /tmp ext4 defaults 0 2 UUID=8f557a3a-c4c8-4166-8e71-dd7451969a56 /usr ext4 defaults 0 2 UUID=de58b6c5-2e6f-4efe-8e09-6554d2457cf4 /var ext4 defaults 0 2 UUID=c86bebd8-c323-4f24-86e2-6a530e185595 none swap sw 0 0 #grep -v '^#' /etc/fstab | tr -s ' ' '\t' proc /proc proc nodev,noexec,nosuid 0 0 UUID=4b116dd4-8bae-475f-9bf1-8344e5844a08 / ext4 errors=remount-ro 0 1 UUID=4fee39df-8166-4af3-8036-8bf48c59ddc7 /boot ext4 defaults 0 2 UUID=b11ca971-924e-45a0-9be9-59ce1efdc8ec /opt ext4 defaults 0 2 UUID=96d9be39-cc11-46f0-bf43-f451ff0eb9fc /srv ext4 defaults 0 2 UUID=ff94cff0-2e8e-449f-9473-da7caa63a93f /tmp ext4 defaults 0 2 UUID=8f557a3a-c4c8-4166-8e71-dd7451969a56 /usr ext4 defaults 0 2 UUID=de58b6c5-2e6f-4efe-8e09-6554d2457cf4 /var ext4 defaults 0 2 UUID=c86bebd8-c323-4f24-86e2-6a530e185595 none swap sw 0 0 #grep -v '^#' /etc/fstab | tr -s ' ' '\t' | cut -s -f 2,6 /proc 0 / 1 /boot 2 /opt 2 /srv 2 /tmp 2 /usr 2 /var 2 none 0 #grep -v '^#' /etc/fstab | tr -s ' ' '\t' | cut -s -f 2,6 | grep -w "/" / 1 #grep -v '^#' /etc/fstab | tr -s ' ' '\t' | cut -s -f 2,6 | grep -w "/" | cut -f 2 1
La valeur de cette dernière instruction permet de spécialiser le message qui va être affichée.
- *** XXX should be checked for errors ***
- *** XXX will be checked for errors at next reboot ***
Une fois terminé, si aucun message n'a été construit, une chaîne vide est envoyée avec la commande echo
. Le résultat de ces vérification est redirigé dans le fichier /var/lib/update-notifier/fsck-at-reboot
.
Enfin, le contenu de ce dernier est affiché à l'aide de la commande cat
.
Anomalies
Affichage "infini"
Dans le cadre de cette installation, le message semblait ne jamais disparaître alors que des reboots étaient effectués. Ce cas, c'est produit pour le résultat de la commande dumpe2fs
suivant.
Filesystem volume name: <none> Last mounted on: /usr Filesystem UUID: 8f557a3a-c4c8-4166-8e71-dd7451969a56 Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize Filesystem flags: signed_directory_hash Default mount options: (none) Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 6111232 Block count: 24413696 Reserved block count: 1220684 Free blocks: 20928817 Free inodes: 5776669 First block: 0 Block size: 4096 Fragment size: 4096 Reserved GDT blocks: 1018 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 8192 Inode blocks per group: 512 Flex block group size: 16 Filesystem created: Sun Dec 12 09:48:17 2010 Last mount time: Sat Apr 23 22:21:49 2016 Last write time: Sat Apr 23 22:21:45 2016 Mount count: 31 Maximum mount count: 34 Last checked: Fri Jul 17 00:11:30 2015 Check interval: 15552000 (6 months) Next check after: Tue Jan 12 23:11:30 2016 Lifetime writes: 822 GB Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 Required extra isize: 28 Desired extra isize: 28 Journal inode: 8 First orphan inode: 1840531 Default directory hash: half_md4 Directory Hash Seed: 4ef0802d-d783-4dcb-be96-78865cad4031 Journal backup: inode blocks Fonctionalités du journal : journal_incompat_revoke Taille du journal : 128M Longueur du journal : 32768 Séquence du journal : 0x00e945e7 Début du journal : 1
Les extractions de valeur donnaient les informations suivantes.
Paramètre | Valeur |
---|---|
Mount count | 31 |
Maximum mount count | 34 |
Check interval | 15552000 |
Next check after | Tue Jan 12 23:11:30 2016 |
Pour une raison inconnue, malgré une date antérieure pour la prochaine vérification, celle-ci ne se déclenchait pas. Elle a été déclenchée qu'une fois que la valeur de Mount count
avait atteint celle de Maximum mount count
.
Erreur calcul
L'instruction suivante, permettant de récupérer le point de montage, peut poser un problème dans des cas particuliers.
mountpoint=$(mount | grep "^$part" | cut -d ' ' -f 3)
En effet, dans le cadre de cette installation, il y a les partitions /dev/sda1
et /dev/sda10
.
L'étude ci dessus donnait le résultat /
pour la partition /dev/sda10
, mais qu'en est il pour /dev/sda1
? Et bien, du fait de l'expression régulière, les résultats pour les deux vont être retournés, soit.
#mount | grep "^/dev/sda1" | cut -d ' ' -f 3 / /usr
Cela n'est potentiellement pas problématique. En effet la valeur, calculée à partir du point de montage, permet uniquement de spécialiser le message d'avertissement. Mais peut être que cette erreur entraîne d'autre problème.
Voir Aussi
Un bug a été levé avec cette description: https://bugs.launchpad.net/ubuntu/+source/update-notifier/+bug/1574707