Berny's Knowledgebase als Newsfeed

Wenn eine Datei gelöscht wird, ist die Erwartungshaltung der meisten User, dass der Plattenplatz, den diese belegt sofort freigegeben wird und wieder für anderweitige Nutzung zur Verfügung steht - in den meisten Fällen ist das auch so.

Anders sieht es nur dann aus, wenn die Datei noch von einem Prozess geöffnet ist (d. h. irgendein Prozess hat noch ein Filehandle auf diese Datei). Dann wird nur der Eintrag im Verzeichnis (also in dem Directory, das die Datei enthält) entfernt, die Datei selbst bleibt aber ansonsten unverändert im Filesystem liegen. Der Prozess, der sie geöffnet hat, kann weiterhin alle Inhalte lesen oder auch weiterhin schreiben. Die gelöschte Datei kann also sogar noch wachsen und zusätzlichen Platz verbrauchen.

Die Ausgabe der Kommandos df und du scheint in so einem Fall nicht mehr zusammen zu passen.

Ausgabe von df und du

Normalfall

root@dunno ~ # df -h /mnt/zbv
Filesystem   Size  Used Avail Use% Mounted on
/dev/sdb1    2.0G  1.1G  807M  57% /mnt/zbv
root@dunno ~ # du -sh /mnt/zbv
1.1G  /mnt/zbv
root@dunno ~ # ls -l /mnt/zbv
total 1048596
-rw-r--r-- 1 root root 1073741824 Mar  7 15:02 junkfile.001
drwx------ 2 root root      16384 Mar  7 15:00 lost+found/

df sagt: 2 GB Filesystem, etwas mehr als 1 GB belegt, etwas weniger als 1 GB frei.

du sagt: In /mnt/zbv/ sind Dateien, die insgesamt etwas mehr als 1 GB belegen.

Also: Sieht alles ganz normal aus.

Mit gelöschten, noch geöffneten Dateien

root@dunno ~ # df -h /mnt/zbv
Filesystem   Size  Used Avail Use% Mounted on
/dev/sdb1    2.0G  1.1G  807M  57% /mnt/zbv
root@dunno ~ # du -sh /mnt/zbv
20K /mnt/zbv
root@dunno ~ # ls -l /mnt/zbv
total 16
drwx------ 2 root root 16384 Mar  7 15:00 lost+found/

Ausgabe von df unverändert im Vergleich zu oben, aber du sagt: In /mnt/zbv/ sind Dateien, die insgesamt 20 kB belegen.

Wie kann das sein?

Gelöschte, noch geöffnete Dateien finden

Mit dem Kommandozeilentool lsof (list open files) können wir uns grundsätzlich alle gerade offenen Filehandles anzeigen. Wenn wir das Tool ohne Parameter aufrufen, bekommen wir auf einem Standard-Linux-System für gewöhnlich eine extrem lange Liste. Es sollten also sinnvollerweise Optionen angegeben werden, um die Liste zu filtern.

lsof +L1

zeigt alle offenen Dateien, deren Link-Count kleiner als 1 ist, also Dateien, die in keinem Verzeichnis mehr eingetragen sind. Oder kurz: Die inzwischen gelöscht wurden.

Wenn wir uns nur für die Dateien in einem bestimmten Filesystem interessieren, können wir die Ausgabe weiter einschränken:

lsof -a +L1 /var

Der Parameter -a sagt lsof, dass die nachfolgenden Bedingungen mit einem AND zu verknüpfen sind. Es sollen also nur Treffer angezeigt werden, die beide Bedinungen erfüllen. (Ohne den Parameter macht lsof eine OR Verknüpfung, aber das ist nicht das was wir wollen.

Warning
Vorsicht:

Wenn lsof als nicht-privilegierter Benutzer ausgeführt wird, können nur die Filehandles angezeigt werden, auf die der Benutzer auch Berechtigungen hat. Um wirklich alle Dateien zu finden, muss der Befehl als root ausgeführt werden.

Analyse im Beispiel von oben

root@dunno ~ # lsof -a +L1 /mnt/zbv
COMMAND    PID   USER   FD  TYPE DEVICE   SIZE/OFF NLINK NODE NAME
keep-file 9460 booboo   3r  REG  254,4  1073741824     0   12 /mnt/zbv/junkfile.001 (deleted)

lsof zeigt uns: Unser /mnt/zbv/junkfile.001 wurde inzwischen gelöscht, ist aber noch geöffnet von einem Prozess mit der PID 9460, der dem User booboo gehört.

Je nachdem, was uns wichtiger ist - der Prozess oder der Plattenplatz - können wir den Prozess am Leben lassen oder eben beenden bzw. killen.

root@dunno ~ # kill 9460
root@dunno ~ # du -sh /mnt/zbv
20K /mnt/zbv
root@dunno ~ # df -h /mnt/zbv
Filesystem  Size  Used Avail Use% Mounted on
/dev/sdb1   2.0G  3.0M  1.8G   1% /mnt/zbv

Jetzt hat niemand mehr ein offenes Filehandle und der Platz ist wieder anderweitig nutzbar.