String (key,value) pair serialization
authorDave Barach <[email protected]>
Thu, 24 Nov 2016 21:34:20 +0000 (16:34 -0500)
committerDave Barach <[email protected]>
Thu, 24 Nov 2016 21:36:01 +0000 (16:36 -0500)
Change-Id: I0e713b5ee82e246d4e5bca138683f3205e984561
Signed-off-by: Dave Barach <[email protected]>
svm/svmdb.c
svm/svmdb.h
svm/svmdbtool.c

index c0680bc..03dfe7c 100644 (file)
@@ -39,6 +39,7 @@
 #include <vppinfra/heap.h>
 #include <vppinfra/pool.h>
 #include <vppinfra/format.h>
+#include <vppinfra/serialize.h>
 
 #include "svmdb.h"
 
@@ -421,6 +422,124 @@ svmdb_local_dump_strings (svmdb_client_t * client)
   region_unlock (client->db_rp);
 }
 
+int
+svmdb_local_serialize_strings (svmdb_client_t * client, char *filename)
+{
+  uword *h;
+  u8 *key;
+  u32 value;
+  svmdb_shm_hdr_t *shm = client->shm;
+  serialize_main_t _sm, *sm = &_sm;
+  clib_error_t *error = 0;
+  u8 *sanitized_name = 0;
+  int fd = 0;
+
+  if (strstr (filename, "..") || index (filename, '/'))
+    {
+      error = clib_error_return (0, "Illegal characters in filename '%s'",
+                                filename);
+      goto out;
+    }
+
+  sanitized_name = format (0, "/tmp/%s%c", filename, 0);
+
+  fd = creat ((char *) sanitized_name, 0644);
+
+  if (fd < 0)
+    {
+      error = clib_error_return_unix (0, "Create '%s'", sanitized_name);
+      goto out;
+    }
+
+  serialize_open_unix_file_descriptor (sm, fd);
+
+  region_lock (client->db_rp, 20);
+
+  h = client->shm->namespaces[SVMDB_NAMESPACE_STRING];
+
+  serialize_likely_small_unsigned_integer (sm, hash_elts (h));
+
+  /* *INDENT-OFF* */
+  hash_foreach_mem(key, value, h,
+  ({
+    svmdb_value_t *v = pool_elt_at_index (shm->values, value);
+
+    /* Omit names with nil values */
+    if (vec_len(v->value))
+      {
+        serialize_cstring (sm, (char *)key);
+        serialize_cstring (sm, (char *)v->value);
+      }
+  }));
+  /* *INDENT-ON* */
+  region_unlock (client->db_rp);
+
+  serialize_close (sm);
+
+out:
+  if (fd > 0 && close (fd) < 0)
+    error = clib_error_return_unix (0, "close fd %d", fd);
+
+  if (error)
+    {
+      clib_error_report (error);
+      return -1;
+    }
+  return 0;
+}
+
+int
+svmdb_local_unserialize_strings (svmdb_client_t * client, char *filename)
+{
+  serialize_main_t _sm, *sm = &_sm;
+  void *oldheap;
+  clib_error_t *error = 0;
+  u8 *key, *value;
+  int fd = 0;
+  u32 nelts;
+  int i;
+
+  fd = open (filename, O_RDONLY);
+
+  if (fd < 0)
+    {
+      error = clib_error_return_unix (0, "Failed to open '%s'", filename);
+      goto out;
+    }
+
+  unserialize_open_unix_file_descriptor (sm, fd);
+
+  region_lock (client->db_rp, 21);
+  oldheap = svm_push_data_heap (client->db_rp);
+
+  nelts = unserialize_likely_small_unsigned_integer (sm);
+
+  for (i = 0; i < nelts; i++)
+    {
+      unserialize_cstring (sm, (char **) &key);
+      unserialize_cstring (sm, (char **) &value);
+      local_set_variable_nolock (client, SVMDB_NAMESPACE_STRING,
+                                key, value, 1 /* elsize */ );
+      vec_free (key);
+      vec_free (value);
+    }
+  svm_pop_heap (oldheap);
+  region_unlock (client->db_rp);
+
+  serialize_close (sm);
+
+out:
+  if (fd > 0 && close (fd) < 0)
+    error = clib_error_return_unix (0, "close fd %d", fd);
+
+  if (error)
+    {
+      clib_error_report (error);
+      return -1;
+    }
+  return 0;
+}
+
 void
 svmdb_local_unset_vec_variable (svmdb_client_t * client, char *var)
 {
index a113c22..e02628a 100644 (file)
@@ -120,6 +120,10 @@ int svmdb_local_add_del_notification (svmdb_client_t * client,
 void *svmdb_local_find_or_add_vec_variable (svmdb_client_t * client,
                                            char *var, u32 nbytes);
 
+int svmdb_local_serialize_strings (svmdb_client_t * client, char *filename);
+int svmdb_local_unserialize_strings (svmdb_client_t * client, char *filename);
+
+
 #endif /* __included_svmdb_h__ */
 
 /*
index a98b22a..a0af15f 100644 (file)
@@ -120,6 +120,32 @@ dump_strings (char *chroot_path)
   svmdb_unmap (c);
 }
 
+static void
+serialize_strings (char *chroot_path, char *filename)
+{
+  svmdb_client_t *c;
+  svmdb_map_args_t *ma;
+
+  ma = map_arg_setup (chroot_path);
+
+  c = svmdb_map (ma);
+  (void) svmdb_local_serialize_strings (c, filename);
+  svmdb_unmap (c);
+}
+
+static void
+unserialize_strings (char *chroot_path, char *filename)
+{
+  svmdb_client_t *c;
+  svmdb_map_args_t *ma;
+
+  ma = map_arg_setup (chroot_path);
+
+  c = svmdb_map (ma);
+  (void) svmdb_local_unserialize_strings (c, filename);
+  svmdb_unmap (c);
+}
+
 static void
 test_vlib_vec_rate (char *chroot_path, f64 vr)
 {
@@ -344,6 +370,7 @@ main (int argc, char **argv)
   u8 *vbl = 0, *value = 0;
   char *chroot_path = 0;
   u8 *chroot_path_u8;
+  u8 *filename;
   uword size;
   f64 vr;
   int uid, gid, rv;
@@ -467,6 +494,18 @@ main (int argc, char **argv)
          vec_free (s);
          svmdbtool_main.gid = grp->gr_gid;
        }
+      else if (unformat (&input, "serialize-strings %s", &filename))
+       {
+         vec_add1 (filename, 0);
+         serialize_strings (chroot_path, (char *) filename);
+         parsed++;
+       }
+      else if (unformat (&input, "unserialize-strings %s", &filename))
+       {
+         vec_add1 (filename, 0);
+         unserialize_strings (chroot_path, (char *) filename);
+         parsed++;
+       }
       else
        {
          break;