[ABRT PATCH] a-a-ureport: generate core_backtrace only for CCpp problems
by Jakub Filak
Closes rhbz#993630
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/plugins/abrt-action-ureport | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/plugins/abrt-action-ureport b/src/plugins/abrt-action-ureport
index 41916bd..44575d8 100755
--- a/src/plugins/abrt-action-ureport
+++ b/src/plugins/abrt-action-ureport
@@ -59,6 +59,13 @@ if __name__ == "__main__":
dd = dd_opendir(dirname, 0)
if not dd:
sys.exit(1)
+
+ report_type = dd.load_text("type", DD_FAIL_QUIETLY_ENOENT)
+
+ # because of backward compatibility
+ if not report_type:
+ report_type = dd.load_text("analyzer", 0)
+
core_backtrace_exists = dd.exist("core_backtrace")
reported_to = dd.load_text("reported_to", DD_FAIL_QUIETLY_ENOENT)
ureports_counter = try_parse_number(dd, "ureports_counter")
@@ -90,7 +97,7 @@ if __name__ == "__main__":
log(_("uReport was already sent, not sending it again"))
sys.exit(0)
- if not core_backtrace_exists:
+ if report_type == "CCpp" and not core_backtrace_exists:
exitcode = spawn_and_wait("abrt-action-generate-core-backtrace")
if exitcode != 0:
log1("uReport can't be sent without core_backtrace. Exiting.")
--
1.8.3.1
10 years, 9 months
[LIBREPORT PATCH] Fix create_symlink_lockfile() to not emit ENOENT when asked not to.
by Denys Vlasenko
One of the error paths was ignoring DD_FAIL_QUIETLY_ENOENT.
Fixing it.
Signed-off-by: Denys Vlasenko <dvlasenk(a)redhat.com>
---
src/lib/dump_dir.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index 1e54f1f..c1037b3 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -397,17 +397,18 @@ struct dump_dir *dd_opendir(const char *dir, int flags)
*/
error_msg("'%s' is not a problem directory", dir);
}
- else if (errno == ENOENT || errno == ENOTDIR)
- {
- if (!(flags & DD_FAIL_QUIETLY_ENOENT))
- error_msg("'%s' does not exist", dir);
- }
else
{
- if (!(flags & DD_FAIL_QUIETLY_EACCES))
- {
cant_access:
- perror_msg("Can't access '%s'", dir);
+ if (errno == ENOENT || errno == ENOTDIR)
+ {
+ if (!(flags & DD_FAIL_QUIETLY_ENOENT))
+ error_msg("'%s' does not exist", dir);
+ }
+ else
+ {
+ if (!(flags & DD_FAIL_QUIETLY_EACCES))
+ perror_msg("Can't access '%s'", dir);
}
}
dd_close(dd);
--
1.8.1.4
10 years, 9 months
hooks rewrite from shell to python
by Jiri Moskovcak
Hi,
as part of the "get rid of inotify and use socket activation" efforts we
need to rewrite some shell code (choices were C or python) so we can use
the sockets. I know we could have written a helper which would do the
socket communication, but I think using the libabrt and exposing the API
to python will be much better solution. So our new team member Petr
Kubat took it as his first assignment and start rewriting the abrt
vmcore harvester:
https://github.com/abrt/abrt/issues/676
Cheers,
Jirka
10 years, 9 months
[LIBREPORT PATCH] do not store potentially big data in /tmp
by Jakub Filak
Closes rhbz#990208
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
configure.ac | 6 ++++++
src/cli/Makefile.am | 1 +
src/cli/cli-report.c | 2 +-
src/include/report.h | 2 +-
src/lib/Makefile.am | 1 +
src/lib/create_dump_dir.c | 4 ++--
src/lib/report.c | 2 +-
src/plugins/Makefile.am | 2 ++
src/plugins/reporter-rhtsupport.c | 8 ++++----
src/plugins/reporter-upload.c | 15 ++++++++-------
10 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac
index 5fa76cf..bfb9957 100644
--- a/configure.ac
+++ b/configure.ac
@@ -216,6 +216,12 @@ AC_ARG_WITH(debugdumpsdir,
[Directory where debugdumps are created])],
[DEBUG_DUMPS_DIR="$withval"])
+AC_ARG_WITH(largedatatmpdir,
+ [AS_HELP_STRING([--with-largedatatmpdir=DIR],
+ [Directory where potentially large data are created (default: /var/tmp)])],
+ [], [with_largedatatmpdir="/var/tmp"])
+AC_SUBST([LARGE_DATA_TMP_DIR], [$with_largedatatmpdir])
+
AC_ARG_WITH([defaultdumpdirmode],
AS_HELP_STRING([--with-defaultdumpdirmode=OCTAL-MODE],
[Default dump dir mode (default: 0660)]),
diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am
index 5edc119..7eec572 100644
--- a/src/cli/Makefile.am
+++ b/src/cli/Makefile.am
@@ -10,6 +10,7 @@ report_cli_CPPFLAGS = \
-I$(srcdir)/../lib \
-DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
-DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
+ -DLARGE_DATA_TMP_DIR=\"$(LARGE_DATA_TMP_DIR)\" \
$(GLIB_CFLAGS) \
-D_GNU_SOURCE \
$(LIBREPORT_CFLAGS)
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c
index 8370185..426561a 100644
--- a/src/cli/cli-report.c
+++ b/src/cli/cli-report.c
@@ -341,7 +341,7 @@ static int launch_editor(const char *path)
static int run_report_editor(problem_data_t *problem_data)
{
/* Open a temporary file and write the crash report to it. */
- char filename[] = "/tmp/abrt-report.XXXXXX";
+ char filename[] = LARGE_DATA_TMP_DIR"/abrt-report.XXXXXX";
int fd = mkstemp(filename);
if (fd == -1) /* errno is set */
{
diff --git a/src/include/report.h b/src/include/report.h
index 29b18d7..d31eb0a 100644
--- a/src/include/report.h
+++ b/src/include/report.h
@@ -40,7 +40,7 @@ enum {
int report_problem_in_dir(const char *dirname, int flags);
/* Reports a problem stored in problem_data_t.
- * It's first saved to /tmp and then processed as a dump dir.
+ * It's first saved to a temporary directory and then processed as a dump dir.
*/
int report_problem_in_memory(problem_data_t *pd, int flags);
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 261aaf2..aceb892 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -67,6 +67,7 @@ libreport_la_CPPFLAGS = \
-DBIN_DIR=\"$(bindir)\" \
-DDEFAULT_DUMP_DIR_MODE=$(DEFAULT_DUMP_DIR_MODE) \
-DDUMP_DIR_OWNED_BY_USER=$(DUMP_DIR_OWNED_BY_USER) \
+ -DLARGE_DATA_TMP_DIR=\"$(LARGE_DATA_TMP_DIR)\" \
$(GLIB_CFLAGS) \
$(GOBJECT_CFLAGS) \
-D_GNU_SOURCE
diff --git a/src/lib/create_dump_dir.c b/src/lib/create_dump_dir.c
index 873139d..fdf5183 100644
--- a/src/lib/create_dump_dir.c
+++ b/src/lib/create_dump_dir.c
@@ -89,9 +89,9 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
}
}
//TODO: try user's home dir obtained by getpwuid(getuid())?
- /* Try /tmp */
+ /* Try system temporary directory */
if (!dd)
- dd = try_dd_create("/tmp", problem_id, uid);
+ dd = try_dd_create(LARGE_DATA_TMP_DIR, problem_id, uid);
}
if (!dd) /* try_dd_create() already emitted the error message */
diff --git a/src/lib/report.c b/src/lib/report.c
index e4cff2c..e85f6ce 100644
--- a/src/lib/report.c
+++ b/src/lib/report.c
@@ -185,7 +185,7 @@ int report_problem_in_dir(const char *dirname, int flags)
int report_problem_in_memory(problem_data_t *pd, int flags)
{
int result = 0;
- struct dump_dir *dd = create_dump_dir_from_problem_data(pd, "/tmp"/* /var/tmp ?? */);
+ struct dump_dir *dd = create_dump_dir_from_problem_data(pd, LARGE_DATA_TMP_DIR);
if (!dd)
return -1;
char *dir_name = xstrdup(dd->dd_dirname);
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 166604c..f8699be 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -140,6 +140,7 @@ reporter_rhtsupport_CPPFLAGS = \
-DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \
-DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
-DPLUGINS_CONF_DIR=\"$(REPORT_PLUGINS_CONF_DIR)\" \
+ -DLARGE_DATA_TMP_DIR=\"$(LARGE_DATA_TMP_DIR)\" \
$(GLIB_CFLAGS) \
$(LIBREPORT_CFLAGS) \
$(LIBXML_CFLAGS) \
@@ -162,6 +163,7 @@ reporter_upload_CPPFLAGS = \
-DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \
-DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
-DPLUGINS_CONF_DIR=\"$(REPORT_PLUGINS_CONF_DIR)\" \
+ -DLARGE_DATA_TMP_DIR=\"$(LARGE_DATA_TMP_DIR)\" \
$(GLIB_CFLAGS) \
$(CURL_CFLAGS) \
$(LIBREPORT_CFLAGS) \
diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c
index b6e2a86..bbf0a1e 100644
--- a/src/plugins/reporter-rhtsupport.c
+++ b/src/plugins/reporter-rhtsupport.c
@@ -361,12 +361,12 @@ int main(int argc, char **argv)
dsc = make_description_bz(problem_data, CD_TEXT_ATT_SIZE_BZ);
}
- char tmpdir_name[sizeof("/tmp/rhtsupport-"LIBREPORT_ISO_DATE_STRING_SAMPLE"-XXXXXX")];
- snprintf(tmpdir_name, sizeof(tmpdir_name), "/tmp/rhtsupport-%s-XXXXXX", iso_date_string(NULL));
+ char tmpdir_name[sizeof(LARGE_DATA_TMP_DIR"/rhtsupport-"LIBREPORT_ISO_DATE_STRING_SAMPLE"-XXXXXX")];
+ snprintf(tmpdir_name, sizeof(tmpdir_name), LARGE_DATA_TMP_DIR"/rhtsupport-%s-XXXXXX", iso_date_string(NULL));
/* mkdtemp does mkdir(xxx, 0700), should be safe (is it?) */
if (mkdtemp(tmpdir_name) == NULL)
{
- error_msg_and_die(_("Can't create a temporary directory in /tmp"));
+ error_msg_and_die(_("Can't create a temporary directory in "LARGE_DATA_TMP_DIR));
}
/* Starting from here, we must perform cleanup on errors
* (delete temp dir)
@@ -375,7 +375,7 @@ int main(int argc, char **argv)
tempfile = append_to_malloced_string(tempfile, ".tar.gz");
if (create_tarball(tempfile, problem_data) != 0)
{
- errmsg = _("Can't create temporary file in /tmp");
+ errmsg = _("Can't create temporary file in "LARGE_DATA_TMP_DIR);
goto ret;
}
diff --git a/src/plugins/reporter-upload.c b/src/plugins/reporter-upload.c
index bde573e..59dccd5 100644
--- a/src/plugins/reporter-upload.c
+++ b/src/plugins/reporter-upload.c
@@ -49,7 +49,8 @@ static int create_and_upload_archive(
/* Create a child gzip which will compress the data */
/* SELinux guys are not happy with /tmp, using /var/run/abrt */
/* Reverted back to /tmp for ABRT2 */
- tempfile = concat_path_basename("/tmp", dump_dir_name);
+ /* Changed again to /var/tmp because of Fedora feature tmp-on-tmpfs */
+ tempfile = concat_path_basename(LARGE_DATA_TMP_DIR, dump_dir_name);
tempfile = append_to_malloced_string(tempfile, ".tar.gz");
int pipe_from_parent_to_child[2];
@@ -75,7 +76,7 @@ static int create_and_upload_archive(
if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile,
/*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0)
{
- errmsg = "Can't create temporary file in /tmp";
+ errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
goto ret;
}
@@ -98,7 +99,7 @@ static int create_and_upload_archive(
//}
if (tar_append_file(tar, full_name, short_name) != 0)
{
- errmsg = "Can't create temporary file in /tmp";
+ errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
free(short_name);
free(full_name);
goto ret;
@@ -114,7 +115,7 @@ static int create_and_upload_archive(
/* Close tar writer... */
if (tar_append_eof(tar) != 0 || tar_close(tar) != 0)
{
- errmsg = "Can't create temporary file in /tmp";
+ errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
goto ret;
}
tar = NULL;
@@ -125,13 +126,13 @@ static int create_and_upload_archive(
if (status != 0)
{
/* We assume the error was out-of-disk-space or out-of-quota */
- errmsg = "Can't create temporary file in /tmp";
+ errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
goto ret;
}
/* Upload the tarball */
/* Upload from /tmp to /tmp + deletion -> BAD, exclude this possibility */
- if (url && url[0] && strcmp(url, "file:///tmp/") != 0)
+ if (url && url[0] && strcmp(url, "file://"LARGE_DATA_TMP_DIR"/") != 0)
{
char *remote_name = upload_file(url, tempfile);
result = (remote_name == NULL); /* error if NULL */
@@ -184,7 +185,7 @@ int main(int argc, char **argv)
"& [-v] -d DIR [-c CONFFILE] [-u URL]\n"
"\n"
"Uploads compressed tarball of problem directory DIR to URL.\n"
- "If URL is not specified, creates tarball in /tmp and exits.\n"
+ "If URL is not specified, creates tarball in "LARGE_DATA_TMP_DIR" and exits.\n"
"\n"
"URL should have form 'protocol://[user[:pass]@]host/dir/[file.tar.gz]'\n"
"where protocol can be http(s), ftp, scp, or file.\n"
--
1.8.3.1
10 years, 9 months
[ABRT PATCH] abrt-dbus: send new problem notify signal to socket
by Jakub Filak
Since abrtd no longer reacts to new problem dirs, we need to trigger
"post-create" via socket.
This change continues work to implement feature in ticket #657
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/dbus/abrt-dbus.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
index 72d0260..ab48d1c 100644
--- a/src/dbus/abrt-dbus.c
+++ b/src/dbus/abrt-dbus.c
@@ -174,11 +174,10 @@ static char *handle_new_problem(GVariant *problem_info, uid_t caller_uid, char *
problem_data_add_basics(pd);
char *problem_id = problem_data_save(pd);
- if (!problem_id)
- {
- if (error)
- *error = xasprintf("Cannot create a new problem");
- }
+ if (problem_id)
+ notify_new_path(problem_id);
+ else if (error)
+ *error = xasprintf("Cannot create a new problem");
problem_data_free(pd);
return problem_id;
--
1.8.3.1
10 years, 9 months
[PATCH 1/8] abrt-handle-event: free more of allocated data
by Denys Vlasenko
This patch doesn't change the logic of the program,
it only makes cleanup in is_crash_a_dup() and main()
more consistent, closing a few leaks:
* dump_dir_name is a result of realpath(), but wasn't freed.
* four instances of dd_close() are collapsed to one.
* dump_dir_name in main() also was leaking, fix it.
* printing of "DUP_OF_DIR: dir" is made simpler-looking.
Signed-off-by: Denys Vlasenko <dvlasenk(a)redhat.com>
---
src/daemon/abrt-handle-event.c | 61 +++++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 31 deletions(-)
diff --git a/src/daemon/abrt-handle-event.c b/src/daemon/abrt-handle-event.c
index e4da837..ea932b2 100644
--- a/src/daemon/abrt-handle-event.c
+++ b/src/daemon/abrt-handle-event.c
@@ -219,16 +219,15 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param)
struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
if (!dd)
return 0; /* wtf? (error, but will be handled elsewhere later) */
-
+ free(analyzer);
analyzer = dd_load_text(dd, FILENAME_ANALYZER);
- /* dump_dir_name can be relative */
- dump_dir_name = realpath(dump_dir_name, NULL);
-
dup_uuid_init(dd);
dup_corebt_init(dd);
-
dd_close(dd);
+ /* dump_dir_name can be relative */
+ dump_dir_name = realpath(dump_dir_name, NULL);
+
DIR *dir = opendir(g_settings_dump_location);
if (dir == NULL)
goto end;
@@ -236,7 +235,7 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param)
/* Scan crash dumps looking for a dup */
//TODO: explain why this is safe wrt concurrent runs
struct dirent *dent;
- while ((dent = readdir(dir)) != NULL)
+ while ((dent = readdir(dir)) != NULL && crash_dump_dup_name == NULL)
{
if (dot_or_dotdot(dent->d_name))
continue; /* skip "." and ".." */
@@ -244,6 +243,7 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param)
if (ext && strcmp(ext, ".new") == 0)
continue; /* skip anything named "<dirname>.new" */
+ dd = NULL;
char *dump_dir_name2 = concat_path_file(g_settings_dump_location, dent->d_name);
char *dd_uid = NULL, *dd_analyzer = NULL;
@@ -258,7 +258,6 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param)
dd_uid = dd_load_text_ext(dd, FILENAME_UID, DD_FAIL_QUIETLY_ENOENT);
if (strcmp(uid, dd_uid))
{
- dd_close(dd);
goto next;
}
@@ -266,36 +265,35 @@ static int is_crash_a_dup(const char *dump_dir_name, void *param)
dd_analyzer = dd_load_text_ext(dd, FILENAME_ANALYZER, DD_FAIL_QUIETLY_ENOENT);
if (strcmp(analyzer, dd_analyzer))
{
- dd_close(dd);
goto next;
}
if (dup_uuid_compare(dd)
|| dup_corebt_compare(dd)
) {
- dd_close(dd);
crash_dump_dup_name = dump_dir_name2;
+ dump_dir_name2 = NULL;
retval = 1; /* "run_event, please stop iterating" */
- goto end;
+ /* sonce crash_dump_dup_name != NULL now, we exit the loop */
}
- dd_close(dd);
next:
free(dump_dir_name2);
+ dd_close(dd);
free(dd_uid);
free(dd_analyzer);
}
closedir(dir);
end:
- free(analyzer);
+ free((char*)dump_dir_name);
return retval;
}
static char *do_log(char *log_line, void *param)
{
- /* We pipe output of events to our log (which usually
- * includes syslog). Otherwise, errors on post-create result in
+ /* We pipe output of events to our log.
+ * Otherwise, errors on post-create result in
* "Corrupted or bad dump DIR, deleting" without adequate explanation why.
*/
log("%s", log_line);
@@ -355,13 +353,21 @@ int main(int argc, char **argv)
struct run_event_state *run_state = new_run_event_state();
if (!interactive)
make_run_event_state_forwarding(run_state);
+ run_state->logging_callback = do_log;
if (post_create)
run_state->post_run_callback = is_crash_a_dup;
- run_state->logging_callback = do_log;
+
int r = run_event_on_dir_name(run_state, dump_dir_name, event_name);
+
+ free_run_event_state(run_state);
+ /* Needed only if is_crash_a_dup() was called, but harmless
+ * even if it wasn't:
+ */
+ dup_uuid_fini();
+ dup_corebt_fini();
+
if (r == 0 && run_state->children_count == 0)
error_msg_and_die("No actions are found for event '%s'", event_name);
- free_run_event_state(run_state);
//TODO: consider this case:
// new dump is created, post-create detects that it is a dup,
@@ -372,24 +378,17 @@ int main(int argc, char **argv)
/* Is crash a dup? (In this case, is_crash_a_dup() should have
* aborted "post-create" event processing as soon as it saw uuid
* and determined that there is another crash with same uuid.
- * In this case it sets state.crash_dump_dup_name)
+ * In this case it sets crash_dump_dup_name)
*/
- if (!crash_dump_dup_name)
- {
- /* No. Was there error on one of processing steps in run_event? */
- if (r != 0)
- return r; /* yes */
- }
- else
- {
+ if (crash_dump_dup_name)
error_msg_and_die("DUP_OF_DIR: %s", crash_dump_dup_name);
- }
- if (post_create)
- {
- dup_uuid_fini();
- dup_corebt_fini();
- }
+ /* Was there error on one of processing steps in run_event? */
+ if (r != 0)
+ return r; /* yes */
+
+ free(dump_dir_name);
+ dump_dir_name = NULL;
}
/* exit 0 means, that there is no duplicate of dump-dir */
--
1.8.1.4
10 years, 9 months
[ABRT PATCH] abrtd: remove "post-create" machinery. Related to #657
by Denys Vlasenko
It is now handled to abrt-server.
Signed-off-by: Denys Vlasenko <dvlasenk(a)redhat.com>
---
src/daemon/abrt-handle-event.c | 7 +
src/daemon/abrtd.c | 388 +----------------------------------------
2 files changed, 16 insertions(+), 379 deletions(-)
diff --git a/src/daemon/abrt-handle-event.c b/src/daemon/abrt-handle-event.c
index e5f3600..73e53f7 100644
--- a/src/daemon/abrt-handle-event.c
+++ b/src/daemon/abrt-handle-event.c
@@ -402,6 +402,13 @@ int main(int argc, char **argv)
if (post_create)
{
run_state->post_run_callback = is_crash_a_dup;
+ /*
+ * The post-create event cannot be run concurrently for more problem
+ * directories. The problem is in searching for duplicates process
+ * in case when two concurrently processed directories are duplicates
+ * of each other. Both of the directories are marked as duplicates
+ * of each other and are deleted.
+ */
create_lockfile();
}
diff --git a/src/daemon/abrtd.c b/src/daemon/abrtd.c
index 62511d3..5586953 100644
--- a/src/daemon/abrtd.c
+++ b/src/daemon/abrtd.c
@@ -60,76 +60,6 @@ static GIOChannel *channel_socket = NULL;
static guint channel_id_socket = 0;
static int child_count = 0;
-/* We spawn three kinds of children:
- * - handlers for accepted socket connections (abrt-server)
- * - handlers for detected uploads (abrt-upload)
- * - handlers for "post-create" + "notify[-dup]" events
- * First two kinds of children don't need spcial handling:
- * we only need to collect their exit status to avoid creating zombies.
- * Unfortunately, the third kind is not this simple: wee need to collect
- * their exit status _after_ we ate their output.
- * Since we can either (1) detect EOF first and do waitpid after it,
- * OR (2) we can get SIGCHLD and do waitpit first, we need to maintain a list
- * of known children of third kind, or else in the case (2) we won't be able
- * to save exit status. s_pid_list exists solely for this purpose.
- */
-static GList *s_pid_list;
-
-/*
- * The post-create event cannot be run concurrently for more problem
- * directories. The problem is in searching for duplicates process in case when
- * two concurrently processed directories are duplicates of each other. Both of
- * the directories are marked as duplicates of each other and are deleted.
- *
- * This queue is used for serialization of processing of created problem
- * directories.
- *
- * The GIO notify handler pushes new directories to this queue and if the queue was
- * empty before push then starts processing of the pushed directory.
- *
- * Directory processing code pops the processed directory from the queue at the
- * end of processing. If the queue is not empty starts processing of the next
- * directory which is on the top of the queue.
- */
-static GList *s_dir_queue;
-
-enum {
- EVTYPE_POST_CREATE,
- EVTYPE_NOTIFY,
-};
-struct event_processing_state
-{
- int event_type;
- pid_t child_pid;
- int child_exitstatus;
- int child_stdout_fd;
- struct strbuf *cmd_output;
- char *dirname;
- char *dup_of_dir;
-};
-static struct event_processing_state *new_event_processing_state(void)
-{
- struct event_processing_state *p = xzalloc(sizeof(*p));
- p->child_pid = -1;
- p->child_stdout_fd = -1;
- p->cmd_output = strbuf_new();
- return p;
-}
-static void free_event_processing_state(struct event_processing_state *p)
-{
- if (!p)
- return;
- /*
- if (p->child_stdout_fd >= 0)
- close(p->child_stdout_fd);
- */
- strbuf_free(p->cmd_output);
- free(p->dirname);
- free(p->dup_of_dir);
- free(p);
-}
-
-
/* Helpers */
static guint add_watch_or_die(GIOChannel *channel, unsigned condition, GIOFunc func)
@@ -185,53 +115,6 @@ static void decrement_child_count(void)
}
}
-static pid_t spawn_event_handler_child(const char *dump_dir_name, const char *event_name, int *fdp)
-{
- char *args[6];
- args[0] = (char *) LIBEXEC_DIR"/abrt-handle-event";
- args[1] = (char *) "-e";
- args[2] = (char *) event_name;
- args[3] = (char *) "--";
- args[4] = (char *) dump_dir_name;
- args[5] = NULL;
-
- int pipeout[2];
- int flags = EXECFLG_INPUT_NUL | EXECFLG_OUTPUT | EXECFLG_QUIET | EXECFLG_ERR2OUT;
- VERB1 flags &= ~EXECFLG_QUIET;
-
- pid_t child = fork_execv_on_steroids(flags, args, pipeout,
- /*env_vec:*/ NULL, /*dir:*/ NULL,
- /*uid(unused):*/ 0);
- if (fdp)
- *fdp = pipeout[0];
- increment_child_count();
- return child;
-}
-
-static int wait_for_child(struct event_processing_state *state)
-{
- int status = 0;
-
- if (state->child_pid < 0)
- status = state->child_exitstatus;
- else
- {
- if (safe_waitpid(state->child_pid, &status, 0) > 0)
- {
- state->child_pid = -1;
- state->child_exitstatus = status;
- decrement_child_count();
- }
- else /* should not happen */
- perror_msg("waitpid(%d)", (int)state->child_pid);
- }
-
- s_pid_list = g_list_remove(s_pid_list, state);
-
- return status;
-}
-
-
/* Callback called by glib main loop when a client connects to ABRT's socket. */
static gboolean server_socket_cb(GIOChannel *source, GIOCondition condition, gpointer ptr_unused)
{
@@ -272,14 +155,7 @@ static gboolean server_socket_cb(GIOChannel *source, GIOCondition condition, gpo
return TRUE;
}
-
/* Signal pipe handler */
-static gint compare_pids(gconstpointer a, gconstpointer b)
-{
- const struct event_processing_state *state = a;
- pid_t pid = (pid_t) (uintptr_t) b;
- return state->child_pid != pid;
-}
static gboolean handle_signal_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
{
uint8_t signo;
@@ -293,239 +169,15 @@ static gboolean handle_signal_cb(GIOChannel *gio, GIOCondition condition, gpoint
s_exiting = 1;
else
{
- pid_t pid;
- int status;
- while ((pid = safe_waitpid(-1, &status, WNOHANG)) > 0)
+ while (safe_waitpid(-1, NULL, WNOHANG) > 0)
{
decrement_child_count();
- GList *l = g_list_find_custom(s_pid_list, (gconstpointer) (uintptr_t) pid, compare_pids);
- if (l)
- {
- struct event_processing_state *state = l->data;
- state->child_pid = -1;
- state->child_exitstatus = status;
- }
}
}
}
return TRUE; /* "please don't remove this event" */
}
-static gboolean handle_event_output_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr);
-
-/* Runs post-create event asynchronously. Uses GIOChanel for communication with event process. */
-static void run_post_create_on_dir_async(const char *name)
-{
- struct event_processing_state *state = new_event_processing_state();
- state->event_type = EVTYPE_POST_CREATE;
- state->dirname = concat_path_file(g_settings_dump_location, name);
-
- state->child_pid = spawn_event_handler_child(state->dirname, "post-create", &state->child_stdout_fd);
- s_pid_list = g_list_prepend(s_pid_list, state);
- ndelay_on(state->child_stdout_fd);
-
- GIOChannel *channel_event_output = my_io_channel_unix_new(state->child_stdout_fd);
- /*uint channel_id_event_output =*/ g_io_add_watch(channel_event_output,
- G_IO_IN | G_IO_PRI | G_IO_HUP,
- handle_event_output_cb,
- state);
-}
-
-/* Event-processing child output handler (such as "post-create" event) */
-static gboolean handle_event_output_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr)
-{
- struct event_processing_state *state = ptr;
-
- //log("Reading from event fd %d", state->child_stdout_fd);
-
- /* Read streamed data and split lines */
- for (;;)
- {
- char buf[250]; /* usually we get one line, no need to have big buf */
- errno = 0;
- gsize r = 0;
- g_io_channel_read_chars(gio, buf, sizeof(buf) - 1, &r, NULL);
- if (r <= 0)
- break;
- buf[r] = '\0';
-
- /* split lines in the current buffer */
- char *raw = buf;
- char *newline;
- while ((newline = strchr(raw, '\n')) != NULL)
- {
- *newline = '\0';
- strbuf_append_str(state->cmd_output, raw);
- char *msg = state->cmd_output->buf;
-
- /* Hmm, DUP_OF_DIR: ends up in syslog. move log() into 'else'? */
- log("%s", msg);
- if (state->event_type == EVTYPE_POST_CREATE
- && strncmp("DUP_OF_DIR: ", msg, strlen("DUP_OF_DIR: ")) == 0
- ) {
- free(state->dup_of_dir);
- state->dup_of_dir = xstrdup(msg + strlen("DUP_OF_DIR: "));
- }
-
- strbuf_clear(state->cmd_output);
- /* jump to next line */
- raw = newline + 1;
- }
-
- /* beginning of next line. the line continues by next read */
- strbuf_append_str(state->cmd_output, raw);
- }
-
- if (errno == EAGAIN)
- {
- /* We got all buffered data, but fd is still open. Done for now */
- //log("EAGAIN on fd %d", state->child_stdout_fd);
- return TRUE; /* "glib, please don't remove this event (yet)" */
- }
-
- /* EOF/error */
-
- /* Wait for child to actually exit, collect status */
- int status = wait_for_child(state);
-
- /* If it was a "notify[-dup]" event, then we're done */
- if (state->event_type == EVTYPE_NOTIFY)
- goto ret;
-
- /* Else: it was "post-create" event */
-
- /* exit 0 means "this is a good, non-dup dir" */
- /* exit with 1 + "DUP_OF_DIR: dir" string => dup */
- if (status != 0)
- {
- if (WIFSIGNALED(status))
- {
- log("'post-create' on '%s' killed by signal %d",
- state->dirname, WTERMSIG(status));
- goto delete_bad_dir;
- }
- /* else: it is WIFEXITED(status) */
- else if (!state->dup_of_dir)
- {
- log("'post-create' on '%s' exited with %d",
- state->dirname, WEXITSTATUS(status));
- goto delete_bad_dir;
- }
- }
-
- char *work_dir = state->dup_of_dir ? state->dup_of_dir : state->dirname;
-
- /* Load problem_data (from the *first dir* if this one is a dup) */
- struct dump_dir *dd = dd_opendir(work_dir, /*flags:*/ 0);
- if (!dd)
- /* dd_opendir already emitted error msg */
- goto delete_bad_dir;
-
- /* Update count */
- char *count_str = dd_load_text_ext(dd, FILENAME_COUNT, DD_FAIL_QUIETLY_ENOENT);
- unsigned long count = strtoul(count_str, NULL, 10);
-
- /* Don't increase crash count if we are working with newly uploaded
- * directory (remote crash) which already has its crash count set.
- */
- if ((status != 0 && state->dup_of_dir) || count == 0)
- {
- count++;
- char new_count_str[sizeof(long)*3 + 2];
- sprintf(new_count_str, "%lu", count);
- dd_save_text(dd, FILENAME_COUNT, new_count_str);
-
- /* This condition can be simplified to either
- * (status * != 0 && * state->dup_of_dir) or (count == 1). But the
- * chosen form is much more reliable and safe. We must not call
- * dd_opendir() to locked dd otherwise we go into a deadlock.
- */
- if (strcmp(dd->dd_dirname, state->dirname) != 0)
- {
- /* Update the last occurrence file by the time file of the new problem */
- struct dump_dir *new_dd = dd_opendir(state->dirname, DD_OPEN_READONLY);
- char *last_ocr = NULL;
- if (new_dd)
- {
- /* TIME must exists in a valid dump directory but we don't want to die
- * due to broken duplicated dump directory */
- last_ocr = dd_load_text_ext(new_dd, FILENAME_TIME,
- DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE | DD_FAIL_QUIETLY_ENOENT);
- dd_close(new_dd);
- }
- else
- { /* dd_opendir() already produced a message with good information about failure */
- error_msg("Can't read the last occurrence file from the new dump directory.");
- }
-
- if (!last_ocr)
- { /* the new dump directory may lie in the dump location for some time */
- log("Using current time for the last occurrence file which may be incorrect.");
- time_t t = time(NULL);
- last_ocr = xasprintf("%lu", (long)t);
- }
-
- dd_save_text(dd, FILENAME_LAST_OCCURRENCE, last_ocr);
-
- free(last_ocr);
- }
- }
-
- /* Reset mode/uig/gid to correct values for all files created by event run */
- dd_sanitize_mode_and_owner(dd);
-
- dd_close(dd);
-
- if (!state->dup_of_dir)
- log("New problem directory %s, processing", work_dir);
- else
- {
- log("Deleting problem directory %s (dup of %s)",
- strrchr(state->dirname, '/') + 1,
- strrchr(state->dup_of_dir, '/') + 1);
- delete_dump_dir(state->dirname);
- }
-
- /* Run "notify[-dup]" event */
- int fd;
- state->child_pid = spawn_event_handler_child(
- work_dir,
- (state->dup_of_dir ? "notify-dup" : "notify"),
- &fd
- );
- s_pid_list = g_list_prepend(s_pid_list, state);
- ndelay_on(fd);
- //log("Started notify, fd %d -> %d", fd, state->child_stdout_fd);
- xmove_fd(fd, state->child_stdout_fd);
- state->event_type = EVTYPE_NOTIFY;
- return TRUE; /* "glib, please don't remove this event (yet)" */
-
-
- delete_bad_dir:
- log("Deleting problem directory '%s'", state->dirname);
- delete_dump_dir(state->dirname);
-
- ret:
- //log("Closing event fd %d", state->child_stdout_fd);
- free_event_processing_state(state);
-
- /* We stop using this channel */
- g_io_channel_unref(gio);
-
- /* pop the currently processed directory from the incoming queue */
- char *name = s_dir_queue->data;
- s_dir_queue = g_list_remove(s_dir_queue, name);
- free(name);
-
- /* if the queue is not empty process directory from */
- /* the top of the incoming queue */
- if (s_dir_queue)
- run_post_create_on_dir_async(s_dir_queue->data);
-
- return FALSE; /* "glib, please remove this events source!" */
- /* Removing will also drop the last ref to this gio, closing/freeing it */
-}
-
static void ensure_writable_dir(const char *dir, mode_t mode, const char *user)
{
struct stat sb;
@@ -666,16 +318,19 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
* but this handler is used for 'g_settings_sWatchCrashdumpArchiveDir' too
*/
log("Recreating deleted dump location '%s'", g_settings_dump_location);
- inotify_rm_watch(g_io_channel_unix_get_fd(gio), event->wd);
+
+ int inotify_fd = g_io_channel_unix_get_fd(gio);
+ inotify_rm_watch(inotify_fd, event->wd);
sanitize_dump_dir_rights();
- if (inotify_add_watch(g_io_channel_unix_get_fd(gio), g_settings_dump_location, IN_DUMP_LOCATION_FLAGS) < 0)
+ if (inotify_add_watch(inotify_fd, g_settings_dump_location, IN_DUMP_LOCATION_FLAGS) < 0)
{
perror_msg_and_die("inotify_add_watch failed on recreated '%s'", g_settings_dump_location);
}
continue;
}
-
+/* We no longer watch for subdirectory creations */
+#if 0
if (!(event->mask & IN_ISDIR) || !name)
{
/* ignore lock files and such */
@@ -690,33 +345,8 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
continue;
}
log("Directory '%s' creation detected", name);
-
- if (g_settings_nMaxCrashReportsSize > 0)
- {
- char *worst_dir = NULL;
- while (g_settings_nMaxCrashReportsSize > 0
- && get_dirsize_find_largest_dir(g_settings_dump_location, &worst_dir, name) / (1024*1024) >= g_settings_nMaxCrashReportsSize
- && worst_dir
- ) {
- log("Size of '%s' >= %u MB, deleting '%s'",
- g_settings_dump_location, g_settings_nMaxCrashReportsSize, worst_dir);
- char *d = concat_path_file(g_settings_dump_location, worst_dir);
- free(worst_dir);
- worst_dir = NULL;
- delete_dump_dir(d);
- free(d);
- }
- free(worst_dir);
- }
-
- const bool empty_queue = s_dir_queue == NULL;
- /* push the new directory to the end of the incoming queue */
- s_dir_queue = g_list_append(s_dir_queue, xstrdup(name));
-
- /* if the queue was empty process the current directory */
- if (empty_queue)
- run_post_create_on_dir_async(name);
-
+ ...
+#endif
} /* while */
free(buf);
--
1.8.1.4
10 years, 9 months
[Bug 856276] [abrt] will-crash-0.2-1.fc17: main: i
by Red Hat Bugzilla
https://bugzilla.redhat.com/show_bug.cgi?id=856276
--- Comment #12 from Fedora End Of Life <endoflife(a)fedoraproject.org> ---
Fedora 17 changed to end-of-life (EOL) status on 2013-07-30. Fedora 17 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.
If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version.
Thank you for reporting this bug and we are sorry it could not be fixed.
--
You are receiving this mail because:
You reported the bug.
10 years, 9 months