Un répertoire est-il supprimé lorsque son nombre de liens durs devient 0?

10

Un répertoire est-il supprimé lorsque son nombre de liens durs devient 0?

Un répertoire a toujours au moins 2 comme nombre de liens durs, à cause de .. Lorsqu'un rm -rrépertoire, diminue-t-il le nombre de liens durs de 2 à 0 de 2 au lieu de 1?

Le nombre de liens durs d'un répertoire peut-il jamais être 1?

Merci.

Tim
la source

Réponses:

9

Tout d'abord, tous les systèmes de fichiers n'utilisent pas .et ..comme liens durs. ceci est documenté dans le manuel de recherche de gnu. Je vais ignorer ces systèmes de fichiers pour le reste de ma réponse car ils n'ont pas été conçus pour Unix et ne font que compliquer les choses sans ajouter de clarté. Je vais également ignorer le répertoire racine et les points de montage pour la même raison.

le nombre de liens vers un répertoire n'est jamais inférieur à deux à cause de .et ... Le nombre de sous-répertoires est égal au nombre de liens moins deux. En raison de cela , vous ne pouvez pas lier ou délier un répertoire, donc rm -rsera statun fichier avant de le supprimer et utiliser au rmdirlieu de unlinksur les répertoires. Les deux appels système utilisent des chemins de code complètement différents dans le noyau.

hildred
la source
Merci. Un répertoire a un lien dur .., uniquement lorsqu'il a un sous-répertoire, n'est-ce pas? N'est ..-ce pas toujours présent pour un répertoire, non?
Tim
..est présent dans chaque répertoire qui est un sous-répertoire. qui est tout mais /qui en a un aussi, donc tous les répertoires.
hildred
1
(1) Si un répertoire n'a pas de sous-répertoire, le répertoire n'a pas de lien dur ..vers lui-même. Quels sont les liens durs vers le répertoire? le fichier avec le chemin d'accès, et .? (2) pourquoi ignorez-vous les points de montage?
Tim
Si le répertoire est un sous-répertoire. l'entrée ..pointera vers le parent. Dans un cas particulier, le lien du répertoire racine pointe vers lui-même. Cela permet à cd ..\..des commandes similaires de fonctionner comme prévu, où que vous soyez. Vous pouvez tester avec la statcommande.
BillThor
1
Vous avez raison, le nombre de liens n'est jamais inférieur à 2, mais ce n'est pas à cause de ... C'est à cause de .et du nom dans le répertoire parent qui le pointe. La seule exception est la racine, qui n'a pas de parent. Mais il a ..pointé sur lui-même, il a donc également un nombre de liens = 2.
Barmar
11

Tout fichier sur un système de fichiers UNIX conventionnellement conçu dont le nombre de références (par exemple la somme du nombre de liens fixes et le nombre de descripteurs de fichiers ouverts *) atteint 0 est supprimé. Cependant, sur les systèmes UNIX modernes, l' rmdirappel système supprime un répertoire vide en une seule opération plutôt que de le supprimer .et ..un par un.

Dans les systèmes UNIX historiques, cependant, cet appel système n'existait pas. Au lieu de cela, la rmdir commande était un programme setuid ( le code source peut être trouvé ici ) qui vérifiait qu'un répertoire était vide (autre que les entrées spéciales), puis supprimé ..et ., dans cet ordre, puis supprimé le répertoire lui-même, le tout avec le unlinkappel système que seul root était autorisé à utiliser sur les répertoires (d'où la raison pour laquelle la commande était setuid). Ainsi, sur ces systèmes, le nombre de liens d'un répertoire serait momentanément 1 après avoir .été supprimé, mais avant que le répertoire ne soit supprimé du répertoire parent, il serait alors de 0.

La rmcommande, par ailleurs, a empêché même root de supprimer des répertoires. Et rm -rappeler la rmdircommande pour supprimer les répertoires après avoir vidé leur contenu.

Sur ces systèmes historiques, une mauvaise utilisation de l' unlinkappel à partir d'un programme s'exécutant en tant que root, l'exécution dans une condition de concurrence critique avec rmdirou mv, ou la création d'un fichier dans un processus dont le répertoire actuel a été supprimé (les systèmes modernes empêchent cela), pourrait entraîner des problèmes de fichiers ou de répertoires qui ont un nombre de liens fixes supérieur à 0 mais qui n'existent pas dans l'arborescence des répertoires. Cette condition a été détectée par dcheck, et est toujours l'une des vérifications, fsckcar elle reste physiquement possible sur la plupart des systèmes de fichiers.


Les systèmes de fichiers ne sont d'ailleurs pas nécessaires pour implémenter les répertoires (y compris .et ..) en tant que fichiers normaux qui ont des liens physiques. Sur ces systèmes de fichiers, le nombre de liens physiques d'un répertoire sera toujours signalé comme 0(mais bien sûr, son existence dans le répertoire parent donne droit à un "nombre de références" de 1).


Le comportement d'un répertoire supprimé (par exemple lorsqu'il est examiné par un processus qui l'a déjà ouvert ou l'a comme répertoire actuel) et la signification exacte du "nombre de liens" d'un répertoire ne sont pas spécifiés. Sur Mac OS X, par exemple, il signalera un nombre de liens durs de 2 , même s'il n'a pas de vrais liens durs. Même si .et ..n'apparaissent pas dans la liste, le répertoire peut être ouvert et statpeut être appelé avec le nom .ou ... Sous Linux, le nombre de liens est 0 mais .et ..même encore du travail.

Mac OS X signale également le nombre de tous les fichiers d'un répertoire comme nombre de liens, au lieu du nombre de sous-répertoires. Mais c'est 2 même quand .et ..sont partis.


* Cela inclut les descripteurs ouverts normaux, les sections mappées en mémoire (y compris par exemple l'exécution de binaires et de bibliothèques partagées) et le traitement des répertoires actuels.

Aléatoire832
la source
2
strcpyà un tableau de taille fixe dans un exécutable setuid ... c'était le bon moment!
Andrea Corbellini
@AndreaCorbellini Il y a en fait un exploit publié pour mkdirbasé sur le fait qu'il doit faire la même chose à l'envers.
Random832
1
Je pense que je l'ai trouvé: securityfocus.com/archive/1/365038/2004-05-31/2004-06-06/0 :)
Andrea Corbellini
en demandant rmdir, ne ..supprimerait- il pas le répertoire parent?
Edward Torvalds
@edwardtorvalds Non, je parlais de la suppression du lien ".." lui-même, pas du répertoire parent vers lequel il pointe.
Random832