既存のディレクトリ上でマウントが行われるのはなぜですか?


52

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

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

ディレクトリの既存のコンテンツをオーバーレイするため、混乱を招きます。(マウントを実行していないユーザーの場合)マウントポイントディレクトリには、予期せず切り替えられる可能性のある2つのコンテンツがあります。

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


1
その動作が必要な場合は、を使用しますudisksctl。なぜ使用mount
ムル

1
それはUnixの方法だからです。この方法はより柔軟性があり、どこにでもマウントできるためです。それらを任意の場所にマウントすると、たとえばデータベースパーティション用の新しいディスクを取得し、DBパーティション内のデータを新しいディスクに移動し、DBデータを許可する適切な場所にマウントするなど、必要に応じてサーバーを拡張できるためもっと成長する。
ルイFリベイロ

8
歴史的なメモとして、WindowsとLInuxが他のすべてのOSを本質的に破壊する前に、Apolloと呼ばれる会社がありました。彼らは、Unixに似た(Unixよりも優れた設計!)オペレーティングシステムを作成しました。NFSエクスポートが自動的にマウントされるディレクトリを作成しました。実際、既存のディレクトリにマウントできませんでした。HPはApolloを購入し、オペレーティングシステムを破棄し、Apolloの64ビットCPUをHP-PAとして使用しました。Apolloのリモートプロシージャコールのシステムは、OSFのDCEになり、明らかにWindowsの内部に存在します。知ることは戦いの半分です!
ブルースエディガー

どういうわけか、これは私のubuntu 14.04,3システムで起こります。まだ調査していません。SDカードがマウントされると、その下に何もないパスになります。私がそれをアンマウントして、手動でマウントして戻そうとすると、エラーが発生します。マウントポイントにディレクトリがありません。
スカペレン

2
@BruceEdiger better design than Unix![要出典]
ルスラン

回答:


51

これは、漏れた実装の詳細の場合です。

UNIXシステムでは、すべてのディレクトリはiノード番号にマップされた名前のリストで構成されます。iノードは、ファイル、ディレクトリ、特殊デバイス、名前付きパイプなどであるかどうかをシステムに伝えるメタデータを保持します。ファイルまたはディレクトリである場合、ディスク上のファイルまたはディレクトリの内容の場所をシステムに伝えます。ほとんどのiノードはファイルまたはディレクトリです。-iオプションlsの意志リストinode番号。

ファイルシステムをマウントすると、ディレクトリiノードを取得し、カーネルのメモリ内コピーにフラグを設定して、「実際、このディレクトリの内容を探すときは、代わりにこの他のファイルシステムを見てください」と言います(このプレゼンテーションのスライド10を参照)。これは、単一のデータ項目を変更するため、比較的簡単です。

代わりに新しいiノードを指すディレクトリエントリを作成しないのはなぜですか?それを実装する方法は2つありますが、どちらにも欠点があります。1つは、ファイルシステムに新しいディレクトリを物理的に書き込むことですが、ファイルシステムが読み取り専用の場合は失敗します!もう1つは、すべてのディレクトリリストプロセスに、実際には存在しない「余分な」もののリストを追加することです。これは手間がかかり、すべてのファイル操作で小さなパフォーマンスヒットが発生する可能性があります。

動的に作成されたマウントポイントが必要な場合、automountシステムはこれを実行できます。特殊な非ディスクファイルシステムはまた、例えば、意のままにディレクトリを作成することができprocsysdevfsというように。

編集:コンテンツを含む既存のフォルダーを「マウントオーバー」するとどうなりますか?


iノードにフラグを設定しないことを除いて。sudo mount --bind / /mnt ; ls /mnt/proc->空。どのように機能するのだろうか。
sourcejedi

正確な操作はにfs/namespace.cあります。私はソースに詳しくないので、詳細を掘り下げるのにあまり時間をかけたくありませんでした。リンクされたプレゼンテーションから取得した「iノードのフラグ」。
pjc50

2
@sourcejedi:マウントのバインドは、実際に参照するファイルシステムのみをバインドします。それらは、その下にマウントされた他のファイルシステムを再帰的にバインドしません。これは、マウントに隠れているジャンクを見つけるのに便利な方法です。(たとえば、マウント/var/cache/var失敗したときにルートFSに何らかの問題が発生した場合。)も参照してくださいpath_resolution(7)。(古いlinux-manpagesには、die.netのようにセクション2にそのmanページがありました)Linuxが実際に内部でどのように動作するかをIDKとして、可能なディレクトリマウントとしてすべてのディレクトリコンポーネントのチェックを最適化します。そのVFSエントリをキャッシュに固定するのでしょうか?
ピーターコーデス

2
そう、それが私のポイントです... fs/namei.c(path-> inode lookup)しかし、namespace.cを呼び出しますlookup_mnt()。dentry(ディレクトリキャッシュエントリ)にフラグがあります。しかし、それは最適化、つまり実装の詳細です。どのファイルシステムがそこにマウントされているかはわかりません。マウントテーブルを確認する必要があります。(実装の詳細については、m_hash()を参照してください。少なくともLinuxは追加の文字列比較を回避し、同時にAFAICSはバインドマウント全体でdentryを再利用します。これはウィザードによって作成されるためです)。
sourcejedi

1
@PeterCordes: :man 8 mount mount --bind foo fooバインドmount呼び出しは、単一のファイルシステム(の一部)のみをアタッチし、可能なサブマウントはアタッチしません。サブマウントを含む全体のファイル階層は、使用して2位に取り付けられているmount --rbind olddir newdir
mikeserv

19

マウントポイントとして新しいディレクトリを作成するmount(2) 必要がある場合、読み取り専用ファイルシステムの下には何もマウントできません。それは馬鹿げているので、それを除外することができます。

mountがオプションでマウントポイントとなる新しいディレクトリを作成した場合、それは奇妙です。マウント/アンマウントが常に発生するわけではないので、1つのシステムコールでこれら2つのステップを実行するためにカーネルに追加のロジックを配置しても、重要なスピードアップにはなりません。mkdir(2)必要に応じてシステムコールを行うために、ユーザースペースに任せてください。ドミトリーの答えmount(2)は、両方のことを行うと非原子的になると指摘しています。そして、あなたはに追加の引数をしたいと思うmount(2)ようにモードフラグを持つopen(2)ために、とりO_CREATO_EXCLそれはちょうど愚かなユーザ空間はそれを行うせることに比較されるなど、。

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


さて、より興味深い質問:なぜ親ファイルシステムにディレクトリが必要なのでしょうか?

pjc50の答えが指摘しているように(彼は私のイニシャルを持っていても関係ありません!)、ディレクトリリストにマウントポイントが表示されるようにするには、everyの追加チェックが必要になりますreaddir()

(親FS上の)それらを含むディレクトリ内にディレクトリとしてマウントポイントが存在することは、素晴らしいトリックです。 readdir()マウントポイントであることに気付く必要はありません。これは、マウントポイントがパスコンポーネントとして使用されている場合にのみ発生します。もちろん、パスの解決では、パスのすべてのディレクトリコンポーネントのマウントテーブルをチェックする必要があります。


1
If mount(2) required the creation of a new directory to be the mount point, you couldn't mount anything under a read-only filesystem. That would be dumb-私はそれをよりスマートに主張します:ユーザーの観点から、読み取り専用ファイルシステムは変更すべきではありませんが、マウントを許可することでそれが可能になります
Izkata

2
@Izkata:ファイルシステムを読み取り専用にしても、VFSのサブツリー全体が凍結されるわけではありません。読み取り/書き込みディレクトリを指すシンボリックリンクを持っているか、親fsが再マウントされたときに、その下に既に読み取り/書き込みマウントポイントを持っている可能性がありますro。引数が意味をなさない読み取り専用ファイルシステムには多くのユースケースがあります。
ピーターコーデス

2
man 8 mountx-mount.mkdir[=mode] ターゲットディレクトリ(マウントポイント)の作成を許可します。オプションの引数modeはmkdir(2)、8進表記で使用されるファイルシステムアクセスモードを指定します。デフォルトのモードは0755です。この機能は、rootユーザーに対してのみサポートされています。
mikeserv

特に初期のUnixではそうではありませんが、読み書き可能なファイルシステムがマウントされた読み取り専用ファイルシステムの重要なユースケースは見当たりません。@PeterCordes
クバンチク

@kubanczyk:読み取り専用のルートファイルシステム、読み取り/書き込み/tmpおよび/home。または/usr、ローカルに/usr/localマウントされた読み取り専用のNFSマウント。またはより一般的には、変更可能な部分がその上にマウントされた共有読み取り専用イメージ。(読み取り専用イメージへのローカルmodは、LiveCDブート可能イメージで使用される、overlayfsまたはLinux用の他のユニオンファイルシステムなどのカスタムファイルシステムを使用して、ファイルごとに実行することもできます。)起動しますが、他のマウントの前にrwにすることができます。
ピーターコーデス

12

既存のディレクトリにマウントすると、mount実質的にアトミックな呼び出しが行われます。少なくともユーザーの観点からは、成功または失敗します。mountマウントポイント自体を作成する必要がある場合、2つの障害点が発生し、クリーンロールバックを保証できなくなります。次のシナリオを想像してください。

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

システムは失敗の副作用で終わりmountます。

もう1つあります。

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

さて、umount成功または失敗を返す必要がありますか?


5
mountエラーには8つの異なるリターンコードがあり、これらも組み合わせることができます。ディレクトリの削除に失敗した場合、別のファイルを追加できます。man7.org/linux/man-pages/man8/mount.8.html#RETURN_CODES
chaos

8
OPは、なぜマウントポイントを既存のディレクトリにする必要があるのか​​を尋ねているのではなく、mountシステムコールがそれを作成しない理由を尋ねていると思います。多分それは、OPが尋ねることを意味すると思ったもの、または私が尋ねていた場合に私が尋ねたであろうことの私の解釈/期待でしたが。
ピーターコーデス

3

発生する可能性がある別のケース:

ブートすると、基本的な読み取り専用イメージがルートディレクトリにロードされます。したがって、実際のルートをマウンドする場合は、オーバーライドする必要があります。したがって、mount syscallはroマウントポイントをにスワップするだけだと想像できますrw

ここで、ルートマウントポイントにファイルシステムの問題があると想像してみましょう。修復を試してみたいと思います。マウントのオーバーラップにより、ファイルシステムをアンマウントし、fsck提供された基本イメージを使用して解決できます。

この機能は、roパーティションとパーティション間の変更を追跡するために強力なセキュリティが必要なシステムでも役立ちますrw


1
これがどのように質問に答えるかはわかりません。mount 必要に応じて、読み取り専用ファイルシステムの上に何もマウントできないマウントポイントの場所に新しいディレクトリを作成することを指摘していますか?冒頭の段落は紛らわしいです。それはLinux initrdの仕組みではありません。それは、pivot_rootシステムコールを使用して、ルートfsを変更します。単に、それ以上のものをマウントします。あなたが話していると思ったので、それは次の段落であなたの論理に従うのを難しくしましたpivot_root(2)
ピーターコーデス

2
@PeterCordes - Linuxは長年にわたってinitrdを使用していない別のルートデバイスを切り替える場合にinitrd、考えpivot_rootた後、umountRAMディスク。しかし、initramfsはrootfsですpivot_root。rootfsもアンマウントもできません。領域を解放するためにrootfsのうち代わりに削除すべて(find -xdev / -exec rm {} \;)、新しいルートとovermountにrootfs()、cd /newmount; mount --move . /; chroot .新しいの/ dev / consoleに標準入力/標準出力/標準エラー出力を添付して、exec新しいinit
mikeserv

@mikeserv:きちんとした!私たちがinitrdの代わりにinitramfsを使い始めたとき、ルートを切り替えるための基本的なメカニズムが変わったことに気付いていませんでした。「正しいカーネルモジュールが最終的にその中に収まるようにする」管理の観点から見ると、それらは同一です。 私はまだこれが質問にあまりよく答えないと思います。「rofsでのマウントは不可能」と解釈され、非常に特殊な問題のケースを示しているようです(initramfsはブート時に読み取り専用でマウントされていないため、ありそうにないようです。 -cpio.gzイメージに影響を与えずに書き込みます。)
Peter Cordes

@PeterCordes-私はこの答えを本当に理解していない。私はちょうどあなたのコメントを見ました-initramfsはファイルシステムです-それは実際に読み取り専用になることはできません-そのfsキャッシュは化身します。
mikeserv

2

私もいつもそう思っていました。

次のような単純なラッパー:

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

PATHをmountオーバーライドするディレクトリに名前が付けられた実行可能スクリプトとして保存されている/bin場合は、煩わしい場合はこれを処理する必要があります。

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


あるいは、失敗したmountラッパーの呼び出しでディレクトリを作成したくない場合は、次の操作を実行できます。

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

mountコマンドは、このように作成されたディレクトリを使用すべきではありませんか?
ムル

1
@muruこれが最後の行の動作です。
PSkocik

ああ、あなたはそれがために使用する必要があります意味しますか:mount /dev/foo /some/path?私はそれがするようにudisksctl動作すると仮定したので、実行しmount /dev/fooます。
ムル

4
を使用せずevalに、最後のcmdline argを取得できます。POSIX shがサポートするために必要なものを超えて何もサポートしていないと思うので、これをDASHでテストしました。 印刷します。$#"${@:-1}"/bin/dash -c 'echo ${@:-1}' foo barbar
ピーターコーデス

1
あなたが使用することができますman -o x-mount.mkdir...
mikeserv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.