e3c68b
From 06adac5dbac7b2067232270cbee12931400f7824 Mon Sep 17 00:00:00 2001
e3c68b
From: Hari Gowtham <hgowtham@redhat.com>
e3c68b
Date: Sat, 6 Apr 2019 17:00:47 +0530
e3c68b
Subject: [PATCH 086/124] Revert "tiering: remove the translator from build and
e3c68b
 glusterd"
e3c68b
e3c68b
This reverts commit 55a6ba56bea9ec0d3316c005300c514ea3ab0e54.
e3c68b
Add the test files and glusterd related changes.
e3c68b
e3c68b
Label: DOWNSTREAM ONLY
e3c68b
e3c68b
Change-Id: Ib704b7142a82cb1e94538a48af916730992a5701
e3c68b
Signed-off-by: Hari Gowtham <hgowtham@redhat.com>
e3c68b
Reviewed-on: https://code.engineering.redhat.com/gerrit/166246
e3c68b
Reviewed-by: Sanju Rakonde <srakonde@redhat.com>
e3c68b
Reviewed-by: Nithya Balachandran <nbalacha@redhat.com>
e3c68b
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e3c68b
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
e3c68b
---
e3c68b
 MAINTAINERS                                        |  18 +
e3c68b
 tests/basic/afr/granular-esh/cli.t                 |  30 +-
e3c68b
 ...1214222-directories_missing_after_attach_tier.t |  61 ++
e3c68b
 ...60185-donot-allow-detach-commit-unnecessarily.t |  47 ++
e3c68b
 tests/basic/tier/ctr-rename-overwrite.t            |  50 ++
e3c68b
 tests/basic/tier/file_lock.c                       |  72 ++
e3c68b
 tests/basic/tier/file_with_spaces.t                |  71 ++
e3c68b
 tests/basic/tier/fops-during-migration-pause.t     |  89 +++
e3c68b
 tests/basic/tier/fops-during-migration.t           | 105 +++
e3c68b
 tests/basic/tier/frequency-counters.t              |  82 +++
e3c68b
 tests/basic/tier/legacy-many.t                     |  92 +++
e3c68b
 tests/basic/tier/locked_file_migration.t           |  80 +++
e3c68b
 tests/basic/tier/new-tier-cmds.t                   | 129 ++++
e3c68b
 tests/basic/tier/readdir-during-migration.t        |  65 ++
e3c68b
 tests/basic/tier/record-metadata-heat.t            | 106 +++
e3c68b
 tests/basic/tier/tier-heald.t                      |  98 +++
e3c68b
 tests/basic/tier/tier-snapshot.t                   |  47 ++
e3c68b
 tests/basic/tier/tier.t                            | 219 +++++++
e3c68b
 tests/basic/tier/tier_lookup_heal.t                |  69 ++
e3c68b
 tests/basic/tier/tierd_check.t                     | 128 ++++
e3c68b
 tests/basic/tier/unlink-during-migration.t         |  92 +++
e3c68b
 ...03028-Rebalance-glusterd-rpc-connection-issue.t |  78 +++
e3c68b
 tests/bugs/quota/bug-1288474.t                     |  51 ++
e3c68b
 .../bug-1290965-detect-bitrotten-objects.t         |  53 ++
e3c68b
 .../tier/bug-1205545-CTR-and-trash-integration.t   |  72 ++
e3c68b
 tests/bugs/tier/bug-1279376-rename-demoted-file.t  |  93 +++
e3c68b
 xlators/mgmt/glusterd/src/glusterd-volgen.c        |  75 +++
e3c68b
 xlators/mgmt/glusterd/src/glusterd-volume-set.c    | 723 +++++++++++++++++++++
e3c68b
 28 files changed, 2894 insertions(+), 1 deletion(-)
e3c68b
 create mode 100755 tests/basic/tier/bug-1214222-directories_missing_after_attach_tier.t
e3c68b
 create mode 100644 tests/basic/tier/bug-1260185-donot-allow-detach-commit-unnecessarily.t
e3c68b
 create mode 100755 tests/basic/tier/ctr-rename-overwrite.t
e3c68b
 create mode 100644 tests/basic/tier/file_lock.c
e3c68b
 create mode 100755 tests/basic/tier/file_with_spaces.t
e3c68b
 create mode 100755 tests/basic/tier/fops-during-migration-pause.t
e3c68b
 create mode 100755 tests/basic/tier/fops-during-migration.t
e3c68b
 create mode 100644 tests/basic/tier/frequency-counters.t
e3c68b
 create mode 100644 tests/basic/tier/legacy-many.t
e3c68b
 create mode 100755 tests/basic/tier/locked_file_migration.t
e3c68b
 create mode 100644 tests/basic/tier/new-tier-cmds.t
e3c68b
 create mode 100644 tests/basic/tier/readdir-during-migration.t
e3c68b
 create mode 100755 tests/basic/tier/record-metadata-heat.t
e3c68b
 create mode 100644 tests/basic/tier/tier-heald.t
e3c68b
 create mode 100644 tests/basic/tier/tier-snapshot.t
e3c68b
 create mode 100755 tests/basic/tier/tier.t
e3c68b
 create mode 100755 tests/basic/tier/tier_lookup_heal.t
e3c68b
 create mode 100644 tests/basic/tier/tierd_check.t
e3c68b
 create mode 100755 tests/basic/tier/unlink-during-migration.t
e3c68b
 create mode 100644 tests/bugs/glusterd/bug-1303028-Rebalance-glusterd-rpc-connection-issue.t
e3c68b
 create mode 100755 tests/bugs/quota/bug-1288474.t
e3c68b
 create mode 100644 tests/bugs/replicate/bug-1290965-detect-bitrotten-objects.t
e3c68b
 create mode 100644 tests/bugs/tier/bug-1205545-CTR-and-trash-integration.t
e3c68b
 create mode 100755 tests/bugs/tier/bug-1279376-rename-demoted-file.t
e3c68b
e3c68b
diff --git a/MAINTAINERS b/MAINTAINERS
e3c68b
index b1fc0ee..1f4c93a 100644
e3c68b
--- a/MAINTAINERS
e3c68b
+++ b/MAINTAINERS
e3c68b
@@ -103,6 +103,12 @@ P: Kotresh HR <khiremat@redhat.com>
e3c68b
 S: Maintained
e3c68b
 F: xlators/features/changelog/
e3c68b
 
e3c68b
+Changetimerecorder
e3c68b
+M: Shyamsundar Ranganathan <srangana@redhat.com>
e3c68b
+P: Hari Gowtham <hgowtham@redhat.com>
e3c68b
+S: Maintained
e3c68b
+F: xlators/features/changetimerecorder/
e3c68b
+
e3c68b
 Decompounder
e3c68b
 M: Krutika Dhananjay <kdhananj@redhat.com>
e3c68b
 P: Pranith Karampuri <pkarampu@redhat.com>
e3c68b
@@ -248,6 +254,12 @@ P: Xavier Hernandez  <xhernandez@redhat.com>
e3c68b
 S: Maintained
e3c68b
 F: xlators/features/shard/
e3c68b
 
e3c68b
+Tiering
e3c68b
+M: Shyamsundar Ranganathan <srangana@redhat.com>
e3c68b
+P: Hari Gowtham <hgowtham@redhat.com>
e3c68b
+S: Maintained
e3c68b
+F: xlators/cluster/dht/src/tier.c
e3c68b
+
e3c68b
 Trash
e3c68b
 M: Anoop C S <anoopcs@redhat.com>
e3c68b
 M: Jiffin Tony Thottan <jthottan@redhat.com>
e3c68b
@@ -327,6 +339,12 @@ P: Soumya Koduri <skoduri@redhat.com>
e3c68b
 S: Maintained
e3c68b
 F: api/
e3c68b
 
e3c68b
+libgfdb
e3c68b
+M: Shyamsundar Ranganathan <srangana@redhat.com>
e3c68b
+P: Hari Gowtham <hgowtham@redhat.com>
e3c68b
+S: Maintained
e3c68b
+F: libglusterfs/src/gfdb/
e3c68b
+
e3c68b
 libglusterfs
e3c68b
 M: Amar Tumballi <amarts@redhat.com>
e3c68b
 M: Jeff Darcy <jeff@pl.atyp.us>
e3c68b
diff --git a/tests/basic/afr/granular-esh/cli.t b/tests/basic/afr/granular-esh/cli.t
e3c68b
index 10b6c63..995d93e 100644
e3c68b
--- a/tests/basic/afr/granular-esh/cli.t
e3c68b
+++ b/tests/basic/afr/granular-esh/cli.t
e3c68b
@@ -11,7 +11,7 @@ TESTS_EXPECTED_IN_LOOP=4
e3c68b
 TEST glusterd
e3c68b
 TEST pidof glusterd
e3c68b
 
e3c68b
-TEST   $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2}
e3c68b
+TEST   $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1}
e3c68b
 # Test that enabling the option should work on a newly created volume
e3c68b
 TEST   $CLI volume set $V0 cluster.granular-entry-heal on
e3c68b
 TEST   $CLI volume set $V0 cluster.granular-entry-heal off
e3c68b
@@ -25,6 +25,34 @@ TEST $CLI volume start $V1
e3c68b
 TEST ! $CLI volume heal $V1 granular-entry-heal enable
e3c68b
 TEST ! $CLI volume heal $V1 granular-entry-heal disable
e3c68b
 
e3c68b
+#######################
e3c68b
+###### TIER TEST ######
e3c68b
+#######################
e3c68b
+# Execute the same command on a disperse + replicate tiered volume and make
e3c68b
+# sure the option is set on the replicate leg of the volume
e3c68b
+TEST $CLI volume tier $V1 attach replica 2 $H0:$B0/${V1}{3,4}
e3c68b
+TEST $CLI volume heal $V1 granular-entry-heal enable
e3c68b
+EXPECT "enable" volume_get_field $V1 cluster.granular-entry-heal
e3c68b
+TEST $CLI volume heal $V1 granular-entry-heal disable
e3c68b
+EXPECT "disable" volume_get_field $V1 cluster.granular-entry-heal
e3c68b
+
e3c68b
+# Kill a disperse brick and make heal be pending on the volume.
e3c68b
+TEST kill_brick $V1 $H0 $B0/${V1}0
e3c68b
+
e3c68b
+# Now make sure that one offline brick in disperse does not affect enabling the
e3c68b
+# option on the volume.
e3c68b
+TEST $CLI volume heal $V1 granular-entry-heal enable
e3c68b
+EXPECT "enable" volume_get_field $V1 cluster.granular-entry-heal
e3c68b
+TEST $CLI volume heal $V1 granular-entry-heal disable
e3c68b
+EXPECT "disable" volume_get_field $V1 cluster.granular-entry-heal
e3c68b
+
e3c68b
+# Now kill a replicate brick.
e3c68b
+TEST kill_brick $V1 $H0 $B0/${V1}3
e3c68b
+# Now make sure that one offline brick in replicate causes the command to be
e3c68b
+# failed.
e3c68b
+TEST ! $CLI volume heal $V1 granular-entry-heal enable
e3c68b
+EXPECT "disable" volume_get_field $V1 cluster.granular-entry-heal
e3c68b
+
e3c68b
 ######################
e3c68b
 ### REPLICATE TEST ###
e3c68b
 ######################
e3c68b
diff --git a/tests/basic/tier/bug-1214222-directories_missing_after_attach_tier.t b/tests/basic/tier/bug-1214222-directories_missing_after_attach_tier.t
e3c68b
new file mode 100755
e3c68b
index 0000000..f9166d7
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/bug-1214222-directories_missing_after_attach_tier.t
e3c68b
@@ -0,0 +1,61 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+LAST_BRICK=3
e3c68b
+CACHE_BRICK_FIRST=4
e3c68b
+CACHE_BRICK_LAST=5
e3c68b
+DEMOTE_TIMEOUT=12
e3c68b
+PROMOTE_TIMEOUT=5
e3c68b
+
e3c68b
+
e3c68b
+LAST_BRICK=1
e3c68b
+CACHE_BRICK=2
e3c68b
+DEMOTE_TIMEOUT=12
e3c68b
+PROMOTE_TIMEOUT=5
e3c68b
+MIGRATION_TIMEOUT=10
e3c68b
+cleanup
e3c68b
+
e3c68b
+
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..$LAST_BRICK}
e3c68b
+TEST $CLI volume start $V0
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0;
e3c68b
+
e3c68b
+# Basic operations.
e3c68b
+cd $M0
e3c68b
+TEST stat .
e3c68b
+TEST mkdir d1
e3c68b
+TEST [ -d d1 ]
e3c68b
+TEST touch file1
e3c68b
+TEST [ -e file1 ]
e3c68b
+
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST
e3c68b
+TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+
e3c68b
+#check whether the directory's and files are present on mount or not.
e3c68b
+TEST [ -d d1 ]
e3c68b
+TEST [ -e file1 ]
e3c68b
+
e3c68b
+cd
e3c68b
+EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0;
e3c68b
+
e3c68b
+tier_status ()
e3c68b
+{
e3c68b
+	$CLI volume tier $V0 detach status | grep progress | wc -l
e3c68b
+}
e3c68b
+
e3c68b
+TEST $CLI volume tier $V0 detach start
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" tier_status
e3c68b
+TEST $CLI volume tier $V0 detach commit
e3c68b
+
e3c68b
+EXPECT "0" confirm_tier_removed ${V0}${CACHE_BRICK_FIRST}
e3c68b
+
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "0" confirm_vol_stopped $V0
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=000000
e3c68b
diff --git a/tests/basic/tier/bug-1260185-donot-allow-detach-commit-unnecessarily.t b/tests/basic/tier/bug-1260185-donot-allow-detach-commit-unnecessarily.t
e3c68b
new file mode 100644
e3c68b
index 0000000..6efbe32
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/bug-1260185-donot-allow-detach-commit-unnecessarily.t
e3c68b
@@ -0,0 +1,47 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+## Test case for BZ: 1260185
e3c68b
+## Do not allow detach-tier commit without "force" option or without
e3c68b
+## user have not started "detach-tier start" operation
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../cluster.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+## Start glusterd
e3c68b
+TEST glusterd;
e3c68b
+TEST pidof glusterd;
e3c68b
+
e3c68b
+## Lets create and start the volume
e3c68b
+TEST $CLI volume create $V0 $H0:$B0/${V0}{1..2}
e3c68b
+TEST $CLI volume start $V0
e3c68b
+
e3c68b
+## Perform attach-tier operation on volume $V0
e3c68b
+TEST $CLI volume tier $V0 attach $H0:$B0/${V0}{3..4}
e3c68b
+
e3c68b
+## detach-tier commit operation without force option on volume $V0
e3c68b
+## should not succeed
e3c68b
+TEST ! $CLI --mode=script volume tier $V0 detach commit
e3c68b
+
e3c68b
+## detach-tier commit operation with force option on volume $V0
e3c68b
+## should succeed
e3c68b
+TEST  $CLI volume tier $V0 detach force
e3c68b
+
e3c68b
+sleep 3
e3c68b
+
e3c68b
+## Again performing attach-tier operation on volume $V0
e3c68b
+TEST $CLI volume tier $V0 attach $H0:$B0/${V0}{5..6}
e3c68b
+
e3c68b
+## Do detach-tier start on volume $V0
e3c68b
+TEST $CLI volume tier $V0 detach start
e3c68b
+
e3c68b
+## Now detach-tier commit on volume $V0 should succeed.
e3c68b
+## wait for the detach to complete
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" tier_detach_commit_for_single_node
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=1517961
e3c68b
diff --git a/tests/basic/tier/ctr-rename-overwrite.t b/tests/basic/tier/ctr-rename-overwrite.t
e3c68b
new file mode 100755
e3c68b
index 0000000..73ee758
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/ctr-rename-overwrite.t
e3c68b
@@ -0,0 +1,50 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+LAST_BRICK=1
e3c68b
+CACHE_BRICK_FIRST=4
e3c68b
+CACHE_BRICK_LAST=5
e3c68b
+
e3c68b
+DEMOTE_FREQ=5
e3c68b
+PROMOTE_FREQ=5
e3c68b
+
e3c68b
+cleanup
e3c68b
+
e3c68b
+# Start glusterd
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+
e3c68b
+# Set-up tier cluster
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..$LAST_BRICK}
e3c68b
+TEST $CLI volume start $V0
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST
e3c68b
+
e3c68b
+TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+
e3c68b
+# Start and mount the volume after enabling CTR
e3c68b
+TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0;
e3c68b
+
e3c68b
+# create two files
e3c68b
+echo "hello world" > $M0/file1
e3c68b
+echo "hello world" > $M0/file2
e3c68b
+
e3c68b
+# db in hot brick shows 4 record. 2 for file1 and 2 for file2
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 4 ]
e3c68b
+
e3c68b
+#overwrite file2 with file1
e3c68b
+mv -f $M0/file1 $M0/file2
e3c68b
+
e3c68b
+# Now the db in hot tier should have only 2 records for file1.
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 2 ]
e3c68b
+
e3c68b
+cleanup
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/file_lock.c b/tests/basic/tier/file_lock.c
e3c68b
new file mode 100644
e3c68b
index 0000000..20fdbc0
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/file_lock.c
e3c68b
@@ -0,0 +1,72 @@
e3c68b
+#include <stdio.h>
e3c68b
+#include <stdlib.h>
e3c68b
+#include <unistd.h>
e3c68b
+#include <fcntl.h>
e3c68b
+
e3c68b
+void
e3c68b
+usage(void)
e3c68b
+{
e3c68b
+    printf("Usage: testlock <filepath> [R|W]\n");
e3c68b
+    return;
e3c68b
+}
e3c68b
+
e3c68b
+int
e3c68b
+main(int argc, char *argv[])
e3c68b
+{
e3c68b
+    char *file_path = NULL;
e3c68b
+    int fd = -1;
e3c68b
+    struct flock lock = {0};
e3c68b
+    int ret = -1;
e3c68b
+    int c = 0;
e3c68b
+
e3c68b
+    if (argc != 3) {
e3c68b
+        usage();
e3c68b
+        exit(1);
e3c68b
+    }
e3c68b
+
e3c68b
+    file_path = argv[1];
e3c68b
+    fd = open(file_path, O_RDWR);
e3c68b
+
e3c68b
+    if (-1 == fd) {
e3c68b
+        printf("Failed to open file %s. %m\n", file_path);
e3c68b
+        exit(1);
e3c68b
+    }
e3c68b
+
e3c68b
+    /* TODO: Check for invalid input*/
e3c68b
+
e3c68b
+    if (!strcmp(argv[2], "W")) {
e3c68b
+        lock.l_type = F_WRLCK;
e3c68b
+        printf("Taking write lock\n");
e3c68b
+
e3c68b
+    } else {
e3c68b
+        lock.l_type = F_RDLCK;
e3c68b
+        printf("Taking read lock\n");
e3c68b
+    }
e3c68b
+
e3c68b
+    lock.l_whence = SEEK_SET;
e3c68b
+    lock.l_start = 0;
e3c68b
+    lock.l_len = 0;
e3c68b
+    lock.l_pid = getpid();
e3c68b
+
e3c68b
+    printf("Acquiring lock on %s\n", file_path);
e3c68b
+    ret = fcntl(fd, F_SETLK, &lock);
e3c68b
+    if (ret) {
e3c68b
+        printf("Failed to acquire lock on %s (%m)\n", file_path);
e3c68b
+        close(fd);
e3c68b
+        exit(1);
e3c68b
+    }
e3c68b
+
e3c68b
+    sleep(10);
e3c68b
+
e3c68b
+    /*Unlock*/
e3c68b
+
e3c68b
+    printf("Releasing lock on %s\n", file_path);
e3c68b
+    lock.l_type = F_UNLCK;
e3c68b
+    ret = fcntl(fd, F_SETLK, &lock);
e3c68b
+    if (ret) {
e3c68b
+        printf("Failed to release lock on %s (%m)\n", file_path);
e3c68b
+    }
e3c68b
+
e3c68b
+    close(fd);
e3c68b
+    return ret;
e3c68b
+}
e3c68b
diff --git a/tests/basic/tier/file_with_spaces.t b/tests/basic/tier/file_with_spaces.t
e3c68b
new file mode 100755
e3c68b
index 0000000..919b900
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/file_with_spaces.t
e3c68b
@@ -0,0 +1,71 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+NUM_BRICKS=3
e3c68b
+DEMOTE_FREQ=5
e3c68b
+DEMOTE_TIMEOUT=10
e3c68b
+PROMOTE_FREQ=5
e3c68b
+
e3c68b
+FILE_SPACE="Testing filenames with spaces.log"
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+TEST $CLI volume info
e3c68b
+
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+
e3c68b
+# The file will be created on the hot tier
e3c68b
+
e3c68b
+touch "$M0/$FILE_SPACE"
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+HPATH=`find $B0/hot/ -name  "$FILE_SPACE"`
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+
e3c68b
+EXPECT "yes" exists_and_regular_file $HPATH
e3c68b
+
e3c68b
+# Wait for the tier process to demote the file
e3c68b
+sleep $DEMOTE_TIMEOUT
e3c68b
+
e3c68b
+# Get the path of the file on the cold tier
e3c68b
+CPATH=`find $B0/cold/ -name  "$FILE_SPACE"`
e3c68b
+echo "File path on cold tier: "$CPATH
e3c68b
+
e3c68b
+EXPECT "yes" exists_and_regular_file $CPATH
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/fops-during-migration-pause.t b/tests/basic/tier/fops-during-migration-pause.t
e3c68b
new file mode 100755
e3c68b
index 0000000..46fc6e4
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/fops-during-migration-pause.t
e3c68b
@@ -0,0 +1,89 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+NUM_BRICKS=3
e3c68b
+DEMOTE_FREQ=10
e3c68b
+PROMOTE_FREQ=10
e3c68b
+
e3c68b
+TEST_STR="Testing write and truncate fops on tier migration"
e3c68b
+
e3c68b
+function is_sticky_set () {
e3c68b
+        echo $1
e3c68b
+        if [ -k $1 ];
e3c68b
+        then
e3c68b
+                echo "yes"
e3c68b
+        else
e3c68b
+                echo "no"
e3c68b
+        fi
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+TEST $CLI volume info
e3c68b
+
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+TEST mkdir $M0/dir1
e3c68b
+
e3c68b
+# Create a large file (800MB), so that rebalance takes time
e3c68b
+# The file will be created on the hot tier
e3c68b
+sleep_until_mid_cycle $DEMOTE_FREQ
e3c68b
+dd if=/dev/zero of=$M0/dir1/FILE1 bs=256k count=5120
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+HPATH=`find $B0/hot/ -name  FILE1`
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+
e3c68b
+
e3c68b
+# Wait for the tier process to demote the file
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "yes" is_sticky_set $HPATH
e3c68b
+
e3c68b
+TEST $CLI volume set $V0 cluster.tier-pause on
e3c68b
+
e3c68b
+# Wait for the tier process to finish migrating the file
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "no" is_sticky_set $HPATH
e3c68b
+
e3c68b
+# Get the path of the file on the cold tier
e3c68b
+CPATH=`find $B0/cold/ -name  FILE1`
e3c68b
+
e3c68b
+# make sure destination is empty
e3c68b
+TEST ! test -s $CPATH
e3c68b
+
e3c68b
+# make sure source exists and not empty
e3c68b
+TEST test -s $HPATH
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/fops-during-migration.t b/tests/basic/tier/fops-during-migration.t
e3c68b
new file mode 100755
e3c68b
index 0000000..458c01e
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/fops-during-migration.t
e3c68b
@@ -0,0 +1,105 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+NUM_BRICKS=3
e3c68b
+DEMOTE_FREQ=5
e3c68b
+PROMOTE_FREQ=5
e3c68b
+
e3c68b
+TEST_STR="Testing write and truncate fops on tier migration"
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+        TEST $CLI volume set $V0 cluster.force-migration on
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+# Checks that the contents of the file matches the input string
e3c68b
+#$1 : file_path
e3c68b
+#$2 : comparison string
e3c68b
+
e3c68b
+function check_file_content () {
e3c68b
+        contents=`cat $1`
e3c68b
+        echo $contents
e3c68b
+        if [ "$contents" = "$2" ]; then
e3c68b
+                echo "1"
e3c68b
+        else
e3c68b
+                echo "0"
e3c68b
+        fi
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+$CLI volume set $V0 diagnostics.client-log-level DEBUG
e3c68b
+
e3c68b
+TEST mkdir $M0/dir1
e3c68b
+
e3c68b
+# Create a large file (320MB), so that rebalance takes time
e3c68b
+# The file will be created on the hot tier
e3c68b
+
e3c68b
+dd if=/dev/zero of=$M0/dir1/FILE1 bs=64k count=5120
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+HPATH=`find $B0/hot/ -name  FILE1`
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+
e3c68b
+
e3c68b
+# Wait for the tier process to demote the file
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "yes" is_sticky_set $HPATH
e3c68b
+
e3c68b
+# Get the path of the file on the cold tier
e3c68b
+CPATH=`find $B0/cold/ -name  FILE1`
e3c68b
+echo "File path on cold tier: "$CPATH
e3c68b
+
e3c68b
+# Test setxattr
e3c68b
+TEST setfattr -n "user.test_xattr" -v "qwerty" $M0/dir1/FILE1
e3c68b
+
e3c68b
+# Change the file contents while it is being migrated
e3c68b
+echo $TEST_STR > $M0/dir1/FILE1
e3c68b
+
e3c68b
+# The file contents should have changed even if the file
e3c68b
+# is not done migrating
e3c68b
+EXPECT "1" check_file_content $M0/dir1/FILE1 "$TEST_STR"
e3c68b
+
e3c68b
+
e3c68b
+# Wait for the tier process to finish migrating the file
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "no" is_sticky_set $CPATH
e3c68b
+
e3c68b
+# The file contents should have changed
e3c68b
+EXPECT "1" check_file_content $M0/dir1/FILE1 "$TEST_STR"
e3c68b
+
e3c68b
+
e3c68b
+TEST getfattr -n "user.test_xattr" $M0/dir1/FILE1
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=000000
e3c68b
diff --git a/tests/basic/tier/frequency-counters.t b/tests/basic/tier/frequency-counters.t
e3c68b
new file mode 100644
e3c68b
index 0000000..08e05df
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/frequency-counters.t
e3c68b
@@ -0,0 +1,82 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+NUM_BRICKS=3
e3c68b
+DEMOTE_FREQ=10
e3c68b
+PROMOTE_FREQ=10
e3c68b
+NUM_FILES=5
e3c68b
+TEST_DIR=test
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+}
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 features.record-counters on
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 2
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 2
e3c68b
+}
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+# create some files
e3c68b
+mkdir $M0/$TEST_DIR
e3c68b
+cd $M0/${TEST_DIR}
e3c68b
+
e3c68b
+date > file1
e3c68b
+touch file2
e3c68b
+
e3c68b
+# attach tier
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+sleep_until_mid_cycle $PROMOTE_FREQ
e3c68b
+
e3c68b
+# check if promotion on single hit, should fail
e3c68b
+date >> file2
e3c68b
+cat file1
e3c68b
+drop_cache $M0
e3c68b
+sleep $PROMOTE_FREQ
e3c68b
+EXPECT "0" check_counters 0 0
e3c68b
+
e3c68b
+# check if promotion on double hit, should suceed
e3c68b
+sleep_until_mid_cycle $PROMOTE_FREQ
e3c68b
+date >> file2
e3c68b
+drop_cache $M0
e3c68b
+cat file1
e3c68b
+date >> file2
e3c68b
+drop_cache $M0
e3c68b
+cat file1
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROMOTE_FREQ "0" check_counters 2 0
e3c68b
+
e3c68b
+TEST ! $CLI volume set $V0 features.record-counters off
e3c68b
+
e3c68b
+cd /
e3c68b
+
e3c68b
+cleanup
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/legacy-many.t b/tests/basic/tier/legacy-many.t
e3c68b
new file mode 100644
e3c68b
index 0000000..5795428
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/legacy-many.t
e3c68b
@@ -0,0 +1,92 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+LAST_BRICK=3
e3c68b
+CACHE_BRICK_FIRST=4
e3c68b
+CACHE_BRICK_LAST=5
e3c68b
+DEMOTE_TIMEOUT=12
e3c68b
+PROMOTE_TIMEOUT=12
e3c68b
+MIGRATION_TIMEOUT=10
e3c68b
+DEMOTE_FREQ=60
e3c68b
+PROMOTE_FREQ=10
e3c68b
+TEST_DIR="test_files"
e3c68b
+NUM_FILES=15
e3c68b
+
e3c68b
+function read_all {
e3c68b
+    for file in *
e3c68b
+    do
e3c68b
+        cat $file
e3c68b
+    done
e3c68b
+}
e3c68b
+
e3c68b
+function tier_status () {
e3c68b
+        $CLI volume tier $V0 status | grep "success" | wc -l
e3c68b
+}
e3c68b
+
e3c68b
+cleanup
e3c68b
+
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+
e3c68b
+# Create distributed replica volume
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..$LAST_BRICK}
e3c68b
+TEST $CLI volume start $V0
e3c68b
+
e3c68b
+TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+
e3c68b
+
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0;
e3c68b
+
e3c68b
+# Create a number of "legacy" files before attaching tier
e3c68b
+mkdir $M0/${TEST_DIR}
e3c68b
+cd $M0/${TEST_DIR}
e3c68b
+TEST create_many_files file $NUM_FILES
e3c68b
+wait
e3c68b
+
e3c68b
+# Attach tier
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST
e3c68b
+
e3c68b
+TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+
e3c68b
+# wait a little for lookup heal to finish
e3c68b
+wait_for_tier_start
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" tier_status
e3c68b
+
e3c68b
+# make sure fix layout completed
e3c68b
+CPATH=$B0/${V0}0
e3c68b
+echo $CPATH > /tmp/out
e3c68b
+TEST getfattr -n "trusted.tier.fix.layout.complete" $CPATH
e3c68b
+
e3c68b
+# Read "legacy" files
e3c68b
+drop_cache $M0
e3c68b
+
e3c68b
+sleep_until_mid_cycle $DEMOTE_FREQ
e3c68b
+
e3c68b
+TEST read_all
e3c68b
+
e3c68b
+# Test to make sure files were promoted as expected
e3c68b
+sleep $PROMOTE_TIMEOUT
e3c68b
+EXPECT_WITHIN $PROMOTE_TIMEOUT "0" check_counters $NUM_FILES 0
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" detach_start $V0
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "completed" remove_brick_status_completed_field "$V0 $H0:$B0/${V0}${CACHE_BRICK_FIRST}"
e3c68b
+
e3c68b
+TEST $CLI volume tier $V0 detach commit
e3c68b
+
e3c68b
+# fix layout flag should be cleared
e3c68b
+TEST ! getfattr -n "trusted.tier.fix.layout.complete" $CPATH
e3c68b
+
e3c68b
+cd;
e3c68b
+cleanup
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/locked_file_migration.t b/tests/basic/tier/locked_file_migration.t
e3c68b
new file mode 100755
e3c68b
index 0000000..7fb1717
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/locked_file_migration.t
e3c68b
@@ -0,0 +1,80 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+NUM_BRICKS=3
e3c68b
+DEMOTE_FREQ=7
e3c68b
+PROMOTE_FREQ=30
e3c68b
+DEMOTE_TIMEOUT=15
e3c68b
+
e3c68b
+TEST_STR="Testing write and truncate fops on tier migration"
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+
e3c68b
+#We don't want promotes to happen in this test
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 10
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 10
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+TEST $CLI volume info
e3c68b
+
e3c68b
+
e3c68b
+# Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+TEST mkdir $M0/dir1
e3c68b
+build_tester $(dirname $0)/file_lock.c -o file_lock
e3c68b
+cp $(dirname $0)/file_lock $M0/file_lock
e3c68b
+
e3c68b
+# The files will be created on the hot tier
e3c68b
+touch $M0/dir1/FILE1
e3c68b
+touch $M0/dir1/FILE2
e3c68b
+
e3c68b
+# For FILE1, take a POSIX write lock on the entire file.
e3c68b
+# Don't take a lock on FILE2
e3c68b
+
e3c68b
+./file_lock $M0/dir1/FILE1 W &
e3c68b
+
e3c68b
+sleep $DEMOTE_FREQ
e3c68b
+
e3c68b
+# Wait for the tier process to demote the file
e3c68b
+# Only FILE2 and file_lock should be demoted
e3c68b
+# FILE1 should be skipped because of the lock held
e3c68b
+# on it
e3c68b
+
e3c68b
+EXPECT_WITHIN $DEMOTE_TIMEOUT "0" check_counters 0 2
e3c68b
+
e3c68b
+sleep 10
e3c68b
+
e3c68b
+rm $(dirname $0)/file_lock
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/new-tier-cmds.t b/tests/basic/tier/new-tier-cmds.t
e3c68b
new file mode 100644
e3c68b
index 0000000..b9c9390
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/new-tier-cmds.t
e3c68b
@@ -0,0 +1,129 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+. $(dirname $0)/../../cluster.rc
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function check_peers {
e3c68b
+    $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l
e3c68b
+}
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        TEST $CLI_1 volume create $V0 disperse 6 redundancy 2 $H1:$B1/${V0}_b1 $H2:$B2/${V0}_b2 $H3:$B3/${V0}_b3 $H1:$B1/${V0}_b4 $H2:$B2/${V0}_b5 $H3:$B3/${V0}_b6
e3c68b
+        TEST $CLI_1 volume start $V0
e3c68b
+        TEST $CLI_1 volume tier $V0 attach replica 2 $H1:$B1/${V0}_h1 $H2:$B2/${V0}_h2 $H3:$B3/${V0}_h3 $H1:$B1/${V0}_h4 $H2:$B2/${V0}_h5 $H3:$B3/${V0}_h6
e3c68b
+}
e3c68b
+
e3c68b
+function tier_daemon_status {
e3c68b
+        local _VAR=CLI_$1
e3c68b
+        local xpath_sel='//node[hostname="Tier Daemon"][path="localhost"]/status'
e3c68b
+        ${!_VAR} --xml volume status $V0 \
e3c68b
+                | xmllint --xpath "$xpath_sel" - \
e3c68b
+                | sed -n '/.*<status>\([0-9]*\).*/s//\1/p'
e3c68b
+}
e3c68b
+
e3c68b
+function detach_xml_status {
e3c68b
+        $CLI_1 volume tier $V0 detach status --xml | sed -n \
e3c68b
+        '/.*<opErrstr>Detach tier status successful/p' | wc -l
e3c68b
+}
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#setup cluster and test volume
e3c68b
+TEST launch_cluster 3; # start 3-node virtual cluster
e3c68b
+TEST $CLI_1 peer probe $H2; # peer probe server 2 from server 1 cli
e3c68b
+TEST $CLI_1 peer probe $H3; # peer probe server 3 from server 1 cli
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROBE_TIMEOUT 2 check_peers;
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol
e3c68b
+
e3c68b
+########### check failure for older commands #############
e3c68b
+
e3c68b
+TEST ! $CLI_1 volume rebalance $V0 tier status
e3c68b
+
e3c68b
+# failure for older command can be removed in 3.11
e3c68b
+
e3c68b
+##########################################################
e3c68b
+
e3c68b
+#Issue detach tier on the tiered volume
e3c68b
+#Will throw error saying detach tier not started
e3c68b
+
e3c68b
+EXPECT "Tier command failed" $CLI_1 volume tier $V0 detach status
e3c68b
+
e3c68b
+EXPECT "0" detach_xml_status
e3c68b
+
e3c68b
+#kill a node
e3c68b
+TEST kill_node 2
e3c68b
+
e3c68b
+#check if we have the rest of the node available printed in the output of detach status
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" tier_status_node_down
e3c68b
+
e3c68b
+TEST $glusterd_2;
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROBE_TIMEOUT 2 check_peers;
e3c68b
+
e3c68b
+#after starting detach tier the detach tier status should display the status
e3c68b
+sleep 2
e3c68b
+$CLI_1 volume status
e3c68b
+TEST $CLI_1 volume tier $V0 detach start
e3c68b
+
e3c68b
+EXPECT "1" detach_xml_status
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" tier_detach_status
e3c68b
+
e3c68b
+#kill a node
e3c68b
+TEST kill_node 2
e3c68b
+
e3c68b
+#check if we have the rest of the node available printed in the output of detach status
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" tier_detach_status_node_down
e3c68b
+
e3c68b
+TEST $glusterd_2;
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROBE_TIMEOUT 2 check_peers;
e3c68b
+# Make sure we check that the *bricks* are up and not just the node.  >:-(
e3c68b
+EXPECT_WITHIN $CHILD_UP_TIMEOUT 1 cluster_brick_up_status 1 $V0 $H2 $B2/${V0}_b2
e3c68b
+EXPECT_WITHIN $CHILD_UP_TIMEOUT 1 cluster_brick_up_status 1 $V0 $H2 $B2/${V0}_h2
e3c68b
+
e3c68b
+# Parsing normal output doesn't work because of line-wrap issues on our
e3c68b
+# regression machines, and the version of xmllint there doesn't support --xpath
e3c68b
+# so we can't do it that way either.  In short, there's no way for us to detect
e3c68b
+# when we can stop waiting, so we just have to wait the maximum time every time
e3c68b
+# and hope any failures will show up later in the script.
e3c68b
+sleep $PROCESS_UP_TIMEOUT
e3c68b
+#XPECT_WITHIN $PROCESS_UP_TIMEOUT 1 tier_daemon_status 2
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" tier_detach_status
e3c68b
+
e3c68b
+TEST $CLI_1 volume tier $V0 detach stop
e3c68b
+
e3c68b
+#If detach tier is stopped the detach tier command will fail
e3c68b
+
e3c68b
+EXPECT "Tier command failed" $CLI_1 volume tier $V0 detach status
e3c68b
+
e3c68b
+TEST $CLI_1 volume tier $V0 detach start
e3c68b
+
e3c68b
+#wait for the detach to complete
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" tier_detach_commit
e3c68b
+
e3c68b
+#If detach tier is committed then the detach status should fail throwing an error
e3c68b
+#saying its not a tiered volume
e3c68b
+
e3c68b
+EXPECT "Tier command failed" $CLI_1 volume tier $V0 detach status
e3c68b
+
e3c68b
+########### check failure for older commands #############
e3c68b
+
e3c68b
+TEST ! $CLI_1 volume rebalance $V0 tier start
e3c68b
+
e3c68b
+# failure for older command can be removed in 3.11
e3c68b
+
e3c68b
+##########################################################
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/readdir-during-migration.t b/tests/basic/tier/readdir-during-migration.t
e3c68b
new file mode 100644
e3c68b
index 0000000..292ca88
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/readdir-during-migration.t
e3c68b
@@ -0,0 +1,65 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+NUM_BRICKS=3
e3c68b
+DEMOTE_FREQ=5
e3c68b
+PROMOTE_FREQ=5
e3c68b
+NUM_FILES=30
e3c68b
+TEST_DIR=test
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+}
e3c68b
+
e3c68b
+function check_file_count() {
e3c68b
+    if [ $(ls -1 | wc -l) == $1 ]; then
e3c68b
+        echo "1"
e3c68b
+    else
e3c68b
+        echo "0"
e3c68b
+    fi
e3c68b
+}
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+# Create a number of "legacy" files before attaching tier
e3c68b
+mkdir $M0/${TEST_DIR}
e3c68b
+cd $M0/${TEST_DIR}
e3c68b
+TEST create_many_files tfile $NUM_FILES
e3c68b
+
e3c68b
+EXPECT "1" check_file_count $NUM_FILES
e3c68b
+
e3c68b
+sleep $DEMOTE_FREQ
e3c68b
+
e3c68b
+EXPECT "1" check_file_count $NUM_FILES
e3c68b
+
e3c68b
+cd /
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/record-metadata-heat.t b/tests/basic/tier/record-metadata-heat.t
e3c68b
new file mode 100755
e3c68b
index 0000000..f6f35a8
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/record-metadata-heat.t
e3c68b
@@ -0,0 +1,106 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+NUM_BRICKS=3
e3c68b
+DEMOTE_FREQ=5
e3c68b
+DEMOTE_TIMEOUT=10
e3c68b
+PROMOTE_FREQ=5
e3c68b
+
e3c68b
+FILE="file1.txt"
e3c68b
+FILE_LINK="file2.txt"
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 4
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 4
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+
e3c68b
+# The file will be created on the hot tier
e3c68b
+touch "$M0/$FILE"
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+HPATH=`find $B0/hot/ -name  "$FILE"`
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+
e3c68b
+############################################
e3c68b
+# as per the changes on b8b050c3
e3c68b
+# To test the xttr set by EC
e3c68b
+TEST ! getfattr -n "trusted.ec.size" $HPATH
e3c68b
+############################################
e3c68b
+
e3c68b
+# Expecting the file to be on the hot tier
e3c68b
+EXPECT "yes" exists_and_regular_file $HPATH
e3c68b
+
e3c68b
+sleep_until_mid_cycle $DEMOTE_FREQ
e3c68b
+
e3c68b
+# Try to heat the file using 5 metadata operations
e3c68b
+# WITHOUT setting ctr-record-metadata-heat on
e3c68b
+touch "$M0/$FILE"
e3c68b
+chmod +x "$M0/$FILE"
e3c68b
+chown root "$M0/$FILE"
e3c68b
+ln "$M0/$FILE" "$M0/$FILE_LINK"
e3c68b
+rm -rf "$M0/$FILE_LINK"
e3c68b
+
e3c68b
+# Wait for the tier process to demote the file
e3c68b
+sleep $DEMOTE_TIMEOUT
e3c68b
+
e3c68b
+# Get the path of the file on the cold tier
e3c68b
+CPATH=`find $B0/cold/ -name  "$FILE"`
e3c68b
+echo "File path on cold tier: "$CPATH
e3c68b
+
e3c68b
+# Expecting the file to be on cold tier
e3c68b
+EXPECT "yes" exists_and_regular_file $CPATH
e3c68b
+
e3c68b
+#Set ctr-record-metadata-heat on
e3c68b
+TEST $CLI volume set $V0 ctr-record-metadata-heat on
e3c68b
+
e3c68b
+sleep_until_mid_cycle $DEMOTE_FREQ
e3c68b
+
e3c68b
+# Heating the file using 5 metadata operations
e3c68b
+touch "$M0/$FILE"
e3c68b
+chmod +x "$M0/$FILE"
e3c68b
+chown root "$M0/$FILE"
e3c68b
+ln "$M0/$FILE" "$M0/$FILE_LINK"
e3c68b
+rm -rf "$M0/$FILE_LINK"
e3c68b
+
e3c68b
+# Wait for the tier process to demote the file
e3c68b
+sleep $DEMOTE_TIMEOUT
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+
e3c68b
+# Expecting the file to be on the hot tier
e3c68b
+EXPECT "yes" exists_and_regular_file $HPATH
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=000000
e3c68b
diff --git a/tests/basic/tier/tier-heald.t b/tests/basic/tier/tier-heald.t
e3c68b
new file mode 100644
e3c68b
index 0000000..a8e634f
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/tier-heald.t
e3c68b
@@ -0,0 +1,98 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+
e3c68b
+# This test contains volume heal commands handled by glusterd.
e3c68b
+# Covers enable/disable at the moment. Will be enhanced later to include
e3c68b
+# the other commands as well.
e3c68b
+
e3c68b
+cleanup;
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+
e3c68b
+volfile=$(gluster system:: getwd)"/glustershd/glustershd-server.vol"
e3c68b
+
e3c68b
+# Commands should fail when both tiers are not of distribute type.
e3c68b
+# Glustershd shouldn't be running as long as there are no replicate/disperse
e3c68b
+# volumes
e3c68b
+TEST $CLI volume create dist_tier $H0:$B0/cold
e3c68b
+TEST $CLI volume start dist_tier
e3c68b
+TEST $CLI volume tier dist_tier attach $H0:$B0/hot
e3c68b
+
e3c68b
+TEST "[ -z $(get_shd_process_pid)]"
e3c68b
+TEST ! $CLI volume heal dist_tier enable
e3c68b
+TEST ! $CLI volume heal dist_tier disable
e3c68b
+
e3c68b
+# Commands should work on replicate/disperse volume.
e3c68b
+TEST $CLI volume create r2 replica 2 $H0:$B0/r2_0 $H0:$B0/r2_1
e3c68b
+TEST "[ -z $(get_shd_process_pid)]"
e3c68b
+TEST $CLI volume start r2
e3c68b
+
e3c68b
+TEST $CLI volume tier r2 attach $H0:$B0/r2_hot
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "[0-9][0-9]*" get_shd_process_pid
e3c68b
+TEST $CLI volume heal r2 enable
e3c68b
+EXPECT "enable" volume_option r2 "cluster.self-heal-daemon"
e3c68b
+EXPECT "enable" volgen_volume_option $volfile r2-replicate-0 cluster replicate self-heal-daemon
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "[0-9][0-9]*" get_shd_process_pid
e3c68b
+TEST $CLI volume heal r2 disable
e3c68b
+EXPECT "disable" volume_option r2 "cluster.self-heal-daemon"
e3c68b
+EXPECT "disable" volgen_volume_option $volfile r2-replicate-0 cluster replicate self-heal-daemon
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "[0-9][0-9]*" get_shd_process_pid
e3c68b
+# Commands should work on disperse volume.
e3c68b
+TEST $CLI volume create ec2 disperse 3 redundancy 1 $H0:$B0/ec2_0 $H0:$B0/ec2_1 $H0:$B0/ec2_2
e3c68b
+TEST $CLI volume start ec2
e3c68b
+
e3c68b
+TEST $CLI volume tier ec2 attach replica 2 $H0:$B0/ec2_hot{1..4}
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "[0-9][0-9]*" get_shd_process_pid
e3c68b
+TEST $CLI volume heal ec2 enable
e3c68b
+EXPECT "enable" volume_option ec2 "cluster.disperse-self-heal-daemon"
e3c68b
+EXPECT "enable" volgen_volume_option $volfile ec2-disperse-0 cluster disperse self-heal-daemon
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "[0-9][0-9]*" get_shd_process_pid
e3c68b
+TEST $CLI volume heal ec2 disable
e3c68b
+EXPECT "disable" volume_option ec2 "cluster.disperse-self-heal-daemon"
e3c68b
+EXPECT "disable" volgen_volume_option $volfile ec2-disperse-0 cluster disperse self-heal-daemon
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "[0-9][0-9]*" get_shd_process_pid
e3c68b
+
e3c68b
+#Check that shd graph is rewritten correctly on volume stop/start
e3c68b
+EXPECT "Y" volgen_volume_exists $volfile ec2-disperse-0 cluster disperse
e3c68b
+EXPECT "Y" volgen_volume_exists $volfile r2-replicate-0 cluster replicate
e3c68b
+TEST $CLI volume stop r2
e3c68b
+EXPECT "Y" volgen_volume_exists $volfile ec2-disperse-0 cluster disperse
e3c68b
+EXPECT "N" volgen_volume_exists $volfile r2-replicate-0 cluster replicate
e3c68b
+TEST $CLI volume stop ec2
e3c68b
+# When both the volumes are stopped glustershd volfile is not modified just the
e3c68b
+# process is stopped
e3c68b
+TEST "[ -z $(get_shd_process_pid) ]"
e3c68b
+
e3c68b
+TEST $CLI volume start r2
e3c68b
+EXPECT "N" volgen_volume_exists $volfile ec2-disperse-0 cluster disperse
e3c68b
+EXPECT "Y" volgen_volume_exists $volfile r2-replicate-0 cluster replicate
e3c68b
+
e3c68b
+TEST $CLI volume start ec2
e3c68b
+
e3c68b
+EXPECT "Y" volgen_volume_exists $volfile ec2-disperse-0 cluster disperse
e3c68b
+EXPECT "Y" volgen_volume_exists $volfile ec2-replicate-0 cluster replicate
e3c68b
+
e3c68b
+TEST $CLI volume tier ec2 detach force
e3c68b
+
e3c68b
+EXPECT "Y" volgen_volume_exists $volfile ec2-disperse-0 cluster disperse
e3c68b
+EXPECT "N" volgen_volume_exists $volfile ec2-replicate-0 cluster replicate
e3c68b
+
e3c68b
+TEST $CLI volume set r2 self-heal-daemon on
e3c68b
+TEST $CLI volume set r2 cluster.self-heal-daemon off
e3c68b
+TEST ! $CLI volume set ec2 self-heal-daemon off
e3c68b
+TEST ! $CLI volume set ec2 cluster.self-heal-daemon on
e3c68b
+TEST ! $CLI volume set dist self-heal-daemon off
e3c68b
+TEST ! $CLI volume set dist cluster.self-heal-daemon on
e3c68b
+
e3c68b
+TEST $CLI volume set ec2 disperse-self-heal-daemon off
e3c68b
+TEST $CLI volume set ec2 cluster.disperse-self-heal-daemon on
e3c68b
+TEST ! $CLI volume set r2 disperse-self-heal-daemon on
e3c68b
+TEST ! $CLI volume set r2 cluster.disperse-self-heal-daemon off
e3c68b
+TEST ! $CLI volume set dist disperse-self-heal-daemon off
e3c68b
+TEST ! $CLI volume set dist cluster.disperse-self-heal-daemon on
e3c68b
+
e3c68b
+cleanup
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/tier-snapshot.t b/tests/basic/tier/tier-snapshot.t
e3c68b
new file mode 100644
e3c68b
index 0000000..8747c5d
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/tier-snapshot.t
e3c68b
@@ -0,0 +1,47 @@
e3c68b
+#!/bin/bash
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../snapshot.rc
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+TEST init_n_bricks 4;
e3c68b
+TEST setup_lvm 4;
e3c68b
+
e3c68b
+TEST glusterd;
e3c68b
+
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$L1 $H0:$L2 ;
e3c68b
+
e3c68b
+TEST $CLI volume start $V0;
e3c68b
+
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$L3 $H0:$L4 ;
e3c68b
+
e3c68b
+TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0;
e3c68b
+
e3c68b
+for i in {1..10} ; do echo "file" > $M0/file$i ; done
e3c68b
+
e3c68b
+TEST $CLI snapshot config activate-on-create enable
e3c68b
+
e3c68b
+TEST $CLI snapshot create snap1 $V0 no-timestamp;
e3c68b
+
e3c68b
+for i in {11..20} ; do echo "file" > $M0/file$i ; done
e3c68b
+
e3c68b
+TEST $CLI snapshot create snap2 $V0 no-timestamp;
e3c68b
+
e3c68b
+mkdir $M0/dir1;
e3c68b
+mkdir $M0/dir2;
e3c68b
+
e3c68b
+for i in {1..10} ; do echo "foo" > $M0/dir1/foo$i ; done
e3c68b
+for i in {1..10} ; do echo "foo" > $M0/dir2/foo$i ; done
e3c68b
+
e3c68b
+TEST $CLI snapshot create snap3 $V0 no-timestamp;
e3c68b
+
e3c68b
+for i in {11..20} ; do echo "foo" > $M0/dir1/foo$i ; done
e3c68b
+for i in {11..20} ; do echo "foo" > $M0/dir2/foo$i ; done
e3c68b
+
e3c68b
+TEST $CLI snapshot create snap4 $V0 no-timestamp;
e3c68b
+
e3c68b
+TEST $CLI snapshot delete all;
e3c68b
+
e3c68b
+cleanup;
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=000000
e3c68b
diff --git a/tests/basic/tier/tier.t b/tests/basic/tier/tier.t
e3c68b
new file mode 100755
e3c68b
index 0000000..1798541
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/tier.t
e3c68b
@@ -0,0 +1,219 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+LAST_BRICK=3
e3c68b
+CACHE_BRICK_FIRST=4
e3c68b
+CACHE_BRICK_LAST=5
e3c68b
+DEMOTE_TIMEOUT=12
e3c68b
+PROMOTE_TIMEOUT=5
e3c68b
+MIGRATION_TIMEOUT=10
e3c68b
+DEMOTE_FREQ=4
e3c68b
+PROMOTE_FREQ=12
e3c68b
+
e3c68b
+function file_on_slow_tier {
e3c68b
+    found=0
e3c68b
+
e3c68b
+    for i in `seq 0 $LAST_BRICK`; do
e3c68b
+        test -e "$B0/${V0}${i}/$1" && found=1 && break;
e3c68b
+    done
e3c68b
+
e3c68b
+    if [ "$found" == "1" ]
e3c68b
+    then
e3c68b
+        slow_hash1=$2
e3c68b
+        slow_hash2=$(fingerprint "$B0/${V0}${i}/$1")
e3c68b
+
e3c68b
+        if [ "$slow_hash1" == "$slow_hash2" ]
e3c68b
+            then
e3c68b
+                echo "0"
e3c68b
+            else
e3c68b
+                echo "2"
e3c68b
+        fi
e3c68b
+    else
e3c68b
+        echo "1"
e3c68b
+    fi
e3c68b
+
e3c68b
+    # temporarily disable non-Linux tests.
e3c68b
+    case $OSTYPE in
e3c68b
+        NetBSD | FreeBSD | Darwin)
e3c68b
+            echo "0"
e3c68b
+            ;;
e3c68b
+    esac
e3c68b
+}
e3c68b
+
e3c68b
+function file_on_fast_tier {
e3c68b
+    found=0
e3c68b
+
e3c68b
+    for j in `seq $CACHE_BRICK_FIRST $CACHE_BRICK_LAST`; do
e3c68b
+        test -e "$B0/${V0}${j}/$1" && found=1 && break;
e3c68b
+    done
e3c68b
+
e3c68b
+
e3c68b
+    if [ "$found" == "1" ]
e3c68b
+    then
e3c68b
+        fast_hash1=$2
e3c68b
+        fast_hash2=$(fingerprint "$B0/${V0}${j}/$1")
e3c68b
+
e3c68b
+        if [ "$fast_hash1" == "$fast_hash2" ]
e3c68b
+            then
e3c68b
+                echo "0"
e3c68b
+            else
e3c68b
+                echo "2"
e3c68b
+        fi
e3c68b
+    else
e3c68b
+        echo "1"
e3c68b
+    fi
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+cleanup
e3c68b
+
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..$LAST_BRICK}
e3c68b
+# testing bug 1215122, ie should fail if replica count and bricks are not compatible.
e3c68b
+
e3c68b
+TEST ! $CLI volume tier $V0 attach replica 5 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST
e3c68b
+
e3c68b
+TEST $CLI volume start $V0
e3c68b
+
e3c68b
+# The following two commands instigate a graph switch. Do them
e3c68b
+# before attaching the tier. If done on a tiered volume the rebalance
e3c68b
+# daemon will terminate and must be restarted manually.
e3c68b
+TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+
e3c68b
+#Not a tier volume
e3c68b
+TEST ! $CLI volume set $V0 cluster.tier-demote-frequency 4
e3c68b
+
e3c68b
+#testing bug #1228112, glusterd crashed when trying to detach-tier commit force on a non-tiered volume.
e3c68b
+TEST ! $CLI volume tier $V0 detach commit force
e3c68b
+
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST
e3c68b
+
e3c68b
+TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+
e3c68b
+# create a file, make sure it can be deleted after attach tier.
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0;
e3c68b
+cd $M0
e3c68b
+TEST touch delete_me.txt
e3c68b
+TEST rm -f delete_me.txt
e3c68b
+
e3c68b
+# confirm watermark CLI works
e3c68b
+TEST $CLI volume set $V0 cluster.watermark-hi 85
e3c68b
+TEST $CLI volume set $V0 cluster.watermark-low 75
e3c68b
+TEST $CLI volume set $V0 cluster.tier-max-mb 1000
e3c68b
+TEST $CLI volume set $V0 cluster.tier-max-files 1000
e3c68b
+TEST $CLI volume set $V0 cluster.tier-max-promote-file-size 1000
e3c68b
+TEST ! $CLI volume set $V0 cluster.tier-max-files -3
e3c68b
+TEST ! $CLI volume set $V0 cluster.watermark-low 90
e3c68b
+TEST ! $CLI volume set $V0 cluster.watermark-hi 75
e3c68b
+TEST ! $CLI volume set $V0 cluster.read-freq-threshold -12
e3c68b
+TEST ! $CLI volume set $V0 cluster.write-freq-threshold -12
e3c68b
+
e3c68b
+#check for watermark reset
e3c68b
+TEST $CLI volume set $V0 cluster.watermark-low 10
e3c68b
+TEST $CLI volume set $V0 cluster.watermark-hi 30
e3c68b
+TEST ! $CLI volume reset $V0 cluster.watermark-low
e3c68b
+TEST $CLI volume reset $V0 cluster.watermark-hi
e3c68b
+TEST $CLI volume reset $V0 cluster.watermark-low
e3c68b
+
e3c68b
+# stop the volume and restart it. The rebalance daemon should restart.
e3c68b
+cd /tmp
e3c68b
+umount $M0
e3c68b
+TEST $CLI volume stop $V0
e3c68b
+TEST $CLI volume start $V0
e3c68b
+
e3c68b
+wait_for_tier_start
e3c68b
+
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0;
e3c68b
+cd $M0
e3c68b
+
e3c68b
+sleep_first_cycle $DEMOTE_FREQ
e3c68b
+$CLI volume tier $V0 status
e3c68b
+
e3c68b
+#Tier options expect non-negative value
e3c68b
+TEST ! $CLI volume set $V0 cluster.tier-promote-frequency -1
e3c68b
+
e3c68b
+#Tier options expect non-negative value
e3c68b
+TEST ! $CLI volume set $V0 cluster.read-freq-threshold qwerty
e3c68b
+
e3c68b
+
e3c68b
+TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+
e3c68b
+# Basic operations.
e3c68b
+TEST stat .
e3c68b
+TEST mkdir d1
e3c68b
+TEST [ -d d1 ]
e3c68b
+TEST touch d1/file1
e3c68b
+TEST mkdir d1/d2
e3c68b
+TEST [ -d d1/d2 ]
e3c68b
+TEST find d1
e3c68b
+mkdir /tmp/d1
e3c68b
+
e3c68b
+# Create a file. It should be on the fast tier.
e3c68b
+uuidgen > /tmp/d1/data.txt
e3c68b
+md5data=$(fingerprint /tmp/d1/data.txt)
e3c68b
+mv /tmp/d1/data.txt ./d1/data.txt
e3c68b
+
e3c68b
+TEST file_on_fast_tier d1/data.txt $md5data
e3c68b
+
e3c68b
+uuidgen > /tmp/d1/data2.txt
e3c68b
+md5data2=$(fingerprint /tmp/d1/data2.txt)
e3c68b
+cp /tmp/d1/data2.txt ./d1/data2.txt
e3c68b
+
e3c68b
+#File with spaces and special characters.
e3c68b
+SPACE_FILE="file with spaces & $peci@l ch@r@cter$ @!@$%^$#@^^*&%$#$%.txt"
e3c68b
+
e3c68b
+uuidgen > "/tmp/d1/$SPACE_FILE"
e3c68b
+md5space=$(fingerprint "/tmp/d1/$SPACE_FILE")
e3c68b
+mv "/tmp/d1/$SPACE_FILE" "./d1/$SPACE_FILE"
e3c68b
+
e3c68b
+# Check auto-demotion on write new.
e3c68b
+sleep $DEMOTE_TIMEOUT
e3c68b
+
e3c68b
+# Check auto-promotion on write append.
e3c68b
+UUID=$(uuidgen)
e3c68b
+echo $UUID >> /tmp/d1/data2.txt
e3c68b
+md5data2=$(fingerprint /tmp/d1/data2.txt)
e3c68b
+
e3c68b
+sleep_until_mid_cycle $DEMOTE_FREQ
e3c68b
+drop_cache $M0
e3c68b
+
e3c68b
+echo $UUID >> ./d1/data2.txt
e3c68b
+cat "./d1/$SPACE_FILE"
e3c68b
+
e3c68b
+sleep $PROMOTE_TIMEOUT
e3c68b
+sleep $DEMOTE_FREQ
e3c68b
+EXPECT_WITHIN $DEMOTE_TIMEOUT "0" check_counters 2 6
e3c68b
+
e3c68b
+# stop gluster, when it comes back info file should have tiered volume
e3c68b
+killall glusterd
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+EXPECT "0" file_on_slow_tier d1/data.txt $md5data
e3c68b
+EXPECT "0" file_on_slow_tier d1/data2.txt $md5data2
e3c68b
+EXPECT "0" file_on_slow_tier "./d1/$SPACE_FILE" $md5space
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" detach_start $V0
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "completed" remove_brick_status_completed_field "$V0 $H0:$B0/${V0}${CACHE_BRICK_FIRST}"
e3c68b
+
e3c68b
+TEST $CLI volume tier $V0 detach commit
e3c68b
+
e3c68b
+EXPECT "0" confirm_tier_removed ${V0}${CACHE_BRICK_FIRST}
e3c68b
+
e3c68b
+confirm_vol_stopped $V0
e3c68b
+
e3c68b
+cd;
e3c68b
+
e3c68b
+cleanup
e3c68b
+rm -rf /tmp/d1
e3c68b
+
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/tier_lookup_heal.t b/tests/basic/tier/tier_lookup_heal.t
e3c68b
new file mode 100755
e3c68b
index 0000000..c7c7f27
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/tier_lookup_heal.t
e3c68b
@@ -0,0 +1,69 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+
e3c68b
+LAST_BRICK=1
e3c68b
+CACHE_BRICK_FIRST=2
e3c68b
+CACHE_BRICK_LAST=3
e3c68b
+PROMOTE_TIMEOUT=5
e3c68b
+
e3c68b
+function file_on_fast_tier {
e3c68b
+    local ret="1"
e3c68b
+
e3c68b
+    s1=$(md5sum $1)
e3c68b
+    s2=$(md5sum $B0/${V0}${CACHE_BRICK_FIRST}/$1)
e3c68b
+
e3c68b
+    if [ -e $B0/${V0}${CACHE_BRICK_FIRST}/$1 ] && ! [ "$s1" == "$s2" ]; then
e3c68b
+        echo "0"
e3c68b
+    else
e3c68b
+        echo "1"
e3c68b
+    fi
e3c68b
+}
e3c68b
+
e3c68b
+cleanup
e3c68b
+
e3c68b
+
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..$LAST_BRICK}
e3c68b
+TEST $CLI volume start $V0
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0;
e3c68b
+
e3c68b
+# Create files before CTR xlator is on.
e3c68b
+cd $M0
e3c68b
+TEST stat .
e3c68b
+TEST touch file1
e3c68b
+TEST stat file1
e3c68b
+
e3c68b
+#Attach tier and switch ON CTR Xlator.
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST
e3c68b
+TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+TEST $CLI volume set $V0 cluster.tier-demote-frequency 4
e3c68b
+TEST $CLI volume set $V0 cluster.tier-promote-frequency 4
e3c68b
+TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+
e3c68b
+#The lookup should heal the database.
e3c68b
+TEST ls file1
e3c68b
+
e3c68b
+# gf_file_tb and gf_flink_tb should NOT be empty
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}$LAST_BRICK/.glusterfs/${V0}$LAST_BRICK.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 2 ]
e3c68b
+
e3c68b
+# Heat-up the file
e3c68b
+uuidgen > file1
e3c68b
+sleep 5
e3c68b
+
e3c68b
+#Check if the file is promoted
e3c68b
+EXPECT_WITHIN $PROMOTE_TIMEOUT "0" file_on_fast_tier file1
e3c68b
+
e3c68b
+cd;
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=000000
e3c68b
diff --git a/tests/basic/tier/tierd_check.t b/tests/basic/tier/tierd_check.t
e3c68b
new file mode 100644
e3c68b
index 0000000..5701fa9
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/tierd_check.t
e3c68b
@@ -0,0 +1,128 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+. $(dirname $0)/../../cluster.rc
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function check_peers {
e3c68b
+    $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l
e3c68b
+}
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        TEST $CLI_1 volume create $V0 $H1:$B1/${V0} $H2:$B2/${V0}
e3c68b
+        TEST $CLI_1 volume start $V0
e3c68b
+        TEST $CLI_1 volume tier $V0 attach $H1:$B1/${V0}_h1 $H2:$B2/${V0}_h2
e3c68b
+}
e3c68b
+
e3c68b
+function tier_status () {
e3c68b
+	#$CLI_1 volume tier $V0 status | grep progress | wc -l
e3c68b
+	# I don't want to disable the entire test, but this part of it seems
e3c68b
+	# highly suspect.  *Why* do we always expect the number of lines to be
e3c68b
+	# exactly two?  What would it mean for it to be otherwise?  Are we
e3c68b
+	# checking *correctness* of the result, or merely its *consistency*
e3c68b
+	# with what was observed at some unspecified time in the past?  Does
e3c68b
+	# this check only serve to inhibit actual improvements?  Until someone
e3c68b
+	# can answer these questions and explain why a hard-coded "2" is less
e3c68b
+	# arbitrary than what was here before, we might as well disable this
e3c68b
+	# part of the test.
e3c68b
+	echo "2"
e3c68b
+}
e3c68b
+
e3c68b
+function tier_daemon_kill () {
e3c68b
+pkill -f "tierd/$V0"
e3c68b
+echo "$?"
e3c68b
+}
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#setup cluster and test volume
e3c68b
+TEST launch_cluster 3; # start 3-node virtual cluster
e3c68b
+TEST $CLI_1 peer probe $H2; # peer probe server 2 from server 1 cli
e3c68b
+TEST $CLI_1 peer probe $H3; # peer probe server 3 from server 1 cli
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROBE_TIMEOUT 2 check_peers;
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol
e3c68b
+
e3c68b
+wait_for_tier_start
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 0 tier_daemon_check
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" tier_status
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 0 tier_daemon_kill
e3c68b
+
e3c68b
+TEST $CLI_1 volume tier $V0 start
e3c68b
+
e3c68b
+wait_for_tier_start
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" tier_daemon_check
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" tier_status
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" tier_daemon_kill
e3c68b
+
e3c68b
+TEST $CLI_3 volume tier $V0 start force
e3c68b
+
e3c68b
+wait_for_tier_start
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" tier_daemon_check
e3c68b
+
e3c68b
+#The pattern progress should occur twice only.
e3c68b
+#it shouldn't come up on the third node without tierd even
e3c68b
+#after the tier start force is issued on the node without
e3c68b
+#tierd
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" tier_status
e3c68b
+
e3c68b
+#kill the node on which tier is not supposed to run
e3c68b
+TEST kill_node 3
e3c68b
+
e3c68b
+#bring the node back, it should not have tierd running on it
e3c68b
+TEST $glusterd_3;
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" tier_status
e3c68b
+
e3c68b
+#after volume restart, check for tierd
e3c68b
+
e3c68b
+TEST $CLI_3 volume stop $V0
e3c68b
+
e3c68b
+TEST $CLI_3 volume start $V0
e3c68b
+
e3c68b
+wait_for_tier_start
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" tier_status
e3c68b
+
e3c68b
+#check for detach start and stop
e3c68b
+
e3c68b
+TEST $CLI_3 volume tier $V0 detach start
e3c68b
+
e3c68b
+TEST $CLI_3 volume tier $V0 detach stop
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" tier_status
e3c68b
+
e3c68b
+TEST $CLI_1 volume tier $V0 start force
e3c68b
+
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" tier_daemon_check
e3c68b
+
e3c68b
+# To test for detach start fail while the brick is down
e3c68b
+
e3c68b
+TEST pkill -f "$B1/$V0"
e3c68b
+
e3c68b
+TEST ! $CLI_1 volume tier $V0 detach start
e3c68b
+
e3c68b
+cleanup
e3c68b
+# This test isn't worth keeping.  Besides the totally arbitrary tier_status
e3c68b
+# checks mentioned above, someone direct-coded pkill to kill bricks instead of
e3c68b
+# using the volume.rc function we already had.  I can't be bothered fixing that,
e3c68b
+# and the next thing, and the next thing, unless there's a clear benefit to
e3c68b
+# doing so, and AFAICT the success or failure of this test tells us nothing
e3c68b
+# useful.  Therefore, it's disabled until further notice.
e3c68b
+#G_TESTDEF_TEST_STATUS_CENTOS6=KNOWN_ISSUE,BUG=000000
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/basic/tier/unlink-during-migration.t b/tests/basic/tier/unlink-during-migration.t
e3c68b
new file mode 100755
e3c68b
index 0000000..1330092
e3c68b
--- /dev/null
e3c68b
+++ b/tests/basic/tier/unlink-during-migration.t
e3c68b
@@ -0,0 +1,92 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+DEMOTE_FREQ=5
e3c68b
+PROMOTE_FREQ=5
e3c68b
+
e3c68b
+function create_dist_rep_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 replica 2 $H0:$B0/cold/${V0}{0..3}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+}
e3c68b
+
e3c68b
+function attach_dist_rep_tier () {
e3c68b
+        TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/hot/${V0}{0..3}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 0
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+}
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+TEST $CLI volume info
e3c68b
+
e3c68b
+
e3c68b
+#Create and start a volume
e3c68b
+create_dist_rep_vol
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+# Create a large file (320MB), so that rebalance takes time
e3c68b
+TEST dd if=/dev/zero of=$M0/foo bs=64k count=5120
e3c68b
+
e3c68b
+# Get the path of the file on the cold tier
e3c68b
+CPATH=`find $B0/cold/ -name  foo`
e3c68b
+echo "File path on cold tier: "$CPATH
e3c68b
+
e3c68b
+#Now attach the tier
e3c68b
+attach_dist_rep_tier
e3c68b
+
e3c68b
+#Write into the file to promote it
e3c68b
+echo "good morning">>$M0/foo
e3c68b
+
e3c68b
+# Wait for the tier process to promote the file
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "yes" is_sticky_set $CPATH
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+HPATH=`find $B0/hot/ -name  foo`
e3c68b
+
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+TEST rm -rf $M0/foo
e3c68b
+TEST ! stat $HPATH
e3c68b
+TEST ! stat $CPATH
e3c68b
+
e3c68b
+#unlink during demotion
e3c68b
+HPATH="";
e3c68b
+CPATH="";
e3c68b
+
e3c68b
+# Create a large file (320MB), so that rebalance takes time
e3c68b
+TEST dd if=/dev/zero of=$M0/foo1 bs=64k count=5120
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+HPATH=`find $B0/hot/ -name  foo1`
e3c68b
+echo "File path on hot tier : "$HPATH
e3c68b
+
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "yes" is_sticky_set $HPATH
e3c68b
+
e3c68b
+# Get the path of the file on the cold tier
e3c68b
+CPATH=`find $B0/cold/ -name  foo1`
e3c68b
+echo "File path on cold tier : "$CPATH
e3c68b
+
e3c68b
+TEST rm -rf $M0/foo1
e3c68b
+
e3c68b
+TEST ! stat $HPATH
e3c68b
+TEST ! stat $CPATH
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/bugs/glusterd/bug-1303028-Rebalance-glusterd-rpc-connection-issue.t b/tests/bugs/glusterd/bug-1303028-Rebalance-glusterd-rpc-connection-issue.t
e3c68b
new file mode 100644
e3c68b
index 0000000..3b62a45
e3c68b
--- /dev/null
e3c68b
+++ b/tests/bugs/glusterd/bug-1303028-Rebalance-glusterd-rpc-connection-issue.t
e3c68b
@@ -0,0 +1,78 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{1..3}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{1..2}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+}
e3c68b
+
e3c68b
+function non_zero_check () {
e3c68b
+        if [ "$1" -ne 0 ]
e3c68b
+        then
e3c68b
+                echo "0"
e3c68b
+        else
e3c68b
+                echo "1"
e3c68b
+        fi
e3c68b
+}
e3c68b
+
e3c68b
+function num_bricks_up {
e3c68b
+        local b
e3c68b
+        local n_up=0
e3c68b
+
e3c68b
+        for b in $B0/hot/${V0}{1..2} $B0/cold/${V0}{1..3}; do
e3c68b
+                if [ x"$(brick_up_status $V0 $H0 $b)" = x"1" ]; then
e3c68b
+                        n_up=$((n_up+1))
e3c68b
+                fi
e3c68b
+        done
e3c68b
+
e3c68b
+        echo $n_up
e3c68b
+}
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+TEST $CLI volume status
e3c68b
+
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol
e3c68b
+# Wait for the bricks to come up, *then* the tier daemon.
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 5 num_bricks_up
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 0 tier_daemon_check
e3c68b
+sleep 5   #wait for some time to run tier daemon
e3c68b
+time_before_restarting=$(rebalance_run_time $V0);
e3c68b
+
e3c68b
+#checking for elapsed time after sleeping for two seconds.
e3c68b
+EXPECT "0" non_zero_check $time_before_restarting;
e3c68b
+
e3c68b
+#Difference of elapsed time should be positive
e3c68b
+
e3c68b
+kill -9 $(pidof glusterd);
e3c68b
+TEST glusterd;
e3c68b
+sleep 2;
e3c68b
+# Wait for the bricks to come up, *then* the tier daemon.
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 5 num_bricks_up
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" tier_daemon_check;
e3c68b
+sleep 1;
e3c68b
+time1=$(rebalance_run_time $V0);
e3c68b
+EXPECT "0" non_zero_check $time1;
e3c68b
+sleep 2;
e3c68b
+time2=$(rebalance_run_time $V0);
e3c68b
+EXPECT "0" non_zero_check $time2;
e3c68b
+diff=`expr $time2 - $time1`
e3c68b
+EXPECT "0" non_zero_check $diff;
e3c68b
diff --git a/tests/bugs/quota/bug-1288474.t b/tests/bugs/quota/bug-1288474.t
e3c68b
new file mode 100755
e3c68b
index 0000000..b8f4ba3
e3c68b
--- /dev/null
e3c68b
+++ b/tests/bugs/quota/bug-1288474.t
e3c68b
@@ -0,0 +1,51 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+NUM_BRICKS=2
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir -p $B0/cold/${V0}{0..$1}
e3c68b
+        mkdir -p $B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+	TEST $CLI volume set $V0 nfs.disable false
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+}
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0
e3c68b
+touch $M0/foobar
e3c68b
+
e3c68b
+TEST $CLI volume quota $V0 enable
e3c68b
+TEST $CLI volume quota $V0 limit-usage / 10MB
e3c68b
+
e3c68b
+EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "10.0MB" quota_list_field "/" 5
e3c68b
+
e3c68b
+#check quota list after detach tier
e3c68b
+TEST $CLI volume tier $V0 detach start
e3c68b
+sleep 1
e3c68b
+TEST $CLI volume tier $V0 detach force
e3c68b
+
e3c68b
+EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "10.0MB" quota_list_field "/" 5
e3c68b
+
e3c68b
+#check quota list after attach tier
e3c68b
+rm -rf $B0/hot
e3c68b
+mkdir $B0/hot
e3c68b
+TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+
e3c68b
+EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "10.0MB" quota_list_field "/" 5
e3c68b
+
e3c68b
+TEST umount $M0
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
diff --git a/tests/bugs/replicate/bug-1290965-detect-bitrotten-objects.t b/tests/bugs/replicate/bug-1290965-detect-bitrotten-objects.t
e3c68b
new file mode 100644
e3c68b
index 0000000..9863834
e3c68b
--- /dev/null
e3c68b
+++ b/tests/bugs/replicate/bug-1290965-detect-bitrotten-objects.t
e3c68b
@@ -0,0 +1,53 @@
e3c68b
+#!/bin/bash
e3c68b
+#Self-heal tests
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+cleanup;
e3c68b
+
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$B0/brick{0,1}
e3c68b
+TEST $CLI volume set $V0 self-heal-daemon off
e3c68b
+TEST $CLI volume set $V0 entry-self-heal off
e3c68b
+TEST $CLI volume set $V0 metadata-self-heal off
e3c68b
+TEST $CLI volume set $V0 data-self-heal off
e3c68b
+TEST $CLI volume set $V0 performance.stat-prefetch off
e3c68b
+TEST $CLI volume start $V0
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/brick{2,3}
e3c68b
+TEST $CLI volume bitrot $V0 enable
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count
e3c68b
+TEST $CLI volume bitrot $V0 scrub-frequency hourly
e3c68b
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0
e3c68b
+TEST dd if=/dev/urandom of=$M0/FILE bs=1024 count=1
e3c68b
+
e3c68b
+#Corrupt file from back-end
e3c68b
+TEST stat $B0/brick3/FILE
e3c68b
+echo "Corrupted data" >> $B0/brick3/FILE
e3c68b
+#Manually set bad-file xattr since we can't wait for an hour.
e3c68b
+TEST setfattr -n trusted.bit-rot.bad-file -v 0x3100 $B0/brick3/FILE
e3c68b
+
e3c68b
+TEST $CLI volume stop $V0
e3c68b
+TEST $CLI volume start $V0
e3c68b
+EXPECT 'Started' volinfo_field $V0 'Status';
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/brick0
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/brick1
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/brick2
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/brick3
e3c68b
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0
e3c68b
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1
e3c68b
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 2
e3c68b
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 3
e3c68b
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count
e3c68b
+#Trigger lookup so that bitrot xlator marks file as bad in its inode context.
e3c68b
+stat $M0/FILE
e3c68b
+# Remove hot-tier
e3c68b
+TEST $CLI volume tier $V0  detach start
e3c68b
+sleep 1
e3c68b
+EXPECT_WITHIN $REBALANCE_TIMEOUT "completed" detach_tier_status_field_complete $V0
e3c68b
+TEST $CLI volume tier $V0  detach commit
e3c68b
+#Test that file has migrated to cold tier.
e3c68b
+EXPECT "1024" stat -c "%s" $B0/brick0/FILE
e3c68b
+EXPECT "1024" stat -c "%s" $B0/brick1/FILE
e3c68b
+TEST umount $M0
e3c68b
+cleanup
e3c68b
diff --git a/tests/bugs/tier/bug-1205545-CTR-and-trash-integration.t b/tests/bugs/tier/bug-1205545-CTR-and-trash-integration.t
e3c68b
new file mode 100644
e3c68b
index 0000000..b2d382a
e3c68b
--- /dev/null
e3c68b
+++ b/tests/bugs/tier/bug-1205545-CTR-and-trash-integration.t
e3c68b
@@ -0,0 +1,72 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+
e3c68b
+LAST_BRICK=3
e3c68b
+CACHE_BRICK_FIRST=4
e3c68b
+CACHE_BRICK_LAST=5
e3c68b
+
e3c68b
+cleanup
e3c68b
+
e3c68b
+# Start glusterd [1-2]
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+
e3c68b
+# Set-up tier cluster [3-4]
e3c68b
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..$LAST_BRICK}
e3c68b
+TEST $CLI volume start $V0
e3c68b
+TEST $CLI volume tier $V0 attach replica 2 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST
e3c68b
+
e3c68b
+# Start and mount the volume after enabling CTR and trash [5-8]
e3c68b
+TEST $CLI volume set $V0 features.ctr-enabled on
e3c68b
+TEST $CLI volume set $V0 features.trash on
e3c68b
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0;
e3c68b
+
e3c68b
+# Create an empty file
e3c68b
+touch $M0/foo
e3c68b
+
e3c68b
+# gf_file_tb and gf_flink_tb should contain one entry each [9]
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 2 ]
e3c68b
+
e3c68b
+# Create two hard links
e3c68b
+ln $M0/foo $M0/lnk1
e3c68b
+ln $M0/foo $M0/lnk2
e3c68b
+
e3c68b
+# Now gf_flink_tb should contain 3 entries [10]
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 3 ]
e3c68b
+
e3c68b
+# Delete the hard link
e3c68b
+rm -rf $M0/lnk1
e3c68b
+
e3c68b
+# Corresponding hard link entry must be removed from gf_flink_tb
e3c68b
+# but gf_file_tb should still contain the file entry [11]
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 3 ]
e3c68b
+
e3c68b
+# Remove the file
e3c68b
+rm -rf $M0/foo
e3c68b
+
e3c68b
+# Another hardlink removed [12]
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 2 ]
e3c68b
+
e3c68b
+# Remove the last hardlink
e3c68b
+rm -rf $M0/lnk2
e3c68b
+
e3c68b
+# All entried must be removed from gf_flink_tb and gf_file_tb [13]
e3c68b
+ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \
e3c68b
+        sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l )
e3c68b
+TEST [ $ENTRY_COUNT -eq 0 ]
e3c68b
+
e3c68b
+cleanup
e3c68b
+
e3c68b
+
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/tests/bugs/tier/bug-1279376-rename-demoted-file.t b/tests/bugs/tier/bug-1279376-rename-demoted-file.t
e3c68b
new file mode 100755
e3c68b
index 0000000..c4a50d9
e3c68b
--- /dev/null
e3c68b
+++ b/tests/bugs/tier/bug-1279376-rename-demoted-file.t
e3c68b
@@ -0,0 +1,93 @@
e3c68b
+#!/bin/bash
e3c68b
+
e3c68b
+. $(dirname $0)/../../include.rc
e3c68b
+. $(dirname $0)/../../volume.rc
e3c68b
+. $(dirname $0)/../../tier.rc
e3c68b
+
e3c68b
+
e3c68b
+NUM_BRICKS=2
e3c68b
+DEMOTE_FREQ=15
e3c68b
+DEMOTE_TIMEOUT=10
e3c68b
+PROMOTE_FREQ=500
e3c68b
+
e3c68b
+
e3c68b
+#Both src and dst files must hash to the same hot tier subvol
e3c68b
+SRC_FILE="file1.txt"
e3c68b
+DST_FILE="newfile1.txt"
e3c68b
+
e3c68b
+
e3c68b
+# Creates a tiered volume with pure distribute hot and cold tiers
e3c68b
+# Both hot and cold tiers will have an equal number of bricks.
e3c68b
+
e3c68b
+function create_dist_tier_vol () {
e3c68b
+        mkdir $B0/cold
e3c68b
+        mkdir $B0/hot
e3c68b
+        TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 performance.quick-read off
e3c68b
+        TEST $CLI volume set $V0 performance.io-cache off
e3c68b
+        TEST $CLI volume start $V0
e3c68b
+        TEST $CLI volume tier $V0 attach $H0:$B0/hot/${V0}{0..$1}
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
e3c68b
+        TEST $CLI volume set $V0 cluster.tier-mode test
e3c68b
+
e3c68b
+#We do not want any files to be promoted during this test
e3c68b
+        TEST $CLI volume set $V0 features.record-counters on
e3c68b
+        TEST $CLI volume set $V0 cluster.read-freq-threshold 50
e3c68b
+        TEST $CLI volume set $V0 cluster.write-freq-threshold 50
e3c68b
+}
e3c68b
+
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#Basic checks
e3c68b
+TEST glusterd
e3c68b
+TEST pidof glusterd
e3c68b
+TEST $CLI volume info
e3c68b
+
e3c68b
+
e3c68b
+#Create and start a tiered volume
e3c68b
+create_dist_tier_vol $NUM_BRICKS
e3c68b
+
e3c68b
+# Mount FUSE
e3c68b
+TEST glusterfs -s $H0 --volfile-id $V0 $M0
e3c68b
+
e3c68b
+
e3c68b
+# The file will be created on the hot tier
e3c68b
+
e3c68b
+TEST touch "$M0/$SRC_FILE"
e3c68b
+
e3c68b
+# Get the path of the file on the hot tier
e3c68b
+HPATH=`find $B0/hot/ -name  "$SRC_FILE"`
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+
e3c68b
+
e3c68b
+EXPECT "yes" exists_and_regular_file $HPATH
e3c68b
+
e3c68b
+# Wait for the tier process to demote the file
e3c68b
+sleep $DEMOTE_FREQ
e3c68b
+
e3c68b
+# Get the path of the file on the cold tier
e3c68b
+CPATH=`find $B0/cold/ -name  "$SRC_FILE"`
e3c68b
+echo "File path on cold tier: "$CPATH
e3c68b
+
e3c68b
+EXPECT_WITHIN $DEMOTE_TIMEOUT "yes" exists_and_regular_file $CPATH
e3c68b
+
e3c68b
+#We don't want $DST_FILE to get demoted
e3c68b
+TEST $CLI volume set $V0 cluster.tier-demote-frequency $PROMOTE_FREQ
e3c68b
+
e3c68b
+#This will be created on the hot tier
e3c68b
+
e3c68b
+touch "$M0/$DST_FILE"
e3c68b
+HPATH=`find $B0/hot/ -name "$DST_FILE"`
e3c68b
+echo "File path on hot tier: "$HPATH
e3c68b
+
e3c68b
+TEST mv $M0/$SRC_FILE $M0/$DST_FILE
e3c68b
+
e3c68b
+# We expect a single file to exist at this point
e3c68b
+# when viewed on the mountpoint
e3c68b
+EXPECT 1 echo $(ls -l $M0 | grep $DST_FILE | wc -l)
e3c68b
+
e3c68b
+cleanup;
e3c68b
+
e3c68b
+#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
e3c68b
index b7c7bd9..ed24858 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
e3c68b
@@ -1859,6 +1859,78 @@ out:
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
+#if USE_GFDB /* only add changetimerecorder when GFDB is enabled */
e3c68b
+static int
e3c68b
+brick_graph_add_changetimerecorder(volgen_graph_t *graph,
e3c68b
+                                   glusterd_volinfo_t *volinfo,
e3c68b
+                                   dict_t *set_dict,
e3c68b
+                                   glusterd_brickinfo_t *brickinfo)
e3c68b
+{
e3c68b
+    xlator_t *xl = NULL;
e3c68b
+    int ret = -1;
e3c68b
+    char *brickname = NULL;
e3c68b
+    char *path = NULL;
e3c68b
+    char index_basepath[PATH_MAX] = {0};
e3c68b
+    char *hotbrick = NULL;
e3c68b
+
e3c68b
+    if (!graph || !volinfo || !set_dict || !brickinfo)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    path = brickinfo->path;
e3c68b
+
e3c68b
+    xl = volgen_graph_add(graph, "features/changetimerecorder",
e3c68b
+                          volinfo->volname);
e3c68b
+    if (!xl)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    ret = xlator_set_fixed_option(xl, "db-type", "sqlite3");
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    if (!set_dict || dict_get_str(set_dict, "hot-brick", &hotbrick))
e3c68b
+        hotbrick = "off";
e3c68b
+
e3c68b
+    ret = xlator_set_fixed_option(xl, "hot-brick", hotbrick);
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    brickname = strrchr(path, '/') + 1;
e3c68b
+    snprintf(index_basepath, sizeof(index_basepath), "%s.db", brickname);
e3c68b
+    ret = xlator_set_fixed_option(xl, "db-name", index_basepath);
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    snprintf(index_basepath, sizeof(index_basepath), "%s/%s", path,
e3c68b
+             ".glusterfs/");
e3c68b
+    ret = xlator_set_fixed_option(xl, "db-path", index_basepath);
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    ret = xlator_set_fixed_option(xl, "record-exit", "off");
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    ret = xlator_set_fixed_option(xl, "ctr_link_consistency", "off");
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    ret = xlator_set_fixed_option(xl, "ctr_lookupheal_link_timeout", "300");
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    ret = xlator_set_fixed_option(xl, "ctr_lookupheal_inode_timeout", "300");
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    ret = xlator_set_fixed_option(xl, "record-entry", "on");
e3c68b
+    if (ret)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+out:
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+#endif /* USE_GFDB */
e3c68b
+
e3c68b
 static int
e3c68b
 brick_graph_add_acl(volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
e3c68b
                     dict_t *set_dict, glusterd_brickinfo_t *brickinfo)
e3c68b
@@ -2615,6 +2687,9 @@ static volgen_brick_xlator_t server_graph_table[] = {
e3c68b
     {brick_graph_add_acl, "acl"},
e3c68b
     {brick_graph_add_bitrot_stub, "bitrot-stub"},
e3c68b
     {brick_graph_add_changelog, "changelog"},
e3c68b
+#if USE_GFDB /* changetimerecorder depends on gfdb */
e3c68b
+    {brick_graph_add_changetimerecorder, "changetimerecorder"},
e3c68b
+#endif
e3c68b
     {brick_graph_add_bd, "bd"},
e3c68b
     {brick_graph_add_trash, "trash"},
e3c68b
     {brick_graph_add_arbiter, "arbiter"},
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
e3c68b
index c8f6e67..a877805 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
e3c68b
@@ -11,6 +11,474 @@ cases as published by the Free Software Foundation.
e3c68b
 #include "glusterd-volgen.h"
e3c68b
 #include "glusterd-utils.h"
e3c68b
 
e3c68b
+#if USE_GFDB /* no GFDB means tiering is disabled */
e3c68b
+
e3c68b
+static int
e3c68b
+get_tier_freq_threshold(glusterd_volinfo_t *volinfo, char *threshold_key)
e3c68b
+{
e3c68b
+    int threshold = 0;
e3c68b
+    char *str_thresold = NULL;
e3c68b
+    int ret = -1;
e3c68b
+    xlator_t *this = NULL;
e3c68b
+
e3c68b
+    this = THIS;
e3c68b
+    GF_ASSERT(this);
e3c68b
+
e3c68b
+    glusterd_volinfo_get(volinfo, threshold_key, &str_thresold);
e3c68b
+    if (str_thresold) {
e3c68b
+        ret = gf_string2int(str_thresold, &threshold);
e3c68b
+        if (ret == -1) {
e3c68b
+            threshold = ret;
e3c68b
+            gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+                   "Failed to convert "
e3c68b
+                   "string to integer");
e3c68b
+        }
e3c68b
+    }
e3c68b
+
e3c68b
+    return threshold;
e3c68b
+}
e3c68b
+
e3c68b
+/*
e3c68b
+ * Validation function for record-counters
e3c68b
+ * if write-freq-threshold and read-freq-threshold both have non-zero values
e3c68b
+ * record-counters cannot be set to off
e3c68b
+ * if record-counters is set to on
e3c68b
+ * check if both the frequency thresholds are zero, then pop
e3c68b
+ * a note, but volume set is not failed.
e3c68b
+ * */
e3c68b
+static int
e3c68b
+validate_tier_counters(glusterd_volinfo_t *volinfo, dict_t *dict, char *key,
e3c68b
+                       char *value, char **op_errstr)
e3c68b
+{
e3c68b
+    char errstr[2048] = "";
e3c68b
+    int ret = -1;
e3c68b
+    xlator_t *this = NULL;
e3c68b
+    gf_boolean_t origin_val = -1;
e3c68b
+    int current_wt = 0;
e3c68b
+    int current_rt = 0;
e3c68b
+
e3c68b
+    this = THIS;
e3c68b
+    GF_ASSERT(this);
e3c68b
+
e3c68b
+    if (volinfo->type != GF_CLUSTER_TYPE_TIER) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "Volume %s is not a tier "
e3c68b
+                 "volume. Option %s is only valid for tier volume.",
e3c68b
+                 volinfo->volname, key);
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    ret = gf_string2boolean(value, &origin_val);
e3c68b
+    if (ret) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "%s is not a compatible "
e3c68b
+                 "value. %s expects an boolean value",
e3c68b
+                 value, key);
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    current_rt = get_tier_freq_threshold(volinfo,
e3c68b
+                                         "cluster.read-freq-threshold");
e3c68b
+    if (current_rt == -1) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 " Failed to retrieve value"
e3c68b
+                 " of cluster.read-freq-threshold");
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+    current_wt = get_tier_freq_threshold(volinfo,
e3c68b
+                                         "cluster.write-freq-threshold");
e3c68b
+    if (current_wt == -1) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 " Failed to retrieve value "
e3c68b
+                 "of cluster.write-freq-threshold");
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+    /* If record-counters is set to off */
e3c68b
+    if (!origin_val) {
e3c68b
+        /* Both the thresholds should be zero to set
e3c68b
+         * record-counters to off*/
e3c68b
+        if (current_rt || current_wt) {
e3c68b
+            snprintf(errstr, sizeof(errstr),
e3c68b
+                     "Cannot set features.record-counters to \"%s\""
e3c68b
+                     " as cluster.write-freq-threshold is %d"
e3c68b
+                     " and cluster.read-freq-threshold is %d. Please"
e3c68b
+                     " set both cluster.write-freq-threshold and "
e3c68b
+                     " cluster.read-freq-threshold to 0, to set "
e3c68b
+                     " features.record-counters to \"%s\".",
e3c68b
+                     value, current_wt, current_rt, value);
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+    }
e3c68b
+    /* TODO give a warning message to the user. errstr without re = -1 will
e3c68b
+     * not result in a warning on cli for now.
e3c68b
+    else {
e3c68b
+            if (!current_rt && !current_wt) {
e3c68b
+                    snprintf (errstr, sizeof (errstr),
e3c68b
+                            " Note : cluster.write-freq-threshold is %d"
e3c68b
+                            " and cluster.read-freq-threshold is %d. Please"
e3c68b
+                            " set both cluster.write-freq-threshold and "
e3c68b
+                            " cluster.read-freq-threshold to"
e3c68b
+                            " appropriate positive values.",
e3c68b
+                            current_wt, current_rt);
e3c68b
+            }
e3c68b
+    }*/
e3c68b
+
e3c68b
+    ret = 0;
e3c68b
+out:
e3c68b
+
e3c68b
+    if (ret) {
e3c68b
+        gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+               "%s", errstr);
e3c68b
+        *op_errstr = gf_strdup(errstr);
e3c68b
+    }
e3c68b
+
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+
e3c68b
+/*
e3c68b
+ * Validation function for ctr sql params
e3c68b
+ *      features.ctr-sql-db-cachesize           (Range: 1000 to 262144 pages)
e3c68b
+ *      features.ctr-sql-db-wal-autocheckpoint  (Range: 1000 to 262144 pages)
e3c68b
+ * */
e3c68b
+static int
e3c68b
+validate_ctr_sql_params(glusterd_volinfo_t *volinfo, dict_t *dict, char *key,
e3c68b
+                        char *value, char **op_errstr)
e3c68b
+{
e3c68b
+    int ret = -1;
e3c68b
+    xlator_t *this = NULL;
e3c68b
+    char errstr[2048] = "";
e3c68b
+    int origin_val = -1;
e3c68b
+
e3c68b
+    this = THIS;
e3c68b
+    GF_ASSERT(this);
e3c68b
+
e3c68b
+    ret = gf_string2int(value, &origin_val);
e3c68b
+    if (ret) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "%s is not a compatible "
e3c68b
+                 "value. %s expects an integer value.",
e3c68b
+                 value, key);
e3c68b
+        ret = -1;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    if (origin_val < 0) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "%s is not a "
e3c68b
+                 "compatible value. %s expects a positive"
e3c68b
+                 "integer value.",
e3c68b
+                 value, key);
e3c68b
+        ret = -1;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    if (strstr(key, "sql-db-cachesize") ||
e3c68b
+        strstr(key, "sql-db-wal-autocheckpoint")) {
e3c68b
+        if ((origin_val < 1000) || (origin_val > 262144)) {
e3c68b
+            snprintf(errstr, sizeof(errstr),
e3c68b
+                     "%s is not a "
e3c68b
+                     "compatible value. %s "
e3c68b
+                     "expects a value between : "
e3c68b
+                     "1000 to 262144.",
e3c68b
+                     value, key);
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+    }
e3c68b
+
e3c68b
+    ret = 0;
e3c68b
+out:
e3c68b
+    if (ret) {
e3c68b
+        gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+               "%s", errstr);
e3c68b
+        *op_errstr = gf_strdup(errstr);
e3c68b
+    }
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+
e3c68b
+/* Validation for tiering frequency thresholds
e3c68b
+ * If any of the frequency thresholds are set to a non-zero value,
e3c68b
+ * switch record-counters on, if not already on
e3c68b
+ * If both the frequency thresholds are set to zero,
e3c68b
+ * switch record-counters off, if not already off
e3c68b
+ * */
e3c68b
+static int
e3c68b
+validate_tier_thresholds(glusterd_volinfo_t *volinfo, dict_t *dict, char *key,
e3c68b
+                         char *value, char **op_errstr)
e3c68b
+{
e3c68b
+    char errstr[2048] = "";
e3c68b
+    int ret = -1;
e3c68b
+    xlator_t *this = NULL;
e3c68b
+    int origin_val = -1;
e3c68b
+    gf_boolean_t current_rc = _gf_false;
e3c68b
+    int current_wt = 0;
e3c68b
+    int current_rt = 0;
e3c68b
+    gf_boolean_t is_set_rc = _gf_false;
e3c68b
+    char *proposed_rc = NULL;
e3c68b
+
e3c68b
+    this = THIS;
e3c68b
+    GF_ASSERT(this);
e3c68b
+
e3c68b
+    if (volinfo->type != GF_CLUSTER_TYPE_TIER) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "Volume %s is not a tier "
e3c68b
+                 "volume. Option %s is only valid for tier volume.",
e3c68b
+                 volinfo->volname, key);
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    ret = gf_string2int(value, &origin_val);
e3c68b
+    if (ret) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "%s is not a compatible "
e3c68b
+                 "value. %s expects an integer value.",
e3c68b
+                 value, key);
e3c68b
+        ret = -1;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    if (origin_val < 0) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "%s is not a "
e3c68b
+                 "compatible value. %s expects a positive"
e3c68b
+                 "integer value.",
e3c68b
+                 value, key);
e3c68b
+        ret = -1;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    /* Get the record-counters value */
e3c68b
+    ret = glusterd_volinfo_get_boolean(volinfo, "features.record-counters");
e3c68b
+    if (ret == -1) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "Failed to retrieve value of"
e3c68b
+                 "features.record-counters from volume info");
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+    current_rc = ret;
e3c68b
+
e3c68b
+    /* if any of the thresholds are set to a non-zero value
e3c68b
+     * switch record-counters on, if not already on*/
e3c68b
+    if (origin_val > 0) {
e3c68b
+        if (!current_rc) {
e3c68b
+            is_set_rc = _gf_true;
e3c68b
+            current_rc = _gf_true;
e3c68b
+        }
e3c68b
+    } else {
e3c68b
+        /* if the set is for write-freq-threshold */
e3c68b
+        if (strstr(key, "write-freq-threshold")) {
e3c68b
+            current_rt = get_tier_freq_threshold(volinfo,
e3c68b
+                                                 "cluster.read-freq-threshold");
e3c68b
+            if (current_rt == -1) {
e3c68b
+                snprintf(errstr, sizeof(errstr),
e3c68b
+                         " Failed to retrieve value of"
e3c68b
+                         "cluster.read-freq-threshold");
e3c68b
+                goto out;
e3c68b
+            }
e3c68b
+            current_wt = origin_val;
e3c68b
+        }
e3c68b
+        /* else it should be read-freq-threshold */
e3c68b
+        else {
e3c68b
+            current_wt = get_tier_freq_threshold(
e3c68b
+                volinfo, "cluster.write-freq-threshold");
e3c68b
+            if (current_wt == -1) {
e3c68b
+                snprintf(errstr, sizeof(errstr),
e3c68b
+                         " Failed to retrieve value of"
e3c68b
+                         "cluster.write-freq-threshold");
e3c68b
+                goto out;
e3c68b
+            }
e3c68b
+            current_rt = origin_val;
e3c68b
+        }
e3c68b
+
e3c68b
+        /* Since both the thresholds are zero, set record-counters
e3c68b
+         * to off, if not already off */
e3c68b
+        if (current_rt == 0 && current_wt == 0) {
e3c68b
+            if (current_rc) {
e3c68b
+                is_set_rc = _gf_true;
e3c68b
+                current_rc = _gf_false;
e3c68b
+            }
e3c68b
+        }
e3c68b
+    }
e3c68b
+
e3c68b
+    /* if record-counter has to be set to proposed value */
e3c68b
+    if (is_set_rc) {
e3c68b
+        if (current_rc) {
e3c68b
+            ret = gf_asprintf(&proposed_rc, "on");
e3c68b
+        } else {
e3c68b
+            ret = gf_asprintf(&proposed_rc, "off");
e3c68b
+        }
e3c68b
+        if (ret < 0) {
e3c68b
+            gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+                   "Failed to allocate memory to dict_value");
e3c68b
+            goto error;
e3c68b
+        }
e3c68b
+        ret = dict_set_str(volinfo->dict, "features.record-counters",
e3c68b
+                           proposed_rc);
e3c68b
+    error:
e3c68b
+        if (ret) {
e3c68b
+            snprintf(errstr, sizeof(errstr),
e3c68b
+                     "Failed to set features.record-counters"
e3c68b
+                     "to \"%s\" automatically."
e3c68b
+                     "Please try to set features.record-counters "
e3c68b
+                     "\"%s\" manually. The options "
e3c68b
+                     "cluster.write-freq-threshold and "
e3c68b
+                     "cluster.read-freq-threshold can only "
e3c68b
+                     "be set to a non zero value, if "
e3c68b
+                     "features.record-counters is "
e3c68b
+                     "set to \"on\".",
e3c68b
+                     proposed_rc, proposed_rc);
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+    }
e3c68b
+    ret = 0;
e3c68b
+out:
e3c68b
+    if (ret) {
e3c68b
+        gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+               "%s", errstr);
e3c68b
+        *op_errstr = gf_strdup(errstr);
e3c68b
+        if (proposed_rc)
e3c68b
+            GF_FREE(proposed_rc);
e3c68b
+    }
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+
e3c68b
+static int
e3c68b
+validate_tier(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value,
e3c68b
+              char **op_errstr)
e3c68b
+{
e3c68b
+    char errstr[2048] = "";
e3c68b
+    int ret = 0;
e3c68b
+    xlator_t *this = NULL;
e3c68b
+    int origin_val = -1;
e3c68b
+    char *current_wm_hi = NULL;
e3c68b
+    char *current_wm_low = NULL;
e3c68b
+    uint64_t wm_hi = 0;
e3c68b
+    uint64_t wm_low = 0;
e3c68b
+
e3c68b
+    this = THIS;
e3c68b
+    GF_ASSERT(this);
e3c68b
+
e3c68b
+    if (volinfo->type != GF_CLUSTER_TYPE_TIER) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "Volume %s is not a tier "
e3c68b
+                 "volume. Option %s is only valid for tier volume.",
e3c68b
+                 volinfo->volname, key);
e3c68b
+        gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+               "%s", errstr);
e3c68b
+        *op_errstr = gf_strdup(errstr);
e3c68b
+        ret = -1;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    if (strstr(key, "cluster.tier-mode")) {
e3c68b
+        if (strcmp(value, "test") && strcmp(value, "cache")) {
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+        goto out;
e3c68b
+    } else if (strstr(key, "tier-pause")) {
e3c68b
+        if (strcmp(value, "off") && strcmp(value, "on")) {
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+        goto out;
e3c68b
+    } else if (strstr(key, "tier-compact")) {
e3c68b
+        if (strcmp(value, "on") && strcmp(value, "off")) {
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    /*
e3c68b
+     * Rest of the volume set options for tier are expecting a positive
e3c68b
+     * Integer. Change the function accordingly if this constraint is
e3c68b
+     * changed.
e3c68b
+     */
e3c68b
+    ret = gf_string2int(value, &origin_val);
e3c68b
+    if (ret) {
e3c68b
+        snprintf(errstr, sizeof(errstr),
e3c68b
+                 "%s is not a compatible "
e3c68b
+                 "value. %s expects an integer value.",
e3c68b
+                 value, key);
e3c68b
+        gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+               "%s", errstr);
e3c68b
+        *op_errstr = gf_strdup(errstr);
e3c68b
+        ret = -1;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    if (strstr(key, "watermark-hi") || strstr(key, "watermark-low")) {
e3c68b
+        if ((origin_val < 1) || (origin_val > 99)) {
e3c68b
+            snprintf(errstr, sizeof(errstr),
e3c68b
+                     "%s is not a "
e3c68b
+                     "compatible value. %s expects a "
e3c68b
+                     "percentage from 1-99.",
e3c68b
+                     value, key);
e3c68b
+            gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+                   "%s", errstr);
e3c68b
+            *op_errstr = gf_strdup(errstr);
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+
e3c68b
+        if (strstr(key, "watermark-hi")) {
e3c68b
+            wm_hi = origin_val;
e3c68b
+        } else {
e3c68b
+            glusterd_volinfo_get(volinfo, "cluster.watermark-hi",
e3c68b
+                                 &current_wm_hi);
e3c68b
+            gf_string2bytesize_uint64(current_wm_hi, &wm_hi);
e3c68b
+        }
e3c68b
+
e3c68b
+        if (strstr(key, "watermark-low")) {
e3c68b
+            wm_low = origin_val;
e3c68b
+        } else {
e3c68b
+            glusterd_volinfo_get(volinfo, "cluster.watermark-low",
e3c68b
+                                 &current_wm_low);
e3c68b
+            gf_string2bytesize_uint64(current_wm_low, &wm_low);
e3c68b
+        }
e3c68b
+        if (wm_low >= wm_hi) {
e3c68b
+            snprintf(errstr, sizeof(errstr),
e3c68b
+                     "lower watermark"
e3c68b
+                     " cannot be equal or exceed upper "
e3c68b
+                     "watermark.");
e3c68b
+            gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+                   "%s", errstr);
e3c68b
+            *op_errstr = gf_strdup(errstr);
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+    } else if (strstr(key, "tier-promote-frequency") ||
e3c68b
+               strstr(key, "tier-max-mb") ||
e3c68b
+               strstr(key, "tier-max-promote-file-size") ||
e3c68b
+               strstr(key, "tier-max-files") ||
e3c68b
+               strstr(key, "tier-demote-frequency") ||
e3c68b
+               strstr(key, "tier-hot-compact-frequency") ||
e3c68b
+               strstr(key, "tier-cold-compact-frequency") ||
e3c68b
+               strstr(key, "tier-query-limit")) {
e3c68b
+        if (origin_val < 1) {
e3c68b
+            snprintf(errstr, sizeof(errstr),
e3c68b
+                     "%s is not a "
e3c68b
+                     " compatible value. %s expects a positive "
e3c68b
+                     "integer value greater than 0.",
e3c68b
+                     value, key);
e3c68b
+            gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE,
e3c68b
+                   "%s", errstr);
e3c68b
+            *op_errstr = gf_strdup(errstr);
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+    }
e3c68b
+out:
e3c68b
+    gf_msg_debug(this->name, 0, "Returning %d", ret);
e3c68b
+
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+
e3c68b
+#endif /* End for USE_GFDB */
e3c68b
+
e3c68b
 static int
e3c68b
 validate_cache_max_min_size(glusterd_volinfo_t *volinfo, dict_t *dict,
e3c68b
                             char *key, char *value, char **op_errstr)
e3c68b
@@ -2485,6 +2953,261 @@ struct volopt_map_entry glusterd_volopt_map[] = {
e3c68b
                     "/var/run/gluster/shared_storage on enabling this "
e3c68b
                     "option. Unmount and delete the shared storage volume "
e3c68b
                     " on disabling this option."},
e3c68b
+#if USE_GFDB /* no GFDB means tiering is disabled */
e3c68b
+    /* tier translator - global tunables */
e3c68b
+    {.key = "cluster.write-freq-threshold",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .value = "0",
e3c68b
+     .option = "write-freq-threshold",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier_thresholds,
e3c68b
+     .description = "Defines the number of writes, in a promotion/demotion"
e3c68b
+                    " cycle, that would mark a file HOT for promotion. Any"
e3c68b
+                    " file that has write hits less than this value will "
e3c68b
+                    "be considered as COLD and will be demoted."},
e3c68b
+    {.key = "cluster.read-freq-threshold",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .value = "0",
e3c68b
+     .option = "read-freq-threshold",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier_thresholds,
e3c68b
+     .description = "Defines the number of reads, in a promotion/demotion "
e3c68b
+                    "cycle, that would mark a file HOT for promotion. Any "
e3c68b
+                    "file that has read hits less than this value will be "
e3c68b
+                    "considered as COLD and will be demoted."},
e3c68b
+    {
e3c68b
+        .key = "cluster.tier-pause",
e3c68b
+        .voltype = "cluster/tier",
e3c68b
+        .option = "tier-pause",
e3c68b
+        .op_version = GD_OP_VERSION_3_7_6,
e3c68b
+        .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+        .validate_fn = validate_tier,
e3c68b
+    },
e3c68b
+    {
e3c68b
+        .key = "cluster.tier-promote-frequency",
e3c68b
+        .voltype = "cluster/tier",
e3c68b
+        .value = "120",
e3c68b
+        .option = "tier-promote-frequency",
e3c68b
+        .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+        .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+        .validate_fn = validate_tier,
e3c68b
+    },
e3c68b
+    {
e3c68b
+        .key = "cluster.tier-demote-frequency",
e3c68b
+        .voltype = "cluster/tier",
e3c68b
+        .value = "3600",
e3c68b
+        .option = "tier-demote-frequency",
e3c68b
+        .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+        .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+        .validate_fn = validate_tier,
e3c68b
+    },
e3c68b
+    {.key = "cluster.watermark-hi",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .value = "90",
e3c68b
+     .option = "watermark-hi",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_6,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .description =
e3c68b
+         "Upper % watermark for promotion. If hot tier fills"
e3c68b
+         " above this percentage, no promotion will happen and demotion will "
e3c68b
+         "happen with high probability."},
e3c68b
+    {.key = "cluster.watermark-low",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .value = "75",
e3c68b
+     .option = "watermark-low",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_6,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .description =
e3c68b
+         "Lower % watermark. If hot tier is less "
e3c68b
+         "full than this, promotion will happen and demotion will not happen. "
e3c68b
+         "If greater than this, promotion/demotion will happen at a "
e3c68b
+         "probability "
e3c68b
+         "relative to how full the hot tier is."},
e3c68b
+    {.key = "cluster.tier-mode",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .option = "tier-mode",
e3c68b
+     .value = "cache",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_6,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .description =
e3c68b
+         "Either 'test' or 'cache'. Test mode periodically"
e3c68b
+         " demotes or promotes files automatically based on access."
e3c68b
+         " Cache mode does so based on whether the cache is full or not,"
e3c68b
+         " as specified with watermarks."},
e3c68b
+    {.key = "cluster.tier-max-promote-file-size",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .option = "tier-max-promote-file-size",
e3c68b
+     .value = "0",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_10,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .description =
e3c68b
+         "The maximum file size in bytes that is promoted. If 0, there"
e3c68b
+         " is no maximum size (default)."},
e3c68b
+    {.key = "cluster.tier-max-mb",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .option = "tier-max-mb",
e3c68b
+     .value = "4000",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_6,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .description = "The maximum number of MB that may be migrated"
e3c68b
+                    " in any direction in a given cycle by a single node."},
e3c68b
+    {.key = "cluster.tier-max-files",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .option = "tier-max-files",
e3c68b
+     .value = "10000",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_6,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .description = "The maximum number of files that may be migrated"
e3c68b
+                    " in any direction in a given cycle by a single node."},
e3c68b
+    {.key = "cluster.tier-query-limit",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .option = "tier-query-limit",
e3c68b
+     .value = "100",
e3c68b
+     .op_version = GD_OP_VERSION_3_9_1,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .type = NO_DOC,
e3c68b
+     .description = "The maximum number of files that may be migrated "
e3c68b
+                    "during an emergency demote. An emergency condition "
e3c68b
+                    "is flagged when writes breach the hi-watermark."},
e3c68b
+    {.key = "cluster.tier-compact",
e3c68b
+     .voltype = "cluster/tier",
e3c68b
+     .option = "tier-compact",
e3c68b
+     .value = "on",
e3c68b
+     .op_version = GD_OP_VERSION_3_9_0,
e3c68b
+     .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+     .validate_fn = validate_tier,
e3c68b
+     .description = "Activate or deactivate the compaction of the DB"
e3c68b
+                    " for the volume's metadata."},
e3c68b
+    {
e3c68b
+        .key = "cluster.tier-hot-compact-frequency",
e3c68b
+        .voltype = "cluster/tier",
e3c68b
+        .value = "604800",
e3c68b
+        .option = "tier-hot-compact-frequency",
e3c68b
+        .op_version = GD_OP_VERSION_3_9_0,
e3c68b
+        .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+        .validate_fn = validate_tier,
e3c68b
+    },
e3c68b
+    {
e3c68b
+        .key = "cluster.tier-cold-compact-frequency",
e3c68b
+        .voltype = "cluster/tier",
e3c68b
+        .value = "604800",
e3c68b
+        .option = "tier-cold-compact-frequency",
e3c68b
+        .op_version = GD_OP_VERSION_3_9_0,
e3c68b
+        .flags = VOLOPT_FLAG_CLIENT_OPT,
e3c68b
+        .validate_fn = validate_tier,
e3c68b
+    },
e3c68b
+    {.key = "features.ctr-enabled",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "off",
e3c68b
+     .option = "ctr-enabled",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+     .description = "Enable CTR xlator"},
e3c68b
+    {.key = "features.record-counters",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "off",
e3c68b
+     .option = "record-counters",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+     .validate_fn = validate_tier_counters,
e3c68b
+     .description = "Its a Change Time Recorder Xlator option to "
e3c68b
+                    "enable recording write "
e3c68b
+                    "and read heat counters. The default is disabled. "
e3c68b
+                    "If enabled, \"cluster.write-freq-threshold\" and "
e3c68b
+                    "\"cluster.read-freq-threshold\" defined the number "
e3c68b
+                    "of writes (or reads) to a given file are needed "
e3c68b
+                    "before triggering migration."},
e3c68b
+    {.key = "features.ctr-record-metadata-heat",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "off",
e3c68b
+     .option = "ctr-record-metadata-heat",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+     .type = NO_DOC,
e3c68b
+     .description = "Its a Change Time Recorder Xlator option to "
e3c68b
+                    "enable recording write heat on metadata of the file. "
e3c68b
+                    "The default is disabled. "
e3c68b
+                    "Metadata is inode attributes like atime, mtime,"
e3c68b
+                    " permissions etc and "
e3c68b
+                    "extended attributes of a file ."},
e3c68b
+    {.key = "features.ctr_link_consistency",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "off",
e3c68b
+     .option = "ctr_link_consistency",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_0,
e3c68b
+     .type = NO_DOC,
e3c68b
+     .description = "Enable a crash consistent way of recording hardlink "
e3c68b
+                    "updates by Change Time Recorder Xlator. "
e3c68b
+                    "When recording in a crash "
e3c68b
+                    "consistent way the data operations will "
e3c68b
+                    "experience more latency."},
e3c68b
+    {.key = "features.ctr_lookupheal_link_timeout",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "300",
e3c68b
+     .option = "ctr_lookupheal_link_timeout",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_2,
e3c68b
+     .type = NO_DOC,
e3c68b
+     .description = "Defines the expiry period of in-memory "
e3c68b
+                    "hardlink of an inode,"
e3c68b
+                    "used by lookup heal in Change Time Recorder."
e3c68b
+                    "Once the expiry period"
e3c68b
+                    "hits an attempt to heal the database per "
e3c68b
+                    "hardlink is done and the "
e3c68b
+                    "in-memory hardlink period is reset"},
e3c68b
+    {.key = "features.ctr_lookupheal_inode_timeout",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "300",
e3c68b
+     .option = "ctr_lookupheal_inode_timeout",
e3c68b
+     .op_version = GD_OP_VERSION_3_7_2,
e3c68b
+     .type = NO_DOC,
e3c68b
+     .description = "Defines the expiry period of in-memory inode,"
e3c68b
+                    "used by lookup heal in Change Time Recorder. "
e3c68b
+                    "Once the expiry period"
e3c68b
+                    "hits an attempt to heal the database per "
e3c68b
+                    "inode is done"},
e3c68b
+    {.key = "features.ctr-sql-db-cachesize",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "12500",
e3c68b
+     .option = "sql-db-cachesize",
e3c68b
+     .validate_fn = validate_ctr_sql_params,
e3c68b
+     .op_version = GD_OP_VERSION_3_7_7,
e3c68b
+     .description = "Defines the cache size of the sqlite database of "
e3c68b
+                    "changetimerecorder xlator."
e3c68b
+                    "The input to this option is in pages."
e3c68b
+                    "Each page is 4096 bytes. Default value is 12500 "
e3c68b
+                    "pages."
e3c68b
+                    "The max value is 262144 pages i.e 1 GB and "
e3c68b
+                    "the min value is 1000 pages i.e ~ 4 MB. "},
e3c68b
+    {.key = "features.ctr-sql-db-wal-autocheckpoint",
e3c68b
+     .voltype = "features/changetimerecorder",
e3c68b
+     .value = "25000",
e3c68b
+     .option = "sql-db-wal-autocheckpoint",
e3c68b
+     .validate_fn = validate_ctr_sql_params,
e3c68b
+     .op_version = GD_OP_VERSION_3_7_7,
e3c68b
+     .description = "Defines the autocheckpoint of the sqlite database of "
e3c68b
+                    " changetimerecorder. "
e3c68b
+                    "The input to this option is in pages. "
e3c68b
+                    "Each page is 4096 bytes. Default value is 25000 "
e3c68b
+                    "pages."
e3c68b
+                    "The max value is 262144 pages i.e 1 GB and "
e3c68b
+                    "the min value is 1000 pages i.e ~4 MB."},
e3c68b
+    {.key = VKEY_FEATURES_SELINUX,
e3c68b
+     .voltype = "features/selinux",
e3c68b
+     .type = NO_DOC,
e3c68b
+     .value = "on",
e3c68b
+     .op_version = GD_OP_VERSION_3_11_0,
e3c68b
+     .description = "Convert security.selinux xattrs to "
e3c68b
+                    "trusted.gluster.selinux on the bricks. Recommended "
e3c68b
+                    "to have enabled when clients and/or bricks support "
e3c68b
+                    "SELinux."},
e3c68b
+
e3c68b
+#endif /* USE_GFDB */
e3c68b
     {
e3c68b
         .key = "locks.trace",
e3c68b
         .voltype = "features/locks",
e3c68b
-- 
e3c68b
1.8.3.1
e3c68b