]> git.itanic.dy.fi Git - rrdd/blobdiff - rrdtool.c
do_rrdtool_update_data: Initialize data buffer
[rrdd] / rrdtool.c
index 53db261354f4102f41f3bdccf4a77b2ee6ba542a..43b3571da5fcfbd7e2d23ad6726f77f20eb15914 100644 (file)
--- a/rrdtool.c
+++ b/rrdtool.c
@@ -2,6 +2,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
 
        args[argcnt] = argstr + idx;                    \
        idx += sprintf(argstr + idx, fmt, ##arg);       \
        argcnt++;                                       \
+       args[argcnt] = 0;                               \
        argstr[++idx] = 0
 
 int rrdtool_draw_image(struct rrd_image *image)
 {
-       int pid;
        char cmd[] = RRDTOOL_CMD;
 //     char cmd[] = "echo";
        char *args[512], argstr[ARGSTR_LEN];
@@ -43,15 +44,11 @@ int rrdtool_draw_image(struct rrd_image *image)
        time_t t = time(0);
        const char *updatestr = "Last update %d.%m.%Y %T (%Z)";
 
-       pid = do_fork_limited();
-       if (pid)
-               return pid;
-
        pr_info("Drawing image %s\n", image->image_filename);
 
        tmpfile[0] = 0;
-       strncat(tmpfile, image->image_filename, sizeof(tmp) - strlen(tmp) - 1);
-       strncat(tmpfile, ".tmp", sizeof(tmp) - strlen(tmp) - 1);
+       strncat(tmpfile, image->image_filename, sizeof(tmp) - 1);
+       strncat(tmpfile, ".tmp", sizeof(tmp) - 1);
 
        if (image->updatestr)
                updatestr = image->updatestr;
@@ -93,21 +90,19 @@ int rrdtool_draw_image(struct rrd_image *image)
 
        add_arg(args, argcnt, argstr, idx, "COMMENT: %s\\c", timestamp);
 
-       args[argcnt] = 0;
-
-       pid = run(cmd, args);
-       harvest_zombies(pid);
+       run(cmd, args);
 
        rename(tmpfile, image->image_filename);
 
-       exit(0);
+       return 0;
 }
 
 int rrdtool_draw_images(struct rrd_image **image)
 {
        int i;
        for (i = 0; image[i]; i++)
-               rrdtool_draw_image(image[i]);
+               queue_work(WORK_PRIORITY_LOW, "rrdtool_draw_image",
+                       rrdtool_draw_image, image[i]);
 
        return 0;
 }
@@ -199,9 +194,64 @@ static int sanitize_rrd_update_data(char *data)
        return entries;
 }
 
-int rrdtool_update_data(struct rrd_database *rrd)
+static int write_to_logfile(struct rrd_database *rrd, const char *data)
+{
+       time_t t = time(NULL);
+       int fd, ret;
+       int spacing, i;
+       char filename[1024];
+       char logstr[RRD_DATA_MAX_LEN * 2] = { 0 };
+       const char *time_stamp_fmt = "%Y.%m.%d %H:%M ";
+       char *str_ptr;
+
+       if (!rrd->logfile)
+               return 0;
+
+       if (rrd->logfile_timestamp_fmt)
+               time_stamp_fmt = rrd->logfile_timestamp_fmt;
+
+       strftime(filename, sizeof(filename), rrd->logfile, localtime(&t));
+
+       fd = open(filename, O_RDWR | O_APPEND | O_CREAT | O_CLOEXEC, 0644);
+       if (fd < 0) {
+               pr_err("Failed to open file %s for logging: %m\n", filename);
+               return -1;
+       }
+
+       strftime(logstr, sizeof(logstr), time_stamp_fmt, localtime(&t));
+
+       str_ptr = logstr + strlen(logstr);
+
+       data += 2;      /* Skip the "N: part */
+       spacing = 12;
+
+       while (*data && str_ptr - logstr < sizeof(logstr) - 1) {
+               if (*data == ':') {
+                       *str_ptr++ = ' ';
+                       for (i = 0; i < spacing; i++)
+                               *str_ptr++ = ' ';
+                       spacing = 12;
+                       data++;
+                       continue;
+               }
+
+               *str_ptr++ = *data++;
+               spacing--;
+       }
+       *str_ptr++ = '\n';
+       *str_ptr++ = 0;
+
+       ret = write(fd, logstr, strlen(logstr));
+       if (ret < 0)
+               pr_err("Failed to write to logfile %s: %m\n", filename);
+
+       close(fd);
+
+       return ret < 0 ? ret : 0;
+}
+
+static int do_rrdtool_update_data(struct rrd_database *rrd)
 {
-       int pid;
        char data[RRD_DATA_MAX_LEN + 3]; /* 3 == "N:" + NULL termination */
        char cmd[] = RRDTOOL_CMD;
 //     char cmd[] = "echo";
@@ -214,10 +264,7 @@ int rrdtool_update_data(struct rrd_database *rrd)
        };
        int l;
 
-       rrd->last_update = time(0);
-       if (do_fork())
-               return 0;
-
+       bzero(data, sizeof(data));
        l = sprintf(data, "N:");
 
        if (rrd->parser && rrd->parser->parse) {
@@ -227,20 +274,30 @@ int rrdtool_update_data(struct rrd_database *rrd)
                pr_info("Data: %s\n", data);
 
                sanitize_rrd_update_data(data + l);
-               pid = run(cmd, cmdline);
-               harvest_zombies(pid);
+               write_to_logfile(rrd, data);
+
+               run(cmd, cmdline);
        }
 
        if (rrd->pre_draw_cmd && !strcmp(rrd->pre_draw_cmd[0], "shell")) {
-               pid = run(rrd->pre_draw_cmd[1], &rrd->pre_draw_cmd[1]);
-               harvest_zombies(pid);
+               run(rrd->pre_draw_cmd[1], &rrd->pre_draw_cmd[1]);
        }
 
        if (rrd->images)
                rrdtool_draw_images(rrd->images);
 
-       while (harvest_zombies(0));
-       exit(0);
+       if (rrd->post_draw_cmd && !strcmp(rrd->post_draw_cmd[0], "shell"))
+               run(rrd->post_draw_cmd[1], &rrd->post_draw_cmd[1]);
+
+       return 0;
+}
+
+int rrdtool_update_data(struct rrd_database *rrd)
+{
+       rrd->last_update = time(0);
+
+       return queue_work(WORK_PRIORITY_HIGH, "rrdtool_update_data",
+                       do_rrdtool_update_data, rrd);
 }
 
 /*
@@ -304,7 +361,7 @@ static int create_database(struct rrd_database *db)
 //     char cmd[] = "echo";
        char *args[512], argstr[ARGSTR_LEN];
        int idx = 0, argcnt = 0;
-       int child, i;
+       int i;
 
        if (!db->filename) {
                pr_err("Database %s missing database filename\n", db->name);
@@ -340,9 +397,7 @@ static int create_database(struct rrd_database *db)
                        db->archives[i].rows);
        }
 
-       child = run(cmd, args);
-
-       harvest_zombies(child);
+       run(cmd, args);
 
        return 0;
 }