4

長時間実行されるプロセスがログ ファイルに書き込むとします。ログ ファイルが無期限に開かれているとします。不注意なシステム管理者がそのログ ファイルを削除したとします。プログラムはこれが発生したことを検出できますか?

fstat()削除されたファイルのリンク数が 0 と報告されると想定しても安全ですか?

切り捨ては、私には少し難しいようです。一部は、ファイル記述子がO_APPENDモードで実行されているかどうかによって異なります。ログ ファイルが で実行されていない場合O_APPEND、プログラムのログ記述子の現在の書き込み位置は変更されず、切り捨てによって先頭のバイトが削除されますが、プログラムは「最後」に書き込みを続け、幻のゼロのギャップが残ります。バイト (ゼロとして読み取られますが、必ずしもディスク上のスペースを占有するとは限りません)。

プログラムが で実行O_APPENDされる場合、現在存在するファイルの最後に書き込みます。切り捨てを観察する唯一の方法は、ファイルの位置がプログラムが予期した場所ではないことに注意することです。これは、その位置を明示的に追跡することを意味します。

全体として、切り捨てについては削除ほど心配していませんが、どんな考えでも大歓迎です。

4

5 に答える 5

4

fstat()ファイルがハード リンクされているか名前が変更されている場合、リンク カウント 0を返すチェックは失敗します。代わりに、定期的にstat()の inode 番号を と比較しfstat()ます。

切り捨てについてはわかりません。

tail -F削除とおそらく切り捨てをチェックするので、そのソースをチェックして、それがどのように実装されているかを確認します.

于 2009-01-20T17:03:34.077 に答える
2

不注意なシステム管理者がプロセスを強制終了したとします。管理者が無作為なことをするのを本当に防ぎたいですか? を使用するなど、時々新しいログファイルを開始する方法を探しているだけだと思いますlogrotate。プログラムがログファイルを手動で再度開く方法を提供するだけで十分です。これを行う標準的な方法は、プログラムで HUP シグナルをリッスンし、ログファイルが到着した場合はログファイルを再度開くことです。

#include <signal.h>

volatile int f_sighup;

void sighup_handler() {
  f_sighup = 1;
}

void trap_sighup() {
  struct sigaction sa;
  int rv;

  memset(&sa, 0, sizeof(struct sigaction));
  sa.sa_handler = &sighup_handler;
  rv = sigaction(SIGHUP, &sa, NULL);
  if (-1 == rv) {
    fprintf(stderr, "warning: setting SIGHUP signal handler failed");
  }
}

int main() {
  f_sighup = 0;
  trap_sighup();
  ...
}

次に、メイン プログラムのフラグを定期的にチェックしてf_sighup、ログ ファイルを再度開く必要があるかどうかを確認します。logrotateこれは、古いログファイルの名前を変更してから呼び出すことができる のようなツールとうまく機能しますkill -s HUP $PID。そして、不注意なシステム管理者は、古いログファイルを削除 (または名前を変更) した後、手動でこれを行うことができます。

于 2009-01-20T18:10:18.903 に答える
1

søren-holm回答に応じて

ファイルが閉じられると、変更時刻が変更されます。

それは正しくないようです:

import os
from time import sleep

TMPF = '/tmp/f'

def print_stats():
    print("%s, %s" % (os.stat(TMPF).st_mtime, os.stat(TMPF).st_ctime))
    sleep(1.1)

print("Opening...")
with open(TMPF, 'w') as f:
    print_stats()
    print("Writing...")
    os.write(f.fileno(), 'apple')
    print_stats()
    print("Flushing...")
    f.flush()
    print_stats()
    print("Closing...")

print_stats()

プロデュース:

Opening...
1483052647.08, 1483052647.08
Writing...
1483052648.18, 1483052648.18
Flushing...
1483052648.18, 1483052648.18
Closing...
1483052648.18, 1483052648.18

確かに、そこにはちょっとした Python の魔法がかかっています。これwrite()は、自動的にフラッシュされることが合理的に保証されているわけではありませんが、ポイントは、ファイルが閉じられたときではなく、ファイルが変更されたときに mtime が更新されることです。の動作はctime、ファイルシステムとそのマウント オプションによって異なります。

于 2016-12-29T23:09:29.340 に答える
1

inotifyを使用してログ ファイルを監視し、ファイル システム イベントを監視できます。

于 2009-01-20T17:06:51.167 に答える
-1

ファイルが閉じられると、変更時刻が変更されます。そのため、stat() を使用して mtime を定期的にチェックすると機能します。

于 2016-06-15T12:25:00.880 に答える