Wie kann man feststellen, ob einer Datei Speicher zugeordnet ist?

8

Ich bin verwirrt über speicherabgebildete Dateien, daher habe ich einige Fragen, über die ich mich sehr freuen würde, wenn Sie mir helfen könnten.

  1. Angenommen, ich navigiere zu einem Verzeichnis in meinem Dateisystem und es befindet sich eine Datei in diesem Verzeichnis. Ist es möglich, dass diese Datei auf eine Region im Hauptspeicher verweist, anstatt auf eine Region auf der Festplatte?
  2. Wenn dies möglich ist, nennen wir dies "speicherabgebildete Datei"?
  3. Was würde es bedeuten, eine solche Datei im Dateisystem zu verschieben (dh mveine solche Datei von einem Verzeichnis in ein anderes zu verschieben)? Ich verstehe, dass, da die Datei speicherabgebildet ist, die mit der Datei interagierenden Prozesse immer in einen vordefinierten Bereich des Hauptspeichers schreiben. Wenn wir diese Datei öffnen (z. B. mit vim), lesen wir diesen Bereich des Hauptspeichers Speicher (also ist keine Festplatte beteiligt). Unabhängig davon, wohin wir die Datei verschieben, funktioniert sie immer richtig, oder? Wenn ja, hat das Verschieben der Datei im Dateisystem eine Bedeutung?
  4. Gibt es einen Befehl, der anzeigt, ob eine Datei dem Speicher zugeordnet ist?
  5. Was passiert , wenn ich eine Speicherzuordnungsdatei mit öffne vim, einige Änderungen daran vornehme und speichere und schließe vim? Werden meine Änderungen einfach in den Hauptspeicher geschrieben? Wenn dies der Fall ist, werden andere Prozesse, die diese Datei verwenden, die Änderungen sehen, die ich gerade vorgenommen habe? Nach meiner Erfahrung haben die anderen Prozesse die Änderungen, die ich an der Datei vorgenommen habe, nicht gesehen, als ich einige Änderungen an der Datei mit vorgenommen habe vim. Was ist der Grund dafür?
Utku
quelle
12
Dies erinnert mich an jemanden, der fragt, wie man erkennt, ob eine Datei ein fester Link ist.
Dmitry Grigoryev
3
@DmitryGrigoryev Das ist in der Tat ziemlich lustig, aber jeder lernt :)
Katze

Antworten:

24

Speicherzugeordnete Dateien funktionieren umgekehrt. Die Speicherzuordnung ist keine Eigenschaft der Datei, sondern eine Möglichkeit, auf die Datei zuzugreifen: Ein Prozess kann den Inhalt einer Datei (oder eine Teilmenge davon) in ihren Adressraum abbilden. Dies erleichtert das Lesen und Schreiben in die Datei. Dazu muss man einfach im Gedächtnis lesen und schreiben. Die Datei selbst auf der Festplatte ist genauso wie jede andere Datei.

Um dies einzurichten, verwenden Prozesse die mmapFunktion. Dies kann auch für andere Zwecke verwendet werden, z. B. zum Teilen des Speichers zwischen Prozessen.

Stephen Kitt
quelle
14
@Utku Dies hat nichts mit speicherabgebildeten Dateien zu tun.
Satō Katsura
12
Wenn Sie den MySQL-Server nicht heruntergefahren haben, ist dies normal: Auf dem Server ist ein Dateideskriptor für die Datei geöffnet, der auch mit gültig bleibt mv.
Stephen Kitt
11
Der Dateideskriptor zeigt (eventuell) auf Inodes im Dateisystem. Dort lebt die Datei wirklich. Verzeichniseinträge verweisen auch auf diese Inodes und mvändern einfach die Verzeichniseinträge, nicht die Inodes (wenn Dateien auf demselben Dateisystem verschoben werden).
Stephen Kitt
1
Ihre Beschreibung ist eine nützliche Vereinfachung, aber nur aus Gründen der Genauigkeit: Speicherzuordnungen sind technisch gesehen nicht dasselbe wie Dateideskriptoren, funktionieren jedoch auf dieselbe Weise (unter Bezugnahme auf den Inode, nicht auf den Dateinamen). open (), mmap (), close () hinterlässt keine FD, nur eine Zuordnung, die mit angezeigt wird lsof. Es verschwindet nicht, bis der Prozess munmap () aufruft oder beendet (oder das Mapping mit mmap (MAP_FIXED) durch ein anderes ersetzt ...)
Peter Cordes
3
@Utku Du hast die Datei nicht wirklich verschoben. Sie haben gerade einen neuen Verzeichniseintrag erstellt, der auf dieselbe Datei verweist, und dann den alten entfernt. Die Änderung der Benennung hat keine Auswirkungen auf einen Prozess, bei dem die Datei bereits geöffnet ist.
David Schwartz
11

Eine Speicherzuordnungsdatei wird nicht (unbedingt) vom Speicher gesichert. Es kann perfekt auf einer Festplatte leben. Wo eine Datei lebt, ist eigentlich keine Eigenschaft der Datei selbst, sondern des Dateisystems, in dem sie sich befindet.

Das Zuordnen einer Datei im Speicher ist eine Operation, die ein Prozess ausführen kann, um einen Teil der Datei in den Speicher zu laden. Das Ergebnis sieht aus wie ein regulärer Speicherbereich, außer dass der Prozess beim Lesen oder Schreiben in diesen Bereich tatsächlich aus der Datei liest und in diese schreibt. Wenn Sie eine Datei öffnen, dem Speicher zuordnen, in sie schreiben und speichern, wird die Änderung an der Datei auf der Festplatte vorgenommen (wenn sie sich natürlich auf einer Festplatte befindet).

Dies kann beispielsweise verwendet werden , wenn Sie wissen , Sie haben eine Menge von Zugriffen auf eine Datei zu tun, die nicht sequentiell sein würde, sein weil es einfacher und effizienter sein kann , zu tun Lese- und Schreibvorgänge im Speicher als zu Ausgabe read, write, und llseekSystemaufrufe. Das einzige Problem bei dieser Methode ist, dass Sie sie nicht wirklich verwenden können, wenn die Datei von mehreren Prozessen gleichzeitig gelesen oder beschrieben werden muss. Die Ergebnisse wären unvorhersehbar.

Ich kenne keinen Befehl, der Ihnen sagen kann, ob eine Datei gerade zugeordnet ist. Sie können jedoch die Zuordnungen eines Prozesses in überprüfen /proc/<pid>/maps(sofern Ihr System über diese verfügt).

Um Ihre zweite Frage zu beantworten: Wenn Sie eine Datei öffnen, können die Prozesse, die sie geöffnet haben, sie auch dann verwenden, wenn Sie sie in das Dateisystem verschieben. Was passiert ist, dass eine Datei nicht von ihren Einträgen in den Dateisystemen abhängig ist. Solange Sie eine Datei geöffnet haben, haben Sie ein "Handle", einen Dateideskriptor, mit dem Sie lesen und darauf schreiben können, selbst wenn sich der Pfad im Dateisystem ändert. Eine Datei verschwindet nur, wenn sie keinen Eintrag im Dateisystem hat und kein Prozess einen Dateideskriptor enthält.

lgeorget
quelle
Wenn wir also eine Datei verschieben, ändert sich der Wert des Dateideskriptors nicht. Es gibt eine Deskriptorzuordnung von Pfad zu Datei, und nur der Pfadteil dieser Zuordnung ändert sich. Ist das richtig?
Utku
1
In gewissem Sinne ja, aber ich bin mir nicht sicher, ob ich dich verstehe, also lass es mich umformulieren. Grundsätzlich besteht "eine Datei" aus drei Dingen. Ein Verzeichniseintrag ist ein Pfad im Dateisystem. Ein Inode ist der Inhalt einer Datei. Ein Dateideskriptor repräsentiert eine geöffnete Datei. Sowohl die Verzeichniseinträge als auch die Dateideskriptoren enthalten einen Zeiger auf ihren Hintergrund-Inode. Wenn Sie eine Datei öffnen, übergeben Sie den Verzeichniseintrag und der Kernel gibt Ihnen einen Dateideskriptor zurück. Selbst wenn sich der ursprüngliche Verzeichniseintrag ändert, zeigt der Dateideskriptor immer noch auf denselben Inode, und Sie können auf die Datei zugreifen.
Lgeorget
1
Sie können jedoch die Zuordnungen eines Prozesses in überprüfen /proc/<pid>/maps. - Vorausgesetzt, dieser Prozess lebt auf einem System, das zunächst einen hat /proc. OpenBSD tut dies nicht und FreeBSD läuft aus. Auch FreeBSD hat /proc/<pid>/mapstatt /proc/<pid>/maps.
Satō Katsura
@SatoKatsura Danke für die Präzision. Ich habe nur eine Linux-Maschine zur Hand, also hatte ich gedacht, ich würde über meinen Fall erzählen und die Leute über ihren erzählen lassen ... Sie können die Antwort jederzeit bearbeiten, wenn Sie hier etwas korrigieren / hinzufügen müssen.
Lgeorget
Da Sie fragen: Sie haben angenommen, dass das OP tatsächlich versteht, was er fragt, und ausführlich erklärt, was speicherabgebildete Dateien sind. Ich glaube nicht, dass du ihm einen Dienst erwiesen hast. IMO war Ihr erster Kommentar oben weitaus relevanter für das, was das OP tatsächlich fragte, als Ihre Antwort. FWIW.
Satō Katsura
9

F4: Gibt es einen Befehl, der anzeigt, ob eine Datei speicherabgebildet ist?

Der lsofBefehl zeigt Ihnen alle Dateien an, die derzeit vom System verwendet werden. Die Spalte "FD" enthält "mem", wenn der Datei Speicher zugeordnet ist. Sie können also die Ausgabe dieses Befehls nach dem Dateinamen durchsuchen, an dem Sie interessiert sind.

Wossname
quelle
3
Oder verwenden Sielsof -ad mem /path/to/file
Stéphane Chazelas
5
Oder besser gesagt, lsof -ad mem,txt /path/to/fileda Dateien, die ausgeführt werden, auch Teile davon im Prozessadressraum mmap haben, aber wie txtin der lsofAusgabe erscheinen.
Stéphane Chazelas
7

Sie scheinen die Speicherzuordnung mit Dateien in speicherresidenten Dateisystemen zu verwechseln, zusammen mit anderen Konzepten wie der Art und Weise, wie Prozesse den Zugriff auf Dateien aufrechterhalten, selbst wenn diese verschoben werden.

Ich werde Frage für Frage gehen, um zu sehen, ob ich die Dinge klären kann.

  1. Angenommen, ich navigiere zu einem Verzeichnis in meinem Dateisystem und es befindet sich eine Datei in diesem Verzeichnis. Ist es möglich, dass diese Datei auf eine Region im Hauptspeicher verweist, anstatt auf eine Region auf der Festplatte?

Es verweist auf den Hauptspeicher, wenn es sich in einem speicherresidenten Dateisystem befindet, z. B. procfs, das normalerweise auf / proc gemountet ist, oder sysfs, das auf / sys ist, oder tmpfs, das manchmal auf / tmp ist.

  1. Wenn dies möglich ist, nennen wir dies "speicherabgebildete Datei"?

Nein. Wie stephen-kitt sagte, bezieht sich "Speicherzuordnung" auf eine Möglichkeit, auf eine Datei zuzugreifen, indem sie im Hauptspeicher "zugeordnet" und dort damit gearbeitet wird, anstatt Blöcke gleichzeitig über Funktionen wie read () und zu lesen und zu schreiben schreiben().

  1. Was bedeutet es, eine solche Datei im Dateisystem zu verschieben (dh eine solche Datei aus einem Verzeichnis in ein anderes zu verschieben)? Ich verstehe, dass, da die Datei speicherabgebildet ist, die mit der Datei interagierenden Prozesse immer in einen vordefinierten Bereich des Hauptspeichers schreiben. Wenn wir diese Datei öffnen (z. B. mit vim), lesen wir diesen Bereich von Hauptspeicher (es ist also keine Festplatte beteiligt). Unabhängig davon, wohin wir die Datei verschieben, funktioniert sie immer richtig, oder? Wenn ja, hat das Verschieben der Datei im Dateisystem eine Bedeutung?

Wenn Sie es innerhalb desselben Dateisystems verschieben, verschieben Sie wirklich nur eine Referenz, einen Inode von einem Verzeichnis in ein anderes. Wenn es Programme gibt, bei denen diese Datei bereits geöffnet wurde, greifen sie weiterhin auf dieselbe Datei zu, da sie den Inode bereits über einen Dateideskriptor zur Hand haben. Dies ist mit der Datei table_name.idb geschehen, die Sie in einem Kommentar erwähnt haben.

  1. Gibt es einen Befehl, der anzeigt, ob eine Datei dem Speicher zugeordnet ist?

Wossname hat dies bereits für Dateien mit Speicherzuordnung beantwortet. lsofHier erfahren Sie, welchen Prozessen die Datei im Speicher zugeordnet ist.

Um festzustellen, ob sich eine Datei in einem speicherresidenten Dateisystem befindet, können Sie die Dateisysteme und ihre Mountpunkte verwenden dfoder mountauflisten. Sie müssen nur wissen, welche Arten von Dateisystemen sich im Speicher befinden, indem Sie sie nachschlagen (z. B. in Wikipedia).

  1. Was passiert, wenn ich eine mit Speicher zugeordnete Datei mit vim öffne, einige Änderungen daran vornehme und vim speichere und schließe? Werden meine Änderungen einfach in den Hauptspeicher geschrieben? Wenn dies der Fall ist, werden andere Prozesse, die diese Datei verwenden, die Änderungen sehen, die ich gerade vorgenommen habe? Nach meiner Erfahrung haben die anderen Prozesse die Änderungen, die ich an der Datei vorgenommen habe, nicht gesehen, als ich mit vim einige Änderungen an der Datei vorgenommen habe. Was ist der Grund dafür?

Persönlich habe ich nicht die verwendete mmapFunktion in einem C - Programm, aber wie ich es verstehe von Skimming man mmapund info mmapgibt es keine Magie bei der Aufrechterhaltung der In-Memory beteiligt Darstellung synchron. In seiner Grundform kopiert der Aufruf von mmap den Dateiinhalt in den Speicher und msyncwird verwendet, um ihn aus dem Speicher auf die Festplatte zurückzuschreiben. Wenn sich die Datei auf der Festplatte ändert, ist nichts vorhanden, um dies zu erkennen und die speicherinterne Darstellung in allen Prozessen, die sie zugeordnet haben, automatisch zu ändern.

BEARBEITEN: Es stellt sich heraus, dass mmap () tatsächlich versucht, die speicherinterne Darstellung unter bestimmten Bedingungen synchron zu halten. Wenn die Karte nur gelesen wird, bleibt sie auch dann synchron, wenn andere Prozesse in die Datei schreiben. Wenn es geschrieben wird (durch Zuweisen zum Speicherbereich), hängt es davon ab, welches der anscheinend obligatorischen MAP_SHARED- oder MAP_PRIVATE-Flags für mmap () bereitgestellt wird. Wenn MAP_PRIVATE angegeben ist, wird die Map von der Darstellung auf der Festplatte getrennt und ist nicht mehr synchron, bis Sie msync () verwenden. Wenn MAP_SHARED bereitgestellt wird, werden die Aktualisierungen für andere Prozesse sichtbar gemacht, denen die Datei zugeordnet ist, sowie für die Darstellung auf der Festplatte (obwohl dies nicht unbedingt unmittelbar erforderlich ist).

Ich habe gerade vim für eine vorhandene Datei geöffnet eund den Befehl ausgeführt :w, während ich inotifywait -m .in einem anderen Terminal ausgeführt habe. Unter einigen seltsamen Dingen ist dies der wichtige Teil, von dem ich bekommen habe inotifywait.

./ MOVED_FROM e
./ MOVED_TO e~
./ CREATE e
./ OPEN e
./ MODIFY e
./ CLOSE_WRITE,CLOSE e
./ ATTRIB e
./ ATTRIB e
./ DELETE e~

Vim erstellt eine neue Datei und entfernt die alte. Warum dies geschieht, anstatt die Datei zu ändern, geht über den Rahmen dieser Frage hinaus, aber der Punkt ist, dass dies eine neue Datei ist und daher einen neuen Inode hat.

Was meinen Sie nun mit anderen Prozessen, die diese Datei verwenden? Wenn Sie Prozesse meinen, bei denen die Datei währenddessen geöffnet wurde, werden die Änderungen nicht angezeigt. Dies liegt daran, dass sie zwar eine Datei mit demselben Pfad geöffnet haben, jedoch nicht dieselbe Datei. Wenn Sie Prozesse meinen, die die Datei danach möglicherweise öffnen, werden die Änderungen angezeigt. Sie öffnen die neue Datei, die Sie erstellt haben.

Es ist wichtig zu beachten, dass Programme zwar eine Datei auf der Benutzeroberfläche geöffnet zu haben scheinen, dies jedoch nicht unbedingt bedeutet, dass sie die Datei dabei offen halten. Vim ist ein Beispiel dafür, wie oben gezeigt.

JoL
quelle
3
" Wenn sich die On-Disk-Datei ändert, ist nichts vorhanden, um dies zu erkennen und die In-Memory-Darstellung in allen Prozessen, die sie zugeordnet haben, automatisch zu ändern. " Was würde das On-Disk-Dateisystem hinter der Rückseite der Seitenzuordnung des Betriebssystems ändern? System? Stellen Sie sich einen Rohzugriff auf das Blockgerät oder ein Blockgerät vor, das über iSCSI oder so etwas gemeinsam genutzt wird?
David Schwartz
@ david-schwartz Nein. Ich stelle mir zwei Prozesse mit einer Datei open () vor. Prozess 1 verwendet mmap (), um den Dateiinhalt in den Speicher zu kopieren / zuzuordnen. Dann verwendet Prozess 2 write () (und möglicherweise fsync ()), um den Inhalt auf der Festplatte zu ändern. Zu diesem Zeitpunkt spiegelt der Dateiinhaltsprozess 1 im Speicher nicht die Änderungen wider, die Prozess 2 vorgenommen hat, oder?
JoL
Nein natürlich nicht. Der Zweck der writeFunktion besteht darin, die Dateidaten zu ändern. Das kann bedeuten, dass der Inhalt auf der Festplatte geändert wird oder nicht, aber was auch immer es beinhaltet, es liegt in der Verantwortung des Dateisystems, es richtig zu machen. In diesem Fall müsste die zugeordnete Speicherseite geändert und als verschmutzt markiert werden.
David Schwartz
@ david-schwartz Ich habe mit mmap () experimentiert und du hast irgendwie recht. In dem Szenario, das ich in meinem vorherigen Kommentar dargelegt habe, spiegelte der Inhaltsprozess 1 im Speicher (in der Karte) tatsächlich die Änderungen wider, es sei denn, Prozess 1 hatte zuvor in den Speicher in der Zuordnung geschrieben. Dies traf auch dann zu, wenn sich der Änderungsprozess 1 an einem anderen Ort befand als der von Prozess 2 vorgenommene. Ich habe die Antwort aktualisiert, indem ich die Fehler gestrichen und das gefundene hinzugefügt habe.
JoL
1
@ david-schwartz Entschuldigung, ich wollte nicht implizieren, dass sich mmap anders verhält als in der Dokumentation angegeben, aber ja, ich denke, ich habe die Antwort zu verwirrend gemacht. Ich denke, es ist noch im Geltungsbereich, aber die Frage "Werden andere Prozesse, die diese Datei verwenden, die Änderungen sehen, die ich gerade vorgenommen habe?" Scheint zu weit gefasst zu sein. Es gibt zu viele "es kommt darauf an". Da das Bedürfnis des OP rein autodidaktisch zu sein scheint, habe ich versucht, eine genaue Antwort zu geben und so viel Boden wie möglich abzudecken, aber ich hätte es vielleicht übertrieben. Trotzdem bin ich froh, dass ich es getan habe, da ich auch einiges gelernt habe.
JoL