Antworten:
Wie von @Kusalananda erwähnt, werden Upgrades normalerweise durchgeführt, indem die alte Datei entfernt und eine neue mit demselben Namen erstellt wird. Dadurch wird tatsächlich eine neue Datei mit einem neuen Inode erstellt, sodass das System die alte Datei verwenden kann, solange sie geöffnet ist.
Als vereinfachtes Beispiel Dinge wie
rm /bin/cat
cp /new/version/of/cat /bin/cat
erstellt eine logisch neue Datei und funktioniert, obwohl sie cat
möglicherweise ausgeführt wird. Gleiches gilt für Bibliotheken. (Das Obige ist ein Beispiel, keine robuste Methode zum Aktualisieren einer Datei in der realen Welt.)
Jemand könnte versuchen, die Binärdatei an Ort und Stelle zu ändern, anstatt eine neue mit demselben Namen zu erstellen. In diesem Fall verhindert zumindest Linux tatsächlich, dass Änderungen an einer verwendeten ausführbaren Datei vorgenommen werden:
window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy
Dies scheint jedoch bei dynamisch geladenen Bibliotheken nicht zu funktionieren ...
Ich habe eine Kopie libc.so.6
zum Testen erstellt und sie während des Gebrauchs mit Nullen gefüllt:
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
linux-vdso.so.1 (0x00007ffcfaf30000)
libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo
Segmentation fault
(In der Zwischenzeit in einem anderen Fenster, nach dem foo
, vor dem Segfault)
window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000
Es gibt wirklich nichts, was das Programm selbst dagegen tun könnte, da ich seinen Code effektiv online bearbeitet habe.
(Dies wäre wahrscheinlich systemabhängig. Ich habe es unter Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3 getestet. Insbesondere IIRC-Windows-Systeme sind noch aggressiver, wenn es darum geht, zu verhindern, dass verwendete Dateien geändert werden.)
Ich denke, die Antwort ist, dass Upgrades normalerweise so durchgeführt werden, dass Probleme vermieden werden. Dies wird durch die Interna des Dateisystems unterstützt. Aber (unter Linux) scheint es keine Schutzmaßnahmen gegen die tatsächliche Beschädigung dynamischer Bibliotheken zu geben.
install
Dienstprogramm wird häufig für solche Dinge verwendet. Sie müssen die Zieldatei nicht explizit rm
angeben. Außerdem werden die Berechtigungen der vorhandenen Datei beibehalten, ein Backup erstellt, ein neuer Modus festgelegt usw. Verwendungsbeispiel:install /new/version/of/cat /bin/cat
rm
+ cp
war als Beispiel gedacht. Es kann auch sinnvoll sein, die neue Datei atomar mit einer Umbenennung zu platzieren, um ein kurzes Fenster zu vermeiden, in dem keine der beiden Versionen verfügbar ist. (Obwohl GNU install
das nicht einmal zu tun scheint, hmpf.)
rm
) ist, wird sie noch nicht gelöscht. Es wird auf der Festplatte vorhanden sein und kann weiterhin von allen Prozessen gelesen werden, bei denen es geöffnet ist. Es wird nur gelöscht, wenn die Anzahl der festen Verbindungen Null erreicht UND die Anzahl der Vorgänge bei geöffneter Datei Null erreicht.
install
Dienstprogramm ist speziell unsicher! Die Zieldatei wird überschrieben, anstatt sie atomar zu ersetzen. mv
(mit Quelle und Ziel im selben Verzeichnis, Quelle normalerweise eine temporäre Datei) ist der einzig sichere Weg, um Dateien zu installieren.
strace
, install
in GNU Coreutils die Verknüpfung der Zieldatei auf und kopiert dann eine neue an ihre Stelle. Dies bedeutet, dass es ein kurzes Fenster gibt, in dem die Datei teilweise ist. Die Datei wird bei einer Umbenennung nicht atomar festgelegt.
Dateien werden nicht "ordnungsgemäß gelöscht", wenn sie nicht verbunden sind, während sie noch geöffnet sind. Wenn sie geschlossen sind, wird der von ihnen verwendete Speicherplatz wieder als "frei" betrachtet. Dies gilt auch für aktuell ausgeführte Anwendungen und deren gemeinsam genutzte Bibliotheken.
Das einzige, was ich als fehlerhaft ansehen konnte, war, wenn ein Programm dlopen()
zum Laden einer gemeinsam genutzten Bibliothek bei Bedarf verwendet wurde oder wenn das Programm bei Bedarf auf andere Dateien wie Wörterbücher, Themendateien oder andere Dateien zugreifen musste, die plötzlich verschwanden.
Zur Veranschaulichung: Das Ausführen vim
in einer Shell-Sitzung beim Löschen der Installation vim
in einer anderen Shell-Sitzung wird die aktuell ausgeführte vim
Sitzung nicht "beschädigen" oder beenden . Einige Dinge schlagen jedoch fehl, beispielsweise die Rechtschreibprüfung, bei der vim
Dateien in der Installation geöffnet werden müssen.
ln -sf
beim Austauschen von Bibliotheken vorgehen sollten , da-f
Sie damit das vorhandene Ziel der symbolischen Verknüpfung mit einer neuen "überschreiben" konnten, ohne dass es jemals "beschädigt" wurde (im Gegensatz zu einer Folge, bei der Sierm
gefolgt sind) aln -s
). Vor dem Befehl zeigte library.so auf die alte Version, z. library.so.4 ... nach dem Befehl, es ist einfach zu spitz library.so.5 (oder was auch immer) statt - ohne jemals nicht auf eine gültige Bibliothek zeigt.