恢复打开的文件

Kar*_*son 5 solaris data-recovery files

我有一个有趣的问题,可能有也可能没有解决方案,但如果可能的话,我很想有一个:

在Solaris开放的日志文件已被删除,它依然延续,而进程正在运行中填充,但现在无法访问所有其他工具一样cattail等等。

有什么办法可以在一切都保持运行的情况下将目录中的条目恢复到这个文件中吗?

jll*_*gre 7

这是可行的,但有一些黑客攻击和限制(您需要 root 权限)。

首先找到应用程序正在使用哪个文件描述符来写入日志文件,然后在之前的日志文件位置创建一个符号链接并指向文件 /proc 条目,例如:

ln -s /var/tmp/file.log /proc/12345/fd/3
Run Code Online (Sandbox Code Playgroud)

第一个限制是,如果文件只为进程写入而打开,则其权限将不允许非特权用户读取其内容。但是,root 和具有 file_dac_read 权限的用户不会受到影响。或者,您可以使用一个过程来复制文件内容,tail就像 Gilles 在他的评论中所建议的那样。例如:

tail -c +1 -f /proc/12345/fd/5 > /var/tmp/file.log
Run Code Online (Sandbox Code Playgroud)

第二个问题是,当进程关闭或退出时,整个文件内容将丢失 ( ln -s) 或其中的一部分 ( tail -c 1 -f)。

解决方法是使用监视此事件的程序并在实际调用 close 之前备份文件。

完成这项工作的可能工具是 dtrace、truss、mdb 或 dbx。

这是在 Solaris 10 上使用 dtrace 的概念证明。

#!/bin/ksh
#
# This dtrace script is monitoring a file descriptor for a given process
# and copy its content to the given path when the file is closed.
#

pid=${1:?"$0: Usage: pid fd path"}
fd=${2:?}
path=${3:?}
[[ -f $path ]] && { echo "$path exists"; exit 1; }
dtrace -w -n '
syscall::close:entry
/pid=='$pid' && arg0=='$fd'/
{
        stop();
        system("cp /proc/%d/fd/%d %s",pid,arg0,"'"$path"'");
        system("prun %d",pid);
        exit(0);
}'
Run Code Online (Sandbox Code Playgroud)