src/rrd_client.h: Renamed the defines to be more consistent with other names.
[rrdtool.git] / src / rrd_daemon.c
index 7423088..9712fcd 100644 (file)
@@ -144,6 +144,8 @@ static cache_item_t   *cache_queue_tail = NULL;
 static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t  cache_cond = PTHREAD_COND_INITIALIZER;
 
+static pthread_cond_t  flush_cond = PTHREAD_COND_INITIALIZER;
+
 static int config_write_interval = 300;
 static int config_flush_interval = 3600;
 
@@ -355,6 +357,7 @@ static void *queue_thread_main (void *args __attribute__((unused))) /* {{{ */
       free (values[i]);
 
     pthread_mutex_lock (&cache_lock);
+    pthread_cond_broadcast (&flush_cond);
   } /* while (do_shutdown == 0) */
   pthread_mutex_unlock (&cache_lock);
 
@@ -423,6 +426,79 @@ static int buffer_get_field (char **buffer_ret, /* {{{ */
   return (0);
 } /* }}} int buffer_get_field */
 
+static int flush_file (const char *filename) /* {{{ */
+{
+  cache_item_t *ci;
+
+  pthread_mutex_lock (&cache_lock);
+
+  ci = g_tree_lookup (cache_tree, filename);
+  if (ci == NULL)
+  {
+    pthread_mutex_unlock (&cache_lock);
+    return (ENOENT);
+  }
+
+  /* Enqueue at head */
+  enqueue_cache_item (ci, HEAD);
+  pthread_cond_signal (&cache_cond);
+
+  while ((ci->flags & CI_FLAGS_IN_QUEUE) != 0)
+  {
+    ci = NULL;
+
+    pthread_cond_wait (&flush_cond, &cache_lock);
+
+    ci = g_tree_lookup (cache_tree, filename);
+    if (ci == NULL)
+    {
+      RRDD_LOG (LOG_ERR, "flush_file: Tree node went away "
+          "while waiting for flush.");
+      pthread_mutex_unlock (&cache_lock);
+      return (-1);
+    }
+  }
+
+  pthread_mutex_unlock (&cache_lock);
+  return (0);
+} /* }}} int flush_file */
+
+static int handle_request_flush (int fd, /* {{{ */
+    char *buffer, size_t buffer_size)
+{
+  char *file;
+  int status;
+  char result[4096];
+
+  status = buffer_get_field (&buffer, &buffer_size, &file);
+  if (status != 0)
+  {
+    RRDD_LOG (LOG_INFO, "handle_request_flush: Cannot get file name.");
+    return (-1);
+  }
+
+  status = flush_file (file);
+  if (status == 0)
+    snprintf (result, sizeof (result), "0 Successfully flushed %s.\n", file);
+  else if (status == ENOENT)
+    snprintf (result, sizeof (result), "-1 No such file: %s.\n", file);
+  else if (status < 0)
+    strncpy (result, "-1 Internal error.\n", sizeof (result));
+  else
+    snprintf (result, sizeof (result), "-1 Failed with status %i.\n", status);
+  result[sizeof (result) - 1] = 0;
+
+  status = write (fd, result, strlen (result));
+  if (status < 0)
+  {
+    status = errno;
+    RRDD_LOG (LOG_INFO, "handle_request_flush: write(2) returned an error.");
+    return (status);
+  }
+
+  return (0);
+} /* }}} int handle_request_flush */
+
 static int handle_request_update (int fd, /* {{{ */
     char *buffer, size_t buffer_size)
 {
@@ -544,7 +620,11 @@ static int handle_request (int fd) /* {{{ */
   int status;
 
   status = read (fd, buffer, sizeof (buffer));
-  if (status < 1)
+  if (status == 0)
+  {
+    return (1);
+  }
+  else if (status < 0)
   {
     RRDD_LOG (LOG_ERR, "handle_request: read(2) failed.");
     return (-1);
@@ -557,6 +637,14 @@ static int handle_request (int fd) /* {{{ */
     RRDD_LOG (LOG_INFO, "handle_request: malformed request.");
     return (-1);
   }
+
+  /* Accept Windows style line endings, too */
+  if ((buffer_size > 2) && (buffer[buffer_size - 2] == '\r'))
+  {
+    buffer_size--;
+    buffer[buffer_size - 1] = '\n';
+  }
+
   /* Place the normal field separator at the end to simplify
    * `buffer_get_field's work. */
   buffer[buffer_size - 1] = ' ';
@@ -574,6 +662,10 @@ static int handle_request (int fd) /* {{{ */
   {
     return (handle_request_update (fd, buffer_ptr, buffer_size));
   }
+  else if (strcmp (command, "flush") == 0)
+  {
+    return (handle_request_flush (fd, buffer_ptr, buffer_size));
+  }
   else
   {
     RRDD_LOG (LOG_INFO, "handle_request: unknown command: %s.", buffer);
@@ -754,7 +846,7 @@ static int open_listen_socket (const char *addr) /* {{{ */
   ai_hints.ai_socktype = SOCK_STREAM;
 
   ai_res = NULL;
-  status = getaddrinfo (addr, DEFAULT_PORT, &ai_hints, &ai_res);
+  status = getaddrinfo (addr, RRDCACHED_DEFAULT_PORT, &ai_hints, &ai_res);
   if (status != 0)
   {
     RRDD_LOG (LOG_ERR, "open_listen_socket: getaddrinfo(%s) failed: "
@@ -842,7 +934,7 @@ static void *listen_thread_main (void *args __attribute__((unused))) /* {{{ */
   }
 
   if (config_listen_address_list_len < 1)
-    open_listen_socket (RRDD_SOCK_PATH);
+    open_listen_socket (RRDCACHED_DEFAULT_ADDRESS);
 
   if (listen_fds_num < 1)
   {