2012-04-03 12 views
5

Wenn mein Prozess eine .so-Bibliothek lädt und eine neue Version der Bibliothek verfügbar ist, ist es möglich, in die neue Bibliothek zu wechseln, ohne einen Prozessneustart durchzuführen? Oder die Antwort hängt von Dingen ab wie ob es eine Parameteränderung zu einer der vorhandenen Funktionen in der Bibliothek gibt?Shared Libraries aktualisieren, ohne Prozesse neu zu starten

Ich arbeite in einem ziemlich großen System, das 100s von Prozessen läuft und jeder 10s von Bibliotheken lädt. Die Bibliotheken bieten spezifische Funktionen und werden von separaten Teams bereitgestellt. Wenn also eine der Änderungen der Bibliothek (für eine Fehlerbehebung, sagen wir mal) die ideale Sache wäre, würde man sie unter der Oberfläche veröffentlichen, ohne den laufenden Prozess zu beeinflussen. Ist es möglich ?

BEARBEITEN Danke! In meinem Fall, wenn eine neue Bibliothek verfügbar ist, müssen alle laufenden Prozesse damit beginnen. Es ist nicht möglich, sie mit der alten Version laufen zu lassen und später die neue Version aufzunehmen. Es scheint also die sicherere Option zu sein, die Prozesse einfach neu zu laden.

+1

Sofern Sie nicht alle ausführbaren Dateien steuern, ist eine Aktualisierung nicht möglich, so dass Dateien ohne hässliche Hacks wie ptracing Prozesse nicht möglich sind. Außerdem verwendet Linux keine DLL. – BatchyX

Antwort

5

Sie können eine verknüpfte Bibliothek während eines laufenden Prozesses nicht aktualisieren. Sie könnten sogar versuchen, aber wenn Sie erfolgreich waren (und Sie werden nicht fehlschlagen mit einer Fehlermeldung "Textdatei wird verwendet"), müssen Sie den Prozess neu starten, um die neue Bibliothek im Speicher abzubilden.

können Sie lsof-Befehl verwenden, um zu überprüfen, welche Bibliotheken in (Laufzeit oder linktime) verbunden sind:

lsof -p <process_pid> | grep ' mem ' 
+0

Anstelle von 'lsof -p ' können Sie auch 'pldd ' verwenden. – Mikel

+0

pldd: Befehl nicht gefunden. apt-cache search pldd: keine gefunden ... – dAm2K

+0

Es wurde erst im März dieses Jahres zu glibc hinzugefügt. Ihre Distribution enthält sie möglicherweise noch nicht. – Mikel

0

LDD die binäre Ihres Prozesses ist eine Möglichkeit, herauszufinden. Obwohl es theoretisch möglich ist, ist es nicht ratsam, an dem laufenden Prozess herumzubasteln, obwohl ich sicher bin, dass es Utilities wie ksplice gibt, die an den laufenden Linux-Kernel basteln.

Sie können einfach upgraden und der laufende Prozess wird mit der alten Version fortfahren und die neue Version beim Neustart übernehmen, vorausgesetzt, dass Ihr Paketverwaltungssystem gut ist und weiß, was zu installieren ist.

0

Vielleicht möchten Sie mehr über die Versionierung der gemeinsam genutzten Bibliotheken und die Option -h lernen.

Eine Möglichkeit, es zu benutzen ist wie folgt:

Sie einen Versionszähler in Ihrem Build-System aufrechtzuerhalten. Sie bauen die gemeinsame Bibliothek mit:

ld ..... -h mylibrary.so.$VERSION 

jedoch, setzen Sie es in Ihrem lib dev Baum als einfach nur mylibrary.so. (Es gibt auch einen Hack, bei dem das gesamte .so in eine .a-Datei eingefügt wird).

Zur Laufzeit suchen Prozesse, die die Bibliothek verwenden, nach dem vollständig versionierten Namen. Um eine neue Version auszurollen, fügen Sie einfach die neue Version zum Bild hinzu. Laufende Programme, die mit der alten Version verknüpft sind, verwenden sie weiterhin. Wenn Programme erneut verknüpft und mit dem neuen Programm getestet werden, werden neue ausführbare Dateien bereitgestellt.

0

Manchmal kann man ein Upgrade ein in Betrieb befindlicher .so, und manchmal kann man nicht. Dies hängt hauptsächlich davon ab, wie Sie es versuchen, aber auch von den Sicherheitsgarantien des Kernels, auf dem Sie laufen. Katze new.so> old.so ... weil schließlich Ihr Prozess kann versuchen Seite etwas zu verlangen, und findet, dass sie nicht mehr in der richtigen Stelle sind:

dies nicht tun. Es ist ein Problem, weil sich die Adressen der Dinge ändern können, und es ist immer noch die gleiche Inode; Sie überschreiben nur die Bytes in der Datei.

Wenn Sie jedoch: mv new.so old.so Sie auf den meisten Systemen in Ordnung sein werden, weil Ihre laufenden Prozesse auf eine jetzt-unbenannte Inode für die alte Bibliothek halten kann, während neue Anrufungen Ihrer Prozesse Hol dir die neue Datei. ABER, einige kerne mögen es nicht, dass sie mv ein in-use .so, vielleicht aus vorsicht, vielleicht für ihre eigene einfachheit.

+1

Ich glaube nicht, dass "cat new.so> old.so" irgendwelche Auswirkungen auf ein laufendes Programm hat. Da der Kernel weiß, dass das Codesegment im Speicher dem Speicher zugeordnet ist, in dem sich old.so befindet, wird er entweder das Schreiben ablehnen ("Text beschäftigt") oder sogar vorausgehen und die Sektoren beiseite legen, bis das Programm beendet ist. – SquareRootOfTwentyThree

0

Wenn Sie libaries erwarten auf einer ziemlich regelmäßig zu ändern, und Sie erwarten up-Zeit zu halten, denke ich, dass Ihr System sollte neu entwickelt werden, so dass solche Bibliotheken werden tatsächlich lose gekoppelte Komponenten (zB Dienstleistungen).

auch sagen, dass meine Antwort auf die Frage ist ja: unter bestimmten Umständen es möglich Bibliotheken ohne Neustart zesse geteilt. In den meisten Fällen erwarte ich, dass es nicht möglich ist, zum Beispiel, wenn sich die API Ihrer Bibliothek ändert, wenn sich die Anordnung Ihres Datensegments ändert, wenn die Bibliothek interne Threads beibehält. Die Liste ist ziemlich lang.

Für sehr kleine Fehlerkorrekturen auf den Code, können Sie immer noch die Verwendung von ptrace machen den Prozess Speicherplatz zu schreiben, und von es wiederholen, was /lib/ld-linux.so hat im Hinblick auf der dynamischen Verknüpfung. Ehrlich gesagt ist es eine äußerst komplexe Aktivität.

3

Eine interessante Technik, obwohl sie im Prüfpunktwiederherstellungsschritt etwas fehleranfällig ist, ist ein unsichtbarer Neustart.

Ihr Server-Prozess oder was auch immer es ist, speichert alle notwendigen Informationen in den Dateien der Festplatte. Einschließlich der Datei-Deskriptor-Nummern und der aktuellen Zustände. Dann führt der Serverprozess einen Systemaufruf exec aus, um sich selbst auszuführen, wobei er die aktuelle Version von sich selbst ersetzt. Dann liest es seinen Zustand von den Plattendateien und setzt seine Dateideskriptoren fort, als ob nichts passiert wäre.

Wenn alles gut geht, ist der Neustart unsichtbar und der neue Prozess verwendet alle aktualisierten Bibliotheken.

+1

Ein großartiges Beispiel ist "irssi" und sein '/ upgrade' Befehl. –

2

Zumindest müssen Sie sicherstellen, dass die Schnittstelle der Bibliothek zwischen den Versionen nicht ändert. Wenn das gewährleistet ist, würde ich versuchen, die Bibliotheken mit dlopen/dlsym dynamisch zu laden und zu sehen, ob dlclose das Neuladen ermöglicht.

Ich habe selbst nie etwas davon getan, aber das ist der Weg, den ich zuerst gehen würde. Wenn Sie diesen Weg gehen, könnten Sie die Ergebnisse veröffentlichen?

2

Linux bietet mehrere dynamische Loader-Schnittstellen und der Prozess kann dynamische Bibliotheken laden, wenn er ausgeführt wird. dlopen und dlsysm, die von linux bereitgestellt werden, können Ihr Problem lösen.

Verwandte Themen