J'ai lu dans des ouvrages que Unix / Linux n'autorisait pas les liens physiques vers des répertoires mais autorisait les liens souples. Est-ce parce que, lorsque nous avons des cycles et que nous créons des liens physiques, et après quelque temps, nous supprimons le fichier d'origine, il va pointer sur une valeur erronée?
Si les cycles étaient la seule raison derrière ne pas autoriser les liens physiques, alors pourquoi les liens symboliques vers des répertoires sont-ils autorisés?
filesystems
directory
symlink
hard-link
utilisateur3539
la source
la source
..
pointer? Surtout après avoir supprimé le lien physique vers ce répertoire, dans le répertoire désigné par..
? Il doit pointer quelque part...
n'a pas besoin d'exister physiquement sur aucun lecteur. De toute façon, le travail du système d’exploitation est de garder une trace du répertoire de travail en cours. Il devrait donc être relativement simple de conserver également une liste des inodes associés à chaque cwd du processus et de s'y référer lorsqu’il voit une utilisation de..
. Bien sûr, cela voudrait dire que les liens symboliques devraient être créés dans cet esprit, mais vous devez déjà faire attention à ne pas les rompre, et je ne pense pas que cette règle supplémentaire les rendrait inutiles.Réponses:
Ceci est juste une mauvaise idée, car il n'y a aucun moyen de faire la différence entre un lien dur et un nom original.
Autoriser des liens physiques vers des répertoires briserait la structure de graphes acyclique dirigée du système de fichiers, créant éventuellement des boucles de répertoires et des sous-arborescences de répertoires pendantes, ce qui rendrait
fsck
toute autre arborescence de fichiers sujette aux erreurs.Tout d’abord, pour comprendre cela, parlons d’inodes. Les données du système de fichiers sont conservées dans des blocs sur le disque et ces blocs sont rassemblés par un inode. Vous pouvez considérer l'inode comme étant LE fichier. Les inodes manquent cependant de noms de fichiers. C'est là que les liens entrent en jeu.
Un lien est juste un pointeur sur un inode. Un répertoire est un inode qui contient des liens. Chaque nom de fichier dans un répertoire est simplement un lien vers un inode. Ouvrir un fichier sous Unix crée également un lien, mais il s'agit d'un type de lien différent (ce n'est pas un lien nommé).
Un lien physique est simplement une entrée de répertoire supplémentaire pointant vers cet inode. Lorsque vous
ls -l
, le nombre après les autorisations est le nombre de liens nommés. La plupart des fichiers normaux auront un lien. Créer un nouveau lien physique vers un fichier fera que les deux noms de fichiers pointent sur le même inode. Remarque:Maintenant, vous pouvez voir clairement qu’il n’existe pas de lien dur. Un lien dur est identique à un nom ordinaire. Dans l'exemple ci-dessus,
test
outest2
, quel est le fichier d'origine et quel est le lien physique? À la fin, vous ne pouvez pas vraiment dire (même par horodatage) car les deux noms désignent le même contenu, le même inode:Le
-i
drapeau àls
vous montre les numéros d’inode au début de la ligne. Notez commenttest
ettest2
avoir le même numéro d’inode, maistest3
un numéro différent.Maintenant, si vous étiez autorisé à le faire pour les répertoires, deux répertoires différents situés à des endroits différents du système de fichiers pourraient pointer vers la même chose. En fait, un sous-répertoire pourrait pointer vers son grand-parent, créant ainsi une boucle.
Pourquoi cette boucle est-elle une préoccupation? Parce que lorsque vous traversez, il n’ya aucun moyen de détecter que vous êtes en boucle (sans garder trace des numéros d’inodes pendant que vous traversez). Imaginez que vous écrivez la
du
commande, qui doit être recurse à travers des sous-répertoires pour en savoir plus sur l'utilisation du disque. Comment pourraitdu
savoir quand il a frappé une boucle? Il y a beaucoup d'erreurs dans la comptabilité et beaucoup de comptabilitédu
à faire, rien que pour réussir cette tâche simple.Les liens symboliques sont une toute autre bête, en ce qu'ils constituent un type de "fichier" spécial que de nombreuses API de système de fichiers ont tendance à suivre automatiquement. Notez qu'un lien symbolique peut pointer vers une destination inexistante, car ils pointent par nom et non directement sur un inode. Ce concept n'a pas de sens avec les liens durs, car la simple existence d'un "lien dur" signifie que le fichier existe.
Alors, pourquoi peut
du
traiter avec des liens symboliques facilement et non des liens durs? Nous avons pu voir ci-dessus que les liens physiques sont impossibles à distinguer des entrées de répertoire normales. Les liens symboliques, cependant, sont spéciaux, détectables et sautables!du
remarque que le lien symbolique est un lien symbolique et le saute complètement!la source
Allowing hard links to directories would break the directed acyclic graph structure of the filesystem
. Pouvez-vous s'il vous plaît expliquer plus sur le problème avec les cycles en utilisant des liens durs? Pourquoi est-ceA l'exception des points de montage, chaque répertoire a un parent et que:
..
.Une façon de faire
pwd
est de vérifier le périphérique: inode pour '.' et '..'. S'ils sont identiques, vous avez atteint la racine du système de fichiers. Sinon, trouvez le nom du répertoire en cours dans le parent, placez-le sur une pile et commencez à comparer '../.' avec '../ ..', puis '../../.' avec '../../ ..', etc. Une fois que vous avez frappé la racine, commencez à afficher et à imprimer les noms de la pile. Cet algorithme repose sur le fait que chaque répertoire a un et un seul parent.Si les liens en dur vers les annuaires étaient autorisés, lequel des nombreux parents devrait
..
pointer? C'est une des raisons impérieuses pour lesquelles les liens physiques en dur ne sont pas autorisés.Les liens symboliques vers les répertoires ne posent pas ce problème. Si un programme le souhaite, il peut faire un
lstat()
sur chaque partie du chemin et détecter quand un lien symbolique est rencontré. L'pwd
algorithme renverra le vrai chemin absolu pour un répertoire cible. Le fait qu'il y ait un morceau de texte quelque part (le lien symbolique) qui pointe vers le répertoire cible est à peu près sans importance. L'existence d'un tel lien symbolique ne crée pas de boucle dans le graphique.la source
..
qu’il s’agit d’une sorte de liaison virtuelle virtuelle avec le parent, il n’ya aucune raison technique pour que la cible du lien ne puisse avoir qu’un autre lien.pwd
devrait simplement utiliser un algorithme différent pour résoudre le chemin.Vous pouvez utiliser bind mount pour simuler des répertoires de liens durs
la source
J'aime ajouter quelques points supplémentaires à cette question. Les liens physiques pour les répertoires sont autorisés sous Linux, mais de manière restreinte.
Une façon de tester cela est lorsque nous listons le contenu d'un répertoire, nous trouvons deux répertoires spéciaux "." et "..". Comme nous le savons "." pointe vers le même répertoire et ".." pointe vers le répertoire parent.
Créons donc une arborescence de répertoires où "a" est le répertoire parent qui a pour répertoire "b".
Notez l'inode du répertoire "a". Et quand nous faisons un
ls -la
répertoire "a", nous pouvons voir cela "." Le répertoire pointe également vers le même inode.Et ici nous pouvons trouver que le répertoire "a" a trois liens durs. En effet, l'inode 797358 a trois liens durs au nom de "." à l'intérieur du répertoire "a" et nommez-le sous la forme ".." dans le répertoire "b" et l'un portant le nom "a" itslef.
Nous pouvons donc comprendre ici que les liens physiques ne sont là que pour que les répertoires se connectent avec leurs répertoires parent et enfant. Ainsi, un répertoire sans enfant n'aura que 2 liens durs, et le répertoire "b" n'aura que deux liens durs.
Une des raisons pour lesquelles la liaison en dur de répertoires a été librement empêchée serait d'éviter les boucles de référence infinies qui risqueraient de brouiller les programmes traversant le système de fichiers.
Comme le système de fichiers est organisé sous forme d'arborescence et que cette arborescence ne peut pas avoir de référence cyclique, cela aurait dû être évité.
la source
Aucune des raisons suivantes ne constitue la véritable raison pour interdire les liens physiques vers des répertoires; chaque problème est assez facile à résoudre:
La vraie raison (comme le suggère @ Thorbjørn Ravn Andersen) vient du fait que vous supprimez un répertoire comportant plusieurs parents, à partir du répertoire désigné par
..
:Que devrait
..
maintenant indiquer?Si le répertoire est supprimé de son parent mais que le nombre de liens est toujours supérieur à
0
ce qu'il doit être, il doit y avoir quelque chose, quelque part qui le pointe toujours. Vous ne pouvez pas laisser..
pointant à rien; de nombreux programmes reposent sur..
, de sorte que le système devrait parcourir tout le système de fichiers jusqu'à ce qu'il trouve la première chose qui pointe vers le répertoire supprimé, juste pour être mis à jour..
. Soit cela, soit le système de fichiers devrait maintenir une liste de tous les répertoires pointant vers un répertoire lié en dur.Dans les deux cas, il s'agirait d'un surcoût de performances et d'une complication supplémentaire pour les métadonnées et / ou le code du système de fichiers. Les concepteurs ont donc décidé de ne pas l'autoriser.
la source
..
), effectuez une mise..
à jour pour pointer sur l'un des autres parents de la liste.a/..
signifierait toujours.
. Voici comment fonctionnent les URL, au fait. C'est le navigateur qui résout '..' avant même d'apparaître sur le serveur. Et ça marche très bien.La création de liens physiques sur des répertoires serait irréversible. Supposons que nous ayons:
Je le lie au lien
/dir2
.Alors
/dir2
maintenant contient également tous ces fichiers et répertoiresEt si je change d'idée? Je ne peux pas juste
rmdir /dir2
(parce que c'est non vide)Et si je supprime récursivement dans
/dir2
... il sera également supprimé/dir1
!IMHO c'est une raison largement suffisante pour éviter cela!
Modifier :
Les commentaires suggèrent de supprimer le répertoire en le faisant
rm
. Maisrm
sur un répertoire non vide échoue et ce comportement doit rester, que le répertoire soit lié durement ou non. Donc, vous ne pouvez pas simplementrm
le dissocier. Il faudrait un nouvel argumentrm
, juste pour dire "si l'inode du répertoire a un nombre de références> 1, alors ne liez pas le répertoire".Ce qui, à son tour, enfreint un autre principe de moindre surprise: cela signifie que la suppression d'un répertoire hardlink que je viens de créer n'est pas la même chose que la suppression d'un fichier normal, hardlink ...
Je vais reformuler ma phrase: sans développement supplémentaire, la création de liens physiques serait irréversible (aucune commande en cours ne pouvant gérer la suppression sans être incohérente avec le comportement actuel).
Si nous autorisons plus de développement à gérer le cas, le nombre de pièges et le risque de perte de données si vous ne connaissez pas suffisamment le fonctionnement du système, un tel développement implique, est à mon humble avis un motif suffisant pour restreindre la liaison en dur aux répertoires.
la source
rm
qui est en dessous de toute façon (dissocier). Voir: unix.stackexchange.com/questions/151951/… Ce n’est vraiment pas un problème, pas plus qu’il ne l’est avec les fichiers à liens fixes . La suppression de la liaison supprime simplement la référence nommée et décrémente le nombre de liens. Le fait dermdir
ne pas supprimer les répertoires non vides n'a aucune importance - cela ne le ferait pas nondir1
plus. Les liens physiques ne sont pas des copies de données, mais le même fichier. Par conséquent, le fait de "supprimer" le fichier dir2 effacerait la liste des répertoires de dir1. Vous auriez toujours besoin de dissocier.rm
dans un répertoire , ne le dissociez pas s'il n'est pas vide. Voir Modifier.C'est une bonne explication. En ce qui concerne "Lequel des parents multiples devrait .. pointer du doigt?" Une solution serait qu'un processus conserve son chemin wd complet, sous forme d'inodes ou de chaînes. les inodes seraient plus robustes puisque les noms peuvent être changés. Au moins dans les temps anciens, il y avait un inode en cœur pour chaque fichier ouvert qui était incrémenté chaque fois qu'un fichier était ouvert, décrémenté lors de sa fermeture. Quand il atteindra zéro, le stockage indiqué sera libéré. Lorsque le fichier n'est plus ouvert par personne, il est abandonné. Cela conserverait le chemin comme valide si un autre processus déplaçait un répertoire dans un autre répertoire alors que le sous-répertoire se trouvait dans le chemin d'un autre processus. Semblable à la façon dont vous pouvez supprimer un fichier ouvert mais il est simplement supprimé du répertoire,
Auparavant, les répertoires de liaison en dur étaient librement autorisés dans UNIX des Bell Labs, au moins V6 et V7, je ne sais pas pour Berkeley ou pour une version ultérieure. Aucun drapeau requis. Pourriez-vous faire des boucles? Oui, ne fais pas ça. Ce que vous faites si vous faites une boucle est très clair. Nether devrait vous entraîner à nouer autour de votre cou pendant que vous attendez votre tour pour sauter en parachute hors de l’avion si vous avez l’autre extrémité accrochée à un crochet sur votre tête.
Ce que j’espérais en faire aujourd’hui, c’était de lier durablement mon domicile à mon domicile pour que je puisse avoir / home / administ disponible, que / home soit masqué ou non par un automout sur mon domicile, ce dernier ayant un lien symbolique nommé administ to / lhome / administ. Cela me permet d’avoir un compte administratif qui fonctionne quel que soit l’état de mon système de fichiers hôte principal. C'EST une expérience pour Linux, mais je pense appris à la fois pour les SunOS à base UCB qui sont faites au automount niveau de chaîne de caractères ASCII. Il est difficile de voir comment ils pourraient être réalisés autrement en tant que couche au-dessus de tout service extérieur arbitraire.
Je lis ailleurs que. et .. ne sont plus des fichiers dans le répertoire non plus. Je suis convaincu que tout cela a de bonnes raisons et qu'une grande partie de ce que nous apprécions (par exemple, être capable de monter des NTFS) est possible grâce à de telles choses, mais une partie de l'élégance d'UNIX réside dans sa mise en œuvre. Ce sont les avantages tels que la généralité et la malléabilité fournis par cette élégance qui lui ont permis d’être si robustes et d’être durables pendant quatre décennies. Au fur et à mesure que nous perdons les élégantes implémentations, il deviendra éventuellement comme Windows (j'espère me tromper!). Quelqu'un créerait alors un nouveau système d'exploitation basé sur des principes élégants. Quelque chose à quoi penser. Peut-être que je me trompe, je ne suis pas (évidemment) au courant de la mise en œuvre actuelle. il est C'est incroyable de voir à quel point 30 ans de compréhension sont applicables à Linux ... la plupart du temps!
la source
.
et..
ne sont pas dans le fichier-liens durs système, pour les systèmes de fichiers modernes. Cependant, le pilote du système de fichiers les imite. Ce sont ces systèmes de fichiers qui bloquent les répertoires de liens. Pour les anciens systèmes de fichiers, c'était possible (mais dangereux). Pour faire ce que vous essayez, regardezmount --bind
, voyezmount --make…
et peut-être aussi des conteneurs.D'après ce que je comprends, la raison principale est qu'il est utile de pouvoir modifier les noms de répertoire sans gâcher les programmes en cours d'exécution qui utilisent leur répertoire de travail pour référencer d'autres fichiers. Supposons que vous utilisiez Wine pour exécuter
~/.newwineprefix/drive_c/Program Files/Firefox/Firefox.exe
et que vous vouliez déplacer le préfixe entier vers~/.wine
. Si pour une raison étrange, Firefox accédaitdrive_c/windows
en se référant à../../windows
, le changement de nom~/.newwineprefix
interrompt les implémentations de..
cette trace du répertoire parent en tant que chaîne de texte au lieu d'un inode.Stocker l'inode d'un seul répertoire parent doit être plus simple que d'essayer de garder trace de chaque chemin en tant que chaîne de texte et série d'inodes.
Une autre raison est que les applications défectueuses peuvent créer des boucles. Les applications comportantes doivent pouvoir vérifier si l'inode du répertoire qui est déplacé est le même que celui de l'un des répertoires imbriqués dans lesquels il est déplacé, tout comme vous ne pouvez pas déplacer un répertoire vers lui-même, mais cela pourrait ne pas être appliqué au niveau du système de fichiers.
Une autre raison encore pourrait être que si vous pouviez créer des liens physiques, vous voudriez éviter de créer des liens physiques qui ne pourraient pas être modifiés.
find
a des considérations de sécurité car il est utilisé pour effacer les fichiers créés par d'autres utilisateurs des répertoires temporaires, ce qui peut poser problème si un utilisateur bascule un répertoire réel pour un lien symbolique alors qu'ilfind
appelle une autre commande. Pouvoir relier en dur des répertoires importants obligerait un administrateur à ajouter des tests supplémentairesfind
pour éviter de les affecter. (Ok, vous ne pouvez déjà pas faire cela pour les fichiers, donc cette raison est invalide.)Une autre raison encore est que le stockage de l'inode du répertoire parent peut fournir une redondance supplémentaire en cas de corruption ou de dommage du système de fichiers. Si vous souhaitez
..
répertorier tous les répertoires parents ayant un lien physique vers celui-ci, un parent différent et arbitraire pourrait donc être facilement trouvé si le répertoire actuel est dissocié. le système de fichiers stocke et utilise les inodes. Avoir des programmes traitant les chemins comme une série (unique pour chaque lien physique) d'inodes de répertoire éviterait cela, mais vous ne pourriez pas obtenir la redondance en cas de dommage du système de fichiers.la source