fix flush race in rrdcached -- Christian Hitz
[rrdtool.git] / src / rrd_daemon.c
index 79fbc31..2c81424 100644 (file)
  * Now for some includes..
  */
 /* {{{ */
  * 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"
 
 #include "rrd_tool.h"
 #include "rrd_client.h"
@@ -188,7 +181,7 @@ struct cache_item_s
   size_t values_num;           /* number of valid pointers */
   size_t values_alloc;         /* number of allocated pointers */
   time_t last_flush_time;
   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;
 #define CI_FLAGS_IN_TREE  (1<<0)
 #define CI_FLAGS_IN_QUEUE (1<<1)
   int flags;
@@ -302,7 +295,9 @@ static int handle_request_help (HANDLER_PROTO);
 static void sig_common (const char *sig) /* {{{ */
 {
   RRDD_LOG(LOG_NOTICE, "caught SIG%s", sig);
 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 */
   pthread_cond_broadcast(&flush_cond);
   pthread_cond_broadcast(&queue_cond);
 } /* }}} void sig_common */
@@ -1331,7 +1326,7 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
 
   /* save it for the journal later */
   if (!JOURNAL_REPLAY(sock))
 
   /* 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)
 
   status = buffer_get_field (&buffer, &buffer_size, &file);
   if (status != 0)
@@ -1422,7 +1417,7 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
   while (buffer_size > 0)
   {
     char *value;
   while (buffer_size > 0)
   {
     char *value;
-    time_t stamp;
+    double stamp;
     char *eostamp;
 
     status = buffer_get_field (&buffer, &buffer_size, &value);
     char *eostamp;
 
     status = buffer_get_field (&buffer, &buffer_size, &value);
@@ -1432,8 +1427,9 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
       break;
     }
 
       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);
     if (eostamp == value || eostamp == NULL || *eostamp != ':')
     {
       pthread_mutex_unlock(&cache_lock);
@@ -1444,8 +1440,8 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
     {
       pthread_mutex_unlock(&cache_lock);
       return send_response(sock, RESP_ERR,
     {
       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
                            stamp, ci->last_update_stamp);
     }
     else
@@ -2653,7 +2649,7 @@ static void *connection_thread_main (void *args) /* {{{ */
      getting overwritten by another thread.
   */
   struct request_info req;
      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));
   fromhost(&req);
   if(!hosts_access(&req)) {
     RRDD_LOG(LOG_INFO, "refused connection from %s", eval_client(&req));