既存のディレクトリでマウントが発生するのはなぜですか?

既存のディレクトリでマウントが発生するのはなぜですか?

次の既存のディレクトリが必要です。マウントポイント

$ ls
$ sudo mount /dev/sdb2 ./datadisk
mount: mount point ./datadisk does not exist
$ mkdir datadisk
$ sudo mount /dev/sdb2 ./datadisk
$

ディレクトリの既存の内容を上書きするので混乱します。マウントポイントディレクトリには2つの可能な内容があり、誤って切り替えることができます(マウントを実行していないユーザーの場合)。

mount新しく作成されたディレクトリではなぜこれが起こらないのですか?これは、グラフィックオペレーティングシステムがリムーバブルメディアを表示する方法です。ディレクトリがマウントされているか(存在するのか)、マウントされていないのか(存在しないのか)明らかです。これには妥当な理由があると確信していますが、まだ発見されていません。

答え1

実装内容が流出した事例です。

UNIXシステムでは、各ディレクトリにマップされた名前のリストが含まれています。インデックスノード数字。 inodeには、ファイル、ディレクトリ、特殊デバイス、名前付きパイプなど、認知システムに通知するメタデータが含まれています。ファイルまたはディレクトリの場合、ディスク上のファイルまたはディレクトリの内容が見つかる場所もシステムに通知します。ほとんどのinodeはファイルまたはディレクトリです。オプションはinode番号をリストします-ils

ファイルシステムをマウントするには、ディレクトリinodeが必要で、「実際にこのディレクトリの内容を見つけるときに別のファイルシステムを見てください」というフラグをカーネルのメモリコピーに設定します(スライド10を参照)。このプレゼンテーション)。これは単一のデータ項目を変更するので比較的簡単です。

新しいinodeを指すディレクトリエントリを生成しないのはなぜですか?これを達成する方法は2つありますが、どちらの方法にも欠点があります。一つは、新しいディレクトリをファイルシステムに物理的に書き込むことです。ただし、ファイルシステムが読み取り専用の場合、この操作は失敗します!別のアプローチは、実際に存在しない「追加」エントリのリストを各ディレクトリリストプロセスに追加することです。これは退屈な操作であり、各ファイル操作のパフォーマンスに多少の影響を与える可能性があります。

動的に作成されたマウントポイントが必要な場合は、システムがこれを行うことがautomountできます。特殊なビディスクファイルシステムは、などprocのディレクトリを勝手に生成することもできますsysdevfs

編集:答えも参照してくださいコンテンツを含む既存のフォルダを「マウント」するとどうなりますか?

答え2

もしmount(2) 必須マウントポイントとして新しいディレクトリを作成します。読み取り専用ファイルシステムでは何もマウントできません。愚かなことなので排除できます。

インストールされている場合オプションでマウントポイントとして新しいディレクトリを作成します。おかしいでしょう。マウント/マウント解除は常に発生するわけではないので、単一のシステムコールで両方のステップを実行するためにカーネルに追加のロジックを配置しても、速度は大幅に向上しません。mkdir(2)必要に応じてシステムコールを実行するには、ユーザースペースに任せます。 Dmitryの答えによれば、mount(2)これら2つのことを行うと原子的ではなくなります。また、take、formount(2)などのモードフラグを使用するには追加のパラメータが必要です。ユーザースペースにこれを実行させることと比較すると、これは愚かです。open(2)O_CREATO_EXCL

mount(8)または(システムコールを作成する従来のプログラムmount(2))、これを行うことを許可するかどうかを尋ねる質問かもしれません。可能ですが、すでにmkdir(1)作業にぴったりのツールがあり、Unixのデザインはすべて組み合わせることができる良い小さなツールについてです。両方を実行するツールが必要な場合は、2つの簡単なツールを使用してシェルスクリプトを簡単に作成してビルドできます。 (またはmuruが説明したように、udisksctlこれはすでに完了しているため作成する必要はありません。)また、mount(8)util-linuxのLinuxは通常、ファイルシステムに渡されたオプションではなく、ユーザースペースオプションをmount -o x-mount.mkdir[=mode]使用して構文をサポートします。x-


今より興味深い質問は次のとおりです。なぜ親ファイルシステムにディレクトリがあるのですか?

pjc50の答えからわかるように(彼が私のイニシャルを持っていても構いません!)ディレクトリリストにマウントポイントを表示するにはreaddir()

マウントポイントを含むディレクトリ(親FS)にディレクトリとして存在させることは良い方法です。 readdir()マウントポイントという事実さえ認識しないでください。そんなことだけ起こるんだもしマウントポイントはパスコンポーネントとして使用されます。もちろん、パス検証では、パス内の各ディレクトリコンポーネントのマウントテーブルを確認する必要があります。

答え3

既存のディレクトリにマウントすると、実際に原子呼び出しが行われますmount。少なくともユーザーの視点では成功または失敗します。マウントポイントを直接作成する必要がある場合は、mount2つの障害ポイントがあり、完全なロールバックは保証されません。次のシナリオを想像してください。

  1. mountマウントポイントが正常に作成されました。
  2. mount新しいファイルシステムをディレクトリにマウントしようとしましたが、失敗しました。
  3. mountマウントポイントを削除しようとしましたが失敗しました。

システムは最終的に失敗という副作用を持つでしょうmount

ここに別のものがあります:

  1. umountファイルシステムを正常にマウント解除しました。
  2. umountマウントポイントを削除しようとしましたが失敗しました。

これでumount成功または失敗を返す必要がありますか?

答え4

私もいつもこれが気になりました。

次の簡単なラッパー:

#!/bin/sh
eval "mkdir -p \"\$$#\"" 
/bin/mount "$@"  

mountPATHで上書きされたディレクトリに名前を付け、実行可能スクリプトとして保存します/bin。面倒すぎる場合は、この点に注意してください。

(実際のバイナリを実行する前に、まだ存在しない場合はmount最後の引数の名前を付けたディレクトリを作成します。)mount


mountまたは、ラッパーのディレクトリ生成呼び出しが失敗しないようにするには、次のようにします。

#!/bin/sh
set -e
eval "lastArg=\"\$$#\""
test -d "$lastArg" || { mkdir "$lastArg"; madeDir=1; }
/bin/mount "$@"  ||  {  test -z "$madeDir" || rmdir "$lastArg"; }

関連情報