Hier gibt es also grundsätzlich zwei verschiedene Arten von Dingen:
- Normale Dateisysteme, die Dateien in Verzeichnissen mit Daten und Metadaten in bekannter Weise enthalten (einschließlich Softlinks, Hardlinks usw.). Diese werden oft, aber nicht immer, von einem Blockgerät für die dauerhafte Speicherung unterstützt (ein tmpfs lebt nur im RAM, ist aber ansonsten identisch mit einem normalen Dateisystem). Die Semantik davon ist vertraut; lesen, schreiben, umbenennen usw., alles funktioniert so, wie Sie es erwarten.
- Virtuelle Dateisysteme verschiedener Art.
/proc
und/sys
sind hier Beispiele, ebenso wie benutzerdefinierte FUSE-Dateisysteme wiesshfs
oderifuse
. Diese sind viel vielfältiger, weil sie sich eigentlich nur auf ein Dateisystem mit einer Semantik beziehen, die in gewissem Sinne „benutzerdefiniert“ ist. Also beim Lesen aus einer Datei unter/proc
, greifen Sie nicht tatsächlich auf ein bestimmtes Datenelement zu, das von etwas anderem gespeichert wurde, das es früher geschrieben hat, wie unter einem normalen Dateisystem. Sie führen im Wesentlichen einen Kernel-Aufruf durch und fordern einige Informationen an, die on-the-fly generiert werden. Und dieser Code kann alles tun, was er will, da es nur eine Funktion ist, die irgendworead
implementiert Semantik. Daher haben Sie das seltsame Verhalten von Dateien unter/proc
, wie zum Beispiel vorgeben, Symlinks zu sein, obwohl sie es nicht wirklich sind.
Der Schlüssel ist dieser /dev
ist eigentlich normalerweise eine der ersten Art. In modernen Distributionen ist es normal, /dev
zu haben so etwas wie ein tmpfs sein, aber in älteren Systemen war es normal, dass es sich um ein einfaches Verzeichnis auf der Festplatte handelte, ohne besondere Attribute. Der Schlüssel ist, dass die Dateien unter /dev
sind Geräteknoten, eine Art spezielle Datei, ähnlich wie FIFOs oder Unix-Sockets; Ein Geräteknoten hat eine Haupt- und eine Nebennummer, und das Lesen oder Schreiben dieser Nummern führt einen Aufruf an einen Kerneltreiber aus, ähnlich wie das Lesen oder Schreiben eines FIFO den Kernel aufruft, um Ihre Ausgabe in einer Pipe zu puffern. Dieser Treiber kann machen was er will, berührt aber normalerweise Hardware irgendwie, z.B. um auf eine Festplatte zuzugreifen oder Ton über die Lautsprecher wiederzugeben.
Um die ursprünglichen Fragen zu beantworten:
-
Es gibt zwei relevante Fragen, ob die „Datei existiert“ oder nicht; Diese sind, ob die Geräteknotendatei tatsächlich existiert und ob der Kernel-Code, der sie unterstützt, sinnvoll ist. Ersteres wird wie alles andere in einem normalen Dateisystem aufgelöst. Moderne Systeme verwenden
udev
oder etwas Ähnliches, um nach Hardwareereignissen zu suchen und die Geräteknoten unter/dev
automatisch zu erstellen und zu zerstören entsprechend. Aber ältere Systeme oder leichte benutzerdefinierte Builds können alle ihre Geräteknoten buchstäblich auf der Festplatte haben, die im Voraus erstellt wurden. Wenn Sie diese Dateien lesen, rufen Sie den Kernel-Code auf, der durch die Haupt- und Nebengerätenummern bestimmt wird. Wenn diese nicht sinnvoll sind (wenn Sie beispielsweise versuchen, ein Blockgerät zu lesen, das nicht existiert), erhalten Sie einfach eine Art I/O-Fehler. -
Die Art und Weise, wie ermittelt wird, welcher Kernel-Code für welche Gerätedatei aufgerufen werden soll, variiert. Für virtuelle Dateisysteme wie
/proc
, implementieren sie ihren eigenenread
undwrite
Funktionen; Der Kernel ruft diesen Code einfach auf, je nachdem, an welchem Einhängepunkt er sich befindet, und die Implementierung des Dateisystems kümmert sich um den Rest. Bei Gerätedateien wird es basierend auf den Haupt- und Nebengerätenummern versendet.
Hier ist eine Dateiliste von /dev/sda1
auf meinem fast aktuellen Arch-Linux-Server:
% ls -li /dev/sda1
1294 brw-rw---- 1 root disk 8, 1 Nov 9 13:26 /dev/sda1
Also der Verzeichniseintrag in /dev/
für sda
hat eine Inode-Nummer, 1294. Es ist eine echte Datei auf der Festplatte.
Sehen Sie sich an, wo die Dateigröße normalerweise angezeigt wird. Stattdessen erscheint „8, 1“. Dies ist eine Haupt- und Nebengerätenummer. Beachten Sie auch das 'b' in den Dateiberechtigungen.
Die Datei /usr/include/ext2fs/ext2_fs.h
enthält diese (Fragment-)C-Struktur:
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
__u16 i_mode; /* File mode */
Diese Struktur zeigt uns die On-Disk-Struktur des Inodes einer Datei. Viele interessante Sachen sind in dieser Struktur; sieh es dir genau an.
Die i_mode
Element von struct ext2_inode
hat 16 Bits, und es verwendet nur 9 für die Berechtigungen user/group/other, read/write/execute und weitere 3 für setuid, setgid und sticky. Es hat 4 Bits, um Typen wie "einfache Datei", "Link", "Verzeichnis", "Named Pipe", "Unix Family Socket" und "Block Device" zu unterscheiden.
Der Linux-Kernel kann dem üblichen Verzeichnissuchalgorithmus folgen und dann basierend auf den Berechtigungen und Flags in i_mode
eine Entscheidung treffen Element. Für 'b', Blockgerätedateien, kann es die Haupt- und Nebengerätenummer finden und traditionell die Hauptgerätenummer verwenden, um einen Zeiger auf eine Kernelfunktion (einen Gerätetreiber) nachzuschlagen, die sich mit Festplatten befasst. Die Minor-Gerätenummer wird normalerweise beispielsweise als SCSI-Bus-Gerätenummer oder als EIDE-Gerätenummer oder so ähnlich verwendet.
Einige andere Entscheidungen zum Umgang mit einer Datei wie /proc/cpuinfo
werden basierend auf dem Dateisystemtyp erstellt. Wenn Sie Folgendes tun:
% mount | grep proc
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
Sie können diesen /proc
sehen hat den Dateisystemtyp "proc". Lesen aus einer Datei in /proc
veranlasst den Kernel, je nach Typ des Dateisystems etwas anderes zu tun, so wie das Öffnen einer Datei auf einem ReiserFS- oder DOS-Dateisystem dazu führen würde, dass der Kernel verschiedene Funktionen verwendet, um Dateien und Daten der Dateien zu lokalisieren.
Am Ende des Tages sind das alles Dateien für Unix, das ist das Schöne an der Abstraktion.
Wie die Dateien vom Kernel gehandhabt werden, das ist nun eine andere Geschichte.
/proc und heutzutage /dev und /run (alias /var/run) sind virtuelle Dateisysteme im RAM. /proc ist eine Schnittstelle/Windows zu Kernel-Variablen und -Strukturen.
Ich empfehle die Lektüre von The Linux Kernel http://tldp.org/LDP/tlk/tlk.html und Linux Device Drivers, Third Edition https://lwn.net/Kernel/LDD3/.
Mir gefiel auch The Design and Implementation of the FreeBSD Operating System http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1
Sehen Sie sich die relevante Seite an, die sich auf Ihre Frage bezieht.
http://www.tldp.org/LDP/tlk/dd/drivers.html