The purpose of the post_draw_cmd is to execute something after the
rrdtool has drawn the images. Right now it executes the command
actually before drawing the images, as the command gets executed from
the high priority work that queued the image drawings.
This is not what we want. Therefore queue the post_draw_cmd to the
same low priority queue where the images are put. This guarantees that
the command does not begin too soon. On uniprocessors it is also
guaranteed that the command does not start executing before all of the
images are completed.
Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
return ret < 0 ? ret : 0;
}
return ret < 0 ? ret : 0;
}
+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)
{
char data[RRD_DATA_MAX_LEN + 3]; /* 3 == "N:" + NULL termination */
static int do_rrdtool_update_data(struct rrd_database *rrd)
{
char data[RRD_DATA_MAX_LEN + 3]; /* 3 == "N:" + NULL termination */
if (rrd->images)
rrdtool_draw_images(rrd->images);
if (rrd->images)
rrdtool_draw_images(rrd->images);
- if (rrd->post_draw_cmd && !strcmp(rrd->post_draw_cmd[0], "shell"))
- run(rrd->post_draw_cmd[1], &rrd->post_draw_cmd[1]);
+ /*
+ * 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);