可以从 inode 创建文件吗?

可以从 inode 创建文件吗?

有一个 apache 进程,它记录到访问和错误日​​志中。这两个日志文件已被删除,但 apache 进程尚未重新启动或重新加载,因此它仍然有这些日志文件的打开文件句柄。

我可以通过从目录中读取文件句柄来访问文件内容/proc

$ sudo lsof +p 30304
...
rotatelog 30304 root    4w   REG  251,0 22480405     265346 /var/log/httpd/error_log-2014-09-11 (deleted)

如果我检查该进程的文件句柄,我可以看到该文件:

$ ls -l /proc/30304/fd
...
l-wx------ 1 root root 64 2014-09-11 10:18 4 -> /var/log/httpd/error_log-2014-09-11 (deleted)

我还可以看到该文件的 inode:

$ ls -i /proc/30304/fd/4
1936760177 /proc/30304/fd/4

我可以复制此文件以获取当前内容,但任何未来的日志消息都不会出现在复制的文件中。有没有办法创建具有该 inode 编号的文件?

这就像用来ln创建文件的硬链接,但没有现有的文件可以引用。

答案1

有一个现有的文件可以引用—— 中的那个/proc/30304/fd。使用它有点棘手,因为常规 link() 拒绝接受它。您需要使用链接()

编写一个小的 C 程序。输入以下内容foo.c

#include <fcntl.h>
#include <err.h>

int main(int argc, char *argv[]) {
    char *src, *dstdir, *dstname;
    int dirfd, r;

    if (argc < 4)
        errx(2, "not enough parameters");

    src = argv[1]; dstdir = argv[2]; dstname = argv[3];

    dirfd = open(dstdir, O_DIRECTORY);
    if (dirfd < 0)
        err(1, "open(%s) failed", dstdir);

    r = linkat(AT_FDCWD, src, dirfd, dstname, AT_SYMLINK_FOLLOW);
    if (r < 0)
        err(1, "linkat(%s, %s/%s) failed", src, dstdir, dstname);

    return 0;
}

运行如下:

make foo
./foo '/proc/30304/fd/4' '/var/log' 'recovered.log'

相关内容