diff options
author | Vijay Bellur <vijay@gluster.com> | 2010-07-19 05:54:25 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-07-19 05:11:05 -0700 |
commit | a6b90707bf68fe62bf115cfb143d9df69627cb64 (patch) | |
tree | 86a98f2e31bd9ec3cdba8b05386ef2d928bc09ed /xlators/mgmt/glusterd | |
parent | 87ec1b72dac8f50f9eb4ba3b127baca19993ae94 (diff) |
Changes for volume commands
Signed-off-by: Vijay Bellur <vijay@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 1161 (gluster volume start command segfaults glusterd)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1161
Diffstat (limited to 'xlators/mgmt/glusterd')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-ha.c | 57 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 481 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-mem-types.h | 5 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 445 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.c | 74 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.h | 7 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 290 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 26 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 9 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 35 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd3_1-mops.c | 87 |
12 files changed, 1295 insertions, 227 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-ha.c b/xlators/mgmt/glusterd/src/glusterd-ha.c index 49e73703ddd..ebf6ce066b6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-ha.c +++ b/xlators/mgmt/glusterd/src/glusterd-ha.c @@ -28,7 +28,6 @@ #include "compat.h" #include "dict.h" #include "protocol-common.h" -//#include "transport.h" #include "xlator.h" #include "logging.h" #include "timer.h" @@ -49,6 +48,7 @@ #include <sys/resource.h> #include <inttypes.h> +#include <dirent.h> int32_t glusterd_ha_create_volume (glusterd_volinfo_t *volinfo) @@ -111,31 +111,58 @@ glusterd_ha_delete_volume (glusterd_volinfo_t *volinfo) { char pathname[PATH_MAX] = {0,}; int32_t ret = -1; - char filepath[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; + DIR *dir = NULL; + struct dirent *entry = NULL; + char path[PATH_MAX] = {0,}; GF_ASSERT (volinfo); - snprintf (pathname, 1024, "%s/vols/%s", GLUSTERD_DEFAULT_WORKDIR, - volinfo->volname); + priv = THIS->private; - snprintf (filepath, 1024, "%s/info", pathname); - ret = unlink (filepath); + GF_ASSERT (priv); + snprintf (pathname, 1024, "%s/vols/%s", priv->workdir, + volinfo->volname); - if (-1 == ret) { - gf_log ("", GF_LOG_ERROR, "unlink() failed on path %s," - "errno: %d", filepath, errno); + dir = opendir (pathname); + if (!dir) goto out; + + entry = readdir (dir); + while (entry != NULL) { + if (!strcmp (entry->d_name, ".") || + !strcmp (entry->d_name, "..")) { + entry = readdir (dir); + continue; + } + snprintf (path, PATH_MAX, "%s/%s", pathname, entry->d_name); + if (DT_DIR == entry->d_type) + ret = rmdir (path); + else + ret = unlink (path); + + gf_log ("", GF_LOG_NORMAL, "%s %s", + ret?"Failed to remove":"Removed", + entry->d_name); + if (ret) + gf_log ("", GF_LOG_NORMAL, "errno:%d", errno); + entry = readdir (dir); + memset (path, 0, sizeof(path)); } - ret = rmdir (pathname); + ret = closedir (dir); + if (ret) { + gf_log ("", GF_LOG_NORMAL, "Failed to close dir, errno:%d", + errno); + } - if (-1 == ret) { - gf_log ("", GF_LOG_ERROR, "rmdir() failed on path %s," - "errno: %d", pathname, errno); - goto out; + ret = rmdir (pathname); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Failed to rmdir: %s, errno: %d", + pathname, errno); } -out: +out: gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 086e62e4e18..36dc83f4a51 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -69,6 +69,7 @@ glusterd_friend_find_by_hostname (const char *hoststr, int ret = -1; glusterd_conf_t *priv = NULL; glusterd_peerinfo_t *entry = NULL; + glusterd_peer_hostname_t *name = NULL; GF_ASSERT (hoststr); GF_ASSERT (peerinfo); @@ -79,14 +80,16 @@ glusterd_friend_find_by_hostname (const char *hoststr, GF_ASSERT (priv); list_for_each_entry (entry, &priv->peers, uuid_list) { - if (entry->hostname && (!strncmp (entry->hostname, hoststr, - sizeof (entry->hostname)))) { + list_for_each_entry (name, &entry->hostnames, hostname_list) { + if (!strncmp (name->hostname, hoststr, + 1024)) { gf_log ("glusterd", GF_LOG_NORMAL, "Friend %s found.. state: %d", hoststr, entry->state.state); *peerinfo = entry; return 0; + } } } @@ -130,7 +133,6 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, char *hostname) glusterd_friend_sm_event_t *event = NULL; glusterd_friend_req_ctx_t *ctx = NULL; - ret = glusterd_friend_find (uuid, hostname, &peerinfo); if (ret) { @@ -279,6 +281,41 @@ out: return ret; } +static int +glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo, + dict_t *volumes, int count) +{ + + int ret = -1; + char key[256] = {0, }; + + GF_ASSERT (volinfo); + GF_ASSERT (volumes); + + snprintf (key, 256, "volume%d.name", count); + ret = dict_set_str (volumes, key, volinfo->volname); + if (ret) + goto out; + + snprintf (key, 256, "volume%d.type", count); + ret = dict_set_int32 (volumes, key, volinfo->type); + if (ret) + goto out; + + snprintf (key, 256, "volume%d.status", count); + ret = dict_set_int32 (volumes, key, volinfo->status); + if (ret) + goto out; + + snprintf (key, 256, "volume%d.brick_count", count); + ret = dict_set_int32 (volumes, key, volinfo->brick_count); + if (ret) + goto out; + +out: + return ret; +} + int glusterd_friend_find (uuid_t uuid, char *hostname, glusterd_peerinfo_t **peerinfo) @@ -323,7 +360,7 @@ glusterd_handle_cluster_lock (rpcsvc_request_t *req) GF_ASSERT (req); - if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &lock_req)) { + if (!gd_xdr_to_mgmt_cluster_lock_req (req->msg[0], &lock_req)) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; goto out; @@ -557,6 +594,44 @@ out: } int +glusterd_handle_cli_get_volume (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_get_vol_req cli_req = {0,}; + dict_t *dict = NULL; + + GF_ASSERT (req); + + if (!gf_xdr_to_cli_get_vol_req (req->msg[0], &cli_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_NORMAL, "Received get vol req"); + + if (cli_req.dict.dict_len) { + /* Unserialize the dictionary */ + dict = dict_new (); + + ret = dict_unserialize (cli_req.dict.dict_val, + cli_req.dict.dict_len, + &dict); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, + "failed to " + "unserialize req-buffer to dictionary"); + goto out; + } + } + + ret = glusterd_get_volumes (req, dict, cli_req.flags); + +out: + return ret; +} + +int glusterd_handle_create_volume (rpcsvc_request_t *req) { int32_t ret = -1; @@ -595,6 +670,78 @@ out: } int +glusterd_handle_cli_start_volume (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_start_vol_req cli_req = {0,}; + //dict_t *dict = NULL; + int32_t flags = 0; + + GF_ASSERT (req); + + if (!gf_xdr_to_cli_start_vol_req (req->msg[0], &cli_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_NORMAL, "Received start vol req" + "for volume %s", cli_req.volname); + + ret = glusterd_start_volume (req, cli_req.volname, flags); + +out: + return ret; +} + +int +glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_stop_vol_req cli_req = {0,}; + int32_t flags = 0; + + GF_ASSERT (req); + + if (!gf_xdr_to_cli_stop_vol_req (req->msg[0], &cli_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_NORMAL, "Received stop vol req" + "for volume %s", cli_req.volname); + + ret = glusterd_stop_volume (req, cli_req.volname, flags); + +out: + return ret; +} + +int +glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_delete_vol_req cli_req = {0,}; + int32_t flags = 0; + + GF_ASSERT (req); + + if (!gf_xdr_to_cli_delete_vol_req (req->msg[0], &cli_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_NORMAL, "Received delete vol req" + "for volume %s", cli_req.volname); + + ret = glusterd_delete_volume (req, cli_req.volname, flags); + +out: + return ret; +} +int glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status) { @@ -645,7 +792,7 @@ glusterd_handle_cluster_unlock (rpcsvc_request_t *req) GF_ASSERT (req); - if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &unlock_req)) { + if (!gd_xdr_to_mgmt_cluster_unlock_req (req->msg[0], &unlock_req)) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; goto out; @@ -775,6 +922,47 @@ out: } int +glusterd_handle_friend_update (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gd1_mgmt_friend_update friend_req = {{0},}; + char str[50] = {0,}; + glusterd_peerinfo_t *peerinfo = NULL; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + glusterd_peerinfo_t *tmp = NULL; + + GF_ASSERT (req); + + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); + + if (!gd_xdr_to_mgmt_friend_update (req->msg[0], &friend_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + uuid_unparse (friend_req.uuid, str); + + gf_log ("glusterd", GF_LOG_NORMAL, + "Received friend update from uuid: %s", str); + + ret = glusterd_friend_find (friend_req.uuid, friend_req.hostname, &tmp); + + if (!ret) + goto out; + + ret = glusterd_friend_add (friend_req.hostname, + GD_FRIEND_STATE_BEFRIENDED, + &friend_req.uuid, NULL, &peerinfo); + +out: + return ret; +} + +int glusterd_handle_probe_query (rpcsvc_request_t *req) { int32_t ret = -1; @@ -784,6 +972,7 @@ glusterd_handle_probe_query (rpcsvc_request_t *req) gd1_mgmt_probe_req probe_req = {{0},}; gd1_mgmt_probe_rsp rsp = {{0},}; char hostname[1024] = {0}; + glusterd_peer_hostname_t *name = NULL; GF_ASSERT (req); @@ -796,18 +985,25 @@ glusterd_handle_probe_query (rpcsvc_request_t *req) } + this = THIS; + + conf = this->private; uuid_unparse (probe_req.uuid, str); gf_log ("glusterd", GF_LOG_NORMAL, "Received probe from uuid: %s", str); + ret = glusterd_peer_hostname_new (probe_req.hostname, &name); - this = THIS; + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get new peer_hostname"); + } else { + list_add_tail (&name->hostname_list, &conf->hostnames); + } - conf = this->private; uuid_copy (rsp.uuid, conf->uuid); - rsp.hostname = gf_strdup (probe_req.hostname); + rsp.hostname = probe_req.hostname; ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL, gd_xdr_serialize_mgmt_probe_rsp); @@ -1159,6 +1355,7 @@ glusterd_friend_add (const char *hoststr, char *port_str = NULL; int port_num = 0; struct rpc_clnt_config rpc_cfg = {0,}; + glusterd_peer_hostname_t *name = NULL; priv = THIS->private; @@ -1170,9 +1367,13 @@ glusterd_friend_add (const char *hoststr, if (friend) *friend = peerinfo; + INIT_LIST_HEAD (&peerinfo->hostnames); peerinfo->state.state = state; if (hoststr) { - peerinfo->hostname = gf_strdup (hoststr); + ret = glusterd_peer_hostname_new ((char *)hoststr, &name); + if (ret) + goto out; + list_add_tail (&peerinfo->hostnames, &name->hostname_list); rpc_cfg.remote_host = gf_strdup (hoststr); } INIT_LIST_HEAD (&peerinfo->uuid_list); @@ -1195,12 +1396,14 @@ glusterd_friend_add (const char *hoststr, port_str = getenv ("GLUSTERD_REMOTE_PORT"); - port_num = atoi (port_str); - rpc_cfg.remote_port = port_num; + if (port_str) + port_num = atoi (port_str); + else + port_num = GLUSTERD_DEFAULT_PORT; + rpc_cfg.remote_port = port_num; gf_log ("glusterd", GF_LOG_NORMAL, "remote-port: %d", port_num); - //ret = dict_set_int32 (options, "remote-port", GLUSTERD_DEFAULT_PORT); ret = dict_set_int32 (options, "remote-port", port_num); if (ret) goto out; @@ -1232,26 +1435,7 @@ out: } -/*int -glusterd_friend_probe (const char *hoststr) -{ - int ret = -1; - glusterd_peerinfo_t *peerinfo = NULL; - - - ret = glusterd_friend_find (NULL, (char *)hoststr, &peerinfo); - - if (ret) { - //We should not reach this state ideally - GF_ASSERT (0); - goto out; - } - - ret = glusterd_xfer_probe_msg (peerinfo, THIS); -out: - return ret; -}*/ int glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr) @@ -1361,68 +1545,6 @@ out: return ret; } -/*int -glusterd_interpret (xlator_t *this, transport_t *trans, - char *hdr_p, size_t hdrlen, struct iobuf *iobuf) -{ - glusterd_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - xlator_t *bound_xl = NULL; - call_frame_t *frame = NULL; - peer_info_t *peerinfo = NULL; - int32_t type = -1; - int32_t op = -1; - int32_t ret = 0; - - hdr = (gf_hdr_common_t *)hdr_p; - type = ntoh32 (hdr->type); - op = ntoh32 (hdr->op); - - conn = trans->xl_private; - if (conn) - bound_xl = conn->bound_xl; - - if (GF_MOP_PROBE_QUERY != op) { - //ret = glusterd_validate_sender (hdr, hdrlen); - } - - peerinfo = &trans->peerinfo; - switch (type) { - - case GF_OP_TYPE_MOP_REQUEST: - if ((op < 0) || (op >= GF_MOP_MAXVALUE)) { - gf_log (this->name, GF_LOG_ERROR, - "invalid mop %"PRId32" from %s", - op, peerinfo->identifier); - break; - } - frame = glusterd_get_frame_for_call (trans, hdr); - frame->op = op; - ret = glusterd_ops[op] (frame, hdr, hdrlen); - break; - - case GF_OP_TYPE_MOP_REPLY: - if ((op < 0) || (op >= GF_MOP_MAXVALUE)) { - gf_log (this->name, GF_LOG_ERROR, - "invalid mop %"PRId32" from %s", - op, peerinfo->identifier); - break; - } - ret = glusterd_resp_ops[op] (frame, hdr, hdrlen); - gf_log ("glusterd", GF_LOG_NORMAL, "Obtained MOP response"); - break; - - - default: - gf_log (this->name, GF_LOG_ERROR, - "Unknown type: %d", type); - ret = -1; - break; - } - - return ret; -} -*/ int glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname) @@ -1547,9 +1669,7 @@ glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict) char *volname = NULL; char *bricks = NULL; int type = 0; - //int sub_count = 2; int count = 0; - //char cmd_str[8192] = {0,}; GF_ASSERT (req); GF_ASSERT (dict); @@ -1574,38 +1694,83 @@ glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict) if (ret) goto out; - /*switch (type) { - case GF_CLUSTER_TYPE_REPLICATE: - { - ret = dict_get_int32 (dict, "replica-count", &sub_count); - if (ret) - goto out; - snprintf (cmd_str, 8192, - "glusterfs-volgen -n %s -c /etc/glusterd -r 1 %s", - volname, bricks); - ret = system (cmd_str); - break; - } - case GF_CLUSTER_TYPE_STRIPE: - { - ret = dict_get_int32 (dict, "stripe-count", &sub_count); - if (ret) - goto out; - snprintf (cmd_str, 8192, - "glusterfs-volgen -n %s -c /etc/glusterd -r 0 %s", - volname, bricks); - ret = system (cmd_str); - break; - } - case GF_CLUSTER_TYPE_NONE: - { - snprintf (cmd_str, 8192, - "glusterfs-volgen -n %s -c /etc/glusterd %s", - volname, bricks); - ret = system (cmd_str); - break; - } - } */ + ret = glusterd_op_txn_begin (); + +out: + return ret; +} + +int32_t +glusterd_start_volume (rpcsvc_request_t *req, char *volname, int flags) +{ + int32_t ret = -1; + glusterd_op_start_volume_ctx_t *ctx = NULL; + + GF_ASSERT (req); + GF_ASSERT (volname); + + ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_start_volume_ctx_t); + + if (!ctx) + goto out; + + strncpy (ctx->volume_name, volname, GD_VOLUME_NAME_MAX); + + glusterd_op_set_op (GD_OP_START_VOLUME); + + glusterd_op_set_ctx (GD_OP_START_VOLUME, ctx); + + ret = glusterd_op_txn_begin (); + +out: + return ret; +} + +int32_t +glusterd_stop_volume (rpcsvc_request_t *req, char *volname, int flags) +{ + int32_t ret = -1; + glusterd_op_stop_volume_ctx_t *ctx = NULL; + + GF_ASSERT (req); + GF_ASSERT (volname); + + ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_stop_volume_ctx_t); + + if (!ctx) + goto out; + + strncpy (ctx->volume_name, volname, GD_VOLUME_NAME_MAX); + + glusterd_op_set_op (GD_OP_STOP_VOLUME); + + glusterd_op_set_ctx (GD_OP_STOP_VOLUME, ctx); + + ret = glusterd_op_txn_begin (); + +out: + return ret; +} + +int32_t +glusterd_delete_volume (rpcsvc_request_t *req, char *volname, int flags) +{ + int32_t ret = -1; + glusterd_op_delete_volume_ctx_t *ctx = NULL; + + GF_ASSERT (req); + GF_ASSERT (volname); + + ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_delete_volume_ctx_t); + + if (!ctx) + goto out; + + strncpy (ctx->volume_name, volname, GD_VOLUME_NAME_MAX); + + glusterd_op_set_op (GD_OP_DELETE_VOLUME); + + glusterd_op_set_ctx (GD_OP_DELETE_VOLUME, ctx); ret = glusterd_op_txn_begin (); @@ -1676,6 +1841,68 @@ out: return ret; } +int32_t +glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags) +{ + int32_t ret = -1; + glusterd_conf_t *priv = NULL; + glusterd_volinfo_t *entry = NULL; + int32_t count = 0; + dict_t *volumes = NULL; + gf1_cli_get_vol_rsp rsp = {0,}; + + priv = THIS->private; + GF_ASSERT (priv); + + if (!list_empty (&priv->volumes)) { + volumes = dict_new (); + if (!volumes) { + gf_log ("", GF_LOG_WARNING, "Out of Memory"); + goto out; + } + } else { + ret = 0; + goto out; + } + + if (flags == GF_CLI_GET_VOLUME_ALL) { + list_for_each_entry (entry, &priv->volumes, vol_list) { + count++; + ret = glusterd_add_volume_detail_to_dict (entry, + volumes, count); + if (ret) + goto out; + + } + + ret = dict_set_int32 (volumes, "count", count); + + if (ret) + goto out; + } + + ret = dict_allocate_and_serialize (volumes, &rsp.volumes.volumes_val, + (size_t *)&rsp.volumes.volumes_len); + + if (ret) + goto out; + + ret = 0; +out: + + if (ret) { + if (volumes) + dict_destroy (volumes); + } + + rsp.op_ret = ret; + + ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL, + gf_xdr_serialize_cli_peer_list_rsp); + + return ret; +} + int glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, void *data) diff --git a/xlators/mgmt/glusterd/src/glusterd-mem-types.h b/xlators/mgmt/glusterd/src/glusterd-mem-types.h index 7ede5efec31..4d3655be2e7 100644 --- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h +++ b/xlators/mgmt/glusterd/src/glusterd-mem-types.h @@ -37,6 +37,7 @@ enum gf_gld_mem_types_ { gf_gld_mt_peerinfo_t, gf_gld_mt_friend_sm_event_t, gf_gld_mt_friend_req_ctx_t, + gf_gld_mt_friend_update_ctx_t, gf_gld_mt_op_sm_event_t, gf_gld_mt_op_lock_ctx_t, gf_gld_mt_op_stage_ctx_t, @@ -44,8 +45,12 @@ enum gf_gld_mem_types_ { gf_gld_mt_mop_stage_req_t, gf_gld_mt_probe_ctx_t, gf_gld_mt_create_volume_ctx_t, + gf_gld_mt_start_volume_ctx_t, + gf_gld_mt_stop_volume_ctx_t, + gf_gld_mt_delete_volume_ctx_t, gf_gld_mt_glusterd_volinfo_t, gf_gld_mt_glusterd_brickinfo_t, + gf_gld_mt_peer_hostname_t, gf_gld_mt_end }; #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 0d99174b85d..1bd246d498d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -49,6 +49,21 @@ static struct list_head gd_op_sm_queue; glusterd_op_info_t opinfo; +static void +glusterd_set_volume_status (glusterd_volinfo_t *volinfo, + glusterd_volume_status status) +{ + GF_ASSERT (volinfo); + volinfo->status = status; +} + +static int +glusterd_is_volume_started (glusterd_volinfo_t *volinfo) +{ + GF_ASSERT (volinfo); + return (!(volinfo->status == GLUSTERD_STATUS_STARTED)); +} + static int glusterd_op_get_len (glusterd_op_t op) { @@ -131,7 +146,43 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req) goto out; } } + break; + + case GD_OP_START_VOLUME: + { + glusterd_op_start_volume_ctx_t *ctx = NULL; + ctx = glusterd_op_get_ctx (op); + GF_ASSERT (ctx); + stage_req->buf.buf_len = + strlen (ctx->volume_name); + stage_req->buf.buf_val = + gf_strdup (ctx->volume_name); + } + break; + + case GD_OP_STOP_VOLUME: + { + glusterd_op_stop_volume_ctx_t *ctx = NULL; + ctx = glusterd_op_get_ctx (op); + GF_ASSERT (ctx); + stage_req->buf.buf_len = + strlen (ctx->volume_name); + stage_req->buf.buf_val = + gf_strdup (ctx->volume_name); + } + break; + case GD_OP_DELETE_VOLUME: + { + glusterd_op_delete_volume_ctx_t *ctx = NULL; + ctx = glusterd_op_get_ctx (op); + GF_ASSERT (ctx); + stage_req->buf.buf_len = + strlen (ctx->volume_name); + stage_req->buf.buf_val = + gf_strdup (ctx->volume_name); + } + break; default: break; @@ -144,6 +195,75 @@ out: return ret; } +static int +glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo, + dict_t *dict, char *bricks) +{ + int32_t sub_count = 0; + int32_t ret = -1; + char cmd_str[8192] = {0,}; + char path[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + priv = this->private; + + GF_ASSERT (priv); + GF_ASSERT (volinfo); + GF_ASSERT (dict); + GF_ASSERT (bricks); + + GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv); + + switch (volinfo->type) { + + case GF_CLUSTER_TYPE_REPLICATE: + { + ret = dict_get_int32 (dict, "replica-count", + &sub_count); + if (ret) + goto out; + snprintf (cmd_str, 8192, + "glusterfs-volgen -n %s -c %s -r 1 %s", + volinfo->volname, path, bricks); + ret = system (cmd_str); + break; + } + + case GF_CLUSTER_TYPE_STRIPE: + { + ret = dict_get_int32 (dict, "stripe-count", + &sub_count); + if (ret) + goto out; + snprintf (cmd_str, 8192, + "glusterfs-volgen -n %s -c %s -r 0 %s", + volinfo->volname, path, bricks); + ret = system (cmd_str); + break; + } + + case GF_CLUSTER_TYPE_NONE: + { + snprintf (cmd_str, 8192, + "glusterfs-volgen -n %s -c %s %s", + volinfo->volname, path, bricks); + ret = system (cmd_str); + break; + } + + default: + gf_log ("", GF_LOG_ERROR, "Unkown type: %d", + volinfo->type); + ret = -1; + } +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + static int @@ -191,6 +311,138 @@ out: } static int +glusterd_op_stage_start_volume (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + char volname [1024] = {0,}; + gf_boolean_t exists = _gf_false; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + + GF_ASSERT (req); + + strncpy (volname, req->buf.buf_val, req->buf.buf_len); + //volname = req->buf.buf_val; + + exists = glusterd_check_volume_exists (volname); + + if (!exists) { + gf_log ("", GF_LOG_ERROR, "Volume with name %s does not exist", + volname); + ret = -1; + } else { + ret = 0; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) + goto out; + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + ret = glusterd_resolve_brick (brickinfo); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to resolve brick" + " with hostname: %s, export: %s", + brickinfo->hostname,brickinfo->path); + goto out; + } + } + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + + return ret; +} + +static int +glusterd_op_stage_stop_volume (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + char volname[1024] = {0,}; + gf_boolean_t exists = _gf_false; + glusterd_volinfo_t *volinfo = NULL; + + GF_ASSERT (req); + + strncpy (volname, req->buf.buf_val, req->buf.buf_len); + + exists = glusterd_check_volume_exists (volname); + + if (!exists) { + gf_log ("", GF_LOG_ERROR, "Volume with name %s does not exist", + volname); + ret = -1; + } else { + ret = 0; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) + goto out; + + ret = glusterd_is_volume_started (volinfo); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Volume %s has not been started", + volname); + goto out; + } + + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + + return ret; +} + +static int +glusterd_op_stage_delete_volume (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + char volname [1024] = {0,}; + gf_boolean_t exists = _gf_false; + glusterd_volinfo_t *volinfo = NULL; + + GF_ASSERT (req); + + strncpy (volname, req->buf.buf_val, req->buf.buf_len); + + exists = glusterd_check_volume_exists (volname); + + if (!exists) { + gf_log ("", GF_LOG_ERROR, "Volume with name %s does not exist", + volname); + ret = -1; + } else { + ret = 0; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) + goto out; + + ret = glusterd_is_volume_started (volinfo); + + if (!ret) { + gf_log ("", GF_LOG_ERROR, "Volume %s has been started." + "Volume needs to be stopped before deletion.", + volname); + goto out; + } + + ret = 0; + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + + return ret; +} + + +static int glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) { int ret = 0; @@ -203,10 +455,6 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) char *brick = NULL; int32_t count = 0; int32_t i = 1; - //char key[50] = {0,}; - int32_t sub_count = 0; - char path[PATH_MAX] = {0,}; - char cmd_str[8192] = {0,}; char *bricks = NULL; char *brick_list = NULL; char *saveptr = NULL; @@ -245,18 +493,15 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) } strncpy (volinfo->volname, volname, 1024); - GF_ASSERT (volinfo->volname); ret = dict_get_int32 (dict, "type", &volinfo->type); - if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to get type"); goto out; } ret = dict_get_int32 (dict, "count", &volinfo->brick_count); - if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to get count"); goto out; @@ -265,7 +510,6 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) count = volinfo->brick_count; ret = dict_get_str (dict, "bricks", &bricks); - if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to get bricks"); goto out; @@ -278,7 +522,6 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) brick = strtok_r (brick_list+1, " \n", &saveptr); while ( i <= count) { - ret = glusterd_brickinfo_from_brick (brick, &brickinfo); if (ret) goto out; @@ -287,58 +530,146 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) brick = strtok_r (NULL, " \n", &saveptr); i++; } + list_add_tail (&volinfo->vol_list, &priv->volumes); ret = glusterd_ha_create_volume (volinfo); if (ret) goto out; + ret = glusterd_volume_create_generate_volfiles + (volinfo, dict, bricks); + if (ret) + goto out; - GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv); - switch (volinfo->type) { +out: + return ret; +} - case GF_CLUSTER_TYPE_REPLICATE: - { - ret = dict_get_int32 (dict, "replica-count", - &sub_count); - if (ret) - goto out; - snprintf (cmd_str, 8192, - "glusterfs-volgen -n %s -c %s -r 1 %s", - volname, path, bricks); - ret = system (cmd_str); - break; - } +static int +glusterd_op_delete_volume (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + char volname[1024] = {0,}; + glusterd_conf_t *priv = NULL; + glusterd_volinfo_t *volinfo = NULL; + xlator_t *this = NULL; - case GF_CLUSTER_TYPE_STRIPE: - { - ret = dict_get_int32 (dict, "stripe-count", - &sub_count); - if (ret) + GF_ASSERT (req); + + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); + + strncpy (volname, req->buf.buf_val, req->buf.buf_len); + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) + goto out; + + ret = glusterd_ha_delete_volume (volinfo); + + if (ret) + goto out; + + ret = glusterd_volinfo_delete (volinfo); + + if (ret) + goto out; + +out: + return ret; +} + +static int +glusterd_op_start_volume (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + char volname[1024] = {0,}; + glusterd_conf_t *priv = NULL; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; + + GF_ASSERT (req); + + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); + + strncpy (volname, req->buf.buf_val, req->buf.buf_len); + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) + goto out; + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + if (!uuid_compare (brickinfo->uuid, priv->uuid)) { + gf_log ("", GF_LOG_NORMAL, "About to start glusterfs" + " for brick %s:%s", brickinfo->hostname, + brickinfo->path); + ret = glusterd_volume_start_glusterfs + (volinfo, brickinfo); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to start " + "glusterfs, ret: %d", ret); goto out; - snprintf (cmd_str, 8192, - "glusterfs-volgen -n %s -c %s -r 0 %s", - volname, path, bricks); - ret = system (cmd_str); - break; + } } + } - case GF_CLUSTER_TYPE_NONE: - { - snprintf (cmd_str, 8192, - "glusterfs-volgen -n %s -c %s %s", - volname, path, bricks); - ret = system (cmd_str); - break; - } + glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STARTED); - default: - gf_log ("", GF_LOG_ERROR, "Unkown type: %d", - volinfo->type); - ret = -1; +out: + return ret; +} + +static int +glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + char volname[1024] = {0,}; + glusterd_conf_t *priv = NULL; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; + + GF_ASSERT (req); + + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); + + strncpy (volname, req->buf.buf_val, req->buf.buf_len); + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) + goto out; + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + if (!uuid_compare (brickinfo->uuid, priv->uuid)) { + gf_log ("", GF_LOG_NORMAL, "About to stop glusterfs" + " for brick %s:%s", brickinfo->hostname, + brickinfo->path); + ret = glusterd_volume_stop_glusterfs + (volinfo, brickinfo); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to stop " + "glusterfs, ret: %d", ret); + goto out; + } + } } + glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED); + out: return ret; } @@ -720,6 +1051,18 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req) ret = glusterd_op_stage_create_volume (req); break; + case GD_OP_START_VOLUME: + ret = glusterd_op_stage_start_volume (req); + break; + + case GD_OP_STOP_VOLUME: + ret = glusterd_op_stage_stop_volume (req); + break; + + case GD_OP_DELETE_VOLUME: + ret = glusterd_op_stage_delete_volume (req); + break; + default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", req->op); @@ -743,6 +1086,18 @@ glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req) ret = glusterd_op_create_volume (req); break; + case GD_OP_START_VOLUME: + ret = glusterd_op_start_volume (req); + break; + + case GD_OP_STOP_VOLUME: + ret = glusterd_op_stop_volume (req); + break; + + case GD_OP_DELETE_VOLUME: + ret = glusterd_op_delete_volume (req); + break; + default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", req->op); diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 3bfbcb9a26b..500d0ebc344 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -116,11 +116,13 @@ struct glusterd_op_info_ { typedef struct glusterd_op_info_ glusterd_op_info_t; -struct glusterd_op_create_volume_ctx_ { +struct glusterd_op_start_volume_ctx_ { char volume_name[GD_VOLUME_NAME_MAX]; }; -typedef struct glusterd_op_create_volume_ctx_ glusterd_op_create_volume_ctx_t; +typedef struct glusterd_op_start_volume_ctx_ glusterd_op_start_volume_ctx_t; +typedef struct glusterd_op_start_volume_ctx_ glusterd_op_stop_volume_ctx_t; +typedef struct glusterd_op_start_volume_ctx_ glusterd_op_delete_volume_ctx_t; struct glusterd_op_lock_ctx_ { diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c index c02412683ce..a5f760f369d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-sm.c @@ -29,7 +29,6 @@ #include <libgen.h> #include "uuid.h" -//#include "transport.h" #include "fnmatch.h" #include "xlator.h" #include "protocol-common.h" @@ -96,13 +95,6 @@ glusterd_ac_friend_add (glusterd_friend_sm_event_t *event, void *ctx) ret = proc->fn (frame, this, event); } -/* ret = glusterd_xfer_friend_req_msg (peerinfo, THIS); - - if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to probe: %s", hostname); - } -*/ - out: gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); @@ -147,13 +139,6 @@ glusterd_ac_friend_probe (glusterd_friend_sm_event_t *event, void *ctx) } -/* ret = glusterd_friend_probe (hostname); - - if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to probe: %s", hostname); - } -*/ - out: gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); @@ -190,12 +175,41 @@ glusterd_ac_send_friend_remove_req (glusterd_friend_sm_event_t *event, void *ctx ret = proc->fn (frame, this, event); } -/* ret = glusterd_xfer_friend_req_msg (peerinfo, THIS); +out: + gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to probe: %s", hostname); + return ret; +} + +static int +glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx) +{ + int ret = 0; + glusterd_peerinfo_t *peerinfo = NULL; + rpc_clnt_procedure_t *proc = NULL; + call_frame_t *frame = NULL; + glusterd_conf_t *conf = NULL; + xlator_t *this = NULL; + + + GF_ASSERT (event); + peerinfo = event->peerinfo; + + this = THIS; + conf = this->private; + + GF_ASSERT (conf); + GF_ASSERT (conf->mgmt); + + proc = &conf->mgmt->proctable[GD_MGMT_FRIEND_UPDATE]; + if (proc->fn) { + frame = create_frame (this, this->ctx->pool); + if (!frame) { + goto out; + } + frame->local = ctx; + ret = proc->fn (frame, this, event); } -*/ out: gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); @@ -203,6 +217,7 @@ out: return ret; } + static int glusterd_ac_handle_friend_remove_req (glusterd_friend_sm_event_t *event, void *ctx) @@ -260,6 +275,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx) uuid_t uuid; glusterd_peerinfo_t *peerinfo = NULL; glusterd_friend_req_ctx_t *ev_ctx = NULL; + glusterd_friend_update_ctx_t *new_ev_ctx = NULL; glusterd_friend_sm_event_t *new_event = NULL; glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE; int status = 0; @@ -285,10 +301,24 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx) } new_event->peerinfo = peerinfo; + + new_ev_ctx = GF_CALLOC (1, sizeof (*new_ev_ctx), + gf_gld_mt_friend_update_ctx_t); + if (!new_ev_ctx) { + ret = -1; + goto out; + } + + uuid_copy (new_ev_ctx->uuid, ev_ctx->uuid); + new_ev_ctx->hostname = gf_strdup (ev_ctx->hostname); + + new_event->ctx = new_ev_ctx; + glusterd_friend_sm_inject_event (new_event); ret = glusterd_xfer_friend_add_resp (ev_ctx->req, ev_ctx->hostname); +out: gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); return ret; @@ -373,7 +403,7 @@ glusterd_sm_t glusterd_state_req_sent_rcvd [] = { {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_NONE, {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_PROBE, {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ, - {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_ACC + {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_ACC {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT @@ -401,8 +431,8 @@ glusterd_sm_t glusterd_state_req_accepted [] = { {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_NONE, {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_PROBE, {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ, - {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_ACC - {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC + {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_ACC + {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h index 2c31238f145..ee1b4cc6b6f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-sm.h @@ -55,6 +55,10 @@ typedef struct glusterd_peer_state_info_ { struct timeval transition_time; }glusterd_peer_state_info_t; +typedef struct glusterd_peer_hostname_ { + char *hostname; + struct list_head hostname_list; +}glusterd_peer_hostname_t; struct glusterd_peerinfo_ { uuid_t uuid; @@ -64,6 +68,7 @@ struct glusterd_peerinfo_ { int port; struct list_head uuid_list; struct list_head op_peers_list; + struct list_head hostnames; struct rpc_clnt *rpc; }; @@ -108,6 +113,8 @@ typedef struct glusterd_friend_req_ctx_ { rpcsvc_request_t *req; } glusterd_friend_req_ctx_t; +typedef glusterd_friend_req_ctx_t glusterd_friend_update_ctx_t; + typedef struct glusterd_probe_ctx_ { char *hostname; rpcsvc_request_t *req; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index feb4919ee19..ad9c907faf6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -28,8 +28,6 @@ #include "glusterfs.h" #include "compat.h" #include "dict.h" -//#include "protocol.h" -//#include "transport.h" #include "xlator.h" #include "logging.h" #include "timer.h" @@ -44,6 +42,8 @@ #include <sys/resource.h> #include <inttypes.h> +#include <signal.h> +#include <sys/types.h> static glusterd_lock_t lock; @@ -336,15 +336,19 @@ glusterd_check_volume_exists (char *volname) char pathname[1024] = {0,}; struct stat stbuf = {0,}; int32_t ret = -1; + glusterd_conf_t *priv = NULL; - snprintf (pathname, 1024, "%s/vols/%s", GLUSTERD_DEFAULT_WORKDIR, + priv = THIS->private; + + snprintf (pathname, 1024, "%s/vols/%s", priv->workdir, volname); ret = stat (pathname, &stbuf); if (ret) { gf_log ("", GF_LOG_DEBUG, "Volume %s does not exist." - "stat failed with errno: %d", volname, errno); + "stat failed with errno : %d on path: %s", + volname, errno, pathname); return _gf_false; } @@ -378,6 +382,49 @@ out: } int32_t +glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo) +{ + int32_t ret = -1; + + GF_ASSERT (brickinfo); + + list_del_init (&brickinfo->brick_list); + + GF_FREE (brickinfo); + + ret = 0; + + return ret; +} + +int32_t +glusterd_volinfo_delete (glusterd_volinfo_t *volinfo) +{ + int32_t ret = -1; + glusterd_brickinfo_t *brickinfo = NULL; + glusterd_brickinfo_t *tmp = NULL; + + GF_ASSERT (volinfo); + + list_del_init (&volinfo->vol_list); + + list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks, + brick_list) { + ret = glusterd_brickinfo_delete (brickinfo); + if (ret) + goto out; + } + + GF_FREE (volinfo); + ret = 0; + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + + +int32_t glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo) { glusterd_brickinfo_t *new_brickinfo = NULL; @@ -403,7 +450,48 @@ out: } int32_t -glusterd_brickinfo_from_brick (char *brick, glusterd_brickinfo_t **brickinfo) +glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo) +{ + int32_t ret = -1; + glusterd_peerinfo_t *peerinfo = NULL; + glusterd_conf_t *priv = NULL; + glusterd_peer_hostname_t *host = NULL; + + priv = THIS->private; + GF_ASSERT (priv); + + GF_ASSERT (brickinfo); + + ret = glusterd_friend_find (NULL, brickinfo->hostname, &peerinfo); + + if (!ret) { + uuid_copy (brickinfo->uuid, peerinfo->uuid); + } else { + list_for_each_entry (host, &priv->hostnames, hostname_list) { + if (!strcmp (host->hostname, brickinfo->hostname)) { + uuid_copy (brickinfo->uuid, priv->uuid); + ret = 0; + break; + } + + } + } + + if (ret) { + if ((!strcmp (brickinfo->hostname, "localhost")) || + (!strcmp (brickinfo->hostname, "127.0.0.1"))) { + uuid_copy (brickinfo->uuid, priv->uuid); + ret = 0; + } + } + + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +int32_t +glusterd_brickinfo_from_brick (char *brick, + glusterd_brickinfo_t **brickinfo) { int32_t ret = -1; glusterd_brickinfo_t *new_brickinfo = NULL; @@ -444,7 +532,197 @@ glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo) rpc_clnt_destroy (peerinfo->rpc); peerinfo->rpc = NULL; } - GF_FREE (peerinfo->hostname); + glusterd_peer_destroy (peerinfo); return 0; } + +int32_t +glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo) +{ + glusterd_volinfo_t *tmp_volinfo = NULL; + int32_t ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *priv = NULL; + + GF_ASSERT (volname); + + this = THIS; + GF_ASSERT (this); + + priv = this->private; + + list_for_each_entry (tmp_volinfo, &priv->volumes, vol_list) { + if (!strcmp (tmp_volinfo->volname, volname)) { + gf_log ("", GF_LOG_DEBUG, "Volume %s found", volname); + ret = 0; + *volinfo = tmp_volinfo; + break; + } + } + + + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + + + +int32_t +glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t *brickinfo) +{ + int32_t ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *priv = NULL; + char pidfile[PATH_MAX] = {0,}; + char volfile[PATH_MAX] = {0,}; + char path[PATH_MAX] = {0,}; + char cmd_str[8192] = {0,}; + char rundir[PATH_MAX] = {0,}; + + GF_ASSERT (volinfo); + GF_ASSERT (brickinfo); + + this = THIS; + GF_ASSERT (this); + + priv = this->private; + + GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); + snprintf (rundir, PATH_MAX, "%s/run", path); + ret = mkdir (rundir, 0777); + + if ((ret == -1) && (EEXIST != errno)) { + gf_log ("", GF_LOG_ERROR, "Unable to create rundir %s", + rundir); + goto out; + } + + GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname); + snprintf (volfile, PATH_MAX, "%s/%s-%s-export.vol", path, + brickinfo->hostname, volinfo->volname); + snprintf (cmd_str, 8192, "glusterfs -f %s -p %s", volfile, pidfile); + ret = system (cmd_str); + +out: + return ret; +} + +int32_t +glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t *brickinfo) +{ + int32_t ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *priv = NULL; + char pidfile[PATH_MAX] = {0,}; + char path[PATH_MAX] = {0,}; + pid_t pid = -1; + FILE *file = NULL; + + GF_ASSERT (volinfo); + GF_ASSERT (brickinfo); + + this = THIS; + GF_ASSERT (this); + + priv = this->private; + + GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); + GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname); + + file = fopen (pidfile, "r+"); + + if (!file) { + gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s", + pidfile); + ret = -1; + goto out; + } + + ret = fscanf (file, "%d", &pid); + if (ret <= 0) { + gf_log ("", GF_LOG_ERROR, "Unable to read pidfile: %s", + pidfile); + ret = -1; + goto out; + } + fclose (file); + file = NULL; + + gf_log ("", GF_LOG_NORMAL, "Stopping glusterfs running in pid: %d", + pid); + + ret = kill (pid, SIGQUIT); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to kill pid %d", pid); + goto out; + } + + ret = unlink (pidfile); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to unlink pidfile: %s", + pidfile); + goto out; + } + +out: + if (file) + fclose (file); + return ret; +} + +int32_t +glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name) +{ + glusterd_peer_hostname_t *peer_hostname = NULL; + int32_t ret = -1; + + GF_ASSERT (hostname); + GF_ASSERT (name); + + peer_hostname = GF_CALLOC (1, sizeof (*peer_hostname), + gf_gld_mt_peer_hostname_t); + + if (!peer_hostname) + goto out; + + peer_hostname->hostname = gf_strdup (hostname); + INIT_LIST_HEAD (&peer_hostname->hostname_list); + + *name = peer_hostname; + ret = 0; + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +int32_t +glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo) +{ + int32_t ret = -1; + glusterd_peer_hostname_t *name = NULL; + glusterd_peer_hostname_t *tmp = NULL; + + if (!peerinfo) + goto out; + + list_del_init (&peerinfo->uuid_list); + list_for_each_entry_safe (name, tmp, &peerinfo->hostnames, + hostname_list) { + list_del_init (&name->hostname_list); + GF_FREE (name->hostname); + } + + list_del_init (&peerinfo->hostnames); + GF_FREE (peerinfo); + + ret = 0; + +out: + return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 03c1b9fb6c0..f21971a599e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -79,4 +79,30 @@ glusterd_brickinfo_from_brick (char *brick, glusterd_brickinfo_t **brickinfo); int32_t glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo); + +int32_t +glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo); + +int32_t +glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name); + +int32_t +glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo); + +int32_t +glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo); + +int32_t +glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t *brickinfo); + +int32_t +glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t *brickinfo); + +int32_t +glusterd_volinfo_delete (glusterd_volinfo_t *volinfo); + +int32_t +glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 8b8509d4c0b..3be035e63ac 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -170,7 +170,7 @@ init (xlator_t *this) struct stat buf = {0,}; char *port_str = NULL; int port_num = 0; - char voldir [PATH_MAX]; + char voldir [PATH_MAX] = {0,}; dir_data = dict_get (this->options, "working-directory"); @@ -199,7 +199,7 @@ init (xlator_t *this) if ((-1 == ret) && (ENOENT == errno)) { - ret = mkdir (dirname, 0644); + ret = mkdir (dirname, 0777); if (-1 == ret) { gf_log (this->name, GF_LOG_CRITICAL, @@ -213,9 +213,9 @@ init (xlator_t *this) snprintf (voldir, PATH_MAX, "%s/vols", dirname); - ret = mkdir (voldir, 0644); + ret = mkdir (voldir, 0777); - if (-1 == ret) { + if ((-1 == ret) && (errno != EEXIST)) { gf_log (this->name, GF_LOG_CRITICAL, "Unable to create volume directory %s" " ,errno = %d", voldir, errno); @@ -260,6 +260,7 @@ init (xlator_t *this) GF_VALIDATE_OR_GOTO(this->name, conf, out); INIT_LIST_HEAD (&conf->peers); INIT_LIST_HEAD (&conf->volumes); + INIT_LIST_HEAD (&conf->hostnames); pthread_mutex_init (&conf->mutex, NULL); conf->rpc = rpc; conf->mgmt = &glusterd3_1_mgmt_prog; diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index d92ec31cd25..a998ce4492b 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -54,12 +54,14 @@ typedef struct { rpcsvc_t *rpc; rpc_clnt_prog_t *mgmt; struct list_head volumes; + struct list_head hostnames; } glusterd_conf_t; struct glusterd_brickinfo { char hostname[1024]; char path[PATH_MAX]; struct list_head brick_list; + uuid_t uuid; }; typedef struct glusterd_brickinfo glusterd_brickinfo_t; @@ -70,19 +72,23 @@ struct glusterd_volinfo_ { int brick_count; struct list_head vol_list; struct list_head bricks; + glusterd_volume_status status; }; typedef struct glusterd_volinfo_ glusterd_volinfo_t; #define GLUSTERD_DEFAULT_WORKDIR "/etc/glusterd" -#define GLUSTERD_DEFAULT_PORT 4284 +#define GLUSTERD_DEFAULT_PORT 6969 typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); #define GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv) \ snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir,\ volinfo->volname); + +#define GLUSTERD_GET_BRICK_PIDFILE(pidfile, volpath, hostname)\ + snprintf (pidfile, PATH_MAX, "%s/run/%s.pid", volpath, hostname); int glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr); @@ -170,4 +176,31 @@ glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags); int glusterd_handle_cli_list_friends (rpcsvc_request_t *req); + +int +glusterd_handle_cli_start_volume (rpcsvc_request_t *req); + +int32_t +glusterd_start_volume (rpcsvc_request_t *req, char *volname, int flags); + +int +glusterd_handle_friend_update (rpcsvc_request_t *req); + +int +glusterd_handle_cli_stop_volume (rpcsvc_request_t *req); + +int +glusterd_stop_volume (rpcsvc_request_t *req, char *volname, int flags); + +int32_t +glusterd_delete_volume (rpcsvc_request_t *req, char *volname, int flags); + +int +glusterd_handle_cli_delete_volume (rpcsvc_request_t *req); + +int +glusterd_handle_cli_get_volume (rpcsvc_request_t *req); + +int32_t +glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c index 29e1dd6251d..3ea0f66fadd 100644 --- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c +++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c @@ -59,6 +59,7 @@ glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov, glusterd_peerinfo_t *peerinfo = NULL; glusterd_peerinfo_t *dup_peerinfo = NULL; glusterd_friend_sm_event_t *event = NULL; + glusterd_peer_hostname_t *name = NULL; conf = THIS->private; @@ -85,17 +86,18 @@ glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov, GF_ASSERT (0); } - if (!peerinfo->hostname) { + if (list_empty (&peerinfo->hostnames)) { glusterd_friend_find (NULL, rsp.hostname, &dup_peerinfo); GF_ASSERT (dup_peerinfo); - GF_ASSERT (dup_peerinfo->hostname); peerinfo->hostname = gf_strdup (rsp.hostname); + glusterd_peer_hostname_new (rsp.hostname, &name); + list_add_tail (&name->hostname_list, &peerinfo->hostnames); peerinfo->rpc = dup_peerinfo->rpc; list_del_init (&dup_peerinfo->uuid_list); - GF_FREE (dup_peerinfo->hostname); GF_FREE (dup_peerinfo); } - GF_ASSERT (peerinfo->hostname); + if (!peerinfo->hostname) + peerinfo->hostname = gf_strdup (rsp.hostname); uuid_copy (peerinfo->uuid, rsp.uuid); ret = glusterd_friend_sm_new_event @@ -139,6 +141,7 @@ glusterd3_1_friend_add_cbk (struct rpc_req * req, struct iovec *iov, int32_t op_ret = -1; int32_t op_errno = -1; glusterd_probe_ctx_t *ctx = NULL; + glusterd_friend_update_ctx_t *ev_ctx = NULL; conf = THIS->private; @@ -182,7 +185,17 @@ glusterd3_1_friend_add_cbk (struct rpc_req * req, struct iovec *iov, goto out; } event->peerinfo = peerinfo; + ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx), + gf_gld_mt_friend_update_ctx_t); + if (!ev_ctx) { + ret = -1; + goto out; + } + + uuid_copy (ev_ctx->uuid, rsp.uuid); + ev_ctx->hostname = gf_strdup (rsp.hostname); + event->ctx = ev_ctx; ret = glusterd_friend_sm_inject_event (event); if (ret) @@ -683,6 +696,45 @@ out: int32_t +glusterd3_1_friend_update (call_frame_t *frame, xlator_t *this, + void *data) +{ + gd1_mgmt_friend_update req = {{0},}; + int ret = 0; + glusterd_peerinfo_t *peerinfo = NULL; + glusterd_conf_t *priv = NULL; + glusterd_friend_sm_event_t *event = NULL; + glusterd_friend_update_ctx_t *ctx = NULL; + + + if (!frame || !this || !data) { + ret = -1; + goto out; + } + + event = data; + priv = this->private; + + GF_ASSERT (priv); + + ctx = event->ctx; + + peerinfo = event->peerinfo; + uuid_copy (req.uuid, priv->uuid); + uuid_copy (req.friend_uuid, ctx->uuid); + req.hostname = ctx->hostname; + + ret = glusterd_submit_request (peerinfo, &req, frame, priv->mgmt, + GD_MGMT_FRIEND_UPDATE, + NULL, gd_xdr_from_mgmt_friend_update, + this, NULL); + +out: + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +int32_t glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this, void *data) { @@ -1016,6 +1068,26 @@ glusterd_handle_rpc_msg (rpcsvc_request_t *req) ret = glusterd_handle_cli_list_friends (req); break; + case GD_MGMT_CLI_START_VOLUME: + ret = glusterd_handle_cli_start_volume (req); + break; + + case GD_MGMT_CLI_STOP_VOLUME: + ret = glusterd_handle_cli_stop_volume (req); + break; + + case GD_MGMT_CLI_DELETE_VOLUME: + ret = glusterd_handle_cli_delete_volume (req); + break; + + case GD_MGMT_FRIEND_UPDATE: + ret = glusterd_handle_friend_update (req); + break; + + case GD_MGMT_CLI_GET_VOLUME: + ret = glusterd_handle_cli_get_volume (req); + break; + default: GF_ASSERT (0); } @@ -1034,6 +1106,7 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = { [GD_MGMT_PROBE_QUERY] = { "PROBE_QUERY", GD_MGMT_PROBE_QUERY, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_FRIEND_ADD] = { "FRIEND_ADD", GD_MGMT_FRIEND_ADD, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_FRIEND_REMOVE] = { "FRIEND_REMOVE", GD_MGMT_FRIEND_REMOVE, glusterd_handle_rpc_msg, NULL, NULL}, + [GD_MGMT_FRIEND_UPDATE] = { "FRIEND_UPDATE", GD_MGMT_FRIEND_UPDATE, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_CLUSTER_LOCK] = { "CLUSTER_LOCK", GD_MGMT_CLUSTER_LOCK, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_CLUSTER_UNLOCK] = { "CLUSTER_UNLOCK", GD_MGMT_CLUSTER_UNLOCK, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_STAGE_OP] = { "STAGE_OP", GD_MGMT_STAGE_OP, glusterd_handle_rpc_msg, NULL, NULL}, @@ -1042,6 +1115,10 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = { [GD_MGMT_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GD_MGMT_CLI_CREATE_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_CLI_DEPROBE] = { "FRIEND_REMOVE", GD_MGMT_CLI_DEPROBE, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GD_MGMT_CLI_LIST_FRIENDS, glusterd_handle_rpc_msg, NULL, NULL}, + [GD_MGMT_CLI_START_VOLUME] = { "START_VOLUME", GD_MGMT_CLI_START_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, + [GD_MGMT_CLI_STOP_VOLUME] = { "STOP_VOLUME", GD_MGMT_CLI_STOP_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, + [GD_MGMT_CLI_DELETE_VOLUME] = { "DELETE_VOLUME", GD_MGMT_CLI_DELETE_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, + [GD_MGMT_CLI_GET_VOLUME] = { "GET_VOLUME", GD_MGMT_CLI_GET_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, }; /*rpcsvc_actor_t glusterd1_mgmt_actors[] = { @@ -1075,7 +1152,7 @@ struct rpc_clnt_procedure glusterd3_1_clnt_mgmt_actors[GD_MGMT_MAXVALUE] = { [GD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd3_1_stage_op}, [GD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd3_1_commit_op}, [GD_MGMT_FRIEND_REMOVE] = { "FRIEND_REMOVE", glusterd3_1_friend_remove}, -// [GF_FOP_GETSPEC] = { "GETSPEC", client_getspec, client_getspec_cbk }, + [GD_MGMT_FRIEND_UPDATE] = { "FRIEND_UPDATE", glusterd3_1_friend_update}, }; |