マウントポイントのinodeが変更されると、Linuxバインドマウントが消えるのはなぜですか?

マウントポイントのinodeが変更されると、Linuxバインドマウントが消えるのはなぜですか?

要約すると、新しいマウントネームスペースの上にファイルをバインドマウントした後に親ネームスペースのinodeが変更されると、バインド/tmp/aマウントは子ネームスペースから消えます。理由を理解しようとしています。/tmp/b/tmp/b

mount(8) は単一ファイル (ディレクトリのみ) をバインドマウントする機能を公開しないため、この操作を再現するには、必要な mount(2) システムコールを実行する追加の実行可能ファイルが必要です。以下は簡単な例です(下記参照bmount)。

#include <sys/mount.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("requires exactly 2 args\n");
        return 1;
    }

    int err = mount(argv[1], argv[2], "none", MS_BIND, NULL);
    if (err == 0) {
        return 0;
    } else {
        printf("mount error (%d): %s\n", errno, strerror(errno));
        return 1;
    }
}

テストケース設定:

# echo a > /tmp/a; echo b > /tmp/b; echo c > /tmp/c;
# ls -ldi /tmp/a /tmp/b /tmp/c
11403315 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/a                                                               
11403422 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/b
11403452 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/c

次に、別のシェルで次の操作を行います。

# unshare -m /bin/bash
# bmount /tmp/a /tmp/b
# ls -ldi /tmp/a /tmp/b /tmp/c
11403315 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/a
11403315 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/b
11403452 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/c
# cat /tmp/b
a
# grep "\/tmp\/" /proc/self/mounts
[redacted] /tmp/b ext4 rw,relatime,errors=remount-ro,data=ordered 0 0

元のシェルから:

# mv /tmp/c /tmp/b
# ls -ldi /tmp/a /tmp/b /tmp/c
ls: cannot access '/tmp/c': No such file or directory                                                               
11403315 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/a                                                               
11403452 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/b

unshareシェルから:

# ls -ldi /tmp/a /tmp/b /tmp/c
ls: cannot access '/tmp/c': No such file or directory
11403315 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/a
11403452 -rw-r--r-- 1 root root 2 Jan 19 13:34 /tmp/b
# cat /tmp/b
c
# grep "\/tmp\/" /proc/self/mounts
#

バインドマウントが静かに消え、デフォルト/tmp/bのファイルシステム上のファイルが名前空間内に表示されるようになりました。

私が一つ見つけたlwn.net 記事セマンティクスの変更は次のとおりです。 2013以前は、mvマウントポイントのコマンドが表示で失敗しましたが、成功し、マウントが削除されるように動作が変更されました。関連カーネルコミットは次のとおりです。rename(2)EBUSY8ed936b5671

私の質問は次のとおりです

  1. inodeを変更するとマウントが削除されるのはなぜですか?マウントポイントが単純なパスではなく、デントリとして識別されるマウントシステムの実装の詳細ですか?
  2. 名前空間外のファイルシステム操作で上書きまたは削除できないという点で、バインドマウントを「脆弱」にする方法はありますか?

実習に関連する状況は次のとおりです。IP-ネット(8);のip netns execバインドを介してインストールされます。 resolvconf(8)またはsystemd-resolvedによってinodeが変更されると、更新された内容は名前空間内で実行されているプロセスに表示されます。/etc/netns/${NAMESPACE}/resolv.conf/etc/resolv.conf/etc/resolv.conf/etc/resolv.conf

答え1

これがインストールの伝播です。 Linuxではデフォルトではこれを有効にしませんが、systemdでは有効にします。インストールと削除が新しい名前空間に伝播したくない場合は、mount --make-rprivate /その名前空間で実行できます。。ナレーター:これはマウントの伝播ではありません。

inodeを変更するとマウントが削除されるのはなぜですか?マウントポイントが単純なパスではなく、デントリとして識別されるマウントシステムの実装の詳細ですか?

私はあなたが期待できるものと存在しない限り、いつでも観察することが不可能であることのrm b; mv c b唯一の違いを言いたいと思います。私はそれがうまく設計されたかメンテナンスされている機能であると説明したいのですが、これは歴史的にマルチユーザーUnixシステムでどのくらい本当であるかはわかりませんが、たとえば実行中のシステムでソフトウェアアップデートをサポートすることにはかなり依存していました。 。mv c bb

私は…考えることができます。「inode change」と呼ばれる別の特定の機能が実装されました。- これは間違いなく実行され、ファイルシステムによって異なります。

関連情報