diff options
author | Dave Barach <dave@barachs.net> | 2016-11-24 16:34:20 -0500 |
---|---|---|
committer | Dave Barach <dave@barachs.net> | 2016-11-24 16:36:01 -0500 |
commit | 23a7412bda2c14b21deda66bc5555c9ee680dec8 (patch) | |
tree | 393b2d8879417e617ae7628ffca0c2def5250eda | |
parent | 4e969f9c188e79b6b03589b91fadf33062c2152c (diff) |
String (key,value) pair serialization
Change-Id: I0e713b5ee82e246d4e5bca138683f3205e984561
Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r-- | svm/svmdb.c | 119 | ||||
-rw-r--r-- | svm/svmdb.h | 4 | ||||
-rw-r--r-- | svm/svmdbtool.c | 39 |
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; |