17b94a
From 80eef2f52bb92ed740ac00eeb11ee7a3e7fffff2 Mon Sep 17 00:00:00 2001
17b94a
From: Raghavendra Bhat <raghavendra@redhat.com>
17b94a
Date: Mon, 11 Mar 2019 12:16:50 -0400
17b94a
Subject: [PATCH 459/465] features/bit-rot: Unconditionally sign the files
17b94a
 during oneshot crawl
17b94a
17b94a
Currently bit-rot feature has an issue with disabling and reenabling it
17b94a
on the same volume. Consider enabling bit-rot detection which goes on to
17b94a
crawl and sign all the files present in the volume. Then some files are
17b94a
modified and the bit-rot daemon goes on to sign the modified files with
17b94a
the correct signature. Now, disable bit-rot feature. While, signing and
17b94a
scrubbing are not happening, previous checksums of the files continue to
17b94a
exist as extended attributes. Now, if some files with checksum xattrs get
17b94a
modified, they are not signed with new signature as the feature is off.
17b94a
17b94a
At this point, if the feature is enabled again, the bit rot daemon will
17b94a
go and sign those files which does not have any bit-rot specific xattrs
17b94a
(i.e. those files which were created after bit-rot was disabled). Whereas
17b94a
the files with bit-rot xattrs wont get signed with proper new checksum.
17b94a
At this point if scrubber runs, it finds the on disk checksum and the actual
17b94a
checksum of the file to be different (because the file got modified) and
17b94a
marks the file as corrupted.
17b94a
17b94a
FIX:
17b94a
17b94a
The fix is to unconditionally sign the files when the bit-rot daemon
17b94a
comes up (instead of skipping the files with bit-rot xattrs).
17b94a
17b94a
upstream fix:
17b94a
	> patch: https://review.gluster.org/#/c/glusterfs/+/22360/
17b94a
	> fixes: #bz1700078
17b94a
	> Change-ID: Iadfb47dd39f7e2e77f22d549a4a07a385284f4f5
17b94a
17b94a
Change-Id: Iadfb47dd39f7e2e77f22d549a4a07a385284f4f5
17b94a
BUG: 1851424
17b94a
Signed-off-by: Raghavendra M <raghavendra@redhat.com>
17b94a
Reviewed-on: https://code.engineering.redhat.com/gerrit/208305
17b94a
Tested-by: RHGS Build Bot <nigelb@redhat.com>
17b94a
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
17b94a
---
17b94a
 tests/bitrot/bug-1700078.t                  | 87 +++++++++++++++++++++++++++++
17b94a
 xlators/features/bit-rot/src/bitd/bit-rot.c | 15 ++++-
17b94a
 2 files changed, 101 insertions(+), 1 deletion(-)
17b94a
 create mode 100644 tests/bitrot/bug-1700078.t
17b94a
17b94a
diff --git a/tests/bitrot/bug-1700078.t b/tests/bitrot/bug-1700078.t
17b94a
new file mode 100644
17b94a
index 0000000..f273742
17b94a
--- /dev/null
17b94a
+++ b/tests/bitrot/bug-1700078.t
17b94a
@@ -0,0 +1,87 @@
17b94a
+#!/bin/bash
17b94a
+
17b94a
+. $(dirname $0)/../include.rc
17b94a
+. $(dirname $0)/../volume.rc
17b94a
+
17b94a
+cleanup;
17b94a
+
17b94a
+## Start glusterd
17b94a
+TEST glusterd;
17b94a
+TEST pidof glusterd;
17b94a
+
17b94a
+## Lets create and start the volume
17b94a
+TEST $CLI volume create $V0 $H0:$B0/${V0}1
17b94a
+TEST $CLI volume start $V0
17b94a
+
17b94a
+## Enable bitrot for volume $V0
17b94a
+TEST $CLI volume bitrot $V0 enable
17b94a
+
17b94a
+## Turn off quick-read so that it wont cache the contents
17b94a
+# of the file in lookup. For corrupted files, it might
17b94a
+# end up in reads being served from the cache instead of
17b94a
+# an error.
17b94a
+TEST $CLI volume set $V0 performance.quick-read off
17b94a
+
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count
17b94a
+
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'Active' scrub_status $V0 'State of scrub'
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/bitd.log' scrub_status $V0 'Bitrot error log location'
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/scrub.log' scrub_status $V0 'Scrubber error log location'
17b94a
+
17b94a
+## Set expiry-timeout to 1 sec
17b94a
+TEST $CLI volume set $V0 features.expiry-time 1
17b94a
+
17b94a
+##Mount $V0
17b94a
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0
17b94a
+
17b94a
+## Turn off quick-read xlator so that, the contents are not served from the
17b94a
+# quick-read cache.
17b94a
+TEST $CLI volume set $V0 performance.quick-read off
17b94a
+
17b94a
+#Create sample file
17b94a
+TEST `echo "1234" > $M0/FILE1`
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'trusted.bit-rot.signature' check_for_xattr 'trusted.bit-rot.signature' "/$B0/${V0}1/FILE1"
17b94a
+
17b94a
+##disable bitrot
17b94a
+TEST $CLI volume bitrot $V0 disable
17b94a
+
17b94a
+## modify the file
17b94a
+TEST `echo "write" >> $M0/FILE1`
17b94a
+
17b94a
+# unmount and remount when the file has to be accessed.
17b94a
+# This is to ensure that, when the remount happens,
17b94a
+# and the file is read, its contents are served from the
17b94a
+# brick instead of cache.
17b94a
+EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0
17b94a
+
17b94a
+##enable bitrot
17b94a
+TEST $CLI volume bitrot $V0 enable
17b94a
+
17b94a
+# expiry time is set to 1 second. Hence sleep for 2 seconds for the
17b94a
+# oneshot crawler to finish its crawling and sign the file properly.
17b94a
+sleep 2
17b94a
+
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count
17b94a
+
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'Active' scrub_status $V0 'State of scrub'
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/bitd.log' scrub_status $V0 'Bitrot error log location'
17b94a
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/scrub.log' scrub_status $V0 'Scrubber error log location'
17b94a
+
17b94a
+## Ondemand scrub
17b94a
+TEST $CLI volume bitrot $V0 scrub ondemand
17b94a
+
17b94a
+# the scrub ondemand CLI command, just ensures that
17b94a
+# the scrubber has received the ondemand scrub directive
17b94a
+# and started. sleep for 2 seconds for scrubber to finish
17b94a
+# crawling and marking file(s) as bad (if if finds that
17b94a
+# corruption has happened) which are filesystem operations.
17b94a
+sleep 2
17b94a
+
17b94a
+TEST ! getfattr -n 'trusted.bit-rot.bad-file' $B0/${V0}1/FILE1
17b94a
+
17b94a
+##Mount $V0
17b94a
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0
17b94a
+
17b94a
+TEST cat $M0/FILE1
17b94a
+
17b94a
+cleanup;
17b94a
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c
17b94a
index b8feef7..424c0d5 100644
17b94a
--- a/xlators/features/bit-rot/src/bitd/bit-rot.c
17b94a
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.c
17b94a
@@ -973,6 +973,7 @@ bitd_oneshot_crawl(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
17b94a
     int32_t ret = -1;
17b94a
     inode_t *linked_inode = NULL;
17b94a
     gf_boolean_t need_signing = _gf_false;
17b94a
+    gf_boolean_t need_reopen = _gf_true;
17b94a
 
17b94a
     GF_VALIDATE_OR_GOTO("bit-rot", subvol, out);
17b94a
     GF_VALIDATE_OR_GOTO("bit-rot", data, out);
17b94a
@@ -1046,6 +1047,18 @@ bitd_oneshot_crawl(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
17b94a
                    uuid_utoa(linked_inode->gfid));
17b94a
     } else {
17b94a
         need_signing = br_check_object_need_sign(this, xattr, child);
17b94a
+
17b94a
+        /*
17b94a
+         * If we are here means, bitrot daemon has started. Is it just
17b94a
+         * a simple restart of the daemon or is it started because the
17b94a
+         * feature is enabled is something hard to determine. Hence,
17b94a
+         * if need_signing is false (because bit-rot version and signature
17b94a
+         * are present), then still go ahead and sign it.
17b94a
+         */
17b94a
+        if (!need_signing) {
17b94a
+            need_signing = _gf_true;
17b94a
+            need_reopen = _gf_true;
17b94a
+        }
17b94a
     }
17b94a
 
17b94a
     if (!need_signing)
17b94a
@@ -1054,7 +1067,7 @@ bitd_oneshot_crawl(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
17b94a
     gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_TRIGGER_SIGN,
17b94a
            "Triggering signing for %s [GFID: %s | Brick: %s]", loc.path,
17b94a
            uuid_utoa(linked_inode->gfid), child->brick_path);
17b94a
-    br_trigger_sign(this, child, linked_inode, &loc, _gf_true);
17b94a
+    br_trigger_sign(this, child, linked_inode, &loc, need_reopen);
17b94a
 
17b94a
     ret = 0;
17b94a
 
17b94a
-- 
17b94a
1.8.3.1
17b94a