From a6b90707bf68fe62bf115cfb143d9df69627cb64 Mon Sep 17 00:00:00 2001 From: Vijay Bellur Date: Mon, 19 Jul 2010 05:54:25 +0000 Subject: Changes for volume commands Signed-off-by: Vijay Bellur Signed-off-by: Anand V. Avati BUG: 1161 (gluster volume start command segfaults glusterd) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1161 --- cli/src/cli-cmd-volume.c | 4 +- cli/src/cli.c | 7 +- cli/src/cli3_1-cops.c | 136 ++++++- contrib/uuid/uuid.h | 1 + contrib/uuid/uuidP.h | 2 +- rpc/rpc-lib/src/protocol-common.h | 1 + rpc/xdr/src/cli1-xdr.c | 37 +- rpc/xdr/src/cli1-xdr.h | 44 ++- rpc/xdr/src/cli1.c | 29 ++ rpc/xdr/src/cli1.h | 12 + rpc/xdr/src/cli1.x | 17 +- rpc/xdr/src/glusterd1-xdr.c | 40 +- rpc/xdr/src/glusterd1-xdr.h | 18 + rpc/xdr/src/glusterd1.c | 15 + rpc/xdr/src/glusterd1.h | 5 + rpc/xdr/src/glusterd1.x | 14 +- xlators/mgmt/glusterd/src/glusterd-ha.c | 57 ++- xlators/mgmt/glusterd/src/glusterd-handler.c | 481 ++++++++++++++++++------- xlators/mgmt/glusterd/src/glusterd-mem-types.h | 5 + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 445 ++++++++++++++++++++--- xlators/mgmt/glusterd/src/glusterd-op-sm.h | 6 +- xlators/mgmt/glusterd/src/glusterd-sm.c | 74 ++-- xlators/mgmt/glusterd/src/glusterd-sm.h | 7 + xlators/mgmt/glusterd/src/glusterd-utils.c | 290 ++++++++++++++- xlators/mgmt/glusterd/src/glusterd-utils.h | 26 ++ xlators/mgmt/glusterd/src/glusterd.c | 9 +- xlators/mgmt/glusterd/src/glusterd.h | 35 +- xlators/mgmt/glusterd/src/glusterd3_1-mops.c | 87 ++++- 28 files changed, 1655 insertions(+), 249 deletions(-) diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index dd15a78379c..af06d89614a 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -51,12 +51,12 @@ cli_cmd_volume_info_cbk (struct cli_state *state, struct cli_cmd_word *word, goto out; if (proc->fn) { - ret = proc->fn (frame, THIS, "localhost"); + ret = proc->fn (frame, THIS, NULL); } out: if (ret) - cli_out ("Probe failed!"); + cli_out ("Getting Volume information failed!"); return ret; } diff --git a/cli/src/cli.c b/cli/src/cli.c index 96261de63ca..5bf32ec894c 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -460,13 +460,14 @@ main (int argc, char *argv[]) if (ret) goto out; + global_rpc = cli_rpc_init (&state); + if (!global_rpc) + goto out; + ret = cli_input_init (&state); if (ret) goto out; - global_rpc = cli_rpc_init (&state); - if (!global_rpc) - goto out; ret = event_dispatch (ctx->event_pool); diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c index 95d0a703902..f0d20ec6bb5 100644 --- a/cli/src/cli3_1-cops.c +++ b/cli/src/cli3_1-cops.c @@ -127,6 +127,7 @@ gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov, if (!rsp.friends.friends_len) { cli_out ("No peers present"); + ret = 0; goto out; } @@ -193,7 +194,113 @@ out: return ret; } +int +gf_cli3_1_get_volume_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + gf1_cli_get_vol_rsp rsp = {0,}; + int ret = 0; + dict_t *dict = NULL; + char *volname = NULL; + int32_t i = 1; + char key[256] = {0,}; + int32_t status = 0; + int32_t type = 0; + int32_t brick_count = 0; + + if (-1 == req->rpc_status) { + goto out; + } + + ret = gf_xdr_to_cli_get_vol_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + //rsp.op_ret = -1; + //rsp.op_errno = EINVAL; + goto out; + } + + + gf_log ("cli", GF_LOG_NORMAL, "Received resp to get vol: %d", + rsp.op_ret); + + if (!rsp.op_ret) { + + if (!rsp.volumes.volumes_len) { + cli_out ("No volumes present"); + ret = 0; + goto out; + } + + dict = dict_new (); + + if (!dict) { + ret = -1; + goto out; + } + + ret = dict_unserialize (rsp.volumes.volumes_val, + rsp.volumes.volumes_len, + &dict); + + if (ret) { + gf_log ("", GF_LOG_ERROR, + "Unable to allocate memory"); + goto out; + } + + ret = dict_get_int32 (dict, "count", &count); + + if (ret) { + goto out; + } + + cli_out ("Number of Volumes: %d", count); + + while ( i <= count) { + snprintf (key, 256, "volume%d.name", i); + ret = dict_get_str (dict, key, &volname); + if (ret) + goto out; + + snprintf (key, 256, "volume%d.type", i); + ret = dict_get_int32 (dict, key, &type); + if (ret) + goto out; + + snprintf (key, 256, "volume%d.status", i); + ret = dict_get_int32 (dict, key, &status); + if (ret) + goto out; + + snprintf (key, 256, "volume%d.brick_count", i); + ret = dict_get_int32 (dict, key, &brick_count); + if (ret) + goto out; + + cli_out ("Volume Name:%s, type:%d, status:%d," + "brick_count: %d\n", + volname, type, status, brick_count); + i++; + } + } else { + ret = -1; + goto out; + } + + + ret = 0; + +out: + cli_cmd_broadcast_response (); + if (ret) + cli_out ("Command Execution Failed\n"); + + if (dict) + dict_destroy (dict); + return ret; +} int gf_cli3_1_create_volume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) @@ -561,6 +668,32 @@ out: return ret; } +int32_t +gf_cli3_1_get_volume (call_frame_t *frame, xlator_t *this, + void *data) +{ + gf1_cli_get_vol_req req = {0,}; + int ret = 0; + + if (!frame || !this) { + ret = -1; + goto out; + } + + req.flags = GF_CLI_GET_VOLUME_ALL; + + ret = cli_submit_request (&req, frame, cli_rpc_prog, + GD_MGMT_CLI_GET_VOLUME, NULL, + gf_xdr_from_cli_get_vol_req, + this, gf_cli3_1_get_volume_cbk); + + if (!ret) { + ret = cli_cmd_await_response (); + } +out: + gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} int32_t gf_cli3_1_create_volume (call_frame_t *frame, xlator_t *this, @@ -974,13 +1107,14 @@ struct rpc_clnt_procedure gluster3_1_cli_actors[GF1_CLI_MAXVALUE] = { [GF1_CLI_NULL] = {"NULL", NULL }, [GF1_CLI_PROBE] = { "PROBE_QUERY", gf_cli3_1_probe}, [GF1_CLI_DEPROBE] = { "DEPROBE_QUERY", gf_cli3_1_deprobe}, - [GF1_CLI_LIST_FRIENDS] = { "DEPROBE_QUERY", gf_cli3_1_list_friends}, + [GF1_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", gf_cli3_1_list_friends}, [GF1_CLI_CREATE_VOLUME] = {"CREATE_VOLUME", gf_cli3_1_create_volume}, [GF1_CLI_DELETE_VOLUME] = {"DELETE_VOLUME", gf_cli3_1_delete_volume}, [GF1_CLI_START_VOLUME] = {"START_VOLUME", gf_cli3_1_start_volume}, [GF1_CLI_STOP_VOLUME] = {"STOP_VOLUME", gf_cli3_1_stop_volume}, [GF1_CLI_RENAME_VOLUME] = {"RENAME_VOLUME", gf_cli3_1_rename_volume}, [GF1_CLI_DEFRAG_VOLUME] = {"DEFRAG_VOLUME", gf_cli3_1_defrag_volume}, + [GF1_CLI_GET_VOLUME] = {"GET_VOLUME", gf_cli3_1_get_volume}, [GF1_CLI_SET_VOLUME] = {"SET_VOLUME", gf_cli3_1_set_volume}, [GF1_CLI_ADD_BRICK] = {"ADD_BRICK", gf_cli3_1_add_brick}, [GF1_CLI_REMOVE_BRICK] = {"REMOVE_BRICK", gf_cli3_1_remove_brick}, diff --git a/contrib/uuid/uuid.h b/contrib/uuid/uuid.h index ca846da0f09..ab006652fc0 100644 --- a/contrib/uuid/uuid.h +++ b/contrib/uuid/uuid.h @@ -35,6 +35,7 @@ #ifndef _UUID_UUID_H #define _UUID_UUID_H +#include "config.h" #include #ifndef _WIN32 #include diff --git a/contrib/uuid/uuidP.h b/contrib/uuid/uuidP.h index 9d6555877b2..9a2de6132fe 100644 --- a/contrib/uuid/uuidP.h +++ b/contrib/uuid/uuidP.h @@ -32,6 +32,7 @@ * %End-Header% */ +#include "uuid.h" #ifdef HAVE_INTTYPES_H #include #else @@ -39,7 +40,6 @@ #endif #include -#include "uuid.h" /* * Offset between 15-Oct-1582 and 1-Jan-70 diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index c4fc12a7042..5b6a2c349f7 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -84,6 +84,7 @@ enum gf_mgmt_procnum { GD_MGMT_STAGE_OP, GD_MGMT_COMMIT_OP, GD_MGMT_FRIEND_REMOVE, + GD_MGMT_FRIEND_UPDATE, GD_MGMT_CLI_PROBE, GD_MGMT_CLI_DEPROBE, GD_MGMT_CLI_LIST_FRIENDS, diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index 5cce70fa67f..832f762ecdb 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -3,7 +3,7 @@ * It was generated using rpcgen. */ -#include "cli1-xdr.h" +#include "cli1.h" bool_t xdr_gf1_cluster_type (XDR *xdrs, gf1_cluster_type *objp) @@ -24,7 +24,16 @@ xdr_gf1_cli_replace_op (XDR *xdrs, gf1_cli_replace_op *objp) } bool_t -xdr_gf1_cli_enum_friends_list (XDR *xdrs, gf1_cli_enum_friends_list *objp) +xdr_gf1_cli_friends_list (XDR *xdrs, gf1_cli_friends_list *objp) +{ + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gf1_cli_get_volume (XDR *xdrs, gf1_cli_get_volume *objp) { if (!xdr_enum (xdrs, (enum_t *) objp)) @@ -100,6 +109,30 @@ xdr_gf1_cli_peer_list_rsp (XDR *xdrs, gf1_cli_peer_list_rsp *objp) return TRUE; } +bool_t +xdr_gf1_cli_get_vol_req (XDR *xdrs, gf1_cli_get_vol_req *objp) +{ + + if (!xdr_int (xdrs, &objp->flags)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gf1_cli_get_vol_rsp (XDR *xdrs, gf1_cli_get_vol_rsp *objp) +{ + + if (!xdr_int (xdrs, &objp->op_ret)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_errno)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->volumes.volumes_val, (u_int *) &objp->volumes.volumes_len, ~0)) + return FALSE; + return TRUE; +} + bool_t xdr_gf1_cli_create_vol_req (XDR *xdrs, gf1_cli_create_vol_req *objp) { diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 81948b34aac..56dbef091f3 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -3,8 +3,8 @@ * It was generated using rpcgen. */ -#ifndef _GLUSTER1_H_RPCGEN -#define _GLUSTER1_H_RPCGEN +#ifndef _CLI1_H_RPCGEN +#define _CLI1_H_RPCGEN #include @@ -31,10 +31,15 @@ enum gf1_cli_replace_op { }; typedef enum gf1_cli_replace_op gf1_cli_replace_op; -enum gf1_cli_enum_friends_list { +enum gf1_cli_friends_list { GF_CLI_LIST_ALL = 1, }; -typedef enum gf1_cli_enum_friends_list gf1_cli_enum_friends_list; +typedef enum gf1_cli_friends_list gf1_cli_friends_list; + +enum gf1_cli_get_volume { + GF_CLI_GET_VOLUME_ALL = 1, +}; +typedef enum gf1_cli_get_volume gf1_cli_get_volume; struct gf1_cli_probe_req { char *hostname; @@ -79,6 +84,25 @@ struct gf1_cli_peer_list_rsp { }; typedef struct gf1_cli_peer_list_rsp gf1_cli_peer_list_rsp; +struct gf1_cli_get_vol_req { + int flags; + struct { + u_int dict_len; + char *dict_val; + } dict; +}; +typedef struct gf1_cli_get_vol_req gf1_cli_get_vol_req; + +struct gf1_cli_get_vol_rsp { + int op_ret; + int op_errno; + struct { + u_int volumes_len; + char *volumes_val; + } volumes; +}; +typedef struct gf1_cli_get_vol_rsp gf1_cli_get_vol_rsp; + struct gf1_cli_create_vol_req { char *volname; gf1_cluster_type type; @@ -236,13 +260,16 @@ typedef struct gf1_cli_set_vol_rsp gf1_cli_set_vol_rsp; #if defined(__STDC__) || defined(__cplusplus) extern bool_t xdr_gf1_cluster_type (XDR *, gf1_cluster_type*); extern bool_t xdr_gf1_cli_replace_op (XDR *, gf1_cli_replace_op*); -extern bool_t xdr_gf1_cli_enum_friends_list (XDR *, gf1_cli_enum_friends_list*); +extern bool_t xdr_gf1_cli_friends_list (XDR *, gf1_cli_friends_list*); +extern bool_t xdr_gf1_cli_get_volume (XDR *, gf1_cli_get_volume*); extern bool_t xdr_gf1_cli_probe_req (XDR *, gf1_cli_probe_req*); extern bool_t xdr_gf1_cli_probe_rsp (XDR *, gf1_cli_probe_rsp*); extern bool_t xdr_gf1_cli_deprobe_req (XDR *, gf1_cli_deprobe_req*); extern bool_t xdr_gf1_cli_deprobe_rsp (XDR *, gf1_cli_deprobe_rsp*); extern bool_t xdr_gf1_cli_peer_list_req (XDR *, gf1_cli_peer_list_req*); extern bool_t xdr_gf1_cli_peer_list_rsp (XDR *, gf1_cli_peer_list_rsp*); +extern bool_t xdr_gf1_cli_get_vol_req (XDR *, gf1_cli_get_vol_req*); +extern bool_t xdr_gf1_cli_get_vol_rsp (XDR *, gf1_cli_get_vol_rsp*); extern bool_t xdr_gf1_cli_create_vol_req (XDR *, gf1_cli_create_vol_req*); extern bool_t xdr_gf1_cli_create_vol_rsp (XDR *, gf1_cli_create_vol_rsp*); extern bool_t xdr_gf1_cli_delete_vol_req (XDR *, gf1_cli_delete_vol_req*); @@ -267,13 +294,16 @@ extern bool_t xdr_gf1_cli_set_vol_rsp (XDR *, gf1_cli_set_vol_rsp*); #else /* K&R C */ extern bool_t xdr_gf1_cluster_type (); extern bool_t xdr_gf1_cli_replace_op (); -extern bool_t xdr_gf1_cli_enum_friends_list (); +extern bool_t xdr_gf1_cli_friends_list (); +extern bool_t xdr_gf1_cli_get_volume (); extern bool_t xdr_gf1_cli_probe_req (); extern bool_t xdr_gf1_cli_probe_rsp (); extern bool_t xdr_gf1_cli_deprobe_req (); extern bool_t xdr_gf1_cli_deprobe_rsp (); extern bool_t xdr_gf1_cli_peer_list_req (); extern bool_t xdr_gf1_cli_peer_list_rsp (); +extern bool_t xdr_gf1_cli_get_vol_req (); +extern bool_t xdr_gf1_cli_get_vol_rsp (); extern bool_t xdr_gf1_cli_create_vol_req (); extern bool_t xdr_gf1_cli_create_vol_rsp (); extern bool_t xdr_gf1_cli_delete_vol_req (); @@ -301,4 +331,4 @@ extern bool_t xdr_gf1_cli_set_vol_rsp (); } #endif -#endif /* !_GLUSTER1_H_RPCGEN */ +#endif /* !_CLI1_H_RPCGEN */ diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c index 008353b9fcd..65252e3c306 100644 --- a/rpc/xdr/src/cli1.c +++ b/rpc/xdr/src/cli1.c @@ -107,6 +107,35 @@ gf_xdr_from_cli_peer_list_req (struct iovec outmsg, void *req) return xdr_serialize_generic (outmsg, (void *)req, (xdrproc_t)xdr_gf1_cli_peer_list_req); } + +ssize_t +gf_xdr_serialize_cli_get_vol_rsp (struct iovec outmsg, void *rsp) +{ + return xdr_serialize_generic (outmsg, (void *)rsp, + (xdrproc_t)xdr_gf1_cli_get_vol_rsp); + +} + +ssize_t +gf_xdr_to_cli_get_vol_req (struct iovec inmsg, void *args) +{ + return xdr_to_generic (inmsg, (void *)args, + (xdrproc_t)xdr_gf1_cli_get_vol_req); +} + +ssize_t +gf_xdr_to_cli_get_vol_rsp (struct iovec inmsg, void *args) +{ + return xdr_to_generic (inmsg, (void *)args, + (xdrproc_t)xdr_gf1_cli_get_vol_rsp); +} + +ssize_t +gf_xdr_from_cli_get_vol_req (struct iovec outmsg, void *req) +{ + return xdr_serialize_generic (outmsg, (void *)req, + (xdrproc_t)xdr_gf1_cli_get_vol_req); +} ssize_t gf_xdr_serialize_cli_create_vol_rsp (struct iovec outmsg, void *rsp) { diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h index ab67084de94..73f9f8d7b41 100644 --- a/rpc/xdr/src/cli1.h +++ b/rpc/xdr/src/cli1.h @@ -181,4 +181,16 @@ gf_xdr_to_cli_set_vol_rsp (struct iovec inmsg, void *args); ssize_t gf_xdr_from_cli_set_vol_req (struct iovec outmsg, void *req); +ssize_t +gf_xdr_serialize_cli_get_vol_rsp (struct iovec outmsg, void *rsp); + +ssize_t +gf_xdr_to_cli_get_vol_req (struct iovec inmsg, void *args); + +ssize_t +gf_xdr_to_cli_get_vol_rsp (struct iovec inmsg, void *args); + +ssize_t +gf_xdr_from_cli_get_vol_req (struct iovec outmsg, void *req); + #endif /* !_CLI1_H */ diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x index a8af1b7d658..41f43a4855b 100644 --- a/rpc/xdr/src/cli1.x +++ b/rpc/xdr/src/cli1.x @@ -13,10 +13,14 @@ GF_REPLACE_OP_STATUS } ; -enum gf1_cli_enum_friends_list { +enum gf1_cli_friends_list { GF_CLI_LIST_ALL = 1 } ; +enum gf1_cli_get_volume { + GF_CLI_GET_VOLUME_ALL = 1 +} ; + struct gf1_cli_probe_req { string hostname<>; } ; @@ -48,6 +52,17 @@ struct gf1_cli_peer_list_rsp { opaque friends<>; } ; +struct gf1_cli_get_vol_req { + int flags; + opaque dict<>; +} ; + +struct gf1_cli_get_vol_rsp { + int op_ret; + int op_errno; + opaque volumes<>; +} ; + struct gf1_cli_create_vol_req { string volname<>; gf1_cluster_type type; diff --git a/rpc/xdr/src/glusterd1-xdr.c b/rpc/xdr/src/glusterd1-xdr.c index 32e6687c866..3ad32d94889 100644 --- a/rpc/xdr/src/glusterd1-xdr.c +++ b/rpc/xdr/src/glusterd1-xdr.c @@ -3,11 +3,21 @@ * It was generated using rpcgen. */ -#include "glusterd1-xdr.h" +#include "glusterd1.h" + +bool_t +xdr_glusterd_volume_status (XDR *xdrs, glusterd_volume_status *objp) +{ + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} bool_t xdr_gd1_mgmt_probe_req (XDR *xdrs, gd1_mgmt_probe_req *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -19,6 +29,7 @@ xdr_gd1_mgmt_probe_req (XDR *xdrs, gd1_mgmt_probe_req *objp) bool_t xdr_gd1_mgmt_probe_rsp (XDR *xdrs, gd1_mgmt_probe_rsp *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -30,6 +41,7 @@ xdr_gd1_mgmt_probe_rsp (XDR *xdrs, gd1_mgmt_probe_rsp *objp) bool_t xdr_gd1_mgmt_friend_req (XDR *xdrs, gd1_mgmt_friend_req *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -41,6 +53,7 @@ xdr_gd1_mgmt_friend_req (XDR *xdrs, gd1_mgmt_friend_req *objp) bool_t xdr_gd1_mgmt_friend_rsp (XDR *xdrs, gd1_mgmt_friend_rsp *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -56,6 +69,7 @@ xdr_gd1_mgmt_friend_rsp (XDR *xdrs, gd1_mgmt_friend_rsp *objp) bool_t xdr_gd1_mgmt_unfriend_req (XDR *xdrs, gd1_mgmt_unfriend_req *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -67,6 +81,7 @@ xdr_gd1_mgmt_unfriend_req (XDR *xdrs, gd1_mgmt_unfriend_req *objp) bool_t xdr_gd1_mgmt_unfriend_rsp (XDR *xdrs, gd1_mgmt_unfriend_rsp *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -82,6 +97,7 @@ xdr_gd1_mgmt_unfriend_rsp (XDR *xdrs, gd1_mgmt_unfriend_rsp *objp) bool_t xdr_gd1_mgmt_cluster_lock_req (XDR *xdrs, gd1_mgmt_cluster_lock_req *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -91,6 +107,7 @@ xdr_gd1_mgmt_cluster_lock_req (XDR *xdrs, gd1_mgmt_cluster_lock_req *objp) bool_t xdr_gd1_mgmt_cluster_lock_rsp (XDR *xdrs, gd1_mgmt_cluster_lock_rsp *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -104,6 +121,7 @@ xdr_gd1_mgmt_cluster_lock_rsp (XDR *xdrs, gd1_mgmt_cluster_lock_rsp *objp) bool_t xdr_gd1_mgmt_cluster_unlock_req (XDR *xdrs, gd1_mgmt_cluster_unlock_req *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -113,6 +131,7 @@ xdr_gd1_mgmt_cluster_unlock_req (XDR *xdrs, gd1_mgmt_cluster_unlock_req *objp) bool_t xdr_gd1_mgmt_cluster_unlock_rsp (XDR *xdrs, gd1_mgmt_cluster_unlock_rsp *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -126,6 +145,7 @@ xdr_gd1_mgmt_cluster_unlock_rsp (XDR *xdrs, gd1_mgmt_cluster_unlock_rsp *objp) bool_t xdr_gd1_mgmt_stage_op_req (XDR *xdrs, gd1_mgmt_stage_op_req *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -139,6 +159,7 @@ xdr_gd1_mgmt_stage_op_req (XDR *xdrs, gd1_mgmt_stage_op_req *objp) bool_t xdr_gd1_mgmt_stage_op_rsp (XDR *xdrs, gd1_mgmt_stage_op_rsp *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -154,6 +175,7 @@ xdr_gd1_mgmt_stage_op_rsp (XDR *xdrs, gd1_mgmt_stage_op_rsp *objp) bool_t xdr_gd1_mgmt_commit_op_req (XDR *xdrs, gd1_mgmt_commit_op_req *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -167,6 +189,7 @@ xdr_gd1_mgmt_commit_op_req (XDR *xdrs, gd1_mgmt_commit_op_req *objp) bool_t xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp) { + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; @@ -178,3 +201,18 @@ xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp) return FALSE; return TRUE; } + +bool_t +xdr_gd1_mgmt_friend_update (XDR *xdrs, gd1_mgmt_friend_update *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->friend_uuid, 16, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_string (xdrs, &objp->hostname, ~0)) + return FALSE; + return TRUE; +} diff --git a/rpc/xdr/src/glusterd1-xdr.h b/rpc/xdr/src/glusterd1-xdr.h index ee5fb9c7db3..2fab3fd3b81 100644 --- a/rpc/xdr/src/glusterd1-xdr.h +++ b/rpc/xdr/src/glusterd1-xdr.h @@ -14,6 +14,13 @@ extern "C" { #endif +enum glusterd_volume_status { + GLUSTERD_STATUS_NONE = 0, + GLUSTERD_STATUS_STARTED = 0 + 1, + GLUSTERD_STATUS_STOPPED = 0 + 2, +}; +typedef enum glusterd_volume_status glusterd_volume_status; + struct gd1_mgmt_probe_req { u_char uuid[16]; char *hostname; @@ -114,9 +121,17 @@ struct gd1_mgmt_commit_op_rsp { }; typedef struct gd1_mgmt_commit_op_rsp gd1_mgmt_commit_op_rsp; +struct gd1_mgmt_friend_update { + u_char uuid[16]; + u_char friend_uuid[16]; + char *hostname; +}; +typedef struct gd1_mgmt_friend_update gd1_mgmt_friend_update; + /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus) +extern bool_t xdr_glusterd_volume_status (XDR *, glusterd_volume_status*); extern bool_t xdr_gd1_mgmt_probe_req (XDR *, gd1_mgmt_probe_req*); extern bool_t xdr_gd1_mgmt_probe_rsp (XDR *, gd1_mgmt_probe_rsp*); extern bool_t xdr_gd1_mgmt_friend_req (XDR *, gd1_mgmt_friend_req*); @@ -131,8 +146,10 @@ extern bool_t xdr_gd1_mgmt_stage_op_req (XDR *, gd1_mgmt_stage_op_req*); extern bool_t xdr_gd1_mgmt_stage_op_rsp (XDR *, gd1_mgmt_stage_op_rsp*); extern bool_t xdr_gd1_mgmt_commit_op_req (XDR *, gd1_mgmt_commit_op_req*); extern bool_t xdr_gd1_mgmt_commit_op_rsp (XDR *, gd1_mgmt_commit_op_rsp*); +extern bool_t xdr_gd1_mgmt_friend_update (XDR *, gd1_mgmt_friend_update*); #else /* K&R C */ +extern bool_t xdr_glusterd_volume_status (); extern bool_t xdr_gd1_mgmt_probe_req (); extern bool_t xdr_gd1_mgmt_probe_rsp (); extern bool_t xdr_gd1_mgmt_friend_req (); @@ -147,6 +164,7 @@ extern bool_t xdr_gd1_mgmt_stage_op_req (); extern bool_t xdr_gd1_mgmt_stage_op_rsp (); extern bool_t xdr_gd1_mgmt_commit_op_req (); extern bool_t xdr_gd1_mgmt_commit_op_rsp (); +extern bool_t xdr_gd1_mgmt_friend_update (); #endif /* K&R C */ diff --git a/rpc/xdr/src/glusterd1.c b/rpc/xdr/src/glusterd1.c index 76ceea3fda9..6b079f4f450 100644 --- a/rpc/xdr/src/glusterd1.c +++ b/rpc/xdr/src/glusterd1.c @@ -85,6 +85,13 @@ gd_xdr_to_mgmt_friend_req (struct iovec inmsg, void *args) (xdrproc_t)xdr_gd1_mgmt_friend_req); } +ssize_t +gd_xdr_to_mgmt_friend_update (struct iovec inmsg, void *args) +{ + return xdr_to_generic (inmsg, (void *)args, + (xdrproc_t)xdr_gd1_mgmt_friend_update); +} + ssize_t gd_xdr_to_mgmt_cluster_lock_req (struct iovec inmsg, void *args) { @@ -164,6 +171,14 @@ gd_xdr_from_mgmt_probe_req (struct iovec outmsg, void *req) } +ssize_t +gd_xdr_from_mgmt_friend_update (struct iovec outmsg, void *req) +{ + return xdr_serialize_generic (outmsg, (void *)req, + (xdrproc_t)xdr_gd1_mgmt_friend_update); + +} + ssize_t gd_xdr_from_mgmt_friend_req (struct iovec outmsg, void *req) { diff --git a/rpc/xdr/src/glusterd1.h b/rpc/xdr/src/glusterd1.h index 44b1c546502..b4c4e3d71d6 100644 --- a/rpc/xdr/src/glusterd1.h +++ b/rpc/xdr/src/glusterd1.h @@ -98,4 +98,9 @@ gd_xdr_serialize_mgmt_commit_op_rsp (struct iovec outmsg, void *rsp); ssize_t gd_xdr_from_mgmt_commit_op_req (struct iovec outmsg, void *req); +ssize_t +gd_xdr_to_mgmt_friend_update (struct iovec outmsg, void *req); + +ssize_t +gd_xdr_from_mgmt_friend_update (struct iovec outmsg, void *req); #endif /* !_MSG_GD_XDR_H */ diff --git a/rpc/xdr/src/glusterd1.x b/rpc/xdr/src/glusterd1.x index 935fde4ef1b..f374ea4bff8 100644 --- a/rpc/xdr/src/glusterd1.x +++ b/rpc/xdr/src/glusterd1.x @@ -1,3 +1,8 @@ + enum glusterd_volume_status { + GLUSTERD_STATUS_NONE = 0, + GLUSTERD_STATUS_STARTED, + GLUSTERD_STATUS_STOPPED +} ; struct gd1_mgmt_probe_req { unsigned char uuid[16]; @@ -81,7 +86,8 @@ struct gd1_mgmt_commit_op_rsp { int op_errno; } ; - - - - +struct gd1_mgmt_friend_update { + unsigned char uuid[16]; + unsigned char friend_uuid[16]; + string hostname<>; +} ; 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 #include +#include 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; @@ -556,6 +593,44 @@ out: return ret; } +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) { @@ -594,6 +669,78 @@ out: return ret; } +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; @@ -774,6 +921,47 @@ out: return ret; } +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) { @@ -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 @@ -190,6 +310,138 @@ out: return ret; } +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) { @@ -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 #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 #include +#include +#include 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; } @@ -377,6 +381,49 @@ out: return ret; } +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) { @@ -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) @@ -682,6 +695,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}, }; -- cgit