diff options
author | Vijay Bellur <vijay@gluster.com> | 2010-07-22 04:17:35 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-07-22 23:10:38 -0700 |
commit | be4dee16c18e262b168c74face54cf17ca13e2f4 (patch) | |
tree | 5301cf748e07815303d5ba16d5b765849a8165a0 | |
parent | 5601c137674b4dabd39b1cf26a36327bfbc707a6 (diff) |
Changes for Dynamic Volume Management
Signed-off-by: Amar Tumballi <amar@gluster.com>
Signed-off-by: Vijay Bellur <vijay@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 1196 ()
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1196
-rw-r--r-- | cli/src/cli-cmd-parser.c | 42 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 13 | ||||
-rw-r--r-- | cli/src/cli3_1-cops.c | 8 | ||||
-rw-r--r-- | extras/Makefile.am | 2 | ||||
-rw-r--r-- | rpc/xdr/src/glusterd1-xdr.c | 19 | ||||
-rw-r--r-- | rpc/xdr/src/glusterd1-xdr.h | 16 | ||||
-rw-r--r-- | rpc/xdr/src/glusterd1.c | 15 | ||||
-rw-r--r-- | rpc/xdr/src/glusterd1.h | 6 | ||||
-rw-r--r-- | rpc/xdr/src/glusterd1.x | 10 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/Makefile.am | 4 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 159 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handshake.c | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 267 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 51 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 8 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd3_1-mops.c | 95 |
16 files changed, 628 insertions, 93 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index cffa22a7e70..6c96d0836c8 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -78,7 +78,10 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options ret = dict_set_int32 (dict, "replica-count", count); if (ret) goto out; - + if (count < 2) { + ret = -1; + goto out; + } brick_index = 5; } else if ((strcasecmp (words[3], "stripe")) == 0) { type = GF_CLUSTER_TYPE_STRIPE; @@ -91,6 +94,10 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options ret = dict_set_int32 (dict, "stripe-count", count); if (ret) goto out; + if (count < 2) { + ret = -1; + goto out; + } brick_index = 5; } else { type = GF_CLUSTER_TYPE_NONE; @@ -214,7 +221,7 @@ out: } int32_t -cli_cmd_volume_add_brick_parse (const char **words, int wordcount, +cli_cmd_volume_add_brick_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; @@ -222,9 +229,10 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount, int ret = -1; gf1_cluster_type type = GF_CLUSTER_TYPE_NONE; int count = 0; - char key[50]; + //char key[50] = {0,}; int brick_count = 0, brick_index = 0; - + char brick_list[8192] = {0,}; + GF_ASSERT (words); GF_ASSERT (options); @@ -257,20 +265,32 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount, brick_index = 3; } - ret = dict_set_int32 (dict, "type", type); - - if (ret) - goto out; - + strcpy (brick_list, " "); while (brick_index < wordcount) { GF_ASSERT (words[brick_index]); + if (!strchr (words[brick_index], ':')) { + gf_log ("cli", GF_LOG_ERROR, + "wrong brick type, use <HOSTNAME>:<export-dir>"); + ret = -1; + goto out; + } + strcat (brick_list, words[brick_index]); + strcat (brick_list, " "); + ++brick_count; + ++brick_index; + /* + char key[50]; snprintf (key, 50, "brick%d", ++brick_count); ret = dict_set_str (dict, key, (char *)words[brick_index++]); if (ret) goto out; + */ } + ret = dict_set_str (dict, "bricks", brick_list); + if (ret) + goto out; ret = dict_set_int32 (dict, "count", brick_count); @@ -291,7 +311,7 @@ out: int32_t -cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, +cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; @@ -301,7 +321,7 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, int count = 0; char key[50]; int brick_count = 0, brick_index = 0; - + GF_ASSERT (words); GF_ASSERT (options); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index d3960d06575..445432ecd03 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -36,6 +36,12 @@ extern struct rpc_clnt *global_rpc; extern rpc_clnt_prog_t *cli_rpc_prog; +void +cli_cmd_volume_start_usage () +{ + cli_out ("Usage: volume start <volname>"); +} + int cli_cmd_volume_info_cbk (struct cli_state *state, struct cli_cmd_word *word, const char **words, int wordcount) @@ -145,6 +151,11 @@ cli_cmd_volume_start_cbk (struct cli_state *state, struct cli_cmd_word *word, goto out; //TODO: Build validation here + if (wordcount < 3) { + cli_cmd_volume_start_usage (); + goto out; + } + volname = (char *)words[2]; GF_ASSERT (volname); @@ -153,7 +164,7 @@ cli_cmd_volume_start_cbk (struct cli_state *state, struct cli_cmd_word *word, } out: - if (ret) + if (ret && volname) cli_out ("Starting Volume %s failed", volname); return ret; diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c index dc9241bc60a..444c0031d91 100644 --- a/cli/src/cli3_1-cops.c +++ b/cli/src/cli3_1-cops.c @@ -747,7 +747,6 @@ gf_cli3_1_create_volume (call_frame_t *frame, xlator_t *this, goto out; ret = dict_get_int32 (dict, "count", &req.count); - if (ret) goto out; @@ -977,16 +976,11 @@ gf_cli3_1_add_brick (call_frame_t *frame, xlator_t *this, if (ret) goto out; - ret = dict_get_int32 (dict, "type", (int32_t *)&req.type); - - if (ret) - goto out; - ret = dict_get_int32 (dict, "count", &req.count); - if (ret) goto out; + ret = dict_allocate_and_serialize (dict, &req.bricks.bricks_val, (size_t *)&req.bricks.bricks_len); diff --git a/extras/Makefile.am b/extras/Makefile.am index 6ea4744c912..26e1e24b675 100644 --- a/extras/Makefile.am +++ b/extras/Makefile.am @@ -7,5 +7,5 @@ dist_bin_SCRIPTS = glusterfs-defrag SUBDIRS = init.d benchmarking volgen -EXTRA_DIST = specgen.scm MacOSX/Portfile glusterfs-mode.el glusterfs.vim migrate-unify-to-distribute.sh backend-xattr-sanitize.sh backend-cleanup.sh defrag.sh scale-n-defrag.sh disk_usage_sync.sh +EXTRA_DIST = specgen.scm MacOSX/Portfile glusterfs-mode.el glusterfs.vim migrate-unify-to-distribute.sh backend-xattr-sanitize.sh backend-cleanup.sh glusterfs-defrag disk_usage_sync.sh diff --git a/rpc/xdr/src/glusterd1-xdr.c b/rpc/xdr/src/glusterd1-xdr.c index cbca582eea9..a6b5b122f11 100644 --- a/rpc/xdr/src/glusterd1-xdr.c +++ b/rpc/xdr/src/glusterd1-xdr.c @@ -221,12 +221,25 @@ 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, + if (!xdr_bytes (xdrs, (char **)&objp->friends.friends_val, (u_int *) &objp->friends.friends_len, ~0)) + return FALSE; + if (!xdr_int (xdrs, &objp->port)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gd1_mgmt_friend_update_rsp (XDR *xdrs, gd1_mgmt_friend_update_rsp *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, 16, sizeof (u_char), (xdrproc_t) xdr_u_char)) return FALSE; - if (!xdr_string (xdrs, &objp->hostname, ~0)) + if (!xdr_int (xdrs, &objp->op)) return FALSE; - if (!xdr_int (xdrs, &objp->port)) + if (!xdr_int (xdrs, &objp->op_ret)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_errno)) return FALSE; return TRUE; } diff --git a/rpc/xdr/src/glusterd1-xdr.h b/rpc/xdr/src/glusterd1-xdr.h index 0fc186ed657..85ca9b4ba1e 100644 --- a/rpc/xdr/src/glusterd1-xdr.h +++ b/rpc/xdr/src/glusterd1-xdr.h @@ -129,12 +129,22 @@ 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; + struct { + u_int friends_len; + char *friends_val; + } friends; int port; }; typedef struct gd1_mgmt_friend_update gd1_mgmt_friend_update; +struct gd1_mgmt_friend_update_rsp { + u_char uuid[16]; + int op; + int op_ret; + int op_errno; +}; +typedef struct gd1_mgmt_friend_update_rsp gd1_mgmt_friend_update_rsp; + /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus) @@ -154,6 +164,7 @@ 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*); +extern bool_t xdr_gd1_mgmt_friend_update_rsp (XDR *, gd1_mgmt_friend_update_rsp*); #else /* K&R C */ extern bool_t xdr_glusterd_volume_status (); @@ -172,6 +183,7 @@ 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 (); +extern bool_t xdr_gd1_mgmt_friend_update_rsp (); #endif /* K&R C */ diff --git a/rpc/xdr/src/glusterd1.c b/rpc/xdr/src/glusterd1.c index 6b079f4f450..f566251548e 100644 --- a/rpc/xdr/src/glusterd1.c +++ b/rpc/xdr/src/glusterd1.c @@ -68,6 +68,14 @@ gd_xdr_serialize_mgmt_commit_op_rsp (struct iovec outmsg, void *rsp) (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp); } + +ssize_t +gd_xdr_serialize_mgmt_friend_update_rsp (struct iovec outmsg, void *rsp) +{ + return xdr_serialize_generic (outmsg, (void *)rsp, + (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp); + +} /* Decode */ @@ -164,6 +172,13 @@ gd_xdr_to_mgmt_commit_op_rsp (struct iovec inmsg, void *args) } ssize_t +gd_xdr_to_mgmt_friend_update_rsp (struct iovec inmsg, void *args) +{ + return xdr_to_generic (inmsg, (void *)args, + (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp); +} + +ssize_t gd_xdr_from_mgmt_probe_req (struct iovec outmsg, void *req) { return xdr_serialize_generic (outmsg, (void *)req, diff --git a/rpc/xdr/src/glusterd1.h b/rpc/xdr/src/glusterd1.h index b4c4e3d71d6..b4822218a92 100644 --- a/rpc/xdr/src/glusterd1.h +++ b/rpc/xdr/src/glusterd1.h @@ -103,4 +103,10 @@ gd_xdr_to_mgmt_friend_update (struct iovec outmsg, void *req); ssize_t gd_xdr_from_mgmt_friend_update (struct iovec outmsg, void *req); + +ssize_t +gd_xdr_serialize_mgmt_friend_update_rsp (struct iovec outmsg, void *rsp); + +ssize_t +gd_xdr_to_mgmt_friend_update_rsp (struct iovec inmsg, void *args); #endif /* !_MSG_GD_XDR_H */ diff --git a/rpc/xdr/src/glusterd1.x b/rpc/xdr/src/glusterd1.x index f374ea4bff8..28e6de01f82 100644 --- a/rpc/xdr/src/glusterd1.x +++ b/rpc/xdr/src/glusterd1.x @@ -88,6 +88,12 @@ struct gd1_mgmt_commit_op_rsp { struct gd1_mgmt_friend_update { unsigned char uuid[16]; - unsigned char friend_uuid[16]; - string hostname<>; + opaque friends<>; } ; + +struct gd1_mgmt_friend_update_rsp { + unsigned char uuid[16]; + int op; + int op_ret; + int op_errno; +} ; diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index 5e835d3b5a7..83f67b92eeb 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -2,9 +2,7 @@ xlator_LTLIBRARIES = glusterd.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mgmt glusterd_la_LDFLAGS = -module -avoidversion glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c glusterd-op-sm.c \ - glusterd-utils.c glusterd3_1-mops.c glusterd-ha.c \ - glusterd-handshake.c - + glusterd-utils.c glusterd3_1-mops.c glusterd-ha.c glusterd-handshake.c glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la\ $(top_builddir)/rpc/xdr/src/libgfxdr.la\ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 308a761fdcd..d3e70321fda 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -637,19 +637,18 @@ glusterd_handle_defrag_volume (rpcsvc_request_t *req) /* Create a directory, mount glusterfs over it, start glusterfs-defrag */ snprintf (cmd_str, 4096, "mkdir -p %s/mount/%s", priv->workdir, cli_req.volname); - system (cmd_str); + ret = system (cmd_str); snprintf (cmd_str, 4096, "glusterfs -f %s/vols/%s/%s-tcp.vol " - "--xlator-option distribute.unhashed-sticky-bit=yes " - "--xlator-option distribute.lookup-unhashed=on %s/mount/%s", + "--xlator-option dht0.unhashed-sticky-bit=yes " + "--xlator-option dht0.lookup-unhashed=on %s/mount/%s", priv->workdir, cli_req.volname, cli_req.volname, priv->workdir, cli_req.volname); - system (cmd_str); + ret = system (cmd_str); - snprintf (cmd_str, 4096, - "$(glusterfs-defrag %s/mount/%s; umount %s/mount/%s) &", - priv->workdir, cli_req.volname, priv->workdir, cli_req.volname); - system (cmd_str); + snprintf (cmd_str, 4096, "glusterfs-defrag %s/mount/%s", + priv->workdir, cli_req.volname); + ret = system (cmd_str); ret = 0; out: @@ -804,6 +803,45 @@ glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) out: return ret; } + +int +glusterd_handle_add_brick (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_add_brick_req cli_req = {0,}; + dict_t *dict = NULL; + + GF_ASSERT (req); + + if (!gf_xdr_to_cli_add_brick_req (req->msg[0], &cli_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_NORMAL, "Received add brick 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_add_brick (req, dict); + +out: + return ret; +} + int glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status) { @@ -994,6 +1032,14 @@ glusterd_handle_friend_update (rpcsvc_request_t *req) glusterd_conf_t *priv = NULL; xlator_t *this = NULL; glusterd_peerinfo_t *tmp = NULL; + gd1_mgmt_friend_update_rsp rsp = {{0},}; + dict_t *dict = NULL; + char key[100] = {0,}; + char *uuid_buf = NULL; + char *hostname = NULL; + int i = 1; + int count = 0; + uuid_t uuid = {0,}; GF_ASSERT (req); @@ -1012,16 +1058,63 @@ glusterd_handle_friend_update (rpcsvc_request_t *req) 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 (friend_req.friends.friends_len) { + /* Unserialize the dictionary */ + dict = dict_new (); - if (!ret) + ret = dict_unserialize (friend_req.friends.friends_val, + friend_req.friends.friends_len, + &dict); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, + "failed to " + "unserialize req-buffer to dictionary"); + goto out; + } + } + + ret = dict_get_int32 (dict, "count", &count); + if (ret) goto out; - ret = glusterd_friend_add (friend_req.hostname, friend_req.port, - GD_FRIEND_STATE_BEFRIENDED, - &friend_req.uuid, NULL, &peerinfo); + while ( i <= count) { + snprintf (key, sizeof (key), "friend%d.uuid", i); + ret = dict_get_str (dict, key, &uuid_buf); + if (ret) + goto out; + uuid_parse (uuid_buf, uuid); + snprintf (key, sizeof (key), "friend%d.hostname", i); + ret = dict_get_str (dict, key, &hostname); + if (ret) + goto out; + + gf_log ("", GF_LOG_NORMAL, "Received uuid: %s, hostname:%s", + uuid_buf, hostname); + + if (!uuid_compare (uuid, priv->uuid)) { + gf_log ("", GF_LOG_NORMAL, "Received my uuid as Friend"); + i++; + continue; + } + + ret = glusterd_friend_find (uuid, hostname, &tmp); + + if (!ret) { + i++; + continue; + } + + ret = glusterd_friend_add (hostname, friend_req.port, + GD_FRIEND_STATE_BEFRIENDED, + &uuid, NULL, &peerinfo); + + i++; + } out: + uuid_copy (rsp.uuid, priv->uuid); + ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL, + gd_xdr_serialize_mgmt_friend_update_rsp); return ret; } @@ -1436,6 +1529,7 @@ glusterd_friend_add (const char *hoststr, int port, goto out; list_add_tail (&peerinfo->hostnames, &name->hostname_list); rpc_cfg.remote_host = gf_strdup (hoststr); + peerinfo->hostname = gf_strdup (hoststr); } INIT_LIST_HEAD (&peerinfo->uuid_list); @@ -1725,11 +1819,8 @@ out: 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 count = 0; + int32_t ret = -1; + data_t *data = NULL; GF_ASSERT (req); GF_ASSERT (dict); @@ -1738,20 +1829,20 @@ glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict) glusterd_op_set_ctx (GD_OP_CREATE_VOLUME, dict); - ret = dict_get_str (dict, "volname", &volname); - if (ret) + data = dict_get (dict, "volname"); + if (!data) goto out; - ret = dict_get_int32 (dict, "type", &type); - if (ret) + data = dict_get (dict, "type"); + if (!data) goto out; - ret = dict_get_int32 (dict, "count", &count); - if (ret) + data = dict_get (dict, "count"); + if (!data) goto out; - ret = dict_get_str (dict, "bricks", &bricks); - if (ret) + data = dict_get (dict, "bricks"); + if (!data) goto out; ret = glusterd_op_txn_begin (); @@ -1838,6 +1929,22 @@ out: return ret; } +int32_t +glusterd_add_brick (rpcsvc_request_t *req, dict_t *dict) +{ + int32_t ret = -1; + + GF_ASSERT (req); + GF_ASSERT (dict); + + glusterd_op_set_op (GD_OP_ADD_BRICK); + + glusterd_op_set_ctx (GD_OP_ADD_BRICK, dict); + + ret = glusterd_op_txn_begin (); + + return ret; +} int32_t glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags) diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index 04692348069..cbaf98372ff 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -43,9 +43,9 @@ build_volfile_path (const char *volname, char *path, size_t path_len) { int32_t ret = -1; - glusterd_conf_t *priv = NULL; + glusterd_conf_t *priv = NULL; - priv = THIS->private; + priv = THIS->private; ret = snprintf (path, path_len, "%s/vols/%s/%s-tcp.vol", priv->workdir, volname, volname); @@ -86,8 +86,6 @@ server_getspec (rpcsvc_request_t *req) gf_getspec_rsp rsp = {0,}; - rsp.spec = ""; - if (xdr_to_glusterfs_req (req, &args, xdr_to_getspec_req)) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 1bd246d498d..7418f63e483 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -48,6 +48,7 @@ static struct list_head gd_op_sm_queue; glusterd_op_info_t opinfo; +static int glusterfs_port = GLUSTERD_DEFAULT_PORT; static void glusterd_set_volume_status (glusterd_volinfo_t *volinfo, @@ -83,6 +84,14 @@ glusterd_op_get_len (glusterd_op_t op) case GD_OP_START_BRICK: break; + case GD_OP_ADD_BRICK: + { + dict_t *dict = glusterd_op_get_ctx (op); + ret = dict_serialized_length (dict); + return ret; + } + break; + default: GF_ASSERT (op); @@ -139,6 +148,8 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req) dict_t *dict = NULL; dict = glusterd_op_get_ctx (op); GF_ASSERT (dict); + ++glusterfs_port; + ret = dict_set_int32 (dict, "port", glusterfs_port); ret = dict_allocate_and_serialize (dict, &stage_req->buf.buf_val, (size_t *)&stage_req->buf.buf_len); @@ -184,6 +195,20 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req) } break; + case GD_OP_ADD_BRICK: + { + dict_t *dict = NULL; + dict = glusterd_op_get_ctx (op); + GF_ASSERT (dict); + ret = dict_allocate_and_serialize (dict, + &stage_req->buf.buf_val, + (size_t *)&stage_req->buf.buf_len); + if (ret) { + goto out; + } + } + break; + default: break; } @@ -196,15 +221,16 @@ out: } static int -glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo, - dict_t *dict, char *bricks) +glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo) { - 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; + char bricks[8192] = {0,}; + glusterd_brickinfo_t *brickinfo = NULL; + int32_t len = 0; this = THIS; GF_ASSERT (this); @@ -212,35 +238,40 @@ glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo, GF_ASSERT (priv); GF_ASSERT (volinfo); - GF_ASSERT (dict); - GF_ASSERT (bricks); GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv); + if (!volinfo->port) { + //volinfo->port = ++glusterfs_port; + } + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + snprintf (bricks + len, 8192 - len, "%s:%s ", + brickinfo->hostname, brickinfo->path); + len = strlen (bricks); + } + + gf_log ("", GF_LOG_DEBUG, "Brick string: %s", bricks); 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); + "glusterfs-volgen -n %s -c %s -r 1 %s -p %d" + "--num-replica %d", + volinfo->volname, path, bricks, + volinfo->port, volinfo->sub_count); 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); + "glusterfs-volgen -n %s -c %s -r 0 %s -p %d" + "--num-stripe %d", + volinfo->volname, path, bricks, + volinfo->port, volinfo->sub_count); ret = system (cmd_str); break; } @@ -248,8 +279,9 @@ glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo, case GF_CLUSTER_TYPE_NONE: { snprintf (cmd_str, 8192, - "glusterfs-volgen -n %s -c %s %s", - volinfo->volname, path, bricks); + "glusterfs-volgen -n %s -c %s %s -p %d", + volinfo->volname, path, bricks, + volinfo->port); ret = system (cmd_str); break; } @@ -259,7 +291,7 @@ glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo, volinfo->type); ret = -1; } -out: +//out: gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); return ret; } @@ -441,6 +473,49 @@ out: return ret; } +static int +glusterd_op_stage_add_brick (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + dict_t *dict = NULL; + char *volname = NULL; + gf_boolean_t exists = _gf_false; + + GF_ASSERT (req); + + dict = dict_new (); + if (!dict) + goto out; + + ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to unserialize dict"); + goto out; + } + + ret = dict_get_str (dict, "volname", &volname); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + goto out; + } + + exists = glusterd_check_volume_exists (volname); + + if (!exists) { + gf_log ("", GF_LOG_ERROR, "Volume with name: %s exists", + volname); + ret = -1; + } else { + 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) @@ -458,6 +533,7 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) char *bricks = NULL; char *brick_list = NULL; char *saveptr = NULL; + int32_t sub_count = 0; GF_ASSERT (req); @@ -507,6 +583,12 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) goto out; } + ret = dict_get_int32 (dict, "port", &volinfo->port); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get port"); + goto out; + } + count = volinfo->brick_count; ret = dict_get_str (dict, "bricks", &bricks); @@ -515,6 +597,21 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) goto out; } + if (GF_CLUSTER_TYPE_REPLICATE == volinfo->type) { + ret = dict_get_int32 (dict, "replica-count", + &sub_count); + if (ret) + goto out; + } else if (GF_CLUSTER_TYPE_STRIPE == volinfo->type) { + ret = dict_get_int32 (dict, "stripe-count", + &sub_count); + if (ret) + goto out; + } + + volinfo->sub_count = sub_count; + + if (bricks) brick_list = gf_strdup (bricks); @@ -537,10 +634,129 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) if (ret) goto out; - ret = glusterd_volume_create_generate_volfiles - (volinfo, dict, bricks); + ret = glusterd_volume_create_generate_volfiles (volinfo); + if (ret) + goto out; + + +out: + return ret; +} + +static int +glusterd_op_add_brick (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + dict_t *dict = NULL; + char *volname = NULL; + glusterd_conf_t *priv = NULL; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; + char *brick = NULL; + int32_t count = 0; + int32_t i = 1; + char *bricks = NULL; + char *brick_list = NULL; + char *saveptr = NULL; + gf_boolean_t glfs_started = _gf_false; + + GF_ASSERT (req); + + this = THIS; + GF_ASSERT (this); + + priv = this->private; + GF_ASSERT (priv); + + dict = dict_new (); + if (!dict) + goto out; + + ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to unserialize dict"); + goto out; + } + + ret = dict_get_str (dict, "volname", &volname); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + goto out; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to allocate memory"); + goto out; + } + + + ret = dict_get_int32 (dict, "count", &count); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get count"); + goto out; + } + + volinfo->brick_count += count; + + ret = dict_get_str (dict, "bricks", &bricks); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get bricks"); + goto out; + } + + if (bricks) + brick_list = gf_strdup (bricks); + + if (count) + brick = strtok_r (brick_list+1, " \n", &saveptr); + + while ( i <= count) { + ret = glusterd_brickinfo_from_brick (brick, &brickinfo); + if (ret) + goto out; + + list_add_tail (&brickinfo->brick_list, &volinfo->bricks); + ret = glusterd_resolve_brick (brickinfo); + + if (!uuid_compare (brickinfo->uuid, priv->uuid)) { + ret = + glusterd_volume_create_generate_volfiles (volinfo); + if (ret) + goto out; + + 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; + } + glfs_started = _gf_true; + } + + brick = strtok_r (NULL, " \n", &saveptr); + i++; + } + + if (!glfs_started) { + ret = glusterd_volume_create_generate_volfiles (volinfo); + if (ret) + goto out; + } + +/* ret = glusterd_ha_update_volume (volinfo); + if (ret) goto out; +*/ out: @@ -1063,6 +1279,10 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req) ret = glusterd_op_stage_delete_volume (req); break; + case GD_OP_ADD_BRICK: + ret = glusterd_op_stage_add_brick (req); + break; + default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", req->op); @@ -1098,6 +1318,9 @@ glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req) ret = glusterd_op_delete_volume (req); break; + case GD_OP_ADD_BRICK: + ret = glusterd_op_add_brick (req); + break; default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", req->op); diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index ad9c907faf6..e0612810757 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -70,6 +70,51 @@ glusterd_unset_lock_owner (uuid_t owner) return 0; } +static int32_t +glusterd_is_local_addr (char *hostname) +{ + int32_t ret = -1; + struct addrinfo *result = NULL; + struct addrinfo *res = NULL; + int32_t found = 0; + + if ((!strcmp (hostname, "localhost")) || + (!strcmp (hostname, "127.0.0.1"))) { + found = 0; + goto out; + } + + ret = getaddrinfo (hostname, NULL, NULL, &result); + + if (ret != 0) { + gf_log ("", GF_LOG_ERROR, "error in getaddrinfo: %s\n", + gai_strerror(ret)); + goto out; + } + + for (res = result; res != NULL; res = res->ai_next) { + char hname[1024] = ""; + + ret = getnameinfo (res->ai_addr, res->ai_addrlen, hname, + NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + if (ret) + goto out; + + if (!strncasecmp (hname, "127", 3)) { + ret = 0; + gf_log ("", GF_LOG_NORMAL, "local addr found"); + found = 1; + break; + } + } + +out: + //if (result) + // freeaddrinfo (result); + + return !found; +} + int32_t glusterd_lock (uuid_t uuid) { @@ -478,11 +523,9 @@ glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo) } if (ret) { - if ((!strcmp (brickinfo->hostname, "localhost")) || - (!strcmp (brickinfo->hostname, "127.0.0.1"))) { + ret = glusterd_is_local_addr (brickinfo->hostname); + if (!ret) uuid_copy (brickinfo->uuid, priv->uuid); - ret = 0; - } } gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 963541b68cd..670ab73c821 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -73,6 +73,8 @@ struct glusterd_volinfo_ { struct list_head vol_list; struct list_head bricks; glusterd_volume_status status; + int sub_count; + int port; }; typedef struct glusterd_volinfo_ glusterd_volinfo_t; @@ -206,4 +208,10 @@ glusterd_handle_cli_get_volume (rpcsvc_request_t *req); int32_t glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags); + +int32_t +glusterd_add_brick (rpcsvc_request_t *req, dict_t *dict); + +int +glusterd_handle_add_brick (rpcsvc_request_t *req); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c index 8e0a958d873..81cdad65e4b 100644 --- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c +++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c @@ -302,6 +302,40 @@ respond: } int32_t +glusterd3_1_friend_update_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + gd1_mgmt_cluster_lock_rsp rsp = {{0},}; + int ret = -1; + int32_t op_ret = -1; + char str[50] = {0,}; + + GF_ASSERT (req); + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + } + +/* ret = gd_xdr_to_mgmt_friend_update_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + uuid_unparse (rsp.uuid, str); + + op_ret = rsp.op_ret; +*/ + gf_log ("glusterd", GF_LOG_NORMAL, + "Received %s from uuid: %s", + (op_ret)?"RJT":"ACC", str); + +//out: + return ret; +} +int32_t glusterd3_1_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { @@ -714,29 +748,71 @@ glusterd3_1_friend_update (call_frame_t *frame, xlator_t *this, glusterd_conf_t *priv = NULL; glusterd_friend_sm_event_t *event = NULL; glusterd_friend_update_ctx_t *ctx = NULL; + dict_t *friends = NULL; + char key[100] = {0,}; + char uuid_buf[50] = {0,}; + char *dup_buf = NULL; + int32_t count = 0; + char *dict_buf = NULL; + size_t len = -1; + call_frame_t *dummy_frame = NULL; - if (!frame || !this || !data) { + if ( !this || !data) { ret = -1; goto out; } + friends = dict_new (); + if (!friends) + goto out; + event = data; priv = this->private; GF_ASSERT (priv); + list_for_each_entry (peerinfo, &priv->peers, uuid_list) { + count++; + uuid_unparse (peerinfo->uuid, uuid_buf); + snprintf (key, sizeof (key), "friend%d.uuid", count); + dup_buf = gf_strdup (uuid_buf); + ret = dict_set_str (friends, key, dup_buf); + if (ret) + goto out; + snprintf (key, sizeof (key), "friend%d.hostname", count); + ret = dict_set_str (friends, key, peerinfo->hostname); + if (ret) + goto out; + gf_log ("", GF_LOG_NORMAL, "Added uuid: %s, host: %s", + dup_buf, peerinfo->hostname); + } + + ret = dict_set_int32 (friends, "count", count); + if (ret) + goto out; + ctx = event->ctx; + ret = dict_allocate_and_serialize (friends, &dict_buf, (size_t *)&len); + + if (ret) + goto out; + + req.friends.friends_val = dict_buf; + req.friends.friends_len = len; + 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); + list_for_each_entry (peerinfo, &priv->peers, uuid_list) { + dummy_frame = create_frame (this, this->ctx->pool); + ret = glusterd_submit_request (peerinfo, &req, dummy_frame, + priv->mgmt, + GD_MGMT_FRIEND_UPDATE, + NULL, gd_xdr_from_mgmt_friend_update, + this, glusterd3_1_friend_update_cbk); + } out: gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); @@ -1101,6 +1177,10 @@ glusterd_handle_rpc_msg (rpcsvc_request_t *req) ret = glusterd_handle_defrag_volume (req); break; + case GD_MGMT_CLI_ADD_BRICK: + ret = glusterd_handle_add_brick (req); + break; + default: GF_ASSERT (0); } @@ -1133,6 +1213,7 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = { [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}, + [GD_MGMT_CLI_ADD_BRICK] = { "GET_VOLUME", GD_MGMT_CLI_ADD_BRICK, glusterd_handle_rpc_msg, NULL, NULL}, }; /*rpcsvc_actor_t glusterd1_mgmt_actors[] = { |