GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie unterscheidet Linux zwischen echten und nicht existierenden (z. B. Geräte-) Dateien?

Hier gibt es also grundsätzlich zwei verschiedene Arten von Dingen:

  1. 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.
  2. Virtuelle Dateisysteme verschiedener Art. /proc und /sys sind hier Beispiele, ebenso wie benutzerdefinierte FUSE-Dateisysteme wie sshfs oder ifuse . 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 irgendwo read 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:

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

  2. 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 eigenen read und write 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


Linux
  1. So löschen Sie Dateien und Verzeichnisse in Linux über die Befehlszeile

  2. So konfigurieren Sie den SAMBA-Server und übertragen Dateien zwischen Linux und Windows

  3. So teilen und kombinieren Sie Dateien von der Befehlszeile in Linux

  4. So übertragen Sie Dateien zwischen Servern in Linux mit SCP und FTP

  5. Wie man Dateien tart, entpackt und den Inhalt der tar-Datei unter Linux anzeigt

So benennen Sie eine Datei (en) in Linux um

So teilen Sie Steam-Spieldateien zwischen Linux und Windows

So öffnen Sie Dateien und Ordner als Administrator im Nautilus-Dateimanager unter Linux

So benennen Sie Dateien und Verzeichnisse in Linux um

So kopieren Sie Dateien und Verzeichnisse im Linux-Terminal

So komprimieren Sie eine Datei unter Linux