Comment les fichiers ouverts se comportent-ils sur les systèmes Linux?

17

Je viens de renommer un fichier journal en "foo.log.old" et j'ai supposé que l'application commencerait à écrire un nouveau fichier journal dans "foo.log". J'ai été surpris de découvrir qu'il suivait le fichier journal jusqu'à son nouveau nom et continuait d'ajouter des lignes à "foo.log.old".

Sous Windows, je ne connais pas ce type de comportement - je ne sais pas s'il est même possible de l'implémenter. Comment ce comportement est-il implémenté exactement sous Linux? Où puis-je en savoir plus à ce sujet?

ripper234
la source
Je ne mets pas cela comme une réponse parce que je ne sais pas vraiment mais je pense que cela a à voir avec les inodes qui ne sont pas modifiés lorsque vous déplacez un fichier.
mathepic

Réponses:

20

Les programmes se connectent aux fichiers via un numéro maintenu par le système de fichiers (appelé un inode sur les systèmes de fichiers Unix traditionnels), dont le nom n'est qu'une référence (et peut-être pas une référence unique à cela).

Donc, plusieurs choses à savoir:

  1. Le déplacement d'un fichier à l'aide de mvne modifie pas ce numéro sous-jacent à moins que vous ne le déplaciez sur les systèmes de fichiers (ce qui équivaut à utiliser cpensuite rmsur l'original).
  2. Parce que plusieurs noms peuvent se connecter à un seul fichier (c'est-à-dire que nous avons des liens durs), les données des fichiers "supprimés" ne disparaissent pas tant que toutes les références au fichier sous-jacent ne disparaissent pas.
  3. Peut-être le plus important: quand un programme est openun fichier, il y fait référence, ce qui équivaut (aux fins de la suppression des données) à avoir un nom de fichier connecté.

Cela donne lieu à plusieurs comportements comme:

  • Un programme peut openlire un fichier, mais ne le lit réellement qu'après que l'utilisateur l'ait rmédité sur la ligne de commande, et le programme aura toujours accès aux données .
  • Celui que vous avez rencontré: mving un fichier ne déconnecte pas la relation entre le fichier et les programmes qui l'ouvrent (à moins que vous ne traversiez les limites du système de fichiers, auquel cas le programme a toujours une version de l'original sur laquelle travailler).
  • Si un programme a openédité un fichier pour l'écriture et que l'utilisateur rmest son dernier nom de fichier sur la ligne de commande, le programme peut continuer à mettre des éléments dans le fichier, mais dès qu'il se ferme, il n'y aura plus de référence à ces données et cela disparaîtra.
  • Deux programmes qui communiquent via un ou plusieurs fichiers peuvent obtenir une sécurité partielle et grossière en supprimant le ou les fichiers une fois qu'ils ont terminé open. (Ce n'est pas un véritable esprit de sécurité, cela transforme simplement un trou béant en condition de course.)
dmckee
la source
1
Je suis d'accord avec @dmckee, je voulais juste noter: un programme peut openun fichier pour la lecture et l'écriture (comme ce qui s'est passé avec le fichier journal dans la question).
jsbillings
@jsbillings: Oui, mais il y a un risque. Si tous les noms de système de fichiers ont disparu, vous pouvez écrire des Go dans un fichier ouvert qui s'évaporera comme la rosée du matin dès que vous le fermerez.
dmckee
1
De plus, l'inode est copié dans le noyau et c'est ce qui est opéré, pas la copie sur disque. Ainsi, le fichier pourrait être mv'd ou cp ', mais un fichier ouvert fonctionne déjà avec les structures de données centrales, pas avec la version du disque. Donc, si vous copiez un autre fichier dans le fichier ouvert pour l'écriture, le processus écrit toujours à la même position relative que dans l'ancien fichier. C'est la raison pour laquelle des programmes, comme Apache httpd, ont un gestionnaire de signal qui ferme et rouvre les fichiers journaux.
Arcege
0

Pour vraiment voir comment ce comportement est implémenté, vous pouvez regarder quelques livres de programmation Unix. Mathepic a raison en ce qu'il est lié à un inode. Le nom de chemin réel n'est utilisé que pour ouvrir le fichier, une fois cela fait, le programme le référence par son descripteur de fichier ouvert. Le descripteur de fichier fait à son tour référence à l'inode, qui dans ce cas ne se soucie pas si le nom des fichiers sous-jacents a changé.

En ce qui concerne l'implémentation de cela dans Windows, c'est une question pour un autre site.

Pour en savoir plus à ce sujet sans toucher aux livres, recherchez simplement les systèmes de fichiers Linux et les inodes. Il n'y a peut-être pas de réponse claire, mais vous pourrez comprendre pourquoi.

M. Shickadance
la source
4
"Cherchez autour - vous ne trouverez probablement pas une bonne réponse mais la comprendrez" n'est pas une bonne réponse.
mattdm