Danh sách chỉ gắn kết gắn kết


24

Thay vì sử dụng mount | grep, tôi muốn sử dụng mount -l -t bind, nhưng nó không hoạt động và -t nonehiển thị tất cả các giá trị gắn kết.

Câu trả lời:


28

Gắn kết ràng buộc không phải là một loại hệ thống tập tin, cũng không phải là một tham số của hệ thống tập tin gắn kết; chúng là các tham số của hoạt động gắn kết . Theo như tôi biết, các chuỗi lệnh sau đây dẫn đến các trạng thái hệ thống cơ bản giống hệt như liên quan đến kernel:

mount /dev/foo /mnt/one; mount --bind /mnt/one /mnt/two
mount /dev/foo /mnt/two; mount --bind /mnt/two /mnt/one

Vì vậy, cách duy nhất để nhớ những gì gắn kết được gắn kết gắn kết là nhật ký của mountcác lệnh còn lại /etc/mtab. Một hoạt động gắn kết liên kết được chỉ định bởi tùy chọnbind gắn kết (làm cho loại hệ thống tập tin bị bỏ qua). Nhưng không có tùy chọn để liệt kê chỉ các hệ thống tập tin được gắn với một bộ tùy chọn cụ thể. Do đó bạn cần phải tự lọc.mount

mount | grep -E '[,(]bind[,)]'
</etc/mtab awk '$4 ~ /(^|,)bind(,|$)/'

Lưu ý rằng /etc/mtabchỉ hữu ích ở đây nếu đó là tệp văn bản được duy trì bởi mount. Một số bản phân phối được thiết lập /etc/mtabnhư một liên kết tượng trưng để /proc/mountsthay thế; /proc/mountshầu hết tương đương với /etc/mtabnhưng có một vài điểm khác biệt, một trong số đó là không theo dõi các liên kết gắn kết.

Một phần thông tin được giữ lại bởi kernel, nhưng không được hiển thị trong đó /proc/mountslà khi điểm gắn kết chỉ hiển thị một phần của cây thư mục trên hệ thống tập tin được gắn kết. Trong thực tế, điều này chủ yếu xảy ra với các liên kết gắn kết:

mount --bind /mnt/one/sub /mnt/partial

Trong /proc/mounts, các mục nhập cho /mnt/one/mnt/partialcó cùng một thiết bị, cùng loại hệ thống tệp và cùng tùy chọn. Thông tin /mnt/partialchỉ hiển thị một phần của hệ thống tập tin gốc /subđược hiển thị trong thông tin điểm gắn trên mỗi quy trình trong /proc/$pid/mountinfo(cột 4). Các mục ở đó trông như thế này:

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

1
@Gilles Trên thực tế, bạn có thể làm điều này chỉ đơn giản bằng cách sử dụng findmnt | fgrep [như được giải thích ở đây .
aculich

@Gilles Bạn mount --versionđang sử dụng bản ghi đó có bindthông tin /etc/mtabgì không? Tôi đang sử dụng phiên bản 2.20.1 và tôi đã xem các nguồn mới nhất và trong mọi trường hợp tôi không thấy thông tin ràng buộc được ghi lại ở bất cứ đâu cho phép bạn grep for bind. Mặt khác, những gì tôi đề xuất trong câu trả lời của mình thực tế lại liệt kê các liên kết gắn kết được tạo ra --bindcũng như sử dụng bind tùy chọn .
aculich

@aculich </etc/mtab awk …tuân thủ POSIX (Tôi quên liệu nó có được hỗ trợ trong Bourne không). Vui lòng kiểm tra sự thật của bạn. Tôi có thể xác nhận rằng /etc/mtabbindtùy chọn cho một hệ thống tập tin được gắn kết với mount --bind /source /targetDebian ổn định (mount từ produc-linux-ng 2.17.2).
Gilles 'SO- đừng trở nên xấu xa'

@Gilles Tôi đã xóa bình luận sai lầm của tôi để xóa nhầm lẫn. Bạn nói đúng, nó thực sự tuân thủ POSIX. Ngoài ra bây giờ tôi hiểu lý do chúng ta đang thấy hành vi khác nhau của mount/etc/mtab. Bạn đang sử dụng Debian ổn định có phiên bản cũ hơn của linux-linux-ng; Tôi đang sử dụng thử nghiệm Debian có phiên bản mới hơn dường như không còn /etc/mtabhành vi tương tự , đó có thể là lý do tại sao @rozcietrzewiacz không thấy bindtrong /etc/mtabbản phân phối của mình cũng sử dụng phiên bản mới hơn?
aculich

1
@aculich Bạn nên đăng bài findmntnhư một câu trả lời. Nó chỉ hoạt động nếu thư mục đích không phải là một điểm gắn kết khác. Hãy thử ví dụsudo mount --bind / foo && findmnt | grep foo
l0b0

21

Có lẽ điều này có thể làm được mẹo:

findmnt | grep  "\["

Thí dụ:

$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep  "\["
│ └─/tmp/foo                     /dev/sda2[/media] ext4            rw,relatime,data=ordered

1
Rõ ràng, điều này chỉ hoạt động khi một thư mục con của một điểm gắn kết được gắn kết. Nếu /bản thân nó được gắn kết, ví dụ, đầu ra không có a [...].
muru

8

Hạt nhân không xử lý các liên kết gắn kết khác với các gắn kết thông thường sau khi thực tế. Chỉ khác nhau trong những gì xảy ra trong khi mountchạy.

Khi bạn gắn kết một hệ thống tệp (ví dụ: với mount -t ext4 /dev/sda1 /mnt), hạt nhân (được đơn giản hóa một chút) thực hiện ba bước:

  1. Hạt nhân tìm kiếm trình điều khiển hệ thống tệp cho loại hệ thống tệp được chỉ định (nếu bạn bỏ qua -thoặc sử dụng loại -t auto mountđoán cho bạn và cung cấp loại đã đoán cho hạt nhân)
  2. Hạt nhân hướng dẫn trình điều khiển hệ thống tập tin truy cập hệ thống tập tin bằng cách sử dụng đường dẫn nguồn và bất kỳ tùy chọn được cung cấp nào. Tại thời điểm này, hệ thống tập tin chỉ được xác định bởi một cặp số chính: số phụ.
  3. Hệ thống tập tin được liên kết với một đường dẫn (điểm gắn kết). Nhân cũng sử dụng một số tùy chọn gắn kết ở đây. ( nodevví dụ: là một tùy chọn trên mountpoint, không phải trên hệ thống tập tin. Bạn có thể có một mount liên kết với nodevvà không có)

Nếu bạn thực hiện gắn kết liên kết (ví dụ: với mount --bind /a /b), điều sau đây xảy ra:

  1. Nhân giải quyết hệ thống tập tin nào chứa đường dẫn nguồn và đường dẫn tương đối từ điểm gắn kết đến thư mục.
  2. Hệ thống tập tin được liên kết với điểm gắn kết mới bằng cách sử dụng các tùy chọn và đường dẫn tương đối.

(Tôi sẽ bỏ qua mount --move, vì nó không liên quan đến câu hỏi.)

Điều này khá giống với cách các tệp được tạo trên Linux:

  1. Nhân giải quyết hệ thống tập tin nào chịu trách nhiệm cho thư mục mà tập tin sẽ được tạo.
  2. Một tập tin mới trong hệ thống tập tin được tạo ra. Tại thời điểm này, tập tin chỉ có một số inode.
  3. Các tập tin mới được liên kết với một tên tệp trong thư mục.

Nếu bạn tạo một liên kết cứng, điều sau đây sẽ xảy ra:

  1. Nhân giải quyết số inode của tệp nguồn.
  2. Các tập tin được liên kết với tên tệp đích.

Như bạn có thể thấy, tệp được tạo và liên kết cứng không thể phân biệt được:

$ 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

Nhưng , vì bạn có thể xác định tất cả các liên kết cứng với một tệp bằng cách so sánh các số inode, bạn có thể xác định tất cả các gắn kết với một hệ thống tệp bằng cách so sánh chính: số phụ gắn kết.

Bạn có thể làm điều này với findmnt -o TARGET,MAJ:MINhoặc bằng cách trực tiếp xem /proc/self/mountinfo( xem tài liệu nhân Linux để biết thêm thông tin ).

Tập lệnh Python sau liệt kê tất cả các liên kết gắn kết. Nó giả định rằng điểm gắn kết cũ nhất có đường dẫn tương đối ngắn nhất đến thư mục gốc của hệ thống tệp được gắn kết là giá trị gốc.

#!/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))

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

0

Điều này tương tự như câu trả lời findmnt khác, nhưng tránh vấn đề định dạng.

Để hiển thị tất cả các mục con:

findmnt --kernel -n --list | grep '\['

Để hiển thị tất cả các phần phụ của hệ thống tập tin kiểu ext4:

findmnt --kernel -t ext4 -n --list | grep '\['

Để hiển thị tất cả các mount không bao gồm các phần phụ:

findmnt --kernel -n --list | grep -v '\['

Để hiển thị tất cả các hệ thống tập tin kiểu ext4 không bao gồm các phần phụ:

findmnt --kernel -t ext4 -n --list | grep -v '\['

"-N" xóa các tiêu đề và "--list" sẽ xóa các dòng của định dạng "cây".

Đã thử nghiệm trên Debian.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.