를 사용하는 대신 mount | grep
을 사용하고 싶지만 mount -l -t bind
작동하지 않고 다음과 같이 -t none
표시됩니다 .모두산.
답변1
어쩌면 이것이 트릭을 수행할 것입니다:
findmnt | grep "\["
예:
$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep "\["
│ └─/tmp/foo /dev/sda2[/media] ext4 rw,relatime,data=ordered
답변2
바인드 마운트는 파일 시스템 유형이 아니며 마운트된 파일 시스템의 매개변수도 아닙니다.작업. 내가 아는 한, 다음 명령 시퀀스는 커널에 관한 한 본질적으로 동일한 시스템 상태를 초래합니다.
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
답변3
커널은 다음과 다른 바인드 마운트를 처리하지 않습니다.정상나중에 설치하세요. 유일한 차이점은 mount
런타임에 발생하는 것입니다.
파일 시스템을 마운트하면(예를 들어 를 사용하여 mount -t ext4 /dev/sda1 /mnt
) 커널(약간 단순화됨)은 세 단계를 수행합니다.
- 커널은 지정된 파일 시스템 유형에 대한 파일 시스템 드라이버를 찾습니다(생략하거나 추측된 유형을
-t
사용-t auto
mount
하고 추측된 유형을 커널에 제공하는 경우). - 커널은 파일 시스템 드라이버에 소스 경로와 제공된 옵션을 사용하여 파일 시스템에 액세스하도록 지시합니다. 이 시점에서 파일 시스템은 메이저:마이너 숫자 쌍으로만 식별됩니다.
- 파일 시스템은 경로(마운트 지점)에 바인딩됩니다. 커널은 여기서도 몇 가지 마운트 옵션을 사용합니다. (
nodev
예를 들어 파일 시스템이 아닌 마운트 지점에 대한 옵션입니다. 마운트를 바인딩하거나nodev
마운트하지 않을 수 있습니다)
바인드 마운트를 수행하면(예: 사용 mount --bind /a /b
) 다음과 같은 일이 발생합니다.
- 커널은 소스 경로와 마운트 지점에서 디렉터리까지의 상대 경로가 포함된 파일 시스템을 확인합니다.
- 옵션과 상대 경로를 사용하여 파일 시스템을 새 마운트 지점에 바인딩합니다.
mount --move
( 질문과 관련없으니 생략하겠습니다 .)
이는 Linux에서 파일을 생성하는 방법과 매우 유사합니다.
- 커널은 파일이 생성되어야 하는 디렉터리를 담당하는 파일 시스템을 결정합니다.
- 파일 시스템에 새 파일이 생성됩니다. 현재 파일에는 하나의 inode 번호만 있습니다.
- 새 파일은 디렉터리의 파일 이름에 연결됩니다.
하드 링크를 만들면 다음과 같은 일이 발생합니다.
- 커널은 소스 파일의 inode 번호를 구문 분석합니다.
- 파일은 대상 파일 이름에 연결됩니다.
보시다시피 생성된 파일과 하드 링크는 구별할 수 없습니다.
$ 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))
답변4
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")