fix many temporary core detail files from flooding the system
authorWilliam Douglas <william.douglas@linux.intel.com>
Thu, 21 Apr 2011 19:49:56 +0000 (12:49 -0700)
committerWilliam Douglas <william.douglas@linux.intel.com>
Thu, 21 Apr 2011 20:13:02 +0000 (13:13 -0700)
Signed-off-by: William Douglas <william.douglas@linux.intel.com>
coredump.c
corewatcher.c
corewatcher.h
submit.c

index 83c9caf..fbafdd1 100644 (file)
@@ -432,10 +432,55 @@ void write_core_detail_file(char *filename, char *text)
        }
 }
 
+char *get_core_detail_filename(char *filename)
+{
+       char *pid, *c, *s;
+       char *detail_filename;
+
+       if (!(s = strstr(filename, ".")))
+               return NULL;
+
+       pid = strdup(++s);
+       if (!(c = strstr(pid, "."))) {
+               free(pid);
+               return NULL;
+       }
+
+       *c = '\0';
+
+       if ((asprintf(&detail_filename, "%s%s.txt", core_folder, pid)) < 0) {
+               free(pid);
+               return NULL;
+       }
+
+       free(pid);
+       return detail_filename;
+}
+
+char *remove_directories(char *fullname)
+{
+       char *dfile = NULL, *c = NULL, *d = NULL;
+       char delim[] = "/";
+
+       dfile = strdup(fullname);
+       if (!dfile)
+               return NULL;
+
+       c = strtok(dfile, delim);
+       while(c) {
+               d = c;
+               c = strtok(NULL, delim);
+       }
+       d = strdup(d);
+       free(dfile);
+
+       return d;
+}
+
 void process_corefile(char *filename)
 {
        struct oops *oops;
-       char newfile[8192];
+       char newfile[8192], *fn = NULL;
 
        oops = extract_core(filename);
 
@@ -444,42 +489,35 @@ void process_corefile(char *filename)
                return;
        }
 
-       /* if this oops hasn't been processed before need to write details out and rename */
-       if (!strstr(filename, ".processed")) {
-               char *dfile = NULL, *c = NULL, *d = NULL;
-               char delim[] = "/";
-
-               dfile = strdup(filename);
-               if (!dfile)
-                       return;
+       if (!(fn = remove_directories(filename))) {
+               FREE_OOPS(oops);
+               return;
+       }
 
-               c = strtok(dfile, delim);
-               while(c) {
-                       d = c;
-                       c = strtok(NULL, delim);
-               }
+       /* if this oops hasn't been processed before need to write details out and rename */
+       if (!strstr(fn, ".processed")) {
                fprintf(stderr, "---[start of coredump]---\n%s\n---[end of coredump]---\n", oops->text);
                dbus_say_found(oops);
 
+               if (!mkdir(core_folder, S_IRWXU | S_IRWXG | S_IRWXO) && errno != EEXIST) {
+                       free(fn);
+                       FREE_OOPS(oops);
+                       return;
+               }
                /* try to write coredump text details to text file */
                write_core_detail_file(filename, oops->text);
-               if (!mkdir(core_folder, S_IRWXU | S_IRWXG | S_IRWXO) && errno != EEXIST)
-                       return;
-               sprintf(newfile,"%s%s.processed", core_folder, d);
+               sprintf(newfile,"%s%s.processed", core_folder, fn);
                rename(filename, newfile);
-               free(dfile);
-               free(oops->filename);
-               oops->filename = strdup(newfile);
+
        } else {
                /* backtrace queued only if files have been processed
                   to avoid putting a new coredump in twice */
+               oops->detail_filename = get_core_detail_filename(fn);
                queue_backtrace(oops);
        }
 
-       free(oops->application);
-       free(oops->text);
-       free(oops->filename);
-       free(oops);
+       free(fn);
+       FREE_OOPS(oops);
 }
 
 
@@ -530,6 +568,6 @@ int scan_dmesg(void __unused *unused)
        if (opted_in >= 2)
                submit_queue();
        else if (opted_in >= 1)
-               ask_permission();
+               ask_permission(core_folder);
        return 1;
 }
index 82ce15d..ff3e900 100644 (file)
@@ -132,16 +132,16 @@ static DBusHandlerResult got_message(
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
-void dbus_ask_permission(char * detail_file_name)
+void dbus_ask_permission(char * detail_folder)
 {
        DBusMessage *message;
        if (!bus)
                return;
        message = dbus_message_new_signal("/org/corewatcher/submit/permission",
                        "org.corewatcher.submit.permission", "ask");
-       if (detail_file_name) {
+       if (detail_folder) {
                dbus_message_append_args(message,
-                       DBUS_TYPE_STRING, &detail_file_name,
+                       DBUS_TYPE_STRING, &detail_folder,
                        DBUS_TYPE_INVALID);
        }
        dbus_connection_send(bus, message, NULL);
index a4b3878..b8a634d 100644 (file)
 
 #define MAX_URLS 9
 
+#define FREE_OOPS(oops)                          \
+       do {                                     \
+               free(oops->application);         \
+               free(oops->text);                \
+               free(oops->filename);            \
+               free(oops->detail_filename);     \
+                free(oops);                      \
+       } while(0)
+
 struct oops {
        struct oops *next;
        char *application;
        char *text;
        char *filename;
+       char *detail_filename;
        unsigned int checksum;
 };
 
@@ -47,8 +57,9 @@ extern void clear_queue(void);
 extern int scan_dmesg(void * unused);
 extern void read_config_file(char *filename);
 
-extern void ask_permission(void);
-extern void dbus_ask_permission(char * detail_file_name);
+
+extern void ask_permission(char *detail_folder);
+extern void dbus_ask_permission(char *detail_folder);
 extern void dbus_say_thanks(char *url);
 extern void dbus_say_found(struct oops *oops);
 
index d47e47e..f2066c1 100644 (file)
--- a/submit.c
+++ b/submit.c
@@ -62,12 +62,6 @@ static struct oops *queued_backtraces;
 static int newoops;
 static int unsubmittedoops;
 
-/* For communicating details to the applet, we write the
- * details in a file, and provide the filename to the applet
- */
-static char *detail_filename;
-
-
 static unsigned int checksum(char *ptr)
 {
        unsigned int temp = 0;
@@ -105,52 +99,11 @@ void queue_backtrace(struct oops *oops)
        new->application = strdup(oops->application);
        new->text = strdup(oops->text);
        new->filename = strdup(oops->filename);
+       new->detail_filename = strdup(oops->detail_filename);
        queued_backtraces = new;
        unsubmittedoops = 1;
 }
 
-
-void write_detail_file(void)
-{
-       int temp_fileno;
-       FILE *tmpf;
-       struct oops *oops;
-       int count = 0;
-
-       detail_filename = strdup("/tmp/corewatcher.XXXXXX");
-       temp_fileno = mkstemp(detail_filename);
-       if (temp_fileno < 0) {
-               free(detail_filename);
-               detail_filename = NULL;
-               return;
-       }
-       /* regular user must be able to read this detail file to be
-        * useful; there is nothing worth doing if fchmod fails.
-        */
-       fchmod(temp_fileno, 0644);
-       tmpf = fdopen(temp_fileno, "w");
-       oops = queued_backtraces;
-       while (oops) {
-               count++; /* Users are not programmers, start at 1 */
-               fprintf(tmpf, "Application failure message %d:\n", count);
-               fprintf(tmpf, "%s", oops->text);
-               fprintf(tmpf, "\n\n");
-               oops = oops->next;
-       }
-       fclose(tmpf);
-       close(temp_fileno);
-}
-
-void unlink_detail_file(void)
-{
-       if (detail_filename) {
-               if (do_unlink)
-                       unlink(detail_filename);
-               free(detail_filename);
-       }
-}
-
-
 static void print_queue(void)
 {
        struct oops *oops, *next;
@@ -164,10 +117,7 @@ static void print_queue(void)
        while (oops) {
                fprintf(stderr, "+ Submit text is:\n---[start of oops]---\n%s\n---[end of oops]---\n", oops->text);
                next = oops->next;
-               free(oops->application);
-               free(oops->text);
-               free(oops->filename);
-               free(oops);
+               FREE_OOPS(oops);
                oops = next;
                count++;
        }
@@ -261,8 +211,10 @@ void submit_queue_with_url(struct oops *queue, char *wsubmit_url, char *proxy)
 
                        sprintf(newfile,"%s.submitted",  oldfile);
 
-                       if (do_unlink)
+                       if (do_unlink) {
+                               unlink(oops->detail_filename);
                                unlink(oops->filename);
+                       }
                        else
                                rename(oops->filename, newfile);
 
@@ -285,7 +237,6 @@ void submit_queue_with_url(struct oops *queue, char *wsubmit_url, char *proxy)
         * the program won't do any useful work anymore going forward.
         */
        if (submitted >= MAX_CHECKSUMS-1) {
-               unlink_detail_file();
                exit(EXIT_SUCCESS);
        }
 }
@@ -339,10 +290,7 @@ void submit_queue(void)
        oops = queue;
        while (oops) {
                next = oops->next;
-               free(oops->application);
-               free(oops->text);
-               free(oops->filename);
-               free(oops);
+               FREE_OOPS(oops);
                oops = next;
        }
 
@@ -360,16 +308,13 @@ void clear_queue(void)
        oops = queue;
        while (oops) {
                next = oops->next;
-               free(oops->application);
-               free(oops->text);
-               free(oops->filename);
-               free(oops);
+               FREE_OOPS(oops);
                oops = next;
        }
        write_logfile(0, "Unknown");
 }
 
-void ask_permission(void)
+void ask_permission(char *detail_folder)
 {
        if (!newoops && !pinged && !unsubmittedoops)
                return;
@@ -377,7 +322,6 @@ void ask_permission(void)
        newoops = 0;
        unsubmittedoops = 0;
        if (queued_backtraces) {
-               write_detail_file();
-               dbus_ask_permission(detail_filename);
+               dbus_ask_permission(detail_folder);
        }
 }