#include <vppinfra/heap.h>
#include <vppinfra/pool.h>
#include <vppinfra/format.h>
+#include <vppinfra/serialize.h>
#include "svmdb.h"
pthread_mutex_unlock (&rp->mutex);
}
-static svmdb_client_t *
-svmdb_map_internal (char *root_path, uword size)
+svmdb_client_t *
+svmdb_map (svmdb_map_args_t * dba)
{
svmdb_client_t *client = 0;
svm_map_region_args_t *a = 0;
vec_validate (client, 0);
vec_validate (a, 0);
- svm_region_init_chroot (root_path);
+ svm_region_init_chroot_uid_gid (dba->root_path, dba->uid, dba->gid);
- a->root_path = root_path;
+ a->root_path = dba->root_path;
a->name = "/db";
- a->size = size ? size : SVMDB_DEFAULT_SIZE;
+ a->size = dba->size ? dba->size : SVMDB_DEFAULT_SIZE;
a->flags = SVM_FLAGS_MHEAP;
+ a->uid = dba->uid;
+ a->gid = dba->gid;
db_rp = client->db_rp = svm_region_find_or_create (a);
return (client);
}
-svmdb_client_t *
-svmdb_map (void)
-{
- return svmdb_map_internal (0, 0);
-}
-
-svmdb_client_t *
-svmdb_map_size (uword size)
-{
- return svmdb_map_internal (0, size);
-}
-
-svmdb_client_t *
-svmdb_map_chroot (char *root_path)
-{
- return svmdb_map_internal (root_path, 0);
-}
-
-svmdb_client_t *
-svmdb_map_chroot_size (char *root_path, uword size)
-{
- return svmdb_map_internal (root_path, size);
-}
-
void
svmdb_unmap (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)
{