동일한 파일 시스템의 "mount --bind"디렉토리에서 파일에 대한 하드 링크를 만들 수없는 이유는 무엇입니까?


9

원래 문제

하나의 파일 시스템에 파일이 있습니다. /data/src/file

그리고 그것을 열심히 연결하고 싶습니다 : /home/user/proj/src/file

그러나 /home한 디스크에 있고 /data다른 디스크 에 있으므로 오류가 발생합니다.

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

좋아, 그래서 나는 장치간에 하드 링크 할 수 없다는 것을 배웠다. 맞는 말이다.

손에 문제

그래서 파일 시스템 src에 있는 폴더를 멋지게 바인드 마운트 할 것이라고 생각했습니다 /data.

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

왜 여전히 작동하지 않습니까?

해결 방법

/data바인딩 된 디렉토리 대신 "실제" 디렉토리 에있는 한 하드 링크를 만들 수 있기 때문에이 설정이 올바른 것입니다.

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

일부 시스템 정보

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

참고 : 상황을보다 명확하게하기 위해 파일과 디렉토리 이름을 수동으로 변경 했으므로 명령 판독 값에 오타가있을 수 있습니다.


2
폴더를 마운트하는 위치는 중요하지 않습니다. 그들은 다른 파티션에 물리적입니다. 각 파티션에는 고유 한 파일 테이블이 있으며이 테이블에는 하드 링크 만 기록되어 있습니다.
user996142

2
여기서 요점은 파일이 실제로 다른 파티션에 있지 않다는 것입니다. 동일한 파티션의 동일한 파일 시스템입니다. 차이점은 바인드 마운트입니다.
roaima

바인드 마운트는 단지 허구 일뿐입니다. 디스크의 데이터 구조는 변경하지 않습니다. 파일 시스템은 여전히 ​​물리적으로 분리되어 있습니다.
Bob Eager

그러나 하드 링크를 만들 때 /data바인드 마운트 디렉토리에서 inode에 액세스 할 수 있으므로 바인드 마운트가와 동일한 파티션에 있어야 /data하거나 하드 링크가 장치에서 작동하므로 불법이어야하지만 어쨌든 작동합니다. 내가 무엇을 놓치고 있습니까?
jdk1.0

답변:


6

코드 에 실망스러운 주석이 있습니다 . 타임 바인드 마운트가 v2.4에서 구현되었으므로 아무도 유용하다고 생각하지 않습니다. 분명히 당신이해야 할 모든 것은 .mnt->mnt_sb그것이 말하는 곳에서 대체 하는 것입니다 .mnt...

하위 트리 주위에 보안 경계를 제공하기 때문입니다.

추신 : 그것은 꽤 많이 논의되었지만 검색을 피하기 위해 : 예를 들어 mount --bind / tmp / tmp; 이제 사용자는 / tmp에 쓰기 가능 권한이 있어도 루트 fs가없는 다른 위치에 대한 링크를 만들 수없는 상황이 발생했습니다. 비슷한 기술이 다른 격리 요구에 적용됩니다. 기본적으로 지정된 하위 트리로 이름 바꾸기 / 링크를 제한 할 수 있습니다. IOW는 고의적 인 기능입니다. 1 년 후 메인 트리에서 물건을 재배치하는 방법에 관계없이 많은 나무를 chroot에 묶고 예측 가능한 제한을 얻을 수 있습니다.

- 알 비로

스레드 아래에 구체적인 예가 있습니다.

mount -r --bind가 제대로 작동 할 때마다 (페이지 캐시 공유를 허용하면서 chroot jails에 필요한 공유 라이브러리 사본을 배치하는 데 사용)이 기능은 보안을 손상시킵니다.

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

보호는 충분하지만 포로가 /jail/lib/libfoo.so (쓰기는 EROFS를 반환합니다)를 / jail / usr / log에 링크하여 잠재적으로 쓰기 가능한 곳을 피하는 것이 좋습니다.


-1

교차 장치 연결을 수행 할 수없는 이유는 모호성을 유발하기 때문입니다. 파일의 디렉토리 항목에는 (단순 시스템에서) 관련된 파일의 i- 노드 번호가 포함됩니다. 하드 링크 (다른 디렉토리 항목 만)도 동일한 i- 노드 번호를 포함해야합니다. 이것은 훌륭하지만 i- 노드 번호는 단일 파일 시스템 내에서만 고유합니다 (일반적으로 1에서 시작하는 밀도가 높습니다).

바인드 마운트는 해당 문제를 해결하지 않습니다. 예, 그것은 일종의 구조의 '소설'을 구성하지만, 그렇지 않은 것은 하나의 파일 시스템에서 모든 i- 노드의 번호를 다시 매겨서 관련된 두 파일 시스템에서 모두 고유해야합니다! 어리석은 일입니다.

이 제한 사항은 항상 UNIX 시스템에있었습니다. 이 문제를 해결하기 위해 심볼릭 링크가 부분적으로 발명되었습니다. 나는 그들이 기능적으로 완전히 동일하지 않다는 것을 알고 있지만 일반적으로 괜찮습니다.

심볼릭 링크를 사용해보십시오? ( ln -s)


여기서는 inode 번호를 다시 매기는 이름이 없습니다. 두 개의보기가있는 하나의 기본 파일 시스템이 있습니다.
Gilles 'SO- 악마 그만해'

내 경로가 매수하고 지저분한을하고 있었기 때문에 나는 심볼릭 링크를하지 않은 이유 중 하나였다 ls -l. 처음에는 바보 같은 추론이지만, 그것은 토끼 구멍으로 이어지고 나는 하드 링크에 무슨 일이 있었는지 궁금해 ...
jdk1.0

@Gilles, 그것이 내가 말한 것입니다. 내가하고있는 요점은 아이 노드 번호 매기기가 어리 석다는 것입니다. 정답이 왜 다운 보트인지 모릅니다.
밥 열망

당신은 결론을 올바르게 얻지 만, 많은 곳에서 당신의 설명이 잘못되어 전체적으로 당신의 대답이 매우 오도됩니다. 좋은 설명은 sourcejedi의 답변을 참조하십시오.
Gilles 'SO- 악한 중지'

나는 더 명확 할 수 있음을 인정하지만 전혀 오류가 보이지 않습니다.
Bob Eager
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.