diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-utils.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 463 |
1 files changed, 271 insertions, 192 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index bcb2dc703..fc4018190 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -445,6 +445,37 @@ glusterd_check_volume_exists (char *volname) return _gf_true; } +glusterd_volinfo_t * +glusterd_volinfo_unref (glusterd_volinfo_t *volinfo) +{ + int refcnt = -1; + + pthread_mutex_lock (&volinfo->reflock); + { + refcnt = --volinfo->refcnt; + } + pthread_mutex_unlock (&volinfo->reflock); + + if (!refcnt) { + glusterd_volinfo_delete (volinfo); + return NULL; + } + + return volinfo; +} + +glusterd_volinfo_t * +glusterd_volinfo_ref (glusterd_volinfo_t *volinfo) +{ + pthread_mutex_lock (&volinfo->reflock); + { + ++volinfo->refcnt; + } + pthread_mutex_unlock (&volinfo->reflock); + + return volinfo; +} + int32_t glusterd_volinfo_new (glusterd_volinfo_t **volinfo) { @@ -478,7 +509,8 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo) new_volinfo->xl = THIS; - *volinfo = new_volinfo; + pthread_mutex_init (&new_volinfo->reflock, NULL); + *volinfo = glusterd_volinfo_ref (new_volinfo); ret = 0; @@ -571,6 +603,14 @@ out: return ret; } +int +glusterd_volinfo_remove (glusterd_volinfo_t *volinfo) +{ + list_del_init (&volinfo->vol_list); + glusterd_volinfo_unref (volinfo); + return 0; +} + int32_t glusterd_volinfo_delete (glusterd_volinfo_t *volinfo) { @@ -595,6 +635,7 @@ glusterd_volinfo_delete (glusterd_volinfo_t *volinfo) glusterd_auth_cleanup (volinfo); + pthread_mutex_destroy (&volinfo->reflock); GF_FREE (volinfo); ret = 0; @@ -1054,7 +1095,7 @@ glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo) peerctx = peerinfo->rpc->mydata; peerinfo->rpc->mydata = NULL; - peerinfo->rpc = rpc_clnt_unref (peerinfo->rpc); + peerinfo->rpc = glusterd_rpc_clnt_unref (priv, peerinfo->rpc); peerinfo->rpc = NULL; if (peerctx) { GF_FREE (peerctx->errstr); @@ -1142,6 +1183,18 @@ glusterd_service_stop (const char *service, char *pidfile, int sig, "%d", service, pid); ret = kill (pid, sig); + if (ret) { + switch (errno) { + case ESRCH: + gf_log (this->name, GF_LOG_DEBUG, "%s is already stopped", + service); + ret = 0; + goto out; + default: + gf_log (this->name, GF_LOG_ERROR, "Failed to kill %s: %s", + service, strerror (errno)); + } + } if (!force_kill) goto out; @@ -1466,9 +1519,7 @@ glusterd_brick_disconnect (glusterd_brickinfo_t *brickinfo) brickinfo->rpc = NULL; if (rpc) { - synclock_unlock (&priv->big_lock); - rpc_clnt_unref (rpc); - synclock_lock (&priv->big_lock); + glusterd_rpc_clnt_unref (priv, rpc); } return 0; @@ -1959,20 +2010,18 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; - if (volinfo->rebal.defrag_cmd) { - rebalance_id_str = gf_strdup (uuid_utoa - (volinfo->rebal.rebalance_id)); - if (!rebalance_id_str) { - ret = -1; - goto out; - } - memset (key, 0, sizeof (key)); - snprintf (key, 256, "volume%d.rebalance-id", count); - ret = dict_set_dynstr (dict, key, rebalance_id_str); - if (ret) - goto out; - rebalance_id_str = NULL; + rebalance_id_str = gf_strdup (uuid_utoa + (volinfo->rebal.rebalance_id)); + if (!rebalance_id_str) { + ret = -1; + goto out; } + memset (key, 0, sizeof (key)); + snprintf (key, 256, "volume%d.rebalance-id", count); + ret = dict_set_dynstr (dict, key, rebalance_id_str); + if (ret) + goto out; + rebalance_id_str = NULL; memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "volume%d.rebalance-op", count); @@ -1980,6 +2029,23 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; + if (volinfo->rebal.dict) { + snprintf (prefix, sizeof (prefix), "volume%d", count); + ctx.dict = dict; + ctx.prefix = prefix; + ctx.opt_count = 1; + ctx.key_name = "rebal-dict-key"; + ctx.val_name = "rebal-dict-value"; + + dict_foreach (volinfo->rebal.dict, _add_dict_to_prdict, &ctx); + ctx.opt_count--; + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.rebal-dict-count", count); + ret = dict_set_int32 (dict, key, ctx.opt_count); + if (ret) + goto out; + } + memset (key, 0, sizeof (key)); snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count); ret = dict_set_int32 (dict, key, volinfo->rep_brick.rb_status); @@ -2069,6 +2135,13 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.brick%d.decommissioned", + count, i); + ret = dict_set_int32 (dict, key, brickinfo->decommissioned); + if (ret) + goto out; + i++; } @@ -2736,6 +2809,7 @@ glusterd_import_new_brick (dict_t *vols, int32_t vol_count, int ret = -1; char *hostname = NULL; char *path = NULL; + int decommissioned = 0; glusterd_brickinfo_t *new_brickinfo = NULL; char msg[2048] = {0}; @@ -2761,12 +2835,22 @@ glusterd_import_new_brick (dict_t *vols, int32_t vol_count, goto out; } + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.brick%d.decommissioned", + vol_count, brick_count); + ret = dict_get_int32 (vols, key, &decommissioned); + if (ret) { + /* For backward compatibility */ + ret = 0; + } + ret = glusterd_brickinfo_new (&new_brickinfo); if (ret) goto out; strcpy (new_brickinfo->path, path); strcpy (new_brickinfo->hostname, hostname); + new_brickinfo->decommissioned = decommissioned; //peerinfo might not be added yet (void) glusterd_resolve_brick (new_brickinfo); ret = 0; @@ -2911,6 +2995,43 @@ out: return ret; } +int +gd_import_friend_volume_rebal_dict (dict_t *dict, int count, + glusterd_volinfo_t *volinfo) +{ + int ret = -1; + char key[256] = {0,}; + int dict_count = 0; + char prefix[64] = {0}; + + GF_ASSERT (dict); + GF_ASSERT (volinfo); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.rebal-dict-count", count); + ret = dict_get_int32 (dict, key, &dict_count); + if (ret) { + /* Older peers will not have this dict */ + ret = 0; + goto out; + } + + volinfo->rebal.dict = dict_new (); + if(!volinfo->rebal.dict) { + ret = -1; + goto out; + } + + snprintf (prefix, sizeof (prefix), "volume%d", count); + ret = import_prdict_dict (dict, volinfo->rebal.dict, "rebal-dict-key", + "rebal-dict-value", dict_count, prefix); +out: + if (ret && volinfo->rebal.dict) + dict_unref (volinfo->rebal.dict); + gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); + return ret; +} + int32_t glusterd_import_volinfo (dict_t *vols, int count, glusterd_volinfo_t **volinfo) @@ -3017,7 +3138,8 @@ glusterd_import_volinfo (dict_t *vols, int count, if (ret) gf_log (THIS->name, GF_LOG_INFO, "peer is possibly old version"); - + new_volinfo->subvol_count = new_volinfo->brick_count/ + glusterd_get_dist_leaf_count (new_volinfo); memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "volume%d.ckusm", count); ret = dict_get_uint32 (vols, key, &new_volinfo->cksum); @@ -3074,19 +3196,16 @@ glusterd_import_volinfo (dict_t *vols, int count, goto out; } - if (new_volinfo->rebal.defrag_cmd) { - memset (key, 0, sizeof (key)); - snprintf (key, sizeof (key), "volume%d.rebalance-id", count); - ret = dict_get_str (vols, key, &rebalance_id_str); - if (ret) { - /* This is not present in older glusterfs versions, - * so don't error out - */ - ret = 0; - } else { - uuid_parse (rebalance_id_str, - new_volinfo->rebal.rebalance_id); - } + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.rebalance-id", count); + ret = dict_get_str (vols, key, &rebalance_id_str); + if (ret) { + /* This is not present in older glusterfs versions, + * so don't error out + */ + ret = 0; + } else { + uuid_parse (rebalance_id_str, new_volinfo->rebal.rebalance_id); } memset (key, 0, sizeof (key)); @@ -3098,6 +3217,12 @@ glusterd_import_volinfo (dict_t *vols, int count, */ ret = 0; } + ret = gd_import_friend_volume_rebal_dict (vols, count, new_volinfo); + if (ret) { + snprintf (msg, sizeof (msg), "Failed to import rebalance dict " + "for volume."); + goto out; + } memset (key, 0, sizeof (key)); snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count); @@ -3324,7 +3449,7 @@ glusterd_delete_stale_volume (glusterd_volinfo_t *stale_volinfo, (void) gf_store_handle_destroy (stale_volinfo->shandle); stale_volinfo->shandle = NULL; } - (void) glusterd_volinfo_delete (stale_volinfo); + (void) glusterd_volinfo_remove (stale_volinfo); return 0; } @@ -3344,10 +3469,14 @@ gd_check_and_update_rebalance_info (glusterd_volinfo_t *old_volinfo, old = &(old_volinfo->rebal); new = &(new_volinfo->rebal); - /* If the task-id's don't match, the old volinfo task is stale and - * should be cleaned up - */ - if (uuid_compare (old->rebalance_id, new->rebalance_id)) { + + //Disconnect from rebalance process + if (old->defrag && old->defrag->rpc) { + rpc_transport_disconnect (old->defrag->rpc->conn.trans); + } + + if (!uuid_is_null (old->rebalance_id) && + uuid_compare (old->rebalance_id, new->rebalance_id)) { (void)gd_stop_rebalance_process (old_volinfo); goto out; } @@ -3362,11 +3491,11 @@ gd_check_and_update_rebalance_info (glusterd_volinfo_t *old_volinfo, new->skipped_files = old->skipped_files; new->rebalance_failures = old->rebalance_failures; new->rebalance_time = old->rebalance_time; - new->defrag = old->defrag; new->dict = (old->dict ? dict_ref (old->dict) : NULL); /* glusterd_rebalance_t.{op, id, defrag_cmd} are copied during volume * import + * a new defrag object should come to life with rebalance being restarted */ out: return ret; @@ -3824,12 +3953,13 @@ int32_t glusterd_nodesvc_disconnect (char *server) { struct rpc_clnt *rpc = NULL; + glusterd_conf_t *priv = THIS->private; rpc = glusterd_nodesvc_get_rpc (server); (void)glusterd_nodesvc_set_rpc (server, NULL); if (rpc) - rpc_clnt_unref (rpc); + glusterd_rpc_clnt_unref (priv, rpc); return 0; } @@ -4594,14 +4724,24 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) { char *path_list = NULL; char *slave = NULL; + char *slave_ip = NULL; + char *slave_vol = NULL; + char *statefile = NULL; + char buf[1024] = "faulty"; int uuid_len = 0; int ret = 0; char uuid_str[64] = {0}; - glusterd_volinfo_t *volinfo = NULL; - char *conf_path = NULL; + glusterd_volinfo_t *volinfo = NULL; + char confpath[PATH_MAX] = ""; + char *op_errstr = NULL; + glusterd_conf_t *priv = NULL; + + GF_ASSERT (THIS); + priv = THIS->private; + GF_ASSERT (priv); + GF_ASSERT (data); volinfo = data; - GF_ASSERT (volinfo); slave = strchr(value->data, ':'); if (slave) slave ++; @@ -4611,22 +4751,63 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) strncpy (uuid_str, (char*)value->data, uuid_len); + /* Getting Local Brickpaths */ ret = glusterd_get_local_brickpaths (volinfo, &path_list); - ret = dict_get_str (this, "conf_path", &conf_path); + /*Generating the conf file path needed by gsyncd */ + ret = glusterd_get_slave_info (slave, &slave_ip, + &slave_vol, &op_errstr); if (ret) { gf_log ("", GF_LOG_ERROR, - "Unable to fetch conf file path."); + "Unable to fetch slave details."); + ret = -1; goto out; } - glusterd_start_gsync (volinfo, slave, path_list, conf_path, - uuid_str, NULL); + ret = snprintf (confpath, sizeof(confpath) - 1, + "%s/"GEOREP"/%s_%s_%s/gsyncd.conf", + priv->workdir, volinfo->volname, + slave_ip, slave_vol); + confpath[ret] = '\0'; + + /* Fetching the last status of the node */ + ret = glusterd_get_statefile_name (volinfo, slave, + confpath, &statefile); + if (ret) { + if (!strstr(slave, "::")) + gf_log ("", GF_LOG_INFO, + "%s is not a valid slave url.", slave); + else + gf_log ("", GF_LOG_INFO, "Unable to get" + " statefile's name"); + goto out; + } - GF_FREE (path_list); - path_list = NULL; + ret = glusterd_gsync_read_frm_status (statefile, buf, sizeof (buf)); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "Unable to read the status"); + goto out; + } + + /* Looks for the last status, to find if the sessiom was running + * when the node went down. If the session was not started or + * not started, do not restart the geo-rep session */ + if ((!strcmp (buf, "Not Started")) || + (!strcmp (buf, "Stopped"))) { + gf_log ("", GF_LOG_INFO, + "Geo-Rep Session was not started between " + "%s and %s::%s. Not Restarting", volinfo->volname, + slave_ip, slave_vol); + goto out; + } + + glusterd_start_gsync (volinfo, slave, path_list, confpath, + uuid_str, NULL); out: + if (path_list) + GF_FREE (path_list); + return ret; } @@ -6045,7 +6226,7 @@ glusterd_delete_volume (glusterd_volinfo_t *volinfo) if (ret) goto out; - ret = glusterd_volinfo_delete (volinfo); + glusterd_volinfo_remove (volinfo); out: gf_log (THIS->name, GF_LOG_DEBUG, "returning %d", ret); return ret; @@ -6771,7 +6952,7 @@ glusterd_volume_defrag_restart (glusterd_volinfo_t *volinfo, char *op_errstr, case GF_DEFRAG_STATUS_STARTED: GLUSTERD_GET_DEFRAG_PID_FILE(pidfile, volinfo, priv); if (gf_is_service_running (pidfile, &pid)) { - glusterd_rebalance_rpc_create (volinfo); + glusterd_rebalance_rpc_create (volinfo, _gf_true); break; } case GF_DEFRAG_STATUS_NOT_STARTED: @@ -7208,21 +7389,16 @@ glusterd_append_gsync_status (dict_t *dst, dict_t *src) } -static int32_t +int32_t glusterd_append_status_dicts (dict_t *dst, dict_t *src) { - int dst_count = 0; - int src_count = 0; - int i = 0; - int ret = 0; - char mst[PATH_MAX] = {0,}; - char slv[PATH_MAX] = {0, }; - char sts[PATH_MAX] = {0, }; - char nds[PATH_MAX] = {0, }; - char *mst_val = NULL; - char *slv_val = NULL; - char *sts_val = NULL; - char *nds_val = NULL; + char sts_val_name[PATH_MAX] = {0, }; + int dst_count = 0; + int src_count = 0; + int i = 0; + int ret = 0; + gf_gsync_status_t *sts_val = NULL; + gf_gsync_status_t *dst_sts_val = NULL; GF_ASSERT (dst); @@ -7240,49 +7416,29 @@ glusterd_append_status_dicts (dict_t *dst, dict_t *src) goto out; } - for (i = 1; i <= src_count; i++) { - snprintf (nds, sizeof(nds), "node%d", i); - snprintf (mst, sizeof(mst), "master%d", i); - snprintf (slv, sizeof(slv), "slave%d", i); - snprintf (sts, sizeof(sts), "status%d", i); - - ret = dict_get_str (src, nds, &nds_val); - if (ret) - goto out; - - ret = dict_get_str (src, mst, &mst_val); - if (ret) - goto out; - - ret = dict_get_str (src, slv, &slv_val); - if (ret) - goto out; + for (i = 0; i < src_count; i++) { + memset (sts_val_name, '\0', sizeof(sts_val_name)); + snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i); - ret = dict_get_str (src, sts, &sts_val); + ret = dict_get_bin (src, sts_val_name, (void **) &sts_val); if (ret) goto out; - snprintf (nds, sizeof(nds), "node%d", i+dst_count); - snprintf (mst, sizeof(mst), "master%d", i+dst_count); - snprintf (slv, sizeof(slv), "slave%d", i+dst_count); - snprintf (sts, sizeof(sts), "status%d", i+dst_count); - - ret = dict_set_dynstr (dst, nds, gf_strdup (nds_val)); - if (ret) + dst_sts_val = GF_CALLOC (1, sizeof(gf_gsync_status_t), + gf_common_mt_gsync_status_t); + if (!dst_sts_val) { + gf_log ("", GF_LOG_ERROR, "Out Of Memory"); goto out; + } - ret = dict_set_dynstr (dst, mst, gf_strdup (mst_val)); - if (ret) - goto out; + memcpy (dst_sts_val, sts_val, sizeof(gf_gsync_status_t)); - ret = dict_set_dynstr (dst, slv, gf_strdup (slv_val)); - if (ret) - goto out; + memset (sts_val_name, '\0', sizeof(sts_val_name)); + snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i + dst_count); - ret = dict_set_dynstr (dst, sts, gf_strdup (sts_val)); + ret = dict_set_bin (dst, sts_val_name, dst_sts_val, sizeof(gf_gsync_status_t)); if (ret) goto out; - } ret = dict_set_int32 (dst, "gsync-count", dst_count+src_count); @@ -9146,72 +9302,15 @@ glusterd_remove_auxiliary_mount (char *volname) return ret; } -/* Just a minimal callback function to which logs if the request was successfull - * or not - */ -int -_gd_stop_rebalance_process_cbk (struct rpc_req *req, struct iovec *iov, - int count, void *call_frame) -{ - xlator_t *this = NULL; - struct syncargs *args = NULL; - gd1_mgmt_brick_op_rsp rsp = {0,}; - int ret = -1; - call_frame_t *frame = NULL; - - this = THIS; - GF_ASSERT (this); - - frame = call_frame; - args = frame->local; - frame->local = NULL; - - if (-1 == req->rpc_status) { - gf_log (this->name, GF_LOG_WARNING, "Failed to stop rebalance " - "process."); - goto out; - } - - ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, "Failed to decode stop " - "rebalance process response."); - goto out; - } - - gf_log (this->name, GF_LOG_INFO, "Stopping rebalance process was %s.", - (rsp.op_ret ? "unsuccessful" : "successful")); - -out: - if ((rsp.op_errstr) && (strcmp (rsp.op_errstr, "") != 0)) - free (rsp.op_errstr); - free (rsp.output.output_val); - - STACK_DESTROY (frame->root); - __wake (args); - - return 0; -} - -int -gd_stop_rebalance_process_cbk (struct rpc_req *req, struct iovec *iov, - int count, void *call_frame) -{ - return glusterd_big_locked_cbk (req, iov, count, call_frame, - _gd_stop_rebalance_process_cbk); -} -/* Stops the rebalance process of the given volume, gracefully +/* Stops the rebalance process of the given volume */ int gd_stop_rebalance_process (glusterd_volinfo_t *volinfo) { - int ret = -1; - xlator_t *this = NULL; - glusterd_conf_t *conf = NULL; - gd1_mgmt_brick_op_req *req = NULL; - dict_t *req_dict = NULL; - char *name = NULL; - struct syncargs args = {0,}; + int ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + char pidfile[PATH_MAX] = {0,}; GF_ASSERT (volinfo); @@ -9221,43 +9320,23 @@ gd_stop_rebalance_process (glusterd_volinfo_t *volinfo) conf = this->private; GF_ASSERT (conf); - req = GF_CALLOC (1, sizeof (*req), gf_gld_mt_mop_brick_req_t); - if (!req) { - ret = -1; - goto out; - } - - req->op = GLUSTERD_BRICK_XLATOR_DEFRAG; - - ret = gf_asprintf(&name, "%s-dht", volinfo->volname); - if (ret < 0) - goto out; - req->name = name; - - req_dict = dict_new(); - if (!req_dict) { - ret = -1; - goto out; - } - - ret = dict_set_int32 (req_dict, "rebalance-command", - GF_DEFRAG_CMD_STOP); - if (ret) - goto out; + GLUSTERD_GET_DEFRAG_PID_FILE (pidfile, volinfo, conf); + ret = glusterd_service_stop ("rebalance", pidfile, SIGTERM, _gf_true); - ret = dict_allocate_and_serialize (req_dict, &req->input.input_val, - &req->input.input_len); - if (ret) - goto out; + return ret; +} - GD_SYNCOP (volinfo->rebal.defrag->rpc, (&args), NULL, - gd_stop_rebalance_process_cbk, req, conf->gfs_mgmt, req->op, - (xdrproc_t)xdr_gd1_mgmt_brick_op_req); -out: +rpc_clnt_t * +glusterd_rpc_clnt_unref (glusterd_conf_t *conf, rpc_clnt_t *rpc) +{ + rpc_clnt_t *ret = NULL; - GF_FREE (name); - GF_FREE (req); - dict_unref (req_dict); + GF_ASSERT (conf); + GF_ASSERT (rpc); + synclock_unlock (&conf->big_lock); + ret = rpc_clnt_unref (rpc); + synclock_lock (&conf->big_lock); return ret; } + |