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()
oldPath
newPath
答え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_dir
overlayfsの新しい形式に依存したいかもしれません。
したがって、これはLinuxであり、望ましくない場合はPOSIXに準拠していません。
https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt
"redirect_dir"機能を有効にしないと、サブディレクトリまたはマージされたディレクトリの名前変更(2)がEXDEVで失敗します。
Overlayfsはすでに他の詳細でUnixファイルシステムの一般的な期待に従わない。
ディレクトリ以外のオブジェクト(ファイル、シンボリックリンク、デバイス特殊ファイルなど)は、適切に親または子ファイルシステムでレンダリングされます。書き込みアクセスの設定、一部のメタデータの変更など、書き込みアクセスが必要な方法で子ファイルシステムのファイルにアクセスすると、ファイルは最初に子ファイルシステムから親ファイルシステムにコピーされます(copy_up)。 ...
copy_upジョブはデフォルトで同じ新しいファイルを作成し、それを古い名前に移動します。 この inode を参照する開いているファイルはすべて、古いデータにアクセスします。