번들 마운트만 나열

번들 마운트만 나열

를 사용하는 대신 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/mtabbind옵션(이렇게 하면 파일 시스템 유형이 무시됩니다.) 그러나 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) 커널(약간 단순화됨)은 세 단계를 수행합니다.

  1. 커널은 지정된 파일 시스템 유형에 대한 파일 시스템 드라이버를 찾습니다(생략하거나 추측된 유형을 -t사용 -t auto mount하고 추측된 유형을 커널에 제공하는 경우).
  2. 커널은 파일 시스템 드라이버에 소스 경로와 제공된 옵션을 사용하여 파일 시스템에 액세스하도록 지시합니다. 이 시점에서 파일 시스템은 메이저:마이너 숫자 쌍으로만 식별됩니다.
  3. 파일 시스템은 경로(마운트 지점)에 바인딩됩니다. 커널은 여기서도 몇 가지 마운트 옵션을 사용합니다. ( nodev예를 들어 파일 시스템이 아닌 마운트 지점에 대한 옵션입니다. 마운트를 바인딩하거나 nodev마운트하지 않을 수 있습니다)

바인드 마운트를 수행하면(예: 사용 mount --bind /a /b) 다음과 같은 일이 발생합니다.

  1. 커널은 소스 경로와 마운트 지점에서 디렉터리까지의 상대 경로가 포함된 파일 시스템을 확인합니다.
  2. 옵션과 상대 경로를 사용하여 파일 시스템을 새 마운트 지점에 바인딩합니다.

mount --move( 질문과 관련없으니 생략하겠습니다 .)

이는 Linux에서 파일을 생성하는 방법과 매우 유사합니다.

  1. 커널은 파일이 생성되어야 하는 디렉터리를 담당하는 파일 시스템을 결정합니다.
  2. 파일 시스템에 새 파일이 생성됩니다. 현재 파일에는 하나의 inode 번호만 있습니다.
  3. 새 파일은 디렉터리의 파일 이름에 연결됩니다.

하드 링크를 만들면 다음과 같은 일이 발생합니다.

  1. 커널은 소스 파일의 inode 번호를 구문 분석합니다.
  2. 파일은 대상 파일 이름에 연결됩니다.

보시다시피 생성된 파일과 하드 링크는 구별할 수 없습니다.

$ 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")

관련 정보