3604df
From 14bdd09e76c966616ba31db938d7309f49e6abc7 Mon Sep 17 00:00:00 2001
3604df
From: Kotresh HR <khiremat@redhat.com>
3604df
Date: Tue, 17 Jan 2017 06:39:25 -0500
3604df
Subject: [PATCH 273/275] features/changelog: Fix htime xattr during brick
3604df
 crash
3604df
3604df
The htime file contains the path of all the changelogs
3604df
that is rolloved over till now. It also maintains xattr
3604df
which tracks the latest changelog file rolloved over
3604df
and the number of changelogs. The path and and xattr
3604df
update happens in two different system calls. If the
3604df
brick is crashed between them, the xattr value becomes
3604df
stale and can lead to the failure of gf_history_changelog.
3604df
To identify this, the total number of changelogs is being
3604df
calculated based on htime file size and the record
3604df
length. The above value is used in case of mismatch.
3604df
3604df
> Change-Id: Ia1c3efcfda7b74227805bb2eb933c9bd4305000b
3604df
> BUG: 1413967
3604df
> Signed-off-by: Kotresh HR <khiremat@redhat.com>
3604df
> Reviewed-on: http://review.gluster.org/16420
3604df
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
> Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
> Reviewed-by: Aravinda VK <avishwan@redhat.com>
3604df
3604df
Change-Id: Ia1c3efcfda7b74227805bb2eb933c9bd4305000b
3604df
BUG: 1412883
3604df
Signed-off-by: Kotresh HR <khiremat@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/95836
3604df
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
3604df
---
3604df
 xlators/features/changelog/src/changelog-helpers.c | 31 +++++++++++++++++++++-
3604df
 1 file changed, 30 insertions(+), 1 deletion(-)
3604df
3604df
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c
3604df
index 0cb6858..5c47f5e 100644
3604df
--- a/xlators/features/changelog/src/changelog-helpers.c
3604df
+++ b/xlators/features/changelog/src/changelog-helpers.c
3604df
@@ -620,7 +620,10 @@ htime_open (xlator_t *this,
3604df
         unsigned long min_ts            = 0;
3604df
         unsigned long max_ts            = 0;
3604df
         unsigned long total             = 0;
3604df
+        unsigned long total1            = 0;
3604df
         ssize_t size                    = 0;
3604df
+        struct stat stat_buf            = {0,};
3604df
+        unsigned long record_len        = 0;
3604df
 
3604df
         CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, ht_dir_path);
3604df
 
3604df
@@ -681,6 +684,16 @@ htime_open (xlator_t *this,
3604df
         /* save this htime_fd in priv->htime_fd */
3604df
         priv->htime_fd = ht_file_fd;
3604df
 
3604df
+        ret = sys_fstat (ht_file_fd, &stat_buf);
3604df
+        if (ret < 0) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, errno,
3604df
+                        CHANGELOG_MSG_HTIME_ERROR,
3604df
+                        "unable to stat htime file: %s",
3604df
+                        ht_file_path);
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
         /* Initialize rollover-number in priv to current number */
3604df
         size = sys_fgetxattr (ht_file_fd, HTIME_KEY, x_value, sizeof (x_value));
3604df
         if (size < 0) {
3604df
@@ -693,11 +706,27 @@ htime_open (xlator_t *this,
3604df
         }
3604df
 
3604df
         sscanf (x_value, "%lu:%lu", &max_ts, &total);
3604df
+
3604df
+        /* 22 = 1(/) + 20(CHANGELOG.TIMESTAMP) + 1(\x00) */
3604df
+        record_len = strlen(priv->changelog_dir) + 22;
3604df
+        total1 = stat_buf.st_size/record_len;
3604df
+        if (total != total1) {
3604df
+                gf_msg (this->name, GF_LOG_INFO, 0,
3604df
+                        CHANGELOG_MSG_TOTAL_LOG_INFO,
3604df
+                        "Mismatch of changelog count. "
3604df
+                        "INIT CASE: XATTR TOTAL: %lu, SIZE TOTAL: %lu",
3604df
+                        total, total1);
3604df
+        }
3604df
+
3604df
         gf_msg (this->name, GF_LOG_INFO, 0,
3604df
                 CHANGELOG_MSG_TOTAL_LOG_INFO,
3604df
                 "INIT CASE: MIN: %lu, MAX: %lu,"
3604df
                 " TOTAL CHANGELOGS: %lu", min_ts, max_ts, total);
3604df
-        priv->rollover_count = total + 1;
3604df
+
3604df
+        if (total < total1)
3604df
+                priv->rollover_count = total1 + 1;
3604df
+        else
3604df
+                priv->rollover_count = total + 1;
3604df
 
3604df
 out:
3604df
         if (ht_dir_fd != -1)
3604df
-- 
3604df
2.9.3
3604df