Blob Blame History Raw
From 14bdd09e76c966616ba31db938d7309f49e6abc7 Mon Sep 17 00:00:00 2001
From: Kotresh HR <khiremat@redhat.com>
Date: Tue, 17 Jan 2017 06:39:25 -0500
Subject: [PATCH 273/275] features/changelog: Fix htime xattr during brick
 crash

The htime file contains the path of all the changelogs
that is rolloved over till now. It also maintains xattr
which tracks the latest changelog file rolloved over
and the number of changelogs. The path and and xattr
update happens in two different system calls. If the
brick is crashed between them, the xattr value becomes
stale and can lead to the failure of gf_history_changelog.
To identify this, the total number of changelogs is being
calculated based on htime file size and the record
length. The above value is used in case of mismatch.

> Change-Id: Ia1c3efcfda7b74227805bb2eb933c9bd4305000b
> BUG: 1413967
> Signed-off-by: Kotresh HR <khiremat@redhat.com>
> Reviewed-on: http://review.gluster.org/16420
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
> Smoke: Gluster Build System <jenkins@build.gluster.org>
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
> Reviewed-by: Aravinda VK <avishwan@redhat.com>

Change-Id: Ia1c3efcfda7b74227805bb2eb933c9bd4305000b
BUG: 1412883
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/95836
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 xlators/features/changelog/src/changelog-helpers.c | 31 +++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c
index 0cb6858..5c47f5e 100644
--- a/xlators/features/changelog/src/changelog-helpers.c
+++ b/xlators/features/changelog/src/changelog-helpers.c
@@ -620,7 +620,10 @@ htime_open (xlator_t *this,
         unsigned long min_ts            = 0;
         unsigned long max_ts            = 0;
         unsigned long total             = 0;
+        unsigned long total1            = 0;
         ssize_t size                    = 0;
+        struct stat stat_buf            = {0,};
+        unsigned long record_len        = 0;
 
         CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, ht_dir_path);
 
@@ -681,6 +684,16 @@ htime_open (xlator_t *this,
         /* save this htime_fd in priv->htime_fd */
         priv->htime_fd = ht_file_fd;
 
+        ret = sys_fstat (ht_file_fd, &stat_buf);
+        if (ret < 0) {
+                gf_msg (this->name, GF_LOG_ERROR, errno,
+                        CHANGELOG_MSG_HTIME_ERROR,
+                        "unable to stat htime file: %s",
+                        ht_file_path);
+                ret = -1;
+                goto out;
+        }
+
         /* Initialize rollover-number in priv to current number */
         size = sys_fgetxattr (ht_file_fd, HTIME_KEY, x_value, sizeof (x_value));
         if (size < 0) {
@@ -693,11 +706,27 @@ htime_open (xlator_t *this,
         }
 
         sscanf (x_value, "%lu:%lu", &max_ts, &total);
+
+        /* 22 = 1(/) + 20(CHANGELOG.TIMESTAMP) + 1(\x00) */
+        record_len = strlen(priv->changelog_dir) + 22;
+        total1 = stat_buf.st_size/record_len;
+        if (total != total1) {
+                gf_msg (this->name, GF_LOG_INFO, 0,
+                        CHANGELOG_MSG_TOTAL_LOG_INFO,
+                        "Mismatch of changelog count. "
+                        "INIT CASE: XATTR TOTAL: %lu, SIZE TOTAL: %lu",
+                        total, total1);
+        }
+
         gf_msg (this->name, GF_LOG_INFO, 0,
                 CHANGELOG_MSG_TOTAL_LOG_INFO,
                 "INIT CASE: MIN: %lu, MAX: %lu,"
                 " TOTAL CHANGELOGS: %lu", min_ts, max_ts, total);
-        priv->rollover_count = total + 1;
+
+        if (total < total1)
+                priv->rollover_count = total1 + 1;
+        else
+                priv->rollover_count = total + 1;
 
 out:
         if (ht_dir_fd != -1)
-- 
2.9.3