import logging from tasks.cephfs.cephfs_test_case import CephFSTestCase from teuthology.exceptions import CommandFailedError log = logging.getLogger(__name__) class TestSubvolume(CephFSTestCase): CLIENTS_REQUIRED = 1 MDSS_REQUIRED = 1 def setUp(self): super().setUp() self.setup_test() def tearDown(self): # clean up self.cleanup_test() super().tearDown() def setup_test(self): self.mount_a.run_shell(['mkdir', 'group']) self.mount_a.run_shell(['mkdir', 'group/subvol1']) self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume', '-v', '1', 'group/subvol1']) self.mount_a.run_shell(['mv', 'group/subvol1', 'group/subvol2']) def cleanup_test(self): self.mount_a.run_shell(['rm', '-rf', 'group']) def test_subvolume_move_out_file(self): """ To verify that file can't be moved out of subvolume """ self.mount_a.run_shell(['touch', 'group/subvol2/file1']) # file can't be moved out of a subvolume with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['rename', 'group/subvol2/file1', 'group/file1', 'group/subvol2/file1']) def test_subvolume_move_in_file(self): """ To verify that file can't be moved into subvolume """ # file can't be moved into a subvolume self.mount_a.run_shell(['touch', 'group/file2']) with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['rename', 'group/file2', 'group/subvol2/file2', 'group/file2']) def test_subvolume_hardlink_to_outside(self): """ To verify that file can't be hardlinked to outside subvolume """ self.mount_a.run_shell(['touch', 'group/subvol2/file1']) # create hard link within subvolume self.mount_a.run_shell(['ln', 'group/subvol2/file1', 'group/subvol2/file1_']) # hard link can't be created out of subvolume with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['ln', 'group/subvol2/file1', 'group/file1_']) def test_subvolume_hardlink_to_inside(self): """ To verify that file can't be hardlinked to inside subvolume """ self.mount_a.run_shell(['touch', 'group/subvol2/file1']) # create hard link within subvolume self.mount_a.run_shell(['ln', 'group/subvol2/file1', 'group/subvol2/file1_']) # hard link can't be created inside subvolume self.mount_a.run_shell(['touch', 'group/file2']) with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['ln', 'group/file2', 'group/subvol2/file2_']) def test_subvolume_snapshot_inside_subvolume_subdir(self): """ To verify that snapshot can't be taken for a subvolume subdir """ self.mount_a.run_shell(['touch', 'group/subvol2/file1']) # create snapshot at subvolume root self.mount_a.run_shell(['mkdir', 'group/subvol2/.snap/s1']) # can't create snapshot in a descendent dir of subvolume self.mount_a.run_shell(['mkdir', 'group/subvol2/dir']) with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['mkdir', 'group/subvol2/dir/.snap/s2']) # clean up self.mount_a.run_shell(['rmdir', 'group/subvol2/.snap/s1']) def test_subvolume_file_move_across_subvolumes(self): """ To verify that file can't be moved across subvolumes """ self.mount_a.run_shell(['touch', 'group/subvol2/file1']) # create another subvol self.mount_a.run_shell(['mkdir', 'group/subvol3']) self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume', '-v', '1', 'group/subvol3']) # can't move file across subvolumes with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['rename', 'group/subvol2/file1', 'group/subvol3/file1', 'group/subvol2/file1']) def test_subvolume_hardlink_across_subvolumes(self): """ To verify that hardlink can't be created across subvolumes """ self.mount_a.run_shell(['touch', 'group/subvol2/file1']) # create another subvol self.mount_a.run_shell(['mkdir', 'group/subvol3']) self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume', '-v', '1', 'group/subvol3']) # can't create hard link across subvolumes with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['ln', 'group/subvol2/file1', 'group/subvol3/file1']) def test_subvolume_create_subvolume_inside_subvolume(self): """ To verify that subvolume can't be created inside a subvolume """ # can't create subvolume inside a subvolume self.mount_a.run_shell(['mkdir', 'group/subvol2/dir']) with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume', '-v', '1', 'group/subvol2/dir']) def test_subvolume_create_snapshot_inside_new_subvolume_parent(self): """ To verify that subvolume can't be created inside a new subvolume parent """ self.mount_a.run_shell(['touch', 'group/subvol2/file1']) # clear subvolume flag self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume', '-v', '0', 'group/subvol2']) # create a snap self.mount_a.run_shell(['mkdir', 'group/subvol2/dir']) self.mount_a.run_shell(['mkdir', 'group/subvol2/dir/.snap/s2']) # override subdir subvolume with parent subvolume self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume', '-v', '1', 'group/subvol2/dir']) self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume', '-v', '1', 'group/subvol2']) # can't create a snap in a subdir of a subvol parent with self.assertRaises(CommandFailedError): self.mount_a.run_shell(['mkdir', 'group/subvol2/dir/.snap/s3']) # clean up self.mount_a.run_shell(['rmdir', 'group/subvol2/dir/.snap/s2'])