Wie kann ich eine gemeinsam genutzte Bibliothek ohne Absturz aktualisieren?

Wie kann ich eine gemeinsam genutzte Bibliothek ohne Absturz aktualisieren?

Hierdort steht, dass Sie eine ausführbare Datei neu schreiben können und der Prozess trotzdem einwandfrei ausgeführt wird – die Datei wird beim Neustart eines Prozesses erneut gelesen.

Wenn ich jedoch versuche, eine Binärdatei zu ersetzen, während der Prozess ausgeführt wird (mit scp, vom Dev- zum Testserver), wird „Datei beschäftigt“ angezeigt. Und wenn ich eine gemeinsam genutzte Bibliotheksdatei (*.so) ersetze, stürzen alle Prozesse ab, die sie verknüpfen.

Warum ist das so? Übersehe ich etwas? Wie kann ich die Binärdateien ersetzen, ohne einen Prozess anzuhalten/abzustürzen?

Antwort1

Wie erwähnt inWarum läuft ein Softwarepaket einwandfrei, selbst wenn es aktualisiert wird?, die Sperre wird auf den Inode gesetzt, nicht auf den Dateinamen. Wenn Sie eine Binärdatei laden und ausführen, wird die Datei als belegt markiert. Deshalb erhalten Sie den Fehler ETXTBSY (Datei belegt), wenn Sie versuchen, in die Datei zu schreiben.

Bei gemeinsam genutzten Bibliotheken ist es etwas anders: Die Bibliotheken werden mit in den Adressraum des Prozesses abgebildet mmap(). Obwohl MAP_DENYWRITEangegeben werden kann, ignoriert zumindest Glibc unter Linux dies stillschweigend (laut der Manpage, schauen Sie ruhig in den Quellen nach) - überprüfen Sie diesFaden. Daher dürfen Sie die Datei tatsächlich schreiben und da sie im Speicher abgebildet ist, sind alle Änderungen fast sofort sichtbar - das heißt, wenn Sie sich genug anstrengen, können Sie es schaffen, ZiegelIhre Maschine, indem Sie die Bibliothek überschreiben.

Die richtige Vorgehensweise zum Aktualisieren ist daher:

  1. Entfernen der Datei, wodurch der Verweis auf die Daten aus dem Dateisystem entfernt wird, sodass sie für neu erstellte Anwendungen, die sie möglicherweise verwenden möchten, nicht zugänglich sind, während die Daten für jeden zugänglich bleiben, der sie bereits geöffnet (oder zugeordnet) hat;

  2. Erstellen einer neuen Datei mit aktualisiertem Inhalt.

Neu erstellte Prozesse verwenden die aktualisierten Inhalte, laufende Anwendungen greifen auf die alte Version zu. Dies ist, was jedes vernünftige Paketverwaltungsprogramm tut. Beachten Sie jedoch, dass dies nicht ganz ungefährlich ist. Beispielsweise dlsym()treten bei Anwendungen, die Code dynamisch laden (mit und ähnlichen), Probleme auf, wenn sich die API der Bibliothek unbemerkt ändert.

Wenn Sie wirklich dabei sein wollen,WirklichFahren Sie zur Sicherheit das System herunter, mounten Sie das Dateisystem von einer anderen Betriebssysteminstanz, führen Sie ein Update durch und starten Sie das aktualisierte System erneut.

Antwort2

Ein RPM-Upgrade bewirkt dasselbe – mit laufenden Binärdateien und Bibliotheken, ohne dass etwas abstürzt.

Was ist also der Unterschied:

  1. Dateiverknüpfung aufheben
  2. neue Datei mit gleichem Namen schreiben

Dadurch wird die Datei NICHT direkt ersetzt: Der Inode, der auf die verwendete Binärdatei verweist, ist noch „beschäftigt“, bis das letzte Objekt, das sie offen hält, fertig ist. Die neue Datei wird mit einer neuen Inode-Nummer erstellt.

Jetzt scpwird cpversucht, die Datei direkt zu ersetzen – wodurch sich der Inhalt ändern würde, auf den sich der Inode bezieht. Das funktioniert – wie von dir beschrieben – nicht.

verwandte Informationen