summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAjeet Jha <ajha@redhat.com>2014-08-23 19:06:45 +0530
committerVijay Bellur <vbellur@redhat.com>2014-08-26 03:16:53 -0700
commitacabde2c297c4175946565017ba17a251ad3fb1c (patch)
tree45a48a9f1c68b1966ce9c68dbb456997f62bdc63
parentb56751b3b9a9ed3cceb2f0d221fa40ef94a8d516 (diff)
features/changelog: Crash consistency of changelog wrt snapshot
This patch introduces call-path fop details logging for data operations in CHANGELOG.SNAP. This feature is enabled with barrier-enable notification and disabled with barrier-disable notification. Change-Id: Ib548d34203eb99cea478a6baff402e82251c73a4 BUG: 1128093 Signed-off-by: Ajeet Jha <ajha@redhat.com> Reviewed-on: http://review.gluster.org/8533 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--xlators/features/changelog/src/changelog-helpers.c156
-rw-r--r--xlators/features/changelog/src/changelog-helpers.h18
-rw-r--r--xlators/features/changelog/src/changelog-misc.h6
-rw-r--r--xlators/features/changelog/src/changelog.c52
4 files changed, 232 insertions, 0 deletions
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c
index 07c6096dce5..9dccf45187c 100644
--- a/xlators/features/changelog/src/changelog-helpers.c
+++ b/xlators/features/changelog/src/changelog-helpers.c
@@ -337,6 +337,101 @@ out:
return ret;
}
+/* Description:
+ * Opens the snap changelog to log call path fops in it.
+ * This changelos name is "CHANGELOG.SNAP", stored in
+ * path ".glusterfs/changelogs/csnap".
+ * Returns:
+ * 0 : On success.
+ * -1 : On failure.
+ */
+int
+changelog_snap_open (xlator_t *this,
+ changelog_priv_t *priv)
+{
+ int fd = -1;
+ int ret = 0;
+ int flags = 0;
+ char buffer[1024] = {0,};
+ char c_snap_path[PATH_MAX] = {0,};
+ char csnap_dir_path[PATH_MAX] = {0,};
+
+ CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir_path);
+
+ (void) snprintf (c_snap_path, PATH_MAX,
+ "%s/"CSNAP_FILE_NAME,
+ csnap_dir_path);
+
+ flags |= (O_CREAT | O_RDWR | O_TRUNC);
+
+ fd = open (c_snap_path, flags,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "unable to open %s file "
+ "reason:(%s)", c_snap_path, strerror (errno));
+ ret = -1;
+ goto out;
+ }
+ priv->c_snap_fd = fd;
+
+ (void) snprintf (buffer, 1024, CHANGELOG_HEADER,
+ CHANGELOG_VERSION_MAJOR,
+ CHANGELOG_VERSION_MINOR,
+ priv->ce->encoder);
+ ret = changelog_snap_write_change (priv, buffer, strlen (buffer));
+ if (ret < 0) {
+ close (priv->c_snap_fd);
+ priv->c_snap_fd = -1;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+/*
+ * Description:
+ * Starts logging fop details in CSNAP journal.
+ * Returns:
+ * 0 : On success.
+ * -1 : On Failure.
+ */
+int
+changelog_snap_logging_start (xlator_t *this,
+ changelog_priv_t *priv)
+{
+ int ret = 0;
+
+ ret = changelog_snap_open (this, priv);
+ gf_log (this->name, GF_LOG_INFO,
+ "Now starting to log in call path");
+
+ return ret;
+}
+
+/*
+ * Description:
+ * Stops logging fop details in CSNAP journal.
+ * Returns:
+ * 0 : On success.
+ * -1 : On Failure.
+ */
+int
+changelog_snap_logging_stop (xlator_t *this,
+ changelog_priv_t *priv)
+{
+ int ret = 0;
+
+ close (priv->c_snap_fd);
+ priv->c_snap_fd = -1;
+
+ gf_log (this->name, GF_LOG_INFO,
+ "Stopped to log in call path");
+
+ return ret;
+}
+
int
changelog_open (xlator_t *this,
changelog_priv_t *priv)
@@ -424,11 +519,72 @@ changelog_fill_rollover_data (changelog_log_data_t *cld, gf_boolean_t is_last)
}
int
+changelog_snap_write_change (changelog_priv_t *priv, char *buffer, size_t len)
+{
+ return changelog_write (priv->c_snap_fd, buffer, len);
+}
+
+int
changelog_write_change (changelog_priv_t *priv, char *buffer, size_t len)
{
return changelog_write (priv->changelog_fd, buffer, len);
}
+/*
+ * Descriptions:
+ * Writes fop details in ascii format to CSNAP.
+ * Issues:
+ * Not Encoding agnostic.
+ * Returns:
+ * 0 : On Success.
+ * -1 : On Failure.
+ */
+int
+changelog_snap_handle_ascii_change (xlator_t *this,
+ changelog_log_data_t *cld)
+{
+ size_t off = 0;
+ size_t gfid_len = 0;
+ char *gfid_str = NULL;
+ char *buffer = NULL;
+ changelog_priv_t *priv = NULL;
+ int ret = 0;
+
+ if (this == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ priv = this->private;
+
+ if (priv == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ gfid_str = uuid_utoa (cld->cld_gfid);
+ gfid_len = strlen (gfid_str);
+
+ /* extra bytes for decorations */
+ buffer = alloca (gfid_len + cld->cld_ptr_len + 10);
+ CHANGELOG_STORE_ASCII (priv, buffer,
+ off, gfid_str, gfid_len, cld);
+
+ CHANGELOG_FILL_BUFFER (buffer, off, "\0", 1);
+
+ ret = changelog_snap_write_change (priv, buffer, off);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error writing csnap to disk");
+ }
+ gf_log (this->name, GF_LOG_INFO,
+ "Successfully wrote to csnap");
+ ret = 0;
+out:
+ return ret;
+}
+
inline int
changelog_handle_change (xlator_t *this,
changelog_priv_t *priv, changelog_log_data_t *cld)
diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h
index 87888fb8c4f..9bd4a3ff37c 100644
--- a/xlators/features/changelog/src/changelog-helpers.h
+++ b/xlators/features/changelog/src/changelog-helpers.h
@@ -212,11 +212,17 @@ struct changelog_priv {
/* htime fd for current changelog session */
int htime_fd;
+ /* c_snap_fd is fd for call-path changelog */
+ int c_snap_fd;
+
/* rollover_count used by htime */
int rollover_count;
gf_lock_t lock;
+ /* lock to synchronize CSNAP updation */
+ gf_lock_t c_snap_lock;
+
/* writen end of the pipe */
int wfd;
@@ -431,6 +437,18 @@ changelog_drain_white_fops (xlator_t *this, changelog_priv_t *priv);
void
changelog_drain_black_fops (xlator_t *this, changelog_priv_t *priv);
+/* Crash consistency of changelog wrt snapshot */
+int
+changelog_snap_logging_stop ( xlator_t *this, changelog_priv_t *priv);
+int
+changelog_snap_logging_start ( xlator_t *this, changelog_priv_t *priv);
+int
+changelog_snap_open ( xlator_t *this, changelog_priv_t *priv);
+int
+changelog_snap_handle_ascii_change (xlator_t *this,
+ changelog_log_data_t *cld);
+int
+changelog_snap_write_change (changelog_priv_t *priv, char *buffer, size_t len);
/* Changelog barrier routines */
void __chlog_barrier_enqueue (xlator_t *this, call_stub_t *stub);
void __chlog_barrier_disable (xlator_t *this, struct list_head *queue);
diff --git a/xlators/features/changelog/src/changelog-misc.h b/xlators/features/changelog/src/changelog-misc.h
index 257c1f34218..58b10961463 100644
--- a/xlators/features/changelog/src/changelog-misc.h
+++ b/xlators/features/changelog/src/changelog-misc.h
@@ -17,6 +17,7 @@
#define CHANGELOG_MAX_TYPE 3
#define CHANGELOG_FILE_NAME "CHANGELOG"
#define HTIME_FILE_NAME "HTIME"
+#define CSNAP_FILE_NAME "CHANGELOG.SNAP"
#define HTIME_KEY "trusted.glusterfs.htime"
#define HTIME_INITIAL_VALUE "0:0"
@@ -71,6 +72,11 @@
strcpy (path, changelog_dir); \
strcat (path, "/htime"); \
} while(0)
+
+#define CHANGELOG_FILL_CSNAP_DIR(changelog_dir, path) do { \
+ strcpy (path, changelog_dir); \
+ strcat (path, "/csnap"); \
+ } while(0)
/**
* everything after 'CHANGELOG_TYPE_ENTRY' are internal types
* (ie. none of the fops trigger this type of event), hence
diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c
index 36643395815..75a62d686d6 100644
--- a/xlators/features/changelog/src/changelog.c
+++ b/xlators/features/changelog/src/changelog.c
@@ -1433,6 +1433,16 @@ changelog_truncate (call_frame_t *frame,
CHANGELOG_INIT (this, frame->local,
loc->inode, loc->inode->gfid, 0);
+ LOCK(&priv->c_snap_lock);
+ {
+ if (priv->c_snap_fd != -1 &&
+ priv->barrier_enabled == _gf_true) {
+ changelog_snap_handle_ascii_change (this,
+ &( ((changelog_local_t *)(frame->local))->cld));
+ }
+ }
+ UNLOCK(&priv->c_snap_lock);
+
wind:
changelog_color_fop_and_inc_cnt (this, priv, frame->local);
@@ -1476,6 +1486,15 @@ changelog_ftruncate (call_frame_t *frame,
CHANGELOG_INIT (this, frame->local,
fd->inode, fd->inode->gfid, 0);
+ LOCK(&priv->c_snap_lock);
+ {
+ if (priv->c_snap_fd != -1 &&
+ priv->barrier_enabled == _gf_true) {
+ changelog_snap_handle_ascii_change (this,
+ &( ((changelog_local_t *)(frame->local))->cld));
+ }
+ }
+ UNLOCK(&priv->c_snap_lock);
wind:
changelog_color_fop_and_inc_cnt (this, priv, frame->local);
@@ -1523,6 +1542,15 @@ changelog_writev (call_frame_t *frame,
CHANGELOG_INIT (this, frame->local,
fd->inode, fd->inode->gfid, 0);
+ LOCK(&priv->c_snap_lock);
+ {
+ if (priv->c_snap_fd != -1 &&
+ priv->barrier_enabled == _gf_true) {
+ changelog_snap_handle_ascii_change (this,
+ &( ((changelog_local_t *)(frame->local))->cld));
+ }
+ }
+ UNLOCK(&priv->c_snap_lock);
wind:
changelog_color_fop_and_inc_cnt (this, priv, frame->local);
@@ -1751,6 +1779,11 @@ notify (xlator_t *this, int event, void *data, ...)
"Barrier off notification");
CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out);
+ LOCK(&priv->c_snap_lock);
+ {
+ changelog_snap_logging_stop (this, priv);
+ }
+ UNLOCK(&priv->c_snap_lock);
LOCK (&priv->bflags.lock);
{
@@ -1800,6 +1833,11 @@ notify (xlator_t *this, int event, void *data, ...)
"Barrier on notification");
CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out);
+ LOCK(&priv->c_snap_lock);
+ {
+ changelog_snap_logging_start (this, priv);
+ }
+ UNLOCK(&priv->c_snap_lock);
LOCK (&priv->bflags.lock);
{
@@ -2080,6 +2118,7 @@ reconfigure (xlator_t *this, dict_t *options)
changelog_time_slice_t *slice = NULL;
changelog_log_data_t cld = {0,};
char htime_dir[PATH_MAX] = {0,};
+ char csnap_dir[PATH_MAX] = {0,};
struct timeval tv = {0,};
uint32_t timeout = 0;
@@ -2115,6 +2154,12 @@ reconfigure (xlator_t *this, dict_t *options)
if (ret)
goto out;
+ CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir);
+ ret = mkdir_p (csnap_dir, 0600, _gf_true);
+
+ if (ret)
+ goto out;
+
GF_OPTION_RECONF ("changelog", active_now, options, bool, out);
/**
@@ -2197,6 +2242,7 @@ init (xlator_t *this)
changelog_priv_t *priv = NULL;
gf_boolean_t cond_lock_init = _gf_false;
char htime_dir[PATH_MAX] = {0,};
+ char csnap_dir[PATH_MAX] = {0,};
uint32_t timeout = 0;
GF_VALIDATE_OR_GOTO ("changelog", this, out);
@@ -2225,6 +2271,7 @@ init (xlator_t *this)
}
LOCK_INIT (&priv->lock);
+ LOCK_INIT (&priv->c_snap_lock);
GF_OPTION_INIT ("changelog-brick", tmp, str, out);
if (!tmp) {
@@ -2264,6 +2311,11 @@ init (xlator_t *this)
if (ret)
goto out;
+ CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir);
+ ret = mkdir_p (csnap_dir, 0600, _gf_true);
+ if (ret)
+ goto out;
+
GF_OPTION_INIT ("changelog", priv->active, bool, out);
GF_OPTION_INIT ("op-mode", tmp, str, out);