답변:
바인드 마운트는 파일 시스템 유형이 아니며 마운트 된 파일 시스템의 매개 변수도 아닙니다. 그것들은 마운트 작업의 매개 변수입니다 . 내가 아는 한 다음 명령 시퀀스는 커널에 관한 한 본질적으로 동일한 시스템 상태로 이어집니다.
mount /dev/foo /mnt/one; mount --bind /mnt/one /mnt/two
mount /dev/foo /mnt/two; mount --bind /mnt/two /mnt/one
따라서 어떤 마운트가 바인드 마운트인지 기억하는 유일한 방법은에 mount
남아있는 명령 로그입니다 /etc/mtab
. 바인드 마운트 조작은 bind
마운트 옵션으로 표시됩니다 (이로 인해 파일 시스템 유형이 무시됩니다). 그러나 mount
특정 옵션 세트로 마운트 된 파일 시스템 만 나열 할 수있는 옵션이 없습니다. 따라서 자체 필터링을 수행해야합니다.
mount | grep -E '[,(]bind[,)]'
</etc/mtab awk '$4 ~ /(^|,)bind(,|$)/'
참고 /etc/mtab
가에 의해 유지되는 텍스트 파일 인 경우에 여기에만 유용합니다 mount
. 일부 배포판 /etc/mtab
은 /proc/mounts
대신에 심볼릭 링크로 설정 됩니다. /proc/mounts
대부분과 동일 /etc/mtab
하지만 몇 가지 차이점이 있으며 그 중 하나는 바인드 마운트를 추적하지 않습니다.
커널에 의해 유지되지만로 표시되지 않은 정보 /proc/mounts
는 마운트 지점이 마운트 된 파일 시스템에서 디렉토리 트리의 일부만 표시 할 때입니다. 실제로 이것은 대부분 바인드 마운트에서 발생합니다.
mount --bind /mnt/one/sub /mnt/partial
에서 /proc/mounts
의에 대한 항목 /mnt/one
과 /mnt/partial
같은 장치, 같은 파일 시스템 유형과 같은 옵션이 있습니다. 그 정보 /mnt/partial
를 루트있어 파일 시스템의 부분만을 도시 /sub
에서 프로세스 당 마운트 포인트 정보에 볼 /proc/$pid/mountinfo
(칼럼 4). 해당 항목은 다음과 같습니다.
12 34 56:78 / /mnt/one rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered
12 34 56:78 /sub /mnt/partial rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered
</etc/mtab awk …
는 POSIX 호환입니다 (본에서 지원되는지 여부는 잊어 버립니다). 사실을 확인하십시오. 나는 그 확인할 수 /etc/mtab
이 bind
파일 시스템이 장착에 대한 옵션 mount --bind /source /target
데비안 안정에을 (폴더의 유틸리티 - 리눅스-ng를 2.17.2을에서 마운트).
mount
와의 다른 행동을 보는 이유를 이해합니다 /etc/mtab
. util-linux-ng의 이전 버전을 가진 데비안 안정을 사용하고 있습니다; 더 이상 동일한 /etc/mtab
동작 을하지 않는 최신 버전의 데비안 테스트를 사용하고 있습니다. 왜냐하면 그의 배포가 최신 버전을 사용하고 있는지 @rozcietrzewiacz에서 보지 못했을 것 bind
입니다 /etc/mtab
.
findmnt
답변으로 게시해야합니다 . 그런데 대상 디렉토리가 다른 마운트 지점이 아닌 경우에만 작동합니다. 예를 들어보십시오sudo mount --bind / foo && findmnt | grep foo
커널은 사실 이후 일반 마운트 와 다른 바인드 마운트를 처리하지 않습니다 . mount
달리는 동안 일어나는 일만 다릅니다 .
파일 시스템을 마운트 할 때 (예 :로 mount -t ext4 /dev/sda1 /mnt
) 커널 (약간 단순화)은 세 단계를 수행합니다.
-t
하거나 사용 -t auto
mount
하는 경우 유형을 추측하여 추측 된 유형을 커널에 제공)nodev
예를 들어, 파일 시스템이 아닌 마운트 지점의 옵션입니다. 바인드 마운트를 사용 nodev
하거나 사용하지 않고 마운트 할 수 있습니다 )바인드 마운트 (예 :로 mount --bind /a /b
)를 수행하면 다음이 발생합니다.
( mount --move
질문과 관련이 없기 때문에을 생략 하겠습니다.)
이것은 Linux에서 파일을 작성하는 방법과 매우 유사합니다.
하드 링크를 만들면 다음이 발생합니다.
보다시피 생성 된 파일과 하드 링크는 구분할 수 없습니다 :
$ touch first
$ ln first second
$ ls -li
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/first
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/second
그러나 inode 번호를 비교하여 파일에 대한 모든 하드 링크를 식별 할 수 있으므로 메이저 : 마운트의 마운트 수를 비교하여 파일 시스템에 대한 모든 마운트를 식별 할 수 있습니다.
findmnt -o TARGET,MAJ:MIN
직접 또는 직접보고 이를 수행 할 수 있습니다 /proc/self/mountinfo
( 자세한 내용은 Linux 커널 설명서 참조 ).
다음 Python 스크립트는 모든 바인드 마운트를 나열합니다. 마운트 된 파일 시스템의 루트에 대한 상대 경로가 가장 짧은 가장 오래된 마운트 지점이 원래 마운트 인 것으로 가정합니다.
#!/usr/bin/python3
import os.path, re
from collections import namedtuple
MountInfo = namedtuple('MountInfo', ['mountid', 'parentid', 'devid', 'root', 'mountpoint', 'mountoptions', 'extra', 'fstype', 'source', 'fsoptions'])
mounts = {}
def unescape(string):
return re.sub(r'\\([0-7]{3})', (lambda m: chr(int(m.group(1), 8))), string)
with open('/proc/self/mountinfo', 'r') as f:
for line in f:
# Parse line
mid, pid, devid, root, mp, mopt, *tail = line.rstrip().split(' ')
extra = []
for item in tail:
if item != '-':
extra.append(item)
else:
break
fstype, src, fsopt = tail[len(extra)+1:]
# Save mount info
mount = MountInfo(int(mid), int(pid), devid, unescape(root), unescape(mp), mopt, extra, fstype, unescape(src), fsopt)
mounts.setdefault(devid, []).append(mount)
for devid, mnts in mounts.items():
# Skip single mounts
if len(mnts) <= 1:
continue
# Sort list to get the first mount of the device's root dir (if still mounted)
mnts.sort(key=lambda x: x.root)
src, *binds = mnts
# Print bind mounts
for bindmount in binds:
if src.root == bindmount.root:
srcstring = src.mountpoint
else:
srcstring = src.mountpoint+':/'+os.path.relpath(bindmount.root, src.root)
print('{0} -> {1.mountpoint} ({1.mountoptions})'.format(srcstring, bindmount))
unset DONE1FSES
FSES=$(findmnt -vUPno SOURCE,FSROOT,TARGET,MAJ:MIN)
FSES=${FSES//MAJ:MIN/MAJ_MIN}
while read SEARCH1FS
do
unset DONE2FSES
eval "$SEARCH1FS"
SEARCH1SOURCE=$SOURCE
SEARCH1FSROOT=$FSROOT
SEARCH1TARGET=$TARGET
SEARCH1MAJMIN=$MAJ_MIN
FS1WASHANDLED=0
while read DONE1FS
do
if [[ $DONE1FS == $MAJ_MIN ]]
then
FS1WASHANDLED=1
break
fi
done < <(echo "$DONE1FSES")
if [[ ($SEARCH1FSROOT == /) && ($FS1WASHANDLED == 0) ]]
then
DONE1FSES+=$MAJ_MIN$'\n'
while read SEARCH2FS
do
eval "$SEARCH2FS"
SEARCH2SOURCE=$SOURCE
SEARCH2FSROOT=$FSROOT
SEARCH2TARGET=$TARGET
SEARCH2MAJMIN=$MAJ_MIN
FS2WASHANDLED=0
while read DONE2FS
do
if [[ $DONE2FS == $SEARCH2FS ]]
then
FS2WASHANDLED=1
break
fi
done < <(echo "$DONE2FSES")
if [[ ($SEARCH1MAJMIN == $SEARCH2MAJMIN) && ($SEARCH1TARGET != $SEARCH2TARGET ) && ($FS2WASHANDLED == 0 ) ]]
then
DONE2FSES+=$SEARCH2FS$'\n'
echo "$SEARCH1TARGET$SEARCH2FSROOT --> $SEARCH2TARGET"
fi
done < <(echo "$FSES")
fi
done < <(echo "$FSES")
이것은 다른 findmnt 답변과 유사하지만 형식 문제를 피합니다.
모든 서브 마운트를 표시하려면
findmnt --kernel -n --list | grep '\['
ext4 유형의 파일 시스템의 모든 서브 마운트를 표시하려면 다음을 수행하십시오.
findmnt --kernel -t ext4 -n --list | grep '\['
서브 마운트를 제외한 모든 마운트를 표시하려면 :
findmnt --kernel -n --list | grep -v '\['
서브 마운트를 제외한 ext4 유형의 파일 시스템 마운트를 모두 표시하려면 다음을 수행하십시오.
findmnt --kernel -t ext4 -n --list | grep -v '\['
"-n"은 헤더를 제거하고 "--list"는 "tree"형식의 행을 제거합니다.
데비안 스트레치에서 테스트했습니다.
findmnt | fgrep [
대로 간단히 사용할 수 있습니다 .