/proc/self/mountinfo
マウントポイントのリストを提供します。最近の順に並べられていると思います。作られた最後にインストールされました(mount --move
影響しません)。
もしそうなら、あなたが最近行った、または作成されたインストールのためにインストールにアクセスできなくなったことを確認できますか?
man proc
表示される最初のフィールド/proc/self/mountinfo
は「インストールID」です。ただし、指定されたパスで最上位のマウント ID を確認する方法については説明しません。
statvfs()
(/usr/bin/stat -f
)は「ファイルシステムID」と呼ばれる他のものを検索できます。各ファイルシステムに固有の値があるようです...ここで質問した内容は役に立ちませんが、元の問題を解決するのに十分です...ファイルシステムIDを関連付ける方法もある場合は、インストールパスとすべてのインストールオプションが含まれています。 (statvfs()
「マウントフラグ」を返しますが、ファイルシステム固有のオプションは返しません/proc/self/mountinfo
。)
これに対する2番目の関心は、不完全な過負荷検出を次のように報告したことです。部族df
。
私の考えではFSINFO_ATTR_MOUNT_INFOこの質問にはとてもよく答えます。ただし、このパッチは現在カーネルでまだ承認されていません。
答え1
.txtファイルの「親ID」フィールドを見ると、インストールツリーのすべての詳細がわかりますmountinfo
。
2つのマウントを検討して/dir/sub
ください/dir
。親マウント/dir/sub
でない/dir
場合はマスクする必要/
があります。/dir/sub
/dir
または、パスに2つのインストールがある場合、/
1つはもう1つの親になり、子は最上位(アクセス可能)インストールになります。
二人いれば以上まったく同じパスにインストールされている場合、これらのインストールの最上位は他のインストールの親ではありません。
だからこれを試してみてください:
マウントパスPを確認してください。マウントMの子孫であるマウントがPにある場合、マウントMは非表示になります(停止)。
マウントパスPを確認してください。マウントMの親であるPにマウントがある場合は、Mをその親に設定して2を繰り返します。
1つ以上のマウントポイントを持つパスPの最長のサブプレフィックスPREを確認します。マウントMのトップマウントPARを探します。親マウントPARが存在しない場合、マウントMは非表示になります(中止)。
再帰的に:親マウントPARが非表示になると、元のマウントも非表示になります。
注:パスには/
より小さいプレフィックスはありません。ステップ2に達し、パスPがと等しい場合、/
マウントMが隠されていないことがわかります。止まる
答え2
Sourcejediのアルゴリズムを実装した後、目に見えるマウントポイントが隠されているという誤検出が表示され、大きな障害物にぶつかりました。パス、ID、および親IDを持つこのマウントポイントセットを取得します。
- ID:2、「/」
- ID: 3, "/a/b", ParentID: 2
- ID: 4, "/a/b/c", ParentID: 3
- ID: 5, "/a/b/c/e/f", ParentID: 4
- ID: 40, "/a/b/c", ParentID: 4
- ID: 5, "/a", ParentID: 2
- ID: 50, "/a/b/c/e/f", ParentID: 5
ID:2 "/"、ID:5、 "/a"、およびID:50 "/a/b/c/e/f"のマウントポイントのみを表示する必要があります。 Sourcejediアルゴリズムの実装のステップ3で、マウントポイントID:50について誤った肯定が得られました。この場合、PREとPARを正しくインポートする方法は、「VFSビュー」でPREが計算されること、つまりPREが複数のマウントポイントに関連付けることができるマウントパスであることを前提に長い間悩んでいました。さらに、1つのPREは別の階層のマウントポイントのみを参照できます。この組み合わせによって、手順3でエラーが発生する可能性があります。
LinuxカーネルのVFSは、ルートから始まり、VFSノードをたどるパスをinodeとして確認することを検討してください。下に「したがって、マウントポイントが隠されていることを確認するために、同じことを行うことは(知ろうとするよりも)より安全なオプションです。戻る問題のあるマウントポイントから始まる階層)。欠点は、特定のマウントポイントが実際にオーバーマウント/非表示になっているかどうかを安全に決定する前に、マウントポイントツリー全体のオーバーマウントを決定する必要があることです。
私のもの実装(Golang)上記のテストケースは次のようになり、基本的には次のようにうまく機能します。
- マウントパス "/"のマウントポイントから始まります。
- 現在のマウントポイントの子の1つのパスP(child(MP))が現在のマウントポイントのパスP(MP)と同じ「内部」オーバーマウントを確認します。
- 例:現在のマウントポイント(サブマウントポイントと共に繰り返し)のすべてのサブマウントポイントを非表示にします。現在のマウントポイントを超えたサブマウントポイントを除く。その後、再実行する前に、オーバーマウントのサブマウントポイントを再帰的に確認してください。
- いいえ:続ける
- パスを比較して、子が他の子を超えていることを確認します。 ISPREFIX(P(ith-child(MP)),P(jth-child(MP))):
- 例:jth-child(MP)とそのすべて(孫)を非表示(オーバーロード)として再帰的に表示します。
- いいえ:続く。
- 隠されていない(オーバーロードされた)すべての子(MP)の場合:このアルゴリズムを使用して再帰的にチェックします。
- 現在のマウントポイントの子の1つのパスP(child(MP))が現在のマウントポイントのパスP(MP)と同じ「内部」オーバーマウントを確認します。
接続実装には、マウントポイントIDに基づいてマウントポイントのリンクツリーを構築し、マウントパスの長さに基づいてサブマウントポイントを並べ替えるなど、いくつかの軽い最適化があります(!)。たとえば、最初の子マウントポイント(存在する場合)のみを調べることで、親以外の子マウントポイントの検証を簡素化できます。また、サブマウントポイントセットのO²プレフィックスオーバーロード検索を半分にしました。これは、O²が行うことに比べて多くの利点を得ることができないことが認められています。
答え3
アクセス権があればchroot
ハッキングがあるのです。最新のカーネルで動作。少なくともLinux v4.17では動作します。シェルフレンドリーではないと思いますが、Pythonは大丈夫です。
chroot
(ユーザーの名前空間にアクセスできる場合、またはそれに対応する機能を使用して、次の機能を取得できますunshare -rm --propagation slave
。)
# mount --bind / /mnt
# mount --make-slave /mnt # don't propagate submounts back to /
# mount --bind / /mnt
さて、過負荷を発見したので調べてみましょう。
# python3
...
>>> import os
>>> os.chdir("/")
>>> os.system("grep mnt proc/self/mountinfo")
231 73 253:0 / /mnt rw,relatime shared:1 - ext4 /dev/mapper/alan_dell_2016-fedora rw,seclabel
352 231 253:0 / /mnt rw,relatime shared:281 - ext4 /dev/mapper/alan_dell_2016-fedora rw,seclabel
0
>>> os.chroot("/mnt")
>>> os.system("cat proc/self/mountinfo")
352 231 253:0 / / rw,relatime shared:281 - ext4 /dev/mapper/alan_dell_2016-fedora rw,seclabel
0
/mnt
この結果は、マウントされたアクセス可能なファイルシステム(マウントID 352などのファイルシステム)があることを示しています。