]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
qa/tasks: add test_corrupt_backtrace 12588/head
authorJohn Spray <john.spray@redhat.com>
Thu, 5 Jan 2017 13:40:41 +0000 (13:40 +0000)
committerJohn Spray <john.spray@redhat.com>
Thu, 5 Jan 2017 13:41:59 +0000 (13:41 +0000)
Validate that we get EIO and a damage table entry
when seeing a decode error on a backtrace.

Signed-off-by: John Spray <john.spray@redhat.com>
qa/tasks/cephfs/mount.py
qa/tasks/cephfs/test_damage.py

index dc76ad500b9582453784ca91ac063539e83d8fca..f5d9d73c2fc696b8d318bb82e1cb88485fc19409 100644 (file)
@@ -136,7 +136,8 @@ class CephFSMount(object):
 
     def run_shell(self, args, wait=True):
         args = ["cd", self.mountpoint, run.Raw('&&'), "sudo"] + args
-        return self.client_remote.run(args=args, stdout=StringIO(), wait=wait)
+        return self.client_remote.run(args=args, stdout=StringIO(),
+                                      stderr=StringIO(), wait=wait)
 
     def open_no_data(self, basename):
         """
index b14ef8d5ea7d25cea364075617d72fff61a5dded..8bc7dec1d972918445039025da52ad10d6cde33f 100644 (file)
@@ -447,3 +447,49 @@ class TestDamage(CephFSTestCase):
         # Now I should be able to create a file with the same name as the
         # damaged guy if I want.
         self.mount_a.touch("subdir/file_to_be_damaged")
+
+    def test_corrupt_backtrace(self):
+        """
+        That an un-decodeable backtrace leads to an appropriate
+        error trying to follow the backtrace to the file.
+        """
+
+        self.mount_a.run_shell(["mkdir", "alpha"])
+        self.mount_a.run_shell(["mkdir", "bravo"])
+        self.mount_a.run_shell(["touch", "alpha/target"])
+        self.mount_a.run_shell(["ln", "alpha/target", "bravo/hardlink"])
+
+        alpha_ino = self.mount_a.path_to_ino("alpha/target")
+
+        # Ensure everything is written to backing store
+        self.mount_a.umount_wait()
+        self.fs.mds_asok(["flush", "journal"])
+
+        # Validate that the backtrace is present and decodable
+        self.fs.read_backtrace(alpha_ino)
+        # Go corrupt the backtrace of alpha/target (used for resolving
+        # bravo/hardlink).
+        self.fs._write_data_xattr(alpha_ino, "parent", "rhubarb")
+
+        # Drop everything from the MDS cache
+        self.mds_cluster.mds_stop()
+        self.fs.journal_tool(['journal', 'reset'])
+        self.mds_cluster.mds_fail_restart()
+        self.fs.wait_for_daemons()
+
+        # Check that touching the hardlink gives EIO
+        self.mount_a.mount()
+        ran = self.mount_a.run_shell(["ls", "-l", "bravo/hardlink"], wait=False)
+        try:
+            ran.wait()
+        except CommandFailedError:
+            self.assertTrue("Input/output error" in ran.stderr.getvalue())
+
+        # Check that an entry is created in the damage table
+        damage = json.loads(
+            self.fs.mon_manager.raw_cluster_cmd(
+                'tell', 'mds.{0}'.format(self.fs.get_active_names()[0]),
+                "damage", "ls", '--format=json-pretty'))
+        self.assertEqual(len(damage), 1)
+        self.assertEqual(damage[0]['damage_type'], "backtrace")
+        self.assertEqual(damage[0]['ino'], alpha_ino)