내 Arch Linux 시스템(Linux Kernel 3.14.2)에서 바인드 마운트가 읽기 전용 옵션을 따르지 않습니다.
# mkdir test
# mount --bind -o ro test/ /mnt
# touch /mnt/foo
생성 파일 /mnt/foo
의 관련 항목은 /proc/mounts
.
/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0
마운트 옵션이 요청한 옵션과 일치하지 않지만 바인드 마운트의 읽기/쓰기 동작 및 초기 /dev/sda2
마운트 시 사용된 옵션과 일치합니다./
/dev/sda2 / ext4 rw,noatime,data=ordered 0 0
하지만 설치를 다시 설치하면 읽기 전용 옵션이 적용됩니다.
# mount --bind -o remount,ro test/ /mnt
# touch /mnt/bar
touch: cannot touch ‘/mnt/bar’: Read-only file system
그리고 관련 아이템/proc/mounts/
/dev/sda2 /mnt ext4 ro,relatime,data=ordered 0 0
test
제가 예상했던 것과 같습니다(비록 실제로는 디렉토리의 전체 경로를 보고 싶습니다 ). 원래 마운트 에 대한 항목 /proc/mounts/
도 변경되지 않고 읽기/쓰기 상태로 유지됩니다./dev/sda2/
/
/dev/sda2 / ext4 rw,noatime,data=ordered 0 0
이 동작과 해결 방법은 적어도 이후부터 알려져 왔습니다.2008년매뉴얼 페이지에 문서화되어 있습니다.mount
파일 시스템 마운트 옵션은 원래 마운트 지점의 옵션과 동일하게 유지되며 --bind/--rbind와 함께 -o 옵션을 전달하여 변경할 수 없습니다. 별도의 재설치 명령을 통해 설치 옵션을 변경할 수 있습니다.
모든 배포판이 동일하게 동작하는 것은 아닙니다. Arch는 이러한 옵션을 조용히 무시하는 것처럼 보이지만 데비안은 바인드 마운트가 읽기 전용 마운트를 얻지 못할 때 경고를 생성합니다.
mount: warning: /mnt seems to be mounted read-write.
데비안에서는 이 동작이 "수정"되었다는 보고가 있습니다.레니와 스퀴즈별거 아닌 것 같으면서도보편적인 수정Debian Wheezy에서도 작동하지 않습니다. 초기 설치 시 읽기 전용 옵션을 고려하여 바인드 설치를 수행할 때 어려운 점은 무엇입니까?
답변1
바인드 마운트는 그냥... 음... 바인드 마운트입니다. 즉, 이것은 새로운 마운트가 아닙니다. 단지 하위 디렉터리를 새 마운트 지점으로 "링크"/"노출"/"고려"할 뿐입니다. 따라서 설치 매개변수를 변경할 수 없습니다. 불만사항이 접수되는 이유는 다음과 같습니다.
# mount /mnt/1/lala /mnt/2 -o bind,ro
mount: warning: /mnt/2 seems to be mounted read-write.
그러나 당신이 말했듯이 일반적인 바인드 마운트가 작동합니다.
# mount /mnt/1/lala /mnt/2 -o bind
그런 다음 ro 재설치도 작동합니다.
# mount /mnt/1/lala /mnt/2 -o bind,remount,ro
그러나 현실은 이 바인드 마운트뿐만 아니라 전체 마운트를 변경하는 것입니다. /proc/mounts를 보면 바인드 마운트와 원시 마운트가 모두 읽기 전용이 된 것을 볼 수 있습니다.
/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
그래서 당신이 하는 일은 초기 설치를 읽기 전용 설치로 변경하는 것과 같습니다.그 다음에물론 읽기 전용인 바인드 마운트를 만듭니다.
2016년 7월 20일에 업데이트됨:
다음은 4.5 커널에서는 작동하지만 4.3 커널에서는 작동하지 않습니다(잘못되었습니다. 아래 업데이트 #2 참조).
커널에는 읽기 전용을 제어하는 두 가지 플래그가 있습니다.
- :
MS_READONLY
마운트가 읽기 전용인지 여부를 나타냅니다. - :
MNT_READONLY
"사용자"가 읽기 전용을 원하는지 여부를 나타냅니다.
4.5 커널에서는 a를 실행하는 것이 mount -o bind,ro
실제로 효과가 있습니다. 예를 들면 다음과 같습니다.
# 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
/tmp/test/a/d
to 의 읽기 전용 바인드 마운트가 생성되며 /tmp/test/b
다음 형식으로 표시됩니다 /proc/mounts
.
none /tmp/test/a tmpfs rw,relatime 0 0
none /tmp/test/b tmpfs ro,relatime 0 0
/proc/self/mountinfo
사용자 보기(네임스페이스)를 고려한 보다 자세한 보기는 에서 볼 수 있습니다 . 관련 라인은 다음과 같습니다.
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
두 번째 줄을 보면 ( MNT_READONLY
)와 rw
( ) 가 모두 표시된 것을 확인할 수 있습니다 !MS_READONLY
.
최종 결과는 다음과 같습니다.
# echo a > /tmp/test/a/d/f
# echo a > /tmp/test/b/f
-su: /tmp/test/b/f: Read-only file system
업데이트 #2(2016년 7월 20일):
더 자세히 조사해 보면 이 동작이 실제로 util-linux의 일부인 libmount 버전에 따라 달라지는 것으로 나타났습니다. 이에 대한 지원이 추가되었습니다.범죄버전 2.27로 출시되었습니다.
9ac77b8a78452eab0612523d27fee52159f5016a 제출 저자: 카렐 주커 날짜: 2015년 8월 17일 월요일 11:54:26 +0200 libmount: "bind,ro" 지원 추가 이제 읽기 전용 데이터베이스를 생성하려면 두 개의 mount(8) 호출을 사용해야 합니다. 산: 마운트 /foo /bar -o 바인드 설치/바 -o 재설치,ro,바인드 이 패치를 사용하면 "bind,ro"를 지정하고 다시 마운트할 수 있습니다. 추가 mount(2) 시스템 호출을 통해 libmount를 통해 자동으로 수행됩니다. 그렇지 않다 물론 원자적입니다. 서명자: Karel Zak
이는 해결 방법도 제공합니다. 이전 및 최신 설치에서 strace를 사용하여 이 동작을 확인할 수 있습니다.
오래된:
mount("/tmp/test/a/d", "/tmp/test/b", 0x222e240, MS_MGC_VAL|MS_RDONLY|MS_BIND, NULL) = 0 <0.000681>
새로운:
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>
결론적으로:
원하는 결과를 얻으려면 두 가지 명령을 실행해야 합니다(@Thomas가 이미 말했듯이).
mount SRC DST -o bind
mount DST -o remount,ro,bind
최신 버전의 마운트(util-linux >=2.27)는 런타임 시 자동으로 이 작업을 수행합니다.
mount SRC DST -o bind,ro
답변2
올바른 해결책은 실제로 두 번 설치하는 것입니다. 명령줄에서:
mount -t none -o bind /source/dir /destination/dir
mount -t none -o bind,remount,ro /source/dir /destination/dir
존재하다 /etc/fstab
:
/source/dir /destination/dir none bind 0 0
/source/dir /destination/dir none remount,bind,ro 0 0
매뉴얼( man mount
)에는 다음과 같이 설명되어 있습니다.
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
답변3
명령줄 관점에서 요청하고 있습니다 mount(8)
(이 사이트에서는 허용됩니다). 이 명령은 다른 답변에서 논의되었으며 경우에 따라 필요한 두 번째 mount(2)
시스템 호출을 추상화합니다.
그런데 두 번째 시스템 호출이 필요한 이유는 무엇입니까? 단일 호출로 mount(2)
읽기 전용 바인드 마운트가 생성되지 않는 이유는 무엇입니까?
이것mount(2)
매뉴얼 페이지다른 사람들이 지적했듯이 설명했습니다.두 세트설정되는 플래그 수:
- 기본 파일 시스템 플래그
- VFS 마운트 지점 플래그
그것은 말한다:
Linux 2.6.16부터
MS_RDONLY
이는 기본 파일 시스템뿐만 아니라 마운트 지점별로 설정하거나 지울 수 있습니다. 마운트된 파일 시스템은 파일 시스템이나 마운트 지점이 모두 읽기 전용으로 표시되지 않은 경우에만 쓰기 가능합니다.
에 대한 MS_REMOUNT
:
Linux 2.6.26부터 이 플래그는
MS_BIND
마운트 지점별 플래그만 수정하는 데 사용할 수 있습니다. 이는 기본 파일 시스템을 변경하지 않고 마운트 지점에서 "읽기 전용" 플래그를 설정하거나 지우는 데 특히 유용합니다. mountflags를 다음과 같이 지정하십시오.MS_REMOUNT | MS_BIND | MS_RDONLY
다른 마운트 지점에 영향을 주지 않고 이 마운트 지점을 통해 읽기 전용으로 액세스할 수 있습니다.
바인드 마운트가 처음 도입되었을 때 문제가 발생한 것 같습니다.
mountflags
MS_BIND
(Linux 2.4부터 사용 가능)가 포함되면 바인드 마운트가 수행됩니다. ...mountflags 매개변수의 나머지 비트도 무시됩니다MS_REC
. (바인드 마운트에는 기본 마운트 지점과 동일한 마운트 옵션이 있습니다.)
MS_BIND | MS_REMOUNT
VFS 플래그를 설정하기 위한 신호로 사용하는 대신 초기 값을 제외(및 허용)하고 이를 마운트 지점에 적용하도록 선택할 수 있는 것으로 보입니다 .MS_RDONLY
MS_BIND
mount(2)
시스템 호출의 의미가 약간 이상하기 때문입니다 .
- 첫 번째 호출은 바인드 마운트를 생성하고 다른 모든 플래그는 무시됩니다.
- 두 번째 통화(재설치) 설정마운트 포인트읽기 전용으로 표시