Re: /kernel: handle_workitem_freeblocks

From: Oliver Fromme <olli(at)secnetix.de>
Date: Tue, 21 May 2002 20:05:15 +0200 (CEST)

Stefan Weißwange <sweisswange(at)gmx.de> wrote:
> Oliver Fromme schrieb:
> > > $ echo "" > ipmon.log
> >
> > Warum genau tust Du das? Daß man so keine Logfiles kürzen
> > kann, ist Dir klar, oder ...?
>
> Jetzt schon ;-) Ich hab's halt so gemacht, weils auch nie damit Probleme
> gab, aber wenn das so nicht geht, wie gehts dann "richtig"? Wie gesagt,
> ich bin relativ neu im FreeBSD und dachte mir, wenn ich die Datei so
> leere, dürfte es keine Probleme geben.

Das ist jetzt nicht FreeBSD-spezifisch, sondern ist bei
UNIX generell so.

Wenn ein Prozeß eine Datei geöffnet hält (z.B. eine Log-
Datei), dann ist es ihm relativ egal, was andere Prozesse
mit dieser Datei anstellen. Wenn er einen open()-syscall
macht, erhält er einen Filehandle für die Datei, der ver-
schiedene Eigenschaften für den Zugriff auf diese Datei
enthält, z.B. den inode die Position im Filesystem und den
Filepointer (d.h. bei welchem Offset in der Datei der näch-
ste Schreibzugriff passiert).

Wenn Du jetzt ein »echo "" > Logdatei« machst, dann macht
die Shell zuerst ein truncate() auf die Datei, um sie auf
0 Bytes zu kürzen, dann erzeugt das »echo ""« ein Newline,
das an den Anfang der Datei geschrieben wird. Theoretisch
müßte die Datei jetzt ein Byte groß sein (eine Leerzeile).

Das alles kümmert aber unseren Prozeß nicht, der die Datei
immer noch geöffnet hält. Weder das truncate() noch der
Schreibzugriff durch das echo haben an seinem Handle etwas
geändert (logisch), und sein Filepointer zeigt immer noch
an die alte Position. Wenn jetzt dieser Prozeß eine wei-
tere Zeile in das Logfile schreibt, landet diese nicht
etwa an Byte 1 (hinter dem Newline), sondern natürlich
dort, wo sein Filepointer (immer noch) hinzeigt, irgendwo
weiter hinten. Zwischen Byte 1 und dieser Schreibposition
entsteht eine Lücke.

Diese Lücke belegt keinen physikalischen Platz auf der
Festplatte, solange keine Daten hineingeschrieben werden.
Wenn man aus der Lücke liest, erzeugt der Kernel »künstli-
che« Nullbytes. Dateien mit solchen Lücken werden »sparse
files« genannt. Du kannst so ein »sparse file« leicht
selbst erzeugen; einfach mal eingeben:

truncate -s 1000G foobar
ls -l foobar

Genauso wirkungslos wäre es übrigens, die Datei zu löschen
(mit rm oder wie auch immer). Solange mindestens ein Pro-
zeß die Datei geöffnet hält, bleibt sie auf der Platte,
auch wenn sie im Verzeichnislisting nicht mehr erscheint.

Richtig wird es so gemacht, daß man die Datei umbenennt
(z.B. »mv bla.log bla.log.0«) und dann dafür sorgt, daß der
Prozeß sie schließt und neu öffnet. Manche Programme tun
dies, wenn man ihnen ein SIGHUP schickt, ansonsten muß man
sie halt killen und neustarten.

Gruß
   Olli

PS: Vielleicht hängt die Kernel-Panic indirekt mit der
(versehentlichen) Erzeugung eines Sparse-files in Verbin-
dung mit Soft-updates zusammen. Das ist aber jetzt nur
geraten; das müßte jemand untersuchen, der mit dem Code
vertraut ist.

-- 
Oliver Fromme, secnetix GmbH & Co KG, Oettingenstr. 2, 80538 München
Any opinions expressed in this message may be personal to the author
and may not necessarily reflect the opinions of secnetix in any way.
"All that we see or seem is just a dream within a dream" (E. A. Poe)
To Unsubscribe: send mail to majordomo(at)de.FreeBSD.org
with "unsubscribe de-bsd-questions" in the body of the message
Received on Tue 21 May 2002 - 20:05:17 CEST

search this site