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