diff mbox series

[2/2] syscalls/pidfd_open04: Add new test with PIDFD_NONBLOCK flag

Message ID 1644399738-2155-2-git-send-email-xuyang2018.jy@fujitsu.com
State Changes Requested
Headers show
Series [1/2] syscalls/pidfd_open: Simplify code | expand

Commit Message

Yang Xu Feb. 9, 2022, 9:42 a.m. UTC
As pidfd_open man-page said
"PIDFD_NONBLOCK (since Linux 5.10)
Return a nonblocking file descriptor.  If the process referred to by
the file descriptor has not yet terminated, then an attempt to wait
on the file descriptor using waitid(2) will immediately  return
the error EAGAIN rather than blocking."

Test this and also test whether set NONBLOCK flag in its pidfd.

Noticed that, don't introduce lapi/pidfd.h because linux/pidfd.h uses
kernel header fcntl.h but ltp api uses libc header. so it may
exist redefinition error of 'struct flock'[1].

[1]https://github.com/golang/go/issues/48221

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 runtest/syscalls                              |  1 +
 .../kernel/syscalls/pidfd_open/.gitignore     |  1 +
 .../kernel/syscalls/pidfd_open/pidfd_open04.c | 78 +++++++++++++++++++
 3 files changed, 80 insertions(+)
 create mode 100644 testcases/kernel/syscalls/pidfd_open/pidfd_open04.c

Comments

Cyril Hrubis Feb. 9, 2022, 1:47 p.m. UTC | #1
Hi!
> diff --git a/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c b/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c
> new file mode 100644
> index 000000000..436351f23
> --- /dev/null
> +++ b/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
> + * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * Verify that the PIDFD_NONBLOCK flag works with pidfd_open() and
> + * that waitid() with a non-blocking pidfd returns EAGAIN.
> + */
> +
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/wait.h>
> +#include "tst_test.h"
> +#include "lapi/pidfd_open.h"
> +
> +#ifndef PIDFD_NONBLOCK
> +#define PIDFD_NONBLOCK O_NONBLOCK
> +#endif
> +
> +#ifndef P_PIDFD
> +#define P_PIDFD  3
> +#endif
> +
> +static void run(void)
> +{
> +	int flag, pid, pidfd;
> +	siginfo_t info;
> +
> +	pid = SAFE_FORK();
> +	if (!pid)
> +		pause();
> +
> +	TST_EXP_PID_SILENT(pidfd_open(pid, PIDFD_NONBLOCK),
> +				"pidfd_open(%d,  PIDFD_NONBLOCK)", pid);

Here as well FD_SILENT();

> +	pidfd = TST_RET;
> +	flag = fcntl(pidfd, F_GETFL);
> +	if (flag == -1)
> +		tst_brk(TFAIL | TERRNO, "fcntl(F_GETFL) failed");
> +
> +	if (!(flag & O_NONBLOCK))
> +		tst_brk(TFAIL, "pidfd_open(%d, O_NONBLOCK) didn't set O_NONBLOCK flag", pid);
> +
> +	tst_res(TPASS, "pidfd_open(%d, O_NONBLOCK) sets O_NONBLOCK flag", pid);
> +
> +	TST_EXP_FAIL(waitid(P_PIDFD, pidfd, &info, WEXITED), EAGAIN,
> +			"waitid(P_PIDFD,...,WEXITED)");
> +
> +	SAFE_KILL(pid, SIGTERM);
> +	SAFE_WAIT(NULL);
> +	SAFE_CLOSE(pidfd);

I guess that we can also test that the waitid() succeds now, right?

> +}
> +
> +static void setup(void)
> +{
> +	pidfd_open_supported();
> +
> +	TEST(pidfd_open(getpid(), PIDFD_NONBLOCK));
> +	if (TST_RET == -1) {
> +		if (TST_ERR == EINVAL) {
> +			tst_brk(TCONF, "PIDFD_NONBLOCK was supported since linux 5.10");
> +			return;
> +		}
> +		tst_brk(TFAIL | TTERRNO,
> +			"pidfd_open(getpid(),PIDFD_NONBLOCK) failed unexpectedly");
> +	}
> +}
> +
> +static struct tst_test test = {
> +	.needs_root = 1,
> +	.forks_child = 1,
> +	.setup = setup,
> +	.test_all = run,
> +};
Yang Xu Feb. 10, 2022, 1:49 a.m. UTC | #2
Hi Cyril
> Hi!
>> diff --git a/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c b/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c
>> new file mode 100644
>> index 000000000..436351f23
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c
>> @@ -0,0 +1,78 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
>> + * Author: Yang Xu<xuyang2018.jy@fujitsu.com>
>> + */
>> +
>> +/*\
>> + * [Description]
>> + *
>> + * Verify that the PIDFD_NONBLOCK flag works with pidfd_open() and
>> + * that waitid() with a non-blocking pidfd returns EAGAIN.
>> + */
>> +
>> +#include<unistd.h>
>> +#include<fcntl.h>
>> +#include<sys/wait.h>
>> +#include "tst_test.h"
>> +#include "lapi/pidfd_open.h"
>> +
>> +#ifndef PIDFD_NONBLOCK
>> +#define PIDFD_NONBLOCK O_NONBLOCK
>> +#endif
>> +
>> +#ifndef P_PIDFD
>> +#define P_PIDFD  3
>> +#endif
>> +
>> +static void run(void)
>> +{
>> +	int flag, pid, pidfd;
>> +	siginfo_t info;
>> +
>> +	pid = SAFE_FORK();
>> +	if (!pid)
>> +		pause();
>> +
>> +	TST_EXP_PID_SILENT(pidfd_open(pid, PIDFD_NONBLOCK),
>> +				"pidfd_open(%d,  PIDFD_NONBLOCK)", pid);
>
> Here as well FD_SILENT();
Yes.
>
>> +	pidfd = TST_RET;
>> +	flag = fcntl(pidfd, F_GETFL);
>> +	if (flag == -1)
>> +		tst_brk(TFAIL | TERRNO, "fcntl(F_GETFL) failed");
>> +
>> +	if (!(flag&  O_NONBLOCK))
>> +		tst_brk(TFAIL, "pidfd_open(%d, O_NONBLOCK) didn't set O_NONBLOCK flag", pid);
>> +
>> +	tst_res(TPASS, "pidfd_open(%d, O_NONBLOCK) sets O_NONBLOCK flag", pid);
>> +
>> +	TST_EXP_FAIL(waitid(P_PIDFD, pidfd,&info, WEXITED), EAGAIN,
>> +			"waitid(P_PIDFD,...,WEXITED)");
>> +
>> +	SAFE_KILL(pid, SIGTERM);
>> +	SAFE_WAIT(NULL);
>> +	SAFE_CLOSE(pidfd);
>
> I guess that we can also test that the waitid() succeds now, right?
Yes, we can use TST_RETRY_FUNC(waitid(P_PIDFD, pidfd, &info, WEXITED), 
TST_RETVAL_EQ0) in here.

Best Regards
Yang Xu
>
>> +}
>> +
>> +static void setup(void)
>> +{
>> +	pidfd_open_supported();
>> +
>> +	TEST(pidfd_open(getpid(), PIDFD_NONBLOCK));
>> +	if (TST_RET == -1) {
>> +		if (TST_ERR == EINVAL) {
>> +			tst_brk(TCONF, "PIDFD_NONBLOCK was supported since linux 5.10");
>> +			return;
>> +		}
>> +		tst_brk(TFAIL | TTERRNO,
>> +			"pidfd_open(getpid(),PIDFD_NONBLOCK) failed unexpectedly");
>> +	}
>> +}
>> +
>> +static struct tst_test test = {
>> +	.needs_root = 1,
>> +	.forks_child = 1,
>> +	.setup = setup,
>> +	.test_all = run,
>> +};
>
diff mbox series

Patch

diff --git a/runtest/syscalls b/runtest/syscalls
index c3e037f72..ce6f89f88 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -954,6 +954,7 @@  personality02 personality02
 pidfd_open01 pidfd_open01
 pidfd_open02 pidfd_open02
 pidfd_open03 pidfd_open03
+pidfd_open04 pidfd_open04
 
 pidfd_send_signal01 pidfd_send_signal01
 pidfd_send_signal02 pidfd_send_signal02
diff --git a/testcases/kernel/syscalls/pidfd_open/.gitignore b/testcases/kernel/syscalls/pidfd_open/.gitignore
index e0b8900c1..cebdc624d 100644
--- a/testcases/kernel/syscalls/pidfd_open/.gitignore
+++ b/testcases/kernel/syscalls/pidfd_open/.gitignore
@@ -1,3 +1,4 @@ 
 pidfd_open01
 pidfd_open02
 pidfd_open03
+pidfd_open04
diff --git a/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c b/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c
new file mode 100644
index 000000000..436351f23
--- /dev/null
+++ b/testcases/kernel/syscalls/pidfd_open/pidfd_open04.c
@@ -0,0 +1,78 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that the PIDFD_NONBLOCK flag works with pidfd_open() and
+ * that waitid() with a non-blocking pidfd returns EAGAIN.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include "tst_test.h"
+#include "lapi/pidfd_open.h"
+
+#ifndef PIDFD_NONBLOCK
+#define PIDFD_NONBLOCK O_NONBLOCK
+#endif
+
+#ifndef P_PIDFD
+#define P_PIDFD  3
+#endif
+
+static void run(void)
+{
+	int flag, pid, pidfd;
+	siginfo_t info;
+
+	pid = SAFE_FORK();
+	if (!pid)
+		pause();
+
+	TST_EXP_PID_SILENT(pidfd_open(pid, PIDFD_NONBLOCK),
+				"pidfd_open(%d,  PIDFD_NONBLOCK)", pid);
+
+	pidfd = TST_RET;
+	flag = fcntl(pidfd, F_GETFL);
+	if (flag == -1)
+		tst_brk(TFAIL | TERRNO, "fcntl(F_GETFL) failed");
+
+	if (!(flag & O_NONBLOCK))
+		tst_brk(TFAIL, "pidfd_open(%d, O_NONBLOCK) didn't set O_NONBLOCK flag", pid);
+
+	tst_res(TPASS, "pidfd_open(%d, O_NONBLOCK) sets O_NONBLOCK flag", pid);
+
+	TST_EXP_FAIL(waitid(P_PIDFD, pidfd, &info, WEXITED), EAGAIN,
+			"waitid(P_PIDFD,...,WEXITED)");
+
+	SAFE_KILL(pid, SIGTERM);
+	SAFE_WAIT(NULL);
+	SAFE_CLOSE(pidfd);
+}
+
+static void setup(void)
+{
+	pidfd_open_supported();
+
+	TEST(pidfd_open(getpid(), PIDFD_NONBLOCK));
+	if (TST_RET == -1) {
+		if (TST_ERR == EINVAL) {
+			tst_brk(TCONF, "PIDFD_NONBLOCK was supported since linux 5.10");
+			return;
+		}
+		tst_brk(TFAIL | TTERRNO,
+			"pidfd_open(getpid(),PIDFD_NONBLOCK) failed unexpectedly");
+	}
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.test_all = run,
+};