Les systèmes Unix génèrent généralement des erreurs s'ils sont confrontés à un chemin qui contient une boucle de liens symboliques ou tout simplement trop de liens symboliques, car ils ont une limite au nombre de liens symboliques qu'ils traverseront dans une recherche de chemin. Mais existe-t-il un moyen de réellement décider si un chemin donné se résout en quelque chose ou contient une boucle, même s'il contient plus de liens qu'un Unix est prêt à suivre? Ou est-ce un problème formellement indécidable? Et si cela peut être décidé, peut-il être décidé dans une quantité raisonnable de temps / mémoire (par exemple sans avoir à visiter tous les fichiers sur un système de fichiers)?
Quelques exemples:
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
Modifier :
Pour clarifier, je ne demande pas de trouver des boucles dans le système de fichiers, je demande un algorithme de décision qui décide d'un chemin donné s'il se résout en un fichier / répertoire défini ou s'il ne se résout pas du tout. Par exemple, dans le système suivant, il y a une boucle, mais le chemin donné se résout toujours bien:
/ -- a -- b
where b is a symlink to /a
Cette arborescence de répertoires a clairement un cycle, mais le chemin a/b/b/b/b/b
se résout toujours bien /a
.
la source
readlink ...
sur les situations ci-dessus?Réponses:
Je ne comprends pas bien ce que vous demandez. Si je ne savais pas mieux, je pense que vous demandiez s'il y avait un moyen de détecter cela pendant que vous traitez un fichier. Je ne pense pas que ce soit possible.
La seule méthode que je peux concevoir est de faire une recherche où vous commencez spécifiquement à parcourir une branche particulière de l'arborescence des répertoires.
Exemple
La
find
commande détectera cette boucle mais ne vous en dira pas beaucoup à ce sujet.J'ai arbitrairement choisi 15 niveaux afin de bloquer toute sortie affichée par le
find
. Vous pouvez cependant supprimer ce commutateur (-mindepth
) si vous ne vous souciez pas de l'arborescence de répertoires affichée. Lafind
commande détecte toujours la boucle et s'arrête:Soit dit en passant , si vous souhaitez remplacer la valeur par défaut
MAXSYMLINKS
qui est apparemment 40 sur Linux (les versions 3.x plus récentes du noyau), vous pouvez voir cette Q&R U&L intitulée: Comment augmenter MAXSYMLINKS .Utilisation de la commande de liens symboliques
Il existe un outil que les responsables du site FTP pourraient utiliser, appelé,
symlinks
qui aidera à exposer les problèmes liés aux arbres longs ou pendants qui ont été causés par des liens symboliques.Dans certains cas, l'
symlinks
outil peut également être utilisé pour supprimer les liens incriminés.Exemple
La bibliothèque glibc
La bibliothèque glibc cherche à offrir quelques fonctions C autour de cela, mais je ne connais pas entièrement leur rôle ni comment les utiliser réellement. Je ne peux donc que vous les signaler.
La page de manuel
man symlink
montre la définition de la fonction d'une fonction appeléesymlink()
. La description va comme ceci:L'une des erreurs indique que cette fonction renvoie:
Je vous dirigerai également vers la page de manuel,
man path_resolution
qui explique comment Unix détermine les chemins d'accès aux éléments sur le disque. Plus précisément ce paragraphe.la source
OK, après réflexion, je pense avoir une solution claire.
L'idée critique est que si chaque lien faisant partie d'un chemin se résout en quelque chose, alors le chemin entier se résout. Ou l'inverse, si un chemin ne se résout pas, il doit y avoir un lien symbolique spécifique qui nécessite une traversée qui ne se résout pas.
En pensant à ce problème auparavant, j'utilisais un algorithme qui traversait les éléments d'un chemin à partir de la racine, et lorsqu'il rencontrait un lien symbolique, il remplaçait cet élément de chemin par le contenu du lien symbolique, puis continuait à parcourir. Étant donné que cette approche ne se souvient pas du lien symbolique qu'elle est en train de résoudre, elle ne peut pas détecter lorsqu'elle se trouve dans une boucle non résolue.
Si l'algorithme garde la trace du lien symbolique qu'il est en train de résoudre (ou de quels liens symboliques en cas de liens récursifs), il peut détecter s'il tente de résoudre récursivement un lien qu'il est toujours en train de résoudre.
Algorithme:
modifier :
J'ai une implémentation fonctionnelle de cela en python à https://bitbucket.org/JanKanis/python-inotify/src/853ed903e870cbfa283e6ce7a5e41aeffe16d4e7/inotify/pathresolver.py?at=pathwatcher .
la source
Python a une fonction appelée networkx.simple_cycles () qui peut être utilisée pour cela. Mais oui, il faudrait lire tous les fichiers du système.
la source
Sur un système au repos (c'est-à-dire quand aucun changement n'a lieu), oui, il y a un algorithme. Il existe un nombre fini de liens symboliques, ils constituent donc un graphe fini, et la détection des cycles est un processus finitaire.
Sur un système sous tension, il n'y a aucun moyen de détecter les cycles, car les liens symboliques peuvent changer pendant que le détecteur de cycle fonctionne. La lecture de chaque lien symbolique est atomique, mais suivre un lien symbolique ne l'est pas. Si certains liens symboliques continuent de changer pendant que le noyau effectue la traversée, il pourrait se retrouver sur un chemin infini impliquant des liens distincts.
la source
Autant que je sache en regardant les sources actuelles du noyau Linux, tout ce que fait le noyau, c'est de compter le nombre de liens qu'il suit, et il se trompe s'il est plus grand qu'un certain nombre. Voir la ligne 1330 dans namei.c pour le commentaire et la
nested_symlink()
fonction. La macro ELOOP (le numéro d'erreur renvoyé par unread(2)
appel système pour cette situation) apparaît à plusieurs endroits dans ce fichier, donc ce n'est peut-être pas aussi simple que de compter les liens suivis, mais c'est sûr à quoi cela ressemble.Il existe un certain nombre d'algorithmes pour trouver des "cycles" dans des listes chaînées ( algorithme de détection de cycle de Floyd ) ou dans des graphiques dirigés . Pour moi, je ne sais pas lequel il faudrait faire pour détecter une "boucle" ou un "cycle" réel dans un chemin particulier. Dans tous les cas, les algorithmes peuvent prendre du temps à s'exécuter, donc je suppose que le simple fait de compter le nombre de liens symboliques suivis vous permet d'atteindre 90% de votre objectif.
la source