Wenn ich das tue (in einer Bourne-ähnlichen Shell):
exec 3> file 4>&3 5> file 6>> file
Die Dateideskriptoren 3 und 4 haben dup()
dieselbe offene Dateibeschreibung (gleiche Eigenschaften, gleicher Versatz in der Datei ...) , da 4 von 3 abgeleitet wurde . Während sich die Dateideskriptoren 5 und 6 dieses Prozesses in einer anderen offenen Dateibeschreibung befinden (z. B. haben sie jeweils einen eigenen Zeiger in der Datei).
In der lsof
Ausgabe sehen wir nur:
zsh 21519 stephane 3w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 4w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 5w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 6w REG 254,2 0 10505865 /home/stephane/file
Es ist ein bisschen besser mit lsof +fg
:
zsh 21519 stephane 3w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 4w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 5w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 6w REG W,AP,LG 254,2 0 10505865 /home/stephane/file
(hier unter Linux 3.16) Da fd 6 unterschiedliche Flags hat, muss es sich um eine andere offene Dateibeschreibung handeln als fd 3, 4 oder 5, von der wir jedoch nicht sagen können, dass fd 5 auf a liegt andere offene Dateibeschreibung . Mit -o
könnten wir auch den Versatz sehen, aber der gleiche Versatz garantiert nicht, dass es die gleiche offene Dateibeschreibung ist .
Gibt es einen nicht-intrusive 1 Weg , das herauszufinden? Extern oder für eigene Dateideskriptoren eines Prozesses?
1 . Ein heuristischer Ansatz könnte darin bestehen, die Flags einer FD zu ändern fcntl()
und zu sehen, welche anderen Dateideskriptoren ihre Flags als Ergebnis aktualisieren, aber das ist offensichtlich weder ideal noch narrensicher
quelle
Antworten:
Ab Linux 3.5 kann dies mit kcmp (3) erreicht werden :
Die Manpage enthält ein Beispiel speziell für den angeforderten Anwendungsfall OP. Beachten Sie, dass für diesen Systemaufruf der Kernel mit
CONFIG_CHECKPOINT_RESTORE
set kompiliert werden muss .quelle
struct file *
Zeiger vergleichen können .Was Sie vergleichen
struct file
möchten, sind die Zeiger, auf die die Dateideskriptoren verweisen. (Innerhalb des Kernels ist einetask_struct
Datenstruktur für jeden Thread. Es enthält einen Zeiger auf eine andere Struktur genanntfiles_struct
. Und die Struktur enthält ein Array von Zeigern, die jeweils einemstruct file
. Es ist das ist ,struct file
dass die Such Offset hält, die offenen Fahnen und ein einige andere Felder.)Ich kenne keine vom Benutzer sichtbare Möglichkeit, die Zeiger in
files_struct
anderen als der Verwendung einiger aufdringlicher Tools zu sehen. Beispielsweise könnte SystemTap eine PID erhalten und die entsprechende findentask_struct
und den Zeigern folgen. Wenn Sie auf der Suche nach passiven sind, denke ich, ist das auch schon alles. Dell hat vor langer Zeit ein Tool namens KME (Kernel Memory Editor) veröffentlicht, das eine spreadsheet-ähnliche Oberfläche für den Live-Kernel-Speicher bietet und das alles kann, was Sie wollen, aber es wurde nie auf 64-Bit portiert. (Ich habe es versucht und nie ganz zum Laufen gebracht und war mir nicht sicher warum.)Ein Grund, warum Sie sich nicht
lsof
als hilfreich erweisen, ist, dass diese Zeiger ebenfalls nicht angezeigt werden (sehen Sie sich jedoch die+f
Option für Nicht-Linux-Systeme an). Sie könnten theoretisch alle Felder in der vergleichenstruct file
und die beiden Strukturen für gleich halten, sie könnten jedoch immer noch von getrenntenopen(2)
Aufrufen stammen.Schauen Sie sich das pfiles- SystemTap-Skript an, um Ideen zu erhalten. Wenn Sie es geändert haben, um die Adresse der auszudrucken
struct file
, hätten Sie Ihre Lösung. Sie können auch die Datei "opens_file_by_pid.stp" überprüfen, da sie eine Funktion enthält, die die Zeichenfolge "ie" ausführtfiles_struct
. die Dateideskriptortabelle, die diestruct file
Objekte betrachtet ...Darf ich fragen, was Sie erreichen wollen?
quelle
probe begin
Block ein und lassen Sie ihn dasfor_each_process
Makro in einem Block von C-Code verwenden, der in das Skript eingebettet ist (Sie müssen SystemTap im "Guru" -Modus verwenden, um C-Code einzubetten). Um dies interessant (!) Zu machen, können Sie eines der assoziativen Arrays von SystemTap verwenden. Verwenden Sie diefiles_struct
Adresse als Schlüssel und eine Liste von PIDs / TIDs als Werte. Sie haben jetzt eine Liste aller geöffneten Dateien und der Aufgaben, die sie gemeinsam nutzen (sie können von Eltern / Kindern gemeinsam genutzt werden). Antworten Sie erneut, wenn Sie über SystemTap sprechen möchten.Hier ist eine linuxspezifische Lösung: / proc / self / fd ist ein Verzeichnis symbolischer Links für offene Dateihandles im aktuellen Prozess. Sie können nur die Linkwerte vergleichen. Bei der Verwendung eines untergeordneten Prozesses wird es komplizierter, da das untergeordnete Element ein anderes / proc / self hat, da es eine pid-abhängige symbolische Verknüpfung ist. Sie können dieses Problem umgehen, indem Sie / proc / $$ / fd verwenden, wobei $$ die gewünschte PID ist.
quelle