Photographie
[UNIX] Le fichier fantome
Le fichier fantôme se manifeste souvent par le fait qu’il occupe 100% d’un filesystem mais on n’arrive pas à le voir. Parfois même le filesystem semble vide. En général il s’agit d’un fichier ouver par un process mais qui a été effacé du FS, par la commande rm par exemple. Ce phénomène s’explique par le fait que unix autorise de supprimer un fichier (en réalité il se contente de supprimer la référence vers ce fichier dans la structure du FS) alors que le fichier est encore utilisé par un process. Il n’est donc en pratique pas libéré physiquement.
Comment donc allons nous faire pour récupérer la place ?
Exemple:
[vincent@sauron 23:22 /u01/FS1] df -k .
Filesystem 1K-blocks Used Available Use% Mounted on
/u01/Tests/FS1.dd 4838 4838 0 100% /u01/FS1
[vincent@sauron 23:25 /u01/FS1] sudo du -sk .
13 .
[vincent@sauron 23:22 /u01/FS1] ls -la
total 21
drwxr-xr-x 3 root root 1024 2008-11-09 23:22 .
drwxr-xr-x 12 root root 4096 2008-11-09 20:52 ..
drwx------ 2 root root 12288 2008-11-09 20:51 lost+found
La solution du débutant:
Le linuxien de base aura à peine compris l’explication ci dessus, mais suffisamment pour proposer une solution: reboot. Ca marchera, mais on aura besoin d’arrêter une machine qui pourrait être critique, et on génère une interruption de service.
L’admin système:
Il a compris qu’un process utilise le fichier, et c’est cela qui empeche le FS de libérer la place. Il faut donc tuer ce process. Le hic, comment identifier le process fautif ?
la commande lsof peut nous aider, en effet elle liste l’ensemble des fichiers ouverts d’un systeme. En outre elle a le bon goùt de marquer lorsqu’un fichier a été supprimé:
[vincent@sauron 23:34 /u01/FS1] lsof|grep deleted
critique. 28564 vincent 3w REG 7,0 3849208 12 /u01/FS1/fichier.log (deleted)
[vincent@sauron 23:35 /u01/FS1] ps -ef | grep 28564
vincent 28564 28420 0 23:19 pts/3 00:00:00 /usr/bin/perl ./critique.pl /u01/FS1/fichier.log
On a retrouvé le fichier, un bête fichier de log. On a aussi le process fautif: critique.pl, mais comme son nom l’indique, il est critique, on ne peut donc pas le tuer immédiatement. J’ai longtemps cru qu’on était bloqué ici, mais un collègue m’a montré que non.
Le Gourou:
La solution a ce problème permet à la fois de se passer de lsof (il n’est pas disponible partout, en particulier sur les Solaris) et de répondre à la question de place, en tronquant le fichier.
L’astuce consiste à interroger directement les structures du noyau en passant par le pseudo FS /proc, chaque process y a en effet son entrée, ainsi que la liste des fichiers qu’il a ouverts. L’autre partie de l’astuce consiste à comprendre qu’un fichier effacé se caractérise par le fait d’avoir son nombre de liens à 0.
[root@sauron 23:50 ~] find -L /proc/*/fd -links 0 -ls
find: `/proc/1087/fd/3': Not a directory
423618 0 -rw-r--r-- 0 root root 0 Nov 8 18:20 /proc/1272/fd/14
423618 0 -rw-r--r-- 0 root root 0 Nov 8 18:20 /proc/25990/fd/14
423618 0 -rw-r--r-- 0 root root 0 Nov 8 18:20 /proc/25991/fd/14
423618 0 -rw-r--r-- 0 root root 0 Nov 8 18:20 /proc/25992/fd/14
423618 0 -rw-r--r-- 0 root root 0 Nov 8 18:20 /proc/25994/fd/14
423618 0 -rw-r--r-- 0 root root 0 Nov 8 18:20 /proc/25998/fd/14
12 3775 -rw-r--r-- 0 vincent root 3849208 Nov 9 23:02 /proc/28564/fd/3
Seul le fichier /proc/28564/fd/3 mérite notre attention a cause de sa taille. En outre on peut vérifier sa nature:
[root@sauron 23:52 ~] ls -l /proc/28564/fd/3
l-wx------ 1 vincent vincent 64 2008-11-09 23:19 /proc/28564/fd/3 -> /u01/FS1/fichier.log (deleted)
Et maintenant, grace à l’entrée dans /proc on peut le tronquer:
[root@sauron 23:52 ~] cat /dev/null > /proc/28564/fd/3
[root@sauron 23:54 ~] df -k /u01/FS1
Filesystem 1K-blocks Used Available Use% Mounted on
/u01/Tests/FS1.dd 4838 1063 3525 24% /u01/FS1
Merci à Arnaud CORNET à qui je dois cette astuce. J’ajoute que cette astuce marche également avec /proc de solaris.
| Print article | This entry was posted by Vincent on 10 November 2008 at 1:01, and is filed under Linux, SUN, Solaris. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |
English
about 1 year ago
Très joli! Je la note dans mes tablettes, celle-là …
about 1 year ago
Bonjour,
merci pour le tuto, très utile!
Cependant, sous Solaris, il ne semble pas possible de tronquer le fichier, de plus, les fd ne sont pas des liens comme dans ton exemple.
1 – J’ai fait un test en perl qui écrit sans fin dans un fichier en paramètre.
2 – Je supprime ce fichier,
3 – Il est toujours présent sous /proc/PID/fd/3 et commence à faire quelques méga!
–w——- 1 user group 150M Nov 12 16:00 3
4 – je tente cat /dev/null > /proc/PID/fd/3
5 – Le fichier n’a pas rétréci…
Je suis preneur pour un “workaround”
A noter qu’après le rm, le nombre de lien est toujours à 1!
Merci,
Bonne continuation!
Pierrick
about 1 year ago
Re-Bonjour
,
au temps pour moi…A présent ça marche!
Merci pour le tuyau!
Cdlt,
about 1 year ago
@daniel: j’insiste, elle n’est pas de moi, mais effectivement je l’ai trouvée tellement bien que je n’ai pas pu résister à la partager.
Même le Pat’ n’y avait pas pensé.