You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
7.2 KiB
183 lines
7.2 KiB
5 years ago
|
From fc028b3417349fd60a2ddd1aff1127a417df512b Mon Sep 17 00:00:00 2001
|
||
|
From: Jakub Filak <jfilak@redhat.com>
|
||
|
Date: Thu, 2 Jul 2015 15:04:06 +0200
|
||
|
Subject: [PATCH] lib: get possible events for problem_data_t
|
||
|
|
||
|
Certainly useful when we have no file system access to dump directories
|
||
|
and we only get a problem data via a D-Bus service.
|
||
|
|
||
|
Related: #1224984
|
||
|
|
||
|
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
||
|
---
|
||
|
src/include/run_event.h | 8 +++++++
|
||
|
src/lib/glib_support.c | 2 +-
|
||
|
src/lib/run_event.c | 56 +++++++++++++++++++++++++++++++++++--------------
|
||
|
3 files changed, 49 insertions(+), 17 deletions(-)
|
||
|
|
||
|
diff --git a/src/include/run_event.h b/src/include/run_event.h
|
||
|
index 7579e8f..bc43d4f 100644
|
||
|
--- a/src/include/run_event.h
|
||
|
+++ b/src/include/run_event.h
|
||
|
@@ -186,6 +186,9 @@ int run_event_on_problem_data(struct run_event_state *state, problem_data_t *dat
|
||
|
*/
|
||
|
char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx);
|
||
|
|
||
|
+/* Like list_possible_events but accepts problem_data_t */
|
||
|
+char *list_possible_events_problem_data(problem_data_t *pd, const char *dump_dir_name, const char *pfx);
|
||
|
+
|
||
|
/*
|
||
|
* Returns a list of possible events for given problem directory
|
||
|
*
|
||
|
@@ -195,6 +198,11 @@ char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const
|
||
|
GList *list_possible_events_glist(const char *problem_dir_name,
|
||
|
const char *pfx);
|
||
|
|
||
|
+/* Like list_possible_events_glist but accepts problem_data_t */
|
||
|
+GList *list_possible_events_problem_data_glist(problem_data_t *pd,
|
||
|
+ const char *problem_dir_name,
|
||
|
+ const char *pfx);
|
||
|
+
|
||
|
/* Command line run event callback implemenetation */
|
||
|
|
||
|
/*
|
||
|
diff --git a/src/lib/glib_support.c b/src/lib/glib_support.c
|
||
|
index 02c2dfd..2751b0c 100644
|
||
|
--- a/src/lib/glib_support.c
|
||
|
+++ b/src/lib/glib_support.c
|
||
|
@@ -92,7 +92,7 @@ GList *parse_list(const char* list)
|
||
|
|
||
|
char *tmp_list = xstrdup(list);
|
||
|
|
||
|
- GList *l = parse_delimited_list(list, LIST_DELIMITER);
|
||
|
+ GList *l = parse_delimited_list(tmp_list, LIST_DELIMITER);
|
||
|
|
||
|
free(tmp_list);
|
||
|
|
||
|
diff --git a/src/lib/run_event.c b/src/lib/run_event.c
|
||
|
index a56cf88..252c6bc 100644
|
||
|
--- a/src/lib/run_event.c
|
||
|
+++ b/src/lib/run_event.c
|
||
|
@@ -298,11 +298,17 @@ static int regcmp_lines(char *val, const char *regex)
|
||
|
static char* pop_next_command(GList **pp_rule_list,
|
||
|
char **pp_event_name, /* reports EVENT value thru this, if not NULL on entry */
|
||
|
struct dump_dir **pp_dd, /* use *pp_dd for access to dump dir, if non-NULL */
|
||
|
+ problem_data_t *pd, /* use *pp for access to problem data, if non-NULL */
|
||
|
const char *dump_dir_name,
|
||
|
const char *pfx,
|
||
|
unsigned pfx_len
|
||
|
)
|
||
|
{
|
||
|
+ /* It is an error to pass both, but we can recover from it and use only
|
||
|
+ * problem_data_t in that case */
|
||
|
+ if (pp_dd != NULL && pd != NULL)
|
||
|
+ error_msg("BUG: both dump dir and problem data passed to %s()", __func__);
|
||
|
+
|
||
|
char *command = NULL;
|
||
|
struct dump_dir *dd = pp_dd ? *pp_dd : NULL;
|
||
|
|
||
|
@@ -331,7 +337,7 @@ static char* pop_next_command(GList **pp_rule_list,
|
||
|
else
|
||
|
{
|
||
|
/* Read from dump dir and compare */
|
||
|
- if (!dd)
|
||
|
+ if (!dd && pd == NULL)
|
||
|
{
|
||
|
/* Without dir to match, we assume match for all conditions */
|
||
|
if (!dump_dir_name)
|
||
|
@@ -349,10 +355,15 @@ static char* pop_next_command(GList **pp_rule_list,
|
||
|
/* Is it "VAR!=VAL"? */
|
||
|
int inverted = (eq_sign > cond_str && eq_sign[-1] == '!');
|
||
|
char *var_name = xstrndup(cond_str, eq_sign - cond_str - (regex|inverted));
|
||
|
- char *real_val = dd_load_text_ext(dd, var_name, DD_FAIL_QUIETLY_ENOENT);
|
||
|
+ char *real_val = NULL;
|
||
|
+ char *free_me = NULL;
|
||
|
+ if (pd == NULL)
|
||
|
+ free_me = real_val = dd_load_text_ext(dd, var_name, DD_FAIL_QUIETLY_ENOENT);
|
||
|
+ else
|
||
|
+ real_val = problem_data_get_content_or_NULL(pd, var_name);
|
||
|
free(var_name);
|
||
|
int vals_differ = regex ? regcmp_lines(real_val, eq_sign + 1) : strcmp(real_val, eq_sign + 1);
|
||
|
- free(real_val);
|
||
|
+ free(free_me);
|
||
|
if (inverted)
|
||
|
vals_differ = !vals_differ;
|
||
|
|
||
|
@@ -422,6 +433,7 @@ int spawn_next_command(struct run_event_state *state,
|
||
|
char *cmd = pop_next_command(&state->rule_list,
|
||
|
NULL, /* don't return event_name */
|
||
|
NULL, /* NULL dd: we match by... */
|
||
|
+ NULL, /* no problem data */
|
||
|
dump_dir_name, /* ...dirname */
|
||
|
event, strlen(event)+1 /* for this event name exactly (not prefix) */
|
||
|
);
|
||
|
@@ -648,7 +660,8 @@ int run_event_on_problem_data(struct run_event_state *state, problem_data_t *dat
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
-char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx)
|
||
|
+
|
||
|
+static char *_list_possible_events(struct dump_dir **dd, problem_data_t *pd, const char *dump_dir_name, const char *pfx)
|
||
|
{
|
||
|
struct strbuf *result = strbuf_new();
|
||
|
|
||
|
@@ -661,7 +674,8 @@ char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const
|
||
|
char *event_name = NULL;
|
||
|
char *cmd = pop_next_command(&rule_list,
|
||
|
&event_name, /* return event_name */
|
||
|
- (dd ? &dd : NULL), /* match this dd... */
|
||
|
+ dd, /* match this dd... */
|
||
|
+ pd, /* no problem data */
|
||
|
dump_dir_name, /* ...or if NULL, this dirname */
|
||
|
pfx, pfx_len /* for events with this prefix */
|
||
|
);
|
||
|
@@ -695,24 +709,34 @@ char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const
|
||
|
return strbuf_free_nobuf(result);
|
||
|
}
|
||
|
|
||
|
+char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx)
|
||
|
+{
|
||
|
+ return _list_possible_events((dd ? &dd : NULL), NULL, dump_dir_name, pfx);
|
||
|
+}
|
||
|
+
|
||
|
+char *list_possible_events_problem_data(problem_data_t *pd, const char *dump_dir_name, const char *pfx)
|
||
|
+{
|
||
|
+ return _list_possible_events(NULL, pd, dump_dir_name, pfx);
|
||
|
+}
|
||
|
+
|
||
|
GList *list_possible_events_glist(const char *problem_dir_name,
|
||
|
const char *pfx)
|
||
|
{
|
||
|
struct dump_dir *dd = dd_opendir(problem_dir_name, DD_OPEN_READONLY);
|
||
|
- GList *l = NULL;
|
||
|
char *events = list_possible_events(dd, problem_dir_name, pfx);
|
||
|
- char *start = events;
|
||
|
- char *end = strchr(events, '\n');
|
||
|
+ GList *l = parse_delimited_list(events, "\n");
|
||
|
+ dd_close(dd);
|
||
|
+ free(events);
|
||
|
|
||
|
- while(end)
|
||
|
- {
|
||
|
- *end = '\0';
|
||
|
- l = g_list_append(l, xstrdup(start));
|
||
|
- start = end + 1;
|
||
|
- end = strchr(start, '\n');
|
||
|
- }
|
||
|
+ return l;
|
||
|
+}
|
||
|
|
||
|
- dd_close(dd);
|
||
|
+GList *list_possible_events_problem_data_glist(problem_data_t *pd,
|
||
|
+ const char *problem_dir_name,
|
||
|
+ const char *pfx)
|
||
|
+{
|
||
|
+ char *events = list_possible_events_problem_data(pd, problem_dir_name, pfx);
|
||
|
+ GList *l = parse_delimited_list(events, "\n");
|
||
|
free(events);
|
||
|
|
||
|
return l;
|
||
|
--
|
||
|
2.4.3
|
||
|
|