Mounten Sie das Verzeichnis auf root

7

Ich habe einen Ordner mit bestimmten Dateien. Gibt es eine Möglichkeit, es zu mounten /, damit der Inhalt eines bestimmten Verzeichnisses an den entsprechenden Stellen in /angezeigt wird?

In meinem Fall enthalten die Verzeichnisse die Dateien, die sich auf eine Anwendung beziehen - es gibt keine Verzeichnisse wie /devund /proc.

Ich habe versucht, ein Bind-Mount auf folgende Weise zu erstellen:

mount --bind ~/applications/firefox /

Dies macht jedoch überhaupt nichts. Anders als in den Kommentaren spekuliert, hat es auch keine nachteiligen Auswirkungen.


Die Motivation dafür ist, dass ich eine Reihe von benutzerdefinierten Anwendungen habe, die ich sauber auf geschäftskritischen Systemen installieren möchte. Verständlicherweise möchte ich das zugehörige Management auf ein Minimum beschränken. Ich erhalte das Dateisystemlayout der Anwendungsinstallation mit einer unionfs-fuse + chroot-Methode , muss mich dann aber noch mit dem Problem befassen, dass sich die Anwendungsdateien mit denen des Systems vermischen. Das Mounten bestimmter Verzeichnisse /würde mir helfen, das Dateisystem sauber zu halten.

Während diese Methode zur Installation von Software pervers erscheint, gibt es eine Distribution namens "Porteus", die Software genau auf diese Weise installiert (und aus den gleichen Gründen). Es ist jedoch bekannt, dass sie zusammen mit aufs einen gepatchten Kernel verwenden. Ich kann jedoch keinen benutzerdefinierten Kernel auf den Systemen verwenden.

user2064000
quelle
1
Sofern ~ / application nicht über ein vollständiges Betriebssystem verfügt (einschließlich / dev und aller), kann diese Art von Mount Ihr System wahrscheinlich zum Absturz bringen / hängen lassen. Ich nehme an, Sie haben versucht, dieses Mount als Root zu verwenden.
Archemar
1
Sagen Sie uns, was Sie wirklich erreichen wollen - vielleicht gibt es andere Möglichkeiten.
Guntbert
@guntbert, ich habe eine Erklärung entsprechend Ihrer Anfrage hinzugefügt.
user2064000
Suche nach dem overlay filezystem.
ott--

Antworten:

3

Was Sie tun möchten, wird mindestens einmal auf nahezu jedem allgemein konfigurierten Linux-System ausgeführt. Die meisten verwenden das Tool, das von busyboxaufgerufen wird switch_root:

Was switch_roottut , ist alle Dateien aus löscht rootfs (um den Speicher freizugeben) und dann chrootin ein neues Dateisystem und exec einen neuen Init - Prozess aus dem neuen Dateisystem.

Dies geschieht während der Systeminitialisierung. Wenn ein Linux-System gestartet wird, bringt der Kernel das System schrittweise hoch. Zuerst wird der Kernel von einem anderen System - wie einem Bootloader oder der Firmware - im Speicher ausgeführt, und an diesem Punkt bleibt der Kernel nur für sich selbst - ohne wirklichen Bezugsrahmen für das System, auf dem er sich befindet es wurde gerade ausgeführt.

Dies ist das, wofür das initramfsImage normalerweise an seinen Speicherplatz angehängt wird (aber möglicherweise auch direkt in den Kernel kompiliert wird) . Die initramfs ist ein echter Linux - Root (komplett w / /devund /procund was-habe-Sie) Dateisystem - Image - es ist das erste Root - Dateisystem jemals von einem Linux - Kernel montiert. Es enthält ein Root-Dateisystemarchiv, das alle systemspezifischen Module / Konfigurationsdateien enthält, die erforderlich sind, um den Kernel auf die Beine zu stellen - um ihn zu booten.

Wie auch immer, der Kernel stellt das Archiv als rootfs bereit (im Grunde genommen ein tmpfs ) und unternimmt dann alles Notwendige, um einen anderen/ zu finden und diesen darüber zu mounten. Dies geschieht jedes Mal, wenn Sie Ihr System starten. Es kann es wieder tun, ohne auf unnötige Hacks wie unionfs oder aufs zurückgreifen zu müssen - beides führt wahrscheinlich zu allen Arten von implementierungsspezifischen Komplikationen und Konfigurationsdetails (ganz zu schweigen von Instabilität) .

In der oben zitierten switch_rootBeschreibung werden Sie wahrscheinlich feststellen, dass der Ausdruck alle Dateien aus rootfs löscht . Offensichtlich wäre dies kein wünschenswertes Verhalten beim Wechsel von einem festplattenbasierten Rootfs. Dies geschieht jedoch nur so, wenn switch_rootder Speicher für das RAM-basierte Dateisystem freigegeben wird - und dies ist völlig unnötig. Hier noch etwas aus dem zuvor zitierten Artikel:

Das folgende Shell-Skriptfragment zeigt, wie switch_root verwendet wird:

   # First, find and mount the new filesystem.

   mkdir /newroot
   mount /dev/whatever /newroot

   # Unmount everything else you've attached to rootfs.  (Moving the filesystems
   # into newroot is something useful to do with them.)

   mount --move /sys /newroot/sys
   mount --move /proc /newroot/proc
   mount --move /dev /newroot/dev

   # Now switch to the new filesystem, and run /sbin/init out of it.  Don't
   # forget the "exec" here, because you want the new init program to inherit
   # PID 1.

   exec switch_root /newroot /sbin/init

Wie Sie oben sehen können, die Handhabung der /dev, /procund die /sysdamit verbundenen Probleme lassen sich sehr einfach erreicht. Wenn Sie eine der mount --moved-Halterungen überlagern würden, müssten Sie sich übrigens nicht nur mit mtabund mountauch mit allen anderen Komplikationen befassen, die Ihr Schichtsystem mit sich bringt. Es ist einfacher, genau so vorzugehen, wie Sie es in der Frage beschrieben haben - hängen Sie root von einem anderen Ort aus ein.

Sie müssen im Grunde alles tun, was in einer typischen Initramfs-Konfiguration passiert, und sehr wenig anderes - (was nicht dazu gedacht ist, Debian- oder Redhats Initramfs-Images zu enthalten - beide sind weit überentwickelt) . Das einzige wirkliche Problem, auf das Sie stoßen könnten, ist, wie Sie PID1 dazu bringen, diesem Beispiel zu folgen. Wenn Sie den Init Ihres Systems auf verwaisten Rootfs festsitzen lassen, kann es bald zu sehr seltsamen Dingen auf Ihrem System kommen. Der naheliegende Weg, dies zu handhaben, besteht darin, sich ab initramfs vorzubereiten. Stellen Sie einfach sicher, dass der initProzess Ihrer Festplatte execspäter auf einen anderen vorbereitet wird, wenn Sie die Roots wechseln möchten. Wenn Sie eine verwenden, systemd initwird diese Komplikation bereits für Sie behandelt:

systemctl --help
...
switch-root ROOT [INIT]         Change to a different root file system
...

Wenn Sie eine systemd-basierte verwenden init, sollten Sie die Einheitendateien untersuchen /usr/lib/systemd/system/initrd*, um eine Vorstellung davon zu erhalten, wie die häufig geskriptete systemdSwitch-Root-Situation im Stil eines Skripts aussieht.

Ein anderer Weg zu gehen , um es zu imitieren sein könnte busybox‚s switch_rootin initramfs - aber das Teil zu verlassen, wo Sie alle anfänglichen root Dateien löschen. Arch Linux-Systeme, die mit systemdin initramfs konfiguriert wurden, tun dies. Auf diesen stellt sich das initramfs-Stammverzeichnis vor dem Ausführen des Switch-Stammverzeichnisses in /newroot's ein /run/initramfsund ist das, worauf das System beim Herunterfahren zurückgreift, um Sleep / Suspend und ähnliches sauber zu handhaben. Das ist vielleicht der beste Weg für Ihren Fall - nur ein winziges, ram-beständiges Root-System, von dem Sie für Ihre verschiedenen individuell verwurzelten Anwendungen Ping-Pong-fähig sind.

mikeserv
quelle
2

Versuchen Sie nicht, überzusteigen /, sondern machen Sie sich zu einem "neuen" (gefälschten, schreibgeschützten):

Ich habe etwas ähnliches gemacht. Zu der Zeit habe ich AUFS verwendet, aber dies sollte auch mit Overlays und / oder Unionfs-Fuse funktionieren:

  • einen Ordner erstellen (zB) ~/apps/_App1_FakeRoot
  • Unionfs Mount /(Root) schreibgeschützt unter ~/apps/_App1Lese- / Schreibzugriff auf Mountpoint ~ / apps / _App1_FakeRoot.
  • Chroot in den FakeRoot, starte deine App.

In meinem speziellen Fall hatte ich so etwas wie das oben Genannte verwendet, um mehrere Ebenen zu vereinheitlichen, einschließlich einer (RAM-) Festplatte für (temporäre) Schreibvorgänge.

Die spezifische Syntax hängt von der Implementierung eines Unioning-FS ab, den Sie verwenden können. Je nachdem, was Ihre App benötigt, müssen Sie möglicherweise auch ein anderes / proc / sys / dev / pts in die Chroot einbinden. Es ist auch möglich, dass einige Arten von Programmen einfach nicht in einer solchen Chroot ausgeführt werden, vielleicht wenn sie Dinge auf Hardware-Ebene tun wollen

(Wenn Ihre spezielle unionfs-Implementierung / nicht als schreibgeschützte Basis verwenden möchte, können Sie dies umgehen, indem Sie sich zuerst schreibgeschützt ein "Root-Dateisystem" einbinden, das Sie als Basis für Ihre Apps verwenden können.)

Alex Stragies
quelle
0

mount --bind ~/applications/firefox /würde Schatten die gesamte Verzeichnisstruktur, einschließlich /dev, /procund so weiter. Es würde alles, was beschattet ist, unzugänglich machen. Es funktioniert nicht, weil Sie kein Verzeichnis binden können, in dem es sich selbst beschatten würde.

Sie möchten das, was sich bereits in Ihrem Verzeichnisbaum befindet, mit einem anderen Verzeichnisbaum mischen . Dies wird als Union Mount bezeichnet . Für Linux stehen mehrere Union-Dateisysteme zur Verfügung. aufs ist in nicht alten Kernen vorhanden; unionfs-fuse ist überall dort verfügbar, wo sich FUSE befindet. Aufs unterstützt das Stammverzeichnis als Mountpunkt, aber Unionfs-Fuse. Für Ihren Anwendungsfall /usrsollte eine Anschlusshalterung ausreichend sein.

Gilles 'SO - hör auf böse zu sein'
quelle
1
aufsunterstützt /als Einhängepunkt. Es gibt fsprotect , das dies tut, und ich denke, dass viele Live-Linux-Distributionen es verwenden, um persistente Daten über ein unveränderliches Root-Dateisystem auf schreibgeschützten Medien zu überlagern. Die Gymnastik, die Sie durchlaufen müssen, um ein aufsRoot-Dateisystem zu erhalten, wird natürlich am besten in frühen Boot-Skripten ausgeführt, normalerweise in den initramfs.
Celada
"Es funktioniert nicht, weil Sie ein Verzeichnis nicht binden können, in dem es sich selbst beschatten würde" - falsch. unshare -rm, mount --bind /tmp /Erfolgreich ist . Wie tut unshare -rm, mount --bind /usr/lib /usr.
Sourcejedi