#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>
static gboolean pq = FALSE;
GCond *pq_work;
+static int diskfree = 100;
+
static char *get_release(void)
{
FILE *file = NULL;
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");
"maps: |\n"
"%s",
h1,
- c1 ? c1 : " Unknown",
- m1 ? m1 : " Unknown");
+ c1 ? c1 : " Unknown\n",
+ m1 ? m1 : " Unknown\n");
free(h1);
if (c1)
free(c1);
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);