Warum läuft ein Softwarepaket auch während des Upgrades einwandfrei?
29
Angenommen, ich führe eine Software aus und führe dann den Paket-Manager aus, um die Software zu aktualisieren. Dabei stelle ich fest, dass Linux den ausgeführten Prozess für die Paketaktualisierung nicht beeinträchtigt - es läuft weiterhin einwandfrei. Wie macht Linux das?
Der Grund dafür ist, dass Unix eine ausführbare Datei nicht sperrt, während sie ausgeführt wird, oder auch wenn es Linux mag, gilt diese Sperre für den Inode und nicht für den Dateinamen. Das bedeutet, dass ein Prozess, der es offen hält, auf dieselben (alten) Daten zugreift, auch nachdem die Datei gelöscht (tatsächlich nicht verknüpft) und durch eine neue mit demselben Namen ersetzt wurde, was im Wesentlichen bei einem Paket-Update der Fall ist.
Das ist einer der Hauptunterschiede zwischen Unix und Windows. Letzteres kann eine gesperrte Datei nicht aktualisieren, da eine Ebene zwischen Dateinamen und Inodes fehlt, was die Aktualisierung oder Installation einiger Pakete erheblich erschwert, da normalerweise ein vollständiger Neustart erforderlich ist.
Zur Verdeutlichung: Unter Linux können Sie eine ausführbare Datei nicht ändern, während sie ausgeführt wird. Sie können jedoch die Verknüpfung der Datei aufheben und sie durch eine neue Datei mit demselben Namen ersetzen.
cjm
Unter Linux können Sie eine ausführbare Datei während der Ausführung ändern. Das Ergebnis wäre jedoch wahrscheinlich unvorhersehbar, es sei denn, Sie wissen wirklich, was Sie tun. Es wurde der Punkt "Gleicher Name" hinzugefügt, der nicht ausdrücklich angegeben wurde.
Juli
4
@ jlliagre Sofern ich nichts falsch verstehe, kannst du es meines Wissens nicht tun: sprunge.us/egiR
Chris Down
2
Eine nette Sache bei NFTS: Wenn Sie einen Umbenennungsvorgang über die Befehlszeile oder ein anderes Programm ausführen, können Sie eine Datei mit dem gleichen Namen dort ablegen. Programme, bei denen die ursprüngliche Datei geöffnet ist, sind davon nicht betroffen. (Der Befehl zum Umbenennen im Explorer funktioniert hierfür nicht)
Steffan Donal
1
@cjm Du hast Recht, was den "File Text Busy" -Schutz unter Linux betrifft. Antwort aktualisiert. Unter Solaris gibt es keine solche Einschränkung, mit der ich besser vertraut bin. Sie können geteilte Bibliotheken jedoch weiterhin mit beiden Betriebssystemen ändern.
Juli
18
Ausführbare Dateien werden in der Regel einmal geöffnet, an einen Dateideskriptor angehängt und haben keinen Dateideskriptor für ihre Binärdatei, der während eines einzelnen Ausführungszeitraums erneut geöffnet wird. Wenn Sie beispielsweise ausführen bash, wird im exec()Allgemeinen nur ein Dateideskriptor für den Inode erstellt, auf den /bin/bashbeim Aufruf einmalig verwiesen wird .
Dies bedeutet häufig, dass für einfache Binärdateien, die während der Ausführung nicht versuchen, sich selbst neu zu lesen (indem sie den Pfad verwenden, über den sie aufgerufen wurden), der zwischengespeicherte Inhalt als baumelnder Inode gültig bleibt. Dies bedeutet, dass im Wesentlichen ein Replikat der vorherigen Version der ausführbaren Datei vorhanden ist.
In komplexeren Fällen kann dies zu Problemen führen. Beispielsweise kann eine Konfigurationsdatei aktualisiert und anschließend erneut gelesen werden, oder das Programm kann sich selbst über den Pfad, von dem aus es ausgeführt wurde, erneut ausführen. Es kann auch Probleme geben, wenn Programme miteinander verbunden sind und eines vor dem Upgrade und eines danach (möglicherweise vom ersten Programm) ausgeführt wird. Dies gilt auch für einige Bibliotheken.
Für einfache Anwendungsfälle ist es jedoch sicher, ein Upgrade durchzuführen, ohne den Prozess neu zu starten.
Die andere Gefahr besteht selbst in einfachen Fällen darin, dass die alte Version des Codes ausgeführt wird, bis Sie die Anwendung manuell neu starten, da die ausgeführte Anwendung eine zwischengespeicherte Kopie der Binärdatei verwendet. Während dies die meiste Zeit keine Rolle spielen sollte; Wenn das Upgrade Sicherheitsupdates enthielt, ist Ihr System trotz des installierten Patches immer noch anfällig, da die alte Version noch ausgeführt wird.
Dan Neely
1
Ich fürchte, dein erster Absatz ist ungenau. Unix / Linux-Kernel laden keine ausführbaren Programme auf einmal, sondern ordnen sie dem Speicher zu. Das bedeutet, dass nur tatsächlich verwendete Seiten in den Arbeitsspeicher gelangen. Dies ist der springende Punkt des Schutzes "Textdatei ausgelastet" unter Linux. Es gibt keine Garantie, dass ein Teil einer ausführbaren Datei nicht lange nach dem Start gelesen wird. Darüber hinaus werden einige Seiten niemals für ausreichend große Programme geladen, und dies gilt umso mehr für dynamisch geladene Bibliotheken. Zum Beispiel sind bashBinärdateien ungefähr 200 4K-Seiten, nicht sicher, ob sie alle in einer durchschnittlichen Sitzung verwendet werden.
Juli
@jlliagre Ich sprach davon ialloc(), beim Lesen eine Kernel-Struktur zu verwenden, nicht die Speicherzuordnung der Seiten selbst. Habe ich nicht Recht, wenn ich denke, dass der Inode auf modernen ext * -Dateisystemen irgendwann im Kernel (und innerhalb des VM-Subsystems) konsistent ist?
Chris Ab
Es gibt keine Garantie, dass Teile des ausführbaren Inhalts nicht lange nach seiner Ausführung gelesen werden, und es gibt auch keine Garantie, dass dieselben Seiten während der Ausführungszeit nach einer Weile nicht mehr gelesen werden.
Juli
@jlliagre Richtig, aber das habe ich nicht gemeint. Vielleicht habe ich meine Worte in meiner Antwort ein wenig zerkleinert, ich werde versuchen, klarer zu machen, was ich meinte.
Ausführbare Dateien werden in der Regel einmal geöffnet, an einen Dateideskriptor angehängt und haben keinen Dateideskriptor für ihre Binärdatei, der während eines einzelnen Ausführungszeitraums erneut geöffnet wird. Wenn Sie beispielsweise ausführen
bash
, wird imexec()
Allgemeinen nur ein Dateideskriptor für den Inode erstellt, auf den/bin/bash
beim Aufruf einmalig verwiesen wird .Dies bedeutet häufig, dass für einfache Binärdateien, die während der Ausführung nicht versuchen, sich selbst neu zu lesen (indem sie den Pfad verwenden, über den sie aufgerufen wurden), der zwischengespeicherte Inhalt als baumelnder Inode gültig bleibt. Dies bedeutet, dass im Wesentlichen ein Replikat der vorherigen Version der ausführbaren Datei vorhanden ist.
In komplexeren Fällen kann dies zu Problemen führen. Beispielsweise kann eine Konfigurationsdatei aktualisiert und anschließend erneut gelesen werden, oder das Programm kann sich selbst über den Pfad, von dem aus es ausgeführt wurde, erneut ausführen. Es kann auch Probleme geben, wenn Programme miteinander verbunden sind und eines vor dem Upgrade und eines danach (möglicherweise vom ersten Programm) ausgeführt wird. Dies gilt auch für einige Bibliotheken.
Für einfache Anwendungsfälle ist es jedoch sicher, ein Upgrade durchzuführen, ohne den Prozess neu zu starten.
quelle
bash
Binärdateien ungefähr 200 4K-Seiten, nicht sicher, ob sie alle in einer durchschnittlichen Sitzung verwendet werden.ialloc()
, beim Lesen eine Kernel-Struktur zu verwenden, nicht die Speicherzuordnung der Seiten selbst. Habe ich nicht Recht, wenn ich denke, dass der Inode auf modernen ext * -Dateisystemen irgendwann im Kernel (und innerhalb des VM-Subsystems) konsistent ist?