Sperren Ausführen von Dateien: Windows funktioniert, Linux nicht. Warum?

81

Ich habe festgestellt, dass eine Datei, die unter Windows (.exe oder .dll) ausgeführt wird, gesperrt ist und nicht gelöscht, verschoben oder geändert werden kann.

Linux hingegen sperrt die Ausführung von Dateien nicht und Sie können sie löschen, verschieben oder ändern.

Warum sperrt Windows, wenn Linux dies nicht tut? Gibt es einen Vorteil beim Sperren?

David Lenihan
quelle
6
Es gibt ein Dienstprogramm namens WhoLockMe, das dem Kontextmenü im Explorer einen Menüeintrag hinzufügt, der die Prozesse anzeigt, mit denen eine bestimmte Datei gesperrt wird . Sehr nützlich, wenn seltsame Fehler beim Sperren von Dateien auftreten. Bearbeiten: Ich weiß, dass dies die Frage nicht beantwortet, aber ich dachte, dass es im Kontext nützlich genug war, um eine separate Antwort zu rechtfertigen (im Gegensatz zu nur einem Kommentar).
JesperE

Antworten:

105

Linux verfügt über einen Referenzzählmechanismus, sodass Sie die Datei während der Ausführung löschen können. Sie bleibt bestehen, solange ein Prozess (der sie zuvor geöffnet hat) über ein offenes Handle verfügt. Der Verzeichniseintrag für die Datei wird beim Löschen entfernt, sodass sie nicht mehr geöffnet werden kann. Prozesse, die diese Datei bereits verwenden, können sie jedoch weiterhin verwenden. Sobald alle Prozesse, die diese Datei verwenden, beendet sind, wird die Datei automatisch gelöscht.

Windows verfügt nicht über diese Funktion, daher muss die Datei gesperrt werden, bis alle von ihr ausgeführten Prozesse abgeschlossen sind.

Ich glaube, dass das Linux-Verhalten vorzuziehen ist. Es gibt wahrscheinlich einige tiefgreifende architektonische Gründe, aber der wichtigste (und einfachste) Grund, den ich am überzeugendsten finde, ist, dass Sie in Windows manchmal eine Datei nicht löschen können, keine Ahnung haben, warum und alles, was Sie wissen, ist, dass ein Prozess sie beibehält verwenden. Unter Linux passiert das nie.

Oren Shemesh
quelle
2
Beachten Sie, dass Sie ein Tool wie Process Explorer in Windows verwenden können, um festzustellen, welcher Prozess eine Datei / einen Ordner verwendet.
J c
14
Ein praktischer Grund für das Linux-Verhalten ist, dass Sie das Betriebssystem und andere Software auf dem System während der Ausführung aktualisieren und niemals / selten neu starten können (Sie können sogar den laufenden Kernel ohne Neustart wechseln, es ist nur schwierig genug, dass es nur aufgerufen wird für in zeitkritische Anwendungen).
Joelhardi
6
"Windows hat diese Funktion nicht" ... sind Sie sicher? Der NT-Kernel basiert auf dem Nachzählen von Objekten mit Handles und Referenzen.
Adam Mitz
10
Windows kann tatsächlich 3 Bits festlegen, die definieren, was ein anderer Prozess mit einer Datei tun kann, während diese geöffnet ist. Eine Datei kann gelöscht werden, während sie geöffnet ist, wenn das FILE_SHARE_DELETEBit gesetzt ist. Ich glaube nicht, dass der PE-Loader (der EXEs und DLLs lädt) dieses Bit setzt. Die Handles werden als Referenz gezählt und beim Löschen verschwindet die Datei, wenn das letzte Handle gelöscht wird. Der Unterschied zwischen diesem und Unix besteht jedoch darin, dass NT in diesem Fall verhindert, dass eine neue Datei mit demselben Namen erstellt wird.
Asveikau
2
Was Comonad sagt, ist völlig falsch. NTFS verwendet natürlich Hardlinks und hat es immer getan. In Windows Vista wurden Symlinks hinzugefügt. Es ist auch völlig falsch, dass Windows kein Ref-Copunting verwendet, sondern nur APIs wie CreateFile liest, in denen klar angegeben ist, unter welchen Umständen Dateien löschbar sind und so weiter. Und das ist auch der richtige Ort für die eigentliche Antwort auf die Frage: CreateFile hat ein Argument mit der Bezeichnung dwShareMode, das das obligatorische Sperren geöffneter Dateien steuert und Anwendungen entscheiden lässt. Der Standardwert ist eine exklusive Sperre ...
Thorsten Schöning
29

Soweit ich weiß, Linux tut Lock ausführbaren Dateien , wenn sie laufen - es aber die Schlösser Inode . Dies bedeutet, dass Sie die "Datei" löschen können, der Inode sich jedoch noch im Dateisystem befindet, unberührt bleibt und Sie nur einen Link löschen.

Unix-Programme verwenden diese Methode, um ständig über das Dateisystem nachzudenken, eine temporäre Datei zu erstellen, sie zu öffnen und den Namen zu löschen. Ihre Datei ist noch vorhanden, aber der Name wird für andere freigegeben, und niemand anderes kann ihn sehen.

Neil Williams
quelle
"die ganze Zeit"? Irgendwelche Beispiele?
Mez
4
Wenn Sie Google nach "Unix Secure Temporary File" fragen, finden Sie genügend Beschreibungen der Technik, um zu zeigen, dass sie bekannt und häufig verwendet wird. Ich habe zwar keine konkreten Beispiele, aber ich wage zu sagen, dass jede sicherheitsbewusste App, die temporäre Dateien verwendet, dies tut.
Dave Sherohman
26

Linux sperrt die Dateien. Wenn Sie versuchen, eine ausgeführte Datei zu überschreiben, wird "ETXTBUSY" (Textdatei beschäftigt) angezeigt. Sie können die Datei jedoch entfernen, und der Kernel löscht die Datei, wenn der letzte Verweis darauf entfernt wird. (Wenn der Computer nicht sauber heruntergefahren wurde, sind diese Dateien die Ursache für die Meldung "Gelöschter Inode hatte keine d-Zeit", wenn das Dateisystem überprüft wird. Sie wurden nicht vollständig gelöscht, da ein laufender Prozess einen Verweis auf sie hatte. und jetzt sind sie.)

Dies hat einige wesentliche Vorteile: Sie können einen laufenden Prozess aktualisieren, indem Sie die ausführbare Datei löschen, ersetzen und anschließend neu starten. Sogar init kann auf diese Weise aktualisiert werden, die ausführbare Datei ersetzen und ein Signal senden, und es wird selbst erneut ausgeführt (), ohne dass ein Neustart erforderlich ist. (Dies wird normalerweise automatisch von Ihrem Paketverwaltungssystem im Rahmen des Upgrades durchgeführt.)

Unter Windows scheint das Ersetzen einer verwendeten Datei ein großer Aufwand zu sein, der im Allgemeinen einen Neustart erfordert, um sicherzustellen, dass keine Prozesse ausgeführt werden.

Es kann einige Probleme geben, z. B. wenn Sie eine extrem große Protokolldatei haben und diese entfernen. Vergessen Sie jedoch, den Prozess, der in dieser Datei protokolliert wurde, anzugeben, um die Datei erneut zu öffnen. Sie enthält die Referenz, und Sie werden sich fragen warum Ihre Festplatte nicht plötzlich viel mehr freien Speicherplatz bekam.

Sie können diesen Trick auch unter Linux für temporäre Dateien verwenden. Öffnen Sie die Datei, löschen Sie sie und verwenden Sie die Datei weiter. Wenn Ihr Prozess beendet wird (egal aus welchem ​​Grund - auch bei Stromausfall), wird die Datei gelöscht.

Programme wie lsof und fuser (oder einfach nur in / proc // fd herumstöbern) können Ihnen zeigen, bei welchen Prozessen Dateien geöffnet sind, die keinen Namen mehr haben.


quelle
6

Ich denke, Linux / Unix verwendet nicht die gleiche Sperrmechanik, da sie von Grund auf als Mehrbenutzersystem aufgebaut sind - was die Möglichkeit erwarten würde, dass mehrere Benutzer dieselbe Datei verwenden, möglicherweise sogar für unterschiedliche Zwecke.

Gibt es einen Vorteil beim Sperren? Nun, es könnte möglicherweise die Anzahl der Zeiger reduzieren, die das Betriebssystem verwalten müsste, aber heutzutage ist die Menge an Einsparungen ziemlich vernachlässigbar. Der größte Vorteil, den ich mir beim Sperren vorstellen kann, ist folgender: Sie sparen einige vom Benutzer sichtbare Mehrdeutigkeiten. Wenn Benutzer a eine Binärdatei ausführt und Benutzer b sie löscht, muss die eigentliche Datei so lange bestehen bleiben, bis der Prozess von Benutzer A abgeschlossen ist. Wenn Benutzer B oder andere Benutzer im Dateisystem danach suchen, können sie es nicht finden - es nimmt jedoch weiterhin Speicherplatz ein. Für mich kein großes Problem.

Ich denke, es ist eher eine Frage der Abwärtskompatibilität mit den Dateisystemen von Windows.

Eric Tuttleman
quelle
"Windows" ist in diesem Zusammenhang die Windows NT-Zeile. Dies wurde als Mehrbenutzer-Nachfolger von Einzelbenutzer-Windows 3.11 konzipiert. Vergleichen Sie mit Unix, dem Einzelbenutzer-Nachfolger von Multics.
MSalters
6

Ich denke, Sie sind zu absolut in Bezug auf Windows. Normalerweise wird kein Swap-Speicherplatz für den Codeteil einer ausführbaren Datei zugewiesen. Stattdessen werden die auslösbaren & DLLs gesperrt. Wenn verworfene Codepages erneut benötigt werden, werden sie einfach neu geladen. Mit / SWAPRUN werden diese Seiten jedoch ausgetauscht. Dies wird für ausführbare Dateien auf CD- oder Netzwerklaufwerken verwendet. Daher muss Windows diese Dateien nicht sperren.

Informationen zu .NET finden Sie unter Schattenkopie .

MSalters
quelle
1

Ob ausgeführter Code in einer Datei gesperrt werden soll oder nicht, ist eine Entwurfsentscheidung, und MS hat sich einfach für das Sperren entschieden, da dies in der Praxis klare Vorteile bietet: Auf diese Weise müssen Sie nicht wissen, welcher Code in welcher Version von welcher Anwendung verwendet wird. Dies ist ein großes Problem mit dem Standardverhalten von Linux, das von den meisten Menschen einfach ignoriert wird. Wenn systemweite Bibliotheken ersetzt werden, können Sie nicht leicht erkennen, welche Apps den Code solcher Bibliotheken verwenden. In den meisten Fällen ist das Beste, was Sie erhalten können, dass der Paketmanager einige Benutzer dieser Bibliotheken kennt und sie neu startet. Aber das funktioniert nur für allgemeine und gut bekannte Dinge wie vielleicht Postgres und seine Bibliotheken oder so. Die interessanteren Szenarien sind, wenn Sie Ihre eigene Anwendung für einige Bibliotheken von Drittanbietern entwickeln und diese ersetzt werden, da der Paketmanager Ihre App meistens einfach nicht kennt. Und das' Dies ist nicht nur ein Problem mit nativem C-Code oder Ähnlichem, sondern kann auch bei fast allem auftreten: Verwenden Sie einfach httpd mit mod_perl und einigen Perl-Bibliotheken, die mit einem Paketmanager installiert wurden, und lassen Sie den Paketmanager diese Perl-Bibliotheken aus irgendeinem Grund aktualisieren. Ihr httpd wird nicht neu gestartet, nur weil er die Abhängigkeiten nicht kennt. Es gibt viele Beispiele wie dieses, einfach weil jede Datei möglicherweise Code enthalten kann, der zu jeder Laufzeit im Speicher verwendet wird. Denken Sie an Java, Python und all diese Dinge.

Es gibt also einen guten Grund, die Meinung zu vertreten, dass das Sperren von Dateien standardmäßig eine gute Wahl sein kann. Sie müssen diesen Gründen jedoch nicht zustimmen.

Was hat MS getan? Sie haben einfach eine API erstellt, mit der die aufrufende Anwendung entscheiden kann, ob Dateien gesperrt werden sollen oder nicht. Sie haben jedoch entschieden, dass der Standardwert dieser API darin besteht, der ersten aufrufenden Anwendung eine exklusive Sperre bereitzustellen. Schauen Sie sich die API rund um CreateFile und seine andwShareMode Argumente an. Dies ist der Grund, warum Sie möglicherweise nicht in der Lage sind, Dateien zu löschen, die von einer Anwendung verwendet werden. Ihr Anwendungsfall ist einfach egal, Sie haben die Standardwerte verwendet und daher von Windows eine exklusive Sperre für eine Datei erhalten.

Bitte glauben Sie nicht an Leute, die Ihnen etwas über Windows erzählen. Sie verwenden keine Ref-Zählung für GRIFFE oder unterstützen keine Hardlinks oder ähnliches, das ist völlig falsch. Fast jede API, die HANDLEs verwendet, dokumentiert ihr Verhalten in Bezug auf das Ref-Zählen, und Sie können in fast jedem Artikel über NTFS leicht lesen, dass es in der Tat Hardlinks unterstützt und dies immer getan hat. Seit Windows Vista werden auch Symlinks unterstützt, und die Unterstützung für Hardlinks wurde verbessert, indem APIs bereitgestellt wurden, mit denen alle für eine bestimmte Datei gelesen werden können usw. .

Darüber hinaus möchten Sie vielleicht einfach einen Blick auf die Strukturen werfen, die zur Beschreibung einer Datei in z. B. Ext4 verwendet werden, im Vergleich zu denen von NTFS , die viel gemeinsam haben. Beide arbeiten mit dem Konzept von Extents, das Daten von Attributen wie Dateinamen trennt, und Inodes sind so ziemlich nur ein anderer Name für ein älteres, aber ähnliches Konzept. Sogar Wikipedia listet beide Dateisysteme in seinem Artikel auf .

Im Vergleich zu anderen Betriebssystemen im Internet gibt es in Windows wirklich viel FUD beim Sperren von Dateien, genau wie bei der Defragmentierung. Einige dieser FUD können durch einfaches Lesen in der Wikipedia ausgeschlossen werden .

Thorsten Schöning
quelle
Das Geschwafel über die Versionsverwaltung von gemeinsam genutzten Abhängigkeiten ist irrelevant. Sie müssen sich mit diesen Problemen befassen, auch wenn für die Aktualisierung ein Neustart erforderlich ist. Unter Windows hat es sogar einen Namen: DLL Hölle. Darüber hinaus wird das von Ihnen beschriebene Laufzeitverhalten vollständig von Linux behandelt, bei dem die Datei bereits in den Speicher geladen ist und weiterhin verfügbar ist. Die Anwendung läuft mit der alten Version weiter, bis sie neu gestartet wird, genau wie wenn Windows einen Neustart erzwingt, um die Datei zu entsperren. An dieser Front gibt es keinen Vorteil.
jpmc26
Die DLL-Hölle geht natürlich völlig daneben und wir haben keine 90er mehr, lesen Sie einfach über Dinge wie WinSxSund so. Außerdem geht es nicht darum, Dinge in den Speicher zu laden und dort zu belassen. Windows macht genau das, wenn nötig, es geht darum zu wissen und zu entscheiden, ob Dateien ersetzt werden sollen oder nicht und wer dafür verantwortlich ist. Die Windows-API lässt einfach den ersten Benutzer der Datei entscheiden, und das ist sehr sinnvoll.
Thorsten Schöning
Aber das ist mein Punkt: Die Entscheidung, welche Version einer DLL verwendet werden soll, ist Teil der DLL-Hölle. Nennen Sie es "Abhängigkeitshölle", wenn Sie sich von einigen der alten eigenwilligen Verhaltensweisen von Windows unterscheiden möchten. Unabhängig davon hilft das standardmäßige Sperren ausführbarer Dateien beim Verwalten gemeinsam genutzter Abhängigkeiten nicht. Überhaupt. Die Dinge, die von einer bestimmten Datei abhängen, werden möglicherweise nicht einmal ausgeführt, wenn Sie versuchen, sie zu aktualisieren. Es gibt keine zusätzliche Sicherheit. Es gibt zwei Möglichkeiten mit gemeinsam genutzten Abhängigkeiten: Kostenlos für alle, bei denen die Gefahr besteht, dass beim Ausführen Probleme auftreten, oder beim Paketmanager, bei dem Sie möglicherweise nicht installiert werden.
jpmc26
Bei dieser Frage geht es nicht darum zu entscheiden, welche EXE oder DLL überhaupt verwendet werden soll, sondern darum, was danach standardmäßig passiert und warum. Sie diskutieren ein ganz anderes Thema. Das Sperren wird nach der Entscheidung verwendet, welche EXE- oder DLL-Datei ausgeführt werden soll, um vom ersten Benutzer, in diesem Beispiel Windows selbst, ein gewisses Maß an zusätzlicher Kontrolle zu erhalten und anderen von diesem Steuerelement zu erzählen. Und "andere" nicht aus irgendeinem Grund Dateien löschen oder in Windows schreiben zu lassen, die Windows benötigt, und sie daher sperrt, ist natürlich ein Mechanismus für zusätzliche Koordination.
Thorsten Schöning
1
Einige EXE- oder DLL-Dateien befinden sich höchstwahrscheinlich ohnehin nicht im Speicher, sind jedoch standardmäßig zugeordnet. Für die Zuordnung muss der Dateiinhalt verfügbar sein. Daher wird das willkürliche Ersetzen standardmäßig als unsicher angesehen, und man sollte wissen, was man tut. Was offensichtlich nicht der Fall ist, wenn man von gesperrten EXEs oder DLLs überrascht wird. OTOH, alle anderen Dateien sind standardmäßig nur gesperrt, nicht unbedingt, sodass Apps je nach Anwendungsfall entscheiden können, ob Sie Schreib- oder Löschvorgänge zulassen. App-Entwickler sollten besser als beliebige Benutzer wissen, wie sie ihre Dateien verwenden und welche Vorgänge wann sicher sind.
Thorsten Schöning
0

NT-Varianten haben die

offene Dateien

Befehl, der anzeigt, welche Prozesse Handles für welche Dateien haben. Es ist jedoch erforderlich, das globale Systemflag "Objektliste verwalten" zu aktivieren.

openfiles / local /?

erklärt Ihnen, wie dies zu tun ist und dass dadurch eine Leistungseinbuße entsteht.

Spender
quelle
0

Ausführbare Dateien werden beim Ausführen schrittweise dem Speicher zugeordnet. Dies bedeutet, dass Teile der ausführbaren Datei nach Bedarf geladen werden. Wenn die Datei vor dem Zuordnen aller Abschnitte ausgelagert wird, kann dies zu einer erheblichen Instabilität führen.

Ken Netherland
quelle