삭제된 파일이 열려 있는 동안 복원하는 방법은 무엇입니까?

삭제된 파일이 열려 있는 동안 복원하는 방법은 무엇입니까?

나는 노력했다

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(리눅스 2.6.39부터)

빈 문자열인 경우 oldpath에서 참조하는 파일에 대한 링크를 만듭니다 olddirfd(플래그를 사용하여 얻었을 수 있음 open(2) O_PATH). 이 경우 olddirfd디렉토리를 제외한 모든 유형의 파일을 참조할 수 있습니다. 이는 일반적으로 파일의 링크 수가 0인 경우 작동하지 않습니다(이를 사용하거나 O_TMPFILE사용하지 않고 생성된 파일은 O_EXCL예외임).. 호출자는 CAP_DAC_READ_SEARCH이 플래그를 사용하기 위한 능력을 가지고 있어야 합니다. 이 플래그는 Linux에만 해당됩니다. _GNU_SOURCE정의를 얻으려면 정의하십시오 .

커널 소스에 따르면 O_TMPFILE. 맨페이지 O_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;
}

답변2

cat간단히 해당 파일 설명자를 사용할 수 있습니다 .

$ echo foo > bar
$ sleep 10m < bar & rm bar 
[1] 15743
$ ls -l /proc/15743/fd 
total 0
lr-x------ 1 olorin olorin 64 Jan 16 17:49 0 -> /tmp/bar (deleted)
lrwx------ 1 olorin olorin 64 Jan 16 17:49 1 -> /dev/pts/6
lrwx------ 1 olorin olorin 64 Jan 16 17:49 2 -> /dev/pts/6
$ cat /proc/15743/fd/0
foo
$ cat /proc/15743/fd/0 > bar
$ cat bar
foo

ln하드 링크는 파일 시스템에 걸쳐 있을 수 없고 /proc가상 파일 시스템( )이기 때문에 해당 파일을 하드 링크로 만들 수 없습니다 procfs. 심지어 내부에서도 /proc수행할 수 있는 작업은 제한되어 있습니다(내용은 커널 상태를 반영하므로 임의의 작업을 수행할 수 없습니다).

관련 정보