summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2014-10-03 17:35:47 +0530
committerVenky Shankar <vshankar@redhat.com>2014-10-12 19:42:10 -0700
commit3b5b5042ec2f119e3ec807829c101c421e90e2da (patch)
treeaa090a1fe94f2cc44d0a4951add079f894451953
parentf5d544d435b1ca0868846e74ce292faa2e7388e4 (diff)
glusterd/geo-rep: Fix race in updating status file
When geo-rep is in paused state and a node in a cluster is rebooted, the geo-rep status goes to "faulty (Paused)" and no worker processes are started on that node yet. In this state, when geo-rep is resumed, there is a race in updating status file between glusterd and gsyncd itself as geo-rep is resumed first and then status is updated. glusterd tries to update to previous state and gsyncd tries to update it to "Initializing...(Paused)" on restart as it was paused previously. If gsyncd on restart wins, the state is always paused but the process is not acutally paused. So the solution is glusterd to update the status file and then resume. Change-Id: I348761a6e8c3ad2630c79833bc86587d062a8f92 BUG: 1149982 Signed-off-by: Kotresh HR <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/8911 Reviewed-by: Aravinda VK <avishwan@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Venky Shankar <vshankar@redhat.com> Tested-by: Venky Shankar <vshankar@redhat.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-geo-rep.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c
index 74d28a71898..a160314134e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c
+++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c
@@ -2821,32 +2821,40 @@ gd_pause_or_resume_gsync (dict_t *dict, char *master, char *slave,
goto out;
}
} else {
- ret = kill (-pid, SIGCONT);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to resume gsyncd. Error: %s",
- strerror (errno));
- goto out;
- }
token = strtok (monitor_status, "(");
ret = glusterd_create_status_file (master, slave,
slave_host,
slave_vol, token);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
- "Unable to update state_file."
- " Error : %s", strerror (errno));
- /* If status cannot be updated pause back */
- if (kill (-pid, SIGSTOP)) {
+ "Resume Failed: Unable to update "
+ "state_file. Error : %s",
+ strerror (errno));
+ goto out;
+ }
+ ret = kill (-pid, SIGCONT);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Resumed Failed: Unable to send"
+ " SIGCONT. Error: %s",
+ strerror (errno));
+ /* Process can't be resumed, update status
+ * back to paused. */
+ ret = glusterd_create_status_file (master,
+ slave,
+ slave_host,
+ slave_vol,
+ monitor_status);
+ if (ret) {
snprintf (errmsg, sizeof(errmsg),
- "Resume successful but could "
- "not update status file."
- " Please use 'pause force' to"
- " pause back and retry resume"
- " to reflect in status");
+ "Resume failed!!! Status "
+ "inconsistent. Please use "
+ "'resume force' to resume and"
+ " reach consistent state");
gf_log (this->name, GF_LOG_ERROR,
- "Pause back Failed. Error: %s",
- strerror (errno));
+ "Updating status back to paused"
+ " Failed. Error: %s",
+ strerror (errno));
*op_errstr = gf_strdup (errmsg);
}
goto out;