Hello list,

As advice me Kevin, I post you my code to add the CREATE method to
RRDcached.
As I am a well experimented coder, I would be really grateful if I could
get some advices to improve this code (and I hope it will be commited when
clean).

You'll find enclosed the path to get this new feature. (It was down on the
yesterday svn snapshot.)

Yann 

On Wed, 7 Jan 2009 20:59:22 -0600, kevin brintnall <[email protected]>
wrote:
> On Mon, Jan 05, 2009 at 11:13:47AM -0600, kevin brintnall wrote:
>> Syntax-checking the CREATE check would probably require separating out
>> some of the code from rrd_update_r.
> 
> Sorry, just noticed...  I meant "... code from rrd_create_r".
> 
> --
>  kevin brintnall =~ /[email protected]/
--- ./src/rrd_client.c	2008-10-17 07:50:22.000000000 +0200
+++ ../rrdtool-1.3.99909021600working/src/rrd_client.c	2009-02-17 17:15:45.000000000 +0100
@@ -508,6 +508,70 @@
   return (0);
 } /* }}} int rrdc_disconnect */
 
+int rrdc_create (const char *filename, unsigned long pdp_step, time_t last_up,  int values_num, /* {{{ */
+		const char * const *values)
+{
+  char buffer[4096];
+  char *buffer_ptr;
+  char str_tmp[32];
+  size_t buffer_free;
+  size_t buffer_size;
+  rrdc_response_t *res;
+  int status;
+  int i;
+
+  char file_path[PATH_MAX];
+
+  memset (buffer, 0, sizeof (buffer));
+  buffer_ptr = &buffer[0];
+  buffer_free = sizeof (buffer);
+
+  status = buffer_add_string ("create", &buffer_ptr, &buffer_free);
+  if (status != 0)
+    return (ENOBUFS);
+
+  /* change to absolute path for rrdcached */
+  if (*filename != '/' && realpath(filename, file_path) != NULL)
+      filename = file_path;
+
+  status = buffer_add_string (filename, &buffer_ptr, &buffer_free);
+  if (status != 0)
+    return (ENOBUFS);
+  snprintf(str_tmp, 32, "b:%lu", last_up);
+  status = buffer_add_string (str_tmp, &buffer_ptr, &buffer_free);
+  if (status != 0)
+    return (ENOBUFS);
+  snprintf(str_tmp, 32, "s:%lu", pdp_step);
+  status = buffer_add_string (str_tmp, &buffer_ptr, &buffer_free);
+  if (status != 0)
+    return (ENOBUFS);
+
+
+
+  for (i = 0; i < values_num; i++)
+  {
+    status = buffer_add_value (values[i], &buffer_ptr, &buffer_free);
+    if (status != 0)
+      return (ENOBUFS);
+  }
+
+  assert (buffer_free < sizeof (buffer));
+  buffer_size = sizeof (buffer) - buffer_free;
+  assert (buffer[buffer_size - 1] == ' ');
+  buffer[buffer_size - 1] = '\n';
+
+  res = NULL;
+  status = request (buffer, buffer_size, &res);
+  if (status != 0)
+    return (status);
+
+  status = res->status;
+  response_free (res);
+
+  return (status);
+} /* }}} int rrdc_create */
+
+
 int rrdc_update (const char *filename, int values_num, /* {{{ */
 		const char * const *values)
 {
--- ./src/rrd_create.c	2008-11-18 18:19:17.000000000 +0100
+++ ../rrdtool-1.3.99909021600working/src/rrd_create.c	2009-02-17 17:19:21.000000000 +0100
@@ -11,6 +11,8 @@
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
 #include "rrd_hw.h"
+#include "rrd_client.h"
+
 
 #include "rrd_is_thread_safe.h"
 
@@ -39,6 +41,7 @@
     struct option long_options[] = {
         {"start", required_argument, 0, 'b'},
         {"step", required_argument, 0, 's'},
+	{"daemon",   required_argument, 0, 'd'},
         {0, 0, 0, 0}
     };
     int       option_index = 0;
@@ -49,12 +52,14 @@
     char     *parsetime_error = NULL;
     long      long_tmp;
     int       rc;
+    char     *opt_daemon = NULL;
+
 
     optind = 0;
     opterr = 0;         /* initialize getopt */
 
     while (1) {
-        opt = getopt_long(argc, argv, "b:s:", long_options, &option_index);
+        opt = getopt_long(argc, argv, "b:s:d:", long_options, &option_index);
 
         if (opt == EOF)
             break;
@@ -81,7 +86,18 @@
             }
             break;
 
-        case 's':
+	case 'd':
+            if (opt_daemon != NULL)
+                free (opt_daemon);
+            opt_daemon = strdup (optarg);
+            if (opt_daemon == NULL)
+            {
+                rrd_set_error("strdup failed.");
+                goto out;
+            }
+            break;
+
+	case 's':
             long_tmp = atol(optarg);
             if (long_tmp < 1) {
                 rrd_set_error("step size should be no less than one second");
@@ -102,9 +118,36 @@
         rrd_set_error("need name of an rrd file to create");
         return -1;
     }
-    rc = rrd_create_r(argv[optind],
+    
+    {   /* try to connect to rrdcached */
+        int status = rrdc_connect(opt_daemon);
+        if (status != 0) return status;
+    }
+
+   if ( !rrdc_is_connected(opt_daemon))
+    {
+      rc = rrd_create_r(argv[optind],
                       pdp_step, last_up,
                       argc - optind - 1, (const char **) (argv + optind + 1));
+    }
+    else /* we are connected */
+    {
+	rc = rrdc_create(argv[optind], /*file name*/
+                      pdp_step, last_up,
+                      argc - optind - 1, /*values number*/
+		      (const char **) (argv + optind + 1)); /*values*/
+
+        if (rc > 0)
+            rrd_set_error("Failed sending the values to rrdcached: %s",
+                          rrd_strerror (rc));
+    }
+
+  out:
+    if (opt_daemon != NULL)
+    {
+        free (opt_daemon);
+        opt_daemon = NULL;
+    }
 
     return rc;
 }
--- ./src/rrd_daemon.c	2008-11-18 18:19:17.000000000 +0100
+++ ../rrdtool-1.3.99909021600working/src/rrd_daemon.c	2009-02-17 15:03:54.000000000 +0100
@@ -971,7 +971,7 @@
   *field_ret = field;
 
   return (0);
-} /* }}} int buffer_get_field */
+} /* }}} int //buffer_get_field */
 
 /* if we're restricting writes to the base directory,
  * check whether the file falls within the dir
@@ -1140,6 +1140,13 @@
     "<num_vals> <filename>\n"
     "\n"
   };
+  
+  char *help_create[2] = 
+  {
+    "Help for CREATE\n"
+    ,
+    "Usage: CREATE <filename> <create definition>\n"
+  };
 
   char *help_update[2] =
   {
@@ -1202,6 +1209,8 @@
   {
     if (strcasecmp (command, "update") == 0)
       help_text = help_update;
+    else if (strcasecmp (command, "create") == 0)
+      help_text = help_create;
     else if (strcasecmp (command, "flush") == 0)
       help_text = help_flush;
     else if (strcasecmp (command, "flushall") == 0)
@@ -1423,6 +1432,59 @@
   return send_response(sock, RESP_OK, "in queue.\n");
 } /* }}} int handle_request_queue */
 
+static int handle_request_create (listen_socket_t *sock, 
+                                  time_t now,
+                                  char *buffer, size_t buffer_size)
+{
+  int status;
+  char *file;
+  char file_tmp[PATH_MAX];
+  time_t starttime=now-10;
+  unsigned long step = 300; 
+  char *argvalues[32];
+  int argc=0;
+  
+  
+  status = has_privilege(sock, PRIV_HIGH);
+  if (status <= 0)
+    return status;
+  status = buffer_get_field (&buffer, &buffer_size, &file);
+  get_abs_path(&file, file_tmp);
+  if (!check_file_access(file, sock)) return 0;
+
+  if (status != 0)
+    return send_response(sock, RESP_ERR,
+                         "Usage: CREATE <filename> [b:starttime] [s:step] <create definition>\n");
+  
+  while (buffer_size > 0)
+  {
+    char *value;
+
+    status = buffer_get_field (&buffer, &buffer_size, &value);
+    if (status != 0)
+    {
+      RRDD_LOG (LOG_INFO, "handle_request_create: Error reading field.");
+      break;
+    }
+    if (!strncmp(value, "b:", 2)) {
+      sscanf(value, "b:%d", (int *) &starttime);
+      continue;
+      }
+    if (!strncmp(value, "s:", 2)) {
+      sscanf(value, "s:%lu", &step);
+      continue;
+      }
+    argvalues[argc] = value;
+    argc++;
+    }
+   
+   status = rrd_create_r( (const char*) file, step, starttime, argc, (const char **) argvalues);
+   if (status)
+      return send_response(sock, RESP_ERR, "Error while creating rrd (%s)\n",rrd_get_error());
+   else
+      return send_response(sock, RESP_OK, "RRD created successfully (%s)\n", file);
+}
+
 static int handle_request_update (listen_socket_t *sock, /* {{{ */
                                   time_t now,
                                   char *buffer, size_t buffer_size)
@@ -1669,6 +1731,8 @@
 
   if (strcasecmp (command, "update") == 0)
     return (handle_request_update (sock, now, buffer_ptr, buffer_size));
+  else if (strcasecmp (command, "create") == 0)
+    return (handle_request_create (sock, now, buffer_ptr, buffer_size));
   else if (strcasecmp (command, "wrote") == 0 && sock == NULL)
   {
     /* this is only valid in replay mode */
_______________________________________________
rrd-developers mailing list
[email protected]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers

Reply via email to