web-dev-qa-db-fra.com

Que se passe-t-il lorsque j'exécute la commande cat / proc / cpuinfo?

Que se passe-t-il lorsque j'écris cat /proc/cpuinfo. Est-ce un canal nommé (ou quelque chose d'autre) vers le système d'exploitation qui lit les informations du processeur à la volée et génère ce texte chaque fois que je l'appelle?

87
slm

Chaque fois que vous lisez un fichier sous /proc, Cela appelle du code dans le noyau qui calcule le texte à lire comme contenu du fichier. Le fait que le contenu soit généré à la volée explique pourquoi presque tous les fichiers ont leur temps signalé comme maintenant et leur taille signalée comme 0 - ici, vous devriez lire 0 comme "ne sais pas". Contrairement aux systèmes de fichiers habituels, le système de fichiers monté sur /proc, Appelé procfs , ne charge pas les données à partir d'un disque ou d'autres supports de stockage (comme FAT, ext2, zfs,… ) ou sur le réseau (comme NFS, Samba,…) et n'appelle pas de code utilisateur (contrairement à Fuse ).

Procfs est présent dans la plupart des unités non BSD. Il a commencé sa vie dans les Bell Labs d'AT & T en NIX 8th edition comme un moyen de rapporter des informations sur les processus (et ps est souvent une jolie imprimante pour les informations lues par /proc). La plupart des implémentations procfs ont un fichier ou un répertoire appelé /proc/123 Pour rapporter des informations sur le processus avec PID 123. Linux étend le système de fichiers proc avec beaucoup plus d'entrées qui rapportent l'état du système, y compris votre exemple /proc/cpuinfo.

Dans le passé, /proc De Linux a acquis divers fichiers qui fournissent des informations sur les pilotes, mais cette utilisation est désormais déconseillée au profit de /sys et /proc évolue désormais lentement. Les entrées comme /proc/bus Et /proc/fs/ext4 Restent où elles sont pour la compatibilité descendante, mais de nouvelles interfaces similaires sont créées sous /sys. Dans cette réponse, je vais me concentrer sur Linux.

Vos premier et deuxième points d'entrée pour la documentation sur /proc Sous Linux sont:

  1. la page de manuel proc(5);
  2. Le système de fichiers /proc dans la documentation du noyau .

Votre troisième point d'entrée, lorsque la documentation ne le couvre pas, est de lire la source . Vous pouvez télécharger la source sur votre machine, mais c'est un énorme programme, et LXR , la référence croisée Linux, est d'une grande aide. (Il existe de nombreuses variantes de LXR; celle qui fonctionne sur lxr.linux.no Est de loin la plus agréable mais malheureusement le site est souvent en panne.) Une petite connaissance de C est requise, mais vous n'avez pas besoin d'être programmeur pour retrouver une valeur mystérieuse.

Le traitement principal des entrées /proc Se trouve dans le répertoire fs/proc . Tout pilote peut enregistrer des entrées dans /proc (Bien que comme indiqué ci-dessus, cela soit désormais déconseillé au profit de /sys), Donc si vous ne trouvez pas ce que vous cherchez dans fs/proc, regardez partout ailleurs. Les fonctions d'appel des pilotes déclarées dans include/linux/proc_fs.h . Les versions du noyau jusqu'à 3.9 fournissent les fonctions create_proc_entry Et certains wrappers (en particulier create_proc_read_entry), Et les versions du noyau .10 et plus fournissent à la place uniquement proc_create Et proc_create_data (Et quelques autres).

En prenant /proc/cpuinfo Comme exemple, une recherche de "cpuinfo" Vous conduit à l'appel de proc_create("cpuinfo, …") en fs/proc/cpuinfo.c . Vous pouvez voir que le code est à peu près du code passe-partout: puisque la plupart des fichiers sous /proc Ne font que vider certaines données texte, il existe des fonctions d'aide pour le faire. Il y a simplement une structure seq_operations , et la vraie viande se trouve dans la structure de données cpuinfo_op , qui dépend de l'architecture, généralement définie dans Arch/<architecture>/kernel/setup.c (ou parfois dans un fichier différent). Prenant x86 comme exemple, nous sommes amenés à Arch/x86/kernel/cpu/proc.c . Là, la fonction principale est show_cpuinfo, Qui imprime le contenu du fichier souhaité; le reste de l'infrastructure est là pour fournir les données au processus de lecture à la vitesse qu'il demande. Vous pouvez voir les données assemblées à la volée à partir de données dans diverses variables du noyau, y compris quelques chiffres calculés à la volée tels que la fréquence du processeur .

Une grande partie de /proc Est l'information par processus dans /proc/<PID>. Ces entrées sont enregistrées dans fs/proc/base.c , dans le tgid_base_stuff Tablea ; certaines fonctions enregistrées ici sont définies dans d'autres fichiers. Voyons quelques exemples de la façon dont ces entrées sont générées:

  • cmdline est généré par proc_pid_cmdline dans le même fichier. Il localise les données dans le processus et les imprime.
  • clear_refs, Contrairement aux entrées que nous avons vues jusqu'à présent, est accessible en écriture mais pas en lecture. Par conséquent, les structures proc_clear_refs_operations définissent une fonction clear_refs_write mais aucune fonction de lecture.
  • cwd est un lien symbolique (un peu magique), déclaré par proc_cwd_link , qui recherche le répertoire courant du processus et le renvoie comme contenu du lien.
  • fd est un sous-répertoire. Les opérations sur le répertoire lui-même sont définies dans la structure de données proc_fd_operations (elles sont passe-partout sauf pour la fonction qui énumère les entrées, proc_readfd , qui énumère les fichiers ouverts du processus) tandis que les opérations sur les entrées sont dans `proc_fd_inode_operations .

Un autre domaine important de /proc Est /proc/sys, Qui est une interface directe avec sysctl . La lecture d'une entrée dans cette hiérarchie renvoie la valeur de la valeur sysctl correspondante et l'écriture définit la valeur sysctl. Les points d'entrée pour sysctl sont dans fs/proc/proc_sysctl.c . Les systèmes ont leur propre système d'enregistrement avec register_sysctl et amis.

La réponse donnée par @slm est très complète, mais je pense qu'une explication plus simple pourrait provenir d'un changement de perspective.

Dans l'utilisation quotidienne, nous pouvons considérer les fichiers comme des choses physiques, c'est-à-dire. des morceaux de données stockés sur un appareil. Cela rend les fichiers comme/proc/cpuinfo très mystérieux et déroutants. Cependant, tout est parfaitement logique si nous considérons les fichiers comme une interface ; un moyen d'envoyer des données dans et hors d'un programme.

Les programmes qui envoient et reçoivent des données de cette manière sont des systèmes de fichiers ou des pilotes (selon la façon dont vous définissez ces termes, leur définition peut être trop large ou trop étroite). Le point important est que certains de ces programmes utilisent un périphérique matériel pour stocker et récupérer les données envoyées via cette interface; mais pas tout.

Voici quelques exemples de systèmes de fichiers qui n'utilisent pas un périphérique de stockage (au moins directement):

  • Systèmes de fichiers utilisant des données recherchées ou calculées. Proc est un exemple, car il obtient des données de divers modules du noyau. Un exemple extrême est πfs (github.com/philipl/pifs)
  • Tous les systèmes de fichiers Fuse, qui gèrent les données avec un programme d'espace utilisateur standard
  • Systèmes de fichiers qui transforment les données d'un autre système de fichiers à la volée, par exemple en utilisant le chiffrement, la compression ou même le transcodage audio (khenriks.github.io/mp3fs/)

Le système d'exploitation Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) est un exemple extrême d'utilisation de fichiers comme interface de programmation générale.

14
Warbo