GNU/Linux >> Linux の 問題 >  >> Linux

バインド マウントのみを一覧表示する

バインド マウントは、ファイル システムの種類でも、マウントされたファイル システムのパラメーターでもありません。それらはマウント操作のパラメータです .私の知る限り、次の一連のコマンドは、カーネルに関する限り、本質的に同一のシステム状態につながります:

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 と同等です ただし、いくつかの違いがあり、そのうちの 1 つはバインド マウントを追跡していません。

カーネルによって保持されるが、/proc/mounts には表示されない 1 つの情報 は、マウント ポイントが、マウントされたファイル システムのディレクトリ ツリーの一部のみを表示する場合です。実際には、これは主にバインド マウントで発生します:

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

おそらくこれでうまくいくでしょう:

findmnt | grep  "\["

例:

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

カーネルは 通常 とは異なるバインド マウントを処理しません 事後にマウントします。 mount の間に何が起こるかだけが異なります

ファイルシステムをマウントするとき (例:mount -t ext4 /dev/sda1 /mnt を使用) ) カーネル (少し簡略化) は 3 つのステップを実行します:

<オール>
  • カーネルは、指定されたファイルシステム タイプのファイルシステム ドライバを探します (-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))
    

    Linux
    1. chrootを使用した後、SFTPユーザーをバインドマウントします

    2. Linuxでマウントをバインドする

    3. Linux でファイルシステム / パーティションをマウントおよびアンマウントする方法 (Mount/Umount コマンドの例)

    1. バインドマウントのみを読み取りますか?

    2. ファイルシステムを読み取り専用でマウントし、書き込みを RAM にリダイレクトしますか?

    3. マウントがバインド マウントの読み取り専用オプションを尊重しないのはなぜですか?

    1. バインドマウント?

    2. 新しいファイルシステムをマウントすると、非再帰的なバインド マウントに影響しますか?

    3. 再起動時の fstab の問題のデバッグ