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/mounts
ist
/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 test
Verzeichnisses 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,ro
funktioniert 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/b
die 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
ro
Wobei 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_RDONLY
kann 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_BIND
um 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 ignoriertMS_REC
. (Der Bind-Mount hat dieselben Mount-Optionen wie der zugrunde liegende Mount-Punkt.)
Es scheint, dass sie, anstatt MS_BIND | MS_REMOUNT
als Signal nur die VFS-Flags zu setzen, sich dafür hätten entscheiden können, „exception“ (und „accept“) MS_RDONLY
zusammen mit dem anfänglichen zu verwenden MS_BIND
und 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