Come funziona / proc / *?


62

Ci sono molti file in /proc, come /proc/cpuinfo, /proc/meminfo, /proc/devicese così via, che, una volta aperto, informazioni di sistema di ritorno.

Questi file non sembrano avere alcuna esistenza nella realtà, poiché l'esecuzione filesu di essi dice solo che sono vuoti.

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

Come funzionano esattamente questi file?

Risposte:


72

In realtà è piuttosto semplice, almeno se non hai bisogno dei dettagli di implementazione.

Prima di tutto, su Linux tutti i file system (ext2, ext3, btrfs, reiserfs, tmpfs, zfs, ...) sono implementati nel kernel. Alcuni possono scaricare il lavoro nel codice userland tramite FUSE, e alcuni sono disponibili solo sotto forma di un modulo del kernel ( ZFS nativo è un esempio notevole di quest'ultimo a causa delle restrizioni di licenza), ma in entrambi i casi rimane un componente del kernel. Questa è una base importante.

Quando un programma vuole leggere da un file, esso emetterà diverse chiamate di libreria di sistema che alla fine finiscono nel kernel nella forma di open(), read(), close()la sequenza (possibilmente con seek()gettato in buona misura). Il kernel prende il percorso e il nome file forniti e attraverso il file system e il livello I / O del dispositivo li traduce in richieste fisiche di lettura (e in molti casi anche richieste di scrittura, ad esempio aggiornamenti atime) in alcuni archivi sottostanti.

Tuttavia, non deve tradurre tali richieste in modo specifico in memoria fisica e persistente . Il contratto del kernel prevede che l'emissione di quel particolare insieme di chiamate di sistema fornirà il contenuto del file in questione . Dove esattamente nel nostro regno fisico il "file" esiste è secondario a questo.

Di /procsolito è montato ciò che è noto come procfs. Questo è un tipo di file system speciale, ma poiché è un file system, in realtà non è diverso da un ext3file system montato da qualche parte. Quindi la richiesta viene passata al codice del driver del file system procfs, che conosce tutti questi file e directory e restituisce particolari informazioni dalle strutture di dati del kernel .

Il "livello di archiviazione" in questo caso sono le strutture di dati del kernel e procfsforniscono un'interfaccia pulita e conveniente per accedervi. Tieni presente che il montaggio di procfs /procè semplicemente una convenzione; potresti semplicemente montarlo altrove. In effetti, a volte ciò viene fatto, ad esempio nelle chroot jail quando il processo in esecuzione ha bisogno di accedere a / proc per qualche motivo.

Funziona allo stesso modo se si scrive un valore in un file; a livello di kernel, che si traduce in una serie di open(), seek(), write(), close()le chiamate che ancora una volta viene passato al driver del file system; di nuovo, in questo caso particolare, il codice procfs.

Il motivo particolare per cui vedi filetornare emptyè che molti dei file esposti da procfs sono esposti con una dimensione di 0 byte. La dimensione di 0 byte è probabilmente un'ottimizzazione sul lato kernel (molti dei file in / proc sono dinamici e possono facilmente variare in lunghezza, possibilmente anche da una lettura alla successiva, e calcolare la lunghezza di ogni file su ogni directory letto sarebbe potenzialmente essere molto costoso). Passando dai commenti a questa risposta, che puoi verificare sul tuo sistema eseguendo strace o uno strumento simile, invia fileprima una stat()chiamata per rilevare eventuali file speciali, quindi coglie l'occasione, se la dimensione del file è segnalata come 0 , interrompere e segnalare il file come vuoto.

Questo comportamento è effettivamente documentato e può essere modificato specificando -so --special-filessulla filechiamata, anche se, come indicato nella pagina di manuale che può avere effetti collaterali. La citazione seguente è tratta dalla pagina man del file BSD 5.11, datata 17 ottobre 2011.

Normalmente, il file tenta solo di leggere e determinare il tipo di file di argomenti i cui report stat (2) sono file ordinari. Questo evita problemi, perché la lettura di file speciali può avere conseguenze peculiari. Se si specifica l' -sopzione, il file legge anche i file degli argomenti che sono file speciali a blocchi o caratteri. Ciò è utile per determinare i tipi di file system dei dati nelle partizioni del disco non elaborate, che sono file speciali a blocchi. Questa opzione fa sì che il file ignori la dimensione del file come riportato da stat (2) poiché su alcuni sistemi riporta una dimensione zero per le partizioni del disco non elaborate.


5
Quando lo guardi con strace file /proc/versiono ltrace -S /proc/version, l'ottimizzazione è piuttosto piccola. Fa stat()prima una chiamata e scopre che la dimensione è 0, saltando così open()- ma prima sta caricando diversi file magici.
ott--

2
@ ott-- Questa è in effetti una strana sequenza di eventi, ma potrebbe essere correlata al fatto che è possibile passare più nomi di file file. In questo modo, il file precarica i file magici, quindi elabora la riga di comando parametro per parametro; invece di spostare il caricamento del file magico nel "fai questo appena prima di provare a determinare quale tipo di file questo particolare è" parte del codice, il che aumenterebbe la complessità. Chiamare stat()e agire sul suo valore di ritorno è essenzialmente innocuo; aggiungere complessità nel tenere traccia di ulteriori rischi statali interni introducendo bug.
un CVn,

@ ott-- In realtà, il motivo fileriporta che "il file è vuoto" è perché chiama statper rilevare file speciali (denominati pipe, dispositivi, ...) e coglie l'occasione per interrompere l'elaborazione di file vuoti. file -s /proc/versionriporta "testo ASCII".
Gilles 'SO- smetti di essere malvagio' il

4
@Gilles -sÈ previsto per dispositivi speciali block / char. Alla fine ho guardato la filefonte e alla fine di fsmagic.c ho visto questa spiegazione del motivo per cui ritorna ASCII textinvece di empty:If stat() tells us the file has zero length, report here that the file is empty, so we can skip all the work of opening and reading the file. But if the -s option has been given, we skip this optimization, since on some systems, stat() reports zero size for raw disk partitions.
ott--

15

In questa directory, puoi controllare come il kernel visualizza i dispositivi, regolare le impostazioni del kernel, aggiungere dispositivi al kernel e rimuoverli di nuovo. In questa directory è possibile visualizzare direttamente l'utilizzo della memoria e le statistiche I / O.

Puoi vedere quali dischi sono montati e quali file system sono utilizzati. In breve, ogni singolo aspetto del tuo sistema Linux può essere esaminato da questa directory, se sai cosa cercare.

La /procdirectory non è una directory normale. Se dovessi eseguire l'avvio da un CD di avvio e guardare quella directory sul tuo disco rigido, la vedresti vuota. Quando lo guardi sotto il tuo normale sistema in esecuzione, può essere abbastanza grande. Tuttavia, non sembra utilizzare alcuno spazio sul disco rigido. Questo perché è un file system virtuale.

Poiché il /procfile system è un file system virtuale e risiede nella memoria, /procogni volta che il computer Linux viene riavviato viene creato un nuovo file system.

In altre parole, è solo un mezzo per sbirciare e colpire facilmente le viscere del sistema Linux attraverso un'interfaccia di tipo file e directory. Quando guardi un file nella /procdirectory, guardi direttamente un intervallo di memoria nel kernel di Linux e vedi cosa può vedere.

I livelli nel file system

Inserisci qui la descrizione dell'immagine

Esempi:

  • All'interno /proc, c'è una directory per ogni processo in esecuzione, denominata con il suo ID processo. Queste directory contengono file che contengono informazioni utili sui processi, come:
    • exe: che è un collegamento simbolico al file su disco da cui è stato avviato il processo.
    • cwd: che è un collegamento simbolico alla directory di lavoro del processo.
    • wchan: che, quando letto, restituisce il canale di attesa in cui è in corso il processo.
    • maps: che, quando letto, restituisce le mappe di memoria del processo.
  • /proc/uptime restituisce il tempo di attività come due valori decimali in secondi, separati da uno spazio:
    • la quantità di tempo dall'avvio del kernel.
    • la quantità di tempo in cui il kernel è rimasto inattivo.
  • /proc/interrupts: Per informazioni relative agli interrupt.
  • /proc/modules: Per un elenco di moduli.

Per informazioni più dettagliate consultare man proc o kernel.org .


"Se dovessi fare il boot da un cd di boot e guardare quella directory sul tuo disco rigido, lo vedresti vuoto." Questo non è specifico di / proc, è generale per qualsiasi punto di montaggio in cui il file system sottostante non è stato montato. Se esegui l'avvio dallo stesso CD di avvio e fai qualcosa del genere mount -t procfs procfs /mnt/proc, vedrai il kernel / proc attualmente in esecuzione.
un CVn del

5

Hai ragione, non sono file reali.

In termini più semplici, è un modo per parlare al kernel usando i normali metodi di lettura e scrittura dei file, invece di chiamare direttamente il kernel. È in linea con la filosofia "tutto è un file" di Unix.

I file in /procnon esistono fisicamente da nessuna parte, ma il kernel reagisce ai file che leggi e scrivi al loro interno e, invece di scrivere in un archivio, riporta informazioni o fa qualcosa.

Allo stesso modo, i file in /devnon sono realmente file nel senso tradizionale (anche se su alcuni sistemi i file in /devrealtà potrebbero esistere sul disco, non avranno molto altro a parte il dispositivo a cui si riferiscono) - ti permettono di parlare a un dispositivo che utilizza la normale API I / O del file Unix o qualsiasi altra cosa che lo utilizza, come le shell


1
È più simile a * nix che solo un file può essere protetto. Poiché gli elenchi di controllo di accesso sono persistenti nel file system, è conveniente proteggere le risorse privilegiate utilizzando il meccanismo comune già fornito dal driver del file system. Questo semplifica l'implementazione di strumenti che accedono alle strutture del kernel e consente loro di funzionare senza permessi elevati leggendo invece dai file virtuali del file system proc.
Pekka,

3

All'interno della /procdirectory, ci sono due tipi di contenuto, la prima directory numerata e la seconda è il file di informazioni di sistema.

/procè un file system virtuale. Ad esempio, se lo fai ls -l /proc/stat, noterai che ha una dimensione di 0 byte, ma se fai "cat / proc / stat", vedrai del contenuto all'interno del file.

Fai un ls -l /proc, e vedrai molte directory con solo numeri. Questi numeri rappresentano gli ID di processo (PID). I file all'interno di questa directory numerata corrispondono al processo con quel particolare PID.

Alcuni file disponibili in /proc, contengono informazioni di sistema come cpuinfo, meminfo e loadavg.

Alcuni comandi di Linux leggono le informazioni da questi /procfile e le visualizzano. Ad esempio, il comando gratuito , legge le informazioni sulla memoria dal /proc/meminfofile, le formatta e le visualizza.

Per saperne di più sui singoli /procfile, fai "man 5 FILENAME".

/proc/cmdline – Kernel command line
/proc/cpuinfo – Information about the processors.
/proc/devices – List of device drivers configured into the currently running kernel.
/proc/dma – Shows which DMA channels are being used at the moment.
/proc/fb – Frame Buffer devices.
/proc/filesystems – File systems supported by the kernel.
/proc/interrupts – Number of interrupts per IRQ on architecture.
/proc/iomem – This file shows the current map of the system’s memory for its various devices
/proc/ioports – provides a list of currently registered port regions used for input or output communication with a device
/proc/loadavg – Contains load average of the system
The first three columns measure CPU utilization of the last 1, 5, and 10 minute periods.
The fourth column shows the number of currently running processes and the total number of processes.
The last column displays the last process ID used.
/proc/locks – Displays the files currently locked by the kernel
Sample line:
1: POSIX ADVISORY WRITE 14375 08:03:114727 0 EOF
/proc/meminfo – Current utilization of primary memory on the system
/proc/misc – This file lists miscellaneous drivers registered on the miscellaneous major device, which is number 10
/proc/modules – Displays a list of all modules that have been loaded by the system
/proc/mounts – This file provides a quick list of all mounts in use by the system
/proc/partitions – Very detailed information on the various partitions currently available to the system
/proc/pci – Full listing of every PCI device on your system
/proc/stat – Keeps track of a variety of different statistics about the system since it was last restarted
/proc/swap – Measures swap space and its utilization
/proc/uptime – Contains information about uptime of the system
/proc/version – Version of the Linux kernel, gcc, name of the Linux flavor installed.

2
Questo mi sembra più "come usare ciò che è in / proc?" piuttosto che "come funziona / proc?". Informazioni utili, ma non necessariamente rispondendo a questa particolare domanda .
un CVn,

Ogni file in / proc è informazioni di runtime, il che significa che quando si cat / proc / meminfo parte del kernel esegue una funzione che genera il contenuto del file.
Shailesh,

3

Esempio eseguibile minimo

Il modo migliore per capire queste cose secondo me è in realtà giocarci intorno, quindi ecco un modulo del kernel che crea una voce procfs:

myprocfs.c

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_open, single_release */
#include <uapi/linux/stat.h> /* S_IRUSR */

static const char *filename = "lkmc_procfs";

static int show(struct seq_file *m, void *v)
{
    seq_printf(m, "abcd\n");
    return 0;
}

static int open(struct inode *inode, struct  file *file)
{
    return single_open(file, show, NULL);
}

static const struct file_operations fops = {
    .llseek = seq_lseek,
    .open = open,
    .owner = THIS_MODULE,
    .read = seq_read,
    .release = single_release,
};

static int myinit(void)
{
    proc_create(filename, 0, NULL, &fops);
    return 0;
}

static void myexit(void)
{
    remove_proc_entry(filename, NULL);
}

module_init(myinit)
module_exit(myexit)
MODULE_LICENSE("GPL");

e quindi interagiamo con esso come:

insmod procfs.ko
cat /proc/lkmc_procfs

e questo produce l'output:

abcd

Da questo esempio, vediamo chiaramente che i procfile ci consentono di implementare arbitrarie "chiamate di sistema relative ai file" come open, reade llseek.

Tali chiamate di sistema possono quindi essere utilizzate per comunicazioni arbitrarie con il kernel.

Pertanto, tali file non devono avere nulla a che fare con i file effettivi nei file system, e questo è il caso di quasi tutti.

Nel nostro piccolo esempio, ad esempio, creiamo semplicemente un file inutile per il quale readritorna sempre abcd\n.

Ecco la mia configurazione QEMU + Buildroot completamente automatizzata per compilare e giocare in modo semplice e sicuro con questo modulo del kernel:

Alcune altre interfacce simili includono:

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.