Whamcloud - gitweb
LU-17276 tests: performance test case for flock 58/53558/4
authorYang Sheng <ys@whamcloud.com>
Wed, 27 Dec 2023 18:26:41 +0000 (02:26 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 10 Jan 2024 07:29:23 +0000 (07:29 +0000)
Add some test cases for flock performance.

Test-Parameters: trivial testlist=performance-sanity env=ONLY=6,ONLY_REPEAT=50
Signed-off-by: Yang Sheng <ys@whamcloud.com>
Change-Id: Id76d38e14bec6a095fe26e22d08569731d4669c9
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53558
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alex Deiter <alex.deiter@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
lustre/tests/flocks_test.c
lustre/tests/performance-sanity.sh

index c82f635..476506e 100644 (file)
 #include <pthread.h>
 #include <sys/file.h>
 #include <sys/wait.h>
+#include <sys/time.h>
 #include <stdarg.h>
+#include <ctype.h>
 
 #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;
index 404835e..ba3833a 100644 (file)
@@ -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