Ich habe die folgenden Befehle in der angegebenen Reihenfolge ausgeführt:
$ln a b
$ls -i a b
523669 a 523669 b
$rm -f a
$ls -i b
523669 b
Ich bin aus diesem Test zu dem Schluss gekommen, dass der Befehl rm
tatsächlich nur den Dateinamen ( a
in diesem Test) anstelle der Datei entfernt, da der Inode noch vorhanden ist und über einen anderen Dateinamen ( b
) abgerufen werden kann .
Meine Frage ist, ob, wenn eine Datei fest mit nur einem Dateinamen verknüpft ist, wenn zur Datei rm
ausgeführt wird, die echte Datei (dh der Inode) vollständig entfernt wird? Und wenn nicht, kann ein Datei-Inode ohne Dateinamen und nur über den Inode abgerufen werden?
Antworten:
Wenn Sie versuchen, eine Datei über ihren Inode zu öffnen, wird die Verzeichnisüberquerung umgangen. Die Verzeichnisdurchquerung ist erforderlich, um die Berechtigungen der Datei und der dazu führenden Verzeichnisse zu bestimmen. Ohne Directory Traversal kann der Kernel nicht feststellen, ob der aufrufende Prozess auf die Datei zugreifen darf.
Es wurde ein Patch für den Linux-Kernel vorgeschlagen, mit dem über einen Dateideskriptor ein Link zu einer Datei erstellt werden kann . Es wurde abgelehnt, weil die sichere Implementierung extrem schwierig gewesen wäre .
Unter Linux (und wahrscheinlich auch unter anderen Unix-Varianten aus demselben Grund) können Sie keine Verknüpfung zu einer gelöschten Datei erstellen. Wenn also eine Datei keinen Namen mehr hat, können Sie keine neue hinzufügen.¹ Sie können eine gelöschte öffnen Datei durch Öffnen der Magic Links unter
/proc/$pid/fd/
.Wenn eine Datei keinen Link mehr hat und nicht mehr geöffnet ist, ist sie nicht mehr vorhanden und der zuvor von ihren Daten verwendete Speicherplatz kann jederzeit zurückgefordert werden.
¹ Möglicherweise können Sie dies tun, indem Sie die Bytes direkt im Dateisystem dateisystemabhängig drehen, z. B. mit
debugfs
ext2 / ext3 / ext4. Dies erfordert den Zugriff auf das Gerät, auf dem das Dateisystem eingehängt ist (dh normalerweise kann es nur Root versuchen). Während Debugfs über Inode auf eine Datei zugreifen können, hilft dies nicht, wenn die Datei gelöscht wird: Die Datei wird wirklich gelöscht, wenn die Anwendung sie schließt, und das Ausführen von Debugfs im Lese- / Schreibmodus auf einem bereitgestellten Dateisystem ist ein Rezept für Katastrophe.quelle
Unter Linux bietet
debugfs
der interaktive Debugger fürln
das Dateisystem ext2 / ext3 / ext4 einen Befehl, der eine Inode-Nummer annehmenfilespec
und eine neue feste Verbindung zur entsprechenden Datei herstellen kann. In der Praxis erfordert dies jedoch, dass die nicht verknüpfte Datei von einem Prozess geöffnet bleibt und ein offener Dateideskriptor in beibehalten wird/proc/[pid]/fd/[n]
. Der Versuch, dies für eine gelöschte Datei zu tun, führt höchstwahrscheinlich zu einer Beschädigung des Dateisystems.Dies liegt daran, dass, um sicherzustellen, dass ext3 (und in der Erweiterung ext4) eine Verknüpfung nach einem Absturz sicher wiederherstellen können , die Blockzeiger im Inode auf Null gesetzt werden , während ext2 diese Blöcke in den Blockbitmaps nur als unbenutzt markiert und die inode als "gelöscht" und lässt die Blockzeiger in Ruhe. Da das Dateisystem jedoch mit Lese- und Schreibzugriff bereitgestellt werden muss, um die feste Verknüpfung zu erstellen, wurden die für die gelöschte Datei reservierten Blöcke möglicherweise bereits neu zugewiesen.
Vor der Kernel-Version 2.6.39 konnte mit der in GNU coreutils 8.0 eingeführten Option eine nicht verknüpfte Datei über einen offenen Dateideskriptor wiederhergestellt werden, wenn sich sowohl die nicht verknüpfte Datei als auch der neue Hardlink auf einem tmpfs- Dateisystem befanden . Diese Funktion wurde seitdem deaktiviert , da, wie Gilles betonte, Sicherheitsaspekte bei der Erstellung von Hardlinks direkt aus einem Dateideskriptor heraus berücksichtigt wurden.
ln
-L|--logical
/proc/[pid]/fd/[n]
quelle
ln -L
, eine gelöschte Datei aus / proc wiederherzustellen und habe den Fehler erhalten: "Keine solche Datei oder kein solches Verzeichnis", daher glaube ich nicht, dass dies tatsächlich unterstützt wird. Ich habe Coreutils 8.21.ln -L
tut nicht, was du sagst. Es sagt ,ln
dass , wenn die Quelle eine symbolische Verknüpfung ist, sollte es das Ziel hart verknüpfen. Die symbolischen Links in/proc/$pid/fd
sind speziell, und das feste Verknüpfen eines(deleted)
Links funktioniert nicht.debugfs
hilft auch nicht, wenn die Datei gelöscht wurde - es sei denn, Sie möchten riskieren, dass sie im Lese- / Schreibmodus auf einem bereitgestellten Dateisystem ausgeführt wird, wodurch wahrscheinlich das gesamte Dateisystem vollständig zerstört wird.ln -L
. Früher war/proc/[pid]/fd/[n]
es unter bestimmten Umständen möglich, feste Verknüpfungen zu erstellen , dies wurde jedoch inzwischen behoben.debugfs
'sln
ist wirklich niedrig und erstellt nur einen Namen, aktualisiert die Anzahl nicht und hebt die Markierung der Blöcke als nicht verwendet auf, sodass es sehr gefährlich ist . Bevorzugendebugfs
‚sundel
die das alles. Achtung:debugfs
wird nicht ausgeführt wird auf einem Dateisystem gemountet , wenn Sie eine Chance auf dem Brennen FS zu Asche nehmen.Die Befehle 'ln' und 'rm' haben seit Anfang der 1970er Jahre in jedem UNIX-Dateisystem genau so funktioniert. Mac OSX, BSD und Linux erben alle dieses ursprüngliche Design.
Eine UNIX-Datei selbst hat keinen Namen, nur eine Inode- Nummer oder eine Inum. Sie können jedoch nur über einen Eintrag in einer speziellen "Verzeichnis" -Datei darauf zugreifen, die der fraglichen inum einen Namen zuordnet. Sie können die Inum nicht direkt angeben.
Ein Verzeichnis ist selbst eine Datei, so dass Sie auch zugreifen , müssen sie durch (anderes) Verzeichnis und so weiter, durch eine Reihe von Verzeichnisnamen durch Schrägstriche begrenzt (/) als „Pfadname“ bekannt. Ein Pfad beginnt im "aktuellen Arbeitsverzeichnis" des Prozesses, es sei denn, der Name beginnt mit einem "/". In diesem Fall beginnt er mit dem Stammverzeichnis des Dateisystems. Wenn der Pfadname beispielsweise keine "/" -Zeichen enthält, wird ein Eintrag im aktuellen Verzeichnis erwartet.
Eine Nicht-Verzeichnis-Datei kann eine beliebige Anzahl von Pfadnamen haben, die als "harte Verknüpfungen" bezeichnet werden. Sie bleibt bestehen, bis alle Pfadnamen entfernt wurden und der letzte Prozess die Datei geschlossen hat. Dann wird die Datei tatsächlich gelöscht und ihr Speicherplatz als zur Wiederverwendung verfügbar markiert. Das heißt, Sie können eine einfach verknüpfte Datei erstellen () oder öffnen () und dann die Verknüpfung aufheben (), sodass sie nicht mehr im Namensraum des Dateisystems angezeigt wird. Die Datei bleibt jedoch bestehen, bis Sie sie schließen. Dies ist nützlich für temporäre Arbeitsdateien, die von keinem anderen Programm gelesen werden.
Obwohl Verzeichnisse über Inode-Nummern verfügen, lassen die meisten Dateisysteme keine festen Verknüpfungen zu. Sie können nur in einem anderen Verzeichnis angezeigt werden. (Eine ungewöhnliche Ausnahme ist das Mac OSX HFS + -Dateisystem. Dadurch können Time Machine-Sicherungen ausgeführt werden.) Sie können weiterhin "Softlinks" zu Verzeichnissen (oder anderen Dateien) erstellen. Ein Softlink ähnelt einem Verzeichniseintrag, enthält jedoch keinen inum, sondern einen anderen Pfadnamen.
Jede UNIX-Datei verfügt über Eigentümer-, Gruppen- und Zugriffsberechtigungen. Es ist notwendig, aber nicht ausreichend, dass Sie die Datei öffnen können. Sie müssen außerdem für jedes Verzeichnis in dem Pfadnamen, auf den Sie verweisen, mindestens über Ausführungsberechtigungen verfügen. Aus diesem Grund gibt es keine Standardmethode zum Öffnen einer UNIX-Datei anhand ihrer Inode-Nummer. das würde einen wichtigen, weit verbreiteten Sicherheitsmechanismus umgehen.
Dies erklärt jedoch nicht, warum es für einen (privilegierten) Root- Benutzer keine Standardmethode zum Öffnen einer Datei nach Inode-Nummer gibt, da die Berechtigungsprüfung ohnehin umgangen wird. Dies wäre für bestimmte Systemverwaltungsfunktionen wie z. B. Sicherungen sehr nützlich. Meines Wissens existieren solche Mechanismen, aber sie sind alle dateisystemspezifisch. Es gibt keine allgemeine Möglichkeit, dies für ein UNIX-Dateisystem zu tun.
quelle
/
ist stumm, daher wird es als "Schrägstrich" ausgesprochen.Die Frage kann theoretisch (was mit erreicht werden kann
debugfs
) oder pragmatisch (Notfallsituation) gestellt werden. Im letzteren Fall gehe ich davon aus, dass die Absicht darin besteht, den Tag zu retten und den Inhalt der Datei möglicherweise dringend wiederherzustellen (so bin ich auf diese Frage gestoßen, und ich denke, dass sie immer noch relevant und nützlich ist).Da es keine Kernel-API gibt,
debugfs
sollte diese nicht auf einem Live-Dateisystem ausgeführt werden, da sie die FS-Struktur direkt manipuliert. Um es live zu machen, müssen Sie sich daher einen anderen Dateinamen besorgen. Angenommen, die Datei ist noch von einem Prozess (einem beliebigen Prozess) geöffnet, können Sie nach den immer praktischen Dateideskriptoren in den folgenden Abschnitten suchen/proc
:Tipps:
file
auf sie ausführentail -f < /proc/$pid/fd/$fd > /dev/null
, den Schreibvorgang zu beenden, damit er sauber beendet wird, und das fd des neuen Prozesses zu verwenden.quelle
tail -f < /proc/...
im zweiten Tipp stehen.tail -c +0 -f
um es an erster Stelle zu kopieren, anstattcat
, wenn der Schreibvorgang nur angehängt wird (kein Zurücksuchen und Neuschreiben). Beenden Sie den anderen Prozess zuvortail
und warten Sietail
, bis die Datei fertig ist.