From e796e95a4efbfeb04223f61c600c7712da7b500f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 Jan 2011 16:39:11 +0100 Subject: replace KerneloopsScanner plugin and dumpoops with abrt-dump-oops, use it in abrtd Patch adds new tool: $ abrt-dump-oops Usage: abrt-dump-oops [-vsrdow] FILE Extract oops from syslog/dmesg file -v, --verbose Be verbose -s Log to syslog -r Parse kernel's message buffer before parsing FILE -d Create ABRT dump for every oops found -o Print found oopses on standard output -w Do not exit, watch the file for new oopses It extends dumpoops. Extensions: * it can watch the syslog using -w option (uses inotify) * it can scan dmesg buffer too In this way, it also becomes a replacement for KerneloopsScanner plugin: oops-detecting logic is taken verbatim from KerneloopsScanner source. abrtd is changed to start it if it sees this directive in abrt.conf: [ LogScanners ] abrt-dump-oops = abrt-dump-oops -drw /var/log/messages Default abrt.conf is changed to have such line. Patch doesn't remove KerneloopsScanner plugin and dumpoops binary yet, I will do it in a separate trivial patch. Signed-off-by: Denys Vlasenko --- src/daemon/Daemon.cpp | 57 +++++++++++++++++++++++++++++++++++++++---------- src/daemon/Settings.cpp | 25 +++++++++++++++------- src/daemon/Settings.h | 5 ++++- src/daemon/abrt.conf | 12 +++++++---- 4 files changed, 75 insertions(+), 24 deletions(-) (limited to 'src/daemon') diff --git a/src/daemon/Daemon.cpp b/src/daemon/Daemon.cpp index c01ea75a..e864c466 100644 --- a/src/daemon/Daemon.cpp +++ b/src/daemon/Daemon.cpp @@ -90,6 +90,7 @@ static volatile sig_atomic_t s_sig_caught; static int s_signal_pipe[2]; static int s_signal_pipe_write = -1; static int s_upload_watch = -1; +static pid_t log_scanner_pid = -1; static unsigned s_timeout; static bool s_exiting; @@ -432,12 +433,22 @@ static gboolean handle_signal_cb(GIOChannel *gio, GIOCondition condition, gpoint s_exiting = 1; else { - if (socket_client_count) - socket_client_count--; - if (!socket_channel_cb_id) + pid_t pid; + while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) { - log("Accepting connections on '%s'", SOCKET_FILE); - socket_channel_cb_id = add_watch_or_die(socket_channel, G_IO_IN | G_IO_PRI, server_socket_cb); + if (pid == log_scanner_pid) + { + log("log scanner exited"); + log_scanner_pid = -1; + continue; + } + if (socket_client_count) + socket_client_count--; + if (!socket_channel_cb_id) + { + log("Accepting connections on '%s'", SOCKET_FILE); + socket_channel_cb_id = add_watch_or_die(socket_channel, G_IO_IN | G_IO_PRI, server_socket_cb); + } } } return TRUE; @@ -648,6 +659,7 @@ static void start_syslog_logging() xdup2(STDIN_FILENO, STDERR_FILENO); openlog("abrtd", 0, LOG_DAEMON); logmode = LOGMODE_SYSLOG; + putenv((char*)"ABRT_SYSLOG=1"); } static void ensure_writable_dir(const char *dir, mode_t mode, const char *user) @@ -719,9 +731,10 @@ int main(int argc, char** argv) unsigned opts = parse_opts(argc, argv, abrtd_options, abrtd_usage); - if (opts & OPT_s) - start_syslog_logging(); + msg_prefix = "abrtd"; /* for log(), error_msg() and such */ + unsetenv("ABRT_SYSLOG"); + putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose)); /* When dbus daemon starts us, it doesn't set PATH * (I saw it set only DBUS_STARTER_ADDRESS and DBUS_STARTER_BUS_TYPE). * In this case, set something sane: @@ -730,9 +743,8 @@ int main(int argc, char** argv) if (!env_path || !env_path[0]) putenv((char*)"PATH=/usr/sbin:/usr/bin:/sbin:/bin"); - putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose)); - - msg_prefix = "abrtd"; /* for log(), error_msg() and such */ + if (opts & OPT_s) + start_syslog_logging(); xpipe(s_signal_pipe); close_on_exec_on(s_signal_pipe[0]); @@ -879,6 +891,22 @@ int main(int argc, char** argv) /* Only now we want signal pipe to work */ s_signal_pipe_write = s_signal_pipe[1]; + if (g_settings_sLogScanners) + { + const char *scanner_argv[] = { + "/bin/sh", "-c", + g_settings_sLogScanners, + NULL + }; + log_scanner_pid = fork_execv_on_steroids(EXECFLG_INPUT_NUL, + (char**)scanner_argv, + /*pipefds:*/ NULL, + /*unsetenv_vec:*/ NULL, + /*dir:*/ NULL, + /*uid:*/ 0); + VERB1 log("Started log scanner, pid:%d", (int)log_scanner_pid); + } + /* Enter the event loop */ log("Init complete, entering main loop"); run_main_loop(pMainloop); @@ -913,10 +941,17 @@ int main(int argc, char** argv) g_main_loop_unref(pMainloop); settings_free(); + + if (log_scanner_pid > 0) + { + VERB2 log("Sending SIGTERM to %d", log_scanner_pid); + kill(log_scanner_pid, SIGTERM); + } + /* Exiting */ if (s_sig_caught && s_sig_caught != SIGALRM && s_sig_caught != SIGCHLD) { - error_msg_and_die("Got signal %d, exiting", s_sig_caught); + error_msg("Got signal %d, exiting", s_sig_caught); signal(s_sig_caught, SIG_DFL); raise(s_sig_caught); } diff --git a/src/daemon/Settings.cpp b/src/daemon/Settings.cpp index abdd0324..63453933 100644 --- a/src/daemon/Settings.cpp +++ b/src/daemon/Settings.cpp @@ -19,8 +19,9 @@ #include "abrtlib.h" #include "Settings.h" -#define SECTION_COMMON "Common" -#define SECTION_CRON "Cron" +#define SECTION_COMMON "Common" +#define SECTION_LOG_SCANNERS "LogScanners" +#define SECTION_CRON "Cron" /* Conf file has this format: * [ section_name1 ] @@ -47,13 +48,16 @@ static map_string_t s_mapSectionCron; /* one line: "OpenGPGCheck = value" */ bool g_settings_bOpenGPGCheck = false; /* one line: "OpenGPGPublicKeys = value1,value2" */ -GList *g_settings_setOpenGPGPublicKeys = NULL; -GList *g_settings_setBlackListedPkgs = NULL; -GList *g_settings_setBlackListedPaths = NULL; -char *g_settings_sWatchCrashdumpArchiveDir = NULL; +GList * g_settings_setOpenGPGPublicKeys = NULL; +GList * g_settings_setBlackListedPkgs = NULL; +GList * g_settings_setBlackListedPaths = NULL; +char * g_settings_sWatchCrashdumpArchiveDir = NULL; unsigned int g_settings_nMaxCrashReportsSize = 1000; bool g_settings_bProcessUnpackaged = false; +/* [ LogScanners ] */ +char * g_settings_sLogScanners = NULL; + /* [ Cron ] */ /* many lines, one per key: "map_key = aa_first,bb_first(bb_second),cc_first" */ map_cron_t g_settings_mapCron; @@ -277,7 +281,7 @@ static int ReadConfigurationFromFile(FILE *fp) value += line[ii]; continue; } - if (isspace(line[ii]) && !is_quote) + if (isspace(line[ii]) && !is_quote && is_key) { continue; } @@ -304,8 +308,9 @@ static int ReadConfigurationFromFile(FILE *fp) section += line[ii]; continue; } - if (line[ii] == '=' && !is_quote) + if (is_key && line[ii] == '=' && !is_quote) { + while (isspace(line[ii + 1])) ii++; is_key = false; key = value; value = ""; @@ -351,6 +356,10 @@ static int ReadConfigurationFromFile(FILE *fp) s_mapSectionCommon[key] += ","; s_mapSectionCommon[key] += value; } + else if (section == SECTION_LOG_SCANNERS) + { + g_settings_sLogScanners = xstrdup(value.c_str()); + } else if (section == SECTION_CRON) { if (s_mapSectionCron[key] != "") diff --git a/src/daemon/Settings.h b/src/daemon/Settings.h index 71824c74..01cd1adc 100644 --- a/src/daemon/Settings.h +++ b/src/daemon/Settings.h @@ -31,7 +31,10 @@ extern GList *g_settings_setBlackListedPaths; extern unsigned int g_settings_nMaxCrashReportsSize; extern bool g_settings_bOpenGPGCheck; extern bool g_settings_bProcessUnpackaged; -extern char *g_settings_sWatchCrashdumpArchiveDir; +extern char * g_settings_sWatchCrashdumpArchiveDir; + +extern char * g_settings_sLogScanners; + extern map_cron_t g_settings_mapCron; int LoadSettings(); diff --git a/src/daemon/abrt.conf b/src/daemon/abrt.conf index 07ea51a0..fedefea0 100644 --- a/src/daemon/abrt.conf +++ b/src/daemon/abrt.conf @@ -8,7 +8,7 @@ OpenGPGCheck = yes # Blacklisted packages # -BlackList = nspluginwrapper, valgrind, strace +BlackList = nspluginwrapper,valgrind,strace # Process crashes in executables which do not belong to any package? # @@ -16,7 +16,7 @@ ProcessUnpackaged = no # Blacklisted executable paths (shell patterns) # -BlackListedPaths = /usr/share/doc/*, */example* +BlackListedPaths = /usr/share/doc/*,*/example* # Enable this if you want abrtd to auto-unpack crashdump tarballs which appear # in this directory (for example, uploaded via ftp, scp etc). @@ -30,12 +30,16 @@ BlackListedPaths = /usr/share/doc/*, */example* MaxCrashReportsSize = 1000 +# So far we support only one line here +# +[ LogScanners ] +abrt-dump-oops = abrt-dump-oops -drw /var/log/messages + + # Which Action plugins to run repeatedly # [ Cron ] # h:m - at h:m # s - every s seconds -120 = KerneloopsScanner - #02:00 = FileTransfer -- cgit