[ABRT PATCH 1/2] a-d-oops: add 'update' command line argument

Jakub Filak jfilak at redhat.com
Wed Jun 5 11:51:58 UTC 2013


If the argument (-u PROBLEM) is used, abrt-dump-oops saves the data
obtained from input in the passed problem directory.

Related to #662

Signed-off-by: Jakub Filak <jfilak at redhat.com>
---
 src/plugins/abrt-dump-oops.c | 129 +++++++++++++++++++++++++++----------------
 1 file changed, 80 insertions(+), 49 deletions(-)

diff --git a/src/plugins/abrt-dump-oops.c b/src/plugins/abrt-dump-oops.c
index 2c8612e..6c4e8eb 100644
--- a/src/plugins/abrt-dump-oops.c
+++ b/src/plugins/abrt-dump-oops.c
@@ -108,6 +108,56 @@ static char *list_of_tainted_modules(const char *proc_modules)
     return strbuf_free_nobuf(result);
 }
 
+static void save_oops_data_in_dump_dir(struct dump_dir *dd, char *oops, const char *proc_modules)
+{
+    char *first_line = oops;
+    char *second_line = (char*)strchr(first_line, '\n'); /* never NULL */
+    *second_line++ = '\0';
+
+    dd_save_text(dd, FILENAME_KERNEL, first_line);
+    dd_save_text(dd, FILENAME_BACKTRACE, second_line);
+
+    /* check if trace doesn't have line: 'Your BIOS is broken' */
+    char *broken_bios = strstr(second_line, "Your BIOS is broken");
+    if (broken_bios)
+        dd_save_text(dd, FILENAME_NOT_REPORTABLE, "Your BIOS is broken.");
+    else
+    {
+        char *tainted_short = kernel_tainted_short(second_line);
+        if (tainted_short)
+        {
+            VERB1 log("Kernel is tainted '%s'", tainted_short);
+            dd_save_text(dd, FILENAME_TAINTED_SHORT, tainted_short);
+
+            char *tnt_long = kernel_tainted_long(tainted_short);
+            dd_save_text(dd, FILENAME_TAINTED_LONG, tnt_long);
+            free(tnt_long);
+
+            struct strbuf *reason = strbuf_new();
+            const char *fmt = _("A kernel problem occurred, but your kernel has been "
+                    "tainted (flags:%s). Kernel maintainers are unable to "
+                    "diagnose tainted reports.");
+            strbuf_append_strf(reason, fmt, tainted_short);
+
+            char *modlist = !proc_modules ? NULL : list_of_tainted_modules(proc_modules);
+            if (modlist)
+            {
+                strbuf_append_strf(reason, _(" Tainted modules: %s."), modlist);
+                free(modlist);
+            }
+
+            dd_save_text(dd, FILENAME_NOT_REPORTABLE, reason->buf);
+            strbuf_free(reason);
+            free(tainted_short);
+        }
+    }
+
+    // TODO: add "Kernel oops: " prefix, so that all oopses have recognizable FILENAME_REASON?
+    // kernel oops 1st line may look quite puzzling otherwise...
+    strchrnul(second_line, '\n')[0] = '\0';
+    dd_save_text(dd, FILENAME_REASON, second_line);
+}
+
 /* returns number of errors */
 static unsigned save_oops_to_dump_dir(GList *oops_list, unsigned oops_cnt)
 {
@@ -137,10 +187,6 @@ static unsigned save_oops_to_dump_dir(GList *oops_list, unsigned oops_cnt)
     unsigned errors = 0;
     while (idx < oops_cnt && --countdown != 0)
     {
-        char *first_line = (char*)g_list_nth_data(oops_list, idx++);
-        char *second_line = (char*)strchr(first_line, '\n'); /* never NULL */
-        *second_line++ = '\0';
-
         struct dump_dir *dd;
         {
             char base[sizeof("oops-YYYY-MM-DD-hh:mm:ss-%lu-%lu") + 2 * sizeof(long)*3];
@@ -152,12 +198,11 @@ static unsigned save_oops_to_dump_dir(GList *oops_list, unsigned oops_cnt)
 
         if (dd)
         {
+            save_oops_data_in_dump_dir(dd, (char*)g_list_nth_data(oops_list, idx++), proc_modules);
             dd_create_basic_files(dd, /*uid:*/ my_euid, NULL);
             dd_save_text(dd, FILENAME_ABRT_VERSION, VERSION);
             dd_save_text(dd, FILENAME_ANALYZER, "Kerneloops");
             dd_save_text(dd, FILENAME_TYPE, "Kerneloops");
-            dd_save_text(dd, FILENAME_KERNEL, first_line);
-            dd_save_text(dd, FILENAME_BACKTRACE, second_line);
             if (cmdline_str)
                 dd_save_text(dd, FILENAME_CMDLINE, cmdline_str);
             if (proc_modules)
@@ -166,46 +211,6 @@ static unsigned save_oops_to_dump_dir(GList *oops_list, unsigned oops_cnt)
                 dd_save_text(dd, "fips_enabled", fips_enabled);
             if (suspend_stats)
                 dd_save_text(dd, "suspend_stats", suspend_stats);
-
-            /* check if trace doesn't have line: 'Your BIOS is broken' */
-            char *broken_bios = strstr(second_line, "Your BIOS is broken");
-            if (broken_bios)
-                dd_save_text(dd, FILENAME_NOT_REPORTABLE, "Your BIOS is broken.");
-            else
-            {
-                char *tainted_short = kernel_tainted_short(second_line);
-                if (tainted_short)
-                {
-                    VERB1 log("Kernel is tainted '%s'", tainted_short);
-                    dd_save_text(dd, FILENAME_TAINTED_SHORT, tainted_short);
-
-                    char *tnt_long = kernel_tainted_long(tainted_short);
-                    dd_save_text(dd, FILENAME_TAINTED_LONG, tnt_long);
-                    free(tnt_long);
-
-                    struct strbuf *reason = strbuf_new();
-                    const char *fmt = _("A kernel problem occurred, but your kernel has been "
-                                 "tainted (flags:%s). Kernel maintainers are unable to "
-                                 "diagnose tainted reports.");
-                    strbuf_append_strf(reason, fmt, tainted_short);
-
-                    char *modlist = !proc_modules ? NULL : list_of_tainted_modules(proc_modules);
-                    if (modlist)
-                    {
-                        strbuf_append_strf(reason, _(" Tainted modules: %s."), modlist);
-                        free(modlist);
-                    }
-
-                    dd_save_text(dd, FILENAME_NOT_REPORTABLE, reason->buf);
-                    strbuf_free(reason);
-                    free(tainted_short);
-                }
-            }
-
-// TODO: add "Kernel oops: " prefix, so that all oopses have recognizable FILENAME_REASON?
-// kernel oops 1st line may look quite puzzling otherwise...
-            strchrnul(second_line, '\n')[0] = '\0';
-            dd_save_text(dd, FILENAME_REASON, second_line);
             dd_close(dd);
         }
         else
@@ -233,7 +238,7 @@ int main(int argc, char **argv)
 
     /* Can't keep these strings/structs static: _() doesn't support that */
     const char *program_usage_string = _(
-        "& [-vsoxm] [-d DIR]/[-D] [FILE]\n"
+        "& [-vusoxm] [-d DIR]/[-D] [FILE]\n"
         "\n"
         "Extract oops from FILE (or standard input)"
     );
@@ -243,9 +248,11 @@ int main(int argc, char **argv)
         OPT_o = 1 << 2,
         OPT_d = 1 << 3,
         OPT_D = 1 << 4,
-        OPT_x = 1 << 5,
-        OPT_m = 1 << 6,
+        OPT_u = 1 << 5,
+        OPT_x = 1 << 6,
+        OPT_m = 1 << 7,
     };
+    char *problem_dir = NULL;
     /* Keep enum above and order of options below in sync! */
     struct options program_options[] = {
         OPT__VERBOSE(&g_verbose),
@@ -256,6 +263,7 @@ int main(int argc, char **argv)
          */
         OPT_STRING('d', NULL, &debug_dumps_dir, "DIR", _("Create new problem directory in DIR for every oops found")),
         OPT_BOOL(  'D', NULL, NULL, _("Same as -d DumpLocation, DumpLocation is specified in abrt.conf")),
+        OPT_STRING('u', NULL, &problem_dir, "PROBLEM", _("Save the extracted information in PROBLEM")),
         OPT_BOOL(  'x', NULL, NULL, _("Make the problem directory world readable")),
         OPT_BOOL(  'm', NULL, NULL, _("Print search string(s) to stdout and exit")),
         OPT_END()
@@ -337,6 +345,29 @@ int main(int argc, char **argv)
                     oops_cnt
             );
         }
+        if (opts & OPT_u)
+        {
+            log("Updating problem directory");
+            switch(g_list_length(oops_list))
+            {
+                case 0:
+                    error_msg(_("Cannot update the problem because of no oops found"));
+                    break;
+                case 1:
+                    {
+                        struct dump_dir *dd = dd_opendir(problem_dir, /*open for writing*/0);
+                        if (dd)
+                        {
+                            save_oops_data_in_dump_dir(dd, (char *)oops_list->data, /*no proc modules*/NULL);
+                            dd_close(dd);
+                        }
+                    }
+                    break;
+                default:
+                    error_msg(_("Cannot update the problem because of more oopses were found"));
+                    break;
+            }
+       }
     }
     list_free_with_free(oops_list);
     //oops_list = NULL;
-- 
1.8.1.4



More information about the Crash-catcher mailing list