同じルートディレクトリを持つ2つのサブディレクトリが同じマウントされたファイルシステムにあることは保証されますか?

同じルートディレクトリを持つ2つのサブディレクトリが同じマウントされたファイルシステムにあることは保証されますか?

cpp私が使用するファイルは、パスがmkdir( path, ... )環境変数(たとえばgetenv( "FOO" );)から来るディレクトリを生成します。

たとえば、上記で生成された$FOOファイルは `/foo/newPath/'/fooです。path

私の問題のシナリオでは、/foo/oldPath/コンテンツ(他のサブディレクトリがないと仮定)があるかもしれませ/foo/oldPath//foo/newPath

私の質問は:/foo/newPath/ieのサブディレクトリとして作成され、同じ親ディレクトリを持つ$FOOので、両方のディレクトリが同じ「マウントされたファイルシステム」にあることが保証されていますか? Linuxのマウントポイントとファイルシステムの私の理解は、せいぜい弱いです。/foo/newPath//foo/oldPath/

この質問の背景は次のとおりです。同じマウントされたファイルシステムにある場合は、他の選択肢よりもファイルの移動を簡単に実行できます/foo/newPath/。この関数のマニュアルページには、同じ「マウントされたファイルシステム」にあり、そうでない場合は失敗することが示されています。/foo/oldPath/rename()oldPathnewPath

答え1

彼らはこれを保証することはできません。これは/foo/oldPathマウントポイントです。

mount | grep 'on /foo/oldPath'oldPathただし、これは「ディレクトリがマウントポイントではないことを示す出力があってはなりません」を実行することで簡単に確認できます。

入れ子になったディレクトリを使用している場合は、どこにもマウントポイントがある可能性があるため、さらに注意が必要です。

これが自動かどうかはわかりませんが、マウントの3番目のフィールド(スペースで区切られています)が各行のマウントポイントであるため、注目に値します cut -d ' ' -f 3。たとえば、他のマウントポイントの部分文字列ではありません/foo/oldPath/nested/mountPoint.)

C / C ++コードに変換したい場合はそれを使用できますが、system("mount | grep 'on /foo/oldPath'")誓うことはありません。必要に応じて StackOverflow でより多くの実装の詳細を取得できます。

答え2

さまざまな理由でこれを試してはいけません(他の回答で詳しく説明されています)。/foo/oldPathマウントポイント自体でも、ファイルシステムを上書きしてファイルの移動を防ぐこともあります。個々のファイルでバインドマウントが発生したり、ファイル名を変更したりすると問題が発生する可能性があります。

ファイル名を変更できるかどうかを事前に決定しないでください。代わりにファイル名を変更してエラーを処理してください。renameエラーが発生した場合は-1を返し、クロスインストールの問題により名前を変更できない場合にerrno設定されます。EXDEVその後、他の方法(コピーと削除)を続行できます。

通常、2つのファイルシステムオブジェクトが同じファイルシステムにあることを確認するには、次のように実行する必要があります。statその上にあるデバイス識別子(st_devフィールド)を見てください。struct stat)。同じファイルシステム内の2つのファイルシステムオブジェクトは、同じデバイス識別子を持ちます。

答え3

overlayfsで実行するときは、rename()既存のディレクトリに依存することはできません。

汎用ファイル管理ツールを作成しない場合は、通常この可能性を無視できると思います。パッケージマネージャ...この場合は明らかに修正できないと思うかもしれません(原子性の理由で)、redirect_diroverlayfsの新しい形式に依存したいかもしれません。

したがって、これはLinuxであり、望ましくない場合はPOSIXに準拠していません。


https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt

"redirect_dir"機能を有効にしないと、サブディレクトリまたはマージされたディレクトリの名前変更(2)がEXDEVで失敗します。

Overlayfsはすでに他の詳細でUnixファイルシステムの一般的な期待に従わない。

ディレクトリ以外のオブジェクト(ファイル、シンボリックリンク、デバイス特殊ファイルなど)は、適切に親または子ファイルシステムでレンダリングされます。書き込みアクセスの設定、一部のメタデータの変更など、書き込みアクセスが必要な方法で子ファイルシステムのファイルにアクセスすると、ファイルは最初に子ファイルシステムから親ファイルシステムにコピーされます(copy_up)。 ...

copy_upジョブはデフォルトで同じ新しいファイルを作成し、それを古い名前に移動します。 この inode を参照する開いているファイルはすべて、古いデータにアクセスします。

関連情報