]> git.itanic.dy.fi Git - rrdd/blobdiff - rrdtool.c
Allow parsers to store private data to databases
[rrdd] / rrdtool.c
index df9b5c80fba4f788855b9f0c3fe3ceb888137ee1..da876d51da7620d8051ca6f0320790c71f5e687f 100644 (file)
--- a/rrdtool.c
+++ b/rrdtool.c
@@ -34,7 +34,6 @@
 
 int rrdtool_draw_image(struct rrd_image *image)
 {
-       int pid;
        char cmd[] = RRDTOOL_CMD;
 //     char cmd[] = "echo";
        char *args[512], argstr[ARGSTR_LEN];
@@ -45,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;
@@ -95,19 +90,19 @@ int rrdtool_draw_image(struct rrd_image *image)
 
        add_arg(args, argcnt, argstr, idx, "COMMENT: %s\\c", timestamp);
 
-       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",
+                       (work_fn_t *)rrdtool_draw_image, image[i]);
 
        return 0;
 }
@@ -255,9 +250,18 @@ static int write_to_logfile(struct rrd_database *rrd, const char *data)
        return ret < 0 ? ret : 0;
 }
 
-int rrdtool_update_data(struct rrd_database *rrd)
+static int run_post_draw_cmd(struct rrd_database *rrd)
+{
+       pr_info("Running post draw command for %s\n", rrd->name);
+
+       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;
+}
+
+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";
@@ -270,14 +274,12 @@ 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) {
-               rrd->parser->parse(data + l, rrd->parser_data);
+               rrd->parser->parse(data + l, rrd->parser_data,
+                               &rrd->parser_state);
                data[RRD_DATA_MAX_LEN + 2] = '\0';
 
                pr_info("Data: %s\n", data);
@@ -285,20 +287,38 @@ int rrdtool_update_data(struct rrd_database *rrd)
                sanitize_rrd_update_data(data + l);
                write_to_logfile(rrd, data);
 
-               pid = run(cmd, cmdline);
-               harvest_zombies(pid);
+               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);
+       /*
+        * We rely on the fact that rrdtool_draw_images queues image
+        * drawings into low priority queue and the post draw queue is
+        * placed on the queue after images. This ensures post draw
+        * command is not started before images are started.
+        *
+        * There is nothing that guarantees post_draw_cmd is executed
+        * after all images are completed though, but it's close..
+        */
+       if (rrd->post_draw_cmd)
+               queue_work(WORK_PRIORITY_LOW, "rrdtool_post_draw_cmd",
+                       (work_fn_t *)run_post_draw_cmd, rrd);
+
+       return 0;
+}
+
+int rrdtool_update_data(struct rrd_database *rrd)
+{
+       rrd->last_update = time(0);
+
+       return queue_work(WORK_PRIORITY_HIGH, "rrdtool_update_data",
+                       (work_fn_t *)do_rrdtool_update_data, rrd);
 }
 
 /*
@@ -362,7 +382,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);
@@ -398,9 +418,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;
 }