Disable kernel core writing if available disk is < 10%
authorTim Pepper <timothy.c.pepper@linux.intel.com>
Tue, 16 Oct 2012 16:04:47 +0000 (09:04 -0700)
committerTim Pepper <timothy.c.pepper@linux.intel.com>
Tue, 16 Oct 2012 16:04:47 +0000 (09:04 -0700)
In an attempt to be more system friendly, corewatcher will disable its
kernel core_pattern if the core_folder's available disk drops below 10%.
It will reenable when disk availability comes back up about 12%.

This code runs at corewatcher's start and at the poll interval (currently
15 minutes).

Someday the core_pattern might be namespaced, but currently there is a
single linux kernel / system global core_pattern.  Only one core watching
type program can own it, with the obvious potential for conflict/confusion
if multiple daemons are writing a pattern there and expecting cores in
the denoted location/form.

Signed-off-by: Tim Pepper <timothy.c.pepper@linux.intel.com>
src/coredump.c

index 6864df9..cc3a20d 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>
@@ -53,6 +55,8 @@ GMutex *pq_mtx;
 static gboolean pq = FALSE;
 GCond *pq_work;
 
+static int diskfree = 100;
+
 static char *get_release(void)
 {
        FILE *file = NULL;
@@ -683,6 +687,46 @@ void *scan_processed_folder(void __unused *unused)
 /* do everything, called from timer event */
 int scan_folders(void __unused *unused)
 {
+       struct statvfs stat;
+       int newdiskfree;
+       int ret;
+
+       if (statvfs(core_folder, &stat) == 0) {
+               newdiskfree = (int)(stat.f_bavail / stat.f_blocks);
+
+               openlog("corewatcher", 0, LOG_KERN);
+               if ((newdiskfree < 10) && (diskfree >= 10)) {
+                       ret = system("echo \"\" > /proc/sys/kernel/core_pattern");
+                       if (ret != -1) {
+                               fprintf(stderr, "+ disabled core pattern, disk low %d%%",
+                                       newdiskfree);
+                               syslog(LOG_WARNING,
+                                       "Disabled kernel core_pattern, %s only has %d%% available",
+                                       core_folder, newdiskfree);
+                       }
+               }
+               if ((newdiskfree > 12) && (diskfree <= 12)) {
+                       char * proc_core_string = NULL;
+                       ret = asprintf(&proc_core_string,
+                                       "echo \"%score_%%e_%%t\" > /proc/sys/kernel/core_pattern",
+                                       core_folder);
+                       if (ret != -1) {
+                               ret = system(proc_core_string);
+                               free(proc_core_string);
+                               if (ret != -1) {
+                                       fprintf(stderr, "+ reenabled core pattern, disk %d%%",
+                                               newdiskfree);
+                                       syslog(LOG_WARNING,
+                                               "Reenabled kernel core_pattern, %s now has %d%% available",
+                                               core_folder, newdiskfree);
+                               }
+                       }
+               }
+               closelog();
+
+               diskfree = newdiskfree;
+       }
+
        scan_core_folder(NULL);
 
        g_mutex_lock(pq_mtx);