summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/dict.c
diff options
context:
space:
mode:
authorAmar Tumballi <amarts@redhat.com>2017-12-19 16:10:11 +0530
committerAmar Tumballi <amarts@redhat.com>2017-12-27 05:20:30 +0000
commitb868d6077c14e3653fdaddcb856ab2bf6ceb9c00 (patch)
tree201f61db8690929aa967808816b49d1d4280c385 /libglusterfs/src/dict.c
parent9a47978877a5415dbbac94b93b4b30d055349681 (diff)
dict: support better on-wire transfer
This patch brings data type awareness to dictionary, and also makes sure valid data is properly sent to the other side of the wire using XDR. Next step is to allow people to add more data types (for example, Bool, UUID, iatt etc), and then make it part of every fop signature in wire. Fixes #203 Change-Id: Ie0eee2db847bea2bf7dad80dec89ce3e7c5917c1 Signed-off-by: Amar Tumballi <amarts@redhat.com>
Diffstat (limited to 'libglusterfs/src/dict.c')
-rw-r--r--libglusterfs/src/dict.c286
1 files changed, 219 insertions, 67 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index d0be267d2ee..1ce176e381c 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -28,11 +28,30 @@
#include "statedump.h"
#include "libglusterfs-messages.h"
+#include "glusterfs-fops.h"
+#include "rpc-common-xdr.h"
+
struct dict_cmp {
dict_t *dict;
gf_boolean_t (*value_ignore) (char *k);
};
+#define VALIDATE_DATA_AND_LOG(data, type, ret_val) do { \
+ if (!data || !data->data) { \
+ gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL, \
+ LG_MSG_INVALID_ARG, "data is NULL"); \
+ return ret_val; \
+ } \
+ \
+ if (data->data_type != type) { \
+ gf_msg_callingfn ("dict", GF_LOG_INFO, EINVAL, \
+ LG_MSG_INVALID_ARG, \
+ "%s type asked, has %s type", \
+ data_type_name[type], \
+ data_type_name[data->data_type]); \
+ } \
+ } while (0)
+
data_t *
get_new_data ()
{
@@ -253,6 +272,7 @@ data_copy (data_t *old)
if (!newdata->data)
goto err_out;
}
+ newdata->data_type = old->data_type;
}
LOCK_INIT (&newdata->lock);
@@ -704,6 +724,7 @@ int_to_data (int64_t value)
return NULL;
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_INT;
return data;
}
@@ -723,6 +744,7 @@ data_from_int64 (int64_t value)
return NULL;
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_INT;
return data;
}
@@ -743,6 +765,7 @@ data_from_int32 (int32_t value)
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_INT;
return data;
}
@@ -763,6 +786,7 @@ data_from_int16 (int16_t value)
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_INT;
return data;
}
@@ -783,6 +807,7 @@ data_from_int8 (int8_t value)
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_INT;
return data;
}
@@ -803,6 +828,7 @@ data_from_uint64 (uint64_t value)
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_UINT;
return data;
}
@@ -824,6 +850,7 @@ data_from_double (double value)
return NULL;
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_DOUBLE;
return data;
}
@@ -845,6 +872,7 @@ data_from_uint32 (uint32_t value)
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_UINT;
return data;
}
@@ -865,6 +893,7 @@ data_from_uint16 (uint16_t value)
}
data->len = strlen (data->data) + 1;
+ data->data_type = GF_DATA_TYPE_UINT;
return data;
}
@@ -882,6 +911,7 @@ data_from_ptr_common (void *value, gf_boolean_t is_static)
data->data = value;
data->is_static = is_static;
+ data->data_type = GF_DATA_TYPE_PTR;
return data;
}
@@ -899,6 +929,7 @@ str_to_data (char *value)
return NULL;
}
data->len = strlen (value) + 1;
+ data->data_type = GF_DATA_TYPE_STR;
data->data = value;
data->is_static = 1;
@@ -921,6 +952,7 @@ data_from_dynstr (char *value)
return NULL;
data->len = strlen (value) + 1;
data->data = value;
+ data->data_type = GF_DATA_TYPE_STR;
return data;
}
@@ -935,6 +967,7 @@ data_from_dynptr (void *value, int32_t len)
data->len = len;
data->data = value;
+ data->data_type = GF_DATA_TYPE_PTR;
return data;
}
@@ -956,18 +989,24 @@ bin_to_data (void *value, int32_t len)
data->is_static = 1;
data->len = len;
data->data = value;
+ data->data_type = GF_DATA_TYPE_PTR;
return data;
}
+static char *data_type_name[GF_DATA_TYPE_MAX] = {
+ [GF_DATA_TYPE_UNKNOWN] = "unknown",
+ [GF_DATA_TYPE_INT] = "integer",
+ [GF_DATA_TYPE_UINT] = "unsigned integer",
+ [GF_DATA_TYPE_DOUBLE] = "float",
+ [GF_DATA_TYPE_STR] = "string",
+ [GF_DATA_TYPE_PTR] = "pointer",
+};
+
int64_t
data_to_int64 (data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -1);
char *str = alloca (data->len + 1);
if (!str)
@@ -981,11 +1020,7 @@ data_to_int64 (data_t *data)
int32_t
data_to_int32 (data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -1);
char *str = alloca (data->len + 1);
if (!str)
@@ -1000,14 +1035,9 @@ data_to_int32 (data_t *data)
int16_t
data_to_int16 (data_t *data)
{
- int16_t value = 0;
-
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -1);
+ int16_t value = 0;
char *str = alloca (data->len + 1);
if (!str)
return -1;
@@ -1033,14 +1063,9 @@ data_to_int16 (data_t *data)
int8_t
data_to_int8 (data_t *data)
{
- int8_t value = 0;
-
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -1);
+ int8_t value = 0;
char *str = alloca (data->len + 1);
if (!str)
return -1;
@@ -1066,8 +1091,8 @@ data_to_int8 (data_t *data)
uint64_t
data_to_uint64 (data_t *data)
{
- if (!data)
- return -1;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, -1);
+
char *str = alloca (data->len + 1);
if (!str)
return -1;
@@ -1081,8 +1106,7 @@ data_to_uint64 (data_t *data)
uint32_t
data_to_uint32 (data_t *data)
{
- if (!data)
- return -1;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, -1);
char *str = alloca (data->len + 1);
if (!str)
@@ -1097,11 +1121,9 @@ data_to_uint32 (data_t *data)
uint16_t
data_to_uint16 (data_t *data)
{
- uint16_t value = 0;
-
- if (!data)
- return -1;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, -1);
+ uint16_t value = 0;
char *str = alloca (data->len + 1);
if (!str)
return -1;
@@ -1127,14 +1149,9 @@ data_to_uint16 (data_t *data)
uint8_t
data_to_uint8 (data_t *data)
{
- uint32_t value = 0;
-
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, -1);
+ uint32_t value = 0;
char *str = alloca (data->len + 1);
if (!str)
return -1;
@@ -1159,33 +1176,21 @@ data_to_uint8 (data_t *data)
char *
data_to_str (data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return NULL;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, NULL);
return data->data;
}
void *
data_to_ptr (data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return NULL;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, NULL);
return data->data;
}
void *
data_to_bin (data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return NULL;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, NULL);
return data->data;
}
@@ -1701,6 +1706,8 @@ dict_get_int8 (dict_t *this, char *key, int8_t *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -EINVAL);
+
ret = data_to_int8_ptr (data, val);
err:
@@ -1746,6 +1753,8 @@ dict_get_int16 (dict_t *this, char *key, int16_t *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -EINVAL);
+
ret = data_to_int16_ptr (data, val);
err:
@@ -1791,6 +1800,8 @@ dict_get_int32 (dict_t *this, char *key, int32_t *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -EINVAL);
+
ret = data_to_int32_ptr (data, val);
err:
@@ -1836,6 +1847,8 @@ dict_get_int64 (dict_t *this, char *key, int64_t *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -EINVAL);
+
ret = data_to_int64_ptr (data, val);
err:
@@ -1881,6 +1894,8 @@ dict_get_uint16 (dict_t *this, char *key, uint16_t *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, -EINVAL);
+
ret = data_to_uint16_ptr (data, val);
err:
@@ -1926,6 +1941,8 @@ dict_get_uint32 (dict_t *this, char *key, uint32_t *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, -EINVAL);
+
ret = data_to_uint32_ptr (data, val);
err:
@@ -1972,6 +1989,8 @@ dict_get_uint64 (dict_t *this, char *key, uint64_t *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, -EINVAL);
+
ret = data_to_uint64_ptr (data, val);
err:
@@ -2017,6 +2036,8 @@ dict_get_double (dict_t *this, char *key, double *val)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_DOUBLE, -EINVAL);
+
ret = data_to_double_ptr (data, val);
err:
@@ -2101,6 +2122,8 @@ dict_get_ptr (dict_t *this, char *key, void **ptr)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, -EINVAL);
+
ret = data_to_ptr_common (data, ptr);
if (ret != 0) {
goto err;
@@ -2129,6 +2152,8 @@ dict_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len)
goto err;
}
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, -EINVAL);
+
*len = data->len;
ret = data_to_ptr_common (data, ptr);
@@ -2173,15 +2198,13 @@ dict_get_str (dict_t *this, char *key, char **str)
if (!this || !key || !str) {
goto err;
}
-
ret = dict_get_with_ref (this, key, &data);
if (ret < 0) {
goto err;
}
- if (!data || !data->data) {
- goto err;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, -EINVAL);
+
*str = data->data;
err:
@@ -2290,9 +2313,8 @@ dict_get_bin (dict_t *this, char *key, void **bin)
goto err;
}
- if (!data || !data->data) {
- goto err;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, ret);
+
*bin = data->data;
err:
@@ -2408,12 +2430,7 @@ dict_get_str_boolean (dict_t *this, char *key, int default_val)
goto err;
}
- GF_ASSERT (data);
-
- if (!data->data) {
- ret = -1;
- goto err;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, -EINVAL);
ret = gf_string2boolean (data->data, &boo);
if (ret == -1)
@@ -2823,6 +2840,7 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill)
}
value->len = vallen;
value->data = memdup (buf, vallen);
+ value->data_type = GF_DATA_TYPE_STR;
value->is_static = 0;
buf += vallen;
@@ -3136,3 +3154,137 @@ unlock:
UNLOCK (&dict->lock);
return 0;
}
+
+/* dict_to_xdr () */
+int
+dict_to_xdr (dict_t *this, gfx_dict *dict)
+{
+ int ret = -1;
+ int i = 0;
+ int index = 0;
+ data_pair_t *dpair = NULL;
+ gfx_dict_pair *xpair = NULL;
+
+ if (!this || !dict)
+ goto out;
+
+ dict->pairs.pairs_val = GF_CALLOC (1, (this->count *
+ sizeof (gfx_dict_pair)),
+ gf_common_mt_char);
+ if (!dict->pairs.pairs_val)
+ goto out;
+
+ dpair = this->members_list;
+ for (i = 0; i < this->count; i++) {
+ xpair = &dict->pairs.pairs_val[index];
+
+ xpair->value.type = dpair->value->data_type;
+ xpair->key.key_val = dpair->key;
+ xpair->key.key_len = strlen (dpair->key) + 1;
+
+ switch (dpair->value->data_type) {
+ /* Add more type here */
+ case GF_DATA_TYPE_INT:
+ index++;
+ data_to_int64_ptr (dpair->value, &xpair->value.gfx_value_u.value_int);
+ break;
+ case GF_DATA_TYPE_UINT:
+ index++;
+ data_to_uint64_ptr (dpair->value, &xpair->value.gfx_value_u.value_uint);
+ break;
+ case GF_DATA_TYPE_DOUBLE:
+ index++;
+ data_to_double_ptr (dpair->value,
+ &xpair->value.gfx_value_u.value_dbl);
+ break;
+ case GF_DATA_TYPE_STR:
+ index++;
+ xpair->value.gfx_value_u.val_string.val_string_val = dpair->value->data;
+ xpair->value.gfx_value_u.val_string.val_string_len = dpair->value->len;
+ break;
+ default:
+ /* Unknown type and ptr type is not sent on wire */
+ gf_log ("", GF_LOG_INFO, "%s is not sent on wire", dpair->key);
+ break;
+ }
+
+ dpair = dpair->next;
+ }
+
+ dict->pairs.pairs_len = index;
+ dict->count = index;
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+xdr_to_dict (gfx_dict *dict, dict_t **to)
+{
+ int ret = -1;
+ int index = 0;
+ char *key = NULL;
+ char *value = NULL;
+ gfx_dict_pair *xpair = NULL;
+ dict_t *this = NULL;
+
+ if (!to || !dict)
+ goto out;
+
+ this = dict_new();
+ if (!this)
+ goto out;
+
+ for (index = 0; index < dict->pairs.pairs_len; index++) {
+ ret = -1;
+ xpair = &dict->pairs.pairs_val[index];
+
+ key = xpair->key.key_val;
+ switch (xpair->value.type) {
+ /* Add more type here */
+ case GF_DATA_TYPE_INT:
+ ret = dict_set_int64 (this, key,
+ xpair->value.gfx_value_u.value_int);
+ break;
+ case GF_DATA_TYPE_UINT:
+ ret = dict_set_uint64 (this, key,
+ xpair->value.gfx_value_u.value_uint);
+ break;
+ case GF_DATA_TYPE_DOUBLE:
+ ret = dict_set_double (this, key,
+ xpair->value.gfx_value_u.value_dbl);
+ break;
+ case GF_DATA_TYPE_STR:
+ value = gf_strdup (xpair->value.gfx_value_u.val_string.val_string_val);
+ if (!value) {
+ errno = ENOMEM;
+ goto out;
+ }
+ free (xpair->value.gfx_value_u.val_string.val_string_val);
+ ret = dict_set_dynstr (this, key, value);
+ break;
+ default:
+ ret = 0;
+ /* Unknown type and ptr type is not sent on wire */
+ break;
+ }
+ if (ret) {
+ gf_msg_debug ("dict", ENOMEM,
+ "failed to set the key (%s) into dict",
+ key);
+ }
+ free (xpair->key.key_val);
+ }
+
+ free (dict->pairs.pairs_val);
+ ret = 0;
+
+ /* If everything is fine, assign the dictionary to target */
+ *to = this;
+ this = NULL;
+out:
+ if (this)
+ dict_unref (this);
+
+ return ret;
+}