diff options
author | Jiri Moskovcak <jmoskovc@redhat.com> | 2011-05-19 14:42:13 +0200 |
---|---|---|
committer | Jiri Moskovcak <jmoskovc@redhat.com> | 2011-05-19 14:42:13 +0200 |
commit | 5ca690225fd1c3fb449b3cbeb1002aae9f951d28 (patch) | |
tree | 3b2e91837fe308adc0e20d4544caa66e41131a8a /src | |
parent | 44cb00d8c979298c0818355d975c9cf80d75cd8e (diff) | |
parent | 51c400f11460957ac4cee17acdda79b42606b10c (diff) | |
download | abrt-5ca690225fd1c3fb449b3cbeb1002aae9f951d28.tar.gz abrt-5ca690225fd1c3fb449b3cbeb1002aae9f951d28.tar.xz abrt-5ca690225fd1c3fb449b3cbeb1002aae9f951d28.zip |
Merge branch 'master' of git://git.fedorahosted.org/git/abrt
Diffstat (limited to 'src')
-rw-r--r-- | src/cli/cli.c | 23 | ||||
-rw-r--r-- | src/gui-wizard-gtk/wizard.c | 127 | ||||
-rw-r--r-- | src/gui-wizard-gtk/wizard.glade | 74 | ||||
-rw-r--r-- | src/include/abrt_problem_data.h | 3 | ||||
-rw-r--r-- | src/include/abrtlib.h | 6 | ||||
-rw-r--r-- | src/include/report/problem_data.h | 18 | ||||
-rw-r--r-- | src/lib/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/kernel-tainted.c | 143 | ||||
-rw-r--r-- | src/lib/make_descr.c | 1 | ||||
-rw-r--r-- | src/lib/problem_data.c | 8 | ||||
-rw-r--r-- | src/plugins/abrt-action-bugzilla.c | 84 | ||||
-rw-r--r-- | src/plugins/abrt-action-bugzilla.txt | 77 | ||||
-rw-r--r-- | src/plugins/abrt-action-install-debuginfo | 35 | ||||
-rw-r--r-- | src/plugins/abrt-action-rhtsupport.c | 2 | ||||
-rw-r--r-- | src/plugins/abrt-dump-oops.c | 14 | ||||
-rw-r--r-- | src/plugins/rhbz.c | 19 |
16 files changed, 398 insertions, 237 deletions
diff --git a/src/cli/cli.c b/src/cli/cli.c index 3981c1bc..0e4ce98c 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -23,6 +23,29 @@ #include "abrt_dbus.h" #include "report.h" + +/* Vector of problems: */ +/* problem_data_vector[i] = { "name" = { "content", CD_FLAG_foo_bits } } */ + +typedef GPtrArray vector_of_problem_data_t; + +static inline problem_data_t *get_problem_data(vector_of_problem_data_t *vector, unsigned i) +{ + return (problem_data_t *)g_ptr_array_index(vector, i); +} + +static void free_vector_of_problem_data(vector_of_problem_data_t *vector) +{ + if (vector) + g_ptr_array_free(vector, TRUE); +} + +static vector_of_problem_data_t *new_vector_of_problem_data(void) +{ + return g_ptr_array_new_with_free_func((void (*)(void*)) &free_problem_data); +} + + static problem_data_t *FillCrashInfo(const char *dump_dir_name) { int sv_logmode = logmode; diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c index 426dfb8a..1585b004 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -25,6 +25,9 @@ #define DEFAULT_WIDTH 800 #define DEFAULT_HEIGHT 500 +#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 22 +# define gtk_assistant_commit(...) ((void)0) +#endif typedef struct event_gui_data_t { @@ -72,7 +75,6 @@ enum { DETAIL_COLUMN_NAME, DETAIL_COLUMN_VALUE, - //COLUMN_PATH, DETAIL_NUM_COLUMNS, }; @@ -102,6 +104,8 @@ enum { PAGENO_BACKTRACE_APPROVAL, PAGENO_REPORT, PAGENO_REPORT_PROGRESS, + PAGENO_REPORT_DONE, + PAGENO_NOT_SHOWN, }; /* Use of arrays (instead of, say, #defines to C strings) @@ -116,6 +120,8 @@ static const gchar PAGE_REPORTER_SELECTOR[] = "page_4_report"; static const gchar PAGE_BACKTRACE_APPROVAL[] = "page_5"; static const gchar PAGE_REPORT[] = "page_6_report"; static const gchar PAGE_REPORT_PROGRESS[] = "page_7_report"; +static const gchar PAGE_REPORT_DONE[] = "page_8_report"; +static const gchar PAGE_NOT_SHOWN[] = "page_9_report"; static const gchar *const page_names[] = { @@ -127,6 +133,8 @@ static const gchar *const page_names[] = PAGE_BACKTRACE_APPROVAL, PAGE_REPORT, PAGE_REPORT_PROGRESS, + PAGE_REPORT_DONE, + PAGE_NOT_SHOWN, NULL }; @@ -159,7 +167,11 @@ static page_obj_t pages[] = { PAGE_BACKTRACE_APPROVAL , "Review the backtrace" , GTK_ASSISTANT_PAGE_CONTENT }, { PAGE_REPORT , "Confirm data to report", GTK_ASSISTANT_PAGE_CONFIRM }, /* Was GTK_ASSISTANT_PAGE_PROGRESS */ - { PAGE_REPORT_PROGRESS , "Reporting" , GTK_ASSISTANT_PAGE_SUMMARY }, + { PAGE_REPORT_PROGRESS , "Reporting" , GTK_ASSISTANT_PAGE_CONTENT }, + { PAGE_REPORT_DONE , "Reporting done" , GTK_ASSISTANT_PAGE_CONTENT }, + /* We prevent user from reaching this page, as it can't be navigated away, + * and we don't want that */ + { PAGE_NOT_SHOWN , "" , GTK_ASSISTANT_PAGE_SUMMARY }, { NULL } }; @@ -292,7 +304,7 @@ static void save_text_from_text_view(GtkTextView *tv, const char *name) free(new_str); } -static void append_to_textview(GtkTextView *tv, const char *str, int len) +static void append_to_textview(GtkTextView *tv, const char *str) { GtkTextBuffer *tb = gtk_text_view_get_buffer(tv); @@ -301,7 +313,7 @@ static void append_to_textview(GtkTextView *tv, const char *str, int len) gtk_text_buffer_get_iter_at_offset(tb, &text_iter, -1); gtk_text_buffer_place_cursor(tb, &text_iter); - gtk_text_buffer_insert_at_cursor(tb, str, len >= 0 ? len : strlen(str)); + gtk_text_buffer_insert_at_cursor(tb, str, strlen(str)); /* Scroll so that the end of the log is visible */ gtk_text_buffer_get_iter_at_offset(tb, &text_iter, -1); @@ -390,7 +402,6 @@ static void tv_details_cursor_changed( */ g_object_set(G_OBJECT(g_tv_details_col2), "editable", editable, - // "editable-set", editable, NULL); } @@ -575,9 +586,6 @@ static event_gui_data_t *add_event_buttons(GtkBox *box, event_gui_data->toggle_button = GTK_TOGGLE_BUTTON(button); *p_event_list = g_list_append(*p_event_list, event_gui_data); - //if (!first_button) - // first_button = event_gui_data; - if (!active_button) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true); @@ -604,7 +612,7 @@ static void append_item_to_ls_details(gpointer name, gpointer value, gpointer da gtk_list_store_append(g_ls_details, &iter); stats->filecount++; - //FIXME: use the value representation here + //FIXME: use the human-readable format_problem_item(item) instead of item->content. /* If text and not multiline... */ if (item->flags & CD_FLAG_TXT) { @@ -614,7 +622,6 @@ static void append_item_to_ls_details(gpointer name, gpointer value, gpointer da gtk_list_store_set(g_ls_details, &iter, DETAIL_COLUMN_NAME, (char *)name, DETAIL_COLUMN_VALUE, item->content, - //DETAIL_COLUMN_PATH, xasprintf("%s%s", g_dump_dir_name, name), -1); } else @@ -622,9 +629,7 @@ static void append_item_to_ls_details(gpointer name, gpointer value, gpointer da gtk_list_store_set(g_ls_details, &iter, DETAIL_COLUMN_NAME, (char *)name, DETAIL_COLUMN_VALUE, _("(click here to view/edit)"), - //DETAIL_COLUMN_PATH, xasprintf("%s%s", g_dump_dir_name, name), -1); - //WARNING: will leak xasprintf results above if uncommented } } else if (item->flags & CD_FLAG_BIN) @@ -637,7 +642,6 @@ static void append_item_to_ls_details(gpointer name, gpointer value, gpointer da gtk_list_store_set(g_ls_details, &iter, DETAIL_COLUMN_NAME, (char *)name, DETAIL_COLUMN_VALUE, msg, - //DETAIL_COLUMN_PATH, xasprintf("%s%s", g_dump_dir_name, name), -1); free(msg); } @@ -842,7 +846,7 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g while ((r = read(evd->fd, buf, sizeof(buf)-1)) > 0) { buf[r] = '\0'; - append_to_textview(evd->tv_log, buf, r); + append_to_textview(evd->tv_log, buf); save_to_event_log(evd, buf); } @@ -872,9 +876,10 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g evd->event_log_state = LOGSTATE_ERRLINE; char *msg; if (WIFSIGNALED(status)) - msg = xasprintf("(killed by signal %d)\n", WTERMSIG(status)); + msg = xasprintf("(killed by signal %u)\n", WTERMSIG(status)); else - msg = xasprintf("(exited with %d)\n", retval); + msg = xasprintf("(exited with %u)\n", retval); + append_to_textview(evd->tv_log, msg); save_to_event_log(evd, msg); free(msg); } @@ -900,10 +905,7 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g || spawn_next_command_in_evd(evd) < 0 ) { VERB1 log("done running event on '%s': %d", g_dump_dir_name, retval); -//append_to_textview(evd->tv_log, msg); - - /* Inform abrt-gui that it is a good idea to rescan the directory */ - kill(getppid(), SIGCHLD); + append_to_textview(evd->tv_log, "\n"); for (;;) { @@ -912,15 +914,9 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g char *msg = xasprintf(evd->end_msg, retval); gtk_label_set_text(evd->status_label, msg); free(msg); - /* Unfreeze assistant - * we can't allow user to continue if analyze action fails - * i.e: if gdb fails to generate backtrace -//TODO: generic solution instead of special-casing on event name! - */ - if (retval == 0 || (strncmp(evd->event_name, "analyze", strlen("analyze")) != 0)) - { - gtk_assistant_set_page_complete(g_assistant, evd->page_widget, true); - } + + /* Hide "Back" button */ + gtk_assistant_commit(g_assistant); /* Enable (un-gray out) navigation buttons */ gtk_widget_set_sensitive(GTK_WIDGET(g_assistant), true); @@ -933,6 +929,9 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g reload_problem_data_from_dump_dir(); update_gui_state_from_problem_data(); + /* Inform abrt-gui that it is a good idea to rescan the directory */ + kill(getppid(), SIGCHLD); + return FALSE; /* "please remove this event" */ } @@ -943,11 +942,12 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g && spawn_next_command_in_evd(evd) >= 0 ) { VERB1 log("running event '%s' on '%s'", evd->event_name, g_dump_dir_name); + char *msg = xasprintf("--- Running %s ---\n", event_name); + append_to_textview(evd->tv_log, msg); + free(msg); break; } /* No commands needed?! (This is untypical) */ -//TODO: msg? -//append_to_textview(evd->tv_log, msg); } } @@ -1002,8 +1002,6 @@ static void start_event_run(const char *event_name, goto no_cmds; } - VERB1 log("running event '%s' on '%s'", event_name, g_dump_dir_name); - /* At least one command is needed, and we started first one. * Hook its output fd to the main loop. */ @@ -1027,10 +1025,13 @@ static void start_event_run(const char *event_name, ); gtk_label_set_text(status_label, start_msg); + + VERB1 log("running event '%s' on '%s'", event_name, g_dump_dir_name); //TODO: save_to_event_log(evd, "message that we run event foo")? + char *msg = xasprintf("--- Running %s ---\n", event_name); + append_to_textview(evd->tv_log, msg, strlen(msg)); + free(msg); - /* Freeze assistant so it can't move away from the page until event run is done */ - gtk_assistant_set_page_complete(g_assistant, page, false); /* Disable (gray out) navigation buttons */ gtk_widget_set_sensitive(GTK_WIDGET(g_assistant), false); } @@ -1051,7 +1052,7 @@ static void add_warning(const char *warning) gtk_widget_show(warning_lbl); } -static void check_backtrace_and_allow_send(void) //TODO: rename, this checks rating, not backtrace +static void check_bt_rating_and_allow_send(void) { bool send = true; bool warn = false; @@ -1062,18 +1063,19 @@ static void check_backtrace_and_allow_send(void) //TODO: rename, this checks rat /* * FIXME: this should be bind to a reporter not to a compoment - * but so far only oopses doesn't have rating, so for now we + * but so far only oopses don't have rating, so for now we * skip the "kernel" manually */ const char *component = get_problem_item_content_or_NULL(g_cd, FILENAME_COMPONENT); +//FIXME: say "no" to special casing! if (strcmp(component, "kernel") != 0) { const char *rating = get_problem_item_content_or_NULL(g_cd, FILENAME_RATING); if (rating) switch (*rating) { - case '4': //bt is ok - no warning here + case '4': /* bt is ok - no warning here */ break; - case '3': //bt is usable, but not complete, so show a warning + case '3': /* bt is usable, but not complete, so show a warning */ add_warning(_("The backtrace is incomplete, please make sure you provide the steps to reproduce.")); warn = true; break; @@ -1103,7 +1105,7 @@ static void check_backtrace_and_allow_send(void) //TODO: rename, this checks rat static void on_bt_approve_toggle(GtkToggleButton *togglebutton, gpointer user_data) { - check_backtrace_and_allow_send(); + check_bt_rating_and_allow_send(); } static void on_comment_changed(GtkTextBuffer *buffer, gpointer user_data) @@ -1204,7 +1206,7 @@ static void on_page_prepare(GtkAssistant *assistant, GtkWidget *page, gpointer u { if (pages[PAGENO_BACKTRACE_APPROVAL].page_widget == page) { - check_backtrace_and_allow_send(); + check_bt_rating_and_allow_send(); } /* Save text fields if changed */ @@ -1226,6 +1228,9 @@ static void on_page_prepare(GtkAssistant *assistant, GtkWidget *page, gpointer u if (pages[PAGENO_COMMENT].page_widget == page) on_comment_changed(gtk_text_view_get_buffer(g_tv_comment), NULL); + + if (pages[PAGENO_REPORT_DONE].page_widget == page) + gtk_assistant_commit(g_assistant); } static gint select_next_page_no(gint current_page_no, gpointer data) @@ -1283,6 +1288,11 @@ static gint select_next_page_no(gint current_page_no, gpointer data) goto again; } break; + case PAGENO_NOT_SHOWN: + /* No! this would SEGV (infinitely recurse into select_next_page_no) */ + /*gtk_assistant_commit(g_assistant);*/ + current_page_no = PAGENO_ANALYZE_SELECTOR-1; + goto again; } VERB2 log("%s: selected page #%d", __func__, current_page_no); @@ -1314,7 +1324,7 @@ static gboolean highlight_search(gpointer user_data) gtk_text_buffer_get_iter_at_offset(buffer, &start_find, offset); } - //returning false will make glib to remove this event + /* returning false will make glib to remove this event */ return false; } @@ -1395,17 +1405,15 @@ static void add_pages() for (i = 0; page_names[i] != NULL; i++) { char *delim = strrchr(page_names[i], '_'); - if(delim != NULL) + if (delim != NULL) { - if (g_report_only && (strncmp(delim+1, "report", strlen("report"))) != 0) + if (g_report_only && (strncmp(delim + 1, "report", strlen("report"))) != 0) { pages[i].page_widget = NULL; continue; } } GtkWidget *page = GTK_WIDGET(gtk_builder_get_object(builder, page_names[i])); - if (page == NULL) - continue; pages[i].page_widget = page; added_pages[page_no++] = &pages[i]; @@ -1423,6 +1431,7 @@ static void add_pages() VERB1 log("added page: %s", page_names[i]); } + /* Set pointers to objects we might need to work with */ g_lbl_cd_reason = GTK_LABEL( gtk_builder_get_object(builder, "lbl_cd_reason")); g_box_analyzers = GTK_BOX( gtk_builder_get_object(builder, "vb_analyzers")); @@ -1448,27 +1457,31 @@ static void add_pages() gtk_widget_modify_font(GTK_WIDGET(g_tv_analyze_log), monospace_font); gtk_widget_modify_font(GTK_WIDGET(g_tv_report_log), monospace_font); gtk_widget_modify_font(GTK_WIDGET(g_tv_backtrace), monospace_font); - //make_label_autowrap_on_resize(g_lbl_cd_reason); fix_all_wrapped_labels(GTK_WIDGET(g_assistant)); - ///* hide the warnings by default */ - //gtk_widget_hide(g_widget_warnings_area); - - //gtk_assistant_set_page_complete(g_assistant, pages[PAGENO_REPORTER_SELECTOR].page_widget, false); if (pages[PAGENO_BACKTRACE_APPROVAL].page_widget != NULL) gtk_assistant_set_page_complete(g_assistant, pages[PAGENO_BACKTRACE_APPROVAL].page_widget, gtk_toggle_button_get_active(g_tb_approve_bt)); - /* configure btn on select analyzers page */ + /* Configure btn on select analyzers page */ GtkWidget *config_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button_cfg1")); if (config_btn) g_signal_connect(G_OBJECT(config_btn), "clicked", G_CALLBACK(on_show_event_list_cb), NULL); - /* configure btn on select reporters page */ + /* Configure btn on select reporters page */ config_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button_cfg2")); if (config_btn) g_signal_connect(G_OBJECT(config_btn), "clicked", G_CALLBACK(on_show_event_list_cb), NULL); + /* Add "Close" button */ + GtkWidget *w; + w = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + g_signal_connect(w, "clicked", G_CALLBACK(gtk_main_quit), NULL); + gtk_widget_show(w); + gtk_assistant_add_action_widget(g_assistant, w); + /* and hide "Cancel" button - "Close" is a better name for what we want */ + gtk_assistant_commit(g_assistant); + /* Set color of the comment evenbox */ GdkColor color; gdk_color_parse("#CC3333", &color); @@ -1505,8 +1518,6 @@ void create_assistant(void) g_ls_details = gtk_list_store_new(DETAIL_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model(g_tv_details, GTK_TREE_MODEL(g_ls_details)); -// gtk_builder_connect_signals(builder, NULL); - g_signal_connect(g_tb_approve_bt, "toggled", G_CALLBACK(on_bt_approve_toggle), NULL); g_signal_connect(g_btn_refresh, "clicked", G_CALLBACK(on_btn_refresh_clicked), NULL); g_signal_connect(gtk_text_view_get_buffer(g_tv_comment), "changed", G_CALLBACK(on_comment_changed), NULL); @@ -1519,10 +1530,4 @@ void create_assistant(void) /* found items background */ gtk_text_buffer_create_tag(backtrace_buf, "search_result_bg", "background", "red", NULL); g_signal_connect(g_search_entry_bt, "changed", G_CALLBACK(search_timeout), NULL); - - if (pages[PAGENO_BACKTRACE_APPROVAL].page_widget != NULL) - gtk_assistant_set_page_complete(g_assistant, - pages[PAGENO_BACKTRACE_APPROVAL].page_widget, - gtk_toggle_button_get_active(g_tb_approve_bt) - ); } diff --git a/src/gui-wizard-gtk/wizard.glade b/src/gui-wizard-gtk/wizard.glade index f79950ee..49acd67d 100644 --- a/src/gui-wizard-gtk/wizard.glade +++ b/src/gui-wizard-gtk/wizard.glade @@ -51,7 +51,7 @@ <object class="GtkScrolledWindow" id="container_details1"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="shadow_type">out</property> + <property name="shadow_type">GTK_SHADOW_OUT</property> <child> <object class="GtkTreeView" id="tv_details"> <property name="visible">True</property> @@ -275,7 +275,7 @@ <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="shadow_type">out</property> + <property name="shadow_type">GTK_SHADOW_OUT</property> <child> <object class="GtkTextView" id="tv_analyze_log"> <property name="visible">True</property> @@ -404,7 +404,7 @@ <object class="GtkScrolledWindow" id="scrolledwindow2"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="shadow_type">out</property> + <property name="shadow_type">GTK_SHADOW_OUT</property> <child> <object class="GtkTextView" id="tv_backtrace"> <property name="visible">True</property> @@ -674,7 +674,7 @@ <object class="GtkScrolledWindow" id="container_details2"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="shadow_type">out</property> + <property name="shadow_type">GTK_SHADOW_OUT</property> <child> <placeholder/> </child> @@ -715,7 +715,7 @@ <object class="GtkScrolledWindow" id="scrolledwindow6"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="shadow_type">out</property> + <property name="shadow_type">GTK_SHADOW_OUT</property> <child> <object class="GtkTextView" id="tv_report_log"> <property name="visible">True</property> @@ -734,4 +734,68 @@ </object> </child> </object> + <object class="GtkWindow" id="window8"> + <property name="can_focus">False</property> + <child> + <object class="GtkVBox" id="page_8_report"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">10</property> + <property name="spacing">3</property> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">Reporting has finished. You can close this window now.</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">If you want to report the problem to a different destination, collect additional information, or provide a better problem description and repeat reporting process, press 'Forward'.</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + </child> + </object> + <object class="GtkWindow" id="window9"> + <property name="can_focus">False</property> + <child> + <object class="GtkVBox" id="page_9_report"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">10</property> + <property name="spacing">3</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + </child> + </object> </interface> diff --git a/src/include/abrt_problem_data.h b/src/include/abrt_problem_data.h index 795c2404..2fa540e3 100644 --- a/src/include/abrt_problem_data.h +++ b/src/include/abrt_problem_data.h @@ -58,6 +58,9 @@ // Optional. Set to "1" by abrt-handle-upload for every unpacked dump #define FILENAME_REMOTE "remote" #define FILENAME_TAINTED "kernel_tainted" +#define FILENAME_TAINTED_SHORT "kernel_tainted_short" +#define FILENAME_TAINTED_LONG "kernel_tainted_long" +// TODO: TicketUploader also has open-coded "TICKET", "CUSTOMER" files #define FILENAME_UUID "uuid" #define FILENAME_COUNT "count" diff --git a/src/include/abrtlib.h b/src/include/abrtlib.h index 294afdda..5d03ee49 100644 --- a/src/include/abrtlib.h +++ b/src/include/abrtlib.h @@ -283,6 +283,12 @@ bool load_conf_file(const char *pPath, map_string_h *settings, bool skipKeysWith #define steal_directory abrt_steal_directory struct dump_dir *steal_directory(const char *base_dir, const char *dump_dir_name); +#define kernel_tainted_short abrt_kernel_tainted_short +char *kernel_tainted_short(unsigned tainted); + +#define kernel_tainted_long abrt_kernel_tainted_long +GList *kernel_tainted_long(unsigned tainted); + #ifdef __cplusplus } #endif diff --git a/src/include/report/problem_data.h b/src/include/report/problem_data.h index c805c37a..f7178077 100644 --- a/src/include/report/problem_data.h +++ b/src/include/report/problem_data.h @@ -45,6 +45,7 @@ typedef struct problem_item problem_item; char *format_problem_item(struct problem_item *item); + /* In-memory problem data structure and accessors */ typedef GHashTable problem_data_t; @@ -77,23 +78,6 @@ const char *get_problem_item_content_or_NULL(problem_data_t *problem_data, const const char *get_problem_item_content_or_die(problem_data_t *problem_data, const char *key); -/* Vector of these structures */ - -typedef GPtrArray vector_of_problem_data_t; - -static inline problem_data_t *get_problem_data(vector_of_problem_data_t *vector, unsigned i) -{ - return (problem_data_t *)g_ptr_array_index(vector, i); -} - -vector_of_problem_data_t *new_vector_of_problem_data(void); -static inline void free_vector_of_problem_data(vector_of_problem_data_t *vector) -{ - if (vector) - g_ptr_array_free(vector, TRUE); -} - - /* Conversions between in-memory and on-disk formats */ void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_dir *dd); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 14220c99..86210d4e 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -11,6 +11,7 @@ lib_LTLIBRARIES = \ # xconnect.cpp libreport_la_SOURCES = \ + kernel-tainted.c \ xfuncs.c \ is_in_string_list.c \ encbase64.c \ diff --git a/src/lib/kernel-tainted.c b/src/lib/kernel-tainted.c new file mode 100644 index 00000000..115e44e0 --- /dev/null +++ b/src/lib/kernel-tainted.c @@ -0,0 +1,143 @@ +/* + Copyright (C) 2011 ABRT team + Copyright (C) 2011 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "abrtlib.h" + +/* From RHEL6 kernel/panic.c: */ +static const int tnts_short[] = { + 'P' , + 'F' , + 'S' , + 'R' , + 'M' , + 'B' , + 'U' , + 'D' , + 'A' , + 'W' , + 'C' , + 'I' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + '-' , + 'H' , + 'T' , +}; + +/** + * print_tainted - return a string to represent the kernel taint state. + * + * 'P' - Proprietary module has been loaded. + * 'F' - Module has been forcibly loaded. + * 'S' - SMP with CPUs not designed for SMP. + * 'R' - User forced a module unload. + * 'M' - System experienced a machine check exception. + * 'B' - System has hit bad_page. + * 'U' - Userspace-defined naughtiness. + * 'D' - Kernel has oopsed before + * 'A' - ACPI table overridden. + * 'W' - Taint on warning. + * 'C' - modules from drivers/staging are loaded. + * 'I' - Working around severe firmware bug. + * 'H' - Hardware is unsupported. + * T - Tech_preview + */ + + +static const char *const tnts_long[] = { + "Proprietary module has been loaded.", + "Module has been forcibly loaded.", + "SMP with CPUs not designed for SMP.", + "User forced a module unload.", + "System experienced a machine check exception.", + "System has hit bad_page.", + "Userspace-defined naughtiness.", + "Kernel has oopsed before.", + "ACPI table overridden.", + "Taint on warning.", + "Modules from drivers/staging are loaded.", + "Working around severe firmware bug.", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Hardware is unsupported.", + "Tech_preview", +}; + +char *kernel_tainted_short(unsigned tainted) +{ + char *tnt = xzalloc(ARRAY_SIZE(tnts_short) + 1); + int i = 0; + while (tainted) + { + if (0x1 & tainted) + tnt[i] = tnts_short[i]; + else + tnt[i] = '-'; + + ++i; + tainted >>= 1; + } + + return tnt; +} + +GList *kernel_tainted_long(unsigned tainted) +{ + int i = 0; + GList *tnt = NULL; + + while (tainted) + { + if (0x1 & tainted && tnts_long[i]) + tnt = g_list_append(tnt, xstrdup(tnts_long[i])); + + ++i; + tainted >>= 1; + } + + return tnt; +} diff --git a/src/lib/make_descr.c b/src/lib/make_descr.c index fe629d2b..036d7770 100644 --- a/src/lib/make_descr.c +++ b/src/lib/make_descr.c @@ -237,6 +237,7 @@ static const char *const blacklisted_items[] = { FILENAME_DUPHASH , FILENAME_UUID , FILENAME_COUNT , + FILENAME_TAINTED_SHORT, NULL }; diff --git a/src/lib/problem_data.c b/src/lib/problem_data.c index 657044bb..b4be1562 100644 --- a/src/lib/problem_data.c +++ b/src/lib/problem_data.c @@ -129,14 +129,6 @@ const char *get_problem_item_content_or_NULL(problem_data_t *problem_data, const } -/* problem_data_vector[i] = { "name" = { "content", CD_FLAG_foo_bits } } */ - -vector_of_problem_data_t *new_vector_of_problem_data(void) -{ - return g_ptr_array_new_with_free_func((void (*)(void*)) &free_problem_data); -} - - /* Miscellaneous helpers */ static const char *const editable_files[] = { diff --git a/src/plugins/abrt-action-bugzilla.c b/src/plugins/abrt-action-bugzilla.c index ee678fe8..5483e420 100644 --- a/src/plugins/abrt-action-bugzilla.c +++ b/src/plugins/abrt-action-bugzilla.c @@ -24,69 +24,6 @@ #define XML_RPC_SUFFIX "/xmlrpc.cgi" -/* From RHEL6 kernel/panic.c: - * { TAINT_PROPRIETARY_MODULE, 'P', 'G' }, - * { TAINT_FORCED_MODULE, 'F', ' ' }, - * { TAINT_UNSAFE_SMP, 'S', ' ' }, - * { TAINT_FORCED_RMMOD, 'R', ' ' }, - * { TAINT_MACHINE_CHECK, 'M', ' ' }, - * { TAINT_BAD_PAGE, 'B', ' ' }, - * { TAINT_USER, 'U', ' ' }, - * { TAINT_DIE, 'D', ' ' }, - * { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' }, - * { TAINT_WARN, 'W', ' ' }, - * { TAINT_CRAP, 'C', ' ' }, - * { TAINT_FIRMWARE_WORKAROUND, 'I', ' ' }, - * entries 12 - 27 are unused - * { TAINT_HARDWARE_UNSUPPORTED, 'H', ' ' }, - * entries 29 - 31 are unused - */ - -static const char * const taint_warnings[] = { - "Proprietary Module", - "Forced Module", - "Unsafe SMP", - "Forced rmmod", - "Machine Check", - "Bad Page", - "User", - "Die", - "Overriden ACPI Table", - "Warning Issued", - "Experimental Module Loaded", - "Firmware Workaround", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Hardware Unsupported", - NULL, - NULL, -}; - -/* TODO: npajkovs: fix tainted string */ -static const char *tainted_string(unsigned tainted) -{ - unsigned idx = 0; - while ((tainted >>= 1) != 0) - idx++; - - return taint_warnings[idx]; -} - static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings) { struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); @@ -298,7 +235,26 @@ int main(int argc, char **argv) const char *program_usage_string = _( "\b [-v] -c CONFFILE -d DIR\n" "\n" - "Reports problem to Bugzilla" + "Reports problem to Bugzilla.\n" + "\n" + "The tool reads DIR. Then it logs in to Bugzilla and tries to find a bug\n" + "with the same abrt_hash:HEXSTRING in 'Whiteboard'.\n" + "\n" + "If such bug is not found, then a new bug is created. Elements of DIR\n" + "are stored in the bug as part of bug description or as attachments,\n" + "depending on their type and size.\n" + "\n" + "Otherwise, if such bug is found and it is marked as CLOSED DUPLICATE,\n" + "the tool follows the chain of duplicates until it finds a non-DUPLICATE bug.\n" + "The tool adds a new comment to found bug.\n" + "\n" + "The URL to new or modified bug is printed to stdout and recorded in\n" + "'reported_to' element.\n" + "\n" + "CONFFILE lines should have 'PARAM = VALUE' format.\n" + "Recognized string parameters: BugzillaURL, Login, Password.\n" + "Recognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify.\n" + "Parameters can be overridden via $Bugzilla_PARAM environment variables." ); enum { OPT_v = 1 << 0, diff --git a/src/plugins/abrt-action-bugzilla.txt b/src/plugins/abrt-action-bugzilla.txt index 313e5b19..6002ccf2 100644 --- a/src/plugins/abrt-action-bugzilla.txt +++ b/src/plugins/abrt-action-bugzilla.txt @@ -3,7 +3,7 @@ abrt-action-buzilla(1) NAME ---- -abrt-action-bugzilla - Sends problem information to bugzilla. +abrt-action-bugzilla - Reports problem to Bugzilla. SYNOPSIS -------- @@ -11,27 +11,23 @@ SYNOPSIS DESCRIPTION ----------- -The tool reads a problem dump direcotry. Firstly, the tool is trying to find -duplication of bug. If duplication is 'not' found, then a new bug is created. -Otherwise if duplication 'is' found and bug is closed as duplication of the -other bug, than, so called, 'hoping' begin. It means, that tool is going to try -track the origin bug. +The tool reads problem dump directory DIR. Then it logs in to Bugzilla +and tries to find a bug with the same abrt_hash:HEXSTRING in 'Whiteboard'. -Example of bug stages are: ------------- -CLOSED DUPLICATE -> CLOSED DUPLICATE -> NEW ------------- -Third one is the origin of the same problem. The tool adds a new comment to bug, -logouts from bugzilla and return link to bug. +If such bug is not found, then a new bug is created. Elements of DIR +are stored in the bug as part of bug description or as attachments, +depending on their type and size. + +Otherwise, if such bug is found and it is marked as CLOSED DUPLICATE, +the tool follows the chain of duplicates until it finds a non-DUPLICATE bug. +The tool adds a new comment to found bug. -Properties of bugzilla can be specified in a configuration file, -and via environment variables. +The URL to new or modified bug is printed to stdout and recorded in +'reported_to' element in DIR. Configuration file ~~~~~~~~~~~~~~~~~~ -Configuration file contains entries in a format "Option = Value". - -The options are: +Configuration file lines should have 'PARAM = VALUE' format. The parameters are: 'Login':: Login to Bugzilla account. @@ -40,28 +36,22 @@ The options are: Password to Bugzilla account. 'BugzillaURL':: - Bugzilla http address. (default: https://bugzilla.redht.com) + Bugzilla http(s) address. (default: https://bugzilla.redht.com) 'SSLVerify':: Use yes/true/on/1 to verify Bugzilla ssl certificate. (default: yes) +Parameters can be overridden via $Bugzilla_PARAM environment variables. + Integration with ABRT events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -'abrt-action-bugzilla' can be used as a reporter, to allow users report -problems to bugzilla when they decide to do it. This usage is -pre-configured in /etc/abrt/events.d/ccpp_events.conf and -/etc/abrt/abrt_events.conf. +'abrt-action-bugzilla' can be used as an ABRT reporter. Example +fragment for /etc/abrt/abrt_events.conf: -For python problems (/etc/abrt/abrt_events.conf) ------------ +# Report Python crashes EVENT=report_Bugzilla analyzer=Python - abrt-action-bugzilla -c /etc/abrt/plugins/Bugzilla.conf ------------- - -For C/C++ problems (/etc/abrt/events.d/ccpp_events.conf) ------------- -EVENT=report_Bugzilla analyzer=CCpp - abrt-action-bugzilla -c /etc/abrt/plugins/Bugzilla.conf + abrt-action-bugzilla -d . -c /etc/abrt/plugins/Bugzilla.conf ------------ OPTIONS @@ -70,27 +60,8 @@ OPTIONS Path to dump directory. -c CONFFILE:: - Path to configration file. When used in ABRT event system, the file - contains site-wide configuration. Users can change the values via - environment variables. - -ENVIRONMENT VARIABLES ---------------------- -Environment variables take precedence over values provided in -the configuration file. + Path to configration file. -'Bugzilla_Login':: - Login to Bugzilla account. - -'Bugzilla_Password':: - Password to Bugzilla account. - -'Bugzilla_BugzillaURL':: - Bugzilla http address. (default: https://bugzilla.redht.com) - -'Bugzilla_SSLVerify':: - Use yes/true/on/1 to verify Bugzilla ssl certificate. (default: yes) - -AUTHORS -------- -* ABRT team +SEE ALSO +-------- +abrt_event.conf diff --git a/src/plugins/abrt-action-install-debuginfo b/src/plugins/abrt-action-install-debuginfo index 75079ff9..2ad0790a 100644 --- a/src/plugins/abrt-action-install-debuginfo +++ b/src/plugins/abrt-action-install-debuginfo @@ -93,9 +93,8 @@ def ask_yes_no(prompt, retries=4): # TODO: unpack just required debuginfo and not entire rpm? # ..that can lead to: foo.c No such file and directory # files is not used... -def unpack_rpm(package_nevra, files, tmp_dir, destdir, keeprpm): - package_name = package_nevra + ".rpm" - package_full_path = tmp_dir + "/" + package_name +def unpack_rpm(package_file_name, files, tmp_dir, destdir, keeprpm): + package_full_path = tmp_dir + "/" + package_file_name log1("Extracting %s to %s", package_full_path, destdir) log2("%s", files) print _("Extracting cpio from %s") % (package_full_path) @@ -125,7 +124,7 @@ def unpack_rpm(package_nevra, files, tmp_dir, destdir, keeprpm): # and open it for reading unpacked_cpio = open(unpacked_cpio_path, 'rb') - print _("Caching files from %s made from %s") % ("unpacked.cpio", package_name) + print _("Caching files from %s made from %s") % ("unpacked.cpio", package_file_name) cpio = Popen(["cpio", "-idu", "--quiet"], stdin=unpacked_cpio, cwd=destdir, bufsize=-1) retcode = cpio.wait() @@ -309,17 +308,21 @@ class DebugInfoDownload(YumBase): os.makedirs(self.cachedir) local = os.path.join(self.tmpdir, local) pkg.localpath = local # Hack: to set the localpath we want - ret = self.downloadPkgs(pkglist=[pkg]) - # downloadPkgs return an non empty list on succes - if ret: + err = self.downloadPkgs(pkglist=[pkg]) + # normalize the name + # just str(pkg) doesn't work because it can have epoch + pkg_nvra = pkg.name + "-" + pkg.version + "-" + pkg.release + "." + pkg.arch + package_file_name = pkg_nvra + ".rpm" + if err: + # I observed a zero-length file left on error, + # which prevents cleanup later. Fix it: + try: + os.unlink(self.tmpdir + "/" + package_file_name) + except: + pass print (_("Downloading package %s failed") % pkg) else: - # normalize the name - # just str(pkg) doesn't work because it can have epoch - pkg_nvra = (pkg.name + "-" + pkg.version + "-" + - pkg.release + "." + pkg.arch) - - unpack_result = unpack_rpm(pkg_nvra, files, self.tmpdir, + unpack_result = unpack_rpm(package_file_name, files, self.tmpdir, self.cachedir, keeprpms) if unpack_result == RETURN_FAILURE: # recursively delete the temp dir on failure @@ -330,8 +333,10 @@ class DebugInfoDownload(YumBase): downloaded_pkgs += 1 if not self.keeprpms and os.path.exists(self.tmpdir): - print (_("All downloaded packages have been extracted, removing %s") - % self.tmpdir) + # Was: "All downloaded packages have been extracted, removing..." + # but it was appearing even if no packages were in fact extracted + # (say, when there was one package, and it has download error). + print (_("Removing %s") % self.tmpdir) try: os.rmdir(self.tmpdir) except OSError: diff --git a/src/plugins/abrt-action-rhtsupport.c b/src/plugins/abrt-action-rhtsupport.c index 89f9944c..989fd75d 100644 --- a/src/plugins/abrt-action-rhtsupport.c +++ b/src/plugins/abrt-action-rhtsupport.c @@ -305,7 +305,7 @@ int main(int argc, char **argv) "CONFFILE lines should have 'PARAM = VALUE' format.\n" "Recognized string parameters: URL, Login, Password.\n" "Recognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify.\n" - "Parameters can be overridded via $RHTSupport_PARAM environment variables." + "Parameters can be overridden via $RHTSupport_PARAM environment variables." ); enum { OPT_v = 1 << 0, diff --git a/src/plugins/abrt-dump-oops.c b/src/plugins/abrt-dump-oops.c index c2879caa..5eba8036 100644 --- a/src/plugins/abrt-dump-oops.c +++ b/src/plugins/abrt-dump-oops.c @@ -542,7 +542,21 @@ static unsigned save_oops_to_dump_dir(GList *oops_list, unsigned oops_cnt) dd_save_text(dd, FILENAME_REASON, second_line); if (tainted_str && tainted_str[0] != '0') + { + unsigned long tainted = xatoi_positive(tainted_str); + char *tainted_short = kernel_tainted_short(tainted); + GList *tainted_long = kernel_tainted_long(tainted); + + struct strbuf *tnt_long = strbuf_new(); + for (GList *li = tainted_long; li; li = li->next) + strbuf_append_strf(tnt_long, "%s\n", (char*) li->data); + dd_save_text(dd, FILENAME_TAINTED, tainted_str); + dd_save_text(dd, FILENAME_TAINTED_SHORT, tainted_short); + dd_save_text(dd, FILENAME_TAINTED_LONG, tnt_long->buf); + strbuf_free(tnt_long); + list_free_with_free(tainted_long); + } dd_close(dd); } diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c index 83c3d20a..86cd86d7 100644 --- a/src/plugins/rhbz.c +++ b/src/plugins/rhbz.c @@ -300,8 +300,8 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data, FILENAME_CRASH_FUNCTION); const char *analyzer = get_problem_item_content_or_NULL(problem_data, FILENAME_ANALYZER); - const char *tainted_str = get_problem_item_content_or_NULL(problem_data, - FILENAME_TAINTED); + const char *tainted_short = get_problem_item_content_or_NULL(problem_data, + FILENAME_TAINTED_SHORT); struct strbuf *buf_summary = strbuf_new(); strbuf_append_strf(buf_summary, "[abrt] %s", package); @@ -312,17 +312,10 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data, if (reason != NULL) strbuf_append_strf(buf_summary, ": %s", reason); - if (tainted_str && analyzer - && (strcmp(analyzer, "Kerneloops") == 0) - ) { - //TODO: fix me; basically it doesn't work as it suppose to work - // I will fix it immediately when this patch land into abrt git - /* - unsigned long tainted = xatoi_positive(tainted_str); - const char *tainted_warning = tainted_string(tainted); - if (tainted_warning) - strbuf_append_strf(buf_summary, ": TAINTED %s", tainted_warning); - */ + if (tainted_short && analyzer + && (strcmp(analyzer, "Kerneloops") == 0)) + { + strbuf_append_strf(buf_summary, ": TAINTED %s", tainted_short); } char *status_whiteboard = xasprintf("abrt_hash:%s", duphash); |