Hallo zusammen, wir teilen mit Ihnen den zweiten Teil der Veröffentlichung „Virtuelle Dateisysteme in Linux: Warum werden sie benötigt und wie funktionieren sie?“ Sie können den ersten Teil lesen
So überwachen Sie VFS mit den Tools eBPF und bcc
Der einfachste Weg, zu verstehen, wie der Kernel mit Dateien arbeitet sysfs
ist, es in der Praxis zu sehen, und der einfachste Weg, ARM64 zu sehen, ist die Verwendung von eBPF. eBPF (kurz für Berkeley Packet Filter) besteht aus einer laufenden virtuellen Maschine query
) über die Befehlszeile. Die Kernel-Quellen sagen dem Leser, was der Kernel kann; Das Ausführen der eBPF-Tools auf einem geladenen System zeigt, was der Kernel tatsächlich tut.
Glücklicherweise ist der Einstieg in die Nutzung von eBPF mithilfe von Tools recht einfach bcc
sind Python-Skripte mit kleinen Einfügungen von C-Code, was bedeutet, dass jeder, der mit beiden Sprachen vertraut ist, sie leicht ändern kann. IN bcc/tools
Es gibt 80 Python-Skripte, was bedeutet, dass ein Entwickler oder Systemadministrator höchstwahrscheinlich etwas Passendes zur Lösung des Problems auswählen kann.
Versuchen Sie es, um zumindest eine oberflächliche Vorstellung davon zu bekommen, welche Arbeit VFSs auf einem laufenden System leisten vfscount
oder vfsstat
. Dies wird, sagen wir, Dutzende von Anrufen zeigen vfs_open()
und „seine Freunde“ passieren buchstäblich jede Sekunde.
vfsstat.py
ist ein Python-Skript mit C-Code-Einfügungen, das einfach VFS-Funktionsaufrufe zählt.
Lassen Sie uns ein trivialeres Beispiel geben und sehen, was passiert, wenn wir ein USB-Flash-Laufwerk an einen Computer anschließen und das System es erkennt.
Mit eBPF können Sie sehen, was passiert
/sys
wenn ein USB-Stick eingesteckt ist. Ein einfaches und komplexes Beispiel wird hier gezeigt.
Im oben gezeigten Beispiel bcc
Werkzeug sysfs_create_files()
. Wir sehen das sysfs_create_files()
wurde mit gestartet kworker
Stream als Reaktion auf die Tatsache, dass das Flash-Laufwerk eingelegt wurde, aber welche Datei wurde erstellt? Das zweite Beispiel zeigt die Leistungsfähigkeit von eBPF. Hier trace.py
Gibt einen Kernel-Backtrace (Option -K) und den Namen der erstellten Datei aus sysfs_create_files()
. Beim Einfügen einer einzelnen Anweisung handelt es sich um C-Code, der eine leicht erkennbare Formatzeichenfolge enthält, die vom Python-Skript bereitgestellt wird, das LLVM ausführt Just-in-Time-Compiler. Es kompiliert diese Zeile und führt sie in einer virtuellen Maschine im Kernel aus. Vollständige Funktionssignatur sysfs_create_files ()
muss im zweiten Befehl wiedergegeben werden, damit der Formatstring auf einen der Parameter verweisen kann. Fehler in diesem Teil des C-Codes führen zu erkennbaren Fehlern des C-Compilers. Wenn beispielsweise der Parameter -l weggelassen wird, wird „Fehler beim Kompilieren des BPF-Textes“ angezeigt. Entwickler, die mit C und Python vertraut sind, finden die Tools bcc
einfach zu erweitern und zu ändern.
Wenn das USB-Laufwerk angeschlossen ist, zeigt der Kernel-Backtrace, dass es sich bei PID 7711 um einen Thread handelt kworker
der die Datei erstellt hat «events»
в sysfs
. Dementsprechend der Anruf von sysfs_remove_files()
zeigt an, dass das Entfernen des Laufwerks zum Löschen der Datei geführt hat events
, was dem allgemeinen Konzept der Referenzzählung entspricht. Gleichzeitig ansehen sysfs_create_link ()
Mit eBPF beim Einstecken des USB-Laufwerks wird angezeigt, dass mindestens 48 symbolische Links erstellt wurden.
Was ist also der Sinn der Ereignisdatei? Verwendung disk_add_events ()
, und entweder "media_change"
Oder "eject_request"
können in einer Ereignisdatei aufgezeichnet werden. Hier informiert die Kernel-Blockschicht den Benutzerbereich darüber, dass eine „Festplatte“ aufgetaucht und ausgeworfen wurde. Beachten Sie, wie aufschlussreich diese Recherchemethode durch das Einstecken eines USB-Laufwerks ist, verglichen mit dem Versuch, allein anhand der Quelle herauszufinden, wie die Dinge funktionieren.
Schreibgeschützte Root-Dateisysteme ermöglichen eingebettete Geräte
Natürlich schaltet niemand den Server oder seinen Computer aus, indem er den Stecker aus der Steckdose zieht. Aber warum? Dies liegt daran, dass auf physischen Speichergeräten gemountete Dateisysteme möglicherweise verzögerte Schreibvorgänge aufweisen und die Datenstrukturen, die ihren Status aufzeichnen, möglicherweise nicht mit Schreibvorgängen in den Speicher synchronisiert werden. In diesem Fall müssen Systembesitzer bis zum nächsten Start warten, um das Dienstprogramm zu starten. fsck filesystem-recovery
und im schlimmsten Fall Datenverlust.
Wir alle wissen jedoch, dass auf vielen IoT-Geräten sowie Routern, Thermostaten und Autos mittlerweile Linux läuft. Viele dieser Geräte haben kaum oder gar keine Benutzeroberfläche und es gibt keine Möglichkeit, sie „sauber“ auszuschalten. Stellen Sie sich vor, Sie starten ein Auto mit leerer Batterie, während die Stromversorgung zum Steuergerät ausfällt fsck
Wann springt der Motor endlich an? Und die Antwort ist einfach. Eingebettete Geräte sind auf das Root-Dateisystem angewiesen ro-rootfs
(schreibgeschütztes Root-Dateisystem)).
ro-rootfs
bieten viele Vorteile, die weniger offensichtlich sind als Authentizität. Ein Vorteil besteht darin, dass Malware nicht darauf schreiben kann /usr
oder /lib
, wenn dort kein Linux-Prozess schreiben kann. Ein weiterer Grund ist, dass ein weitgehend unveränderliches Dateisystem für den Feldsupport von Remote-Geräten von entscheidender Bedeutung ist, da das Supportpersonal auf lokale Systeme angewiesen ist, die nominell mit den Feldsystemen identisch sind. Der vielleicht wichtigste (aber auch heimtückischste) Vorteil besteht darin, dass Ro-RootFS Entwickler dazu zwingt, bereits in der Entwurfsphase des Systems zu entscheiden, welche Systemobjekte unveränderlich sein sollen. Die Arbeit mit Ro-RootFS kann umständlich und mühsam sein, da es in Programmiersprachen häufig Konstantenvariablen gibt, aber ihre Vorteile rechtfertigen problemlos den zusätzlichen Aufwand.
Schöpfung rootfs
Nur-Lesen erfordert für Embedded-Entwickler einen gewissen Mehraufwand, und hier kommt VFS ins Spiel. Linux erfordert, dass Dateien vorhanden sind /var
waren beschreibbar, und außerdem versuchen viele beliebte Anwendungen, die eingebettete Systeme ausführen, Konfigurationen zu erstellen dot-files
в $HOME
. Eine Lösung für Konfigurationsdateien im Home-Verzeichnis besteht normalerweise darin, sie vorab zu generieren und darin zu integrieren rootfs
. Für /var
Ein möglicher Ansatz besteht darin, es auf einer separaten beschreibbaren Partition bereitzustellen /
schreibgeschützt gemountet. Eine weitere beliebte Alternative ist die Verwendung von Bind- oder Overlay-Mounts.
Verbindbare und stapelbare Halterungen, ihre Verwendung bei Behältern
Einen Befehl ausführen man mount
ist der beste Weg, etwas über bindbare und überlagerbare Mounts zu lernen, die Entwicklern und Systemadministratoren die Möglichkeit geben, ein Dateisystem in einem Pfad zu erstellen und es dann für Anwendungen in einem anderen Pfad verfügbar zu machen. Für eingebettete Systeme bedeutet dies die Möglichkeit, Dateien darin zu speichern /var
auf einem schreibgeschützten Flash-Laufwerk, aber einem Overlay- oder verknüpfbaren Mount-Pfad von tmpfs
в /var
Beim Laden können Anwendungen dort Notizen schreiben (Gekritzel). Wenn Sie das nächste Mal die Änderungen an aktivieren /var
wird verloren sein. Eine Overlay-Halterung schafft eine Verbindung zwischen tmpfs
und das zugrunde liegende Dateisystem und ermöglicht es Ihnen, scheinbare Änderungen an vorhandenen Dateien in vorzunehmen ro-tootf
wohingegen ein bindbares Reittier neue leer machen kann tmpfs
Ordner, die als beschreibbar sichtbar sind ro-rootfs
Wege. Während overlayfs
das ist das Richtige (proper
) Dateisystemtyp, in dem ein bindbarer Mount implementiert ist
Basierend auf der Beschreibung des Overlays und der verbindbaren Halterung wundert das niemanden mountsnoop
aus bcc
.
Вызов system-nspawn
startet den Container während der Ausführung mountsnoop.py
.
Lass uns nachsehen, was passiert ist:
Starten mountsnoop
während der Container „bootet“, zeigt, dass die Laufzeit des Containers stark vom verknüpften Mount abhängt (nur der Anfang der langen Ausgabe wird angezeigt).
Hier systemd-nspawn
stellt ausgewählte Dateien bereit procfs
и sysfs
vom Host zum Container als Pfade dorthin rootfs
. Außer MS_BIND
Flag, das den Bindungs-Mount einrichtet, definieren einige andere Flags auf dem Mount die Beziehung zwischen Änderungen am Host- und Container-Namespace. Beispielsweise kann ein verknüpfter Mount entweder Änderungen an überspringen /proc
и /sys
in den Container kopieren oder je nach Aufruf ausblenden.
Abschluss
Das Innenleben von Linux zu verstehen, kann wie eine unmögliche Aufgabe erscheinen, da der Kernel selbst eine riesige Menge an Code enthält, abgesehen von Linux-User-Space-Anwendungen und Systemaufrufschnittstellen in C-Bibliotheken wie z glibc
. Eine Möglichkeit, Fortschritte zu erzielen, besteht darin, den Quellcode eines Kernel-Subsystems zu lesen, wobei der Schwerpunkt auf dem Verständnis von Systemaufrufen und User-Space-Headern sowie der wichtigsten internen Kernel-Schnittstellen wie Tabellen liegt file_operations
. Dateioperationen basieren auf dem „Alles ist eine Datei“-Prinzip und sind daher besonders angenehm zu verwalten. C-Kernel-Quelldateien im Verzeichnis der obersten Ebene fs/
stellen eine Implementierung virtueller Dateisysteme vor, bei denen es sich um eine Wrapper-Schicht handelt, die eine breite und relativ einfache Kompatibilität zwischen gängigen Dateisystemen und Speichergeräten bietet. Das Verknüpfen und Overlay-Mounting über Linux-Namespaces ist die Magie von VFS, die die Erstellung schreibgeschützter Container und Root-Dateisysteme ermöglicht. Kombiniert mit einer Untersuchung des Quellcodes, des eBPF-Kerntools und seiner Schnittstelle bcc
Dadurch wird die Kernerkundung einfacher als je zuvor.
Freunde, schreibt, war dieser Artikel für euch nützlich? Vielleicht haben Sie Anmerkungen oder Anmerkungen? Und alle, die sich für den Linux-Administrator-Kurs interessieren, sind herzlich dazu eingeladen
Source: habr.com