Whamcloud - gitweb
LU-13745 test: add splice test for lustre 95/39695/6
authorWang Shilong <wshilong@ddn.com>
Sun, 6 Sep 2020 21:56:56 +0000 (17:56 -0400)
committerOleg Drokin <green@whamcloud.com>
Mon, 19 Oct 2020 03:13:13 +0000 (03:13 +0000)
copied from xfstests with adjustment with PAGE SIZE
alignement for DIO, and codes style cleanup.

Test-Parameters: trivial envdefinitions=ONLY=425 testlist=sanity
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Change-Id: I28e83abb4a1181db20a2564a10f40ca208bb2756
Reviewed-on: https://review.whamcloud.com/39695
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/tests/.gitignore
lustre/tests/Makefile.am
lustre/tests/sanity.sh
lustre/tests/splice-test.c [new file with mode: 0644]

index 5f6be9d..f06c5e9 100644 (file)
@@ -2,6 +2,7 @@
 /*.xml
 /Makefile.in
 /XMLCONFIG
 /*.xml
 /Makefile.in
 /XMLCONFIG
+/aiocp
 /badarea_io
 /check_fallocate
 /check_fhandle_syscalls
 /badarea_io
 /check_fallocate
 /check_fhandle_syscalls
@@ -78,6 +79,7 @@
 /sleeptest
 /small_write
 /smalliomany
 /sleeptest
 /small_write
 /smalliomany
+/splice-test
 /stat
 /statmany
 /statone
 /stat
 /statmany
 /statone
index c642e16..46fd861 100644 (file)
@@ -76,7 +76,7 @@ THETESTS += group_lock_test llapi_fid_test sendfile_grouplock mmap_cat
 THETESTS += swap_lock_test lockahead_test mirror_io mmap_mknod_test
 THETESTS += create_foreign_file parse_foreign_file
 THETESTS += create_foreign_dir parse_foreign_dir
 THETESTS += swap_lock_test lockahead_test mirror_io mmap_mknod_test
 THETESTS += create_foreign_file parse_foreign_file
 THETESTS += create_foreign_dir parse_foreign_dir
-THETESTS += check_fallocate
+THETESTS += check_fallocate splice-test
 if LIBAIO
 THETESTS += aiocp
 endif
 if LIBAIO
 THETESTS += aiocp
 endif
index 4212768..a6d2294 100755 (executable)
@@ -23449,6 +23449,14 @@ test_425() {
 }
 run_test 425 "lock count should not exceed lru size"
 
 }
 run_test 425 "lock count should not exceed lru size"
 
+test_426() {
+       splice-test -r $DIR/$tfile
+       splice-test -rd $DIR/$tfile
+       splice-test $DIR/$tfile
+       splice-test -d $DIR/$tfile
+}
+run_test 426 "splice test on Lustre"
+
 prep_801() {
        [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
        [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
 prep_801() {
        [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
        [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
diff --git a/lustre/tests/splice-test.c b/lustre/tests/splice-test.c
new file mode 100644 (file)
index 0000000..09ae140
--- /dev/null
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 RedHat Inc.  All Rights Reserved.
+ * Author: Andreas Gruenbacher <agruenba@redhat.com>
+ *
+ * Make sure that reading and writing to a pipe via splice.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <err.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+
+#define SECTOR_SIZE (sysconf(_SC_PAGESIZE))
+#define BUFFER_SIZE (150 * SECTOR_SIZE)
+
+void read_from_pipe(int fd, const char *filename, size_t size)
+{
+       char buffer[SECTOR_SIZE];
+       size_t sz;
+       ssize_t ret;
+
+       while (size) {
+               sz = size;
+               if (sz > sizeof(buffer))
+                       sz = sizeof(buffer);
+               ret = read(fd, buffer, sz);
+               if (ret < 0)
+                       err(1, "read: %s", filename);
+               if (ret == 0) {
+                       fprintf(stderr, "read: %s: unexpected EOF\n", filename);
+                       exit(1);
+               }
+               size -= sz;
+       }
+}
+
+void do_splice1(int fd, const char *filename, size_t size)
+{
+       bool retried = false;
+       int pipefd[2];
+
+       if (pipe(pipefd) == -1)
+               err(1, "pipe");
+       while (size) {
+               ssize_t spliced;
+
+               spliced = splice(fd, NULL, pipefd[1], NULL, size, SPLICE_F_MOVE);
+               if (spliced == -1) {
+                       if (errno == EAGAIN && !retried) {
+                               retried = true;
+                               fprintf(stderr, "retrying splice\n");
+                               sleep(1);
+                               continue;
+                       }
+                       err(1, "splice");
+               }
+               read_from_pipe(pipefd[0], filename, spliced);
+               size -= spliced;
+       }
+       close(pipefd[0]);
+       close(pipefd[1]);
+}
+
+void do_splice2(int fd, const char *filename, size_t size)
+{
+       bool retried = false;
+       int pipefd[2];
+       int pid;
+
+       if (pipe(pipefd) == -1)
+               err(1, "pipe");
+
+       pid = fork();
+       if (pid == 0) {
+               close(pipefd[1]);
+               read_from_pipe(pipefd[0], filename, size);
+               exit(0);
+       } else {
+               close(pipefd[0]);
+               while (size) {
+                       ssize_t spliced;
+
+                       spliced = splice(fd, NULL, pipefd[1], NULL, size, SPLICE_F_MOVE);
+                       if (spliced == -1) {
+                               if (errno == EAGAIN && !retried) {
+                                       retried = true;
+                                       fprintf(stderr, "retrying splice\n");
+                                       sleep(1);
+                                       continue;
+                               }
+                               err(1, "splice");
+                       }
+                       size -= spliced;
+               }
+               close(pipefd[1]);
+               waitpid(pid, NULL, 0);
+       }
+}
+
+void usage(const char *argv0)
+{
+       fprintf(stderr, "USAGE: %s [-rd] {filename}\n", basename(argv0));
+       exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+       void (*do_splice)(int fd, const char *filename, size_t size);
+       const char *filename;
+       char *buffer;
+       int opt, open_flags, fd;
+       ssize_t ret;
+
+       do_splice = do_splice1;
+       open_flags = O_CREAT | O_TRUNC | O_RDWR | O_DIRECT;
+
+       while ((opt = getopt(argc, argv, "rd")) != -1) {
+               switch (opt) {
+               case 'r':
+                       do_splice = do_splice2;
+                       break;
+               case 'd':
+                       open_flags &= ~O_DIRECT;
+                       break;
+               default:  /* '?' */
+                       usage(argv[0]);
+               }
+       }
+
+       if (optind >= argc)
+               usage(argv[0]);
+       filename = argv[optind];
+
+       printf("%s reader %s O_DIRECT\n",
+                  do_splice == do_splice1 ? "sequential" : "concurrent",
+                  (open_flags & O_DIRECT) ? "with" : "without");
+
+       buffer = aligned_alloc(SECTOR_SIZE, BUFFER_SIZE);
+       if (buffer == NULL)
+               err(1, "aligned_alloc");
+
+       fd = open(filename, open_flags, 0666);
+       if (fd == -1)
+               err(1, "open: %s", filename);
+
+       memset(buffer, 'x', BUFFER_SIZE);
+       ret = write(fd, buffer, BUFFER_SIZE);
+       if (ret < 0)
+               err(1, "write: %s", filename);
+       if (ret != BUFFER_SIZE) {
+               fprintf(stderr, "%s: short write\n", filename);
+               exit(1);
+       }
+
+       ret = lseek(fd, 0, SEEK_SET);
+       if (ret != 0)
+               err(1, "lseek: %s", filename);
+
+       do_splice(fd, filename, BUFFER_SIZE);
+
+       if (unlink(filename) == -1)
+               err(1, "unlink: %s", filename);
+
+       return 0;
+}