Abschluss:

Abschluss:

Auf meinem Arch Linux-System (Linux-Kernel 3.14.2) respektieren Bind-Mounts die Option „Nur lesen“ nicht

# mkdir test
# mount --bind -o ro test/ /mnt
# touch /mnt/foo

erstellt die Datei /mnt/foo. Der entsprechende Eintrag in /proc/mountsist

/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0

Die Mount-Optionen entsprechen nicht meinen gewünschten Optionen, entsprechen aber sowohl dem Lese-/Schreibverhalten des Bind-Mounts als auch den Optionen, die beim ursprünglichen Mounten verwendet wurden /dev/sda2./

/dev/sda2 / ext4 rw,noatime,data=ordered 0 0

Wenn ich das Mount jedoch erneut mounte, wird die Option „Nur lesen“ berücksichtigt.

# mount --bind -o remount,ro test/ /mnt
# touch /mnt/bar
touch: cannot touch ‘/mnt/bar’: Read-only file system

und der entsprechende Eintrag in/proc/mounts/

/dev/sda2 /mnt ext4 ro,relatime,data=ordered 0 0

sieht aus wie erwartet (obwohl ich eigentlich den vollständigen Pfad des testVerzeichnisses erwarten würde). Der Eintrag in /proc/mounts/für die ursprüngliche Einbindung von /dev/sda2/on /ist ebenfalls unverändert und bleibt lesbar/schreibbar.

/dev/sda2 / ext4 rw,noatime,data=ordered 0 0

Dieses Verhalten und der Workaround sind seit mindestens2008und sind dokumentiert in der Manpage vonmount

Beachten Sie, dass die Einhängeoptionen des Dateisystems dieselben bleiben wie die des ursprünglichen Einhängepunkts und nicht durch Übergeben der Option -o zusammen mit --bind/--rbind geändert werden können. Die Einhängeoptionen können durch einen separaten Remount-Befehl geändert werden.

Nicht alle Distributionen verhalten sich gleich. Arch scheint die Optionen stillschweigend nicht zu respektieren, während Debian eine Warnung generiert, wenn der Bind-Mount nicht schreibgeschützt ist.

mount: warning: /mnt seems to be mounted read-write.

Es gibt Berichte, dass dieses Verhalten in Debian "behoben" wurdeLenny und Squeezeobwohl es nicht so aussieht, als ob es einUniversalfixierungnoch funktioniert es in Debian Wheezy. Welche Schwierigkeiten gibt es, wenn man Bind Mount so einstellt, dass die Option „Nur lesen“ beim ersten Mounten berücksichtigt?

Antwort1

Bind Mount ist einfach... nun ja... ein Bind Mount. D. h. es ist kein neues Mount. Es „verknüpft“/„macht verfügbar“/„berücksichtigt“ lediglich ein Unterverzeichnis als neuen Mount-Punkt. Daher kann es die Mount-Parameter nicht ändern. Deshalb gibt es Beschwerden:

# mount /mnt/1/lala /mnt/2 -o bind,ro
mount: warning: /mnt/2 seems to be mounted read-write.

Aber wie gesagt, ein normales Bind-Mount funktioniert:

# mount /mnt/1/lala /mnt/2 -o bind

Und dann funktioniert auch ein Ro-Remount:

# mount /mnt/1/lala /mnt/2 -o bind,remount,ro 

Was jedoch passiert, ist, dass Sie die gesamte Einbindung ändern und nicht nur diese Bind-Einbindung. Wenn Sie einen Blick auf /proc/mounts werfen, werden Sie sehen, dass sowohl die Bind-Einbindung als auch die ursprüngliche Einbindung auf schreibgeschützt geändert werden:

/dev/loop0 /mnt/1 ext2 ro,relatime,errors=continue,user_xattr,acl 0 0
/dev/loop0 /mnt/2 ext2 ro,relatime,errors=continue,user_xattr,acl 0 0

Sie ändern also die ursprüngliche Einbindung in eine schreibgeschützte Einbindung undDannFühren Sie eine Bind-Mount-Operation durch, die natürlich schreibgeschützt ist.

UPDATE 20.07.2016:

Folgendes gilt für 4.5-Kernel, aber nicht für 4.3-Kernel (Das ist falsch. Siehe Update Nr. 2 unten):

Der Kernel verfügt über zwei Flags, die den schreibgeschützten Modus steuern:

  • Das MS_READONLY: Gibt an, ob die Einbindung schreibgeschützt ist
  • Die MNT_READONLY: Angabe, ob der „Benutzer“ es schreibgeschützt haben möchte

Auf einem 4.5-Kernel mount -o bind,rofunktioniert es tatsächlich, wenn Sie Folgendes ausführen. Zum Beispiel Folgendes:

# mkdir /tmp/test
# mkdir /tmp/test/a /tmp/test/b
# mount -t tmpfs none /tmp/test/a
# mkdir /tmp/test/a/d
# mount -o bind,ro /tmp/test/a/d /tmp/test/b

erstellt eine schreibgeschützte Bind-Einbindung von /tmp/test/a/d, /tmp/test/bdie wie folgt angezeigt wird /proc/mounts:

none /tmp/test/a tmpfs rw,relatime 0 0
none /tmp/test/b tmpfs ro,relatime 0 0

Eine detailliertere Ansicht ist in sichtbar /proc/self/mountinfo, die die Benutzeransicht (Namespace) berücksichtigt. Die relevanten Zeilen sind diese:

363 74 0:49 / /tmp/test/a rw,relatime shared:273 - tmpfs none rw
368 74 0:49 /d /tmp/test/b ro,relatime shared:273 - tmpfs none rw

roWobei in der zweiten Zeile, wie Sie sehen können, sowohl ( MNT_READONLY) als auch rw( ) steht !MS_READONLY.

Das Endergebnis ist folgendes:

# echo a > /tmp/test/a/d/f
# echo a > /tmp/test/b/f
-su: /tmp/test/b/f: Read-only file system

UPDATE 2016-07-20 #2:

Ein bisschen mehr Nachforschung zeigt, dass das Verhalten tatsächlich von der Version von libmount abhängt, die Teil von util-linux ist. Unterstützung hierfür wurde mit diesem hinzugefügtbegehenund wurde mit Version 2.27 veröffentlicht:

Commit 9ac77b8a78452eab0612523d27fee52159f5016a
Autor: Karel Zak
Datum: Mo 17. Aug 2015 11:54:26 +0200

    libmount: Unterstützung für „bind,ro“ hinzufügen

    Nun ist es notwendig, zwei mount(8)-Aufrufe zu verwenden, um eine schreibgeschützte
    montieren:

      mount /foo /bar -o binden
      mount /bar -o remount,ro,binden

    Dieser Patch erlaubt die Angabe von "bind,ro" und der erneute Mount ist abgeschlossen
    automatisch von libmount durch zusätzlichen mount(2) Systemaufruf. Es ist nicht
    natürlich atomar.

    Unterzeichnet von: Karel Zak

was auch den Workaround bietet. Das Verhalten kann mit strace auf einem älteren und einem neueren Mount beobachtet werden:

Alt:

mount("/tmp/test/a/d", "/tmp/test/b", 0x222e240, MS_MGC_VAL|MS_RDONLY|MS_BIND, NULL) = 0 <0.000681>

Neu:

mount("/tmp/test/a/d", "/tmp/test/b", 0x1a8ee90, MS_MGC_VAL|MS_RDONLY|MS_BIND, NULL) = 0 <0.011492>
mount("none", "/tmp/test/b", NULL, MS_RDONLY|MS_REMOUNT|MS_BIND, NULL) = 0 <0.006281>

Abschluss:

Um das gewünschte Ergebnis zu erzielen, müssen zwei Befehle ausgeführt werden (wie @Thomas bereits sagte):

mount SRC DST -o bind
mount DST -o remount,ro,bind

Neuere Versionen von mount (util-linux >=2.27) tun dies automatisch, wenn eine

mount SRC DST -o bind,ro

Antwort2

Die richtige Lösung besteht eigentlich darin, es zweimal zu mounten. Auf der Kommandozeile:

mount -t none -o bind /source/dir /destination/dir
mount -t none -o bind,remount,ro /source/dir /destination/dir

In /etc/fstab:

/source/dir            /destination/dir    none  bind            0 0
/source/dir            /destination/dir    none  remount,bind,ro 0 0

Im Handbuch ( man mount) steht es so:

   The bind mounts.
          Since Linux 2.4.0 it is possible to remount part of the file hierarchy somewhere else. The call is
                 mount --bind olddir newdir
   [...]
          Note that the filesystem mount options will remain the same as those on the original mount point, and cannot be changed  by  passing  the  -o  option
          along with --bind/--rbind. The mount options can be changed by a separate remount command, for example:
          .
                 mount --bind olddir newdir
                 mount -o remount,ro newdir
          .
          Note  that  behavior  of  the remount operation depends on the /etc/mtab file. The first command stores the 'bind' flag to the /etc/mtab file and the
          second command reads the flag from the file.  If you have a system without the /etc/mtab file or if you explicitly define source and target  for  the
          remount command (then mount(8) does not read /etc/mtab), then you have to use bind flag (or option) for the remount command too. For example:
          .
                 mount --bind olddir newdir
                 mount -o remount,ro,bind olddir newdir

Antwort3

Sie fragen aus der Perspektive der mount(8)Befehlszeile (was auf dieser Site akzeptabel ist). Dieser Befehl wurde in den anderen Antworten besprochen und abstrahiert in einigen Fällen den erforderlichen zweiten mount(2)Systemaufruf.

Aber warum ist der zweite Systemaufruf erforderlich? Warum kann ein einzelner mount(2)Aufruf nicht die schreibgeschützte Bind-Einbindung erstellen?

Dermount(2)manpageerklärt, dass es, wie andere bereits angemerkt haben,zwei Setsvon Flags, die gesetzt werden:

  • Die zugrunde liegenden Dateisystem-Flags
  • Die VFS-Mount-Point-Flags

Es sagt:

Seit Linux 2.6.16 MS_RDONLYkann es für jeden Einhängepunkt und für das zugrunde liegende Dateisystem festgelegt oder gelöscht werden. Das eingehängte Dateisystem ist nur dann beschreibbar, wenn weder das Dateisystem noch der Einhängepunkt als schreibgeschützt gekennzeichnet sind.

Und bezüglich MS_REMOUNT:

Seit Linux 2.6.26 kann dieses Flag verwendet werden, MS_BINDum nur die Flags pro Einhängepunkt zu ändern. Dies ist insbesondere nützlich, um das Flag „schreibgeschützt“ an einem Einhängepunkt zu setzen oder zu löschen, ohne das zugrunde liegende Dateisystem zu ändern. Einhängeflags werden wie folgt angegeben:

      MS_REMOUNT | MS_BIND | MS_RDONLY

macht den Zugriff über diesen Einhängepunkt schreibgeschützt, ohne andere Einhängepunkte zu beeinflussen.

Ich denke, das Problem entstand, als Bind Mounts erstmals eingeführt wurden:

Wenn mountflags enthält MS_BIND(verfügbar seit Linux 2.4), führen Sie einen Bind-Mount aus. ... Die restlichen Bits im Argument mountflags werden mit Ausnahme von ebenfalls ignoriert MS_REC. (Der Bind-Mount hat dieselben Mount-Optionen wie der zugrunde liegende Mount-Punkt.)

Es scheint, dass sie, anstatt MS_BIND | MS_REMOUNTals Signal nur die VFS-Flags zu setzen, sich dafür hätten entscheiden können, „exception“ (und „accept“) MS_RDONLYzusammen mit dem anfänglichen zu verwenden MS_BINDund es auf den Einhängepunkt anzuwenden.

Aufgrund der etwas seltsamen Semantik des mount(2)Systemaufrufs gilt Folgendes:

  • Der erste Aufruf erstellt den Bind-Mount und alle anderen Flags werden ignoriert
  • Der zweite Aufruf (mit Remount) setzt dieEinhängepunktFlags auf schreibgeschützt

verwandte Informationen