Cosa succede quando eseguo il comando cat / proc / cpuinfo?


Risposte:


72

Ogni volta che leggi un file sotto /proc, questo invoca del codice nel kernel che calcola il testo da leggere come contenuto del file. Il fatto che il contenuto sia generato al volo spiega perché quasi tutti i file hanno il loro tempo riportato come ora e le loro dimensioni riportate come 0 - qui dovresti leggere 0 come "non lo so". A differenza dei soliti filesystem, il filesystem su cui è montato /proc, che si chiama procfs , non carica i dati da un disco o altri supporti di archiviazione (come FAT, ext2, zfs, ...) o sulla rete (come NFS, Samba, ...) e non chiama il codice utente (a differenza di FUSE ).

Procfs è presente nella maggior parte dei sistemi non BSD. Ha iniziato la sua vita nei Bell Lab di AT&T nell'ottava edizione di UNIX come un modo per riportare informazioni sui processi (ed psè spesso una bella stampante per leggere le informazioni /proc). La maggior parte delle implementazioni procfs hanno un file o una directory chiamata /proc/123per riportare informazioni sul processo con PID 123. Linux estende il filesystem proc con molte più voci che riportano lo stato del sistema, incluso il tuo esempio /proc/cpuinfo.

In passato, Linux ha /procacquisito vari file che forniscono informazioni sui driver, ma questo uso è ora deprecato a favore /syse /procora si evolve lentamente. Le voci gradiscono /proc/buse /proc/fs/ext4rimangono dove sono per compatibilità con le versioni precedenti, ma sotto vengono create interfacce simili più recenti /sys. In questa risposta, mi concentrerò su Linux.

Il tuo primo e secondo punto di accesso per la documentazione /procsu Linux sono:

  1. la proc(5)pagina man ;
  2. Il /procfilesystem nella documentazione del kernel .

Il tuo terzo punto di ingresso, quando la documentazione non lo copre, sta leggendo la fonte . Puoi scaricare il sorgente sul tuo computer, ma questo è un programma enorme e LXR , il riferimento incrociato di Linux, è di grande aiuto. (Esistono molte varianti di LXR; quella in esecuzione lxr.linux.noè di gran lunga la più bella ma sfortunatamente il sito è spesso inattivo.) È richiesta una piccola conoscenza di C, ma non è necessario essere un programmatore per rintracciare un valore misterioso .

La gestione principale delle /procvoci si trova nella fs/procdirectory. Qualsiasi driver può registrare le voci /proc(anche se, come indicato sopra, ora è deprecato a favore di /sys), quindi se non trovi quello che cerchi fs/proc, cerca ovunque. I driver chiamano le funzioni dichiarate in include/linux/proc_fs.h. Le versioni del kernel fino alla 3.9 forniscono le funzioni create_proc_entrye alcuni wrapper (in particolare create_proc_read_entry) e le versioni 3.10 e successive del kernel invece forniscono solo proc_createe proc_create_data(e alcune altre).

Prendendo /proc/cpuinfocome esempio, una ricerca per "cpuinfo"conduce alla chiamata a proc_create("cpuinfo, …")in fs/proc/cpuinfo.c. Puoi vedere che il codice è praticamente un codice di tipo boilerplate: poiché la maggior parte dei file /procesegue il dump di alcuni dati di testo, ci sono funzioni di supporto per farlo. C'è solo una seq_operationsstruttura, e la carne vera è nella cpuinfo_opstruttura dei dati, che dipende dall'architettura, di solito definita in arch/<architecture>/kernel/setup.c(o talvolta un file diverso). Prendendo x86 come esempio, siamo guidati a arch/x86/kernel/cpu/proc.c. Ecco la funzione principaleshow_cpuinfo, che stampa il contenuto del file desiderato; il resto dell'infrastruttura è lì per fornire i dati al processo di lettura alla velocità richiesta. Puoi vedere i dati che vengono assemblati al volo dai dati in varie variabili nel kernel, inclusi alcuni numeri calcolati al volo come la frequenza della CPU .

Una grande parte di /procè l'informazione per processo in /proc/<PID>. Queste voci sono registrate in fs/proc/base.c, nella tgid_base_stuffmatrice ; alcune funzioni registrate qui sono definite in altri file. Diamo un'occhiata ad alcuni esempi di come vengono generate queste voci:

Un'altra area importante di /procè /proc/sys, che è un'interfaccia diretta per sysctl. La lettura da una voce in questa gerarchia restituisce il valore del valore sysctl corrispondente e la scrittura imposta il valore sysctl. Sono presenti i punti di ingresso per sysctl fs/proc/proc_sysctl.c. Sysctls ha il proprio sistema di registrazione con register_sysctle amici.


59

Quando cerchi di capire quale tipo di magia sta accadendo dietro le quinte, il tuo migliore amico è strace. Imparare a utilizzare questo strumento è una delle cose migliori che puoi fare per ottenere un migliore apprezzamento per ciò che la magia folle sta accadendo dietro le quinte.

$ 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
...

Dall'output sopra puoi vedere che /proc/cpuinfoè solo un file normale, o almeno sembrerebbe essere uno. Quindi scaviamo più a fondo.

Immersione più profonda

# 1 - con ls ..

Guardando il file stesso sembrerebbe "solo un file".

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

Ma dai un'occhiata più da vicino. Otteniamo il nostro primo suggerimento che è speciale, si noti che la dimensione del file è 0 byte.

# 2 - con stat ..

Se ora guardiamo il file usando statpossiamo ottenere il nostro prossimo suggerimento che ci sia qualcosa di speciale /proc/cpuinfo.

eseguire # 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: -
eseguire # 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: -

Notare i tempi di accesso, modifica e modifica? Continuano a cambiare per ogni accesso. Questo è molto insolito che tutti e 3 cambieranno così. A meno che gli attributi di data e ora di un file modificati rimangano generalmente gli stessi.

# 3 - con il file ..

Ancora un altro indizio che questo file è tutt'altro che un file normale:

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

Se fosse una manifestazione di una pipe denominata, mostrerebbe simile a uno di questi file:

$ 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

Se tocchiamo un emptyfile, /proc/cpuinfosembra essere più simile a un file che a una pipe:

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

Quindi a questo punto dobbiamo fare un passo indietro e ridurre un po 'lo zoom. Stiamo esaminando un determinato file, ma forse dovremmo guardare al filesystem su cui risiede il file. E per questo possiamo usare il mountcomando.

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

OK, quindi il tipo di filesystem è di tipo proc. Quindi /procè un diverso tipo di filesystem, questo è il nostro suggerimento che i file sotto /procsono speciali. Non sono solo la corsa dei file del mulino. Scopriamo quindi qualche informazione in più su ciò che rende procspeciale il filesystem.

Dai un'occhiata alla mountpagina man di:

Il filesystem proc non è associato a un dispositivo speciale e quando lo si monta, è possibile utilizzare una parola chiave arbitraria, come proc, anziché una specifica del dispositivo. (La scelta consueta nessuna è meno fortunata: il messaggio di errore "nessuno occupato" di umount può essere fonte di confusione.)

E se diamo un'occhiata alla procpagina man di:

Il file system proc è un pseudo-file system utilizzato come interfaccia per le strutture di dati del kernel. È comunemente montato su / proc. La maggior parte è di sola lettura, ma alcuni file consentono di modificare le variabili del kernel.

Un po 'più in basso nella stessa pagina man:

/ Proc / cpuinfo

Questa è una raccolta di elementi dipendenti dalla CPU e dall'architettura di sistema, per ogni architettura supportata un elenco diverso. Due voci comuni sono il processore che fornisce il numero di CPU e i bogomips; una costante di sistema che viene calcolata durante l'inizializzazione del kernel. Le macchine SMP hanno informazioni per ogni CPU. Il comando lscpu (1) raccoglie le sue informazioni da questo file.

In fondo alla pagina man c'è un riferimento a un documento del kernel che puoi trovare qui, intitolato: THE / proc FILESYSTEM . Citando da quel documento:

Il file system proc funge da interfaccia per le strutture di dati interne nel kernel. Può essere usato per ottenere informazioni sul sistema e per modificare alcuni parametri del kernel in fase di esecuzione (sysctl).

conclusioni

Quindi cosa abbiamo imparato qui? Beh, dato che /procviene indicato come uno pseudo filesystem e anche un "interfaccia per strutture dati interne" è probabilmente lecito ritenere che gli elementi al suo interno sono non file effettivi, ma piuttosto solo manifestazioni fatto a guardare come i file, ma non sono realmente.

Chiuderò con questa citazione che apparentemente appariva in una versione precedente del man 5 proc2004 circa, ma per qualsiasi motivo non è più inclusa. NOTA: non sono sicuro del motivo per cui è stato rimosso poiché descrive molto bene ciò che /procè:

La directory / proc sui sistemi GNU / Linux fornisce un'interfaccia simile al file system al kernel. Ciò consente alle applicazioni e agli utenti di recuperare informazioni e impostare valori nel kernel utilizzando la normale operazione di I / O del file system.

Il file system proc viene talvolta definito pseudo-file system di informazioni di processo. Non contiene file `` reali '' ma piuttosto informazioni di runtime del sistema (ad es. Memoria di sistema, dispositivi montati, configurazione hardware, ecc.). Per questo motivo può essere considerato un centro di controllo e informazione per il kernel. In effetti, molte utilità di sistema sono semplicemente chiamate a file in questa directory. Ad esempio, il comando lsmod, che elenca i moduli caricati dal kernel, è sostanzialmente lo stesso di 'cat / proc / modules' mentre lspci, che elenca i dispositivi collegati al bus PCI del sistema, è lo stesso di 'cat / proc / pci'. Modificando i file che si trovano in questa directory è possibile modificare i parametri del kernel mentre il sistema è in esecuzione.

Fonte: il pseudo file system proc

Riferimenti


1
Bene, :) Questa è la prima cosa che ho provato quando ho visto la domanda:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc

1
Bella risposta! Su Linux, se vuoi approfondire, il sorgente per il filesystem proc è in fs / proc nel sorgente del kernel. Vedrai che esiste un fs / proc / cpuinfo.c ma, sfortunatamente, è piuttosto vuoto poiché il sollevamento pesante è distribuito su tutto l'arco / poiché dipende dall'architettura. Per un esempio più semplice vedi fs / proc / uptime.c. Dando un'occhiata al file possiamo indovinare che uptime_proc_show è il cavallo di battaglia di ciò che ci fornisce i dati che vogliamo e che potremmo esplorare di più immergendoci nelle funzioni che chiama. Per capire l'interfaccia di seq_file e come viene usata nei procfs, vedi:
Steven D


1
@slm: +1, ottima risposta. Ma per me, il primo suggerimento è che un file speciale è la sua dimensione ^^ 0 byte, eppure puoi catalogarne molte cose (un po 'come alcuni file di pipe).
Olivier Dulac il

@OlivierDulac - buon punto. Ho apportato ulteriori modifiche in base al tuo feedback. LMK se posso apportare ulteriori miglioramenti. Grazie.
slm

14

La risposta data da @slm è molto completa, ma penso che una spiegazione più semplice potrebbe venire da un cambiamento di prospettiva.

Nell'uso quotidiano possiamo pensare ai file come cose fisiche, cioè. blocchi di dati memorizzati su alcuni dispositivi. Questo rende file come / proc / cpuinfo molto misteriosi e confusi. Tuttavia, ha perfettamente senso se pensiamo ai file come a un'interfaccia ; un modo per inviare e uscire i dati da alcuni programmi.

I programmi che inviano e ricevono dati in questo modo sono filesystem o driver (a seconda di come si definiscono questi termini, che potrebbe essere una definizione troppo ampia o troppo ristretta). Il punto importante è che alcuni di questi programmi utilizzano un dispositivo hardware per archiviare e recuperare i dati inviati tramite questa interfaccia; ma non tutto.

Alcuni esempi di filesystem che non utilizzano un dispositivo di archiviazione (almeno direttamente) sono:

  • File system che utilizzano dati cercati o calcolati. Proc è un esempio, poiché ottiene dati da vari moduli del kernel. Un esempio estremo è πfs (github.com/philipl/pifs)
  • Tutti i filesystem FUSE, che gestiscono i dati con un normale programma di spazio utente
  • Filesystem che trasformano i dati di un altro filesystem al volo, ad esempio utilizzando la crittografia, la compressione o persino la transcodifica audio (khenriks.github.io/mp3fs/)

Il sistema operativo Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) è un esempio estremo dell'uso dei file come interfaccia di programmazione generale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.