All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v3 1/2] splice02: Generate input in C
@ 2021-04-13  4:38 Petr Vorel
  2021-04-13  4:38 ` [LTP] [PATCH v3 2/2] commands: Add shell pipe test Petr Vorel
  2021-04-15 13:46 ` [LTP] [PATCH v3 1/2] splice02: Generate input in C Cyril Hrubis
  0 siblings, 2 replies; 7+ messages in thread
From: Petr Vorel @ 2021-04-13  4:38 UTC (permalink / raw)
  To: ltp

instead relying on shell piping data into it.

Found on SLES JeOS (https://progress.opensuse.org/issues/77260).

Also add metadata docs.

Reported-by: Martin Loviska <mloviska@suse.com>
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
changes v2->v3:
* fix bugs found by Cyril (use !num_writes, !SAFE_FORK(), break if !TST_RET)

BTW I'm still not sure if break on !TST_RET is needed, but it does not
harm. If you really like it, I can use while (!TST_RET).

Kind regards,
Petr

 runtest/smoketest                           |   2 +-
 runtest/syscalls                            |   2 +-
 testcases/kernel/syscalls/splice/splice02.c | 104 +++++++++++++++++---
 3 files changed, 94 insertions(+), 14 deletions(-)

diff --git a/runtest/smoketest b/runtest/smoketest
index 0c24fc1fa..ec0c088cb 100644
--- a/runtest/smoketest
+++ b/runtest/smoketest
@@ -11,5 +11,5 @@ symlink01 symlink01
 stat04 symlink01 -T stat04
 utime01A symlink01 -T utime01
 rename01A symlink01 -T rename01
-splice02 seq 1 20 | splice02
+splice02 splice02 -n 20
 route4-change-dst route-change-dst.sh
diff --git a/runtest/syscalls b/runtest/syscalls
index 2d1e7b648..b89c545f0 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1451,7 +1451,7 @@ socketpair02 socketpair02
 sockioctl01 sockioctl01
 
 splice01 splice01
-splice02 seq 1 20000 | splice02
+splice02 splice02
 splice03 splice03
 splice04 splice04
 splice05 splice05
diff --git a/testcases/kernel/syscalls/splice/splice02.c b/testcases/kernel/syscalls/splice/splice02.c
index b579667b9..fd71f2995 100644
--- a/testcases/kernel/syscalls/splice/splice02.c
+++ b/testcases/kernel/syscalls/splice/splice02.c
@@ -1,40 +1,120 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) Jens Axboe <axboe@kernel.dk>, 2009
+ * Copyright (c) 2021 Petr Vorel <pvorel@suse.cz>
+ */
+
+/*\
+ * [DESCRIPTION]
+ * Original reproducer for kernel fix
+ * bf40d3435caf NFS: add support for splice writes
+ * from v2.6.31-rc1.
+ *
  * http://lkml.org/lkml/2009/4/2/55
+ *
+ * [ALGORITHM]
+ * - create pipe
+ * - fork(), child replace stdin with pipe
+ * - parent write to pipe
+ * - child slice from pipe
+ * - check resulted file size
  */
 
 #define _GNU_SOURCE
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/stat.h>
 #include <unistd.h>
-#include <fcntl.h>
 
 #include "tst_test.h"
 #include "lapi/splice.h"
 
-#define SPLICE_SIZE (64*1024)
+#define WRITE_SIZE 1024
+#define TEST_FILENAME "splice02-temp"
+
+static char *narg;
+static int num_writes;
+static int pipe_fd[2];
+
+static void setup(void)
+{
+	if (tst_parse_int(narg, &num_writes, 1, INT_MAX))
+		tst_brk(TBROK, "invalid number of writes '%s'", narg);
+}
 
-static void splice_test(void)
+static void do_child(void)
 {
-	int fd;
+	int fd, to_write = num_writes;
+	struct stat st;
+
+	SAFE_CLOSE(pipe_fd[1]);
+	SAFE_DUP2(pipe_fd[0], STDIN_FILENO);
 
-	fd = SAFE_OPEN("splice02-temp", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	fd = SAFE_OPEN(TEST_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0644);
 
-	TEST(splice(STDIN_FILENO, NULL, fd, NULL, SPLICE_SIZE, 0));
-	if (TST_RET < 0) {
-		tst_res(TFAIL, "splice failed - errno = %d : %s",
-			TST_ERR, strerror(TST_ERR));
-	} else {
-		tst_res(TPASS, "splice() system call Passed");
+	while (to_write > 0) {
+		TEST(splice(STDIN_FILENO, NULL, fd, NULL, WRITE_SIZE, 0));
+		tst_res(TINFO, "splice() wrote %ld, remaining %d", TST_RET, to_write);
+		if (TST_RET < 0) {
+			tst_res(TFAIL | TTERRNO, "splice failed");
+			goto cleanup;
+		} else if (!TST_RET) {
+			break;
+		} else {
+			to_write -= TST_RET;
+		}
 	}
 
+	stat(TEST_FILENAME, &st);
+	if (st.st_size != num_writes) {
+		tst_res(TFAIL, "file size is different from expected: %d (%d)",
+				st.st_size, num_writes);
+		return;
+	}
+
+	tst_res(TPASS, "splice() system call passed");
+
+cleanup:
 	SAFE_CLOSE(fd);
+	exit(0);
+}
+
+static void run(void)
+{
+	int i, max_pipe_size;
+
+	SAFE_PIPE(pipe_fd);
+
+	if (!num_writes) {
+		max_pipe_size = SAFE_FCNTL(pipe_fd[1], F_GETPIPE_SZ);
+		num_writes = max_pipe_size << 2;
+	}
+
+	if (!SAFE_FORK())
+		do_child();
+
+	tst_res(TINFO, "writting %d times", num_writes);
+
+	for (i = 0; i < num_writes; i++)
+		SAFE_WRITE(1, pipe_fd[1], "x", 1);
+
+	tst_reap_children();
+
+	SAFE_CLOSE(pipe_fd[0]);
+	SAFE_CLOSE(pipe_fd[1]);
 }
 
 static struct tst_test test = {
-	.test_all = splice_test,
+	.test_all = run,
+	.setup = setup,
+	.needs_checkpoints = 1,
 	.needs_tmpdir = 1,
+	.forks_child = 1,
 	.min_kver = "2.6.17",
+	.options = (struct tst_option[]) {
+		{"n:", &narg, "-n x     Number of writes (default 2x max pipe size)"},
+		{}
+	},
 };
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v3 2/2] commands: Add shell pipe test
  2021-04-13  4:38 [LTP] [PATCH v3 1/2] splice02: Generate input in C Petr Vorel
@ 2021-04-13  4:38 ` Petr Vorel
  2021-04-15 13:46 ` [LTP] [PATCH v3 1/2] splice02: Generate input in C Cyril Hrubis
  1 sibling, 0 replies; 7+ messages in thread
From: Petr Vorel @ 2021-04-13  4:38 UTC (permalink / raw)
  To: ltp

This adds basic shell pipe testing, which was removed from splice02
in 85cebe238 ("splice02: Generate input in C").

Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
The same as v2.

 runtest/commands                         |  1 +
 runtest/smoketest                        |  1 +
 testcases/commands/shell/shell_pipe01.sh | 17 +++++++++++++++++
 3 files changed, 19 insertions(+)
 create mode 100755 testcases/commands/shell/shell_pipe01.sh

diff --git a/runtest/commands b/runtest/commands
index 058266b54..8cfad0449 100644
--- a/runtest/commands
+++ b/runtest/commands
@@ -41,3 +41,4 @@ gdb01_sh gdb01.sh
 unshare01_sh unshare01.sh
 sysctl01_sh sysctl01.sh
 sysctl02_sh sysctl02.sh
+shell_test01 echo "SUCCESS" | shell_pipe01.sh
diff --git a/runtest/smoketest b/runtest/smoketest
index ec0c088cb..85f377192 100644
--- a/runtest/smoketest
+++ b/runtest/smoketest
@@ -13,3 +13,4 @@ utime01A symlink01 -T utime01
 rename01A symlink01 -T rename01
 splice02 splice02 -n 20
 route4-change-dst route-change-dst.sh
+shell_test01 echo "SUCCESS" | shell_pipe01.sh
diff --git a/testcases/commands/shell/shell_pipe01.sh b/testcases/commands/shell/shell_pipe01.sh
new file mode 100755
index 000000000..3c8ef49fb
--- /dev/null
+++ b/testcases/commands/shell/shell_pipe01.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2021 Petr Vorel <pvorel@suse.cz>
+
+TST_TESTFUNC=do_test
+
+. tst_test.sh
+
+do_test()
+{
+	tst_res TINFO "expecting SUCCESS string passed from stdin"
+
+	read line
+	EXPECT_PASS [ "$line" = "SUCCESS" ]
+}
+
+tst_run
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v3 1/2] splice02: Generate input in C
  2021-04-13  4:38 [LTP] [PATCH v3 1/2] splice02: Generate input in C Petr Vorel
  2021-04-13  4:38 ` [LTP] [PATCH v3 2/2] commands: Add shell pipe test Petr Vorel
@ 2021-04-15 13:46 ` Cyril Hrubis
  2021-04-15 14:11   ` Petr Vorel
  1 sibling, 1 reply; 7+ messages in thread
From: Cyril Hrubis @ 2021-04-15 13:46 UTC (permalink / raw)
  To: ltp

Hi!
> ---
> changes v2->v3:
> * fix bugs found by Cyril (use !num_writes, !SAFE_FORK(), break if !TST_RET)
> 
> BTW I'm still not sure if break on !TST_RET is needed, but it does not
> harm. If you really like it, I can use while (!TST_RET).

I meant that we could simplify the test with:

diff --git a/testcases/kernel/syscalls/splice/splice02.c b/testcases/kernel/syscalls/splice/splice02.c
index fd71f2995..1b566a2f4 100644
--- a/testcases/kernel/syscalls/splice/splice02.c
+++ b/testcases/kernel/syscalls/splice/splice02.c
@@ -54,18 +54,13 @@ static void do_child(void)
 
 	fd = SAFE_OPEN(TEST_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0644);
 
-	while (to_write > 0) {
+	do {
 		TEST(splice(STDIN_FILENO, NULL, fd, NULL, WRITE_SIZE, 0));
-		tst_res(TINFO, "splice() wrote %ld, remaining %d", TST_RET, to_write);
 		if (TST_RET < 0) {
 			tst_res(TFAIL | TTERRNO, "splice failed");
 			goto cleanup;
-		} else if (!TST_RET) {
-			break;
-		} else {
-			to_write -= TST_RET;
 		}
-	}
+	} while (TST_RET > 0);
 
 	stat(TEST_FILENAME, &st);
 	if (st.st_size != num_writes) {
@@ -100,10 +95,10 @@ static void run(void)
 	for (i = 0; i < num_writes; i++)
 		SAFE_WRITE(1, pipe_fd[1], "x", 1);
 
-	tst_reap_children();
-
 	SAFE_CLOSE(pipe_fd[0]);
 	SAFE_CLOSE(pipe_fd[1]);
+
+	tst_reap_children();
 }
 
 static struct tst_test test = {


If you close the pipe in the parent before reaping children the last
splice() will return 0 and exit the loop. No need to count anything.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v3 1/2] splice02: Generate input in C
  2021-04-15 13:46 ` [LTP] [PATCH v3 1/2] splice02: Generate input in C Cyril Hrubis
@ 2021-04-15 14:11   ` Petr Vorel
  2021-04-15 14:27     ` Petr Vorel
  0 siblings, 1 reply; 7+ messages in thread
From: Petr Vorel @ 2021-04-15 14:11 UTC (permalink / raw)
  To: ltp

Hi Cyril,

> I meant that we could simplify the test with:

> diff --git a/testcases/kernel/syscalls/splice/splice02.c b/testcases/kernel/syscalls/splice/splice02.c
> index fd71f2995..1b566a2f4 100644
> --- a/testcases/kernel/syscalls/splice/splice02.c
> +++ b/testcases/kernel/syscalls/splice/splice02.c
> @@ -54,18 +54,13 @@ static void do_child(void)

>  	fd = SAFE_OPEN(TEST_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0644);

> -	while (to_write > 0) {
> +	do {
>  		TEST(splice(STDIN_FILENO, NULL, fd, NULL, WRITE_SIZE, 0));
> -		tst_res(TINFO, "splice() wrote %ld, remaining %d", TST_RET, to_write);
>  		if (TST_RET < 0) {
>  			tst_res(TFAIL | TTERRNO, "splice failed");
>  			goto cleanup;
> -		} else if (!TST_RET) {
> -			break;
> -		} else {
> -			to_write -= TST_RET;
>  		}
> -	}
> +	} while (TST_RET > 0);

>  	stat(TEST_FILENAME, &st);
>  	if (st.st_size != num_writes) {
> @@ -100,10 +95,10 @@ static void run(void)
>  	for (i = 0; i < num_writes; i++)
>  		SAFE_WRITE(1, pipe_fd[1], "x", 1);

> -	tst_reap_children();
> -
>  	SAFE_CLOSE(pipe_fd[0]);
>  	SAFE_CLOSE(pipe_fd[1]);
> +
> +	tst_reap_children();
>  }

>  static struct tst_test test = {


> If you close the pipe in the parent before reaping children the last
> splice() will return 0 and exit the loop. No need to count anything.

LGTM, going to merge it with these changes (+ cleanup to_write)
and your Reviewed-by: tags.
Thanks a lot!

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v3 1/2] splice02: Generate input in C
  2021-04-15 14:11   ` Petr Vorel
@ 2021-04-15 14:27     ` Petr Vorel
  2021-04-16 12:32       ` Cyril Hrubis
  0 siblings, 1 reply; 7+ messages in thread
From: Petr Vorel @ 2021-04-15 14:27 UTC (permalink / raw)
  To: ltp

Hi Cyril,

> LGTM, going to merge it with these changes (+ cleanup to_write)
> and your Reviewed-by: tags.
> Thanks a lot!

Maybe one more change: INT_MAX is a bit too much, it timeouts.
I'll use 262144 as max allowed -n (the default on intel - 2x max pipe size).

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v3 1/2] splice02: Generate input in C
  2021-04-15 14:27     ` Petr Vorel
@ 2021-04-16 12:32       ` Cyril Hrubis
  2021-04-16 13:10         ` Petr Vorel
  0 siblings, 1 reply; 7+ messages in thread
From: Cyril Hrubis @ 2021-04-16 12:32 UTC (permalink / raw)
  To: ltp

Hi!
> > LGTM, going to merge it with these changes (+ cleanup to_write)
> > and your Reviewed-by: tags.
> > Thanks a lot!
> 
> Maybe one more change: INT_MAX is a bit too much, it timeouts.
> I'll use 262144 as max allowed -n (the default on intel - 2x max pipe size).

I guess that the main problem here is that we write one character at a
time, which means that we spend most of the time in syscall handler code
rather than copying the data. It may work much better if we change the
code to write 512 bytes at a time. I.e. something as:

	#define BUFSIZE 512

	char buf[BUFSIZE];

	memset(buf, 'a', BUFSIZE);

	while (to_write > 0) {
		size_t size = to_write > BUFSIZE ? BUFSIZE : to_write;

		...

		to_write -= written;
	}

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v3 1/2] splice02: Generate input in C
  2021-04-16 12:32       ` Cyril Hrubis
@ 2021-04-16 13:10         ` Petr Vorel
  0 siblings, 0 replies; 7+ messages in thread
From: Petr Vorel @ 2021-04-16 13:10 UTC (permalink / raw)
  To: ltp

Hi Cyril,

...
> > Maybe one more change: INT_MAX is a bit too much, it timeouts.
> > I'll use 262144 as max allowed -n (the default on intel - 2x max pipe size).

> I guess that the main problem here is that we write one character at a
> time, which means that we spend most of the time in syscall handler code
> rather than copying the data. It may work much better if we change the
> code to write 512 bytes at a time. I.e. something as:

Sounds very reasonable, thx! I'll send v4.

Kind regards,
Petr

> 	#define BUFSIZE 512

> 	char buf[BUFSIZE];

> 	memset(buf, 'a', BUFSIZE);

> 	while (to_write > 0) {
> 		size_t size = to_write > BUFSIZE ? BUFSIZE : to_write;

> 		...

> 		to_write -= written;
> 	}

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-04-16 13:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-13  4:38 [LTP] [PATCH v3 1/2] splice02: Generate input in C Petr Vorel
2021-04-13  4:38 ` [LTP] [PATCH v3 2/2] commands: Add shell pipe test Petr Vorel
2021-04-15 13:46 ` [LTP] [PATCH v3 1/2] splice02: Generate input in C Cyril Hrubis
2021-04-15 14:11   ` Petr Vorel
2021-04-15 14:27     ` Petr Vorel
2021-04-16 12:32       ` Cyril Hrubis
2021-04-16 13:10         ` Petr Vorel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.