grim7reaper

Un artisan du code

À la recherche de l’espace (disque) perdu…

La semaine dernière j’ai aidé à résoudre un problème assez surprenant : une partition racine pleine selon df (ou dfc) :

df -h
FILESYSTEM               (=) USED      FREE (-)  %USED AVAILABLE  TOTAL MOUNTED ON
[…]
/dev/dm-0                [====================]   100%     15.6G  15.6G /
[…]

Mais lorsque l’on essaye de trouver les coupables via ncdu, la somme est loin de faire 16Go :

ncdu -x
    .   3.8GiB [##########] /var
        1.2GiB [###       ] /srv
      885.2MiB [##        ] /opt
      223.0MiB [          ] /lib
    .  95.4MiB [          ] /etc
    […]

Surprenant !

Les fichiers perdus dans les limbes

Après réflexion, je me suis souvenu que certains fichiers pouvaient rester bloqués dans les limbes. En effet, il faut savoir que, sous Linux, quand un fichier est supprimé (avec rm par exemple), il n’est pas réellement supprimé tant qu’au moins un processus utilise ledit fichier. Par conséquent, même si le fichier n’est plus affiché par ls ou find, il occupe toujours de l’espace sur le disque.

Pour lister ces fichiers, on ne peut pas utiliser les commandes habituelles telles que ls ou find, mais on peut utiliser lsof qui est une commande qui liste les fichiers ouverts (lsof => list open files). La sortie de lsof est très verbeuse, heureusement en lisant sa page de manuel (man 8 lsof) on y trouve l’option L qui peut être suivi d’un nombre. Lorsque L est suivi d’un nombre N, lsof va uniquement lister les fichiers qui sont référencé un nombre de fois strictement inférieur à N. Dans notre cas, comme on veut lister les fichiers supprimés (qui ne sont donc plus référencés) il faut utiliser L1 pour lister les fichier ayant 0 référence.

En combinant lsof +L1 avec la commande sort on peut trier par taille pour voir quels sont les fichiers occupant le plus de place.

La commande finale est donc lsof -s +L1 | sort -nk7 ce qui se traduit par : liste (lsof) la taille (-s) de tout les fichiers supprimés et encore ouvert (+L1) et trie (sort) cette liste de manière numérique (-n) sur le champs 7 (-k7, car c’est le septième champs qui est le champ de la taille).

Exemple de sortie
% lsof -s +L1 | sort -nk7

COMMAND  PID        USER   FD   TYPE DEVICE    SIZE NLINK    NODE NAME
conky   5372 grim7reaper    0u   CHR 136,16             0      19 /dev/pts/16 (deleted)
conky   5372 grim7reaper    1u   CHR 136,16             0      19 /dev/pts/16 (deleted)
conky   5372 grim7reaper    2u   CHR 136,16             0      19 /dev/pts/16 (deleted)
systemd  709 grim7reaper  txt    REG  254,2 1018520     0 1619496 /usr/lib/systemd/systemd (deleted)

Cette commande a permis de découvrir que l’espace disque était utilisé par des fichiers temporaires de Terminator.

Terminator et libVTE

Reste à savoir pourquoi Terminator utilise autant d’espace disque.

Tout d’abord il faut savoir que le Terminator en cause ici était configuré pour conserver toutes les sorties des terminaux, sans limite (option Inifinite scrollback). Le problème c’est que les buffers des terminaux sont stockés sur disques et donc que plus les terminaux sont utilisés longtemps et plus il y’a de choses affichées dedans, plus l’espace disque occupé va augmenter.

Ce comportement ne vient pas de Terminator lui-même, mais de la libVTE qui est une bibliothèque utilisée pour implémenter des émulateurs de terminaux. Ce bug touche donc tout les terminaux basés sur libVTE (Terminator, Gnome-Terminal, xfce4-terminal, guake, …).

Ce comportement existe depuis 2009, il est connu et ne sera probablement pas corrigé, alors même que cela peut poser problème (je vous conseille de lire ce rapport de bug qui explique bien la situation)…

Conclusion

Je pense que je vais continuer d’utiliser urxvt :D, qui est l’un des rares terminaux à bien gérer l’espace insécable fine et qui n’est pas basé sur libVTE. Cette petite mésaventure m’aura au moins fait découvrir un aspect fort utile de lsof.