Was passiert, wenn ich den Befehl cat / proc / cpuinfo ausführe?

Antworten:

72

Wann immer Sie eine Datei lesen, wird ein /procCode im Kernel aufgerufen, der den zu lesenden Text als Dateiinhalt berechnet. Die Tatsache, dass der Inhalt im Handumdrehen generiert wird, erklärt, warum für fast alle Dateien die aktuelle Zeit und die Größe 0 angegeben wurde. Hier sollte 0 als „Weiß nicht“ angegeben werden. Im Gegensatz zu gewöhnlichen Dateisystemen lädt das Dateisystem /proc, das als procfs bezeichnet wird , keine Daten von einer Festplatte oder einem anderen Speichermedium (wie FAT, ext2, zfs,…) oder über das Netzwerk (wie NFS, Samba,…). und ruft keinen Benutzercode auf (im Gegensatz zu FUSE ).

Procfs ist in den meisten Nicht-BSD-Unices vorhanden. Es wurde in den Bell Labs von AT & T in UNIX 8 eingeführt , um Informationen zu Prozessen zu melden (und psist häufig ein sehr nützlicher Drucker, um Informationen durchzulesen /proc). Die meisten procfs-Implementierungen haben eine Datei oder ein Verzeichnis, die bzw. das aufgerufen wird /proc/123, um Informationen über den Prozess mit PID 123 zu melden. Linux erweitert das proc-Dateisystem um viele weitere Einträge, die den Status des Systems melden, einschließlich Ihres Beispiels /proc/cpuinfo.

In der Vergangenheit hat Linux /procverschiedene Dateien erworben, die Informationen zu Treibern enthalten. Diese Verwendung wird jetzt jedoch nicht mehr empfohlen /sysund /procentwickelt sich nur langsam. Einträge mögen /proc/busund /proc/fs/ext4bleiben dort, wo sie aus Gründen der Abwärtskompatibilität sind, aber neuere ähnliche Schnittstellen werden unter erstellt /sys. In dieser Antwort werde ich mich auf Linux konzentrieren.

Ihr erster und zweiter Einstiegspunkt für die Dokumentation /proczu Linux sind:

  1. die proc(5)Manpage ;
  2. Das /procDateisystem in der Kerneldokumentation .

Ihr dritter Einstiegspunkt, wenn die Dokumentation dies nicht behandelt, ist das Lesen der Quelle . Sie können den Quellcode auf Ihren Computer herunterladen, aber dies ist ein riesiges Programm, und LXR , der Linux-Querverweis, ist eine große Hilfe. (Es gibt viele LXR-Varianten; die lxr.linux.nomit Abstand beste, aber leider ist die Site häufig nicht erreichbar.) Ein wenig C-Kenntnisse sind erforderlich, aber Sie müssen kein Programmierer sein, um einen mysteriösen Wert aufzuspüren .

Die Kernbehandlung von /procEinträgen befindet sich im fs/procVerzeichnis. Jeder Fahrer kann Einträge in registrieren /proc(obwohl dies, wie oben angegeben, jetzt zugunsten von veraltet ist /sys). Wenn Sie also nicht das finden, wonach Sie suchen fs/proc, suchen Sie überall anders. Treiber rufen Funktionen auf, die in deklariert sind include/linux/proc_fs.h. Kernel-Versionen bis 3.9 bieten die Funktionen create_proc_entryund einige Wrapper (insbesondere create_proc_read_entry), und Kernel-Versionen 3.10 und höher bieten stattdessen nur proc_createund proc_create_data(und einige mehr).

Am /proc/cpuinfoBeispiel einer Suche nach "cpuinfo"führt Sie der Aufruf zu proc_create("cpuinfo, …")in fs/proc/cpuinfo.c. Sie können sehen, dass es sich bei dem Code so ziemlich um Boilerplate-Code handelt: Da die meisten Dateien /procnur Textdaten ausgeben, gibt es dafür Hilfsfunktionen. Es gibt nur eine seq_operationsStruktur, und das eigentliche Fleisch befindet sich in der cpuinfo_opDatenstruktur, die architekturabhängig ist und normalerweise in arch/<architecture>/kernel/setup.c(oder manchmal in einer anderen Datei) definiert wird. Am Beispiel von x86 werden wir dazu geführt arch/x86/kernel/cpu/proc.c. Dort ist die Hauptfunktionshow_cpuinfo, der den gewünschten Dateiinhalt druckt; Der Rest der Infrastruktur ist dazu da, die Daten mit der von ihr angeforderten Geschwindigkeit an den Leseprozess weiterzuleiten. Sie können die Daten, die im laufenden Betrieb zusammengestellt werden, anhand von Daten in verschiedenen Variablen im Kernel sehen, einschließlich einiger Zahlen, die im laufenden Betrieb berechnet werden, z. B. der CPU-Frequenz .

Ein großer Teil davon /procsind die prozessbezogenen Informationen in /proc/<PID>. Diese Einträge sind fs/proc/base.cin dem tgid_base_stuffArray registriert . Einige hier registrierte Funktionen sind in anderen Dateien definiert. Schauen wir uns ein paar Beispiele an, wie diese Einträge generiert werden:

Ein weiterer wichtiger Bereich von /procist /proc/sys, das eine direkte Schnittstelle zu ist sysctl. Das Lesen von einem Eintrag in dieser Hierarchie gibt den Wert des entsprechenden Sysctl-Werts zurück, und das Schreiben legt den Sysctl-Wert fest. Die Einstiegspunkte für sysctl befinden sich in fs/proc/proc_sysctl.c. Sysctls haben ein eigenes Registrierungssystem mit register_sysctlund mit Freunden.

Gilles
quelle
59

Wenn Sie versuchen, einen Einblick zu gewinnen, welche Art von Magie sich hinter den Kulissen abspielt, ist Ihr bester Freund strace. Das Erlernen der Bedienung dieses Tools ist eines der besten Dinge, die Sie tun können, um besser zu verstehen, was verrückte Magie hinter den Kulissen vor sich geht.

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

An der obigen Ausgabe können Sie erkennen, dass /proc/cpuinfoes sich nur um eine reguläre Datei handelt oder zumindest eine solche zu sein scheint. Also lasst uns tiefer graben.

Tiefer tauchen

# 1 - mit ls ..

Betrachtet man die Datei selbst, scheint es sich um "nur eine Datei" zu handeln.

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

Aber schauen Sie genauer hin. Wir bekommen unseren ersten Hinweis, dass es etwas Besonderes ist, beachten Sie, dass die Größe der Datei 0 Bytes beträgt.

# 2 - mit stat ..

Wenn wir uns nun die Datei mit ansehen, können statwir unseren nächsten Hinweis erhalten, dass etwas Besonderes daran liegt /proc/cpuinfo.

Lauf Nr. 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: -
Lauf Nr. 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: -

Beachten Sie die Zugriffs-, Änderungs- und Änderungszeiten? Sie ändern sich bei jedem Zugriff. Das ist höchst ungewöhnlich, dass sich alle 3 so ändern würden. Die Zeitstempelattribute einer Datei bleiben in der Regel unverändert, es sei denn, sie wurden bearbeitet.

# 3 - mit Datei ..

Noch ein Hinweis darauf, dass diese Datei alles andere als eine reguläre Datei ist:

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

Wenn es sich um eine Manifestation einer Named Pipe handeln würde, würde sie ähnlich einer der folgenden Dateien angezeigt:

$ 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

Wenn wir eine berühren emptyfile, /proc/cpuinfoscheint dies eher eine Datei als eine Pipe zu sein:

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

An diesem Punkt müssen wir also einen Schritt zurücktreten und etwas herauszoomen. Wir schauen uns eine bestimmte Datei an, aber vielleicht sollten wir uns das Dateisystem ansehen, in dem sich diese Datei befindet. Und dafür können wir den mountBefehl verwenden.

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

OK, der Dateisystemtyp ist also vom Typ proc. Es handelt sich also /procum einen anderen Dateisystemtyp, das ist unser Hinweis darauf, dass die Dateien darunter etwas /procBesonderes sind. Sie sind nicht nur Ihre Lieblingsdateien. Informieren wir uns über die procBesonderheiten des Dateisystems.

Schauen Sie sich die mountManpage von an:

Das proc-Dateisystem ist keinem speziellen Gerät zugeordnet, und beim Mounten kann anstelle einer Gerätespezifikation ein beliebiges Schlüsselwort wie proc verwendet werden. (Die übliche Wahl none ist weniger glücklich: Die Fehlermeldung none busy von umount kann verwirrend sein.)

Und wenn wir uns die procManpage anschauen :

Das proc-Dateisystem ist ein Pseudodateisystem, das als Schnittstelle zu Kerneldatenstrukturen verwendet wird. Es wird üblicherweise bei / proc montiert. Das meiste davon ist schreibgeschützt, aber in einigen Dateien können Kernelvariablen geändert werden.

Ein bisschen weiter unten in derselben Manpage:

/ proc / cpuinfo

Dies ist eine Sammlung von Elementen, die von der CPU und der Systemarchitektur abhängen. Für jede unterstützte Architektur wird eine andere Liste erstellt. Zwei gebräuchliche Einträge sind Prozessor, der die CPU-Nummer und die Bogomips angibt. Eine Systemkonstante, die während der Kernel-Initialisierung berechnet wird. SMP-Maschinen verfügen über Informationen für jede CPU. Der Befehl lscpu (1) sammelt seine Informationen aus dieser Datei.

Am Ende der Manpage befindet sich ein Verweis auf ein Kerneldokument, das Sie hier mit dem Titel: THE / proc FILESYSTEM finden . Zitat aus diesem Dokument:

Das proc-Dateisystem fungiert als Schnittstelle zu internen Datenstrukturen im Kernel. Es kann verwendet werden, um Informationen über das System zu erhalten und bestimmte Kernelparameter zur Laufzeit zu ändern (sysctl).

Schlussfolgerungen

Also, was haben wir hier gelernt? Nun /proc, da dies als Pseudo-Dateisystem und auch als "Schnittstelle zu internen Datenstrukturen" bezeichnet wird, ist es wahrscheinlich sicher anzunehmen, dass die darin enthaltenen Elemente keine tatsächlichen Dateien sind, sondern nur Manifestationen, die wie Dateien aussehen, aber nicht wirklich sind.

Ich werde mit diesem Zitat schließen, das anscheinend in einer früheren Version des man 5 procvon circa 2004 war, aber aus welchem ​​Grund auch immer nicht mehr enthalten ist. HINWEIS: Ich bin nicht sicher, warum es entfernt wurde, da es sehr gut beschreibt, was /procist:

Das Verzeichnis / proc auf GNU / Linux-Systemen bietet eine dateisystemähnliche Schnittstelle zum Kernel. Auf diese Weise können Anwendungen und Benutzer Informationen aus dem Kernel abrufen und Werte im normalen Dateisystem-E / A-Betrieb festlegen.

Das proc-Dateisystem wird manchmal als Prozessinformations-Pseudodateisystem bezeichnet. Es enthält keine echten Dateien, sondern Informationen zum Laufzeitsystem (z. B. Systemspeicher, gemountete Geräte, Hardwarekonfiguration usw.). Aus diesem Grund kann es als Kontroll- und Informationszentrum für den Kernel angesehen werden. Tatsächlich sind viele Systemdienstprogramme lediglich Aufrufe von Dateien in diesem Verzeichnis. Beispielsweise ist der Befehl lsmod, der die vom Kernel geladenen Module auflistet, im Grunde derselbe wie 'cat / proc / modules', während lspci, der an den PCI-Bus des Systems angeschlossene Geräte auflistet, derselbe ist wie 'cat / proc / pci '. Durch Ändern der Dateien in diesem Verzeichnis können Sie die Kernelparameter ändern, während das System ausgeführt wird.

Quelle: Das proc Pseudo-Dateisystem

Verweise

slm
quelle
1
Cool, :) Dies ist das erste, was ich ausprobiert habe, als ich die Frage sah:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc
1
Gute Antwort! Unter Linux befindet sich die Quelle für das proc-Dateisystem in fs / proc in der Kernelquelle, wenn Sie tiefer graben möchten. Sie werden sehen, dass es eine fs / proc / cpuinfo.c gibt, diese ist jedoch leider eher leer, da das schwere Heben über den gesamten Bogen verteilt ist, da es von der Architektur abhängt. Ein einfacheres Beispiel finden Sie unter fs / proc / uptime.c. Wenn wir uns die Datei ansehen, können wir erraten, dass uptime_proc_show das Arbeitspferd der Daten ist, die wir benötigen, und wir könnten sie genauer untersuchen, indem wir in die aufgerufenen Funktionen eintauchen. Um die seq_file-Schnittstelle zu verstehen und wie sie in procfs verwendet wird, siehe:
Steven D
1
@slm: +1, tolle Antwort. Aber für mich ist der erste Hinweis, dass es sich um eine spezielle Datei handelt, ihre Größe ^^ 0 Bytes, aber Sie können eine Menge Dinge daraus ableiten (ein bisschen wie bei einigen Pipe-Dateien).
Olivier Dulac
@OlivierDulac - guter Punkt. Aufgrund Ihres Feedbacks habe ich weitere Änderungen vorgenommen. LMK wenn ich noch etwas verbessern kann. Vielen Dank.
SLM
14

Die Antwort von @slm ist sehr umfassend, aber ich denke, eine einfachere Erklärung könnte aus einem Perspektivwechsel resultieren.

Im täglichen Gebrauch können wir uns Dateien als physische Dinge vorstellen, z. Datenblöcke, die auf einem Gerät gespeichert sind. Dies macht Dateien wie / proc / cpuinfo sehr mysteriös und verwirrend. Es macht jedoch alles Sinn, wenn wir uns Dateien als Schnittstelle vorstellen. eine Möglichkeit, Daten in ein Programm hinein und aus einem Programm heraus zu senden.

Die Programme, die Daten auf diese Weise senden und empfangen, sind Dateisysteme oder Treiber (je nachdem, wie Sie diese Begriffe definieren, ist eine Definition möglicherweise zu weit oder zu eng). Der wichtige Punkt ist, dass einige dieser Programme ein Hardwaregerät verwenden, um die über diese Schnittstelle gesendeten Daten zu speichern und abzurufen. aber nicht alles.

Einige Beispiele für Dateisysteme, die (zumindest direkt) kein Speichergerät verwenden, sind:

  • Dateisysteme, die gesuchte oder berechnete Daten verwenden. Proc ist ein Beispiel, da es Daten von verschiedenen Kernelmodulen erhält. Ein extremes Beispiel ist πfs (github.com/philipl/pifs)
  • Alle FUSE-Dateisysteme, die die Daten mit einem normalen Userspace-Programm verarbeiten
  • Dateisysteme, die die Daten eines anderen Dateisystems im laufenden Betrieb umwandeln, beispielsweise durch Verschlüsselung, Komprimierung oder sogar Audio-Transcodierung (khenriks.github.io/mp3fs/)

Das Plan9-Betriebssystem ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) ist ein extremes Beispiel für die Verwendung von Dateien als allgemeine Programmierschnittstelle.

Warbo
quelle