기존 디렉토리에서 마운트가 발생하는 이유는 무엇입니까?


52

마운트 지점 으로 기존 디렉토리가 필요 합니다 .

$ ls
$ sudo mount /dev/sdb2 ./datadisk
mount: mount point ./datadisk does not exist
$ mkdir datadisk
$ sudo mount /dev/sdb2 ./datadisk
$

디렉토리의 기존 내용을 오버레이하기 때문에 혼란 스럽습니다. 마운트 포인트 디렉토리에는 예상치 않게 전환 될 수있는 두 가지 가능한 컨텐츠가 있습니다 (마운트를 수행하지 않는 사용자의 경우).

mount새로 작성된 디렉토리에 발생 하지 않는 이유는 무엇 입니까? 그래픽 운영 체제가 이동식 매체를 표시하는 방법입니다. 디렉토리가 마운트 (존재)되어 있는지 또는 마운트되지 않은지 (존재하지 않는지) 분명합니다. 나는 정당한 이유가 있다고 확신하지만 아직 그것을 발견하지 못했습니다.


1
해당 동작을 원하면을 사용하십시오 udisksctl. 왜 사용 mount합니까?
muru December

1
그것이 유닉스의 방식이기 때문입니다. 이 방법은 더 유연하므로 언제 어디서나 마운트 할 수 있습니다. 예를 들어, 데이터베이스 파티션에 새 디스크를 가져오고 DB 파티션의 데이터를 새 디스크로 이동 한 후 올바른 위치에 마운트하여 DB 데이터를 허용하는 등 필요한 곳에 서버를 마운트 할 수 있기 때문에 더 성장하기 위해.
Rui F Ribeiro

8
역사적으로 Windows와 LInux가 다른 모든 OS를 분쇄하기 전에 Apollo라는 회사가있었습니다. 그들은 유닉스와 비슷한 (유닉스보다 더 나은 디자인) 운영 체제를 썼습니다. NFS 내보내기가 자동으로 마운트되는 디렉토리를 작성했습니다. 실제로 기존 디렉토리에 마운트 할 수 없습니다. HP는 Apollo를 구입하고 운영 체제를 버리고 Apollo의 64 비트 CPU를 HP-PA로 사용했습니다. Apollo의 원격 프로 시저 호출 시스템은 OSF의 DCE가되었으며 이는 Windows 내부에 존재합니다. 아는 것은 반전입니다!
Bruce Ediger

어떻게 든 이것은 내 우분투 14.04,3 ​​시스템에서 발생합니다. 아직 조사하지 않았습니다. 내 SD 카드가 마운트되면 아래에 아무것도없는 경로로 끝납니다. 마운트를 해제하고 수동으로 다시 마운트하려고하면 마운트 지점에 디렉토리가 없다는 오류가 발생합니다.
Skaperen

2
@BruceEdiger better design than Unix![인용 필요]
Ruslan

답변:


51

유출 된 구현 세부 사항의 경우입니다.

UNIX 시스템에서 모든 디렉토리는 inode 번호에 맵핑 된 이름 목록으로 구성됩니다 . inode는 파일, 디렉토리, 특수 장치, 명명 된 파이프 등인지 시스템에 알려주는 메타 데이터를 보유합니다. 파일이나 디렉토리 인 경우 시스템에서 디스크에서 파일 또는 디렉토리 내용을 찾을 위치를 알려줍니다. 대부분의 inode는 파일 또는 디렉토리입니다. inode 번호를 나열 하는 -i옵션 ls입니다.

파일 시스템을 마운트하면 디렉토리 inode가 필요하고 커널의 메모리 내 복사본에 플래그를 설정하여 "실제로이 디렉토리의 내용을 찾을 때이 다른 파일 시스템을 대신보십시오"라고 표시합니다 ( 이 프레젠테이션의 슬라이드 10 참조 ). 단일 데이터 항목을 변경하기 때문에 비교적 쉽습니다.

왜 새 inode를 가리키는 디렉토리 항목을 작성하지 않습니까? 이를 구현할 수있는 두 가지 방법이 있는데 둘 다 단점이 있습니다. 하나는 물리적으로 파일 시스템에 새 디렉토리를 작성하는 것입니다. 그러나 파일 시스템이 읽기 전용이면 실패합니다! 다른 하나는 모든 디렉토리 목록 프로세스에 실제로 존재하지 않는 "추가"항목의 목록을 추가하는 것입니다. 이것은 어리 석고 잠재적으로 모든 파일 작업에서 약간의 성능 저하를 일으킬 수 있습니다.

동적으로 작성된 마운트 지점을 원하면 automount시스템이이를 수행 할 수 있습니다. 디스크 이외의 특수 파일 시스템은 원하는대로 디렉토리를 만들 수도 있습니다 (예 : proc, sys등) devfs.

편집 : 내용이 있는 기존 폴더를 '마운트하면 어떻게됩니까?'에 대한 답변도 참조하십시오 .


inode에 플래그를 설정하지 않는 한. sudo mount --bind / /mnt ; ls /mnt/proc-> 비어 있습니다. 어떻게 작동하는지 궁금합니다.
sourcejedi

정확한 작업은입니다 fs/namespace.c. 나는 소스에 익숙하지 않고 디테일까지 드릴링하는 데 너무 오래 걸리고 싶지 않았습니다. 링크 된 프레젠테이션에서 얻은 "아이 노드의 깃발".
pjc50

2
@sourcejedi : 바인드 마운트는 실제로 참조하는 파일 시스템 만 바인드합니다. 그것들은 그 아래에 마운트 된 다른 파일 시스템을 재귀 적으로 바인딩하지 않습니다. 마운트에 의해 숨겨진 정크를 찾는 편리한 방법입니다. (예 : 마운트에 실패 /var/cache했을 때 루트 FS에 일부 /var내용이있는 경우) 참조하십시오 path_resolution(7). (이전의 linux-manpages는 die.net과 같은 섹션 2의 해당 man 페이지를 가졌습니다.) IDK는 모든 디렉토리 구성 요소를 가능한 마운트로 검사하는 것을 최적화하기 위해 Linux가 실제로 내부적으로 작동하는 방식을 나타냅니다. VFS 항목을 캐시에 고정시킬 수 있습니까?
Peter Cordes

2
맞아, 그건 내 요점 ... 그래서 fs/namei.c(경로-> inode 조회)는 namespace.c를 호출합니다 lookup_mnt(). dentry (디렉토리 캐시 항목)에 플래그가 있습니다. 그러나 그것은 단지 최적화 일명 구현 세부 사항입니다. 어떤 파일 시스템이 마운트되어 있는지 알려주지 않습니다 . 마운트 테이블을 살펴 봐야합니다. (자세한 구현에 대한 자세한 내용은 m_hash ()를 참조하십시오. Linux는 최소한 추가 문자열 비교를 피하고 AFAICS는 마법사가 작성하기 때문에 예를 들어 바인드 마운트에서 dentry를 재사용 할 수 있습니다).
sourcejedi

1
@PeterCordes : man 8 mount: mount --bind foo foo. 바인드 mount호출은 단일 파일 시스템 만 (일부) 연결하며 가능한 서브 마운트는 연결하지 않습니다. 서브 마운트를 포함한 전체 파일 계층 구조는 다음 을 사용하여 두 번째로 첨부됩니다 .mount --rbind olddir newdir
mikeserv

19

마운트 지점이되도록 새 디렉토리를 작성 mount(2) 해야하는 경우 읽기 전용 파일 시스템에서 어떤 것도 마운트 할 수 없습니다. 그것은 멍청 할 것이므로 우리는 그것을 배제 할 수 있습니다.

mount 가 마운트 지점이 될 새 디렉토리를 선택적으로 생성 한 경우 이상합니다. 마운트 / 마운트 해제가 항상 발생하는 것은 아니므로 단일 시스템 호출로이 두 단계를 수행하기 위해 커널에 추가 논리를 추가하는 것은 중요한 속도 향상이 아닙니다. mkdir(2)원하는 경우 시스템 호출 을하려면 사용자 공간에 그대로 두십시오 . Dmitry의 답변 mount(2)은 두 가지를 모두 수행하면 원자가 아닌 것으로 만듭니다. 그리고 당신에게 여분의 인수 싶어 mount(2)모드 플래그가 좋아 함께이 open(2)들어, 소요 O_CREAT, O_EXCL등 그냥 사용자 공간을시키는에 비해 어리석은 것 그것을 할.

아니면 mount(8)( mount(2)시스템 호출 을하는 전통적인 프로그램 )이 이것을 하는 것에 대해 질문 했습니까? 가능할 수도 있지만 이미 mkdir(1)작업에 완벽하게 적합 하며 Unix의 디자인은 결합 가능한 훌륭한 작은 도구에 관한 것입니다. 두 가지를 모두 수행하는 도구를 원한다면 간단한 두 가지 도구로 해당 도구를 빌드하는 셸 스크립트를 쉽게 작성할 수 있습니다. 또는 muru가 udisksctl이미 언급 했듯이이 작업을 수행 할 필요가 없으므로 쓸 필요가 없습니다. 또한 mount(8)util-linux 의 일반적인 Linux 는 옵션이 파일 시스템에 전달되는 옵션이 아니라 사용자 공간 옵션에 대한 구문 mount -o x-mount.mkdir[=mode]사용을 지원합니다 x-.


더 흥미로운 질문 : 왜 부모 파일 시스템에 디렉토리가 있어야 하는가?

pjc50의 답변이 지적한 것처럼 (내 이니셜이 있지만 관계 없음) 디렉토리 목록에 마운트 포인트가 표시되면 모든 추가 검사가 필요합니다 readdir().

마운트 지점을 포함하는 디렉토리 (부모 FS)에 디렉토리로 존재하는 것은 좋은 방법입니다. readdir()마운트 지점이라는 것을 전혀 알 필요가 없습니다. 마운트 지점이 경로 구성 요소로 사용되는 경우 에만 발생 합니다 . 물론 경로 확인은 경로의 모든 디렉토리 구성 요소에 대한 마운트 테이블을 확인해야합니다.


1
If mount(2) required the creation of a new directory to be the mount point, you couldn't mount anything under a read-only filesystem. That would be dumb-더 똑똑하다고 주장합니다 : 사용자 관점에서 읽기 전용 파일 시스템은 변경되지 않아야하지만 마운트를 허용하면 가능합니다
Izkata

2
@Izkata : 파일 시스템을 읽기 전용으로 만든다고해서 VFS의 전체 하위 트리가 정지 된 것은 아닙니다. 읽기-쓰기 디렉토리를 가리키는 심볼릭 링크가 있거나 상위 fs가 다시 마운트 될 때 이미 그 아래에 읽기 / 쓰기 마운트 지점이있을 수 ro있습니다. 인수가 의미가없는 읽기 전용 파일 시스템에 대한 많은 사용 사례가 있습니다.
Peter Cordes

2
man 8 mount: x-mount.mkdir[=mode] 대상 디렉토리 (마운트 포인트)를 만들 수 있습니다. 선택적 인수 모드 mkdir(2)는 8 진법으로 사용되는 파일 시스템 액세스 모드를 지정합니다 . 기본 모드는 0755입니다.이 기능은 루트 사용자에게만 지원됩니다.
mikeserv

읽기-쓰기 파일 시스템이 마운트 된 읽기 전용 파일 시스템, 특히 초기 유닉스에서는 그렇지 않은 읽기 전용 파일 시스템의 중요한 사용 사례가 없습니다. @PeterCordes
kubanczyk

@kubanczyk : 읽기 전용 읽기 - 쓰기와 루트 파일 시스템, /tmp/home. 또는 /usr로컬에 /usr/local마운트 된 읽기 전용 NFS 마운트 . 또는보다 일반적으로 수정 가능한 부분이 마운트 된 공유 읽기 전용 이미지. (읽기 전용 이미지에 대한 로컬 수정은 오버레이 CD 또는 Linux 용 기타 통합 파일 시스템과 같은 사용자 정의 파일 시스템 ( LiveCD 부팅 가능 이미지에 사용)을 사용하여 파일 단위로 수행 할 수도 있습니다 .) 처음에는 루트 FS가 처음에 RO에 마운트 된 것을 생각하고있었습니다. 부팅하지만 다른 마운트 전에 발생할 수 있습니다.
Peter Cordes

12

기존 디렉토리에 마운트하면 mount실질적으로 원 자성을 호출합니다 . 최소한 사용자의 관점에서 볼 때 성공하거나 실패합니다. 경우 mount마운트 지점 자체를 만들 수 있었다, 그것이 불가능 다시 깨끗한 롤을 보장하고, 실패의 두 점을 가질 것이다. 다음 시나리오를 상상해보십시오.

  1. mount 탑재 지점을 성공적으로 만듭니다.
  2. mount 새 파일 시스템을 해당 디렉토리에 마운트하려고 시도하지만 실패
  3. mount 마운트 포인트를 제거하려고하지만 실패

시스템은 고장의 부작용으로 끝납니다 mount.

다른 하나는 다음과 같습니다.

  1. umount 파일 시스템을 성공적으로 마운트 해제합니다
  2. umount 마운트 포인트를 제거하려고하지만 실패

이제 umount성공 또는 실패를 반환 해야 합니까?


5
mount결합 할 수있는 오류에 대한 8 가지 리턴 코드가 있습니다. 디렉토리 제거에 실패하면 다른 것을 추가 할 수 있습니다. man7.org/linux/man-pages/man8/mount.8.html#RETURN_CODES
혼돈

8
OP가 마운트 포인트가 기존 디렉토리가 아닌 이유를 묻고 mount시스템 호출이 생성 하지 않는 이유를 묻습니다 . 어쩌면 그것은 OP가 요구한다고 생각한 것, 또는 내가 묻고 있는지 물었던 것에 대한 나의 해석 / 기대 일뿐입니다.
Peter Cordes

3

발생할 수있는 또 다른 경우 :

부팅 할 때 기본 읽기 전용 이미지는 루트 디렉토리에로드됩니다. 따라서 실제 루트를 고치려고 할 때 재정의하고 싶습니다. 마운트 syscall이 ro마운트 포인트를로 바꾼다고 상상할 수 있습니다 rw.

여기서 루트 마운트 포인트에 파일 시스템 문제가 있다고 가정하고 복구하려고합니다. 마운트 오버랩을 사용하면 파일 시스템을 마운트 해제하고 fsck제공된 기본 이미지를 사용하여 파일 시스템 을 해결할 수 있습니다.

이 기능은 ro파티션과 파티션 간의 변경을 추적하기 위해 강력한 보안이 필요한 시스템에서도 유용 할 수 있습니다 rw.


1
이것이 어떻게 질문에 대답하는지 잘 모르겠습니다. mount 필요한 경우 마운트 지점 위치에 새 디렉토리를 작성하여 읽기 전용 파일 시스템 위에 아무것도 마운트 할 수 없다는 것을 지적하고 있습니까? 시작 단락은 혼란 스럽습니다. Linux initrd가 작동하는 방식이 아닙니다. 그것은 pivot_root시스템 호출을 사용하여 루트 fs를 변경합니다. 단지 더 많은 것을 마운트하는 것이 아닙니다. 다음 단락에서 논리를 따르기가 어려워졌습니다 pivot_root(2).
Peter Cordes

2
@PeterCordes은 - 리눅스는 많은 년 동안 initrd를 사용하지 않은 : 또 다른 루트 장치, initrd를 것 전환 할 때 pivot_root다음 umount램 디스크를. 그러나 initramfs는 rootfs입니다. pivot_rootrootfs 나 마운트 해제 할 수 없습니다 . 대신 공간 (확보하기 위해 rootfs 중 모든 것을 삭제 find -xdev / -exec rm {} \;), 새로운 루트 (와 overmount rootfs cd /newmount; mount --move . /; chroot .), 연결을 표준 입력 / 표준 출력 / 표준 에러 새로운는 / dev / 콘솔 및에 exec새로운init
mikeserv

@ mikeserv : 깔끔한! 루트를 전환하는 기본 메커니즘이 initrd 대신 initramfs를 사용하기 시작했을 때 바뀌 었다는 것을 알지 못했습니다. "올바른 커널 모듈이 그 안에 있는지 확인하십시오"라는 관리 관점에서 보면>. <와 동일합니다. 나는 아직도 이것이 실제로 질문에 잘 대답하지 못한다고 생각합니다 . "rofs 아래의 마운트는 불가능하다"해석을 가정하고 매우 특정한 문제 사례를 제공합니다 (initialfs는 부팅시 읽기 전용으로 마운트되지 않았기 때문에 거의 보이지 않습니다). -cpio.gz 이미지에 영향을주지 않고 쓰기.)
Peter Cordes

@ PeterCordes-나는이 대답을 정말로 이해하지 못한다. 방금 당신의 의견을 보았습니다-initramfs는 파일 시스템입니다-실제로는 읽기 전용이 될 수 없습니다-fs 캐시가 화신합니다.
mikeserv

2

항상 궁금했습니다.

다음과 같은 간단한 래퍼 :

#!/bin/sh
eval "mkdir -p \"\$$#\"" 
/bin/mount "$@"  

PATH에서 mount재정의 /bin된 디렉토리에 명명 된 실행 가능한 스크립트로 저장 하면 너무 많이 신경 쓰면 이것을 처리해야합니다.

실제 mount바이너리를 실행하기 전에에 대한 마지막 인수의 이름을 딴 디렉토리가 생성됩니다 mount(해당 디렉토리가없는 경우).


또는 mount래퍼 호출 실패로 디렉토리를 작성 하지 않으려는 경우 다음을 수행 할 수 있습니다.

#!/bin/sh
set -e
eval "lastArg=\"\$$#\""
test -d "$lastArg" || { mkdir "$lastArg"; madeDir=1; }
/bin/mount "$@"  ||  {  test -z "$madeDir" || rmdir "$lastArg"; }

mount그런 다음 명령이 이렇게 생성 된 디렉토리를 사용 해서는 안 됩니까?
muru December

1
@muru 그게 마지막 줄입니다.
PSkocik

아, 그래서 당신은 다음과 같이 사용해야한다는 것을 의미합니다 mount /dev/foo /some/path. 나는 그것이 작동하는 것처럼 작동한다고 가정 udisksctl했으므로 실행 mount /dev/foo합니다.
muru December

4
를 사용하여 eval확장 하지 않고 마지막 cmdline 인수를 얻을 수 있습니다 . POSIX sh가 지원 해야하는 것 이상을 지원하지 않는다고 생각하기 때문에 DASH로 이것을 테스트했습니다. 인쇄합니다 . $#"${@:-1}"/bin/dash -c 'echo ${@:-1}' foo barbar
Peter Cordes

1
당신은 사용할 수 있습니다 man -o x-mount.mkdir...
mikeserv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.