summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@gluster.com>2011-04-03 15:44:17 +0000
committerVijay Bellur <vijay@dev.gluster.com>2011-04-04 08:02:30 -0700
commitf338193a707ae5b6b5ab6f820bea32612c4311bb (patch)
tree940842ac59eeb180f892ac8d379219b994b83a11
parent01b3dff29adee2041b0ef1b374eda8c88fb07678 (diff)
syncdaemon: refine intermal configuration of gsyncdv3.2.0qa7
Signed-off-by: Csaba Henk <csaba@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 2561 (gsyncd command's must be preconfigured) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2561
-rw-r--r--cli/src/cli-rpc-ops.c63
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c95
2 files changed, 121 insertions, 37 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 110962c6c..c358192d2 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -26,6 +26,7 @@
#ifndef GSYNC_CONF
#define GSYNC_CONF "gsync/gsyncd.conf"
#endif
+#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
#include "cli.h"
#include "compat-errno.h"
@@ -2609,7 +2610,7 @@ gf_cli3_1_gsync_get_param_file (char *prmfile, const char *ext, char *master, ch
char buff[PATH_MAX] = {0, };
char cmd[PATH_MAX] = {0, };
char *ptr = NULL;
- char pidfolder[PATH_MAX] = {0, };
+ char prmfolder[PATH_MAX] = {0, };
char *dotp = NULL;
int ret = 0;
@@ -2637,7 +2638,7 @@ gf_cli3_1_gsync_get_param_file (char *prmfile, const char *ext, char *master, ch
ptr = fgets(buff, sizeof(buff), in);
if (ptr) {
buff[strlen(buff)-1]='\0'; //strip off \n
- snprintf (pidfolder, PATH_MAX, "%s/gsync/%s", gl_workdir, buff);
+ snprintf (prmfolder, PATH_MAX, "%s/gsync/%s", gl_workdir, buff);
} else {
ret = -1;
goto out;
@@ -2648,7 +2649,7 @@ gf_cli3_1_gsync_get_param_file (char *prmfile, const char *ext, char *master, ch
ptr = fgets(buff, sizeof(buff), in);
if (ptr) {
buff[strlen(buff)-1]='\0'; //strip off \n
- snprintf (prmfile, PATH_MAX, "%s/%s.pid", pidfolder, buff);
+ snprintf (prmfile, PATH_MAX, "%s/%s.%s", prmfolder, buff, ext);
}
out:
@@ -2704,7 +2705,7 @@ gf_cli3_1_start_gsync (char *master, char *slave, char *gl_workdir)
if (ret == -1) {
ret = -1;
gf_log ("", GF_LOG_WARNING, "failed to construct the "
- "prmfile string");
+ "pidfile string");
goto out;
}
@@ -2766,6 +2767,60 @@ gf_cli3_1_start_gsync (char *master, char *slave, char *gl_workdir)
goto out;
}
+ ret = gf_cli3_1_gsync_get_param_file (prmfile, "log", master,
+ slave, DEFAULT_LOG_FILE_DIRECTORY);
+ if (ret == -1) {
+ gf_log ("", GF_LOG_WARNING, "failed to construct the "
+ "logfile string");
+ goto out;
+ }
+ /* XXX "mkdir -p": eventually this should be made into a library routine */
+ tslash = strrchr(prmfile, '/');
+ if (tslash) {
+ char *slash = prmfile;
+ struct stat st = {0,};
+
+ *tslash = '\0';
+ if (*slash == '/')
+ slash++;
+ while (slash) {
+ slash = strchr (slash, '/');
+ if (slash)
+ *slash = '\0';
+ ret = mkdir (prmfile, 0777);
+ if (ret == -1 && errno != EEXIST) {
+ gf_log ("", GF_LOG_DEBUG, "mkdir failed (%s)",
+ strerror (errno));
+ goto out;
+ }
+ if (slash) {
+ *slash = '/';
+ slash++;
+ }
+ }
+ ret = stat (prmfile, &st);
+ if (ret == -1 || !S_ISDIR (st.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_DEBUG, "mkdir failed (%s)",
+ strerror (errno));
+ goto out;
+ }
+ *tslash = '/';
+ }
+
+ ret = snprintf (cmd, PATH_MAX, GSYNCD_PREFIX "/gsyncd -c %s/%s %s %s"
+ " --config-set log-file %s", gl_workdir,
+ GSYNC_CONF, master, slave, prmfile);
+ if (ret >= PATH_MAX)
+ ret = -1;
+ if (ret != -1)
+ ret = system (cmd) ? -1 : 0;
+ if (ret == -1) {
+ gf_log ("", GF_LOG_WARNING, "failed to set status file "
+ "for %s %s", master, slave);
+ goto out;
+ }
+
memset (cmd, 0, sizeof (cmd));
ret = snprintf (cmd, PATH_MAX, GSYNCD_PREFIX "/gsyncd --monitor -c %s/%s %s %s"
, gl_workdir, GSYNC_CONF, master, slave);
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index 004973afb..b4df630d0 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -229,6 +229,66 @@ out:
return ret;
}
+static int
+configure_syncaemon (xlator_t *this, const char *workdir)
+{
+ int ret = 0;
+#if SYNCDAEMON_COMPILE
+ char voldir[PATH_MAX] = {0,};
+ char cmd[4096] = {0,};
+ int blen = 0;
+
+ snprintf (voldir, PATH_MAX, "%s/gsync", workdir);
+ ret = mkdir (voldir, 0777);
+ if ((-1 == ret) && (errno != EEXIST)) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Unable to create gsync directory %s (%s)",
+ voldir, strerror (errno));
+ return -1;
+ }
+
+ blen = snprintf (cmd, PATH_MAX, GSYNCD_PREFIX"/gsyncd -c %s/"GSYNC_CONF
+ " --config-set-rx ", workdir);
+
+ /* remote-gsyncd */
+ strcpy (cmd + blen,
+ "remote-gsyncd "
+ "'"GSYNCD_PREFIX"/gsyncd --gluster-command "GFS_PREFIX"/sbin/glusterfs' "
+ ". .");
+ ret = system (cmd);
+ if (ret)
+ goto out;
+
+ strcpy (cmd + blen,
+ "remote-gsyncd /usr/local/libexec/glusterfs/gsyncd . ^ssh:");
+ ret = system (cmd);
+ if (ret)
+ goto out;
+
+ /* gluster-command */
+ /* XXX $sbindir should be used (throughout the codebase) */
+ strcpy (cmd + blen,
+ "gluster-command "GFS_PREFIX"/sbin/glusterfs . .");
+ ret = system (cmd);
+ if (ret)
+ goto out;
+
+ /* ssh-command */
+ strcpy (cmd + blen,
+ "ssh-command 'ssh -oPasswordAuthentication=no' . .");
+ ret = system (cmd);
+ if (ret)
+ goto out;
+
+ out:
+#else
+ (void)this;
+ (void)workdir;
+#endif
+ return ret ? -1 : 0;
+}
+
+
/*
* init - called during glusterd initialization
*
@@ -247,7 +307,6 @@ init (xlator_t *this)
char dirname [PATH_MAX];
char cmd_log_filename [PATH_MAX] = {0,};
int first_time = 0;
- char cmd [PATH_MAX] = {0,};
dir_data = dict_get (this->options, "working-directory");
@@ -338,41 +397,11 @@ init (xlator_t *this)
" ,errno = %d", voldir, errno);
exit (1);
}
-#if (SYNCDAEMON_COMPILE)
- snprintf (voldir, PATH_MAX, "%s/gsync", dirname);
- ret = mkdir (voldir, 0777);
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create gsync directory %s"
- " ,errno = %d", voldir, errno);
- exit (1);
- }
-
- ret = snprintf (cmd, PATH_MAX, GSYNCD_PREFIX "/gsyncd -c %s/%s "
- " --config-set-rx remote-gsyncd %s/gsyncd . ."
- , dirname, GSYNC_CONF, GSYNCD_PREFIX);
- if (ret <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = system (cmd);
- if (ret == -1)
- goto out;
- ret = snprintf (cmd, 1024, GSYNCD_PREFIX "/gsyncd -c %s/%s "
- " --config-set-rx remote-gsyncd"
- " /usr/local/libexec/glusterfs/gsyncd . ^ssh:"
- , dirname, GSYNC_CONF);
- if (ret <= 0) {
- ret = -1;
+ ret = configure_syncaemon (this, dirname);
+ if (ret)
goto out;
- }
- ret = system (cmd);
- if (ret == -1)
- goto out;
-#endif
ret = glusterd_rpcsvc_options_build (this->options);
if (ret)
goto out;
= -1; int32_t peer_cnt = 0; dict_t *rsp_dict = NULL; glusterd_peerinfo_t *peerinfo = NULL; struct syncargs args = {0}; struct list_head *peers = NULL; uuid_t peer_uuid = {0}; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (conf); GF_ASSERT (req_dict); GF_ASSERT (op_errstr); peers = &conf->xaction_peers; rsp_dict = dict_new (); if (!rsp_dict) { gf_log (this->name, GF_LOG_ERROR, "Failed to create response dictionary"); goto out; } /* Pre Validation on local node */ ret = gd_mgmt_v3_pre_validate_fn (op, req_dict, op_errstr, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Pre Validation failed for " "operation %s on local node", gd_op_list[op]); if (*op_errstr == NULL) { ret = gf_asprintf (op_errstr, "Pre-validation failed " "on localhost. Please " "check log file for details"); if (ret == -1) *op_errstr = NULL; ret = -1; } goto out; } ret = glusterd_pre_validate_aggr_rsp_dict (op, req_dict, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "%s", "Failed to aggregate response from " " node/brick"); goto out; } dict_unref (rsp_dict); rsp_dict = NULL; if (!npeers) { ret = 0; goto out; } /* Sending Pre Validation req to other nodes in the cluster */ gd_syncargs_init (&args, req_dict); synctask_barrier_init((&args)); peer_cnt = 0; list_for_each_entry (peerinfo, peers, op_peers_list) { gd_mgmt_v3_pre_validate_req (op, req_dict, peerinfo, &args, MY_UUID, peer_uuid); peer_cnt++; } gd_synctask_barrier_wait((&args), peer_cnt); if (args.op_ret) { gf_log (this->name, GF_LOG_ERROR, "Pre Validation failed on peers"); if (args.errstr) *op_errstr = gf_strdup (args.errstr); } ret = args.op_ret; gf_log (this->name, GF_LOG_DEBUG, "Sent pre valaidation req for %s " "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret); out: return ret; } int glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict, glusterd_op_t op) { int32_t ret = -1; dict_t *req_dict = NULL; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (op_errstr); GF_ASSERT (dict); req_dict = dict_new (); if (!req_dict) goto out; switch (op) { case GD_OP_SNAP: dict_copy (dict, req_dict); break; default: break; } *req = req_dict; ret = 0; out: return ret; } int32_t gd_mgmt_v3_brick_op_cbk_fn (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = -1; struct syncargs *args = NULL; glusterd_peerinfo_t *peerinfo = NULL; gd1_mgmt_v3_brick_op_rsp rsp = {{0},}; call_frame_t *frame = NULL; int32_t op_ret = -1; int32_t op_errno = -1; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (myframe); frame = myframe; args = frame->local; peerinfo = frame->cookie; frame->local = NULL; frame->cookie = NULL; /* If the operation failed, then iov can be NULL. So better check the status of the operation and then worry about iov (if the status of the command is success) */ if (-1 == req->rpc_status) { op_errno = ENOTCONN; goto out; } if (!iov) { gf_log (this->name, GF_LOG_ERROR, "iov is NULL"); op_errno = EINVAL; goto out; } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_v3_brick_op_rsp); if (ret < 0) goto out; uuid_copy (args->uuid, rsp.uuid); op_ret = rsp.op_ret; op_errno = rsp.op_errno; out: gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL, GLUSTERD_MGMT_V3_BRICK_OP, peerinfo, rsp.uuid); if (rsp.op_errstr) free (rsp.op_errstr); if (rsp.dict.dict_val) free (rsp.dict.dict_val); STACK_DESTROY (frame->root); synctask_barrier_wake(args); return 0; } int32_t gd_mgmt_v3_brick_op_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { return glusterd_big_locked_cbk (req, iov, count, myframe, gd_mgmt_v3_brick_op_cbk_fn); } int gd_mgmt_v3_brick_op_req (glusterd_op_t op, dict_t *op_ctx, glusterd_peerinfo_t *peerinfo, struct syncargs *args, uuid_t my_uuid, uuid_t recv_uuid) { int32_t ret = -1; gd1_mgmt_v3_brick_op_req req = {{0},}; glusterd_conf_t *conf = THIS->private; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (op_ctx); GF_ASSERT (peerinfo); GF_ASSERT (args); ret = dict_allocate_and_serialize (op_ctx, &req.dict.dict_val, &req.dict.dict_len); if (ret) goto out; uuid_copy (req.uuid, my_uuid); req.op = op; synclock_unlock (&conf->big_lock); ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo, &gd_mgmt_v3_prog, GLUSTERD_MGMT_V3_BRICK_OP, gd_mgmt_v3_brick_op_cbk, (xdrproc_t) xdr_gd1_mgmt_v3_brick_op_req); synclock_lock (&conf->big_lock); out: GF_FREE (req.dict.dict_val); gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); return ret; } int glusterd_mgmt_v3_brick_op (glusterd_conf_t *conf, glusterd_op_t op, dict_t *req_dict, char **op_errstr, int npeers) { int32_t ret = -1; int32_t peer_cnt = 0; dict_t *rsp_dict = NULL; glusterd_peerinfo_t *peerinfo = NULL; struct syncargs args = {0}; struct list_head *peers = NULL; uuid_t peer_uuid = {0}; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (conf); GF_ASSERT (req_dict); GF_ASSERT (op_errstr); peers = &conf->xaction_peers; rsp_dict = dict_new (); if (!rsp_dict) { gf_log (this->name, GF_LOG_ERROR, "Failed to create response dictionary"); goto out; } /* Perform brick op on local node */ ret = gd_mgmt_v3_brick_op_fn (op, req_dict, op_errstr, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Brick ops failed for " "operation %s on local node", gd_op_list[op]); if (*op_errstr == NULL) { ret = gf_asprintf (op_errstr, "Brick ops failed " "on localhost. Please " "check log file for details"); if (ret == -1) *op_errstr = NULL; ret = -1; } goto out; } dict_unref (rsp_dict); rsp_dict = NULL; if (!npeers) { ret = 0; goto out; } /* Sending brick op req to other nodes in the cluster */ gd_syncargs_init (&args, NULL); synctask_barrier_init((&args)); peer_cnt = 0; list_for_each_entry (peerinfo, peers, op_peers_list) { gd_mgmt_v3_brick_op_req (op, req_dict, peerinfo, &args, MY_UUID, peer_uuid); peer_cnt++; } gd_synctask_barrier_wait((&args), peer_cnt); if (args.op_ret) { gf_log (this->name, GF_LOG_ERROR, "Brick ops failed on peers"); if (args.errstr) *op_errstr = gf_strdup (args.errstr); } ret = args.op_ret; gf_log (this->name, GF_LOG_DEBUG, "Sent brick op req for %s " "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret); out: return ret; } int32_t gd_mgmt_v3_commit_cbk_fn (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = -1; struct syncargs *args = NULL; glusterd_peerinfo_t *peerinfo = NULL; gd1_mgmt_v3_commit_rsp rsp = {{0},}; call_frame_t *frame = NULL; int32_t op_ret = -1; int32_t op_errno = -1; dict_t *rsp_dict = NULL; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (myframe); frame = myframe; args = frame->local; peerinfo = frame->cookie; frame->local = NULL; frame->cookie = NULL; if (-1 == req->rpc_status) { op_errno = ENOTCONN; goto out; } if (!iov) { gf_log (this->name, GF_LOG_ERROR, "iov is NULL"); op_errno = EINVAL; goto out; } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_v3_commit_rsp); if (ret < 0) goto out; if (rsp.dict.dict_len) { /* Unserialize the dictionary */ rsp_dict = dict_new (); ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &rsp_dict); if (ret < 0) { free (rsp.dict.dict_val); goto out; } else { rsp_dict->extra_stdfree = rsp.dict.dict_val; } } uuid_copy (args->uuid, rsp.uuid); pthread_mutex_lock (&args->lock_dict); { ret = glusterd_syncop_aggr_rsp_dict (rsp.op, args->dict, rsp_dict); } pthread_mutex_unlock (&args->lock_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "%s", "Failed to aggregate response from " " node/brick"); if (!rsp.op_ret) op_ret = ret; else { op_ret = rsp.op_ret; op_errno = rsp.op_errno; } } else { op_ret = rsp.op_ret; op_errno = rsp.op_errno; } out: if (rsp_dict) dict_unref (rsp_dict); gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL, GLUSTERD_MGMT_V3_COMMIT, peerinfo, rsp.uuid); STACK_DESTROY (frame->root); synctask_barrier_wake(args); return 0; } int32_t gd_mgmt_v3_commit_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { return glusterd_big_locked_cbk (req, iov, count, myframe, gd_mgmt_v3_commit_cbk_fn); } int gd_mgmt_v3_commit_req (glusterd_op_t op, dict_t *op_ctx, glusterd_peerinfo_t *peerinfo, struct syncargs *args, uuid_t my_uuid, uuid_t recv_uuid) { int32_t ret = -1; gd1_mgmt_v3_commit_req req = {{0},}; glusterd_conf_t *conf = THIS->private; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (op_ctx); GF_ASSERT (peerinfo); GF_ASSERT (args); ret = dict_allocate_and_serialize (op_ctx, &req.dict.dict_val, &req.dict.dict_len); if (ret) goto out; uuid_copy (req.uuid, my_uuid); req.op = op; synclock_unlock (&conf->big_lock); ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo, &gd_mgmt_v3_prog, GLUSTERD_MGMT_V3_COMMIT, gd_mgmt_v3_commit_cbk, (xdrproc_t) xdr_gd1_mgmt_v3_commit_req); synclock_lock (&conf->big_lock); out: GF_FREE (req.dict.dict_val); gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); return ret; } int glusterd_mgmt_v3_commit (glusterd_conf_t *conf, glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict, char **op_errstr, int npeers) { int32_t ret = -1; int32_t peer_cnt = 0; dict_t *rsp_dict = NULL; glusterd_peerinfo_t *peerinfo = NULL; struct syncargs args = {0}; struct list_head *peers = NULL; uuid_t peer_uuid = {0}; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (conf); GF_ASSERT (op_ctx); GF_ASSERT (req_dict); GF_ASSERT (op_errstr); peers = &conf->xaction_peers; rsp_dict = dict_new (); if (!rsp_dict) { gf_log (this->name, GF_LOG_ERROR, "Failed to create response dictionary"); goto out; } /* Commit on local node */ ret = gd_mgmt_v3_commit_fn (op, req_dict, op_errstr, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Commit failed for " "operation %s on local node", gd_op_list[op]); if (*op_errstr == NULL) { ret = gf_asprintf (op_errstr, "Commit failed " "on localhost. Please " "check log file for details."); if (ret == -1) *op_errstr = NULL; ret = -1; } goto out; } ret = glusterd_syncop_aggr_rsp_dict (op, op_ctx, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "%s", "Failed to aggregate response from " " node/brick"); goto out; } dict_unref (rsp_dict); rsp_dict = NULL; if (!npeers) { ret = 0; goto out; } /* Sending commit req to other nodes in the cluster */ gd_syncargs_init (&args, op_ctx); synctask_barrier_init((&args)); peer_cnt = 0; list_for_each_entry (peerinfo, peers, op_peers_list) { gd_mgmt_v3_commit_req (op, req_dict, peerinfo, &args, MY_UUID, peer_uuid); peer_cnt++; } gd_synctask_barrier_wait((&args), peer_cnt); if (args.op_ret) { gf_log (this->name, GF_LOG_ERROR, "Commit failed on peers"); if (args.errstr) *op_errstr = gf_strdup (args.errstr); } ret = args.op_ret; gf_log (this->name, GF_LOG_DEBUG, "Sent commit req for %s to %d " "peers. Returning %d", gd_op_list[op], peer_cnt, ret); out: return ret; } int32_t gd_mgmt_v3_post_validate_cbk_fn (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = -1; struct syncargs *args = NULL; glusterd_peerinfo_t *peerinfo = NULL; gd1_mgmt_v3_post_val_rsp rsp = {{0},}; call_frame_t *frame = NULL; int32_t op_ret = -1; int32_t op_errno = -1; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (myframe); frame = myframe; args = frame->local; peerinfo = frame->cookie; frame->local = NULL; frame->cookie = NULL; if (-1 == req->rpc_status) { op_errno = ENOTCONN; goto out; } if (!iov) { gf_log (this->name, GF_LOG_ERROR, "iov is NULL"); op_errno = EINVAL; goto out; } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_v3_post_val_rsp); if (ret < 0) goto out; uuid_copy (args->uuid, rsp.uuid); op_ret = rsp.op_ret; op_errno = rsp.op_errno; out: gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL, GLUSTERD_MGMT_V3_POST_VALIDATE, peerinfo, rsp.uuid); if (rsp.op_errstr) free (rsp.op_errstr); if (rsp.dict.dict_val) free (rsp.dict.dict_val); STACK_DESTROY (frame->root); synctask_barrier_wake(args); return 0; } int32_t gd_mgmt_v3_post_validate_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { return glusterd_big_locked_cbk (req, iov, count, myframe, gd_mgmt_v3_post_validate_cbk_fn); } int gd_mgmt_v3_post_validate_req (glusterd_op_t op, int32_t op_ret, dict_t *op_ctx, glusterd_peerinfo_t *peerinfo, struct syncargs *args, uuid_t my_uuid, uuid_t recv_uuid) { int32_t ret = -1; gd1_mgmt_v3_post_val_req req = {{0},}; glusterd_conf_t *conf = THIS->private; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (op_ctx); GF_ASSERT (peerinfo); GF_ASSERT (args); ret = dict_allocate_and_serialize (op_ctx, &req.dict.dict_val, &req.dict.dict_len); if (ret) goto out; uuid_copy (req.uuid, my_uuid); req.op = op; req.op_ret = op_ret; synclock_unlock (&conf->big_lock); ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo, &gd_mgmt_v3_prog, GLUSTERD_MGMT_V3_POST_VALIDATE, gd_mgmt_v3_post_validate_cbk, (xdrproc_t) xdr_gd1_mgmt_v3_post_val_req); synclock_lock (&conf->big_lock); out: GF_FREE (req.dict.dict_val); gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); return ret; } int glusterd_mgmt_v3_post_validate (glusterd_conf_t *conf, glusterd_op_t op, int32_t op_ret, dict_t *dict, dict_t *req_dict, char **op_errstr, int npeers) { int32_t ret = -1; int32_t peer_cnt = 0; dict_t *rsp_dict = NULL; glusterd_peerinfo_t *peerinfo = NULL; struct syncargs args = {0}; struct list_head *peers = NULL; uuid_t peer_uuid = {0}; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (conf); GF_ASSERT (dict); GF_VALIDATE_OR_GOTO (this->name, req_dict, out); GF_ASSERT (op_errstr); peers = &conf->xaction_peers; GF_ASSERT (peers); rsp_dict = dict_new (); if (!rsp_dict) { gf_log (this->name, GF_LOG_ERROR, "Failed to create response dictionary"); goto out; } /* Copy the contents of dict like missed snaps info to req_dict */ dict_copy (dict, req_dict); /* Post Validation on local node */ ret = gd_mgmt_v3_post_validate_fn (op, op_ret, req_dict, op_errstr, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Post Validation failed for " "operation %s on local node", gd_op_list[op]); if (*op_errstr == NULL) { ret = gf_asprintf (op_errstr, "Post-validation failed " "on localhost. Please check " "log file for details"); if (ret == -1) *op_errstr = NULL; ret = -1; } goto out; } dict_unref (rsp_dict); rsp_dict = NULL; if (!npeers) { ret = 0; goto out; } /* Sending Post Validation req to other nodes in the cluster */ gd_syncargs_init (&args, req_dict); synctask_barrier_init((&args)); peer_cnt = 0; list_for_each_entry (peerinfo, peers, op_peers_list) { gd_mgmt_v3_post_validate_req (op, op_ret, req_dict, peerinfo, &args, MY_UUID, peer_uuid); peer_cnt++; } gd_synctask_barrier_wait((&args), peer_cnt); if (args.op_ret) { gf_log (this->name, GF_LOG_ERROR, "Post Validation failed on peers"); if (args.errstr) *op_errstr = gf_strdup (args.errstr); } ret = args.op_ret; gf_log (this->name, GF_LOG_DEBUG, "Sent post valaidation req for %s " "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret); out: return ret; } int32_t gd_mgmt_v3_unlock_cbk_fn (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = -1; struct syncargs *args = NULL; glusterd_peerinfo_t *peerinfo = NULL; gd1_mgmt_v3_unlock_rsp rsp = {{0},}; call_frame_t *frame = NULL; int32_t op_ret = -1; int32_t op_errno = -1; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (myframe); frame = myframe; args = frame->local; peerinfo = frame->cookie; frame->local = NULL; frame->cookie = NULL; if (-1 == req->rpc_status) { op_errno = ENOTCONN; goto out; } if (!iov) { gf_log (this->name, GF_LOG_ERROR, "iov is NULL"); op_errno = EINVAL; goto out; } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp); if (ret < 0) goto out; uuid_copy (args->uuid, rsp.uuid); op_ret = rsp.op_ret; op_errno = rsp.op_errno; out: gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL, GLUSTERD_MGMT_V3_UNLOCK, peerinfo, rsp.uuid); if (rsp.dict.dict_val) free (rsp.dict.dict_val); STACK_DESTROY (frame->root); synctask_barrier_wake(args); return 0; } int32_t gd_mgmt_v3_unlock_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { return glusterd_big_locked_cbk (req, iov, count, myframe, gd_mgmt_v3_unlock_cbk_fn); } int gd_mgmt_v3_unlock (glusterd_op_t op, dict_t *op_ctx, glusterd_peerinfo_t *peerinfo, struct syncargs *args, uuid_t my_uuid, uuid_t recv_uuid) { int32_t ret = -1; gd1_mgmt_v3_unlock_req req = {{0},}; glusterd_conf_t *conf = THIS->private; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (op_ctx); GF_ASSERT (peerinfo); GF_ASSERT (args); ret = dict_allocate_and_serialize (op_ctx, &req.dict.dict_val, &req.dict.dict_len); if (ret) goto out; uuid_copy (req.uuid, my_uuid); req.op = op; synclock_unlock (&conf->big_lock); ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo, &gd_mgmt_v3_prog, GLUSTERD_MGMT_V3_UNLOCK, gd_mgmt_v3_unlock_cbk, (xdrproc_t) xdr_gd1_mgmt_v3_unlock_req); synclock_lock (&conf->big_lock); out: GF_FREE (req.dict.dict_val); gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); return ret; } int glusterd_mgmt_v3_release_peer_locks (glusterd_conf_t *conf, glusterd_op_t op, dict_t *dict, int32_t op_ret, char **op_errstr, int npeers, gf_boolean_t is_acquired) { int32_t ret = -1; int32_t peer_cnt = 0; uuid_t peer_uuid = {0}; xlator_t *this = NULL; glusterd_peerinfo_t *peerinfo = NULL; struct syncargs args = {0}; struct list_head *peers = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (conf); GF_ASSERT (dict); GF_ASSERT (op_errstr); peers = &conf->xaction_peers; /* If the lock has not been held during this * transaction, do not send unlock requests */ if (!is_acquired) goto out; if (!npeers) { ret = 0; goto out; } /* Sending mgmt_v3 unlock req to other nodes in the cluster */ gd_syncargs_init (&args, NULL); synctask_barrier_init((&args)); peer_cnt = 0; list_for_each_entry (peerinfo, peers, op_peers_list) { gd_mgmt_v3_unlock (op, dict, peerinfo, &args, MY_UUID, peer_uuid); peer_cnt++; } gd_synctask_barrier_wait((&args), peer_cnt); if (args.op_ret) { gf_log (this->name, GF_LOG_ERROR, "Unlock failed on peers"); if (!op_ret && args.errstr) *op_errstr = gf_strdup (args.errstr); } ret = args.op_ret; gf_log (this->name, GF_LOG_DEBUG, "Sent unlock op req for %s " "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret); out: return ret; } int32_t glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op, dict_t *dict) { int32_t ret = -1; int32_t op_ret = -1; int32_t npeers = 0; dict_t *req_dict = NULL; dict_t *tmp_dict = NULL; glusterd_conf_t *conf = NULL; char *op_errstr = NULL; xlator_t *this = NULL; gf_boolean_t is_acquired = _gf_false; uuid_t *originator_uuid = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (dict); conf = this->private; GF_ASSERT (conf); /* Save the MY_UUID as the originator_uuid. This originator_uuid * will be used by is_origin_glusterd() to determine if a node * is the originator node for a command. */ originator_uuid = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t); if (!originator_uuid) { ret = -1; goto out; } uuid_copy (*originator_uuid, MY_UUID); ret = dict_set_bin (dict, "originator_uuid", originator_uuid, sizeof (uuid_t)); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to set originator_uuid."); goto out; } /* Marking the operation as complete synctasked */ ret = dict_set_int32 (dict, "is_s