#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];
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;
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;
}
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";
};
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) {
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);
}
/*
// 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);
db->archives[i].rows);
}
- child = run(cmd, args);
-
- harvest_zombies(child);
+ run(cmd, args);
return 0;
}