summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVijay Bellur <vijay@gluster.com>2010-07-22 04:17:35 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-07-22 23:10:38 -0700
commitbe4dee16c18e262b168c74face54cf17ca13e2f4 (patch)
tree5301cf748e07815303d5ba16d5b765849a8165a0
parent5601c137674b4dabd39b1cf26a36327bfbc707a6 (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.c42
-rw-r--r--cli/src/cli-cmd-volume.c13
-rw-r--r--cli/src/cli3_1-cops.c8
-rw-r--r--extras/Makefile.am2
-rw-r--r--rpc/xdr/src/glusterd1-xdr.c19
-rw-r--r--rpc/xdr/src/glusterd1-xdr.h16
-rw-r--r--rpc/xdr/src/glusterd1.c15
-rw-r--r--rpc/xdr/src/glusterd1.h6
-rw-r--r--rpc/xdr/src/glusterd1.x10
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c159
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c267
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c51
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h8
-rw-r--r--xlators/mgmt/glusterd/src/glusterd3_1-mops.c95
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[] = {