public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases
@ 2019-03-19  6:49 Sumit Garg
  2019-03-19  6:49 ` [LTP] [PATCH v3 1/3] syscalls/tgkill01: add new test Sumit Garg
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Sumit Garg @ 2019-03-19  6:49 UTC (permalink / raw)
  To: ltp

This patch-set is inherited from Greg which adds test-cases for tgkill
syscall.

Changes in v3:
- Use checkpoint library to keep threads asleep while waiting for
  signals.
- Start threads during test setup() rather than test run().

Changes in v2:
- Free allocated memory for threads.
- Remove redundant call to stop_threads().
- Apply reviewed-by tag.

Greg Hackmann (3):
  syscalls/tgkill01: add new test
  syscalls/tgkill02: add new test
  syscalls/tgkill03: add new test

 runtest/syscalls                            |   4 +
 testcases/kernel/syscalls/tgkill/.gitignore |   3 +
 testcases/kernel/syscalls/tgkill/Makefile   |  10 +++
 testcases/kernel/syscalls/tgkill/tgkill.h   |  22 +++++
 testcases/kernel/syscalls/tgkill/tgkill01.c | 134 ++++++++++++++++++++++++++++
 testcases/kernel/syscalls/tgkill/tgkill02.c |  68 ++++++++++++++
 testcases/kernel/syscalls/tgkill/tgkill03.c | 110 +++++++++++++++++++++++
 7 files changed, 351 insertions(+)
 create mode 100644 testcases/kernel/syscalls/tgkill/.gitignore
 create mode 100644 testcases/kernel/syscalls/tgkill/Makefile
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill.h
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill01.c
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill02.c
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill03.c

-- 
2.7.4


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

* [LTP] [PATCH v3 1/3] syscalls/tgkill01: add new test
  2019-03-19  6:49 [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Sumit Garg
@ 2019-03-19  6:49 ` Sumit Garg
  2019-03-19 13:55   ` Cyril Hrubis
  2019-03-19  6:49 ` [LTP] [PATCH v3 2/3] syscalls/tgkill02: " Sumit Garg
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Sumit Garg @ 2019-03-19  6:49 UTC (permalink / raw)
  To: ltp

From: Greg Hackmann <ghackmann@google.com>

tgkill() delivers a signal to a specific thread.  Test this by
installing a SIGUSR1 handler which records the current pthread ID.
Start a number of threads in parallel, then one-by-one call tgkill(...,
tid, SIGUSR1) and check that the expected pthread ID was recorded.

Signed-off-by: Greg Hackmann <ghackmann@google.com>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Li Wang <liwang@redhat.com>
---
 runtest/syscalls                            |   2 +
 testcases/kernel/syscalls/tgkill/.gitignore |   1 +
 testcases/kernel/syscalls/tgkill/Makefile   |  10 +++
 testcases/kernel/syscalls/tgkill/tgkill.h   |  22 +++++
 testcases/kernel/syscalls/tgkill/tgkill01.c | 134 ++++++++++++++++++++++++++++
 5 files changed, 169 insertions(+)
 create mode 100644 testcases/kernel/syscalls/tgkill/.gitignore
 create mode 100644 testcases/kernel/syscalls/tgkill/Makefile
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill.h
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill01.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 03b613c..d6999f0 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1400,6 +1400,8 @@ syslog10 syslog10
 syslog11 syslog11
 syslog12 syslog12
 
+tgkill01 tgkill01
+
 time01 time01
 time02 time02
 
diff --git a/testcases/kernel/syscalls/tgkill/.gitignore b/testcases/kernel/syscalls/tgkill/.gitignore
new file mode 100644
index 0000000..f4566fd
--- /dev/null
+++ b/testcases/kernel/syscalls/tgkill/.gitignore
@@ -0,0 +1 @@
+tgkill01
diff --git a/testcases/kernel/syscalls/tgkill/Makefile b/testcases/kernel/syscalls/tgkill/Makefile
new file mode 100644
index 0000000..a51080c
--- /dev/null
+++ b/testcases/kernel/syscalls/tgkill/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2018 Google, Inc.
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+LDLIBS			+= -pthread
diff --git a/testcases/kernel/syscalls/tgkill/tgkill.h b/testcases/kernel/syscalls/tgkill/tgkill.h
new file mode 100644
index 0000000..a7d96f4
--- /dev/null
+++ b/testcases/kernel/syscalls/tgkill/tgkill.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2018 Google, Inc.
+ */
+
+#ifndef TGKILL_H
+#define TGKILL_H
+
+#include "config.h"
+#include "lapi/syscalls.h"
+
+static inline int sys_tgkill(int tgid, int tid, int sig)
+{
+	return tst_syscall(__NR_tgkill, tgid, tid, sig);
+}
+
+static inline pid_t sys_gettid(void)
+{
+	return tst_syscall(__NR_gettid);
+}
+
+#endif /* TGKILL_H */
diff --git a/testcases/kernel/syscalls/tgkill/tgkill01.c b/testcases/kernel/syscalls/tgkill/tgkill01.c
new file mode 100644
index 0000000..075bf48
--- /dev/null
+++ b/testcases/kernel/syscalls/tgkill/tgkill01.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2018 Google, Inc.
+ *
+ * tgkill() delivers a signal to a specific thread.  Test this by installing
+ * a SIGUSR1 handler which records the current pthread ID.  Start a number
+ * of threads in parallel, then one-by-one call tgkill(..., tid, SIGUSR1)
+ * and check that the expected pthread ID was recorded.
+ */
+
+#include <pthread.h>
+#include <stdlib.h>
+
+#include "tst_safe_pthread.h"
+#include "tst_test.h"
+#include "tgkill.h"
+
+struct thread_state {
+	pthread_t thread;
+	pid_t tid;
+};
+
+static char *str_threads;
+static int n_threads = 10;
+static struct thread_state *threads;
+
+static pthread_t sigusr1_thread;
+
+static void sigusr1_handler(int signum __attribute__((unused)))
+{
+	sigusr1_thread = pthread_self();
+}
+
+static void *thread_func(void *arg)
+{
+	struct thread_state *thread = arg;
+
+	/**
+	 * There is no standard way to map pthread -> tid, so we will have the
+	 * child stash its own tid then notify the parent that the stashed tid
+	 * is available.
+	 */
+	thread->tid = sys_gettid();
+
+	TST_CHECKPOINT_WAKE(0);
+
+	TST_CHECKPOINT_WAIT(1);
+
+	return arg;
+}
+
+static void start_thread(struct thread_state *thread)
+{
+	SAFE_PTHREAD_CREATE(&thread->thread, NULL, thread_func, thread);
+
+	TST_CHECKPOINT_WAIT(0);
+}
+
+static void stop_threads(void)
+{
+	int i;
+
+	TST_CHECKPOINT_WAKE2(1, n_threads);
+
+	for (i = 0; i < n_threads; i++) {
+		if (threads[i].tid == -1)
+			continue;
+
+		SAFE_PTHREAD_JOIN(threads[i].thread, NULL);
+		threads[i].tid = -1;
+	}
+
+	if (threads)
+		free(threads);
+}
+
+static void run(void)
+{
+	int i;
+
+	for (i = 0; i < n_threads; i++) {
+		sigusr1_thread = pthread_self();
+
+		TEST(sys_tgkill(getpid(), threads[i].tid, SIGUSR1));
+		if (TST_RET) {
+			tst_res(TFAIL | TTERRNO, "tgkill() failed");
+			return;
+		}
+
+		while (pthread_equal(sigusr1_thread, pthread_self()))
+			usleep(1000);
+
+		if (!pthread_equal(sigusr1_thread, threads[i].thread)) {
+			tst_res(TFAIL, "SIGUSR1 delivered to wrong thread");
+			return;
+		}
+	}
+
+	tst_res(TPASS, "SIGUSR1 delivered to correct threads");
+}
+
+static void setup(void)
+{
+	int i;
+
+	if (tst_parse_int(str_threads, &n_threads, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of threads '%s'", str_threads);
+
+	threads = SAFE_MALLOC(sizeof(*threads) * n_threads);
+
+	struct sigaction sigusr1 = {
+		.sa_handler = sigusr1_handler,
+	};
+	SAFE_SIGACTION(SIGUSR1, &sigusr1, NULL);
+
+	for (i = 0; i < n_threads; i++)
+		threads[i].tid = -1;
+
+	for (i = 0; i < n_threads; i++)
+		start_thread(&threads[i]);
+}
+
+static struct tst_option options[] = {
+	{"t:", &str_threads, "-t       Number of threads (default 10)"},
+	{NULL, NULL, NULL},
+};
+
+static struct tst_test test = {
+	.options = options,
+	.needs_checkpoints = 1,
+	.setup = setup,
+	.test_all = run,
+	.cleanup = stop_threads,
+};
-- 
2.7.4


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

* [LTP] [PATCH v3 2/3] syscalls/tgkill02: add new test
  2019-03-19  6:49 [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Sumit Garg
  2019-03-19  6:49 ` [LTP] [PATCH v3 1/3] syscalls/tgkill01: add new test Sumit Garg
@ 2019-03-19  6:49 ` Sumit Garg
  2019-03-19  6:49 ` [LTP] [PATCH v3 3/3] syscalls/tgkill03: " Sumit Garg
  2019-03-19 13:54 ` [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Cyril Hrubis
  3 siblings, 0 replies; 12+ messages in thread
From: Sumit Garg @ 2019-03-19  6:49 UTC (permalink / raw)
  To: ltp

From: Greg Hackmann <ghackmann@google.com>

tgkill() should fail with EAGAIN when RLIMIT_SIGPENDING is reached with
a real-time signal.  Test this by starting a child thread with SIGRTMIN
blocked and a limit of 0 pending signals, then attempting to deliver
SIGRTMIN from the parent thread.

Signed-off-by: Greg Hackmann <ghackmann@google.com>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Li Wang <liwang@redhat.com>
---
 runtest/syscalls                            |  1 +
 testcases/kernel/syscalls/tgkill/.gitignore |  1 +
 testcases/kernel/syscalls/tgkill/tgkill02.c | 68 +++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill02.c

diff --git a/runtest/syscalls b/runtest/syscalls
index d6999f0..7af9136 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1401,6 +1401,7 @@ syslog11 syslog11
 syslog12 syslog12
 
 tgkill01 tgkill01
+tgkill02 tgkill02
 
 time01 time01
 time02 time02
diff --git a/testcases/kernel/syscalls/tgkill/.gitignore b/testcases/kernel/syscalls/tgkill/.gitignore
index f4566fd..42be2bb 100644
--- a/testcases/kernel/syscalls/tgkill/.gitignore
+++ b/testcases/kernel/syscalls/tgkill/.gitignore
@@ -1 +1,2 @@
 tgkill01
+tgkill02
diff --git a/testcases/kernel/syscalls/tgkill/tgkill02.c b/testcases/kernel/syscalls/tgkill/tgkill02.c
new file mode 100644
index 0000000..88f3842
--- /dev/null
+++ b/testcases/kernel/syscalls/tgkill/tgkill02.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2018 Google, Inc.
+ *
+ * tgkill() should fail with EAGAIN when RLIMIT_SIGPENDING is reached with a
+ * real-time signal.  Test this by starting a child thread with SIGRTMIN
+ * blocked and a limit of 0 pending signals, then attempting to deliver
+ * SIGRTMIN from the parent thread.
+ */
+
+#include <pthread.h>
+#include <signal.h>
+
+#include "tst_safe_pthread.h"
+#include "tst_test.h"
+#include "tgkill.h"
+
+static void *thread_func(void *arg)
+{
+	const struct rlimit sigpending = {
+		.rlim_cur = 0,
+		.rlim_max = 0,
+	};
+	sigset_t sigrtmin;
+	int err;
+	pid_t *tid = arg;
+
+	sigemptyset(&sigrtmin);
+	sigaddset(&sigrtmin, SIGRTMIN);
+
+	err = pthread_sigmask(SIG_BLOCK, &sigrtmin, NULL);
+	if (err)
+		tst_brk(TBROK, "pthread_sigmask() failed: %s",
+			tst_strerrno(err));
+
+	SAFE_SETRLIMIT(RLIMIT_SIGPENDING, &sigpending);
+	*tid = sys_gettid();
+
+	TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+	return arg;
+}
+
+static void run(void)
+{
+	pthread_t thread;
+	pid_t tid = -1;
+
+	SAFE_PTHREAD_CREATE(&thread, NULL, thread_func, &tid);
+
+	TST_CHECKPOINT_WAIT(0);
+
+	TEST(sys_tgkill(getpid(), tid, SIGRTMIN));
+	if (TST_RET && TST_ERR == EAGAIN)
+		tst_res(TPASS, "tgkill() failed with EAGAIN as expected");
+	else
+		tst_res(TFAIL | TTERRNO,
+			"tgkill() should have failed with EAGAIN");
+
+	TST_CHECKPOINT_WAKE(0);
+
+	SAFE_PTHREAD_JOIN(thread, NULL);
+}
+
+static struct tst_test test = {
+	.needs_checkpoints = 1,
+	.test_all = run,
+};
-- 
2.7.4


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

* [LTP] [PATCH v3 3/3] syscalls/tgkill03: add new test
  2019-03-19  6:49 [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Sumit Garg
  2019-03-19  6:49 ` [LTP] [PATCH v3 1/3] syscalls/tgkill01: add new test Sumit Garg
  2019-03-19  6:49 ` [LTP] [PATCH v3 2/3] syscalls/tgkill02: " Sumit Garg
@ 2019-03-19  6:49 ` Sumit Garg
  2019-03-19 13:56   ` Cyril Hrubis
  2019-06-15 23:08   ` Jan Stancek
  2019-03-19 13:54 ` [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Cyril Hrubis
  3 siblings, 2 replies; 12+ messages in thread
From: Sumit Garg @ 2019-03-19  6:49 UTC (permalink / raw)
  To: ltp

From: Greg Hackmann <ghackmann@google.com>

Test simple tgkill() error cases.

Signed-off-by: Greg Hackmann <ghackmann@google.com>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Li Wang <liwang@redhat.com>
---
 runtest/syscalls                            |   1 +
 testcases/kernel/syscalls/tgkill/.gitignore |   1 +
 testcases/kernel/syscalls/tgkill/tgkill03.c | 110 ++++++++++++++++++++++++++++
 3 files changed, 112 insertions(+)
 create mode 100644 testcases/kernel/syscalls/tgkill/tgkill03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 7af9136..b090408 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1402,6 +1402,7 @@ syslog12 syslog12
 
 tgkill01 tgkill01
 tgkill02 tgkill02
+tgkill03 tgkill03
 
 time01 time01
 time02 time02
diff --git a/testcases/kernel/syscalls/tgkill/.gitignore b/testcases/kernel/syscalls/tgkill/.gitignore
index 42be2bb..a6d2299 100644
--- a/testcases/kernel/syscalls/tgkill/.gitignore
+++ b/testcases/kernel/syscalls/tgkill/.gitignore
@@ -1,2 +1,3 @@
 tgkill01
 tgkill02
+tgkill03
diff --git a/testcases/kernel/syscalls/tgkill/tgkill03.c b/testcases/kernel/syscalls/tgkill/tgkill03.c
new file mode 100644
index 0000000..b78e9d9
--- /dev/null
+++ b/testcases/kernel/syscalls/tgkill/tgkill03.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2018 Google, Inc.
+ *
+ * Test simple tgkill() error cases.
+ */
+
+#include <pthread.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+#include "tst_safe_pthread.h"
+#include "tst_test.h"
+#include "tgkill.h"
+
+static pthread_t child_thread;
+
+static pid_t parent_tgid;
+static pid_t parent_tid;
+static pid_t child_tid;
+static pid_t defunct_tid;
+
+static const int invalid_pid = -1;
+
+static void *child_thread_func(void *arg)
+{
+	child_tid = sys_gettid();
+
+	TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+	return arg;
+}
+
+static void *defunct_thread_func(void *arg)
+{
+	defunct_tid = sys_gettid();
+
+	return arg;
+}
+
+static void setup(void)
+{
+	sigset_t sigusr1;
+	pthread_t defunct_thread;
+
+	sigemptyset(&sigusr1);
+	sigaddset(&sigusr1, SIGUSR1);
+	pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);
+
+	parent_tgid = getpid();
+	parent_tid = sys_gettid();
+
+	SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func, NULL);
+
+	TST_CHECKPOINT_WAIT(0);
+
+	SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func, NULL);
+
+	SAFE_PTHREAD_JOIN(defunct_thread, NULL);
+}
+
+static void cleanup(void)
+{
+	TST_CHECKPOINT_WAKE(0);
+
+	SAFE_PTHREAD_JOIN(child_thread, NULL);
+}
+
+static const struct testcase {
+	const char *desc;
+	const int *tgid;
+	const int *tid;
+	const int sig;
+	const int err;
+} testcases[] = {
+	{ "Invalid tgid", &invalid_pid, &parent_tid, SIGUSR1, EINVAL },
+	{ "Invalid tid", &parent_tgid, &invalid_pid, SIGUSR1, EINVAL },
+	{ "Invalid signal", &parent_tgid, &parent_tid, -1, EINVAL },
+	{ "Defunct thread ID", &parent_tgid, &defunct_tid, SIGUSR1, ESRCH },
+	{ "Valid tgkill call", &parent_tgid, &child_tid, SIGUSR1, 0 },
+};
+
+static void run(unsigned int i)
+{
+	const struct testcase *tc = &testcases[i];
+
+	TEST(sys_tgkill(*tc->tgid, *tc->tid, tc->sig));
+	if (tc->err) {
+		if (TST_RET < 0 && TST_ERR == tc->err)
+			tst_res(TPASS | TTERRNO, "%s failed as expected",
+				tc->desc);
+		else
+			tst_res(TFAIL | TTERRNO,
+				"%s should have failed with %s", tc->desc,
+				tst_strerrno(tc->err));
+	} else {
+		if (TST_RET == 0)
+			tst_res(TPASS, "%s succeeded", tc->desc);
+		else
+			tst_res(TFAIL | TTERRNO, "%s failed", tc->desc);
+	}
+}
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(testcases),
+	.needs_checkpoints = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test = run,
+};
-- 
2.7.4


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

* [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases
  2019-03-19  6:49 [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Sumit Garg
                   ` (2 preceding siblings ...)
  2019-03-19  6:49 ` [LTP] [PATCH v3 3/3] syscalls/tgkill03: " Sumit Garg
@ 2019-03-19 13:54 ` Cyril Hrubis
  2019-03-20  7:43   ` Sumit Garg
  3 siblings, 1 reply; 12+ messages in thread
From: Cyril Hrubis @ 2019-03-19 13:54 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with minor changes, thanks.

Also we are still missing the EPERM error case, for that we would have
to start the test as root, fork a child change the UID and GID and
attempt to send a signal to parent process.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 1/3] syscalls/tgkill01: add new test
  2019-03-19  6:49 ` [LTP] [PATCH v3 1/3] syscalls/tgkill01: add new test Sumit Garg
@ 2019-03-19 13:55   ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-03-19 13:55 UTC (permalink / raw)
  To: ltp

Hi!
> --- /dev/null
> +++ b/testcases/kernel/syscalls/tgkill/Makefile
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2018 Google, Inc.
> +
> +top_srcdir		?= ../../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> +
> +LDLIBS			+= -pthread

I've changed this to CFLAGS += -pthread since that is only supported way
how to compile programs with pthreads on Linux.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 3/3] syscalls/tgkill03: add new test
  2019-03-19  6:49 ` [LTP] [PATCH v3 3/3] syscalls/tgkill03: " Sumit Garg
@ 2019-03-19 13:56   ` Cyril Hrubis
  2019-06-15 23:08   ` Jan Stancek
  1 sibling, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-03-19 13:56 UTC (permalink / raw)
  To: ltp

Hi!
I've added one more ESRCH case here:

diff --git a/testcases/kernel/syscalls/tgkill/tgkill03.c b/testcases/kernel/syscalls/tgkill/tgkill03.c
index b78e9d95a..f5bbdc5a8 100644
--- a/testcases/kernel/syscalls/tgkill/tgkill03.c
+++ b/testcases/kernel/syscalls/tgkill/tgkill03.c
@@ -76,7 +76,8 @@ static const struct testcase {
        { "Invalid tgid", &invalid_pid, &parent_tid, SIGUSR1, EINVAL },
        { "Invalid tid", &parent_tgid, &invalid_pid, SIGUSR1, EINVAL },
        { "Invalid signal", &parent_tgid, &parent_tid, -1, EINVAL },
-       { "Defunct thread ID", &parent_tgid, &defunct_tid, SIGUSR1, ESRCH },
+       { "Defunct tid", &parent_tgid, &defunct_tid, SIGUSR1, ESRCH },
+       { "Defunct tgid", &defunct_tid, &child_tid, SIGUSR1, ESRCH },
        { "Valid tgkill call", &parent_tgid, &child_tid, SIGUSR1, 0 },
 };


-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases
  2019-03-19 13:54 ` [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Cyril Hrubis
@ 2019-03-20  7:43   ` Sumit Garg
  0 siblings, 0 replies; 12+ messages in thread
From: Sumit Garg @ 2019-03-20  7:43 UTC (permalink / raw)
  To: ltp

On Tue, 19 Mar 2019 at 19:25, Cyril Hrubis <chrubis@suse.cz> wrote:
>
> Hi!
> Pushed with minor changes, thanks.

Thanks for these changes and merge.

>
> Also we are still missing the EPERM error case, for that we would have
> to start the test as root, fork a child change the UID and GID and
> attempt to send a signal to parent process.
>

Hmm I see. I will try to add test case for this too.

-Sumit

> --
> Cyril Hrubis
> chrubis@suse.cz

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

* [LTP] [PATCH v3 3/3] syscalls/tgkill03: add new test
  2019-03-19  6:49 ` [LTP] [PATCH v3 3/3] syscalls/tgkill03: " Sumit Garg
  2019-03-19 13:56   ` Cyril Hrubis
@ 2019-06-15 23:08   ` Jan Stancek
  2019-06-16  4:22     ` Li Wang
  1 sibling, 1 reply; 12+ messages in thread
From: Jan Stancek @ 2019-06-15 23:08 UTC (permalink / raw)
  To: ltp


----- Original Message -----
> +static void setup(void)
> +{
> +	sigset_t sigusr1;
> +	pthread_t defunct_thread;
> +
> +	sigemptyset(&sigusr1);
> +	sigaddset(&sigusr1, SIGUSR1);
> +	pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);
> +
> +	parent_tgid = getpid();
> +	parent_tid = sys_gettid();
> +
> +	SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func, NULL);
> +
> +	TST_CHECKPOINT_WAIT(0);

I'm seeing reports of this test failing on s390x:

st_test.c:1096: INFO: Timeout per run is 0h 05m 00s
tgkill03.c:92: PASS: Invalid tgid failed as expected: EINVAL
tgkill03.c:92: PASS: Invalid tid failed as expected: EINVAL
tgkill03.c:92: PASS: Invalid signal failed as expected: EINVAL
tgkill03.c:96: FAIL: Defunct tid should have failed with ESRCH: SUCCESS
tgkill03.c:92: PASS: Defunct tgid failed as expected: ESRCH
tgkill03.c:99: PASS: Valid tgkill call succeeded

and I suspect this piece:

> +
> +	SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func, NULL);
> +
> +	SAFE_PTHREAD_JOIN(defunct_thread, NULL);
> +}

glibc pthread_join() waits for CLONE_CHILD_CLEARTID to clear tid,
and then resumes. Which kernel does at:
  do_exit
    exit_mm
      mm_release
        put_user(0, tsk->clear_child_tid);

so there's still work to be done after that, and I suspect tid is still valid
while that happens.

My first idea: wait until /proc/pid/task/<tid> disappears.

Regards,
Jan

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

* [LTP] [PATCH v3 3/3] syscalls/tgkill03: add new test
  2019-06-15 23:08   ` Jan Stancek
@ 2019-06-16  4:22     ` Li Wang
  2019-06-16  7:04       ` Jan Stancek
  0 siblings, 1 reply; 12+ messages in thread
From: Li Wang @ 2019-06-16  4:22 UTC (permalink / raw)
  To: ltp

On Sun, Jun 16, 2019 at 7:08 AM Jan Stancek <jstancek@redhat.com> wrote:

>
> ----- Original Message -----
> > +static void setup(void)
> > +{
> > +     sigset_t sigusr1;
> > +     pthread_t defunct_thread;
> > +
> > +     sigemptyset(&sigusr1);
> > +     sigaddset(&sigusr1, SIGUSR1);
> > +     pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);
> > +
> > +     parent_tgid = getpid();
> > +     parent_tid = sys_gettid();
> > +
> > +     SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func, NULL);
> > +
> > +     TST_CHECKPOINT_WAIT(0);
>
> I'm seeing reports of this test failing on s390x:
>
> st_test.c:1096: INFO: Timeout per run is 0h 05m 00s
> tgkill03.c:92: PASS: Invalid tgid failed as expected: EINVAL
> tgkill03.c:92: PASS: Invalid tid failed as expected: EINVAL
> tgkill03.c:92: PASS: Invalid signal failed as expected: EINVAL
> tgkill03.c:96: FAIL: Defunct tid should have failed with ESRCH: SUCCESS
> tgkill03.c:92: PASS: Defunct tgid failed as expected: ESRCH
> tgkill03.c:99: PASS: Valid tgkill call succeeded
>
> and I suspect this piece:
>
> > +
> > +     SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func,
> NULL);
> > +
> > +     SAFE_PTHREAD_JOIN(defunct_thread, NULL);
> > +}
>
> glibc pthread_join() waits for CLONE_CHILD_CLEARTID to clear tid,
> and then resumes. Which kernel does at:
>   do_exit
>     exit_mm
>       mm_release
>         put_user(0, tsk->clear_child_tid);
>
> so there's still work to be done after that, and I suspect tid is still
> valid
> while that happens.
>
> My first idea: wait until /proc/pid/task/<tid> disappears.
>

The anaysis is probably right, but this idea doesn't work for me. Seems
/proc/pid/task/<tid> is not the key point to confirm that tid has been
clear.

I just have a try as below:

===========
# for i in `seq 1000`; do echo "i = $i" && ./tgkill03 || break; done
...
i = 96
tst_test.c:1112: INFO: Timeout per run is 0h 05m 00s
tgkill03.c:106: FAIL: Defunct tid should have failed with ESRCH: SUCCESS

===========
--- a/testcases/kernel/syscalls/tgkill/tgkill03.c
+++ b/testcases/kernel/syscalls/tgkill/tgkill03.c
@@ -5,6 +5,7 @@
  * Test simple tgkill() error cases.
  */

+#include <stdio.h>
 #include <pthread.h>
 #include <pwd.h>
 #include <sys/types.h>
@@ -19,6 +20,7 @@ static pid_t parent_tgid;
 static pid_t parent_tid;
 static pid_t child_tid;
 static pid_t defunct_tid;
+char buf[1024];

 static const int invalid_pid = -1;

@@ -35,6 +37,8 @@ static void *defunct_thread_func(void *arg)
 {
        defunct_tid = sys_gettid();

+       sprintf(buf, "/proc/pid/task/%d", defunct_tid);
+
        return arg;
 }

@@ -73,18 +77,23 @@ static const struct testcase {
        const int sig;
        const int err;
 } testcases[] = {
-       { "Invalid tgid", &invalid_pid, &parent_tid, SIGUSR1, EINVAL },
-       { "Invalid tid", &parent_tgid, &invalid_pid, SIGUSR1, EINVAL },
-       { "Invalid signal", &parent_tgid, &parent_tid, -1, EINVAL },
+//     { "Invalid tgid", &invalid_pid, &parent_tid, SIGUSR1, EINVAL },
+//     { "Invalid tid", &parent_tgid, &invalid_pid, SIGUSR1, EINVAL },
+//     { "Invalid signal", &parent_tgid, &parent_tid, -1, EINVAL },
        { "Defunct tid", &parent_tgid, &defunct_tid, SIGUSR1, ESRCH },
-       { "Defunct tgid", &defunct_tid, &child_tid, SIGUSR1, ESRCH },
-       { "Valid tgkill call", &parent_tgid, &child_tid, SIGUSR1, 0 },
+//     { "Defunct tgid", &defunct_tid, &child_tid, SIGUSR1, ESRCH },
+//     { "Valid tgkill call", &parent_tgid, &child_tid, SIGUSR1, 0 },
 };

 static void run(unsigned int i)
 {
        const struct testcase *tc = &testcases[i];

+       // debug code //
+       while (access(buf, F_OK) == 0) {
+               tst_res(TINFO, "Debug: %s still exist!", buf);
+       }
+
        TEST(sys_tgkill(*tc->tgid, *tc->tid, tc->sig));
        if (tc->err) {
                if (TST_RET < 0 && TST_ERR == tc->err)


-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190616/e441e026/attachment.html>

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

* [LTP] [PATCH v3 3/3] syscalls/tgkill03: add new test
  2019-06-16  4:22     ` Li Wang
@ 2019-06-16  7:04       ` Jan Stancek
  2019-06-16  7:19         ` Li Wang
  0 siblings, 1 reply; 12+ messages in thread
From: Jan Stancek @ 2019-06-16  7:04 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> On Sun, Jun 16, 2019 at 7:08 AM Jan Stancek <jstancek@redhat.com> wrote:
> 
> >
> > ----- Original Message -----
> > > +static void setup(void)
> > > +{
> > > +     sigset_t sigusr1;
> > > +     pthread_t defunct_thread;
> > > +
> > > +     sigemptyset(&sigusr1);
> > > +     sigaddset(&sigusr1, SIGUSR1);
> > > +     pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);
> > > +
> > > +     parent_tgid = getpid();
> > > +     parent_tid = sys_gettid();
> > > +
> > > +     SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func, NULL);
> > > +
> > > +     TST_CHECKPOINT_WAIT(0);
> >
> > I'm seeing reports of this test failing on s390x:
> >
> > st_test.c:1096: INFO: Timeout per run is 0h 05m 00s
> > tgkill03.c:92: PASS: Invalid tgid failed as expected: EINVAL
> > tgkill03.c:92: PASS: Invalid tid failed as expected: EINVAL
> > tgkill03.c:92: PASS: Invalid signal failed as expected: EINVAL
> > tgkill03.c:96: FAIL: Defunct tid should have failed with ESRCH: SUCCESS
> > tgkill03.c:92: PASS: Defunct tgid failed as expected: ESRCH
> > tgkill03.c:99: PASS: Valid tgkill call succeeded
> >
> > and I suspect this piece:
> >
> > > +
> > > +     SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func,
> > NULL);
> > > +
> > > +     SAFE_PTHREAD_JOIN(defunct_thread, NULL);
> > > +}
> >
> > glibc pthread_join() waits for CLONE_CHILD_CLEARTID to clear tid,
> > and then resumes. Which kernel does at:
> >   do_exit
> >     exit_mm
> >       mm_release
> >         put_user(0, tsk->clear_child_tid);
> >
> > so there's still work to be done after that, and I suspect tid is still
> > valid
> > while that happens.
> >
> > My first idea: wait until /proc/pid/task/<tid> disappears.
> >
> 
> The anaysis is probably right, but this idea doesn't work for me. Seems
> /proc/pid/task/<tid> is not the key point to confirm that tid has been
> clear.
> 
> I just have a try as below:
> 
> ===========
> # for i in `seq 1000`; do echo "i = $i" && ./tgkill03 || break; done
> ...
> i = 96
> tst_test.c:1112: INFO: Timeout per run is 0h 05m 00s
> tgkill03.c:106: FAIL: Defunct tid should have failed with ESRCH: SUCCESS
> 
> ===========
> --- a/testcases/kernel/syscalls/tgkill/tgkill03.c
> +++ b/testcases/kernel/syscalls/tgkill/tgkill03.c
> @@ -5,6 +5,7 @@
>   * Test simple tgkill() error cases.
>   */
> 
> +#include <stdio.h>
>  #include <pthread.h>
>  #include <pwd.h>
>  #include <sys/types.h>
> @@ -19,6 +20,7 @@ static pid_t parent_tgid;
>  static pid_t parent_tid;
>  static pid_t child_tid;
>  static pid_t defunct_tid;
> +char buf[1024];
> 
>  static const int invalid_pid = -1;
> 
> @@ -35,6 +37,8 @@ static void *defunct_thread_func(void *arg)
>  {
>         defunct_tid = sys_gettid();
> 
> +       sprintf(buf, "/proc/pid/task/%d", defunct_tid);

How about?
          sprintf(buf, "/proc/%d/task/%d", getpid(), defunct_tid);



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

* [LTP] [PATCH v3 3/3] syscalls/tgkill03: add new test
  2019-06-16  7:04       ` Jan Stancek
@ 2019-06-16  7:19         ` Li Wang
  0 siblings, 0 replies; 12+ messages in thread
From: Li Wang @ 2019-06-16  7:19 UTC (permalink / raw)
  To: ltp

On Sun, Jun 16, 2019 at 3:04 PM Jan Stancek <jstancek@redhat.com> wrote:

>
>
> ----- Original Message -----
> > On Sun, Jun 16, 2019 at 7:08 AM Jan Stancek <jstancek@redhat.com> wrote:
> >
> > >
> > > ----- Original Message -----
> > > > +static void setup(void)
> > > > +{
> > > > +     sigset_t sigusr1;
> > > > +     pthread_t defunct_thread;
> > > > +
> > > > +     sigemptyset(&sigusr1);
> > > > +     sigaddset(&sigusr1, SIGUSR1);
> > > > +     pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);
> > > > +
> > > > +     parent_tgid = getpid();
> > > > +     parent_tid = sys_gettid();
> > > > +
> > > > +     SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func,
> NULL);
> > > > +
> > > > +     TST_CHECKPOINT_WAIT(0);
> > >
> > > I'm seeing reports of this test failing on s390x:
> > >
> > > st_test.c:1096: INFO: Timeout per run is 0h 05m 00s
> > > tgkill03.c:92: PASS: Invalid tgid failed as expected: EINVAL
> > > tgkill03.c:92: PASS: Invalid tid failed as expected: EINVAL
> > > tgkill03.c:92: PASS: Invalid signal failed as expected: EINVAL
> > > tgkill03.c:96: FAIL: Defunct tid should have failed with ESRCH: SUCCESS
> > > tgkill03.c:92: PASS: Defunct tgid failed as expected: ESRCH
> > > tgkill03.c:99: PASS: Valid tgkill call succeeded
> > >
> > > and I suspect this piece:
> > >
> > > > +
> > > > +     SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func,
> > > NULL);
> > > > +
> > > > +     SAFE_PTHREAD_JOIN(defunct_thread, NULL);
> > > > +}
> > >
> > > glibc pthread_join() waits for CLONE_CHILD_CLEARTID to clear tid,
> > > and then resumes. Which kernel does at:
> > >   do_exit
> > >     exit_mm
> > >       mm_release
> > >         put_user(0, tsk->clear_child_tid);
> > >
> > > so there's still work to be done after that, and I suspect tid is still
> > > valid
> > > while that happens.
> > >
> > > My first idea: wait until /proc/pid/task/<tid> disappears.
> > >
> >
> > The anaysis is probably right, but this idea doesn't work for me. Seems
> > /proc/pid/task/<tid> is not the key point to confirm that tid has been
> > clear.
> >
> > I just have a try as below:
> >
> > ===========
> > # for i in `seq 1000`; do echo "i = $i" && ./tgkill03 || break; done
> > ...
> > i = 96
> > tst_test.c:1112: INFO: Timeout per run is 0h 05m 00s
> > tgkill03.c:106: FAIL: Defunct tid should have failed with ESRCH: SUCCESS
> >
> > ===========
> > --- a/testcases/kernel/syscalls/tgkill/tgkill03.c
> > +++ b/testcases/kernel/syscalls/tgkill/tgkill03.c
> > @@ -5,6 +5,7 @@
> >   * Test simple tgkill() error cases.
> >   */
> >
> > +#include <stdio.h>
> >  #include <pthread.h>
> >  #include <pwd.h>
> >  #include <sys/types.h>
> > @@ -19,6 +20,7 @@ static pid_t parent_tgid;
> >  static pid_t parent_tid;
> >  static pid_t child_tid;
> >  static pid_t defunct_tid;
> > +char buf[1024];
> >
> >  static const int invalid_pid = -1;
> >
> > @@ -35,6 +37,8 @@ static void *defunct_thread_func(void *arg)
> >  {
> >         defunct_tid = sys_gettid();
> >
> > +       sprintf(buf, "/proc/pid/task/%d", defunct_tid);
>
> How about?
>           sprintf(buf, "/proc/%d/task/%d", getpid(), defunct_tid);
>
>
Ah, I was stupid to lost the getpid :-).

This look prettry good. The test fall into while loop when defunct_tid is
still exit, and get the expected result once /proc/pid/task/<tid>
disappears.

# for i in `seq 1000`; do echo "i = $i" && ./tgkill03 || break; done
...
i = 997
tst_test.c:1112: INFO: Timeout per run is 0h 05m 00s
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:95: INFO: Debug: /proc/5164/task/5166 still exist!
tgkill03.c:102: PASS: Defunct tgid failed as expected: ESRCH

Summary:
passed   1
failed   0
skipped  0
warnings 0
...
i = 1000
tst_test.c:1112: INFO: Timeout per run is 0h 05m 00s
tgkill03.c:102: PASS: Defunct tgid failed as expected: ESRCH

Summary:
passed   1
failed   0
skipped  0
warnings 0

-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190616/a5257eb4/attachment-0001.html>

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

end of thread, other threads:[~2019-06-16  7:19 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-03-19  6:49 [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Sumit Garg
2019-03-19  6:49 ` [LTP] [PATCH v3 1/3] syscalls/tgkill01: add new test Sumit Garg
2019-03-19 13:55   ` Cyril Hrubis
2019-03-19  6:49 ` [LTP] [PATCH v3 2/3] syscalls/tgkill02: " Sumit Garg
2019-03-19  6:49 ` [LTP] [PATCH v3 3/3] syscalls/tgkill03: " Sumit Garg
2019-03-19 13:56   ` Cyril Hrubis
2019-06-15 23:08   ` Jan Stancek
2019-06-16  4:22     ` Li Wang
2019-06-16  7:04       ` Jan Stancek
2019-06-16  7:19         ` Li Wang
2019-03-19 13:54 ` [LTP] [PATCH v3 0/3] syscalls: add tgkill test-cases Cyril Hrubis
2019-03-20  7:43   ` Sumit Garg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox