From a7aa6491c3c7153af0d0718084e433dee0a5f8a3 Mon Sep 17 00:00:00 2001 From: Christopher Hoffman Date: Tue, 24 Sep 2024 13:25:48 +0000 Subject: [PATCH] qa: Add tests of interopability of fscrypt between fuse/kernel Fixes: https://tracker.ceph.com/issues/66577 Signed-off-by: Christopher Hoffman --- qa/workunits/suites/fscrypt-snippets.py | 119 +++++++++++++++++++++++- 1 file changed, 115 insertions(+), 4 deletions(-) diff --git a/qa/workunits/suites/fscrypt-snippets.py b/qa/workunits/suites/fscrypt-snippets.py index 6984f18b9bf5b..0d861135d30c0 100755 --- a/qa/workunits/suites/fscrypt-snippets.py +++ b/qa/workunits/suites/fscrypt-snippets.py @@ -2,8 +2,11 @@ import hashlib import os +import sys from time import sleep +client_type = "" + def write_fill(fd, fill, size, offset): s = '' for i in range(0,size): @@ -12,6 +15,9 @@ def write_fill(fd, fill, size, offset): os.lseek(fd, offset - int(size / 2), 0) os.write(fd, str.encode(s)) +def run_strided_test(fuse_file, kernel_file, size, offset): + a = 1 + def test_overwrite_block_boundary(): """Test writing data with small, half write on previous block and trailing on new block""" @@ -80,7 +86,7 @@ def test_simple_rmw(): os.close(fd) if match_hash != m.hexdigest(): - raise + raise Exception os.remove(file) @@ -107,7 +113,7 @@ def test_truncate_overwrite(): os.close(fd2) if os.stat(file1).st_size != expected_size: - raise + raise Exception os.remove(file1) os.remove(file2) @@ -126,7 +132,7 @@ def test_truncate_path(): #fstest stat test1 size if os.lstat(file).st_size != expected_size: - raise + raise Exception #stat above command returns 69632 instead of truncated value. os.remove(file) @@ -149,12 +155,111 @@ def test_lchown_symlink(): #-rw-r--r--. 1 root root 0 Apr 22 18:11 file1 #lrwxrwxrwx. 1 135 579 46 Apr 22 18:11 symlink1 -> ''$'\266\310''%'$'\005''W'$'\335''.'$'\355\211''kblD'$'\300''gq'$'\002\236\367''3'$'\255\201\001''Z6;'$'\221''&'$'\216\331\177''Q' if os.readlink(file2) != file1: - raise + raise Exception os.remove(file1) os.remove(file2) +def test_900mhole_100mwrite(): + """ Test 900m hole 100m data write""" + + MB = 1024 * 1024 + offset = 900 * MB + data_size = 100 * MB + + contents = '' + fill = 'a' + + for i in range(0,data_size): + contents+= fill + + fuse_path = '/mnt/mycephfs/' + kernel_path='/mnt/kclient/' + + #file originated in kernel mount + kfile = 'kfile.log' + + #file originated in fuse mount + fuse_file = 'fuse_file.log' + + fd = os.open(kernel_path + kfile, os.O_WRONLY|os.O_CREAT) + os.lseek(fd, offset, 0) + os.write(fd, str.encode(contents)) + os.close(fd) + +def test_1gwrite_400m600mwrite(): + """ Test 200M overwrite of 1G file""" + + GB = 1024 * 1024 * 1024 + MB = 1024 * 1024 + + kfile = '/mnt/kclient/enc1/kfile.log' + fuse_file = '/mnt/mycephfs/enc1/kfile.log' + + contents = "a" * GB + + fd = os.open(kfile, os.O_WRONLY|os.O_CREAT) + os.write(fd, str.encode(contents)) + os.close(fd) + + overwrite_contents = "b" * 200 * MB + fd = os.open(fuse_file, os.O_WRONLY) + os.lseek(fd, 400 * MB, 0) + os.write(fd, str.encode(overwrite_contents)) + os.close(fd) + os.remove(kfile) + +def test_truncate_ladder(): + """ Test truncate down from 1GB""" + MB = 1024 * 1024 + + expected_sizes = [1024, 900, 500, 1] + + kfiles = ['/mnt/kclient/enc1/kfile.log', '/mnt/kclient/enc1/fuse_file.log'] + fuse_files = ['/mnt/mycephfs/enc1/kfile.log', '/mnt/mycephfs/enc1/fuse_file.log'] + KERNEL_INDEX = 0 + FUSE_INDEX = 1 + + #generate files from kernel + fd = os.open(kfiles[KERNEL_INDEX], os.O_WRONLY|os.O_CREAT) + os.close(fd) + for expected_size in expected_sizes: + os.truncate(kfiles[KERNEL_INDEX], expected_size) + stat_size = os.stat(fuse_files[KERNEL_INDEX]).st_size + if os.stat(fuse_files[KERNEL_INDEX]).st_size != expected_size: + print(f"{expected_size} vs {stat_size} path:=%s" % (kfiles[FUSE_INDEX])) + #raise Exception + #os.remove(kfiles[KERNEL_INDEX]) + + # generate files from fuse + fd = os.open(fuse_files[FUSE_INDEX], os.O_WRONLY|os.O_CREAT) + os.close(fd) + for expected_size in expected_sizes: + os.truncate(fuse_files[FUSE_INDEX], expected_size) + stat_size = os.stat(kfiles[FUSE_INDEX]).st_size + if stat_size != expected_size: + print(f"{expected_size} 1vs {stat_size} path:=%s" % (kfiles[FUSE_INDEX])) + #os.remove(fuse_files[FUSE_INDEX]) + +def test_strided_small_write(): + """ Test strided writes within a single fscrypt block""" + a = 1 + +def test_strided_regular_write(): + """ Test aligned strided writes on fscrypt block""" + b = 1 + +def test_unaligned_strided_write(): + """ Test unaligned strided write on fscrypt block""" + c = 1 + def main(): + if (len(sys.argv) == 2): + client_type = sys.argv[1] + else: + print("Usage is: %s " % sys.argv[0]) + sys.exit(1) + test_overwrite_block_boundary() test_huge_hole() test_med_hole_write_boundary() @@ -162,6 +267,12 @@ def main(): test_truncate_overwrite() test_truncate_path() test_lchown_symlink() + test_900mhole_100mwrite + test_1gwrite_400m600mwrite() + test_truncate_ladder() + test_strided_small_write() + test_strided_regular_write() + test_unaligned_strided_write() if __name__ == '__main__': main() -- 2.39.5