Unix-Systeme versagen normalerweise nur dann, wenn sie mit einem Pfad konfrontiert werden, der eine Symlink-Schleife enthält, oder wenn zu viele Symlinks vorhanden sind, da die Anzahl der Symlinks, die sie in einer Pfadsuche durchlaufen, begrenzt ist. Aber gibt es eine Möglichkeit, tatsächlich zu entscheiden, ob ein bestimmter Pfad zu etwas aufgelöst wird oder eine Schleife enthält, selbst wenn er mehr Links enthält, als ein Unix bereit ist, zu folgen? Oder ist das ein formal unentscheidbares Problem? Und wenn es entschieden werden kann, kann es in einem angemessenen Zeitraum / Speicher entschieden werden (z. B. ohne alle Dateien auf einem Dateisystem besuchen zu müssen)?
Einige Beispiele:
a/b/c/d
where a/b is a symlink to ../e
and e is a symlink to f
and f is a symlink to a/b
a/b/c/d
where a/b/c is a symlink to ../c
a/b/c/d
where a/b/c is a symlink to ../c/d
a/b/c/d
where a/b/c is a symlink to /a/b/e
where a/b/e is a symlink to /a/b/f
where a/b/f is a symlink to /a/b/g
Bearbeiten :
Um dies zu verdeutlichen, frage ich nicht nach Schleifen im Dateisystem, sondern nach einem Entscheidungsalgorithmus, der über einen bestimmten Pfad entscheidet, ob er in eine bestimmte Datei / ein bestimmtes Verzeichnis aufgelöst wird oder ob er überhaupt nicht aufgelöst wird. In dem folgenden System gibt es beispielsweise eine Schleife, der angegebene Pfad wird jedoch weiterhin ordnungsgemäß aufgelöst:
/ -- a -- b
where b is a symlink to /a
Dieser Verzeichnisbaum hat eindeutig einen Zyklus, aber der Pfad wird a/b/b/b/b/b
trotzdem gut aufgelöst /a
.
quelle
readlink ...
zu den oben genannten Situationen?Antworten:
Ich verstehe nicht ganz, was Sie fragen. Wenn ich es nicht besser wüsste, haben Sie sich wahrscheinlich gefragt, ob es eine Möglichkeit gibt, dies während des Umgangs mit einer Datei zu erkennen. Ich glaube nicht, dass das möglich ist.
Die einzige Methode, die ich mir vorstellen kann, ist das Durchsuchen eines bestimmten Zweigs im Verzeichnisbaum.
Beispiel
Der
find
Befehl erkennt diese Schleife, sagt Ihnen aber nicht wirklich viel darüber.Ich habe willkürlich 15 Stufen ausgewählt, um die Ausgabe der zu blockieren
find
. Sie können diesen Schalter (-mindepth
) jedoch fallen lassen, wenn Sie sich nicht für den angezeigten Verzeichnisbaum interessieren. Derfind
Befehl erkennt die Schleife weiterhin und stoppt:Übrigens , wenn Sie die Standardeinstellung außer Kraft zu setzen ,
MAXSYMLINKS
die scheinbar 40 auf Linux (neuere 3.x Versionen des Kernels) ist , dass Sie diese U & L sehen Q & A Titel: How do you MAXSYMLINKS erhöhen .Verwenden Sie den Befehl symlinks
Es gibt ein Tool, das von Betreuern von FTP-Sites verwendet werden kann.
symlinks
Mit diesem Tool können Probleme mit langen oder baumelnden Bäumen aufgedeckt werden, die durch symbolische Links verursacht wurden.In bestimmten Fällen kann das
symlinks
Tool auch verwendet werden, um störende Links zu löschen.Beispiel
Die glibc Bibliothek
Die glibc-Bibliothek scheint einige C-Funktionen zu bieten, aber ich weiß nicht genau, welche Rolle sie spielt oder wie man sie tatsächlich benutzt. Deshalb kann ich Sie nur darauf hinweisen.
Die Manpage
man symlink
zeigt die Funktionsdefinition für eine aufgerufene Funktionsymlink()
. Die Beschreibung lautet wie folgt:Einer der Fehler besagt, dass diese Funktion Folgendes zurückgibt:
Ich werde Sie auch auf die Manpage weiterleiten, auf
man path_resolution
der erläutert wird, wie Unix die Pfade zu Elementen auf der Festplatte ermittelt. Speziell dieser Absatz.quelle
OK, nach einigem Nachdenken denke ich, ich habe eine klare Lösung.
Die entscheidende Erkenntnis ist, dass, wenn jeder Link, der Teil eines Pfades ist, zu etwas aufgelöst wird, der gesamte Pfad aufgelöst wird. Oder umgekehrt, wenn sich ein Pfad nicht auflöst, muss es einen bestimmten Symlink geben, der eine Überquerung erfordert, die sich nicht auflöst.
Während ich zuvor über dieses Problem nachdachte, verwendete ich einen Algorithmus, der Elemente eines Pfades ab dem Stammverzeichnis durchlief. Als er auf einen Symlink stieß, ersetzte er dieses Pfadelement durch den Inhalt des Symlinks und fuhr dann mit dem Durchlaufen fort. Da sich dieser Ansatz nicht daran erinnert, welcher Symlink gerade aufgelöst wird, kann er nicht erkennen, ob er sich in einer nicht auflösenden Schleife befindet.
Wenn der Algorithmus nachverfolgt, welchen Symlink er gerade auflöst (oder welche Symlinks bei rekursiven Links), kann er erkennen, ob er versucht, einen Link rekursiv wieder aufzulösen, der noch aufgelöst wird.
Algorithmus:
bearbeiten :
Ich habe eine funktionierende Implementierung in Python unter https://bitbucket.org/JanKanis/python-inotify/src/853ed903e870cbfa283e6ce7a5e41aeffe16d4e7/inotify/pathresolver.py?at=pathwatcher .
quelle
Python hat eine Funktion namens networkx.simple_cycles (), die dafür verwendet werden kann. Aber ja, es müsste jede Datei auf dem System lesen.
quelle
Auf einem stillstehenden System (dh wenn keine Änderungen stattfinden) gibt es einen Algorithmus. Es gibt eine endliche Anzahl symbolischer Verknüpfungen, daher bilden sie einen endlichen Graphen, und das Erkennen von Zyklen ist ein endlicher Prozess.
Auf einem Live-System gibt es keine Möglichkeit, Zyklen zu erkennen, da sich symbolische Verknüpfungen ändern können, während der Zyklusdetektor ausgeführt wird. Das Lesen jeder symbolischen Verknüpfung ist atomar, das Lesen einer symbolischen Verknüpfung jedoch nicht. Wenn sich einige Symlinks ständig ändern, während der Kernel den Durchlauf durchführt, könnte dies auf einem unendlichen Pfad enden, der verschiedene Links beinhaltet.
quelle
Soweit ich aus aktuellen Linux-Kernel-Quellen ersehen kann, zählt der Kernel nur, wie viele Links verfolgt werden, und es tritt ein Fehler auf, wenn diese größer als eine bestimmte Anzahl sind. Siehe Zeile 1330 in namei.c für den Kommentar und die
nested_symlink()
Funktion. Das ELOOP-Makro (die Fehlernummer, die von einemread(2)
Systemaufruf für diese Situation zurückgegeben wurde) wird an mehreren Stellen in dieser Datei angezeigt, sodass es möglicherweise nicht so einfach ist, die folgenden Links zu zählen, aber das ist sicher, wie es aussieht.Es gibt eine Reihe von Algorithmen zum Auffinden von "Zyklen" in verknüpften Listen ( Floyd's Cycle Detection-Algorithmus ) oder in gerichteten Diagrammen . Mir ist nicht klar, welchen Vorgang Sie ausführen müssen, um eine tatsächliche "Schleife" oder einen "Zyklus" in einem bestimmten Pfad zu erkennen. In jedem Fall kann die Ausführung der Algorithmen einige Zeit in Anspruch nehmen. Wenn Sie also nur die Anzahl der symbolischen Verknüpfungen zählen, sind Sie zu 90% am Ziel.
quelle