Il s'agit d'une question de bas niveau, et je comprends que ce n'est peut-être pas le meilleur endroit à poser. Mais, il semblait plus approprié que tout autre site SE, alors voilà.
Je sais que sur le système de fichiers Linux, certains fichiers existent réellement , par exemple: /usr/bin/bash
est celui qui existe. Cependant, (pour autant que je le comprends), certains aussi n'existent pas réellement en tant que tels et sont plus virtuels des fichiers, par exemple: /dev/sda
, /proc/cpuinfo
, etc. Mes questions sont (ils sont deux, mais trop étroitement liés comme des questions distinctes):
- Comment le noyau Linux fonctionne-t-il pour savoir si ces fichiers sont réels (et donc les lire depuis le disque) ou non lorsqu'une commande de lecture (ou autre) est émise?
- Si le fichier n'est pas réel: à titre d'exemple, une lecture de
/dev/random
retournera des données aléatoires et une lecture de/dev/null
retourneraEOF
. Comment fonctionne-t-il quelles données lire à partir de ce fichier virtuel (et donc quoi faire quand / si des données écrites dans le fichier virtuel aussi) - existe-t-il une sorte de carte avec des pointeurs pour séparer les commandes de lecture / écriture appropriées pour chaque fichier, ou même pour le répertoire virtuel lui-même? Ainsi, une entrée pour/dev/null
pourrait simplement retourner unEOF
.
Réponses:
Il y a donc essentiellement deux types de choses ici:
/proc
et/sys
sont des exemples ici, tout comme les systèmes de fichiers personnalisés FUSE commesshfs
ouifuse
. Il y a beaucoup plus de diversité dans ceux-ci, car en réalité, ils se réfèrent simplement à un système de fichiers avec une sémantique qui est en quelque sorte «personnalisée». Ainsi, lorsque vous lisez à partir d'un fichier sous/proc
, vous n'accédez pas réellement à un élément de données spécifique qui a été stocké par quelque chose d'autre l'écrivant plus tôt, comme sous un système de fichiers normal. Vous effectuez essentiellement un appel au noyau, demandant des informations générées à la volée. Et ce code peut faire tout ce qu'il veut, car ce n'est qu'une fonction implémentant quelque part laread
sémantique. Ainsi, vous avez le comportement étrange des fichiers sous/proc
, comme par exemple faire semblant d'être des liens symboliques lorsqu'ils ne sont pas 'La clé est qu'en
/dev
fait, c'est généralement l'un des premiers. Il est normal dans les distributions modernes d'avoir/dev
quelque chose comme un tmpfs, mais dans les systèmes plus anciens, il était normal que ce soit un simple répertoire sur le disque, sans aucun attribut spécial. La clé est que les fichiers sous/dev
sont des nœuds de périphériques, un type de fichier spécial similaire aux FIFO ou aux sockets Unix; un nœud de périphérique a un nombre majeur et mineur, et leur lecture ou leur écriture fait un appel à un pilote du noyau, tout comme la lecture ou l'écriture d'un FIFO appelle le noyau pour mettre en mémoire tampon votre sortie dans un canal. Ce pilote peut faire tout ce qu'il veut, mais il touche généralement le matériel, par exemple pour accéder à un disque dur ou lire du son dans les haut-parleurs.Pour répondre aux questions originales:
Il y a deux questions pertinentes pour savoir si le «fichier existe» ou non; il s'agit de savoir si le fichier de nœud de périphérique existe littéralement et si le code du noyau le soutenant est significatif. Le premier est résolu comme n'importe quoi sur un système de fichiers normal. Les systèmes modernes utilisent
udev
ou quelque chose du genre pour surveiller les événements matériels et créer et détruire automatiquement les nœuds de périphérique en/dev
conséquence. Mais les systèmes plus anciens, ou les versions personnalisées légères, peuvent simplement avoir tous leurs nœuds de périphérique sur le disque, créés à l'avance. Pendant ce temps, lorsque vous lisez ces fichiers, vous faites un appel au code du noyau qui est déterminé par les numéros de périphérique majeurs et mineurs; si ceux-ci ne sont pas raisonnables (par exemple, vous essayez de lire un périphérique bloc qui n'existe pas), vous obtiendrez simplement une sorte d'erreur d'E / S.La façon dont il détermine quel code de noyau appeler pour quel fichier de périphérique varie. Pour les systèmes de fichiers virtuels comme
/proc
, ils implémentent leurs propres fonctionsread
etwrite
; le noyau appelle simplement ce code en fonction du point de montage dans lequel il se trouve et l'implémentation du système de fichiers s'occupe du reste. Pour les fichiers de périphérique, il est distribué en fonction des numéros de périphérique majeurs et mineurs.la source
/dev
mis hors tension, les fichiers seraient toujours là, mais je suppose qu'ils seraient effacés au démarrage du système?tmpfs
les créerait et les supprimerait dynamiquement au besoin, par exemple: démarrage et arrêt?devtmpfs
, le/dev
système de fichiers sous Linux moderne, est similaire à atmpfs
, mais a quelques différences à supporterudev
. (Le noyau effectue lui-même une création de nœud automatisée avant de le transférerudev
, afin de rendre le démarrage moins compliqué.) Dans tous ces cas, les nœuds de périphérique ne vivent que dans la RAM et sont créés et détruits dynamiquement selon les besoins du matériel. Vraisemblablement, vous pouvez également l'utiliserudev
sur un disque ordinaire/dev
, mais je n'ai jamais vu cela faire et il ne semble pas y avoir de bonnes raisons de le faire.Voici une liste de fichiers
/dev/sda1
sur mon serveur Arch Linux presque à jour:Ainsi, l'entrée de répertoire
/dev/
poursda
a un numéro d'inode, 1294. C'est un vrai fichier sur le disque.Regardez où la taille du fichier apparaît généralement. "8, 1" apparaît à la place. Il s'agit d'un numéro d'appareil majeur et mineur. Notez également le «b» dans les autorisations de fichier.
Le fichier
/usr/include/ext2fs/ext2_fs.h
contient cette (fragment) structure C:Cette structure nous montre la structure sur disque de l'inode d'un fichier. Beaucoup de choses intéressantes sont dans cette structure; regardez-le longuement.
L'
i_mode
élément destruct ext2_inode
a 16 bits et n'utilise que 9 pour l'utilisateur / groupe / autre, les autorisations de lecture / écriture / exécution et 3 autres pour setuid, setgid et sticky. Il dispose de 4 bits pour différencier les types tels que "fichier simple", "lien", "répertoire", "canal nommé", "socket de famille Unix" et "périphérique de bloc".Le noyau Linux peut suivre l'algorithme de recherche de répertoire habituel, puis prendre une décision en fonction des autorisations et des drapeaux de l'
i_mode
élément. Pour 'b', bloquer les fichiers de périphériques, il peut trouver les numéros de périphériques majeurs et mineurs et, traditionnellement, utiliser le numéro de périphérique principal pour rechercher un pointeur vers une fonction du noyau (un pilote de périphérique) qui traite des disques. Le numéro de périphérique mineur est généralement utilisé, par exemple, le numéro de périphérique de bus SCSI, ou le numéro de périphérique EIDE ou quelque chose comme ça.Quelques autres décisions sur la façon de traiter un fichier comme
/proc/cpuinfo
sont prises en fonction du type de système de fichiers. Si vous faites:vous pouvez voir que
/proc
le type de système de fichiers est "proc". La lecture d'un fichier dans/proc
fait que le noyau fait quelque chose de différent en fonction du type du système de fichiers, tout comme l'ouverture d'un fichier sur un système de fichiers ReiserFS ou DOS obligerait le noyau à utiliser différentes fonctions pour localiser les fichiers et localiser les données du des dossiers.la source
4026531975 -r--r--r-- 1 root root 0 Nov 14 18:41 /proc/mdstat
ce qui n'est clairement pas un "vrai fichier".À la fin de la journée, ce sont tous des fichiers pour Unix, c'est la beauté de l'abstraction.
La façon dont les fichiers sont gérés par le noyau, maintenant c'est une histoire différente.
/ proc et de nos jours / dev et / run (alias / var / run) sont des systèmes de fichiers virtuels en RAM. / proc est une interface / windows pour les variables et les structures du noyau.
Je recommande de lire le noyau Linux http://tldp.org/LDP/tlk/tlk.html et les pilotes de périphériques Linux, troisième édition https://lwn.net/Kernel/LDD3/ .
J'ai également apprécié la conception et la mise en œuvre du système d'exploitation FreeBSD http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1
Jetez un oeil à la page pertinente qui se rapporte à votre question.
http://www.tldp.org/LDP/tlk/dd/drivers.html
la source
En plus des réponses de @ RuiFRibeiro et @ BruceEdiger, la distinction que vous faites n'est pas exactement la distinction que fait le noyau. En fait, vous avez différents types de fichiers: fichiers normaux, répertoires, liens symboliques, périphériques, sockets (et j'en oublie toujours quelques-uns donc je n'essaierai pas de faire une liste complète). Vous pouvez avoir les informations sur le type d'un fichier avec
ls
: c'est le premier caractère de la ligne. Par exemple:Le «b» au tout début signale que ce fichier est un périphérique bloc. Un tiret, signifie un fichier normal, 'l' un lien symbolique et ainsi de suite. Ces informations sont stockées dans les métadonnées du fichier et sont accessibles via l'appel système
stat
par exemple, afin que le noyau puisse lire différemment un fichier et un lien symbolique par exemple.Ensuite, vous faites une autre distinction entre les "vrais fichiers"
/bin/bash
et les "fichiers virtuels"/proc/cpuinfo
maisls
signalez les deux comme des fichiers normaux, la différence est donc d'un autre type:Ce qui se passe, c'est qu'ils appartiennent à différents systèmes de fichiers.
/proc
est le point de montage d'un pseudo-système de fichiersprocfs
alors qu'il se/bin/bash
trouve sur un système de fichiers sur disque normal. Lorsque Linux ouvre un fichier (il le fait différemment selon le système de fichiers), il remplit une structure de donnéesfile
qui a, entre autres attributs, une structure de plusieurs pointeurs de fonction qui décrivent comment utiliser ce fichier. Par conséquent, il peut implémenter des comportements distincts pour différents types de fichiers.Par exemple, ce sont les opérations annoncées par
/proc/meminfo
:Si vous regardez la définition de
meminfo_proc_open
, vous pouvez voir que cette fonction remplit un tampon en mémoire avec les informations renvoyées par la fonctionmeminfo_proc_show
, dont la tâche est de collecter des données sur l'utilisation de la mémoire. Ces informations peuvent ensuite être lues normalement. Chaque fois que vous ouvrez le fichier, la fonctionmeminfo_proc_open
est appelée et les informations sur la mémoire sont actualisées.la source
Tous les fichiers d'un système de fichiers sont "réels" dans le sens où ils autorisent les E / S sur les fichiers. Lorsque vous ouvrez un fichier, le noyau crée un descripteur de fichier, qui est un objet (au sens d'une programmation orientée objet) qui agit comme un fichier. Si vous lisez le fichier, le descripteur de fichier exécute sa méthode de lecture, qui à son tour demandera au système de fichiers (sysfs, ext4, nfs, etc.) les données du fichier. Les systèmes de fichiers présentent une interface uniforme vers l'espace utilisateur et savent quoi faire pour gérer les lectures et les écritures. Les systèmes de fichiers demandent à leur tour à d'autres couches de gérer leurs demandes. Pour un fichier normal sur un système de fichiers ext4 par exemple, cela impliquera des recherches dans les structures de données du système de fichiers (ce qui peut impliquer des lectures sur disque), et éventuellement une lecture à partir du disque (ou du cache) pour copier les données dans le tampon de lecture. Pour un fichier dans disons sysfs, il suffit généralement de sprintf () quelque chose dans le tampon. Pour un nœud de développement de blocs, il demandera au pilote de disque de lire certains blocs et de les copier dans le tampon (les nombres majeurs et mineurs indiquent au système de fichiers à quel pilote adresser les requêtes).
la source