summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJiri Moskovcak <jmoskovc@redhat.com>2010-02-07 16:03:50 +0100
committerJiri Moskovcak <jmoskovc@redhat.com>2010-02-07 16:03:50 +0100
commit34fc227339ccd23b30973ea4684fcb6fb408635e (patch)
treec47ba01ecdc6e0e2ab5fc38c5eb07c4d6deeeedd /src
parent985908c6b086b83381eccd95a0a6508c8bf1d731 (diff)
parent1e76e071620e1f9bf110dacf3cf8caffccef324b (diff)
downloadabrt-34fc227339ccd23b30973ea4684fcb6fb408635e.tar.gz
abrt-34fc227339ccd23b30973ea4684fcb6fb408635e.tar.xz
abrt-34fc227339ccd23b30973ea4684fcb6fb408635e.zip
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Diffstat (limited to 'src')
-rwxr-xr-xsrc/Backtrace/abrt-bz-dupchecker7
-rwxr-xr-xsrc/Backtrace/abrt-bz-hashchecker2
-rw-r--r--src/CLI/dbus.cpp28
-rw-r--r--src/CLI/dbus.h14
-rw-r--r--src/CLI/report.cpp55
-rw-r--r--src/Daemon/Daemon.cpp58
-rw-r--r--src/Daemon/MiddleWare.cpp22
-rw-r--r--src/Daemon/MiddleWare.h9
8 files changed, 152 insertions, 43 deletions
diff --git a/src/Backtrace/abrt-bz-dupchecker b/src/Backtrace/abrt-bz-dupchecker
index d7748c72..344d1326 100755
--- a/src/Backtrace/abrt-bz-dupchecker
+++ b/src/Backtrace/abrt-bz-dupchecker
@@ -130,7 +130,7 @@ dupcount = 0
for backtrace, components in database.items():
for component, bugitems in components.items():
if len(bugitems) > 1:
- dupcount += len(value) - 1
+ dupcount += len(bugitems) - 1
print "Total number of duplicate bugs detected: {0}".format(dupcount)
print "------------------------------"
@@ -140,5 +140,8 @@ for backtrace, components in database.items():
for component, bugitems in components.items():
if len(bugitems) > 1:
print "Component: {0}".format(component)
- print "Duplicates: {0}".format(map(lambda x: "{0} ({1})".format(x['id'],x['comments']), bugitems).join(", "))
+ print "Duplicates: {0}".format(
+ reduce(lambda x,y: x+", "+y,
+ map(lambda x: "{0} ({1})".format(x['id'],x['comments']),
+ bugitems)))
print "Backtrace: {0}".format(backtrace)
diff --git a/src/Backtrace/abrt-bz-hashchecker b/src/Backtrace/abrt-bz-hashchecker
index 9c4a5ff3..ec7ce1a6 100755
--- a/src/Backtrace/abrt-bz-hashchecker
+++ b/src/Backtrace/abrt-bz-hashchecker
@@ -56,4 +56,4 @@ bz.logout()
for hash, ids in hashes.items():
if len(ids) > 1:
- print "Duplicates found: ", ids.join(", ")
+ print "Duplicates found: ", reduce(lambda x,y: str(x)+", "+str(y), ids)
diff --git a/src/CLI/dbus.cpp b/src/CLI/dbus.cpp
index ffd1157e..db45cd8b 100644
--- a/src/CLI/dbus.cpp
+++ b/src/CLI/dbus.cpp
@@ -142,12 +142,15 @@ map_crash_data_t call_CreateReport(const char* uuid)
return argout;
}
-report_status_t call_Report(const map_crash_data_t& report)
+report_status_t call_Report(const map_crash_data_t& report,
+ const map_map_string_t &plugins)
{
DBusMessage* msg = new_call_msg(__func__ + 5);
DBusMessageIter out_iter;
dbus_message_iter_init_append(msg, &out_iter);
store_val(&out_iter, report);
+ if (!plugins.empty())
+ store_val(&out_iter, plugins);
DBusMessage *reply = send_get_reply_and_unref(msg);
@@ -184,7 +187,6 @@ int32_t call_DeleteDebugDump(const char* uuid)
return result;
}
-#ifdef UNUSED
map_map_string_t call_GetPluginsInfo()
{
DBusMessage *msg = new_call_msg(__func__ + 5);
@@ -201,7 +203,27 @@ map_map_string_t call_GetPluginsInfo()
dbus_message_unref(reply);
return argout;
}
-#endif
+
+map_plugin_settings_t call_GetPluginSettings(const char *name)
+{
+ DBusMessage *msg = new_call_msg(__func__ + 5);
+ dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID);
+
+ DBusMessage *reply = send_get_reply_and_unref(msg);
+
+ DBusMessageIter in_iter;
+ dbus_message_iter_init(reply, &in_iter);
+
+ map_string_t argout;
+ int r = load_val(&in_iter, argout);
+ if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */
+ error_msg_and_die("dbus call %s: return type mismatch", __func__ + 5);
+
+ dbus_message_unref(reply);
+ return argout;
+}
void handle_dbus_err(bool error_flag, DBusError *err)
{
diff --git a/src/CLI/dbus.h b/src/CLI/dbus.h
index c6fd7a4d..c6c61eb5 100644
--- a/src/CLI/dbus.h
+++ b/src/CLI/dbus.h
@@ -25,10 +25,19 @@ extern DBusConnection* s_dbus_conn;
vector_map_crash_data_t call_GetCrashInfos();
map_crash_data_t call_CreateReport(const char *uuid);
-report_status_t call_Report(const map_crash_data_t& report);
+
+/** Sends report using enabled Reporter plugins.
+ * @param plugins
+ * Optional settings for plugins, can be empty.
+ * Format: plugins["PluginName"]["SettingsKey"] = "SettingsValue"
+ * If it contains settings for some plugin, it must contain _all fields_
+ * obtained by call_GetPluginSettings, otherwise the plugin might ignore
+ * the settings.
+ */
+report_status_t call_Report(const map_crash_data_t& report,
+ const map_map_string_t &plugins);
int32_t call_DeleteDebugDump(const char* uuid);
-#ifdef UNUSED
/* Gets basic data about all installed plugins.
*/
map_map_string_t call_GetPluginsInfo();
@@ -38,7 +47,6 @@ map_map_string_t call_GetPluginsInfo();
* Corresponds to name obtained from call_GetPluginsInfo.
*/
map_plugin_settings_t call_GetPluginSettings(const char *name);
-#endif
void handle_dbus_err(bool error_flag, DBusError *err);
diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp
index 2bcd52af..7ef33acf 100644
--- a/src/CLI/report.cpp
+++ b/src/CLI/report.cpp
@@ -412,10 +412,63 @@ int report(const char *uuid, bool always)
}
}
+ map_map_string_t pluginSettings;
+ if (!always)
+ {
+ // Get informations about all plugins.
+ map_map_string_t plugins = call_GetPluginsInfo();
+ // Check the configuration of each enabled Reporter plugin.
+ map_map_string_t::iterator it, itend = plugins.end();
+ for (it = plugins.begin(); it != itend; ++it)
+ {
+ // Skip disabled plugins.
+ if (0 != strcmp(it->second["Enabled"].c_str(), "yes"))
+ continue;
+ // Skip nonReporter plugins.
+ if (0 != strcmp(it->second["Type"].c_str(), "Reporter"))
+ continue;
+
+ map_string_t settings = call_GetPluginSettings(it->first.c_str());
+ // Login information is missing.
+ bool loginMissing = settings.find("Login") != settings.end()
+ && 0 == strcmp(settings["Login"].c_str(), "");
+ bool passwordMissing = settings.find("Password") != settings.end()
+ && 0 == strcmp(settings["Password"].c_str(), "");
+ if (!loginMissing && !passwordMissing)
+ continue;
+
+ // Copy the received settings as defaults.
+ // Plugins won't work without it, if some value is missing
+ // they use their default values for all fields.
+ pluginSettings[it->first] = settings;
+
+ printf(_("Wrong settings were detected for plugin %s.\n"), it->second["Name"].c_str());
+ if (loginMissing)
+ {
+ printf(_("Enter your login: "));
+ fflush(NULL);
+ char answer[64] = "";
+ fgets(answer, sizeof(answer), stdin);
+ if (strlen(answer) > 0)
+ pluginSettings[it->first]["Login"] = answer;
+ }
+ if (passwordMissing)
+ {
+// TODO: echo off, see http://fixunix.com/unix/84474-echo-off.html
+ printf(_("Enter your password: "));
+ fflush(NULL);
+ char answer[64] = "";
+ fgets(answer, sizeof(answer), stdin);
+ if (strlen(answer) > 0)
+ pluginSettings[it->first]["Password"] = answer;
+ }
+ }
+ }
+
int errors = 0;
int plugins = 0;
puts(_("Reporting..."));
- report_status_t r = call_Report(cr);
+ report_status_t r = call_Report(cr, pluginSettings);
report_status_t::iterator it = r.begin();
while (it != r.end())
{
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
index 511d45d6..99214230 100644
--- a/src/Daemon/Daemon.cpp
+++ b/src/Daemon/Daemon.cpp
@@ -316,9 +316,12 @@ static void FindNewDumps(const char* pPath)
}
closedir(dp);
- log("Checking for unsaved crashdumps (%u dirs to check)", (unsigned)dirs.size());
+ unsigned size = dirs.size();
+ if (size == 0)
+ return;
+ log("Checking for unsaved crashes (dirs to check:%u)", size);
- /* Get potential unsaved debugdumps */
+ /* Get potentially non-processed debugdumps */
vector_string_t::iterator itt = dirs.begin();
for (; itt != dirs.end(); ++itt)
{
@@ -332,19 +335,22 @@ static void FindNewDumps(const char* pPath)
case MW_OK:
/* Not VERB1: this is new, unprocessed crash dump.
* Last abrtd somehow missed it - need to inform user */
- log("Non-processed crashdump in %s, saving into database", dir_name);
- RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str());
+ log("Non-processed crash in %s, saving into database", dir_name);
+ /* Run automatic actions and reporters on it (if we have them configured) */
+ RunActionsAndReporters(dir_name);
break;
case MW_IN_DB:
+ /* This debugdump was found in DB, nothing else was done
+ * by SaveDebugDump or needs to be done by us */
VERB1 log("%s is already saved in database", dir_name);
break;
- case MW_REPORTED:
- case MW_OCCURED:
- VERB1 log("Already saved crash %s, deleting", dir_name);
+ case MW_REPORTED: /* already reported dup */
+ case MW_OCCURRED: /* not-yet-reported dup */
+ VERB1 log("Duplicate crash %s, deleting", dir_name);
delete_debug_dump_dir(dir_name);
break;
default:
- log("Corrupted or bad crashdump %s (res:%d), deleting", dir_name, (int)res);
+ log("Corrupted or bad crash %s (res:%d), deleting", dir_name, (int)res);
delete_debug_dump_dir(dir_name);
break;
}
@@ -354,6 +360,7 @@ static void FindNewDumps(const char* pPath)
error_msg("%s", e.what());
}
}
+ log("Done checking for unsaved crashes");
}
static int CreatePidFile()
@@ -483,27 +490,37 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
try
{
std::string fullname = concat_path_file(DEBUG_DUMPS_DIR, name);
-//todo: rename SaveDebugDump to ???? it does not save crashinfo, it FETCHES crashinfo
+ /* Note: SaveDebugDump does not save crashinfo, it _fetches_ crashinfo */
map_crash_data_t crashinfo;
mw_result_t res = SaveDebugDump(fullname.c_str(), crashinfo);
switch (res)
{
case MW_OK:
- log("New crash, saving");
- RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str());
+ log("New crash %s, processing", fullname.c_str());
+ /* Run automatic actions and reporters on it (if we have them configured) */
+ RunActionsAndReporters(fullname.c_str());
/* Fall through */
- case MW_REPORTED:
- case MW_OCCURED:
+
+ case MW_REPORTED: /* already reported dup */
+ case MW_OCCURRED: /* not-yet-reported dup */
{
if (res != MW_OK)
- log("Already saved crash, just sending dbus signal");
+ {
+ const char *first = get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str();
+ log("Deleting crash %s (dup of %s), sending dbus signal",
+ strrchr(fullname.c_str(), '/') + 1,
+ strrchr(first, '/') + 1);
+ delete_debug_dump_dir(fullname.c_str());
+ }
+#define fullname fullname_should_not_be_used_here
const char *analyzer = get_crash_data_item_content(crashinfo, FILENAME_ANALYZER).c_str();
const char *uid_str = get_crash_data_item_content(crashinfo, FILENAME_UID).c_str();
/* Autoreport it if configured to do so */
- if (analyzer_has_AutoReportUIDs(analyzer, uid_str))
- {
+ if (res != MW_REPORTED
+ && analyzer_has_AutoReportUIDs(analyzer, uid_str)
+ ) {
VERB1 log("Reporting the crash automatically");
map_crash_data_t crash_report;
mw_result_t crash_result = CreateCrashReport(
@@ -531,15 +548,18 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
uid_str = NULL;
g_pCommLayer->Crash(get_crash_data_item_content(crashinfo, FILENAME_PACKAGE).c_str(), uid_str);
break;
+#undef fullname
}
+ case MW_IN_DB:
+ log("Huh, this crash is already in db?! Nothing to do");
+ break;
case MW_BLACKLISTED:
case MW_CORRUPTED:
case MW_PACKAGE_ERROR:
case MW_GPG_ERROR:
- case MW_IN_DB:
case MW_FILE_ERROR:
default:
- log("Corrupted or bad crash, deleting");
+ log("Corrupted or bad crash %s (res:%d), deleting", fullname.c_str(), (int)res);
delete_debug_dump_dir(fullname.c_str());
break;
}
@@ -859,7 +879,7 @@ int main(int argc, char** argv)
{
/* This may take a while, therefore we don't do it in init section */
FindNewDumps(DEBUG_DUMPS_DIR);
- log("Running...");
+ log("Init complete, entering main loop");
run_main_loop(pMainloop);
}
catch (CABRTException& e)
diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp
index c3f9061a..ebd5c0fc 100644
--- a/src/Daemon/MiddleWare.cpp
+++ b/src/Daemon/MiddleWare.cpp
@@ -702,10 +702,6 @@ static mw_result_t SavePackageDescriptionToDebugDump(
catch (CABRTException& e)
{
error_msg("%s", e.what());
- if (e.type() == EXCEP_DD_SAVE)
- {
- return MW_FILE_ERROR;
- }
return MW_ERROR;
}
@@ -832,15 +828,16 @@ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID,
mw_result_t res = FillCrashInfo(pUUID, pUID, pCrashData);
if (res == MW_OK)
{
+ const char *first = get_crash_data_item_content(pCrashData, CD_DUMPDIR).c_str();
if (row.m_sReported == "1")
{
- log("Crash is already reported");
+ log("Crash is in database already (dup of %s) and is reported", first);
return MW_REPORTED;
}
if (row.m_sCount != "1")
{
- log("Crash is in database already");
- return MW_OCCURED;
+ log("Crash is in database already (dup of %s)", first);
+ return MW_OCCURRED;
}
}
return res;
@@ -876,10 +873,6 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir,
catch (CABRTException& e)
{
error_msg("%s", e.what());
- if (e.type() == EXCEP_DD_SAVE)
- {
- return MW_FILE_ERROR;
- }
return MW_ERROR;
}
@@ -898,6 +891,13 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir,
const char *uid_str = analyzer_has_InformAllUsers(analyzer.c_str())
? "-1"
: UID.c_str();
+ /* Loads pCrashData (from the *first debugdump dir* if this one is a dup)
+ * Returns:
+ * MW_REPORTED: "the crash is flagged as reported in DB" (which also means it's a dup)
+ * MW_OCCURRED: "crash count is != 1" (iow: it is > 1 - dup)
+ * MW_OK: "crash count is 1" (iow: this is a new crash, not a dup)
+ * else: an error code
+ */
return SaveDebugDumpToDatabase(lUUID.c_str(), uid_str, time.c_str(), pDebugDumpDir, pCrashData);
}
diff --git a/src/Daemon/MiddleWare.h b/src/Daemon/MiddleWare.h
index 71d17f35..aa37e3ed 100644
--- a/src/Daemon/MiddleWare.h
+++ b/src/Daemon/MiddleWare.h
@@ -37,7 +37,7 @@ typedef enum {
MW_PACKAGE_ERROR, /**< Cannot determine package name.*/
MW_GPG_ERROR, /**< Package is not signed properly.*/
MW_REPORTED, /**< Crash is already reported.*/
- MW_OCCURED, /**< Crash occurred in the past, but it is not reported yet.*/
+ MW_OCCURRED, /**< Crash occurred in the past, but it is not reported yet.*/
MW_IN_DB, /**< Debugdump directory is already saved in a database.*/
MW_IN_DB_ERROR, /**< Error while working with a database.*/
MW_PLUGIN_ERROR, /**< plugin wasn't found or error within plugin*/
@@ -105,8 +105,11 @@ report_status_t Report(const map_crash_data_t& pCrashData,
std::string getDebugDumpDir( const char *pUUID,
const char *pUID);
/**
- * Saves debugdump into database. If saving is successful,
- * it fills crash info.
+ * Adds package name and description to debugdump dir.
+ * Saves debugdump into database.
+ * Detects whether it's a duplicate crash.
+ * Fills crash info.
+ * Note that if it's a dup, loads _first crash_ info, not this one's.
* @param pDebugDumpDir A debugdump directory.
* @param pCrashData A crash info.
* @return It return results of operation. See mw_result_t.