From ebad4b05134fcf1e7a1a2f4a2f5434ed9284d4e6 Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Thu, 11 Dec 2014 16:15:35 +0100
Subject: [PATCH] dump_dir: add function for creating a dump dir in dump
location
Related to abrt/abrt#548
Signed-off-by: Jakub Filak <jfilak@redhat.com>
---
src/include/dump_dir.h | 11 +++++
src/include/problem_data.h | 9 ++++
src/lib/create_dump_dir.c | 101 +++++++++++++++++++++++++++------------------
3 files changed, 81 insertions(+), 40 deletions(-)
diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h
index ed4c873..fbe2e31 100644
--- a/src/include/dump_dir.h
+++ b/src/include/dump_dir.h
@@ -165,6 +165,17 @@ int dump_dir_stat_for_uid(const char *dirname, uid_t uid);
*/
int dd_mark_as_notreportable(struct dump_dir *dd, const char *reason);
+typedef int (*save_data_call_back)(struct dump_dir *, void *args);
+
+/* Saves data in a new dump directory
+ *
+ * Creates a new dump directory in "problem dump location", adds the basic
+ * information to the new directory, calls given callback to allow callees to
+ * customize the dump dir contents (save problem data) and commits the dump
+ * directory (makes the directory visible for a problem daemon).
+ */
+struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type,
+ uid_t uid, save_data_call_back save_data, void *args);
#ifdef __cplusplus
}
#endif
diff --git a/src/include/problem_data.h b/src/include/problem_data.h
index 7a65d6c..661d31e 100644
--- a/src/include/problem_data.h
+++ b/src/include/problem_data.h
@@ -132,6 +132,15 @@ problem_data_t *create_problem_data_for_reporting(const char *dump_dir_name);
*/
struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name);
+/**
+ @brief Saves the problem data object in opened dump directory
+
+ @param dd Dump directory
+ @param problem_data Problem data object to save
+ @return 0 on success; otherwise non-zero value
+ */
+int save_problem_data_in_dump_dir(struct dump_dir *dd, problem_data_t *problem_data);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/create_dump_dir.c b/src/lib/create_dump_dir.c
index 4f67523..9f312e0 100644
--- a/src/lib/create_dump_dir.c
+++ b/src/lib/create_dump_dir.c
@@ -30,36 +30,10 @@ static struct dump_dir *try_dd_create(const char *base_dir_name, const char *dir
return dd;
}
-struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name)
+struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type, uid_t uid, save_data_call_back save_data, void *args)
{
INITIALIZE_LIBREPORT();
- char *type = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER);
-
- if (!type)
- {
- error_msg(_("Missing required item: '%s'"), FILENAME_ANALYZER);
- return NULL;
- }
-
- uid_t uid = (uid_t)-1L;
- char *uid_str = problem_data_get_content_or_NULL(problem_data, FILENAME_UID);
-
- if (uid_str)
- {
- char *endptr;
- errno = 0;
- long val = strtol(uid_str, &endptr, 10);
-
- if (errno != 0 || endptr == uid_str || *endptr != '\0' || INT_MAX < val)
- {
- error_msg(_("uid value is not valid: '%s'"), uid_str);
- return NULL;
- }
-
- uid = (uid_t)val;
- }
-
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0)
{
@@ -99,6 +73,34 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
if (!dd) /* try_dd_create() already emitted the error message */
goto ret;
+ if (save_data(dd, args))
+ {
+ dd_delete(dd);
+ dd = NULL;
+ goto ret;
+ }
+
+ /* need to create basic files AFTER we save the pd to dump_dir
+ * otherwise we can't skip already created files like in case when
+ * reporting from anaconda where we can't read /etc/{system,redhat}-release
+ * and os_release is taken from anaconda
+ */
+ dd_create_basic_files(dd, uid, NULL);
+
+ problem_id[strlen(problem_id) - strlen(NEW_PD_SUFFIX)] = '\0';
+ char* new_path = concat_path_file(base_dir_name, problem_id);
+ log_info("Renaming from '%s' to '%s'", dd->dd_dirname, new_path);
+ dd_rename(dd, new_path);
+
+ ret:
+ free(problem_id);
+ return dd;
+}
+
+int save_problem_data_in_dump_dir(struct dump_dir *dd, problem_data_t *problem_data)
+{
+ INITIALIZE_LIBREPORT();
+
GHashTableIter iter;
char *name;
struct problem_item *value;
@@ -129,19 +131,38 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
dd_save_text(dd, name, value->content);
}
- /* need to create basic files AFTER we save the pd to dump_dir
- * otherwise we can't skip already created files like in case when
- * reporting from anaconda where we can't read /etc/{system,redhat}-release
- * and os_release is taken from anaconda
- */
- dd_create_basic_files(dd, uid, NULL);
+ return 0;
+}
- problem_id[strlen(problem_id) - strlen(NEW_PD_SUFFIX)] = '\0';
- char* new_path = concat_path_file(base_dir_name, problem_id);
- log_info("Renaming from '%s' to '%s'", dd->dd_dirname, new_path);
- dd_rename(dd, new_path);
+struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name)
+{
+ INITIALIZE_LIBREPORT();
- ret:
- free(problem_id);
- return dd;
+ char *type = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER);
+
+ if (!type)
+ {
+ error_msg(_("Missing required item: '%s'"), FILENAME_ANALYZER);
+ return NULL;
+ }
+
+ uid_t uid = (uid_t)-1L;
+ char *uid_str = problem_data_get_content_or_NULL(problem_data, FILENAME_UID);
+
+ if (uid_str)
+ {
+ char *endptr;
+ errno = 0;
+ long val = strtol(uid_str, &endptr, 10);
+
+ if (errno != 0 || endptr == uid_str || *endptr != '\0' || INT_MAX < val)
+ {
+ error_msg(_("uid value is not valid: '%s'"), uid_str);
+ return NULL;
+ }
+
+ uid = (uid_t)val;
+ }
+
+ return create_dump_dir(base_dir_name, type, uid, (save_data_call_back)save_problem_data_in_dump_dir, problem_data);
}
--
2.1.0