Ich versuche also herauszufinden, ob die Ausführung stderr
eines Prozesses an eine ungewöhnliche Stelle umgeleitet wurde (es handelt sich um einen Java-Prozess und ich möchte einen Thread-Dump, aber er wird über eine Reihe von Startskripten gestartet).
Ich finde meinen Prozess mit pgrep
und verwende, pfiles
um zu sehen, was da ist:
4366: /foo/bar/platform/solaris2/jre_1.5.0/bin/java -Xmx2048m -Xms10 Aktuelles rlimit: 65536 Dateideskriptoren 0: S_IFCHR-Modus:0666 dev:302,0 ino:6815752 uid:0 gid:3 rdev:13,2 O_RDONLY|O_LARGEFILE /Geräte/Pseudo/mm@0:null 1: S_IFREG-Modus:0640 dev:85,56 ino:26471 uid:0 gid:0 Größe:10485812 O_WRONLY|O_LARGEFILE 2: S_IFREG-Modus: 0640 dev: 85,56 ino: 26471 uid: 0 gid: 0 Größe: 10485812 O_WRONLY|O_LARGEFILE 3: S_IFCHR-Modus:0666 dev:302,0 ino:6815772 uid:0 gid:3 rdev:13,12
Ich sehe also, dass stdout
und stderr
(Dateideskriptoren 1 und 2) auf die gleiche Stelle verweisen. Ich denke, sie werden in den Startskripten auf die gleiche Datei umgeleitet, also passt das zusammen.
Aber wenn ich nach einer Datei mit der Inode-Nummer 26471 suche, sehe ich Folgendes:
# finden / -inum 26471 /usr/share/man/man3mlib/mlib_MatrixScale_S16_U8_Sat.3mlib /proc/4366/fd/1 /proc/4366/fd/2 /proc/4366/fd/83
Der erste Treffer ist (da bin ich mir sicher) eine Datei auf einem anderen Dateisystem. Die drei Einträge darin /proc
sind FDS, die mein Prozess geöffnet hat.
Wenn ich hineinschaue /proc/4366
, kann ich nicht mehr Informationen sehen, als ich von bekomme pfiles
.
# ls -li 0 1 2 3 6815752 c--------- 1 Root-System 13, 2. Januar 20 14:10 0 26471 --w------- 0 root root 10485812 20. Januar 13:42 1 26471 --w------- 0 root root 10485812 Jan 20 13:42 2 6815772 c--------- 1 root sys 13, 12 7. Juni 2009 3 # Datei 0 1 2 3 0: Charakter Spezial (13/2) 1: ASCII-Text 2: ASCII-Text 3: Charakter Spezial (13/12)
(Ich kann eines dieser FDS verfolgen und daraus ableiten, um welche Datei es sich handelt. Ich frage, weil ich die Beziehung zwischen den FDS und den Inodes offensichtlich nicht gründlich genug verstehe.)
Mein Prozess besteht also darin, zu schreiben anetwas(auf einigen Geräten mit Inode 26471) und die Daten gelangen dann in eine Datei mit einer anderen Inode-Nummer. Kann mir jemand eine Idee geben, was dieses Etwas sein könnte (oder mir sogar sagen, ob meine Argumentation bisher völlig falsch ist)?
Antwort1
Soweit ich weiß, find
werden die Verzeichnisse des Dateisystems durchsucht. Wenn die Datei gelöscht wurde, aber noch existiert, weil sie geöffnet ist (ein gängiger Trick unter Unix), wird sie nicht gefunden find
.
Ich habe es nicht in Solaris versucht, aberHierist ein Hinweis zur Verwendung lsof
zur Identifizierung solcher 'gelöschten, aber offenen' Dateien und zur Wiederherstellung über einecat /proc/<procid>/fd/<fdid> > /tmp/xxxx
Bearbeiten:
Sie haben anscheinend bereits erkannt, dass dies der Fall ist, fragen sich aber immer noch, wie das möglich ist. Hier eine kurze Erklärung:
Auf POSIX-Dateisystemen werden Dateien von ihm verwaltet inode
und die Verzeichnisse sind kaum mehr als eine „Pfad => Inode“-Zuordnung. Sie können mehr als einen Pfad haben, der auf denselben Inode „zeigt“ (dies wird als Hardlink bezeichnet), und der Inode zählt, wie viele Links er hat. Der rm
Befehl ruft einfach unlink()
diesen Pfad auf, wodurch die Anzahl der Links reduziert wird und die Datei „möglicherweise“ selbst gelöscht wird.
Ein Pfad im Verzeichnisbaum ist jedoch nicht die einzige mögliche Referenz auf einen Inode. fd
Auch das Öffnen eines laufenden Prozesses zählt, und eine „gelöschte“ Datei wird erst dann wirklich entfernt, wenn sie auf 0 zurückgesetzt wird.
Wie ich oben nebenbei erwähnt habe, handelt es sich um einen gängigen Trick: Wenn Sie eine temporäre Datei haben, die Sie nach Abschluss Ihres Prozesses nicht behalten möchten, öffnen Sie sie einfach und „löschen“ Sie sie sofort. Der geöffnete Handle funktioniert zuverlässig, und wenn Ihr Prozess beendet wird (entweder normal, beendet oder abgestürzt), entfernt das System den Handle und löscht die temporäre Datei sauber.
Eine Protokolldatei ist kein wahrscheinlicher Kandidat für eine solche „versteckte, automatisch gelöschte“ Datei, aber es passiert schnell, dass dies versehentlich passiert.
Da Ihre gelöschte Protokolldatei noch aktiv ist und Daten sammelt, scheint es nicht viel zu helfen, den Inhalt einfach zu kopieren. Versuchen Sie also, einen neuen Hardlink zur Datei /proc//fd/ zu erstellen, etwa wie ln /proc/4366/fd/1 /tmp/xxxx
. Beachten Sie -s
, dass es kein Flag ln
gibt. Sie sollten also einen neuen Hardlink mit demselben Inode wie das Original erstellen und keinen symbolischen Link (der kaum mehr als ein Zeiger auf einen vorhandenen Pfad ist und nicht das, was Sie wollen).
Bearbeiten:
Der ln /proc/... /tmp/...
Befehl kann nicht funktionieren, da /proc und /tmp in unterschiedlichen Dateisystemen liegen. Leider kenne ich keine Möglichkeit, einen Pfadnamen für einen vorhandenen Inode zu erstellen. Man würde sich wünschen, dass der link()
Systemaufruf eine Inode-Nummer und einen Pfad annimmt, aber er nimmt Quell- und Zielpfade an.