Quote filenames
[platform/upstream/corewatcher.git] / src / coredump.c
index 46c1a6a..a378eea 100644 (file)
@@ -35,6 +35,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/statvfs.h>
+#include <syslog.h>
 #include <dirent.h>
 #include <glib.h>
 #include <errno.h>
  * race where the condition is set before the thread is awaiting it and
  * thus is not woken.
  */
-static GMutex pq_mtx;
+GMutex *pq_mtx;
 static gboolean pq = FALSE;
-static GCond pq_work;
+GCond *pq_work;
+
+static int diskfree = 100;
 
 static char *get_release(void)
 {
@@ -221,7 +225,7 @@ static struct oops *extract_core(char *fullpath, char *appfile, char *reportname
 
        fprintf(stderr, "+ extract_core() called for %s\n", fullpath);
 
-       if (asprintf(&command, "LANG=C gdb --batch -f %s %s -x /etc/corewatcher/gdb.command 2> /dev/null", appfile, fullpath) == -1)
+       if (asprintf(&command, "LANG=C gdb --batch -f '%s' '%s' -x /etc/corewatcher/gdb.command 2> /dev/null", appfile, fullpath) == -1)
                return NULL;
 
        file = popen(command, "r");
@@ -322,8 +326,8 @@ static struct oops *extract_core(char *fullpath, char *appfile, char *reportname
                       "maps: |\n"
                       "%s",
                       h1,
-                      c1 ? c1 : "        Unknown",
-                      m1 ? m1 : "        Unknown");
+                      c1 ? c1 : "        Unknown\n",
+                      m1 ? m1 : "        Unknown\n");
        free(h1);
        if (c1)
                free(c1);
@@ -578,9 +582,6 @@ int scan_core_folder(void __unused *unused)
        }
        fprintf(stderr, "+ Begin scanning %s...\n", core_folder);
        while(1) {
-               free(fullpath);
-               fullpath = NULL;
-
                entry = readdir(dir);
                if (!entry || !entry->d_name)
                        break;
@@ -603,15 +604,18 @@ int scan_core_folder(void __unused *unused)
                ret = move_core(fullpath, "to-process");
                if (ret == 0)
                        work++;
+
+               free(fullpath);
+               fullpath = NULL;
        }
        closedir(dir);
 
        if (work) {
                fprintf(stderr, "+ Found %d files, setting pq_work condition\n", work);
-               g_mutex_lock(&pq_mtx);
-               g_cond_signal(&pq_work);
+               g_mutex_lock(pq_mtx);
+               g_cond_signal(pq_work);
                pq = TRUE;
-               g_mutex_unlock(&pq_mtx);
+               g_mutex_unlock(pq_mtx);
        }
 
        fprintf(stderr, "+ End scanning %s...\n", core_folder);
@@ -630,13 +634,13 @@ void *scan_processed_folder(void __unused *unused)
        struct oops *oops = NULL;
 
        while(1) {
-               g_mutex_lock(&pq_mtx);
+               g_mutex_lock(pq_mtx);
                while (pq != TRUE) {
                        fprintf(stderr, "+ Awaiting work in %s...\n", processed_folder);
-                       g_cond_wait(&pq_work, &pq_mtx);
+                       g_cond_wait(pq_work, pq_mtx);
                }
                pq = FALSE;
-               g_mutex_unlock(&pq_mtx);
+               g_mutex_unlock(pq_mtx);
 
                fprintf(stderr, "+ Begin scanning %s...\n", processed_folder);
 
@@ -680,15 +684,74 @@ void *scan_processed_folder(void __unused *unused)
        return NULL;
 }
 
+static void disable_corefiles(int diskfree)
+{
+       int ret;
+       ret = system("echo \"\" > /proc/sys/kernel/core_pattern");
+       if (ret != -1) {
+               fprintf(stderr, "+ disabled core pattern, disk low %d%%\n", diskfree);
+               syslog(LOG_WARNING,
+                       "Disabled kernel core_pattern, %s only has %d%% available",
+                       core_folder, diskfree);
+       }
+}
+
+void enable_corefiles(int diskfree)
+{
+       int ret;
+       char * proc_core_string = NULL;
+       ret = asprintf(&proc_core_string,
+                       "echo \"%score_%%e_%%t\" > /proc/sys/kernel/core_pattern",
+                       core_folder);
+       if (ret == -1)
+               goto err;
+
+       ret = system(proc_core_string);
+       free(proc_core_string);
+       if (ret == -1)
+               goto err;
+
+       if (diskfree == -1) {
+               fprintf(stderr, "+ enabled core pattern\n");
+               syslog(LOG_INFO, "Enabled corewatcher kernel core_pattern\n");
+       } else {
+               fprintf(stderr, "+ reenabled core pattern, disk %d%%", diskfree);
+               syslog(LOG_WARNING,
+                       "Reenabled corewatcher kernel core_pattern, %s now has %d%% available",
+                       core_folder, diskfree);
+       }
+       return;
+err:
+       fprintf(stderr, "+ unable to enable core pattern\n");
+       syslog(LOG_WARNING, "Unable to enable kernel core_pattern\n");
+       return;
+}
+
 /* do everything, called from timer event */
 int scan_folders(void __unused *unused)
 {
+       struct statvfs stat;
+       int newdiskfree;
+
+       if (statvfs(core_folder, &stat) == 0) {
+               newdiskfree = (int)(100 * stat.f_bavail / stat.f_blocks);
+
+               openlog("corewatcher", 0, LOG_KERN);
+               if ((newdiskfree < 10) && (diskfree >= 10))
+                       disable_corefiles(newdiskfree);
+               if ((newdiskfree > 12) && (diskfree <= 12))
+                       enable_corefiles(newdiskfree);
+               closelog();
+
+               diskfree = newdiskfree;
+       }
+
        scan_core_folder(NULL);
 
-       g_mutex_lock(&pq_mtx);
-       g_cond_signal(&pq_work);
+       g_mutex_lock(pq_mtx);
+       g_cond_signal(pq_work);
        pq = TRUE;
-       g_mutex_unlock(&pq_mtx);
+       g_mutex_unlock(pq_mtx);
 
        return TRUE;
 }