* Now for some includes..
*/
/* {{{ */
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(HAVE_CONFIG_H)
-#include "../win32/config.h"
-#else
-#ifdef HAVE_CONFIG_H
-#include "../rrd_config.h"
-#endif
-#endif
#include "rrd_tool.h"
#include "rrd_client.h"
size_t values_num; /* number of valid pointers */
size_t values_alloc; /* number of allocated pointers */
time_t last_flush_time;
- time_t last_update_stamp;
+ double last_update_stamp;
#define CI_FLAGS_IN_TREE (1<<0)
#define CI_FLAGS_IN_QUEUE (1<<1)
int flags;
static void sig_common (const char *sig) /* {{{ */
{
RRDD_LOG(LOG_NOTICE, "caught SIG%s", sig);
- state = FLUSHING;
+ if (state == RUNNING) {
+ state = FLUSHING;
+ }
pthread_cond_broadcast(&flush_cond);
pthread_cond_broadcast(&queue_cond);
} /* }}} void sig_common */
/* save it for the journal later */
if (!JOURNAL_REPLAY(sock))
- strncpy(orig_buf, buffer, buffer_size);
+ strncpy(orig_buf, buffer, min(RRD_CMD_MAX,buffer_size));
status = buffer_get_field (&buffer, &buffer_size, &file);
if (status != 0)
while (buffer_size > 0)
{
char *value;
- time_t stamp;
+ double stamp;
char *eostamp;
status = buffer_get_field (&buffer, &buffer_size, &value);
break;
}
- /* make sure update time is always moving forward */
- stamp = strtol(value, &eostamp, 10);
+ /* make sure update time is always moving forward. We use double here since
+ update does support subsecond precision for timestamps ... */
+ stamp = strtod(value, &eostamp);
if (eostamp == value || eostamp == NULL || *eostamp != ':')
{
pthread_mutex_unlock(&cache_lock);
{
pthread_mutex_unlock(&cache_lock);
return send_response(sock, RESP_ERR,
- "illegal attempt to update using time %ld when last"
- " update time is %ld (minimum one second step)\n",
+ "illegal attempt to update using time %lf when last"
+ " update time is %lf (minimum one second step)\n",
stamp, ci->last_update_stamp);
}
else
getting overwritten by another thread.
*/
struct request_info req;
- request_init(&req, RQ_DAEMON, "rrdcache\0", RQ_FILE, fd, NULL );
+ request_init(&req, RQ_DAEMON, "rrdcached\0", RQ_FILE, fd, NULL );
fromhost(&req);
if(!hosts_access(&req)) {
RRDD_LOG(LOG_INFO, "refused connection from %s", eval_client(&req));
return (open_listen_socket_network(sock));
} /* }}} int open_listen_socket */
+#ifndef SD_LISTEN_FDS_START
+# define SD_LISTEN_FDS_START 3
+#endif
+/*
+ * returns number of descriptors passed from systemd
+ */
+static int open_listen_sockets_systemd(void) /* {{{ */
+{
+ listen_socket_t *temp;
+ struct sockaddr_un sa;
+ socklen_t l;
+ int sd_fd;
+ const char *env;
+ unsigned long n;
+
+ /* check if it for us */
+ env = getenv("LISTEN_PID");
+ if (!env)
+ return 0;
+
+ n = strtoul(env, NULL, 10);
+ if (!n || n == ULONG_MAX || (pid_t)n != getpid())
+ return 0;
+
+ /* get the number of passed descriptors */
+ env = getenv("LISTEN_FDS");
+ if (!env)
+ return 0;
+
+ n = strtoul(env, NULL, 10);
+ if (!n || n == ULONG_MAX)
+ return 0;
+
+ temp = (listen_socket_t *) rrd_realloc (listen_fds,
+ sizeof (listen_fds[0]) * (listen_fds_num + n));
+ if (temp == NULL)
+ {
+ fprintf (stderr, "rrdcached: open_listen_socket_systemd: realloc failed.\n");
+ return 0;
+ }
+ listen_fds = temp;
+
+ for (unsigned int i = 0; i < n; i++)
+ {
+ sd_fd = SD_LISTEN_FDS_START + i;
+
+ l = sizeof(sa);
+ memset(&sa, 0, l);
+ if (getsockname(sd_fd, &sa, &l) < 0)
+ {
+ fprintf(stderr, "open_listen_sockets_systemd: problem getting fd %d: %s\n", sd_fd, rrd_strerror (errno));
+ return i;
+ }
+
+ listen_fds[listen_fds_num].fd = sd_fd;
+ listen_fds[listen_fds_num].family = sa.sun_family;
+ listen_fds_num++;
+ }
+
+ return n;
+} /* }}} open_listen_sockets_systemd */
+
+static void open_listen_sockets_traditional(void) /* {{{ */
+{
+ if (config_listen_address_list_len > 0)
+ {
+ for (size_t i = 0; i < config_listen_address_list_len; i++)
+ open_listen_socket (config_listen_address_list[i]);
+
+ rrd_free_ptrs((void ***) &config_listen_address_list,
+ &config_listen_address_list_len);
+ }
+ else
+ {
+ strncpy(default_socket.addr, RRDCACHED_DEFAULT_ADDRESS,
+ sizeof(default_socket.addr) - 1);
+ default_socket.addr[sizeof(default_socket.addr) - 1] = '\0';
+
+ if (default_socket.permissions == 0)
+ socket_permission_set_all (&default_socket);
+
+ open_listen_socket (&default_socket);
+ }
+} /* }}} open_list_sockets_traditional */
+
static int close_listen_sockets (void) /* {{{ */
{
size_t i;
if (pid_fd < 0)
return pid_fd;
- /* open all the listen sockets */
- if (config_listen_address_list_len > 0)
- {
- for (size_t i = 0; i < config_listen_address_list_len; i++)
- open_listen_socket (config_listen_address_list[i]);
+ /* gather sockets passed from systemd;
+ * if none, open all the listen sockets from config or default */
- rrd_free_ptrs((void ***) &config_listen_address_list,
- &config_listen_address_list_len);
- }
- else
- {
- strncpy(default_socket.addr, RRDCACHED_DEFAULT_ADDRESS,
- sizeof(default_socket.addr) - 1);
- default_socket.addr[sizeof(default_socket.addr) - 1] = '\0';
-
- if (default_socket.permissions == 0)
- socket_permission_set_all (&default_socket);
-
- open_listen_socket (&default_socket);
- }
+ if (!(open_listen_sockets_systemd() > 0))
+ open_listen_sockets_traditional();
if (listen_fds_num < 1)
{