diff options
| -rw-r--r-- | libglusterfs/src/dict.c | 6 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/dict.h | 6 | ||||
| -rw-r--r-- | libglusterfs/src/libglusterfs.sym | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 27 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 180 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 3 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 5 | 
7 files changed, 187 insertions, 41 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index 2374ab032d1..6648be123b7 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -2799,10 +2799,6 @@ dict_rename_key(dict_t *this, char *key, char *replace_key)   *     4        4         4       <key len>   <value len>   */ -#define DICT_HDR_LEN 4 -#define DICT_DATA_HDR_KEY_LEN 4 -#define DICT_DATA_HDR_VAL_LEN 4 -  /**   * dict_serialized_length_lk - return the length of serialized dict. This   *                             procedure has to be called with this->lock held. @@ -2812,7 +2808,7 @@ dict_rename_key(dict_t *this, char *key, char *replace_key)   *        : failure: -errno   */ -static int +int  dict_serialized_length_lk(dict_t *this)  {      int ret = -EINVAL; diff --git a/libglusterfs/src/glusterfs/dict.h b/libglusterfs/src/glusterfs/dict.h index 52b833fd559..022f564f62a 100644 --- a/libglusterfs/src/glusterfs/dict.h +++ b/libglusterfs/src/glusterfs/dict.h @@ -91,6 +91,9 @@ typedef struct _data_pair data_pair_t;  #define DICT_MAX_FLAGS 256  #define DICT_FLAG_SET 1  #define DICT_FLAG_CLEAR 0 +#define DICT_HDR_LEN 4 +#define DICT_DATA_HDR_KEY_LEN 4 +#define DICT_DATA_HDR_VAL_LEN 4  struct _data {      char *data; @@ -412,4 +415,7 @@ are_dicts_equal(dict_t *one, dict_t *two,                  gf_boolean_t (*value_ignore)(char *k));  int  dict_has_key_from_array(dict_t *dict, char **strings, gf_boolean_t *result); + +int +dict_serialized_length_lk(dict_t *this);  #endif diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index 93ab05f166a..188cda27bc5 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -400,6 +400,7 @@ dict_rename_key  dict_reset  dict_serialize  dict_serialized_length +dict_serialized_length_lk  dict_serialize_value_with_delim  dict_set  dict_setn diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index a6c157e6abb..86ae48c6d6f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -1528,11 +1528,9 @@ glusterd_rpc_friend_add(call_frame_t *frame, xlator_t *this, void *data)      RCU_READ_UNLOCK; -    ret = glusterd_add_volumes_to_export_dict(&peer_data); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, -               "Unable to add list of volumes " -               "in the peer_data dict for handshake"); +    peer_data = dict_new(); +    if (!peer_data) { +        errno = ENOMEM;          goto out;      } @@ -1563,10 +1561,23 @@ glusterd_rpc_friend_add(call_frame_t *frame, xlator_t *this, void *data)          }      } -    ret = dict_allocate_and_serialize(peer_data, &req.vols.vols_val, -                                      &req.vols.vols_len); -    if (ret) +    /* Don't add any key-value in peer_data dictionary after call this function +     */ +    ret = glusterd_add_volumes_to_export_dict(peer_data, &req.vols.vols_val, +                                              &req.vols.vols_len); +    if (ret) { +        gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, +               "Unable to add list of volumes " +               "in the peer_data dict for handshake");          goto out; +    } + +    if (!req.vols.vols_len) { +        ret = dict_allocate_and_serialize(peer_data, &req.vols.vols_val, +                                          &req.vols.vols_len); +        if (ret) +            goto out; +    }      ret = glusterd_submit_request(          peerinfo->rpc, &req, frame, peerinfo->peer, GLUSTERD_FRIEND_ADD, NULL, diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index c919be3270b..eac220a4d57 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -3204,11 +3204,118 @@ out:      return NULL;  } +int +glusterd_dict_searialize(dict_t *dict_arr[], int count, int totcount, char *buf) +{ +    int i = 0; +    int32_t keylen = 0; +    int64_t netword = 0; +    data_pair_t *pair = NULL; +    int dict_count = 0; +    int ret = 0; + +    netword = hton32(totcount); +    memcpy(buf, &netword, sizeof(netword)); +    buf += DICT_HDR_LEN; + +    for (i = 0; i < count; i++) { +        if (dict_arr[i]) { +            dict_count = dict_arr[i]->count; +            pair = dict_arr[i]->members_list; +            while (dict_count) { +                if (!pair) { +                    gf_msg("glusterd", GF_LOG_ERROR, 0, +                           LG_MSG_PAIRS_LESS_THAN_COUNT, +                           "less than count data pairs found!"); +                    ret = -1; +                    goto out; +                } + +                if (!pair->key) { +                    gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, +                           "pair->key is null!"); +                    ret = -1; +                    goto out; +                } + +                keylen = strlen(pair->key); +                netword = hton32(keylen); +                memcpy(buf, &netword, sizeof(netword)); +                buf += DICT_DATA_HDR_KEY_LEN; +                if (!pair->value) { +                    gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, +                           "pair->value is null!"); +                    ret = -1; +                    goto out; +                } + +                netword = hton32(pair->value->len); +                memcpy(buf, &netword, sizeof(netword)); +                buf += DICT_DATA_HDR_VAL_LEN; + +                memcpy(buf, pair->key, keylen); +                buf += keylen; +                *buf++ = '\0'; + +                if (pair->value->data) { +                    memcpy(buf, pair->value->data, pair->value->len); +                    buf += pair->value->len; +                } + +                pair = pair->next; +                dict_count--; +            } +        } +    } + +out: +    for (i = 0; i < count; i++) { +        if (dict_arr[i]) +            dict_unref(dict_arr[i]); +    } +    return ret; +} + +int +glusterd_dict_arr_serialize(dict_t *dict_arr[], int count, char **buf, +                            u_int *length) +{ +    ssize_t len = 0; +    int i = 0; +    int totcount = 0; +    int ret = 0; + +    for (i = 0; i < count; i++) { +        if (dict_arr[i]) { +            len += dict_serialized_length_lk(dict_arr[i]); +            totcount += dict_arr[i]->count; +        } +    } + +    // Subtract HDR_LEN except one dictionary +    len = len - ((count - 1) * DICT_HDR_LEN); + +    *buf = GF_MALLOC(len, gf_common_mt_char); +    if (*buf == NULL) { +        ret = -ENOMEM; +        goto out; +    } + +    if (length != NULL) { +        *length = len; +    } + +    ret = glusterd_dict_searialize(dict_arr, count, totcount, *buf); + +out: +    return ret; +} +  int32_t -glusterd_add_volumes_to_export_dict(dict_t **peer_data) +glusterd_add_volumes_to_export_dict(dict_t *peer_data, char **buf, +                                    u_int *length)  {      int32_t ret = -1; -    dict_t *dict = NULL;      dict_t *dict_arr[128] = {          0,      }; @@ -3234,10 +3341,6 @@ glusterd_add_volumes_to_export_dict(dict_t **peer_data)      priv = this->private;      GF_ASSERT(priv); -    dict = dict_new(); -    if (!dict) -        goto out; -      /* Count the total number of volumes */      cds_list_for_each_entry(volinfo, &priv->volumes, vol_list) volcnt++; @@ -3259,14 +3362,15 @@ glusterd_add_volumes_to_export_dict(dict_t **peer_data)          cds_list_for_each_entry(volinfo, &priv->volumes, vol_list)          {              count++; -            ret = glusterd_add_volume_to_dict(volinfo, dict, count, "volume"); +            ret = glusterd_add_volume_to_dict(volinfo, peer_data, count, +                                              "volume");              if (ret)                  goto out;              if (!dict_get_sizen(volinfo->dict, VKEY_FEATURES_QUOTA))                  continue; -            ret = glusterd_vol_add_quota_conf_to_dict(volinfo, dict, count, +            ret = glusterd_vol_add_quota_conf_to_dict(volinfo, peer_data, count,                                                        "volume");              if (ret)                  goto out; @@ -3308,34 +3412,34 @@ glusterd_add_volumes_to_export_dict(dict_t **peer_data)          gf_log(this->name, GF_LOG_INFO,                 "Finished dictionary popluation in all threads"); -        for (i = 0; i < totthread; i++) { -            dict_copy_with_ref(dict_arr[i], dict); -            dict_unref(dict_arr[i]); -        } -        gf_log(this->name, GF_LOG_INFO, -               "Finished merger of all dictionraies into single one");      } -    ret = dict_set_int32n(dict, "count", SLEN("count"), volcnt); +    ret = dict_set_int32n(peer_data, "count", SLEN("count"), volcnt);      if (ret)          goto out; -    ctx.dict = dict; +    ctx.dict = peer_data;      ctx.prefix = "global";      ctx.opt_count = 1;      ctx.key_name = "key";      ctx.val_name = "val";      dict_foreach(priv->opts, _add_dict_to_prdict, &ctx);      ctx.opt_count--; -    ret = dict_set_int32n(dict, "global-opt-count", SLEN("global-opt-count"), -                          ctx.opt_count); +    ret = dict_set_int32n(peer_data, "global-opt-count", +                          SLEN("global-opt-count"), ctx.opt_count);      if (ret)          goto out; -    *peer_data = dict; +    if (totthread) { +        gf_log(this->name, GF_LOG_INFO, +               "Finished merger of all dictionraies into single one"); +        dict_arr[totthread++] = peer_data; +        ret = glusterd_dict_arr_serialize(dict_arr, totthread, buf, length); +        gf_log(this->name, GF_LOG_INFO, +               "Serialize dictionary data return is %d", ret); +    } +  out: -    if (ret) -        dict_unref(dict);      gf_msg_trace(this->name, 0, "Returning %d", ret);      return ret; @@ -4607,6 +4711,7 @@ glusterd_import_friend_volumes_synctask(void *opaque)      xlator_t *this = NULL;      glusterd_conf_t *conf = NULL;      dict_t *peer_data = NULL; +    glusterd_friend_synctask_args_t *arg = NULL;      this = THIS;      GF_ASSERT(this); @@ -4614,8 +4719,17 @@ glusterd_import_friend_volumes_synctask(void *opaque)      conf = this->private;      GF_ASSERT(conf); -    peer_data = (dict_t *)opaque; -    GF_ASSERT(peer_data); +    arg = opaque; +    peer_data = dict_new(); +    if (!peer_data) { +        goto out; +    } + +    ret = dict_unserialize(arg->dict_buf, arg->dictlen, &peer_data); +    if (ret) { +        errno = ENOMEM; +        goto out; +    }      ret = dict_get_int32n(peer_data, "count", SLEN("count"), &count);      if (ret) @@ -4647,6 +4761,10 @@ glusterd_import_friend_volumes_synctask(void *opaque)  out:      if (peer_data)          dict_unref(peer_data); +    if (arg->dict_buf) +        GF_FREE(arg->dict_buf); +    if (arg) +        GF_FREE(arg);      gf_msg_debug("glusterd", 0, "Returning with %d", ret);      return ret; @@ -4813,7 +4931,7 @@ glusterd_compare_friend_data(dict_t *peer_data, int32_t *status, char *hostname)      gf_boolean_t update = _gf_false;      xlator_t *this = NULL;      glusterd_conf_t *priv = NULL; -    dict_t *peer_data_copy = NULL; +    glusterd_friend_synctask_args_t *arg = NULL;      this = THIS;      GF_ASSERT(this); @@ -4855,9 +4973,17 @@ glusterd_compare_friend_data(dict_t *peer_data, int32_t *status, char *hostname)           * first brick to come up before attaching the subsequent bricks           * in case brick multiplexing is enabled           */ -        peer_data_copy = dict_copy_with_ref(peer_data, NULL); -        glusterd_launch_synctask(glusterd_import_friend_volumes_synctask, -                                 peer_data_copy); +        arg = GF_CALLOC(1, sizeof(*arg), gf_common_mt_char); +        ret = dict_allocate_and_serialize(peer_data, &arg->dict_buf, +                                          &arg->dictlen); +        if (ret < 0) { +            gf_log(this->name, GF_LOG_ERROR, +                   "dict_serialize failed while handling " +                   " import friend volume request"); +            goto out; +        } + +        glusterd_launch_synctask(glusterd_import_friend_volumes_synctask, arg);      }  out: diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 9679c8b80db..c506da32950 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -224,7 +224,8 @@ glusterd_volume_brickinfo_get_by_brick(char *brick, glusterd_volinfo_t *volinfo,                                         gf_boolean_t construct_real_path);  int32_t -glusterd_add_volumes_to_export_dict(dict_t **peer_data); +glusterd_add_volumes_to_export_dict(dict_t *peer_data, char **buf, +                                    u_int *length);  int32_t  glusterd_compare_friend_data(dict_t *peer_data, int32_t *status, diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 305a17bb447..7db7896256c 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -236,6 +236,11 @@ typedef struct glusterd_add_dict_args {      int end;  } glusterd_add_dict_args_t; +typedef struct glusterd_friend_synctask_args { +    char *dict_buf; +    u_int dictlen; +} glusterd_friend_synctask_args_t; +  typedef enum gf_brick_status {      GF_BRICK_STOPPED,      GF_BRICK_STARTED,  | 
