Risposte:
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/123
per 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 /proc
acquisito vari file che forniscono informazioni sui driver, ma questo uso è ora deprecato a favore /sys
e /proc
ora si evolve lentamente. Le voci gradiscono /proc/bus
e /proc/fs/ext4
rimangono 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 /proc
su Linux sono:
proc(5)
pagina man ;/proc
filesystem 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 /proc
voci si trova nella fs/proc
directory. 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_entry
e alcuni wrapper (in particolare create_proc_read_entry
) e le versioni 3.10 e successive del kernel invece forniscono solo proc_create
e proc_create_data
(e alcune altre).
Prendendo /proc/cpuinfo
come 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 /proc
esegue il dump di alcuni dati di testo, ci sono funzioni di supporto per farlo. C'è solo una seq_operations
struttura, e la carne vera è nella cpuinfo_op
struttura 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_stuff
matrice ; alcune funzioni registrate qui sono definite in altri file. Diamo un'occhiata ad alcuni esempi di come vengono generate queste voci:
cmdline
viene generato dallo proc_pid_cmdline
stesso file. Individua i dati nel processo e li stampa.clear_refs
, a differenza delle voci che abbiamo visto finora, è scrivibile ma non leggibile. Pertanto le proc_clear_refs_operations
strutture definiscono una clear_refs_write
funzione ma nessuna funzione di lettura.cwd
è un collegamento simbolico (leggermente magico), dichiarato da proc_cwd_link
, che cerca la directory corrente del processo e la restituisce come contenuto del collegamento.fd
è una sottodirectory. Le operazioni sulla directory stessa sono definite nella proc_fd_operations
struttura dei dati (sono boilerplate ad eccezione della funzione che enumera le voci proc_readfd
, che enumera i file aperti del processo) mentre le operazioni sulle voci sono in `proc_fd_inode_operations .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_sysctl
e amici.
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.
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 stat
possiamo ottenere il nostro prossimo suggerimento che ci sia qualcosa di speciale /proc/cpuinfo
.
$ 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/cpuinfo
sembra 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 mount
comando.
$ 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 /proc
sono speciali. Non sono solo la corsa dei file del mulino. Scopriamo quindi qualche informazione in più su ciò che rende proc
speciale il filesystem.
Dai un'occhiata alla mount
pagina 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 proc
pagina 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).
Quindi cosa abbiamo imparato qui? Beh, dato che /proc
viene 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 proc
2004 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
strace -o catcpuproc.txt cat /proc/cpuinfo
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:
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.