興味深い問題があります。解決策があるかどうかはわかりませんが、できれば解決策があれば嬉しいです。
Solaris では、開いているログ ファイルが削除されました。このファイルは、プロセスの実行中は引き続き入力されますが、、などの他のすべてのツールからはアクセスできなくなりましcat
たtail
。
すべてが実行され続けている間に、ディレクトリ内のエントリをこのファイルに復元する方法はありますか?
答え1
これは、多少のハッキングと制限(ルート権限が必要)を伴いますが、実行可能です。
まず、アプリケーションがログ ファイルを書き込むために使用しているファイル記述子を見つけ、以前のログ ファイルの場所にシンボリック リンクを作成し、ファイル /proc エントリを参照します。例:
ln -s /var/tmp/file.log /proc/12345/fd/3
最初の制限は、ファイルがプロセスによって書き込み専用に開かれている場合、その権限では権限のないユーザーがその内容を読み取ることができないことです。ただし、root および file_dac_read 権限を持つユーザーは影響を受けません。あるいは、tail
Gilles がコメントで提案しているように、プロセスを使用してファイルの内容をコピーすることもできます。例:
tail -c +1 -f /proc/12345/fd/5 > /var/tmp/file.log
2 番目の問題は、プロセスがファイルを閉じるか終了すると、ファイルの内容全体が失われる ( 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);
}'