Retour à l'accueil

df du diffèrent : trouver les fichiers supprimés Linux

Sous Linux l'écart df et du est dû aux fichiers supprimés retenus par les descripteurs de processus ouverts. L'article explique la mécanique des inodes, la recherche via lsof +L1 et la libération d'espace avec > /proc/PID/fd/FD sans redémarrage. Recommandations sur logrotate copytruncate et la surveillance.

df ment ? Non, recherche de fichiers supprimés dans lsof
Advertisement 728x90

Pourquoi df et du divergent : Découvrir les gigaoctets cachés sur Linux

La commande df -h indique 95 % d'utilisation du disque, tandis que du -sh /* ne totalise que 20 %. Les 75 % restants sont invisibles pour du mais occupent des blocs de disque. La raison en est les descripteurs de fichiers ouverts par des processus pointant vers des fichiers supprimés. df lit directement le superbloc du système de fichiers, du parcourt l'arborescence des répertoires et ignore les fichiers sans entrée dedans.

Un inode stocke les métadonnées du fichier, y compris la liste des blocs de données. rm ne supprime que l'entrée du répertoire (lien physique), le compteur de liens de l'inode diminue, mais si un processus détient un descripteur, les blocs restent alloués.

Diagramme :

Google AdInline article slot
Avant rm :
répertoire        inode          blocs
/var/log/  --> app.log  -->  [bloc1][bloc2]
               ^
               descripteur nginx (pid 1234, fd 7)

Après rm :
répertoire        inode          blocs
/var/log/  --> (supprimé) -->  [bloc1][bloc2]
               ^
               descripteur nginx

du ne voit pas le fichier dans /var/log/, df enregistre les blocs occupés.

Cas classiques du problème

Rotation des logs : logrotate effectue rm sur un ancien fichier, mais nginx ou java détient un descripteur depuis le démarrage. Le processus écrit dans le fichier supprimé, df enregistre une utilisation accrue, du non.

Autres scénarios :

Google AdInline article slot
  • Démon à longue durée de vie avec des logs ouverts.
  • Bogues dans les scripts de nettoyage où rm précède la fermeture du descripteur.
  • Conteneurs Docker où des processus internes détiennent des fichiers de l'hôte.

Le problème s'accumule : des gigaoctets disparaissent sans être remarqués jusqu'à ce que le disque soit plein.

Trouver les processus avec des fichiers supprimés

Utilisez lsof +L1 pour les fichiers avec NLINK < 1 (supprimés du système de fichiers mais ouverts) :

COMMANDE  PID  UTILISATEUR  FD  TYPE  PÉRIPHÉRIQUE  TAILLE/OFFSET  NLINK  NŒUD  NOM
nginx   1234  www   7w  REG   8,1  2147483648  0  12345  /var/log/app.log (supprimé)
java    5678  app   3w  REG   8,1   536870912  0  67890  /var/log/service.log (supprimé)

Champs clés :

Google AdInline article slot
  • COMMANDE/PID : processus et identifiant.
  • FD : descripteur (7w — écriture, numéro 7).
  • TAILLE/OFFSET : taille — source des Go perdus.
  • NLINK=0 : confirmation de la suppression.
  • NOM (supprimé) : chemin avant rm.

Filtre de taille : lsof +L1 | awk '$7 > 104857600 {print}' (fichiers >100 Mo).

Libérer de l'espace sans redémarrer

Pour le processus PID 1234, FD 7 :

$ > /proc/1234/fd/7

/proc est procfs en mémoire. La commande met le fichier à zéro via le descripteur, le noyau libère les blocs instantanément. df se met à jour, le processus continue d'écrire dans fd 7.

Vérification : lsof +L1 | grep 1234 — TAILLE/OFFSET=0 ou vide.

Automatisation par script :

#!/bin/bash
lsof +L1 | awk '$7 > 104857600 && $9 ~ /supprimé/ {print $2, $8}' | while read pid fd; do
  echo "Mise à zéro de $pid/$fd"
  > /proc/$pid/fd/$fd
  echo "Espace libéré"
done

Prévenir le problème dans logrotate

Évitez rm dans la rotation. Dans /etc/logrotate.d/app :

/var/log/app.log {
    quotidien
    rotation 7
    compression
    copytruncate
}

copytruncate copie le log, puis tronque l'original (mécanisme >). Le descripteur ne change pas.

Inconvénient : micro-délai de copie — perte possible de lignes.

Alternative sans perte :

  • logrotate : mv ancien → nouveau fichier.
  • kill -HUP <pid> (SIGHUP pour réouverture des logs).

nginx : nginx -s reopen. systemd : systemctl reload nginx.

Surveillance et alertes

Script de vérification :

lsof +L1 -F s | awk '/^s/ && substr($0,2)+0 > 104857600 {count++} END {print count+0}'

Affiche le nombre de fichiers supprimés >100 Mo.

Intégration Prometheus :

  • node_filefd_allocated — croissance des fd ouverts.
  • Comparer df/disk_used vs somme du.

Cron toutes les 5 min : alerte si écart >10 %.

Points clés à retenir

  • df montre les blocs alloués depuis le superbloc, du montre les fichiers visibles dans le répertoire.
  • lsof +L1 trouve les processus avec des fichiers (supprimés) par NLINK=0.
  • Libérer de l'espace : > /proc/PID/fd/FD — mise à zéro sans redémarrage.
  • logrotate copytruncate prévient le problème sans HUP.
  • Surveillance : scripts avec lsof ou métriques node_exporter.

— Editorial Team

Advertisement 728x90

Lire ensuite