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

Réponses:

72

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 heure et leur taille signalées comme étant égales à 0. Ici, vous devez lire 0 comme «ne sait pas». Contrairement aux systèmes de fichiers habituels, le système de fichiers sur lequel est monté le processus , /procappelé procfs , ne charge pas les données d'un disque ou d'un autre support de stockage (comme FAT, ext2, zfs,…) ou sur le réseau (comme NFS, Samba,…). et n'appelle pas le code utilisateur (contrairement à FUSE ).

Procfs est présent dans la plupart des ordinateurs non BSD. Il a commencé sa vie dans les Bell Labs d’AT & T sous UNIX 8ème édition en tant que moyen de rapporter des informations sur les processus (et psest souvent une jolie imprimante pour la lecture d’informations /proc). La plupart des implémentations procfs ont un fichier ou un répertoire appelé /proc/123pour rapporter des informations sur le processus avec PID 123. Linux étend le système de fichiers proc avec beaucoup plus d'entrées indiquant l'état du système, y compris votre exemple /proc/cpuinfo.

Dans le passé, Linux avait /procacquis divers fichiers qui fournissaient des informations sur les pilotes, mais cette utilisation est maintenant déconseillée en faveur de /sys, et /procévolue maintenant lentement. Les entrées aiment /proc/buset /proc/fs/ext4restent où elles sont pour la compatibilité ascendante, mais des interfaces similaires plus récentes 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 /procsur Linux sont:

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

Votre troisième point d’entrée, lorsque la documentation ne la couvre pas, lit la source . Vous pouvez télécharger le code source sur votre ordinateur, mais il s’agit d’un programme gigantesque et LXR , la référence croisée Linux, est une aide précieuse. (Il existe de nombreuses variantes de LXR; celle qui tourne lxr.linux.noest de loin la plus belle, mais malheureusement, le site est souvent en panne.) Un peu de connaissance de C est nécessaire, mais vous n'avez pas besoin d'être un programmeur pour retrouver une valeur mystérieuse. .

Le traitement de base des /procentrées est dans le fs/procrépertoire. N'importe quel pilote peut enregistrer des entrées /proc(bien que, comme indiqué ci-dessus, il soit désormais déconseillé de l' /sysutiliser), si vous ne trouvez pas ce que vous recherchez fs/proc, cherchez partout ailleurs. Les fonctions d’appel des conducteurs déclarées dans include/linux/proc_fs.h. Les versions du noyau jusqu'à la version 3.9 fournissent les fonctions create_proc_entryet certains wrappers (en particulier create_proc_read_entry), tandis que les versions du noyau 3.10 et supérieures fournissent uniquement un proc_createet proc_create_data(et quelques autres).

En prenant /proc/cpuinfocomme exemple, une recherche "cpuinfo"vous conduit à l'appel à proc_create("cpuinfo, …")en fs/proc/cpuinfo.c. Vous pouvez voir que le code est en gros un code standard: puisque la plupart des fichiers /procne font que vider certaines données textuelles, il existe des fonctions d'assistance pour le faire. Il y a simplement une seq_operationsstructure, et la vraie chair réside dans la cpuinfo_opstructure de données, qui dépend de l'architecture, généralement définie dans arch/<architecture>/kernel/setup.c(ou parfois dans un fichier différent). Nous prenons l'exemple de x86 arch/x86/kernel/cpu/proc.c. Là la fonction principale estshow_cpuinfo, qui imprime le contenu du fichier souhaité; le reste de l'infrastructure est là pour transmettre les données au processus de lecture à la vitesse demandée. Vous pouvez voir les données assemblées à la volée à partir des données de diverses variables du noyau, y compris quelques nombres calculés à la volée, tels que la fréquence du processeur .

Une grande partie de /procl'information sur chaque processus est /proc/<PID>. Ces entrées sont enregistrées dans fs/proc/base.c, dans le tgid_base_stufftableau ; certaines fonctions enregistrées ici sont définies dans d'autres fichiers. Regardons quelques exemples de la façon dont ces entrées sont générées:

  • cmdlineest généré par proc_pid_cmdlinedans 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 n'est pas lisible. Par conséquent, les proc_clear_refs_operationsstructures définissent une clear_refs_writefonction mais pas de fonction de lecture.
  • cwdest un lien symbolique (légèrement magique), déclaré par proc_cwd_link, qui recherche le répertoire actuel du processus et le renvoie comme contenu du lien.
  • fdest un sous-répertoire. Les opérations sur le répertoire lui-même sont définies dans la proc_fd_operationsstructure de données (elles sont passe-partout, à l'exception de 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 /procest /proc/sys, qui est une interface directe à 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 de sysctl se trouvent dans fs/proc/proc_sysctl.c. Les systèmes ont leur propre système d'enregistrement avec leurs register_sysctlamis.

Gilles
la source
59

Lorsque vous essayez de comprendre quel type de magie se déroule dans les coulisses, votre meilleur ami est strace. Apprendre à utiliser cet outil est l’une des meilleures choses que vous puissiez faire pour mieux comprendre ce qui se passe dans les coulisses de la folle magie.

$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536)                      = 0
close(3)                                = 0
...

Dans la sortie ci-dessus, vous pouvez voir qu’il /proc/cpuinfos’agit simplement d’un fichier ordinaire, ou du moins qu’il semble en être un. Alors creusons plus profondément.

Plongée plus profonde

# 1 - avec ls ..

En regardant le fichier lui-même, il semblerait que ce ne soit "qu'un fichier".

$ ls -l /proc/cpuinfo 
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo

Mais regardez de plus près. Nous obtenons notre premier indice que sa particularité, notez la taille du fichier est 0 octets.

# 2 - avec stat ..

Si nous examinons maintenant le fichier en utilisant, statnous pouvons avoir notre indice suivant: il y a quelque chose de spécial à propos de /proc/cpuinfo.

courir # 1
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
 Birth: -
courir # 2
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
 Birth: -

Notez les horaires d'accès, de modification et de modification? Ils continuent à changer pour chaque accès. C'est très inhabituel que tous les 3 changeraient comme ça. Sauf modification, les attributs d'horodatage d'un fichier restent généralement les mêmes.

# 3 - avec le fichier ..

Encore un indice que ce fichier est tout sauf un fichier normal:

$ file /proc/cpuinfo 
/proc/cpuinfo: empty

S'il s'agissait d'une manifestation d'un canal nommé, le résultat serait similaire à l'un de ces fichiers:

$ ls -l /dev/initctl /dev/zero 
prw-------. 1 root root    0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero

$ file /dev/initctl /dev/zero 
/dev/initctl: fifo (named pipe)
/dev/zero:    character special

Si nous touchons un emptyfile, /proc/cpuinfone semble plus ressembler à un fichier, alors un tuyau:

$ touch emptyfile
$ ls -l emptyfile 
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile 
emptyfile: empty
# 4 - avec monture ..

Nous devons donc faire un pas en arrière et faire un zoom arrière. Nous examinons un fichier en particulier, mais nous devrions peut-être examiner le système de fichiers sur lequel ce fichier se trouve. Et pour cela, nous pouvons utiliser la mountcommande.

$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

OK, le type de système de fichiers est donc de type proc. Donc, /procest un type de système de fichiers différent, c'est notre indice que les fichiers sous /procsont spéciaux. Ce ne sont pas que des dossiers courants. Voyons donc quelques informations supplémentaires sur ce qui rend le procsystème de fichiers spécial.

Regarde mountla page de manuel de:

Le système de fichiers proc n'est pas associé à un périphérique spécial et, lors du montage, un mot clé arbitraire, tel que proc, peut être utilisé à la place d'une spécification de périphérique. (Le choix habituel, aucun est moins chanceux: le message d'erreur «aucun occupé» de umount peut être déroutant.)

Et si nous regardons procla page de manuel de:

Le système de fichiers proc est un pseudo-système de fichiers utilisé comme interface pour les structures de données du noyau. Il est généralement monté sur / proc. La plupart sont en lecture seule, mais certains fichiers permettent de modifier les variables du noyau.

Un peu plus loin dans cette même page de manuel:

/ proc / cpuinfo

Il s'agit d'un ensemble d'éléments dépendants de la CPU et de l'architecture système, une liste différente pour chaque architecture prise en charge. Deux entrées communes sont processeur qui donne le numéro de la CPU et bogomips; une constante système calculée lors de l'initialisation du noyau. Les machines SMP ont des informations pour chaque CPU. La commande lscpu (1) collecte ses informations à partir de ce fichier.

Au bas de la page de manuel, vous trouverez une référence à un document du noyau que vous pouvez trouver ici, intitulée: THE / proc FILESYSTEM . Citant ce document:

Le système de fichiers proc agit comme une interface avec les structures de données internes du noyau. Il peut être utilisé pour obtenir des informations sur le système et pour modifier certains paramètres du noyau lors de l'exécution (sysctl).

Conclusions

Alors qu'avons-nous appris ici? Etant donné qu’on /procparle de pseudo système de fichiers et également d’une "interface avec des structures de données internes", il est probablement prudent de supposer que les éléments qu’il contient ne sont pas de véritables fichiers, mais plutôt des manifestations faites pour ressembler à des fichiers, mais ne le sont vraiment pas.

Je terminerai avec cette citation qui, apparemment, man 5 procfigurait dans une version antérieure de 2004, mais pour une raison quelconque n'est plus incluse. NOTE: Je ne sais pas pourquoi il a été supprimé car il décrit très bien ce qui /procest:

Le répertoire / proc sur les systèmes GNU / Linux fournit un système de fichiers semblable à une interface avec le noyau. Cela permet aux applications et aux utilisateurs d'extraire des informations et de définir des valeurs dans le noyau à l'aide d'une opération d'E / S normale du système de fichiers.

Le système de fichiers proc est parfois appelé système de pseudo-fichiers d'informations de processus. Il ne contient pas de fichiers `` réels '' mais plutôt des informations système à l'exécution (par exemple, la mémoire système, les périphériques montés, la configuration matérielle, etc.). Pour cette raison, il peut être considéré comme un centre de contrôle et d’information pour le noyau. En fait, de nombreux utilitaires système ne sont que des appels aux fichiers de ce répertoire. Par exemple, la commande lsmod, qui répertorie les modules chargés par le noyau, est fondamentalement identique à 'cat / proc / modules', tandis que lspci, qui répertorie les périphériques connectés au bus PCI du système, est identique à 'cat / proc / pci '. En modifiant les fichiers situés dans ce répertoire, vous pouvez modifier les paramètres du noyau pendant l’exécution du système.

Source: Le pseudo système de fichiers proc

Références

slm
la source
1
Cool, :) c'est la première chose que j'ai essayée en voyant la question:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc
1
Bonne réponse! Sous Linux, si vous voulez aller plus loin, la source du système de fichiers proc est dans fs / proc dans la source du noyau. Vous verrez qu'il existe un fichier fs / proc / cpuinfo.c mais, malheureusement, il est plutôt vide car le gros des travaux est réparti sur arch / car il dépend de l'architecture. Pour un exemple plus simple, voir fs / proc / uptime.c. En jetant un coup d'œil sur le fichier, on peut deviner que uptime_proc_show est le fer de lance de ce qui nous fournit les données que nous voulons et nous pourrions les explorer davantage en plongeant dans les fonctions qu'il appelle. Pour comprendre l'interface seq_file et son utilisation dans procfs, voir:
Steven D
1
@slm: +1, bonne réponse. Mais pour moi, le premier indice qu’il s’agit d’un fichier spécial est sa taille ^^ 0 octets, mais vous pouvez en lire beaucoup de choses (un peu comme certains fichiers de pipe).
Olivier Dulac
@OlivierDulac - bon point. J'ai apporté des modifications supplémentaires en fonction de vos commentaires. LMK si je peux apporter d'autres améliorations. Merci.
slm
14

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.

Au quotidien, nous pouvons considérer les fichiers comme des objets physiques, c.-à-d. des morceaux de données stockées sur un appareil. Cela rend les fichiers tels que / proc / cpuinfo très mystérieux et déroutant. Cependant, tout à fait logique si l' on pense des fichiers en tant que l' 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, cette 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 n'utilisant pas de 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 récupère les données de divers modules du noyau. Πfs est un exemple extrême (github.com/philipl/pifs)
  • Tous les systèmes de fichiers FUSE, qui gèrent les données avec un programme 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 cryptage, 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 en tant qu'interface de programmation générale.

Warbo
la source