Pourquoi les liens physiques vers les directorys ne sont-ils pas autorisés sous UNIX / Linux?

Je lis dans des manuels que Unix / Linux n'autorise pas les liens durs vers les directorys mais autorise les liens logiciels. Est-ce parce que, lorsque nous avons des cycles et que nous créons des liens durs, et après un certain time, nous supprimons le file original, il indiquera une valeur de déchet?

Si les cycles étaient la seule raison de ne pas autoriser les liens durs, pourquoi les liens mous vers les directorys sont-ils autorisés?

    C'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.

    Permettre des liens vers des directorys briserait la structure graphique acyclique dirigée du système de files, créant éventuellement des loops de directory et des sous-arborescences de directorys pendantes, ce qui rendrait fsck et tout autre tree de files vulnérable.

    Tout d'abord, pour comprendre cela, parlons d'inodes. Les données du système de files sont stockées dans des blocs sur le disque, et ces blocs sont rassemblés par un inode. Vous pouvez penser à l'inode comme le file. Les Inodes manquent de noms de files, cependant. C'est là que les liens entrent en jeu.

    Un lien est juste un pointeur vers un inode. Un directory est un inode qui contient des liens. Chaque nom de file dans un directory est juste un lien vers un inode. Ouvrir un file dans Unix crée également un lien, mais c'est un type de lien différent (ce n'est pas un lien nommé).

    Un lien dur est juste une input de directory supplémentaire pointant vers cet inode. Lorsque ls -l , le nombre après les permissions est le nombre de liens nommé. La plupart des files réguliers auront un lien. La création d'un nouveau lien physique vers un file fera pointer les deux noms de files vers le même inode. Remarque:

     % ls -l test ls: test: No such file or directory % touch test % ls -l test -rw-r--r-- 1 danny staff 0 Oct 13 17:58 test % ln test test2 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 % touch test3 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3 ^ ^ this is the link count 

    Maintenant, vous pouvez voir clairement qu'il n'y a pas de lien physique. Un lien physique est identique à un nom normal. Dans l'exemple ci-dessus, test ou test2 , qui est le file original et qui est le lien dur? À la fin, vous ne pouvez pas vraiment dire (même par horodatage) parce que les deux noms désignent le même contenu, le même inode:

     % ls -li test* 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 14445892 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3 

    Le drapeau -i à ls vous montre les numéros d'inode au début de la ligne. Notez comment test et test2 ont le même numéro d'inode, mais test3 a un différent.

    Maintenant, si vous étiez autorisé à faire cela pour les directorys, deux directorys différents dans différents points du système de files pourraient pointer la même chose. En fait, un subdir pourrait renvoyer à ses grands-parents, créant une boucle.

    Pourquoi cette boucle est-elle une préoccupation? Parce que lors de la traversée, il n'y a aucun moyen de détecter que vous faites une boucle (sans tenir count des numéros d'inode que vous traversez). Imaginez que vous écrivez la command du , qui doit recourir à des sous-dossiers pour connaître l'utilisation du disque. Comment saurais-tu quand il a frappé une boucle? C'est une question d'erreurs et beaucoup de comptabilité que vous auriez à faire, juste pour accomplir cette tâche simple.

    Les liens symboliques sont une bête complètement différente, en ce sens qu'ils sont un type particulier de "file" que de nombreuses API de files ont tendance à suivre automatiquement. Notez qu'un lien symbolique peut pointer vers une destination inexistante, car ils pointent par nom et non directement vers un inode. Ce concept n'a pas de sens avec les liens durs, parce que la simple existence d'un "lien dur" signifie que le file existe.

    Alors pourquoi peut-on gérer facilement des liens symboliques et non des liens durs? Nous avons pu voir ci-dessus que les liens durs ne peuvent pas être distingués des inputs de directory normales. Les liens symboliques, cependant, sont spéciaux, détectables et désactivables! du remarque que le lien symbolique est un lien symbolique, et le saute complètement!

     % ls -l total 4 drwxr-xr-x 3 danny staff 102 Oct 13 18:14 test1/ lrwxr-xr-x 1 danny staff 5 Oct 13 18:13 test2@ -> test1 % du -ah 242M ./test1/bigfile 242M ./test1 4.0K ./test2 242M . 

    À l'exception des points de assembly, chaque directory possède un seul parent: ..

    Une façon de faire pwd est de vérifier le périphérique: inode pour '.' et '..'. Si elles sont identiques, vous avez atteint la racine du système de files. Sinon, searchz le nom du directory actuel dans le parent, poussez-le sur une stack et commencez à comparer '../.' avec '../ ..', alors '../../.' avec '../../ ..', etc. Une fois que vous avez touché la racine, commencez à afficher et imprimer les noms de la stack. Cet algorithm repose sur le fait que chaque directory a un et un seul parent.

    Si les liens durs vers les directorys étaient autorisés, lequel des parents multiples devrait indiquer? C'est une raison impérieuse pour laquelle les liens vers les directorys ne sont pas autorisés.

    Les liens symboliques vers les directorys ne provoquent pas ce problème. Si un programme le souhaite, il peut faire un lstat() sur chaque partie du nom de path et détecter quand un lien symbolique est rencontré. L'algorithm pwd returnnera le vrai path absolu pour un directory cible. Le fait qu'il y ait un bout de text quelque part (le lien symbolique) qui pointe vers le directory cible est peu pertinent. L'existence d'un tel lien symbolique ne crée pas de boucle dans le graphique.

    Vous pouvez utiliser bind mount pour simuler des directorys de binding

     sudo mount --bind /some/existing_real_contents /else/dummy_but_existing_directory sudo umount /else/dummy_but_existing_directory 

    J'aime append quelques points supplémentaires sur cette question. Les liens durs pour les directorys sont autorisés sous Linux, mais de manière restreinte.

    Une façon dont nous pouvons tester c'est lorsque nous listons le contenu d'un directory, nous trouvons deux directorys spéciaux "." et "..". Comme nous le soaps "." pointe vers le même directory et ".." pointe vers le directory parent.

    Donc, permet de créer un tree de directory où "a" est le directory parent dont le directory "b" est son enfant.

      a `-- b 

    Notez l'inode du directory "a". Et quand nous faisons un ls -la du directory "a" on peut voir ça "." directory pointe également vers le même inode.

     797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a 

    Et ici nous pouvons find que le directory "a" a trois liens durs. C'est parce que l'inode 797358 a trois liens durs au nom de "." à l'intérieur d'un directory "a" et nom comme ".." à l'intérieur du directory "b" et un avec le nom "a" itslef.

     $ ls -ali a/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 . $ ls -ali a/b/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 .. 

    Donc, ici, nous pouvons comprendre que les liens durs sont là pour les directorys uniquement pour se connecter avec leurs directorys parent et enfant. Ainsi, un directory sans enfant n'aura que 2 liens, et le directory "b" n'aura donc que deux liens.

    Une raison pour laquelle la binding directe des directorys a été évitée serait d'éviter des loops de reference infinies qui confondraient les programmes qui traversent le système de files.

    Comme le système de files est organisé en tree et que l'tree ne peut pas avoir de reference cyclique, cela aurait dû être évité.

    Aucun des éléments suivants n'est la vraie raison d'interdire les liens durs vers les directorys; chaque problème est assez facile à résoudre:

    • les cycles dans l'arborescence provoquent des traverses difficiles
    • plusieurs parents, alors quel est le "vrai"?
    • système de files garbage collection

    La vraie raison (comme suggéré par @ Thorbjørn Ravn Andersen) vient quand vous supprimez un directory qui a plusieurs parents, à partir du directory pointé par .. :

    Que devrais- .. maintenant?

    Si le directory est supprimé de son parent mais que son nombre de liens est toujours supérieur à 0 il doit y avoir quelque chose, quelque part encore pointé vers lui. Tu ne peux pas partir .. montrant rien; beaucoup de programmes countnt sur .. , donc le système devrait traverser le système de files entier jusqu'à ce qu'il trouve la première chose qui pointe vers le directory supprimé, juste pour mettre à jour .. Soit cela, soit le système de files devrait maintenir une list de tous les directorys pointant vers un directory lié.

    D'une façon ou d'une autre, ce serait une surcharge de performance et une complication supplémentaire pour les métadonnées et / ou le code du système de files, de sorte que les concepteurs ont décidé de ne pas l'autoriser.

    La création de liens sur les directorys serait irréversible. Supposons que nous ayons:

     /dir1 ├──this.txt ├──directory │ └──subfiles └──etc 

    Je le relie à /dir2 .

    So /dir2 contient maintenant tous ces files et directorys

    Et si je change d'avis? Je ne peux pas juste rmdir /dir2 (parce que ce n'est pas vide)

    Et si je supprime récursivement dans /dir2 … il sera supprimé de /dir1 aussi!

    IMHO c'est une raison largement suffisante pour éviter cela!

    C'est une bonne explication. En ce qui concerne "Lequel des parents multiples devrait .. pointer?" une solution serait pour un process de maintenir son path wd complet, en tant qu'inodes ou en tant que string. les inodes seraient plus robustes puisque les noms peuvent être changés. Au less dans les time anciens, il y avait un inode central pour chaque file ouvert qui était incrémenté chaque fois qu'un file était ouvert, décrémenté lorsqu'il était fermé. Quand il a atteint zéro et le stockage pointé vers le haut serait libéré. Lorsque le file n'était plus ouvert par quiconque, il (la copy en-core) serait abandonné. Cela maintiendrait le path comme valide si un autre process déplacait un directory vers un autre directory alors que le sous-directory se trouvait dans le path d'un autre process. Semblable à la façon dont vous pouvez supprimer un file ouvert, mais il est simplement supprimé du directory, mais toujours ouvert pour tous les process qui l'ont ouvert.

    Les directorys hard-linking étaient librement autorisés dans les Bell Labs UNIX, au less V6 et V7, Ne sais pas à propos de Berkeley ou plus tard. Aucun drapeau requirejs. Pourriez-vous faire des loops? Oui, ne fais pas ça. Il est très clair ce que vous faites si vous faites une boucle. Le Néant devrait vous entrainer à nouer un nœud autour de votre cou pendant que vous attendez votre tour pour sauter hors de l'avion si vous avez l'autre extrémité commodément accroché à un crochet sur la tête en vrac.

    Ce que j'espérais en faire aujourd'hui était de lier durablement lhome à la maison afin que je puisse avoir / home / administ disponible ou non / home a été couvert avec un automout au-dessus de la maison, ce automount ayant un lien symbolique nommé administ à / lhome / administ. Cela me permet d'avoir un count administratif qui fonctionne quel que soit l'état de mon système de files principal. Ceci est une expérience pour linux, mais je pense appris à un moment donné pour le SunOS basé sur UCB que les automounts sont faits au niveau de la string ascii. Il est difficile de voir comment ils pourraient être faits autrement comme une couche sur le dessus de tout FS arbitraire.

    J'ai lu ailleurs cela. et .. ne sont plus des files dans le directory non plus. Je suis sûr qu'il y a de bonnes raisons pour tout cela et que beaucoup de ce que nous apprécions (comme le fait d'être capable de monter NTFS) est possible à cause de telles choses, mais une partie de l'élégance d'UNIX était dans la mise en œuvre. Ce sont les avantages tels que la généralité et la malléabilité que cette élégance a fournis qui lui a permis d'être si robuste et de supporter pendant quatre décennies. Comme nous perdons les implémentations élégantes, il finira par devenir comme Windows (j'espère que j'ai tort!). Quelqu'un créerait alors un nouvel OS basé sur des principes élégants. Quelque chose à penser. Peut-être que je me trompe, je ne suis (évidemment) pas au courant de la mise en œuvre actuelle. C'est incroyable, mais comment la compréhension de 30 ans est applicable à Linux … la plupart du time!