마운트가 바인드 마운트에 대한 읽기 전용 옵션을 존중하지 않는 이유는 무엇입니까?


35

내 아치 리눅스 시스템 (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디렉토리 의 전체 경로를 볼 것으로 기대하지만 ). on /proc/mounts/의 orignal 마운트 에 대한 입력 도 변경되지 않으며 읽기 / 쓰기로 유지됩니다./dev/sda2//

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

이 동작과 해결 방법은 2008 년 이후로 알려져 있으며 설명서 페이지에 설명되어 있습니다.mount

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

모든 배포판이 동일하게 작동하는 것은 아닙니다. 바인드 마운트가 읽기 전용 마운트를 얻지 못할 때 데비안이 경고를 생성하는 동안 아치는 옵션을 무시하지 않는 것 같습니다

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

이 문제는 데비안 레니와 스퀴즈 에서 "고정"되었다는보고가 있지만, 일반적인 수정은 아니지만 데비안 위지에서는 여전히 작동하지 않습니다. 초기 마운트에서 바인드 마운트가 읽기 전용 옵션을 존중하도록하는 것과 어려운 점은 무엇입니까?


/ etc / mtab이 있습니까?
eyoung100


@ECarterYoung 그래 /etc/mtab. 초기 마운트 후 항목은 마운트가 rw라고 표시하고 다시 마운트 한 후에는 ro를 표시하므로 마운트 상태를 올바르게보고합니다. 실패한 마운트 명령 일뿐입니다.
StrongBad

3
나는,이 개 데비안 테스트 / 불안정한 시스템에서 하나의 데비안 커널을 실행하고 하나에 kernel.org 커널, 어느 일을 실행 테스트 mount --bind -o ro메시지 출력, 둘 다 침 mount: warning: «mountpoint» seems to be mounted read-write.이 데비안 떨어 뜨리거나 어떤 점에서 패치를 잃은 것 같다 그래서 ... 다시 마운트를 그래도 작동합니다.
derobert

2
@StrongBad 요청에 따라 테스트되었으며 작동하지 않습니다.
derobert

답변:


21

바인드 마운트는 바인드 마운트입니다. 즉, 새로운 마운트가 아닙니다. 하위 디렉토리를 새 마운트 지점으로 "링크"/ "노출"/ "고려"합니다. 따라서 마운트 매개 변수를 변경할 수 없습니다. 이것이 불만을 제기하는 이유입니다.

# 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 remount도 작동합니다.

# 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: 마운트 여부를 표시하는 것은 읽기 전용
  • 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
저자 : Karel Zak 
날짜 : 월요일 8 월 17 일 11:54:26 2015 +0200

    libmount : "bind, ro"에 대한 지원 추가

    이제 두 개의 mount (8) 호출을 사용하여 읽기 전용을 만들 필요가 없습니다.
    산:

      마운트 / foo / bar -o 바인드
      마운트 / bar -o 다시 마운트, ro, 바인드

    이 패치는 "bind, ro"를 지정할 수 있으며 다시 마운트가 완료됩니다
    추가 mount (2) syscall에 의해 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

최신 버전의 mount (util-linux> = 2.27)는 실행시 자동으로이를 수행합니다.

mount SRC DST -o bind,ro

3
예, 아니요 IIRC는 다른 마운트 지점 (파일 시스템이 아닌)이 다른 옵션을 갖도록 커널에서 일부 지원합니다 . 데비안 mount -o bind,ro은 읽기-쓰기 파일 시스템의 읽기 전용보기를 만들 수있는 패치를 가지고 있었습니다.
Gilles 'SO- 악마 중지

이것이 위와 어떻게 모순되는지 모르겠습니다. 해킹은 의미가없는 것을 포함하여 모든 종류의 것을 허용 할 수 있습니다. 현재 3.14 커널의 읽기 전용 다시 마운트는 결국 다음 호출에 의해 처리됩니다. (읽기 전용) 마운트 플래그. 적어도 저의 이해입니다.
V13

따라서 이것은“확산 구조체 마운트”패치 ( 특히이 commit )의 결과로 커널 3.3에서 처음 나타납니다. 이 패치의 결과가 lkml 또는 lwn에서 논의되었는지 알고 있습니까?
Gilles 'SO- 악마 그만해'

7
mount --bind /tmp/ /mnt/tmp/; mount -o remount,bind,ro /mnt/tmp/... 다음 touch /tmp/aOK이지만, touch /mnt/tmp/b제공합니다 touch: cannot touch ‘/mnt/tmp/b’: Read-only file system. 데비안 3.13과 kernel.org 3.14.2에서 모두 작동합니다. 따라서 전체 마운트 만 변경하지는 않습니다. 적어도 최근 커널에서는 그렇지 않습니다.
derobert

1
아마도 "바인드 마운트는 ... 바로 ... 바인드 마운트"라는 진술 일 것입니다. 정말 중요하지만 아무 의미가 없습니다. 또한 왜 마운트 옵션으로 두 번째로 작동하는지 이해하지 못합니다.
StrongBad

9

올바른 해결책은 실제로 두 번 마운트하는 것입니다. 명령 행에서 :

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

이것은 적어도 우분투 14.04 LTS 및 커널 3.19.0-51-low-latency와 함께 작동하는 것 같습니다. 좋은!
Mikko Rantalainen 2016 년

0

mount(8)커맨드 라인 의 관점에서 묻는 것입니다 (이 사이트에서는 허용됩니다). 이 명령은 다른 답변에서 논의되었으며 경우에 따라 필요한 두 번째 mount(2)시스템 호출을 추상화 합니다.

그러나 왜 두 번째 시스템 호출이 필요합니까? 단일 mount(2)호출로 읽기 전용 바인드 마운트를 작성할 수없는 이유는 무엇 입니까?

mount(2)man 페이지는 다른 사람들이 지적으로,이 있다는 것을 설명하고 두 가지 플래그가 세트되는이 :

  • 기본 파일 시스템 플래그
  • 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_REMOUNTVFS 플래그 만 설정하는 신호로 사용 하는 대신 MS_RDONLYinitial과 함께 제외 (및 수락) MS_BIND를 선택하여 마운트 지점에 적용 할 수있는 것으로 보입니다 .

따라서 mount(2)시스템 호출 의 다소 이상한 의미 때문에

  • 첫 번째 호출은 바인드 마운트를 작성하고 다른 모든 플래그는 무시됩니다.
  • 두 번째 호출 (다시 마운트)은 마운트 지점 플래그를 읽기 전용으로 설정합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.