결론:

결론:

내 Arch Linux 시스템(Linux 커널 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). on /proc/mounts/의 원래 마운트에 대한 항목 도 변경되지 않고 읽기/쓰기 상태로 유지됩니다./dev/sda2//

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

이 동작과 해결 방법은 적어도 이후부터 알려져 왔습니다.2008년맨 페이지에 문서화되어 있습니다.mount

파일 시스템 마운트 옵션은 원래 마운트 지점의 옵션과 동일하게 유지되며 --bind/--rbind와 함께 -o 옵션을 전달하여 변경할 수 없습니다. 별도의 remount 명령으로 마운트 옵션을 변경할 수 있습니다.

모든 배포판이 동일하게 동작하는 것은 아닙니다. 바인드 마운트가 읽기 전용 마운트를 얻지 못할 때 데비안이 경고를 생성하는 동안 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-07-20:

다음은 4.5 커널에는 해당되지만 4.3 커널에는 해당되지 않습니다. (이는 잘못된 것입니다. 아래 업데이트 #2를 참조하세요.)

커널에는 읽기 전용을 제어하는 ​​두 가지 플래그가 있습니다.

  • : MS_READONLY마운트가 읽기 전용인지 여부를 나타냅니다.
  • The MNT_READONLY: "사용자"가 읽기 전용을 원하는지 여부를 나타냅니다.

4.5 커널에서는 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/dto 의 읽기 전용 바인드 마운트를 생성합니다 /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

업데이트 2016-07-20 #2:

이에 대해 좀 더 자세히 살펴보면 실제로 동작이 util-linux의 일부인 libmount 버전에 따라 다르다는 것을 알 수 있습니다. 이에 대한 지원이 추가되었습니다.저지르다버전 2.27로 출시되었습니다.

9ac77b8a78452eab0612523d27fee52159f5016a 커밋
저자: 카렐 자크
날짜: 8월 17일 월요일 11:54:26 2015 +0200

    libmount: "bind,ro" 지원 추가

    이제 읽기 전용 데이터베이스를 생성하기 위해 두 개의 mount(8) 호출을 사용할 필요가 없습니다.
    산:

      마운트 /foo /bar -o 바인드
      마운트 /bar -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:

MS_BINDLinux 2.6.26부터 이 플래그는 마운트 지점별 플래그만 수정하는 데 사용할 수 있습니다 . 이는 기본 파일 시스템을 변경하지 않고 마운트 지점에서 "읽기 전용" 플래그를 설정하거나 지우는 데 특히 유용합니다. mountflags를 다음과 같이 지정합니다.

      MS_REMOUNT | MS_BIND | MS_RDONLY

다른 마운트 지점에 영향을 주지 않고 이 마운트 지점을 통해 읽기 전용으로 액세스할 수 있습니다.

바인드 마운트가 처음 도입되었을 때 문제가 발생한 것 같습니다.

mountflags가 포함된 경우 MS_BIND(Linux 2.4부터 사용 가능) 바인드 마운트를 수행합니다. ... 를 제외하고 mountflags 인수의 나머지 비트도 무시됩니다 MS_REC. (바인드 마운트에는 기본 마운트 지점과 동일한 마운트 옵션이 있습니다.)

MS_BIND | MS_REMOUNTVFS 플래그만 설정하기 위한 신호로 사용하는 대신 MS_RDONLY초기 플래그와 함께 제외(및 수락)를 선택 MS_BIND하고 이를 마운트 지점에 적용할 수 있었던 것 같습니다.

mount(2)따라서 시스템 호출 의 다소 이상한 의미로 인해 :

  • 첫 번째 호출은 바인드 마운트를 생성하고 다른 모든 플래그는 무시됩니다.
  • 두 번째 호출(다시 마운트 포함)은마운트 지점읽기 전용 플래그

관련 정보