summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-11-24 16:34:20 -0500
committerDave Barach <dave@barachs.net>2016-11-24 16:36:01 -0500
commit23a7412bda2c14b21deda66bc5555c9ee680dec8 (patch)
tree393b2d8879417e617ae7628ffca0c2def5250eda
parent4e969f9c188e79b6b03589b91fadf33062c2152c (diff)
String (key,value) pair serialization
Change-Id: I0e713b5ee82e246d4e5bca138683f3205e984561 Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--svm/svmdb.c119
-rw-r--r--svm/svmdb.h4
-rw-r--r--svm/svmdbtool.c39
3 files changed, 162 insertions, 0 deletions
diff --git a/svm/svmdb.c b/svm/svmdb.c
index c0680bc3279..03dfe7c33d3 100644
--- a/svm/svmdb.c
+++ b/svm/svmdb.c
@@ -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)
{
diff --git a/svm/svmdb.h b/svm/svmdb.h
index a113c22d10d..e02628a0bb9 100644
--- a/svm/svmdb.h
+++ b/svm/svmdb.h
@@ -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__ */
/*
diff --git a/svm/svmdbtool.c b/svm/svmdbtool.c
index a98b22a1272..a0af15fcbbf 100644
--- a/svm/svmdbtool.c
+++ b/svm/svmdbtool.c
@@ -121,6 +121,32 @@ dump_strings (char *chroot_path)
}
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)
{
svmdb_client_t *c;
@@ -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;