ファイルがまだ開いている間に削除されたファイルを回復する方法は?

ファイルがまだ開いている間に削除されたファイルを回復する方法は?

頑張った

xtricman⚓ArchVirtual⏺️~

ベストアンサー1

これを行うことはできません(ただし、興味深い例外については以下をお読みください)。

カーネルがそれを許可する場合、呼び出しは次のようになります。

fd = open(filename, O_CREAT|O_RDWR, 0666);
unlink(filename);

linkat(fd, "", 0, "/new/path", AT_EMPTY_PATH);

fdcapsがあるプロセスによって完了すると、参照されたinodeのリンク数が0であっても成功しますCAP_DAC_READ_SEARCH

ただし、カーネルは、これを行うプロセスの機能や権限に関係なく、このようなことが発生しないように積極的に防ぎます。

int vfs_link(struct dentry *old_dentry, ...
{
        ...
        /* Make sure we don't allow creating hardlink to an unlinked file */
        if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE))
                error =  -ENOENT;

これはマンページにも文書化されています。

AT_EMPTY_PATH(Linux 2.6.39以降)

空の文字列の場合は、oldpath参照されたファイルへのリンクを作成します(このフラグを使用して取得olddirfdできます)。open(2) O_PATHこの場合、olddirfdディレクトリ以外のあらゆる種類のファイルを参照できます。 これは通常、ファイルのリンク数がゼロの場合は機能しません(を O_TMPFILE使用または使用せずに生成されたファイルを除くO_EXCL)。。呼び出し側はCAP_DAC_READ_SEARCHこのフラグを使用できる必要があります。このフラグは、_GNU_SOURCE定義を取得するために定義したLinux固有のものです。

カーネルソースコードによるとO_TMPFILEO_TMPFILEこれはopen(2)マンページに文書化されています。これにはこれに基づいた小さな例があります。

#define _GNU_SOURCE 1
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <err.h>

int main(int ac, char **av){
        char path[64]; int fd;
        if(ac < 3) errx(1, "usage: %s dir newpath", av[0]);

        if((fd = open(av[1], O_TMPFILE|O_RDWR, 0666)) == -1) err(1, "open");

        /*
         * ...
         * write stuff to fd and only "realize" the file at the end if
         * everything has succeeded
         */

        /* the following line only works with CAP_DAC_READ_SEARCH */
        /* if(linkat(fd, "", 0, av[2], AT_EMPTY_PATH)) err(1, "linkat"); */

        snprintf(path, sizeof path, "/proc/self/fd/%d", fd);
        if(linkat(AT_FDCWD, path, AT_FDCWD, av[2], AT_SYMLINK_FOLLOW))
                err(1, "linkat");
        return 0;
}

おすすめ記事