From 6377859352b861861c7a46e1e9a11e4be75d626e Mon Sep 17 00:00:00 2001 From: Yang Sheng Date: Thu, 28 Dec 2023 02:26:41 +0800 Subject: [PATCH] LU-17276 tests: performance test case for flock Add some test cases for flock performance. Test-Parameters: trivial testlist=performance-sanity env=ONLY=6,ONLY_REPEAT=50 Signed-off-by: Yang Sheng Change-Id: Id76d38e14bec6a095fe26e22d08569731d4669c9 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53558 Reviewed-by: Andreas Dilger Reviewed-by: Alex Deiter Reviewed-by: Oleg Drokin Tested-by: Maloo Tested-by: jenkins --- lustre/tests/flocks_test.c | 109 +++++++++++++++++++++++++++++++++++++ lustre/tests/performance-sanity.sh | 47 ++++++++++++++-- 2 files changed, 150 insertions(+), 6 deletions(-) diff --git a/lustre/tests/flocks_test.c b/lustre/tests/flocks_test.c index c82f635..476506e 100644 --- a/lustre/tests/flocks_test.c +++ b/lustre/tests/flocks_test.c @@ -38,9 +38,21 @@ #include #include #include +#include #include +#include #define MAX_PATH_LENGTH 4096 + + +static double now(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; +} + /** * helper functions */ @@ -586,6 +598,100 @@ static int t5(int argc, char *argv[]) } +#define T6BUF_SIZE 200 + +int set_lock(struct flock *lock, char *buf) +{ + int i, v; + struct tag_node { + char tag; + int mode; + } tags[] = { + { 'W', F_WRLCK }, + { 'R', F_RDLCK }, + { 'U', F_UNLCK }, + { 0, 0 } + }; + + for (i = 0; isspace(buf[i]) && i < T6BUF_SIZE;) + i++; + for (v = 0; tags[v].tag && i < T6BUF_SIZE; v++) { + if (buf[i] == tags[v].tag) { + char *head; + + head = buf + i + 1; + for (; buf[i] != ','; i++) + if (i >= T6BUF_SIZE) + break; + buf[i] = '\0'; + lock->l_start = atol(head); + if (lock->l_start < 0) + break; + for (; !isdigit(buf[i]); i++) + if (i >= T6BUF_SIZE) + break; + lock->l_len = atol(buf + i); + if (lock->l_len <= 0) + break; + lock->l_type = tags[v].mode; + return 1; + } + } + fprintf(stderr, "Invalid line: %s\n", buf); + return 0; +} + +/* + * Read command from stdin then enqueue a lock + * + * [W|R|U]sss,lll + * W: write R: read U: unlock + * sss: start of range + * lll: length of range + * + * for example: + * W1,100 # add a write lock from 1 to 100 + * R100,100 # add a read lock from 100 to 199 + */ +static int t6(int argc, char *argv[]) +{ + struct flock lock = { + .l_whence = SEEK_SET, + }; + + int fd, rc = 0; + char buf[T6BUF_SIZE+1]; + double stime; + + if (argc < 3) { + fprintf(stderr, "usage: flocks_test 6 file\n"); + return EXIT_FAILURE; + } + + fd = open(argv[2], O_RDWR); + if (fd < 0) { + fprintf(stderr, "Couldn't open file: %s\n", argv[2]); + return EXIT_FAILURE; + } + + memset(buf, '\0', T6BUF_SIZE + 1); + stime = now(); + while (fgets(buf, T6BUF_SIZE, stdin)) { + if (set_lock(&lock, buf)) { + rc = t_fcntl(fd, F_SETLKW, &lock); + if (rc != 0) { + fprintf(stderr, "%d: cannot set lock: %s\n", + getpid(), strerror(errno)); + rc = EXIT_FAILURE; + break; + } + } + } + close(fd); + printf("Time for processing %.03lfs\n", now() - stime); + return rc; +} + /** ============================================================== * program entry */ @@ -620,6 +726,9 @@ int main(int argc, char *argv[]) case 5: rc = t5(argc, argv); break; + case 6: + rc = t6(argc, argv); + break; default: fprintf(stderr, "unknown test number '%s'\n", argv[1]); break; diff --git a/lustre/tests/performance-sanity.sh b/lustre/tests/performance-sanity.sh index 404835e..ba3833a 100644 --- a/lustre/tests/performance-sanity.sh +++ b/lustre/tests/performance-sanity.sh @@ -13,16 +13,19 @@ init_logging ALWAYS_EXCEPT="$PERFORMANCE_SANITY_EXCEPT " build_test_filter -[[ -x "$MPIRUN" ]] || skip_env "no mpirun program found" -[[ -x "$MDTEST" ]] || skip_env "no mdtest program found" - check_and_setup_lustre -get_mpiuser_id $MPI_USER -MPI_RUNAS=${MPI_RUNAS:-"runas -u $MPI_USER_UID -g $MPI_USER_GID"} -$GSS_KRB5 && refresh_krb5_tgt $MPI_USER_UID $MPI_USER_GID $MPI_RUNAS +env_verify() +{ + [[ -x "$MPIRUN" ]] || skip_env "no mpirun program found" + [[ -x "$MDTEST" ]] || skip_env "no mdtest program found" + get_mpiuser_id $MPI_USER + MPI_RUNAS=${MPI_RUNAS:-"runas -u $MPI_USER_UID -g $MPI_USER_GID"} + $GSS_KRB5 && refresh_krb5_tgt $MPI_USER_UID $MPI_USER_GID $MPI_RUNAS +} test_1() { + env_verify echo "Small files creation performance test" # LU-2600/LU-4108 - Decrease load on zfs if [[ "$SLOW" == no && "$mds1_FSTYPE" == zfs ]]; then @@ -33,12 +36,14 @@ test_1() { run_test 1 "small files create/open/delete" test_2() { + env_verify echo "Large files creation performance test" run_mdtest create-large } run_test 2 "large files create/open/delete" test_3() { + env_verify NUM_DIRS=1 NUM_FILES=200000 echo "Single directory lookup rate for $NUM_FILES files" @@ -47,6 +52,7 @@ test_3() { run_test 3 "lookup rate 200k files in single directory" test_4() { + env_verify NUM_DIRS=100 NUM_FILES=200000 echo "Directory lookup rate $NUM_DIRS directories, $((NUM_FILES/NUM_DIRS)) files each" @@ -54,6 +60,35 @@ test_4() { } run_test 4 "lookup rate 200k files in 100 directories" +test_5() { + touch $DIR/$tfile + for((i=0; i < 20000; i++)) { + echo "W$((i * 10)), 5" + } | flocks_test 6 $DIR/$tfile + rm -r $DIR/$tfile +} +run_test 5 "enqueue 20k no overlap flocks on same file" + +test_6() { + touch $DIR/$tfile + for((i=0; i < 20000; i++)) { + [ $i -eq 0 ] && echo "W0,99999999" && continue + echo "R$((i * 10)), 5" + } | flocks_test 6 $DIR/$tfile + rm -r $DIR/$tfile +} +run_test 6 "split a flock 20k times" + +test_7() { + touch $DIR/$tfile + for((i=0; i < 20001; i++)) { + echo "R$((i * 10)), 5" + [ $i -eq 20000 ] && echo "W0,99999999" && continue + } | flocks_test 6 $DIR/$tfile + rm -r $DIR/$tfile +} +run_test 7 "merge 20k flocks" + complete_test $SECONDS check_and_cleanup_lustre exit_status -- 1.8.3.1