開いたファイルの復元

開いたファイルの復元

解決策があるかもしれないし、そうでないかもしれない興味深い問題がありますが、可能であれば1つ欲しいです。

Solarisでは、開いているログファイルが削除され、プロセスの実行中にファイルはいっぱいになりますが、他のすべてのツール(などcat)からアクセスできなくなりましたtail

すべてを実行し続けながら、ディレクトリ内のエントリをそのファイルに復元する方法はありますか?

答え1

可能ですが、いくつかのハッキングと制限があります(ルートアクセスが必要です)。

まず、ログファイルを作成するためにアプリケーションで使用されているファイル記述子を見つけて、古いログファイルの場所にシンボリックリンクを作成し、ファイル/ procエントリをポイントします。例:

ln -s /var/tmp/file.log /proc/12345/fd/3

最初の制限は、ファイルがプロセスによる書き込み用にのみ開いている場合、その権限のために権限のないユーザーがその内容を読み取ることができないことです。ただし、file_dac_read権限を持つルートとユーザーは影響を受けません。あるいは、tailGilesが彼のコメントで提案したように、プロセスを使用してファイルの内容をコピーすることもできます。たとえば、

tail -c +1 -f /proc/12345/fd/5 > /var/tmp/file.log

2番目の問題は、プロセスが終了または終了したときにファイル全体の内容が失われる(または)ln -s一部()が失われることです。tail -c 1 -f

回避策は、このイベントを監視して実際に閉じるを呼び出す前にファイルをバックアップするプログラムを使用することです。

これを実行できるツールは、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);
}'

関連情報