summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt
diff options
context:
space:
mode:
authorKotresh H R <khiremat@redhat.com>2014-08-01 16:12:38 +0530
committerVijay Bellur <vbellur@redhat.com>2014-09-08 12:02:19 -0700
commit81a127513da40424c572d566c1f26a7dfb345037 (patch)
treea0cf87e5d13742015353843db64ec934ed75e688 /xlators/mgmt
parent85275c5f1d9fe120ed45147a15be74b70d4c7958 (diff)
feature/geo-rep: Keep marker.tstamp's mtime unchangeable during snapshot.
Problem: Geo-replicatoin does a full xsync crawl after snapshot restoration of slave and master. It does not do history crawl. Analysis: Marker creates 'marker.tstamp' file when geo-rep is started for the first time. The virtual extended attribute 'trusted.glusterfs.volume-mark' is maintained and whenever it is queried on gluster mount point, marker fills it on the fly and returns the combination of uuid, ctime of marker.tstamp and others. So ctime of marker.tstamp, in other sense 'volume-mark' marks the geo-rep start time when the session is freshly created. From the above, after the first filesystem crawl(xsync) is done during first geo-rep start, stime should always be less than 'volume-mark'. So whenever stime is less than volume-mark, it does full filesystem crawl (xsync). Root Cause: When snapshot is restored, marker.tstamp file is freshly created losing the timestamps, it was originally created with. Solution: 1. Change is made to depend on mtime instead of ctime. 2. mtime and atime of marker.tstamp is restored back when snapshot is created and restored. BUG: 1138952 Change-Id: I0e19e1cb2593171b9a2b41d0d303330feb7fd2b3 Signed-off-by: Kotresh H R <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/8401 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> Reviewed-on: http://review.gluster.org/8642
Diffstat (limited to 'xlators/mgmt')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c69
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c65
2 files changed, 123 insertions, 11 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 266767cd37a..46ec9eb2e5b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -617,6 +617,62 @@ out:
return ret;
}
+/*
+ * glusterd_snap_geo_rep_restore:
+ * This function restores the atime and mtime of marker.tstamp
+ * if present from snapped marker.tstamp file.
+ */
+static int
+glusterd_snap_geo_rep_restore (glusterd_volinfo_t *snap_volinfo,
+ glusterd_volinfo_t *new_volinfo)
+{
+ char vol_tstamp_file[PATH_MAX] = {0,};
+ char snap_tstamp_file[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ int geo_rep_indexing_on = 0;
+ int ret = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (snap_volinfo);
+ GF_ASSERT (new_volinfo);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ /* Check if geo-rep indexing is enabled, if yes, we need restore
+ * back the mtime of 'marker.tstamp' file.
+ */
+ geo_rep_indexing_on = glusterd_volinfo_get_boolean (new_volinfo,
+ VKEY_MARKER_XTIME);
+ if (geo_rep_indexing_on == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "Failed"
+ " to check whether geo-rep-indexing enabled or not");
+ ret = 0;
+ goto out;
+ }
+
+ if (geo_rep_indexing_on == 1) {
+ GLUSTERD_GET_VOLUME_DIR (vol_tstamp_file, new_volinfo, priv);
+ strncat (vol_tstamp_file, "/marker.tstamp",
+ PATH_MAX - strlen(vol_tstamp_file) - 1);
+ GLUSTERD_GET_VOLUME_DIR (snap_tstamp_file, snap_volinfo, priv);
+ strncat (snap_tstamp_file, "/marker.tstamp",
+ PATH_MAX - strlen(snap_tstamp_file) - 1);
+ ret = gf_set_timestamp (snap_tstamp_file, vol_tstamp_file);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set atime and mtime of %s as of %s",
+ vol_tstamp_file, snap_tstamp_file);
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
/* This function will copy snap volinfo to the new
* passed volinfo and regenerate backend store files
* for the restored snap.
@@ -749,6 +805,19 @@ glusterd_snap_volinfo_restore (dict_t *dict, dict_t *rsp_dict,
/* Regenerate all volfiles */
ret = glusterd_create_volfiles_and_notify_services (new_volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to regenerate volfiles");
+ goto out;
+ }
+
+ /* Restore geo-rep marker.tstamp's timestamp */
+ ret = glusterd_snap_geo_rep_restore (snap_volinfo, new_volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Geo-rep: marker.tstamp's timestamp restoration failed");
+ goto out;
+ }
out:
if (ret && (NULL != new_brickinfo)) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 9701c6b939c..f1e30e1ee82 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -16,6 +16,7 @@
#include <fnmatch.h>
#include <sys/wait.h>
#include <dlfcn.h>
+#include <utime.h>
#if (HAVE_LIB_XML)
#include <libxml/encoding.h>
@@ -3824,12 +3825,34 @@ get_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo)
PATH_MAX - strlen(filename) - 1);
}
+static void
+get_parent_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ snprintf (filename, PATH_MAX, "%s/vols/%s", priv->workdir,
+ volinfo->parent_volname);
+ strncat (filename, "/marker.tstamp",
+ PATH_MAX - strlen(filename) - 1);
+}
+
int
generate_brick_volfiles (glusterd_volinfo_t *volinfo)
{
- glusterd_brickinfo_t *brickinfo = NULL;
- char tstamp_file[PATH_MAX] = {0,};
- int ret = -1;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char tstamp_file[PATH_MAX] = {0,};
+ char parent_tstamp_file[PATH_MAX] = {0,};
+ int ret = -1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
ret = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME);
if (ret == -1)
@@ -3840,29 +3863,49 @@ generate_brick_volfiles (glusterd_volinfo_t *volinfo)
if (ret) {
ret = open (tstamp_file, O_WRONLY|O_CREAT|O_EXCL, 0600);
if (ret == -1 && errno == EEXIST) {
- gf_log ("", GF_LOG_DEBUG, "timestamp file exist");
+ gf_log (this->name, GF_LOG_DEBUG,
+ "timestamp file exist");
ret = -2;
}
if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "failed to create %s (%s)",
- tstamp_file, strerror (errno));
+ gf_log (this->name, GF_LOG_ERROR, "failed to create "
+ "%s (%s)", tstamp_file, strerror (errno));
return -1;
}
- if (ret >= 0)
+ if (ret >= 0) {
close (ret);
+ /* If snap_volume, retain timestamp for marker.tstamp
+ * from parent. Geo-replication depends on mtime of
+ * 'marker.tstamp' to decide the volume-mark, i.e.,
+ * geo-rep start time just after session is created.
+ */
+ if (volinfo->is_snap_volume) {
+ get_parent_vol_tstamp_file (parent_tstamp_file,
+ volinfo);
+ ret = gf_set_timestamp (parent_tstamp_file,
+ tstamp_file);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set atime and mtime"
+ " of %s as of %s", tstamp_file,
+ parent_tstamp_file);
+ goto out;
+ }
+ }
+ }
} else {
ret = unlink (tstamp_file);
if (ret == -1 && errno == ENOENT)
ret = 0;
if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "failed to unlink %s (%s)",
- tstamp_file, strerror (errno));
+ gf_log (this->name, GF_LOG_ERROR, "failed to unlink "
+ "%s (%s)", tstamp_file, strerror (errno));
return -1;
}
}
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- gf_log ("", GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_DEBUG,
"Found a brick - %s:%s", brickinfo->hostname,
brickinfo->path);
@@ -3875,7 +3918,7 @@ generate_brick_volfiles (glusterd_volinfo_t *volinfo)
ret = 0;
out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}