summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-handler.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c1388
1 files changed, 1388 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
new file mode 100644
index 00000000000..00067a566d4
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -0,0 +1,1388 @@
+/*
+ Copyright (c) 2006-2009 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+#include <inttypes.h>
+
+
+#include "globals.h"
+#include "glusterfs.h"
+#include "compat.h"
+#include "dict.h"
+#include "protocol-common.h"
+#include "xlator.h"
+#include "logging.h"
+#include "timer.h"
+#include "defaults.h"
+#include "compat.h"
+#include "compat-errno.h"
+#include "statedump.h"
+#include "glusterd-mem-types.h"
+#include "glusterd.h"
+#include "glusterd-sm.h"
+#include "glusterd-op-sm.h"
+#include "glusterd-utils.h"
+#include "gd-xdr.h"
+#include "cli-xdr.h"
+#include "rpc-clnt.h"
+
+#include <sys/resource.h>
+#include <inttypes.h>
+
+/* for default_*_cbk functions */
+#include "defaults.c"
+#include "common-utils.h"
+
+
+/*typedef int32_t (*glusterd_mop_t) (call_frame_t *frame,
+ gf_hdr_common_t *hdr, size_t hdrlen);*/
+
+//static glusterd_mop_t glusterd_ops[GF_MOP_MAXVALUE];
+
+
+
+static int
+glusterd_friend_find_by_hostname (const char *hoststr,
+ glusterd_peerinfo_t **peerinfo)
+{
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_peerinfo_t *entry = NULL;
+
+ GF_ASSERT (hoststr);
+ GF_ASSERT (peerinfo);
+
+ *peerinfo = NULL;
+ priv = THIS->private;
+
+ GF_ASSERT (priv);
+
+ list_for_each_entry (entry, &priv->peers, uuid_list) {
+ if (entry->hostname && (!strncmp (entry->hostname, hoststr,
+ sizeof (entry->hostname)))) {
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Friend %s found.. state: %d", hoststr,
+ entry->state.state);
+ *peerinfo = entry;
+ return 0;
+ }
+ }
+
+ return ret;
+}
+
+static int
+glusterd_friend_find_by_uuid (uuid_t uuid,
+ glusterd_peerinfo_t **peerinfo)
+{
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_peerinfo_t *entry = NULL;
+
+ GF_ASSERT (peerinfo);
+
+ *peerinfo = NULL;
+ priv = THIS->private;
+
+ GF_ASSERT (priv);
+
+ list_for_each_entry (entry, &priv->peers, uuid_list) {
+ if (!uuid_compare (entry->uuid, uuid)) {
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Friend found.. state: %d",
+ entry->state.state);
+ *peerinfo = entry;
+ return 0;
+ }
+ }
+
+ return ret;
+}
+
+static int
+glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, char *hostname)
+{
+ int ret = -1;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_friend_sm_event_t *event = NULL;
+ glusterd_friend_req_ctx_t *ctx = NULL;
+
+
+ ret = glusterd_friend_find (uuid, hostname, &peerinfo);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Unable to find peer");
+
+ }
+
+ ret = glusterd_friend_sm_new_event
+ (GD_FRIEND_EVENT_RCVD_FRIEND_REQ, &event);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "event generation failed: %d", ret);
+ return ret;
+ }
+
+ event->peerinfo = peerinfo;
+
+ ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_friend_req_ctx_t);
+
+ if (!ctx) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ ret = -1;
+ goto out;
+ }
+
+ uuid_copy (ctx->uuid, uuid);
+ if (hostname)
+ ctx->hostname = gf_strdup (hostname);
+ ctx->req = req;
+
+ event->ctx = ctx;
+
+ ret = glusterd_friend_sm_inject_event (event);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject event %d, "
+ "ret = %d", event->event, ret);
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ if (0 != ret) {
+ if (ctx && ctx->hostname)
+ GF_FREE (ctx->hostname);
+ if (ctx)
+ GF_FREE (ctx);
+ }
+
+ return ret;
+}
+
+
+
+
+
+int
+glusterd_friend_find (uuid_t uuid, char *hostname,
+ glusterd_peerinfo_t **peerinfo)
+{
+ int ret = -1;
+
+ if (uuid) {
+ ret = glusterd_friend_find_by_uuid (uuid, peerinfo);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Unable to find peer by uuid");
+ } else {
+ goto out;
+ }
+
+ }
+
+ if (hostname) {
+ ret = glusterd_friend_find_by_hostname (hostname, peerinfo);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Unable to find hostname: %s", hostname);
+ } else {
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int
+glusterd_handle_cluster_lock (rpcsvc_request_t *req)
+{
+ gd1_mgmt_cluster_lock_req lock_req = {{0},};
+ int32_t ret = -1;
+ char str[50] = {0,};
+ glusterd_op_sm_event_t *event = NULL;
+ glusterd_op_lock_ctx_t *ctx = NULL;
+
+ GF_ASSERT (req);
+
+ if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &lock_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+ uuid_unparse (lock_req.uuid, str);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Received LOCK from uuid: %s", str);
+
+ ret = glusterd_op_sm_new_event (GD_OP_EVENT_LOCK, &event);
+
+ if (ret) {
+ //respond back here
+ return ret;
+ }
+
+ ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_stage_ctx_t);
+
+ if (!ctx) {
+ //respond here
+ return -1;
+ }
+
+ uuid_copy (ctx->uuid, lock_req.uuid);
+ ctx->req = req;
+ event->ctx = ctx;
+
+ ret = glusterd_op_sm_inject_event (event);
+
+out:
+ gf_log ("", GF_LOG_NORMAL, "Returning %d", ret);
+
+ return ret;
+}
+
+int
+glusterd_handle_stage_op (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ char str[50];
+ gd1_mgmt_stage_op_req *stage_req = NULL;
+ glusterd_op_sm_event_t *event = NULL;
+ glusterd_op_stage_ctx_t *ctx = NULL;
+
+ GF_ASSERT (req);
+
+ stage_req = GF_CALLOC (1, sizeof (*stage_req),
+ gf_gld_mt_mop_stage_req_t);
+
+ GF_ASSERT (stage_req);
+
+ if (!gd_xdr_to_mgmt_stage_op_req (req->msg[0], stage_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ uuid_unparse (stage_req->uuid, str);
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Received stage op from uuid: %s", str);
+
+ ret = glusterd_op_sm_new_event (GD_OP_EVENT_STAGE_OP, &event);
+
+ if (ret) {
+ //respond back here
+ return ret;
+ }
+
+ ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_stage_ctx_t);
+
+ if (!ctx) {
+ //respond here
+ return -1;
+ }
+
+ //CHANGE THIS
+ ctx->stage_req = &stage_req;
+ ctx->req = req;
+ event->ctx = ctx;
+
+ ret = glusterd_op_sm_inject_event (event);
+
+out:
+ return ret;
+}
+
+int
+glusterd_handle_commit_op (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ char str[50];
+ glusterd_op_sm_event_t *event = NULL;
+ gd1_mgmt_commit_op_req commit_req = {{0},};
+ glusterd_op_commit_ctx_t *ctx = NULL;
+
+ GF_ASSERT (req);
+
+ if (!gd_xdr_to_mgmt_commit_op_req (req->msg[0], &commit_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ uuid_unparse (commit_req.uuid, str);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Received commit op from uuid: %s", str);
+
+ ret = glusterd_op_sm_new_event (GD_OP_EVENT_COMMIT_OP, &event);
+
+ if (ret) {
+ //respond back here
+ return ret;
+ }
+
+ ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_commit_ctx_t);
+
+ if (!ctx) {
+ //respond here
+ return -1;
+ }
+
+ ctx->req = req;
+ //CHANGE THIS
+ ctx->stage_req = &commit_req;
+ event->ctx = ctx;
+
+ ret = glusterd_op_sm_inject_event (event);
+
+out:
+ return ret;
+}
+
+int
+glusterd_handle_cli_probe (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_probe_req cli_req = {0,};
+
+ GF_ASSERT (req);
+
+ if (!gf_xdr_to_cli_probe_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_NORMAL, "Received CLI probe req");
+
+
+ ret = glusterd_probe_begin (req, cli_req.hostname);
+
+out:
+ return ret;
+}
+
+int
+glusterd_handle_create_volume (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_create_vol_req cli_req = {0,};
+ dict_t *dict = NULL;
+
+ GF_ASSERT (req);
+
+ if (!gf_xdr_to_cli_create_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 create volume req");
+
+ if (cli_req.bricks.bricks_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (cli_req.bricks.bricks_val,
+ cli_req.bricks.bricks_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ }
+ }
+
+ ret = glusterd_create_volume (req, dict);
+
+out:
+ return ret;
+}
+
+int
+glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status)
+{
+
+ gd1_mgmt_cluster_lock_rsp rsp = {{0},};
+ int ret = -1;
+
+ GF_ASSERT (req);
+ glusterd_get_uuid (&rsp.uuid);
+ rsp.op_ret = status;
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gd_xdr_serialize_mgmt_cluster_lock_rsp);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Responded, ret: %d", ret);
+
+ return 0;
+}
+
+int
+glusterd_op_unlock_send_resp (rpcsvc_request_t *req, int32_t status)
+{
+
+ gd1_mgmt_cluster_unlock_rsp rsp = {{0},};
+ int ret = -1;
+
+ GF_ASSERT (req);
+ rsp.op_ret = status;
+ glusterd_get_uuid (&rsp.uuid);
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gd_xdr_serialize_mgmt_cluster_unlock_rsp);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Responded to unlock, ret: %d", ret);
+
+ return ret;
+}
+
+int
+glusterd_handle_cluster_unlock (rpcsvc_request_t *req)
+{
+ gd1_mgmt_cluster_unlock_req unlock_req = {{0}, };
+ int32_t ret = -1;
+ char str[50] = {0, };
+ glusterd_op_lock_ctx_t *ctx = NULL;
+ glusterd_op_sm_event_t *event = NULL;
+
+ GF_ASSERT (req);
+
+ if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &unlock_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ uuid_unparse (unlock_req.uuid, str);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Received UNLOCK from uuid: %s", str);
+
+ ret = glusterd_op_sm_new_event (GD_OP_EVENT_UNLOCK, &event);
+
+ if (ret) {
+ //respond back here
+ return ret;
+ }
+
+ ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_lock_ctx_t);
+
+ if (!ctx) {
+ //respond here
+ return -1;
+ }
+ event->ctx = ctx;
+ uuid_copy (ctx->uuid, unlock_req.uuid);
+ ctx->req = req;
+
+ ret = glusterd_op_sm_inject_event (event);
+
+out:
+ return ret;
+}
+
+int
+glusterd_op_stage_send_resp (rpcsvc_request_t *req,
+ int32_t op, int32_t status)
+{
+
+ gd1_mgmt_stage_op_rsp rsp = {{0},};
+ int ret = -1;
+
+ GF_ASSERT (req);
+ rsp.op_ret = status;
+ glusterd_get_uuid (&rsp.uuid);
+ rsp.op = op;
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gd_xdr_serialize_mgmt_stage_op_rsp);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Responded to stage, ret: %d", ret);
+
+ return ret;
+}
+
+int
+glusterd_op_commit_send_resp (rpcsvc_request_t *req,
+ int32_t op, int32_t status)
+{
+ gd1_mgmt_commit_op_rsp rsp = {{0}, };
+ int ret = -1;
+
+ GF_ASSERT (req);
+ rsp.op_ret = status;
+ glusterd_get_uuid (&rsp.uuid);
+ rsp.op = op;
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gd_xdr_serialize_mgmt_commit_op_rsp);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Responded to commit, ret: %d", ret);
+
+ return ret;
+}
+
+int
+glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gd1_mgmt_friend_req friend_req = {{0},};
+ char str[50];
+
+ GF_ASSERT (req);
+ if (!gd_xdr_to_mgmt_friend_req (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 probe from uuid: %s", str);
+
+ ret = glusterd_handle_friend_req (req, friend_req.uuid,
+ friend_req.hostname);
+
+out:
+
+ return ret;
+}
+
+int
+glusterd_handle_probe_query (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ char str[50];
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ gd1_mgmt_probe_req probe_req = {{0},};
+ gd1_mgmt_probe_rsp rsp = {{0},};
+ char hostname[1024] = {0};
+
+ GF_ASSERT (req);
+
+ probe_req.hostname = hostname;
+
+ if (!gd_xdr_to_mgmt_probe_req (req->msg[0], &probe_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+
+ uuid_unparse (probe_req.uuid, str);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Received probe from uuid: %s", str);
+
+
+ this = THIS;
+
+ conf = this->private;
+
+ uuid_copy (rsp.uuid, conf->uuid);
+ rsp.hostname = gf_strdup (probe_req.hostname);
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gd_xdr_serialize_mgmt_probe_rsp);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Responded to %s, ret: %d", probe_req.hostname, ret);
+
+out:
+ return ret;
+}
+
+/*int
+glusterd_handle_friend_req_resp (call_frame_t *frame,
+ gf_hdr_common_t *rsp_hdr, size_t hdrlen)
+{
+ gf_mop_probe_rsp_t *rsp = NULL;
+ int32_t ret = -1;
+ char str[50];
+ glusterd_peerinfo_t *peerinfo = NULL;
+ int32_t op_ret = -1;
+ glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
+ glusterd_friend_sm_event_t *event = NULL;
+
+ GF_ASSERT (rsp_hdr);
+
+ rsp = gf_param (rsp_hdr);
+ uuid_unparse (rsp->uuid, str);
+
+ op_ret = rsp_hdr->rsp.op_ret;
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Received %s from uuid: %s, host: %s",
+ (op_ret)?"RJT":"ACC", str, rsp->hostname);
+
+ ret = glusterd_friend_find (rsp->uuid, rsp->hostname, &peerinfo);
+
+ if (ret) {
+ GF_ASSERT (0);
+ }
+
+ if (op_ret)
+ event_type = GD_FRIEND_EVENT_RCVD_ACC;
+ else
+ event_type = GD_FRIEND_EVENT_RCVD_RJT;
+
+ ret = glusterd_friend_sm_new_event (event_type, &event);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Unable to get event");
+ return ret;
+ }
+
+ event->peerinfo = peerinfo;
+ ret = glusterd_friend_sm_inject_event (event);
+
+ gf_log ("glusterd", GF_LOG_NORMAL, "Received resp to friend req");
+
+ return 0;
+}*/
+
+/*int
+glusterd_handle_probe_resp (call_frame_t *frame, gf_hdr_common_t *rsp_hdr,
+ size_t hdrlen)
+{
+ gf_mop_probe_rsp_t *rsp = NULL;
+ int32_t ret = -1;
+ char str[50];
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_friend_sm_event_t *event = NULL;
+ glusterd_peerinfo_t *dup_peerinfo = NULL;
+
+ GF_ASSERT (rsp_hdr);
+
+ rsp = gf_param (rsp_hdr);
+ uuid_unparse (rsp->uuid, str);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Received probe resp from uuid: %s, host: %s",
+ str, rsp->hostname);
+
+ ret = glusterd_friend_find (rsp->uuid, rsp->hostname, &peerinfo);
+
+ if (ret) {
+ GF_ASSERT (0);
+ }
+
+ if (!peerinfo->hostname) {
+ glusterd_friend_find_by_hostname (rsp->hostname, &dup_peerinfo);
+ GF_ASSERT (dup_peerinfo);
+ GF_ASSERT (dup_peerinfo->hostname);
+ peerinfo->hostname = gf_strdup (rsp->hostname);
+ peerinfo->trans = dup_peerinfo->trans;
+ list_del_init (&dup_peerinfo->uuid_list);
+ GF_FREE (dup_peerinfo->hostname);
+ GF_FREE (dup_peerinfo);
+ }
+ GF_ASSERT (peerinfo->hostname);
+ uuid_copy (peerinfo->uuid, rsp->uuid);
+
+ ret = glusterd_friend_sm_new_event
+ (GD_FRIEND_EVENT_INIT_FRIEND_REQ, &event);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Unable to get event");
+ return ret;
+ }
+
+ event->peerinfo = peerinfo;
+ ret = glusterd_friend_sm_inject_event (event);
+
+ return 0;
+}*/
+
+/*
+static glusterd_mop_t glusterd_ops[GF_MOP_MAXVALUE] = {
+ [GF_MOP_PROBE_QUERY] = glusterd_handle_probe_query,
+ [GF_MOP_FRIEND_REQ] = glusterd_handle_incoming_friend_req,
+ [GF_MOP_STAGE_OP] = glusterd_handle_stage_op,
+ [GF_MOP_COMMIT_OP] = glusterd_handle_commit_op,
+ [GF_MOP_CLUSTER_LOCK] = glusterd_handle_cluster_lock,
+ [GF_MOP_CLUSTER_UNLOCK] = glusterd_handle_cluster_unlock,
+};
+
+static glusterd_mop_t glusterd_resp_ops [GF_MOP_MAXVALUE] = {
+ [GF_MOP_PROBE_QUERY] = glusterd_handle_probe_resp,
+ [GF_MOP_FRIEND_REQ] = glusterd_handle_friend_req_resp,
+};
+*/
+
+/*int
+glusterd_xfer_probe_msg (glusterd_peerinfo_t *peerinfo, xlator_t *this)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_mop_probe_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ call_frame_t *dummy_frame = NULL;
+ int len = 0;
+
+ GF_ASSERT (peerinfo);
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ len = STRLEN_0 (peerinfo->hostname);
+ hdrlen = gf_hdr_len (req, len);
+ hdr = gf_hdr_new (req, len);
+
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ memcpy (&req->uuid, &priv->uuid, sizeof(uuid_t));
+ strncpy (req->hostname, peerinfo->hostname, len);
+
+ dummy_frame = create_frame (this, this->ctx->pool);
+
+ if (!dummy_frame)
+ goto unwind;
+
+ dummy_frame->local = peerinfo->trans;
+
+ ret = glusterd_xfer (dummy_frame, this,
+ peerinfo->trans,
+ GF_OP_TYPE_MOP_REQUEST, GF_MOP_PROBE_QUERY,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ return 0;
+}*/
+
+/*int
+glusterd_xfer_friend_req_msg (glusterd_peerinfo_t *peerinfo, xlator_t *this)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_mop_probe_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ call_frame_t *dummy_frame = NULL;
+ int len = 0;
+
+ GF_ASSERT (peerinfo);
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ len = STRLEN_0 (peerinfo->hostname);
+ hdrlen = gf_hdr_len (req, len);
+ hdr = gf_hdr_new (req, len);
+
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ memcpy (&req->uuid, &priv->uuid, sizeof(uuid_t));
+ strncpy (req->hostname, peerinfo->hostname, len);
+
+ dummy_frame = create_frame (this, this->ctx->pool);
+
+ if (!dummy_frame)
+ goto unwind;
+
+ dummy_frame->local = peerinfo->trans;
+
+ ret = glusterd_xfer (dummy_frame, this,
+ peerinfo->trans,
+ GF_OP_TYPE_MOP_REQUEST, GF_MOP_FRIEND_REQ,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ //STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}*/
+
+/*int
+glusterd_xfer_cluster_lock_req (xlator_t *this, int32_t *lock_count)
+{
+ gd1_mgmt_cluster_lock_req req = {{0},};
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ call_frame_t *dummy_frame = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ int pending_lock = 0;
+ rpc_clnt_procedure_t *proc = NULL;
+
+ GF_ASSERT (this);
+ GF_ASSERT (lock_count);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ uuid_copy (req.uuid, priv->uuid);
+
+ dummy_frame = create_frame (this, this->ctx->pool);
+
+ if (!dummy_frame)
+ goto unwind;
+
+
+ list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
+ GF_ASSERT (peerinfo);
+
+ if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ continue;
+
+
+ ret = glusterd_submit_request (peerinfo, &req, dummy_frame,
+ prog, GD_MGMT_PROBE_QUERY,
+ NULL, gd_xdr_from_mgmt_probe_req,
+ this);
+ if (!ret)
+ pending_lock++;
+ }
+
+ gf_log ("glusterd", GF_LOG_NORMAL, "Sent lock req to %d peers",
+ pending_lock);
+ *lock_count = pending_lock;
+
+unwind:
+
+ return ret;
+}*/
+
+/*int
+glusterd_xfer_cluster_unlock_req (xlator_t *this, int32_t *pending_count)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_mop_cluster_unlock_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ call_frame_t *dummy_frame = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ int pending_unlock = 0;
+
+ GF_ASSERT (this);
+ GF_ASSERT (pending_count);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ uuid_copy (req->uuid, priv->uuid);
+
+ dummy_frame = create_frame (this, this->ctx->pool);
+
+ if (!dummy_frame)
+ goto unwind;
+
+
+ list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
+ GF_ASSERT (peerinfo);
+
+ if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ continue;
+
+
+ ret = glusterd_xfer (dummy_frame, this,
+ peerinfo->trans,
+ GF_OP_TYPE_MOP_REQUEST,
+ GF_MOP_CLUSTER_UNLOCK,
+ hdr, hdrlen, NULL, 0, NULL);
+ if (!ret)
+ pending_unlock++;
+ }
+
+ gf_log ("glusterd", GF_LOG_NORMAL, "Sent unlock req to %d peers",
+ pending_unlock);
+ *pending_count = pending_unlock;
+
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ return ret;
+}*/
+
+
+int
+glusterd_friend_add (const char *hoststr,
+ glusterd_peer_state_t state,
+ uuid_t *uuid,
+ struct rpc_clnt *rpc,
+ glusterd_peerinfo_t **friend)
+{
+ int ret = 0;
+ glusterd_conf_t *priv = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ dict_t *options = NULL;
+ char *port_str = NULL;
+ int port_num = 0;
+ struct rpc_clnt_config rpc_cfg = {0,};
+
+ priv = THIS->private;
+
+ peerinfo = GF_CALLOC (1, sizeof(*peerinfo), gf_gld_mt_peerinfo_t);
+
+ if (!peerinfo)
+ return -1;
+
+ if (friend)
+ *friend = peerinfo;
+
+ peerinfo->state.state = state;
+ if (hoststr) {
+ peerinfo->hostname = gf_strdup (hoststr);
+ rpc_cfg.remote_host = gf_strdup (hoststr);
+ }
+ INIT_LIST_HEAD (&peerinfo->uuid_list);
+
+ list_add_tail (&peerinfo->uuid_list, &priv->peers);
+
+ if (uuid) {
+ uuid_copy (peerinfo->uuid, *uuid);
+ }
+
+
+ if (hoststr) {
+ options = dict_new ();
+ if (!options)
+ return -1;
+
+ ret = dict_set_str (options, "remote-host", (char *)hoststr);
+ if (ret)
+ goto out;
+
+
+ port_str = getenv ("GLUSTERD_REMOTE_PORT");
+ port_num = atoi (port_str);
+ 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;
+
+ ret = dict_set_str (options, "transport.address-family", "inet");
+ if (ret)
+ goto out;
+
+ rpc = rpc_clnt_init (&rpc_cfg, options, THIS->ctx, THIS->name);
+
+ if (!rpc) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "rpc init failed for peer: %s!", hoststr);
+ ret = -1;
+ goto out;
+ }
+
+ ret = rpc_clnt_register_notify (rpc, glusterd_rpc_notify,
+ peerinfo);
+
+ peerinfo->rpc = rpc;
+
+ }
+
+ gf_log ("glusterd", GF_LOG_NORMAL, "connect returned %d", ret);
+
+out:
+ return ret;
+
+}
+
+/*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)
+{
+ int ret = -1;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_friend_sm_event_t *event = NULL;
+ glusterd_probe_ctx_t *ctx = NULL;
+
+ GF_ASSERT (hoststr);
+ GF_ASSERT (req);
+
+ ret = glusterd_friend_find (NULL, (char *)hoststr, &peerinfo);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_NORMAL, "Unable to find peerinfo"
+ " for host: %s", hoststr);
+ ret = glusterd_friend_add ((char *)hoststr, GD_PEER_STATE_NONE,
+ NULL, NULL, &peerinfo);
+ }
+
+ ret = glusterd_friend_sm_new_event
+ (GD_FRIEND_EVENT_PROBE, &event);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Unable to get new event");
+ return ret;
+ }
+
+ ctx = GF_CALLOC (1, sizeof(*ctx), gf_gld_mt_probe_ctx_t);
+
+ if (!ctx) {
+ return ret;
+ }
+
+ ctx->hostname = gf_strdup (hoststr);
+ ctx->req = req;
+
+ event->peerinfo = peerinfo;
+ event->ctx = ctx;
+
+ ret = glusterd_friend_sm_inject_event (event);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject event %d, "
+ "ret = %d", event->event, ret);
+ return ret;
+ }
+
+ 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_add_resp (rpcsvc_request_t *req, char *hostname)
+{
+ gd1_mgmt_friend_rsp rsp = {{0}, };
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+
+ GF_ASSERT (hostname);
+
+ rsp.op_ret = 0;
+ this = THIS;
+ GF_ASSERT (this);
+
+ conf = this->private;
+
+ uuid_copy (rsp.uuid, conf->uuid);
+ rsp.hostname = gf_strdup (hostname);
+
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gd_xdr_serialize_mgmt_friend_rsp);
+
+ gf_log ("glusterd", GF_LOG_NORMAL,
+ "Responded to %s, ret: %d", hostname, ret);
+ return ret;
+}
+
+int
+glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,
+ int32_t op_errno, char *hostname)
+{
+ gf1_cli_probe_rsp rsp = {0, };
+ int32_t ret = -1;
+
+ GF_ASSERT (req);
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.hostname = hostname;
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_probe_rsp);
+
+ gf_log ("glusterd", GF_LOG_NORMAL, "Responded to CLI, ret: %d",ret);
+
+ return ret;
+}
+
+int32_t
+glusterd_op_txn_begin ()
+{
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_op_sm_event_t *event = NULL;
+ int32_t locked = 0;
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ ret = glusterd_lock (priv->uuid);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Unable to acquire local lock, ret: %d", ret);
+ goto out;
+ }
+
+ locked = 1;
+ gf_log ("glusterd", GF_LOG_NORMAL, "Acquired local lock");
+
+ ret = glusterd_op_sm_new_event (GD_OP_EVENT_START_LOCK, &event);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Unable to get event, ret: %d", ret);
+ goto out;
+ }
+
+ ret = glusterd_op_sm_inject_event (event);
+
+ gf_log ("glusterd", GF_LOG_NORMAL, "Returning %d", ret);
+
+out:
+ if (locked && ret)
+ glusterd_unlock (priv->uuid);
+ return ret;
+}
+
+int32_t
+glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict)
+{
+ int32_t ret = -1;
+ 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);
+
+ glusterd_op_set_op (GD_OP_CREATE_VOLUME);
+
+ glusterd_op_set_ctx (GD_OP_CREATE_VOLUME, dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+
+ ret = dict_get_int32 (dict, "type", &type);
+ if (ret)
+ goto out;
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret)
+ goto out;
+
+ ret = dict_get_str (dict, "bricks", &bricks);
+ 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);
+ 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);
+ system (cmd_str);
+ break;
+ }
+ case GF_CLUSTER_TYPE_NONE:
+ {
+ snprintf (cmd_str, 8192,
+ "glusterfs-volgen -n %s -c /etc/glusterd %s",
+ volname, bricks);
+ system (cmd_str);
+ break;
+ }
+ }
+
+ ret = glusterd_op_txn_begin ();
+
+out:
+ return ret;
+}
+
+
+int
+glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data)
+{
+ xlator_t *this = NULL;
+ char *handshake = NULL;
+ glusterd_conf_t *conf = NULL;
+ int ret = 0;
+
+ this = mydata;
+ conf = this->private;
+
+
+ switch (event) {
+ case RPC_CLNT_CONNECT:
+ {
+ // connect happened, send 'get_supported_versions' mop
+ ret = dict_get_str (this->options, "disable-handshake",
+ &handshake);
+
+ gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
+
+ if ((ret < 0) || (strcasecmp (handshake, "on"))) {
+ //ret = client_handshake (this, conf->rpc);
+
+ } else {
+ //conf->rpc->connected = 1;
+ ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
+ }
+ break;
+ }
+
+ case RPC_CLNT_DISCONNECT:
+
+ //Inject friend disconnected here
+
+ gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
+
+ default_notify (this, GF_EVENT_CHILD_DOWN, NULL);
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_TRACE,
+ "got some other RPC event %d", event);
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}