Cosa succede quando scrivo cat /proc/cpuinfo . È una named pipe (o qualcos'altro) al sistema operativo che legge le informazioni sulla CPU al volo e genera quel testo ogni volta che lo chiamo?
Risposta accettata:
Ogni volta che leggi un file in /proc , questo richiama 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 adesso e le loro dimensioni riportate come 0 — qui dovresti leggere 0 come "non so". A differenza dei normali filesystem, il filesystem che è montato su /proc , chiamato procfs, non carica i dati da un disco o altro supporto di memorizzazione (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 degli unice non BSD. Ha iniziato la sua vita nei Bell Labs di AT&T nell'ottava edizione di UNIX come un modo per riportare informazioni sui processi (e ps è spesso una graziosa stampante per informazioni lette tramite /proc ). La maggior parte delle implementazioni di procfs ha 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, /proc di Linux ha acquisito vari file che forniscono informazioni sui driver, ma questo uso è ora deprecato a favore di /sys e /proc ora si evolve lentamente. Voci come /proc/bus e /proc/fs/ext4 rimangono dove si trovano per la compatibilità con le versioni precedenti, ma le interfacce simili più recenti vengono create in /sys . In questa risposta, mi concentrerò su Linux.
Il primo e il secondo punto di accesso per la documentazione su /proc su Linux sono:
- il
proc(5)pagina man; - Il
/procfilesystem nella documentazione del kernel .
Il tuo terzo punto di accesso, quando la documentazione non lo copre, è leggere la fonte . Puoi scaricare il sorgente sulla tua macchina, ma questo è un programma enorme e LXR, il riferimento incrociato di Linux, è di grande aiuto. (Ci sono molte varianti di LXR; quella in esecuzione su lxr.linux.no è di gran lunga il più bello, ma sfortunatamente il sito è spesso inattivo.) È richiesta una piccola conoscenza del C, ma non è necessario essere un programmatore per rintracciare un valore misterioso.
La gestione principale di /proc le voci si trovano in fs/proc directory. Qualsiasi pilota può registrare voci in /proc (sebbene, come indicato sopra, questo sia ora deprecato a favore di /sys ), quindi se non trovi quello che cerchi in fs/proc , guarda 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 (soprattutto create_proc_read_entry ), e le versioni del kernel 3.10 e successive forniscono invece solo proc_create e proc_create_data (e pochi altri).
Prendendo /proc/cpuinfo ad esempio, una ricerca per "cpuinfo" ti porta alla chiamata a proc_create("cpuinfo, …") in fs/proc/cpuinfo.c . Puoi vedere che il codice è praticamente un codice standard:poiché la maggior parte dei file sotto /proc scarica solo alcuni dati di testo, ci sono funzioni di supporto per farlo. C'è semplicemente un seq_operations struttura, e la vera carne è nel cpuinfo_op struttura dei dati, che dipende dall'architettura, generalmente definita in arch/<architecture>/kernel/setup.c (o talvolta un file diverso). Prendendo come esempio x86, siamo portati a arch/x86/kernel/cpu/proc.c . Lì la funzione principale è show_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 assemblati al volo dai dati in varie variabili nel kernel, inclusi alcuni numeri calcolati al volo come la frequenza della CPU.
Gran parte di /proc sono le informazioni per processo in /proc/<PID> . Queste voci sono registrate in fs/proc/base.c , nel tgid_base_stuff Vettore; alcune funzioni qui registrate sono definite in altri file. Diamo un'occhiata ad alcuni esempi di come vengono generate queste voci:
cmdlineè generato daproc_pid_cmdlinenello 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 leproc_clear_refs_operationsstrutture definisce unclear_refs_writefunzione ma nessuna funzione di lettura.cwdè un collegamento simbolico (un po' magico), dichiarato daproc_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 inproc_fd_operationsstruttura dei dati (sono standard 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 importante area 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. I punti di ingresso per sysctl sono in fs/proc/proc_sysctl.c . Sysctl ha il proprio sistema di registrazione con register_sysctl e amici.