summaryrefslogtreecommitdiffstats
path: root/src/Daemon/CrashWatcher.cpp
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-08-21 17:01:41 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-08-21 17:01:41 +0200
commitbc71159f125f58bd48af950988b8ed19213f57b6 (patch)
tree6ebf9fd3332e1df5dda460fd6886ade3d9f5f5fa /src/Daemon/CrashWatcher.cpp
parent574e102451faba061502c07a0a78ab9c300e2191 (diff)
downloadabrt-bc71159f125f58bd48af950988b8ed19213f57b6.tar.gz
abrt-bc71159f125f58bd48af950988b8ed19213f57b6.tar.xz
abrt-bc71159f125f58bd48af950988b8ed19213f57b6.zip
move class CCrashWatcher into daemon.cpp
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'src/Daemon/CrashWatcher.cpp')
-rw-r--r--src/Daemon/CrashWatcher.cpp953
1 files changed, 0 insertions, 953 deletions
diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp
deleted file mode 100644
index bd45c5f9..00000000
--- a/src/Daemon/CrashWatcher.cpp
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
- Copyright (C) 2009 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"
-#include "CrashWatcher.h"
-#include <iostream>
-#include <climits>
-#include <cstdlib>
-#include <cstring>
-#include <csignal>
-#include <sstream>
-#include <cstring>
-#include "ABRTException.h"
-
-#define VAR_RUN_LOCK_FILE VAR_RUN"/abrt.lock"
-#define VAR_RUN_PIDFILE VAR_RUN"/abrt.pid"
-
-/* just a helper function
-template< class T >
-std::string
-to_string( T x )
-{
- std::ostringstream o;
- o << x;
- return o.str();
-}
-*/
-
-/* Is it "." or ".."? */
-/* abrtlib candidate */
-static bool dot_or_dotdot(const char *filename)
-{
- if (filename[0] != '.') return false;
- if (filename[1] == '\0') return true;
- if (filename[1] != '.') return false;
- if (filename[2] == '\0') return true;
- return false;
-}
-
-static double GetDirSize(const std::string &pPath);
-
-gboolean CCrashWatcher::handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer daemon)
-{
- GIOError err;
- char *buf = new char[INOTIFY_BUFF_SIZE];
- gsize len;
- gsize i = 0;
- err = g_io_channel_read(gio, buf, INOTIFY_BUFF_SIZE, &len);
- CCrashWatcher *cc = (CCrashWatcher*)daemon;
- if (err != G_IO_ERROR_NONE)
- {
- cc->Warning("Error reading inotify fd.");
- delete[] buf;
- return FALSE;
- }
- /* reconstruct each event and send message to the dbus */
- while (i < len)
- {
- const char *name = NULL;
- struct inotify_event *event;
-
- event = (struct inotify_event *) &buf[i];
- if (event->len)
- name = &buf[i] + sizeof (struct inotify_event);
- i += sizeof (struct inotify_event) + event->len;
-
- cc->Debug(std::string("Created file: ") + name);
-
- /* we want to ignore the lock files */
- if (event->mask & IN_ISDIR)
- {
- if (GetDirSize(DEBUG_DUMPS_DIR) / (1024*1024) < cc->m_pSettings->GetMaxCrashReportsSize())
- {
- //std::string sName = name;
- map_crash_info_t crashinfo;
- try
- {
- CMiddleWare::mw_result_t res;
- res = cc->m_pMW->SaveDebugDump(std::string(DEBUG_DUMPS_DIR) + "/" + name, crashinfo);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- cc->Debug("New crash, saving...");
- cc->m_pMW->RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
- /* send message to dbus */
- cc->m_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT]);
- break;
- case CMiddleWare::MW_REPORTED:
- case CMiddleWare::MW_OCCURED:
- /* send message to dbus */
- cc->Debug("Already saved crash, deleting...");
- cc->m_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT]);
- cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
- break;
- case CMiddleWare::MW_BLACKLISTED:
- case CMiddleWare::MW_CORRUPTED:
- case CMiddleWare::MW_PACKAGE_ERROR:
- case CMiddleWare::MW_GPG_ERROR:
- case CMiddleWare::MW_IN_DB:
- case CMiddleWare::MW_FILE_ERROR:
- default:
- cc->Warning("Corrupted or bad crash, deleting...");
- cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
- break;
- }
- }
- catch (CABRTException& e)
- {
- cc->Warning(e.what());
- if (e.type() == EXCEP_FATAL)
- {
- delete[] buf;
- return -1;
- }
- }
- catch (...)
- {
- delete[] buf;
- throw;
- }
- }
- else
- {
- cc->Debug(std::string("DebugDumps size has exceeded the limit, deleting the last dump: ") + name);
- cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
- }
- }
- else
- {
- cc->Debug("Some file created, ignoring...");
- }
- }
- delete[] buf;
- return TRUE;
-}
-
-void *CCrashWatcher::create_report(void *arg)
-{
- thread_data_t *thread_data = (thread_data_t *) arg;
- map_crash_info_t crashReport;
- thread_data->daemon->Debug("Creating report...");
- try
- {
- CMiddleWare::mw_result_t res;
- res = thread_data->daemon->m_pMW->CreateCrashReport(thread_data->UUID,thread_data->UID,crashReport);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- break;
- case CMiddleWare::MW_IN_DB_ERROR:
- thread_data->daemon->Warning(std::string("Did not find crash with UUID ")+thread_data->UUID+ " in database.");
- break;
- case CMiddleWare::MW_PLUGIN_ERROR:
- thread_data->daemon->Warning(std::string("Particular analyzer plugin isn't loaded or there is an error within plugin(s)."));
- break;
- case CMiddleWare::MW_CORRUPTED:
- case CMiddleWare::MW_FILE_ERROR:
- default:
- {
- std::string debugDumpDir;
- thread_data->daemon->Warning(std::string("Corrupted crash with UUID ")+thread_data->UUID+", deleting.");
- debugDumpDir = thread_data->daemon->m_pMW->DeleteCrashInfo(thread_data->UUID, thread_data->UID);
- thread_data->daemon->m_pMW->DeleteDebugDumpDir(debugDumpDir);
- }
- break;
- }
- /* only one thread can write */
- pthread_mutex_lock(&(thread_data->daemon->m_pJobsMutex));
- thread_data->daemon->pending_jobs[std::string(thread_data->UID)][thread_data->thread_id] = crashReport;
- pthread_mutex_unlock(&(thread_data->daemon->m_pJobsMutex));
- thread_data->daemon->m_pCommLayer->JobDone(thread_data->dest, thread_data->thread_id);
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- /* free strduped strings */
- free(thread_data->UUID);
- free(thread_data->UID);
- free(thread_data->dest);
- free(thread_data);
- throw e;
- }
- thread_data->daemon->Warning(e.what());
- }
- /* free strduped strings */
- free(thread_data->UUID);
- free(thread_data->UID);
- free(thread_data->dest);
- free(thread_data);
-
- /* Bogus value. pthreads require us to return void* */
- return NULL;
-}
-
-gboolean CCrashWatcher::cron_activation_periodic_cb(gpointer data)
-{
- cron_callback_data_t* cronPeriodicCallbackData = static_cast<cron_callback_data_t*>(data);
- cronPeriodicCallbackData->m_pCrashWatcher->Debug("Activating plugin: " + cronPeriodicCallbackData->m_sPluginName);
- cronPeriodicCallbackData->m_pCrashWatcher->m_pMW->RunAction(cronPeriodicCallbackData->m_pCrashWatcher->m_sTarget,
- cronPeriodicCallbackData->m_sPluginName,
- cronPeriodicCallbackData->m_sPluginArgs);
- return TRUE;
-}
-gboolean CCrashWatcher::cron_activation_one_cb(gpointer data)
-{
- cron_callback_data_t* cronOneCallbackData = static_cast<cron_callback_data_t*>(data);
- cronOneCallbackData->m_pCrashWatcher->Debug("Activating plugin: " + cronOneCallbackData->m_sPluginName);
- cronOneCallbackData->m_pCrashWatcher->m_pMW->RunAction(cronOneCallbackData->m_pCrashWatcher->m_sTarget,
- cronOneCallbackData->m_sPluginName,
- cronOneCallbackData->m_sPluginArgs);
- return FALSE;
-}
-gboolean CCrashWatcher::cron_activation_reshedule_cb(gpointer data)
-{
- cron_callback_data_t* cronResheduleCallbackData = static_cast<cron_callback_data_t*>(data);
- cronResheduleCallbackData->m_pCrashWatcher->Debug("Rescheduling plugin: " + cronResheduleCallbackData->m_sPluginName);
- cron_callback_data_t* cronPeriodicCallbackData = new cron_callback_data_t(cronResheduleCallbackData->m_pCrashWatcher,
- cronResheduleCallbackData->m_sPluginName,
- cronResheduleCallbackData->m_sPluginArgs,
- cronResheduleCallbackData->m_nTimeout);
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
- cronPeriodicCallbackData->m_nTimeout,
- cron_activation_periodic_cb,
- static_cast<gpointer>(cronPeriodicCallbackData),
- cron_delete_callback_data_cb);
-
-
- return FALSE;
-}
-
-void CCrashWatcher::cron_delete_callback_data_cb(gpointer data)
-{
- cron_callback_data_t* cronDeleteCallbackData = static_cast<cron_callback_data_t*>(data);
- delete cronDeleteCallbackData;
-}
-
-void CCrashWatcher::SetUpMW()
-{
- m_pMW->SetOpenGPGCheck(m_pSettings->GetOpenGPGCheck());
- m_pMW->SetDatabase(m_pSettings->GetDatabase());
- CSettings::set_strings_t openGPGPublicKeys = m_pSettings->GetOpenGPGPublicKeys();
- CSettings::set_strings_t::iterator it_k;
- for (it_k = openGPGPublicKeys.begin(); it_k != openGPGPublicKeys.end(); it_k++)
- {
- m_pMW->AddOpenGPGPublicKey(*it_k);
- }
- CSettings::set_strings_t blackList = m_pSettings->GetBlackList();
- CSettings::set_strings_t::iterator it_b;
- for (it_b = blackList.begin(); it_b != blackList.end(); it_b++)
- {
- m_pMW->AddBlackListedPackage(*it_b);
- }
- CSettings::set_strings_t enabledPlugins = m_pSettings->GetEnabledPlugins();
- CSettings::set_strings_t::iterator it_p;
- for (it_p = enabledPlugins.begin(); it_p != enabledPlugins.end(); it_p++)
- {
- m_pMW->RegisterPlugin(*it_p);
- }
- CSettings::vector_pair_strings_t actionsAndReporters = m_pSettings->GetActionsAndReporters();
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = actionsAndReporters.begin(); it_ar != actionsAndReporters.end(); it_ar++)
- {
- m_pMW->AddActionOrReporter((*it_ar).first, (*it_ar).second);
- }
-
- CSettings::map_analyzer_actions_and_reporters_t analyzerActionsAndReporters = m_pSettings->GetAnalyzerActionsAndReporters();
- CSettings::map_analyzer_actions_and_reporters_t::iterator it_aar;
- for (it_aar = analyzerActionsAndReporters.begin(); it_aar != analyzerActionsAndReporters.end(); it_aar++)
- {
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = it_aar->second.begin(); it_ar != it_aar->second.end(); it_ar++)
- {
- m_pMW->AddAnalyzerActionOrReporter(it_aar->first, (*it_ar).first, (*it_ar).second);
- }
- }
-}
-
-void CCrashWatcher::SetUpCron()
-{
- CSettings::map_cron_t cron = m_pSettings->GetCron();
- CSettings::map_cron_t::iterator it_c;
- for (it_c = cron.begin(); it_c != cron.end(); it_c++)
- {
- std::string::size_type pos = it_c->first.find(":");
- int timeout = 0;
- int nH = -1;
- int nM = -1;
- int nS = -1;
-
- if (pos != std::string::npos)
- {
- std::string sH = "";
- std::string sM = "";
-
- sH = it_c->first.substr(0, pos);
- nH = atoi(sH.c_str());
- nH = nH > 23 ? 23 : nH;
- nH = nH < 0 ? 0 : nH;
- nM = nM > 59 ? 59 : nM;
- nM = nM < 0 ? 0 : nM;
- timeout += nH * 60 * 60;
- sM = it_c->first.substr(pos + 1);
- nM = atoi(sM.c_str());
- timeout += nM * 60;
- }
- else
- {
- std::string sS = "";
-
- sS = it_c->first;
- nS = atoi(sS.c_str());
- nS = nS <= 0 ? 1 : nS;
- timeout = nS;
- }
-
- if (nS != -1)
- {
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = it_c->second.begin(); it_ar != it_c->second.end(); it_ar++)
- {
-
- cron_callback_data_t* cronPeriodicCallbackData = new cron_callback_data_t(this, (*it_ar).first, (*it_ar).second, timeout);
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
- timeout,
- cron_activation_periodic_cb,
- static_cast<gpointer>(cronPeriodicCallbackData),
- cron_delete_callback_data_cb);
- }
- }
- else
- {
- time_t actTime = time(NULL);
- if (actTime == ((time_t)-1))
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot get time.");
- }
- struct tm locTime;
- if (localtime_r(&actTime, &locTime) == NULL)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot get local time.");
- }
- locTime.tm_hour = nH;
- locTime.tm_min = nM;
- locTime.tm_sec = 0;
- time_t nextTime = mktime(&locTime);
- if (nextTime == ((time_t)-1))
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot set up time.");
- }
- if (actTime > nextTime)
- {
- timeout = 24*60*60 + (nextTime - actTime);
- }
- else
- {
- timeout = nextTime - actTime;
- }
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = it_c->second.begin(); it_ar != it_c->second.end(); it_ar++)
- {
-
- cron_callback_data_t* cronOneCallbackData = new cron_callback_data_t(this, (*it_ar).first, (*it_ar).second, timeout);
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
- timeout,
- cron_activation_one_cb,
- static_cast<gpointer>(cronOneCallbackData),
- cron_delete_callback_data_cb);
- cron_callback_data_t* cronResheduleCallbackData = new cron_callback_data_t(this, (*it_ar).first, (*it_ar).second, 24 * 60 * 60);
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
- timeout,
- cron_activation_reshedule_cb,
- static_cast<gpointer>(cronResheduleCallbackData),
- cron_delete_callback_data_cb);
- }
- }
- }
-}
-
-void CCrashWatcher::Status(const std::string& pMessage, const std::string& pDest)
-{
- std::cout << "Update: " + pMessage << std::endl;
- //FIXME: send updates only to job owner
- if(m_pCommLayer != NULL)
- m_pCommLayer->Update(pDest,pMessage);
-}
-
-void CCrashWatcher::Warning(const std::string& pMessage, const std::string& pDest)
-{
- std::cerr << "Warning: " + pMessage << std::endl;
- if(m_pCommLayer != NULL)
- m_pCommLayer->Warning(pDest,pMessage);
-}
-
-void CCrashWatcher::Debug(const std::string& pMessage, const std::string& pDest)
-{
- //some logic to add logging levels?
- std::cout << "Debug: " + pMessage << std::endl;
-}
-
-static double GetDirSize(const std::string &pPath)
-{
- double size = 0;
- struct dirent *ep;
- struct stat stats;
- DIR *dp;
-
- dp = opendir(pPath.c_str());
- if (dp != NULL)
- {
- while ((ep = readdir(dp)) != NULL)
- {
- if (dot_or_dotdot(ep->d_name))
- continue;
- std::string dname = pPath + "/" + ep->d_name;
- if (lstat(dname.c_str(), &stats) == 0)
- {
- if (S_ISDIR(stats.st_mode))
- {
- size += GetDirSize(dname);
- }
- else if (S_ISREG(stats.st_mode))
- {
- size += stats.st_size;
- }
- }
- }
- closedir(dp);
- }
- else
- {
- throw CABRTException(EXCEP_FATAL, std::string(__func__) + ": Init Failed");
- }
- return size;
-}
-
-CCrashWatcher::CCrashWatcher(const std::string& pPath)
-{
- int watch = 0;
- m_sTarget = pPath;
-
- // TODO: initialize object according parameters -w -d
- // status has to be always created.
- m_pCommLayer = NULL;
- comm_layer_inner_init(this);
-
- m_pSettings = new CSettings();
- m_pSettings->LoadSettings(std::string(CONF_DIR) + "/abrt.conf");
-
- m_pMainloop = g_main_loop_new(NULL,FALSE);
- m_pMW = new CMiddleWare(PLUGINS_CONF_DIR,PLUGINS_LIB_DIR);
- if (pthread_mutex_init(&m_pJobsMutex, NULL) != 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Can't init mutex!");
- }
- try
- {
- SetUpMW();
- SetUpCron();
- FindNewDumps(pPath);
-#ifdef ENABLE_DBUS
- m_pCommLayer = new CCommLayerServerDBus();
-#elif ENABLE_SOCKET
- m_pCommLayer = new CCommLayerServerSocket();
-#endif
-// m_pCommLayer = new CCommLayerServerDBus();
-// m_pCommLayer = new CCommLayerServerSocket();
- m_pCommLayer->Attach(this);
-
- if ((m_nFd = inotify_init()) == -1)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Init Failed");
- }
- if ((watch = inotify_add_watch(m_nFd, pPath.c_str(), IN_CREATE)) == -1)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Add watch failed:" + pPath);
- }
- m_pGio = g_io_channel_unix_new(m_nFd);
- }
- catch (...)
- {
- /* This restores /proc/sys/kernel/core_pattern, among other things */
- delete m_pMW;
- //too? delete m_pCommLayer;
- throw;
- }
-}
-
-CCrashWatcher::~CCrashWatcher()
-{
- //delete dispatcher, connection, etc..
- //m_pConn->disconnect();
-
- g_io_channel_unref(m_pGio);
- g_main_loop_unref(m_pMainloop);
-
- delete m_pCommLayer;
- delete m_pMW;
- delete m_pSettings;
- if (pthread_mutex_destroy(&m_pJobsMutex) != 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Can't destroy mutex!");
- }
- /* delete pid file */
- unlink(VAR_RUN_PIDFILE);
- /* delete lock file */
- unlink(VAR_RUN_LOCK_FILE);
-}
-
-void CCrashWatcher::FindNewDumps(const std::string& pPath)
-{
- Debug("Scanning for unsaved entries...");
- struct dirent *ep;
- struct stat stats;
- DIR *dp;
- std::vector<std::string> dirs;
- std::string dname;
- // get potential unsaved debugdumps
- dp = opendir(pPath.c_str());
- if (dp != NULL)
- {
- while ((ep = readdir(dp)))
- {
- if (dot_or_dotdot(ep->d_name))
- continue;
- dname = pPath + "/" + ep->d_name;
- if (lstat(dname.c_str(), &stats) == 0)
- {
- if (S_ISDIR(stats.st_mode))
- {
- dirs.push_back(dname);
- }
- }
- }
- (void) closedir(dp);
- }
- else
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::FindNewDumps(): Couldn't open the directory:" + pPath);
- }
-
- for (std::vector<std::string>::iterator itt = dirs.begin(); itt != dirs.end(); ++itt){
- map_crash_info_t crashinfo;
- try
- {
- CMiddleWare::mw_result_t res;
- res = m_pMW->SaveDebugDump(*itt, crashinfo);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- Debug("Saving into database (" + *itt + ").");
- m_pMW->RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
- break;
- case CMiddleWare::MW_IN_DB:
- Debug("Already saved in database (" + *itt + ").");
- break;
- case CMiddleWare::MW_REPORTED:
- case CMiddleWare::MW_OCCURED:
- case CMiddleWare::MW_BLACKLISTED:
- case CMiddleWare::MW_CORRUPTED:
- case CMiddleWare::MW_PACKAGE_ERROR:
- case CMiddleWare::MW_GPG_ERROR:
- case CMiddleWare::MW_FILE_ERROR:
- default:
- Warning("Corrupted, bad or already saved crash, deleting.");
- m_pMW->DeleteDebugDumpDir(*itt);
- break;
- }
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
- }
-}
-void CCrashWatcher::CreatePidFile()
-{
- int fd;
-
- /* JIC */
- unlink(VAR_RUN_PIDFILE);
-
- /* open the pidfile */
- fd = open(VAR_RUN_PIDFILE, O_WRONLY|O_CREAT|O_EXCL, 0644);
- if (fd >= 0)
- {
- /* write our pid to it */
- char buf[sizeof(int)*3 + 2];
- int len = sprintf(buf, "%u\n", (unsigned)getpid());
- write(fd, buf, len);
- close(fd);
- return;
- }
-
- /* something went wrong */
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreatePidFile(): can not open pid file");
-}
-
-void CCrashWatcher::Lock()
-{
- int lfp = open(VAR_RUN_LOCK_FILE, O_RDWR|O_CREAT, 0640);
- if (lfp < 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::Lock(): can not open lock file");
- }
- if (lockf(lfp, F_TLOCK, 0) < 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::Lock(): cannot create lock on lockfile");
- }
- /* only first instance continues */
- //sprintf(str,"%d\n",getpid());
- //write(lfp,str,strlen(str)); /* record pid to lockfile */
-}
-
-void CCrashWatcher::StartWatch()
-{
- char *buff = new char[INOTIFY_BUFF_SIZE];
- int len = 0;
- int i = 0;
- char action[FILENAME_MAX];
- struct inotify_event *pevent;
- //run forever
- while (1)
- {
- i = 0;
- len = read(m_nFd,buff,INOTIFY_BUFF_SIZE);
- while (i < len)
- {
- pevent = (struct inotify_event *)&buff[i];
- if (pevent->len)
- {
- std::strcpy(action, pevent->name);
- }
- else
- {
- std::strcpy(action, m_sTarget.c_str());
- }
-
- i += sizeof(struct inotify_event) + pevent->len;
- Debug(std::string("Created file: ") + action);
- }
- }
- delete[] buff;
-}
-
-extern uint8_t sig_caught;
-//prepare()
-//If the source can determine that it is ready here (without waiting
-//for the results of the poll() call) it should return TRUE. It can also
-//return a timeout_ value which should be the maximum timeout (in milliseconds)
-//which should be passed to the poll() call.
-//check()
-//Called after all the file descriptors are polled. The source should
-//return TRUE if it is ready to be dispatched.
-//dispatch()
-//Called to dispatch the event source, after it has returned TRUE
-//in either its prepare or its check function. The dispatch function
-//is passed in a callback function and data. The callback function
-//may be NULL if the source was never connected to a callback using
-//g_source_set_callback(). The dispatch function should
-//call the callback function with user_data and whatever additional
-//parameters are needed for this type of event source.
-typedef struct SignalSource
-{
- GSource src;
- CCrashWatcher* watcher;
-} SignalSource;
-static gboolean waitsignal_prepare(GSource *source, gint *timeout_)
-{
- /* We depend on the fact that in Unix, poll() is interrupted
- * by caught signals (returns EINTR). Thus we do not need to set
- * a small timeout here: infinite timeout (-1) works too */
- *timeout_ = -1;
- return sig_caught != 0;
-}
-static gboolean waitsignal_check(GSource *source)
-{
- return sig_caught != 0;
-}
-static gboolean waitsignal_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
-{
- SignalSource *ssrc = (SignalSource*) source;
- ssrc->watcher->StopRun();
- return 1;
-}
-
-/* daemon loop with glib */
-void CCrashWatcher::GStartWatch()
-{
- g_io_add_watch(m_pGio, G_IO_IN, handle_event_cb, this);
-
- GSourceFuncs waitsignal_funcs;
- memset(&waitsignal_funcs, 0, sizeof(waitsignal_funcs));
- waitsignal_funcs.prepare = waitsignal_prepare;
- waitsignal_funcs.check = waitsignal_check;
- waitsignal_funcs.dispatch = waitsignal_dispatch;
- //waitsignal_funcs.finalize = NULL; - already done
- SignalSource *waitsignal_src = (SignalSource*) g_source_new(&waitsignal_funcs, sizeof(*waitsignal_src));
- waitsignal_src->watcher = this;
- g_source_attach(&waitsignal_src->src, g_main_context_default());
-
- //enter the event loop
- g_main_run(m_pMainloop);
-}
-
-void CCrashWatcher::Run()
-{
- Debug("Running...");
- Lock();
- CreatePidFile();
- GStartWatch();
-}
-
-void CCrashWatcher::StopRun()
-{
- g_main_quit(m_pMainloop);
-}
-
-vector_crash_infos_t CCrashWatcher::GetCrashInfos(const std::string &pUID)
-{
- vector_crash_infos_t retval;
- Debug("Getting crash infos...");
- try
- {
- vector_pair_string_string_t UUIDsUIDs;
- UUIDsUIDs = m_pMW->GetUUIDsOfCrash(pUID);
-
- unsigned int ii;
- for (ii = 0; ii < UUIDsUIDs.size(); ii++)
- {
- CMiddleWare::mw_result_t res;
- map_crash_info_t info;
-
- res = m_pMW->GetCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second, info);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- retval.push_back(info);
- break;
- case CMiddleWare::MW_ERROR:
- Warning("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
- Status("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
- m_pMW->DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
- break;
- case CMiddleWare::MW_FILE_ERROR:
- {
- std::string debugDumpDir;
- Warning("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting ");
- Status("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting ");
- debugDumpDir = m_pMW->DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
- m_pMW->DeleteDebugDumpDir(debugDumpDir);
- }
- break;
- default:
- break;
- }
- }
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- Status(e.what());
- }
-
- //retval = m_pMW->GetCrashInfos(pUID);
- //Notify("Sent crash info");
- return retval;
-}
-
-uint64_t CCrashWatcher::CreateReport_t(const std::string &pUUID,const std::string &pUID, const std::string &pSender)
-{
- thread_data_t *thread_data = (thread_data_t *)xzalloc(sizeof(thread_data_t));
- if (thread_data != NULL)
- {
- thread_data->UUID = xstrdup(pUUID.c_str());
- thread_data->UID = xstrdup(pUID.c_str());
- thread_data->dest = xstrdup(pSender.c_str());
- thread_data->daemon = this;
- if (pthread_create(&(thread_data->thread_id), NULL, create_report, (void *)thread_data) != 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreateReport_t(): Cannot create thread!");
- }
- }
- else
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreateReport_t(): Cannot allocate memory!");
- }
- //FIXME: we don't use this value anymore, so fix the API
- return 0;
-}
-
-CMiddleWare::report_status_t CCrashWatcher::Report(map_crash_report_t pReport, const std::string& pUID)
-{
- //#define FIELD(X) crashReport.m_s##X = pReport[#X];
- //crashReport.m_sUUID = pReport["UUID"];
- //ALL_CRASH_REPORT_FIELDS;
- //#undef FIELD
- //for (dbus_map_report_info_t::iterator it = pReport.begin(); it!=pReport.end(); ++it) {
- // std::cerr << it->second << std::endl;
- //}
- CMiddleWare::report_status_t rs;
- try
- {
- rs = m_pMW->Report(pReport, pUID);
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- Status(e.what());
- return rs;
- }
- return rs;
-}
-
-bool CCrashWatcher::DeleteDebugDump(const std::string& pUUID, const std::string& pUID)
-{
- try
- {
- std::string debugDumpDir;
- debugDumpDir = m_pMW->DeleteCrashInfo(pUUID,pUID);
- m_pMW->DeleteDebugDumpDir(debugDumpDir);
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- Status(e.what());
- return false;
- }
- return true;
-}
-
-map_crash_report_t CCrashWatcher::GetJobResult(uint64_t pJobID, const std::string& pSender)
-{
- /* FIXME: once we return the result, we should remove it from map to free memory
- - use some TTL to clean the memory even if client won't get it
- - if we don't find it in the cache we should try to ask MW to get it again??
- */
- return pending_jobs[pSender][pJobID];
-}
-
-vector_map_string_string_t CCrashWatcher::GetPluginsInfo()
-{
- try
- {
- return m_pMW->GetPluginsInfo();
- }
- catch (CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
- // TODO: is it right? I added it just to disable a warning...
- // but maybe returning empty map is wrong here?
- return vector_map_string_string_t();
-}
-
-map_plugin_settings_t CCrashWatcher::GetPluginSettings(const std::string& pName, const std::string& pUID)
-{
- try
- {
- return m_pMW->GetPluginSettings(pName, pUID);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}
-
-void CCrashWatcher::RegisterPlugin(const std::string& pName)
-{
- try
- {
- m_pMW->RegisterPlugin(pName);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}
-
-void CCrashWatcher::UnRegisterPlugin(const std::string& pName)
-{
- try
- {
- m_pMW->UnRegisterPlugin(pName);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}
-
-void CCrashWatcher::SetPluginSettings(const std::string& pName, const std::string& pUID, const map_plugin_settings_t& pSettings)
-{
- try
- {
- m_pMW->SetPluginSettings(pName, pUID, pSettings);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}