From: Richard Palethorpe <rpalethorpe@suse.de>
To: Cyril Hrubis <chrubis@suse.cz>
Cc: mszeredi@redhat.com, brauner@kernel.org, Jan Kara <jack@suse.cz>,
Matthew Wilcox <willy@infradead.org>,
viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org,
ltp@lists.linux.it
Subject: Re: [LTP] [PATCH v2 1/4] lib: Add tst_fd iterator
Date: Tue, 24 Oct 2023 10:39:52 +0100 [thread overview]
Message-ID: <877cncuzns.fsf@suse.de> (raw)
In-Reply-To: <20231016123320.9865-2-chrubis@suse.cz>
Hello,
Good stuff!
Reviewed-by: Richard Palethorpe <rpalethorpe@suse.com>
Cyril Hrubis <chrubis@suse.cz> writes:
> Which allows tests to loop over different types of file descriptors
>
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
> include/tst_fd.h | 61 +++++++++
> include/tst_test.h | 1 +
> lib/tst_fd.c | 331 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 393 insertions(+)
> create mode 100644 include/tst_fd.h
> create mode 100644 lib/tst_fd.c
>
> diff --git a/include/tst_fd.h b/include/tst_fd.h
> new file mode 100644
> index 000000000..2f15a06c8
> --- /dev/null
> +++ b/include/tst_fd.h
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/*
> + * Copyright (C) 2023 Cyril Hrubis <chrubis@suse.cz>
> + */
> +
> +#ifndef TST_FD_H__
> +#define TST_FD_H__
> +
> +enum tst_fd_type {
> + TST_FD_FILE,
> + TST_FD_PATH,
> + TST_FD_DIR,
> + TST_FD_DEV_ZERO,
> + TST_FD_PROC_MAPS,
> + TST_FD_PIPE_READ,
> + TST_FD_PIPE_WRITE,
> + TST_FD_UNIX_SOCK,
> + TST_FD_INET_SOCK,
> + TST_FD_EPOLL,
> + TST_FD_EVENTFD,
> + TST_FD_SIGNALFD,
> + TST_FD_TIMERFD,
> + TST_FD_PIDFD,
> + TST_FD_FANOTIFY,
> + TST_FD_INOTIFY,
> + TST_FD_USERFAULTFD,
> + TST_FD_PERF_EVENT,
> + TST_FD_IO_URING,
> + TST_FD_BPF_MAP,
> + TST_FD_FSOPEN,
> + TST_FD_FSPICK,
> + TST_FD_OPEN_TREE,
> + TST_FD_MEMFD,
> + TST_FD_MEMFD_SECRET,
> + TST_FD_MAX,
> +};
> +
> +struct tst_fd {
> + enum tst_fd_type type;
> + int fd;
> + /* used by the library, do not touch! */
> + long priv;
> +};
> +
> +#define TST_FD_INIT {.type = TST_FD_FILE, .fd = -1}
> +
> +/*
> + * Advances the iterator to the next fd type, returns zero at the end.
> + */
> +int tst_fd_next(struct tst_fd *fd);
> +
> +#define TST_FD_FOREACH(fd) \
> + for (struct tst_fd fd = TST_FD_INIT; tst_fd_next(&fd); )
> +
> +/*
> + * Returns human readable name for the file descriptor type.
> + */
> +const char *tst_fd_desc(struct tst_fd *fd);
> +
> +#endif /* TST_FD_H__ */
> diff --git a/include/tst_test.h b/include/tst_test.h
> index 75c2109b9..5eee36bac 100644
> --- a/include/tst_test.h
> +++ b/include/tst_test.h
> @@ -44,6 +44,7 @@
> #include "tst_taint.h"
> #include "tst_memutils.h"
> #include "tst_arch.h"
> +#include "tst_fd.h"
>
> /*
> * Reports testcase result.
> diff --git a/lib/tst_fd.c b/lib/tst_fd.c
> new file mode 100644
> index 000000000..3e0a0fe20
> --- /dev/null
> +++ b/lib/tst_fd.c
> @@ -0,0 +1,331 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/*
> + * Copyright (C) 2023 Cyril Hrubis <chrubis@suse.cz>
> + */
> +
> +#define TST_NO_DEFAULT_MAIN
> +
> +#include <sys/epoll.h>
> +#include <sys/eventfd.h>
> +#include <sys/signalfd.h>
> +#include <sys/timerfd.h>
> +#include <sys/fanotify.h>
> +#include <sys/inotify.h>
> +#include <linux/perf_event.h>
> +
> +#include "tst_test.h"
> +#include "tst_safe_macros.h"
> +
> +#include "lapi/pidfd.h"
> +#include "lapi/io_uring.h"
> +#include "lapi/bpf.h"
> +#include "lapi/fsmount.h"
> +
> +#include "tst_fd.h"
> +
> +struct tst_fd_desc {
> + void (*open_fd)(struct tst_fd *fd);
> + void (*destroy)(struct tst_fd *fd);
> + const char *desc;
> +};
> +
> +static void open_file(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_OPEN("fd_file", O_RDWR | O_CREAT, 0666);
> + SAFE_UNLINK("fd_file");
> +}
> +
> +static void open_path(struct tst_fd *fd)
> +{
> + int tfd;
> +
> + tfd = SAFE_CREAT("fd_file", 0666);
> + SAFE_CLOSE(tfd);
> +
> + fd->fd = SAFE_OPEN("fd_file", O_PATH);
> +
> + SAFE_UNLINK("fd_file");
> +}
> +
> +static void open_dir(struct tst_fd *fd)
> +{
> + SAFE_MKDIR("fd_dir", 0700);
> + fd->fd = SAFE_OPEN("fd_dir", O_DIRECTORY);
> + SAFE_RMDIR("fd_dir");
> +}
> +
> +static void open_dev_zero(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_OPEN("/dev/zero", O_RDONLY);
> +}
> +
> +static void open_proc_self_maps(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_OPEN("/proc/self/maps", O_RDONLY);
> +}
> +
> +static void open_pipe_read(struct tst_fd *fd)
> +{
> + int pipe[2];
> +
> + SAFE_PIPE(pipe);
> + fd->fd = pipe[0];
> + fd->priv = pipe[1];
> +}
> +
> +static void open_pipe_write(struct tst_fd *fd)
> +{
> + int pipe[2];
> +
> + SAFE_PIPE(pipe);
> + fd->fd = pipe[1];
> + fd->priv = pipe[0];
> +}
> +
> +static void destroy_pipe(struct tst_fd *fd)
> +{
> + SAFE_CLOSE(fd->priv);
> +}
> +
> +static void open_unix_sock(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_SOCKET(AF_UNIX, SOCK_STREAM, 0);
> +}
> +
> +static void open_inet_sock(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
> +}
> +
> +static void open_epoll(struct tst_fd *fd)
> +{
> + fd->fd = epoll_create(1);
> +
> + if (fd->fd < 0)
> + tst_brk(TBROK | TERRNO, "epoll_create()");
> +}
> +
> +static void open_eventfd(struct tst_fd *fd)
> +{
> + fd->fd = eventfd(0, 0);
> +
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_signalfd(struct tst_fd *fd)
> +{
> + sigset_t sfd_mask;
> + sigemptyset(&sfd_mask);
> +
> + fd->fd = signalfd(-1, &sfd_mask, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_timerfd(struct tst_fd *fd)
> +{
> + fd->fd = timerfd_create(CLOCK_REALTIME, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_pidfd(struct tst_fd *fd)
> +{
> + fd->fd = pidfd_open(getpid(), 0);
> + if (fd->fd < 0)
> + tst_brk(TBROK | TERRNO, "pidfd_open()");
> +}
> +
> +static void open_fanotify(struct tst_fd *fd)
> +{
> + fd->fd = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_inotify(struct tst_fd *fd)
> +{
> + fd->fd = inotify_init();
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_userfaultfd(struct tst_fd *fd)
> +{
> + fd->fd = syscall(__NR_userfaultfd, 0);
> +
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_perf_event(struct tst_fd *fd)
> +{
> + struct perf_event_attr pe_attr = {
> + .type = PERF_TYPE_SOFTWARE,
> + .size = sizeof(struct perf_event_attr),
> + .config = PERF_COUNT_SW_CPU_CLOCK,
> + .disabled = 1,
> + .exclude_kernel = 1,
> + .exclude_hv = 1,
> + };
> +
> + fd->fd = syscall(__NR_perf_event_open, &pe_attr, 0, -1, -1, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_io_uring(struct tst_fd *fd)
> +{
> + struct io_uring_params uring_params = {};
> +
> + fd->fd = io_uring_setup(1, &uring_params);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_bpf_map(struct tst_fd *fd)
> +{
> + union bpf_attr array_attr = {
> + .map_type = BPF_MAP_TYPE_ARRAY,
> + .key_size = 4,
> + .value_size = 8,
> + .max_entries = 1,
> + };
> +
> + fd->fd = bpf(BPF_MAP_CREATE, &array_attr, sizeof(array_attr));
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_fsopen(struct tst_fd *fd)
> +{
> + fd->fd = fsopen("ext2", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_fspick(struct tst_fd *fd)
> +{
> + fd->fd = fspick(AT_FDCWD, "/", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_open_tree(struct tst_fd *fd)
> +{
> + fd->fd = open_tree(AT_FDCWD, "/", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_memfd(struct tst_fd *fd)
> +{
> + fd->fd = syscall(__NR_memfd_create, "ltp_memfd", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_memfd_secret(struct tst_fd *fd)
> +{
> + fd->fd = syscall(__NR_memfd_secret, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static struct tst_fd_desc fd_desc[] = {
> + [TST_FD_FILE] = {.open_fd = open_file, .desc = "file"},
> + [TST_FD_PATH] = {.open_fd = open_path, .desc = "O_PATH file"},
> + [TST_FD_DIR] = {.open_fd = open_dir, .desc = "directory"},
> + [TST_FD_DEV_ZERO] = {.open_fd = open_dev_zero, .desc = "/dev/zero"},
> + [TST_FD_PROC_MAPS] = {.open_fd = open_proc_self_maps, .desc = "/proc/self/maps"},
> + [TST_FD_PIPE_READ] = {.open_fd = open_pipe_read, .desc = "pipe read end", .destroy = destroy_pipe},
> + [TST_FD_PIPE_WRITE] = {.open_fd = open_pipe_write, .desc = "pipe write end", .destroy = destroy_pipe},
> + [TST_FD_UNIX_SOCK] = {.open_fd = open_unix_sock, .desc = "unix socket"},
> + [TST_FD_INET_SOCK] = {.open_fd = open_inet_sock, .desc = "inet socket"},
> + [TST_FD_EPOLL] = {.open_fd = open_epoll, .desc = "epoll"},
> + [TST_FD_EVENTFD] = {.open_fd = open_eventfd, .desc = "eventfd"},
> + [TST_FD_SIGNALFD] = {.open_fd = open_signalfd, .desc = "signalfd"},
> + [TST_FD_TIMERFD] = {.open_fd = open_timerfd, .desc = "timerfd"},
> + [TST_FD_PIDFD] = {.open_fd = open_pidfd, .desc = "pidfd"},
> + [TST_FD_FANOTIFY] = {.open_fd = open_fanotify, .desc = "fanotify"},
> + [TST_FD_INOTIFY] = {.open_fd = open_inotify, .desc = "inotify"},
> + [TST_FD_USERFAULTFD] = {.open_fd = open_userfaultfd, .desc = "userfaultfd"},
> + [TST_FD_PERF_EVENT] = {.open_fd = open_perf_event, .desc = "perf event"},
> + [TST_FD_IO_URING] = {.open_fd = open_io_uring, .desc = "io uring"},
> + [TST_FD_BPF_MAP] = {.open_fd = open_bpf_map, .desc = "bpf map"},
> + [TST_FD_FSOPEN] = {.open_fd = open_fsopen, .desc = "fsopen"},
> + [TST_FD_FSPICK] = {.open_fd = open_fspick, .desc = "fspick"},
> + [TST_FD_OPEN_TREE] = {.open_fd = open_open_tree, .desc = "open_tree"},
> + [TST_FD_MEMFD] = {.open_fd = open_memfd, .desc = "memfd"},
> + [TST_FD_MEMFD_SECRET] = {.open_fd = open_memfd_secret, .desc = "memfd secret"},
> +};
> +
> +const char *tst_fd_desc(struct tst_fd *fd)
> +{
> + if (fd->type >= ARRAY_SIZE(fd_desc))
> + return "invalid";
> +
> + return fd_desc[fd->type].desc;
> +}
> +
> +void tst_fd_init(struct tst_fd *fd)
> +{
> + fd->type = TST_FD_FILE;
> + fd->fd = -1;
> +}
> +
> +int tst_fd_next(struct tst_fd *fd)
> +{
> + size_t len = ARRAY_SIZE(fd_desc);
> +
> + if (fd->fd >= 0) {
> + SAFE_CLOSE(fd->fd);
> +
> + if (fd_desc[fd->type].destroy)
> + fd_desc[fd->type].destroy(fd);
> +
> + fd->type++;
> + }
> +
> + for (;;) {
> + if (fd->type >= len)
> + return 0;
> +
> + fd_desc[fd->type].open_fd(fd);
> +
> + if (fd->fd >= 0)
> + return 1;
> +
> + fd->type++;
> + }
> +}
> --
> 2.41.0
--
Thank you,
Richard.
--
Mailing list info: https://lists.linux.it/listinfo/ltp
WARNING: multiple messages have this Message-ID (diff)
From: Richard Palethorpe <rpalethorpe@suse.de>
To: Cyril Hrubis <chrubis@suse.cz>
Cc: mszeredi@redhat.com, brauner@kernel.org, Jan Kara <jack@suse.cz>,
Matthew Wilcox <willy@infradead.org>,
viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org,
ltp@lists.linux.it
Subject: Re: [LTP] [PATCH v2 1/4] lib: Add tst_fd iterator
Date: Tue, 24 Oct 2023 10:39:52 +0100 [thread overview]
Message-ID: <877cncuzns.fsf@suse.de> (raw)
In-Reply-To: <20231016123320.9865-2-chrubis@suse.cz>
Hello,
Good stuff!
Reviewed-by: Richard Palethorpe <rpalethorpe@suse.com>
Cyril Hrubis <chrubis@suse.cz> writes:
> Which allows tests to loop over different types of file descriptors
>
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
> include/tst_fd.h | 61 +++++++++
> include/tst_test.h | 1 +
> lib/tst_fd.c | 331 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 393 insertions(+)
> create mode 100644 include/tst_fd.h
> create mode 100644 lib/tst_fd.c
>
> diff --git a/include/tst_fd.h b/include/tst_fd.h
> new file mode 100644
> index 000000000..2f15a06c8
> --- /dev/null
> +++ b/include/tst_fd.h
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/*
> + * Copyright (C) 2023 Cyril Hrubis <chrubis@suse.cz>
> + */
> +
> +#ifndef TST_FD_H__
> +#define TST_FD_H__
> +
> +enum tst_fd_type {
> + TST_FD_FILE,
> + TST_FD_PATH,
> + TST_FD_DIR,
> + TST_FD_DEV_ZERO,
> + TST_FD_PROC_MAPS,
> + TST_FD_PIPE_READ,
> + TST_FD_PIPE_WRITE,
> + TST_FD_UNIX_SOCK,
> + TST_FD_INET_SOCK,
> + TST_FD_EPOLL,
> + TST_FD_EVENTFD,
> + TST_FD_SIGNALFD,
> + TST_FD_TIMERFD,
> + TST_FD_PIDFD,
> + TST_FD_FANOTIFY,
> + TST_FD_INOTIFY,
> + TST_FD_USERFAULTFD,
> + TST_FD_PERF_EVENT,
> + TST_FD_IO_URING,
> + TST_FD_BPF_MAP,
> + TST_FD_FSOPEN,
> + TST_FD_FSPICK,
> + TST_FD_OPEN_TREE,
> + TST_FD_MEMFD,
> + TST_FD_MEMFD_SECRET,
> + TST_FD_MAX,
> +};
> +
> +struct tst_fd {
> + enum tst_fd_type type;
> + int fd;
> + /* used by the library, do not touch! */
> + long priv;
> +};
> +
> +#define TST_FD_INIT {.type = TST_FD_FILE, .fd = -1}
> +
> +/*
> + * Advances the iterator to the next fd type, returns zero at the end.
> + */
> +int tst_fd_next(struct tst_fd *fd);
> +
> +#define TST_FD_FOREACH(fd) \
> + for (struct tst_fd fd = TST_FD_INIT; tst_fd_next(&fd); )
> +
> +/*
> + * Returns human readable name for the file descriptor type.
> + */
> +const char *tst_fd_desc(struct tst_fd *fd);
> +
> +#endif /* TST_FD_H__ */
> diff --git a/include/tst_test.h b/include/tst_test.h
> index 75c2109b9..5eee36bac 100644
> --- a/include/tst_test.h
> +++ b/include/tst_test.h
> @@ -44,6 +44,7 @@
> #include "tst_taint.h"
> #include "tst_memutils.h"
> #include "tst_arch.h"
> +#include "tst_fd.h"
>
> /*
> * Reports testcase result.
> diff --git a/lib/tst_fd.c b/lib/tst_fd.c
> new file mode 100644
> index 000000000..3e0a0fe20
> --- /dev/null
> +++ b/lib/tst_fd.c
> @@ -0,0 +1,331 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/*
> + * Copyright (C) 2023 Cyril Hrubis <chrubis@suse.cz>
> + */
> +
> +#define TST_NO_DEFAULT_MAIN
> +
> +#include <sys/epoll.h>
> +#include <sys/eventfd.h>
> +#include <sys/signalfd.h>
> +#include <sys/timerfd.h>
> +#include <sys/fanotify.h>
> +#include <sys/inotify.h>
> +#include <linux/perf_event.h>
> +
> +#include "tst_test.h"
> +#include "tst_safe_macros.h"
> +
> +#include "lapi/pidfd.h"
> +#include "lapi/io_uring.h"
> +#include "lapi/bpf.h"
> +#include "lapi/fsmount.h"
> +
> +#include "tst_fd.h"
> +
> +struct tst_fd_desc {
> + void (*open_fd)(struct tst_fd *fd);
> + void (*destroy)(struct tst_fd *fd);
> + const char *desc;
> +};
> +
> +static void open_file(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_OPEN("fd_file", O_RDWR | O_CREAT, 0666);
> + SAFE_UNLINK("fd_file");
> +}
> +
> +static void open_path(struct tst_fd *fd)
> +{
> + int tfd;
> +
> + tfd = SAFE_CREAT("fd_file", 0666);
> + SAFE_CLOSE(tfd);
> +
> + fd->fd = SAFE_OPEN("fd_file", O_PATH);
> +
> + SAFE_UNLINK("fd_file");
> +}
> +
> +static void open_dir(struct tst_fd *fd)
> +{
> + SAFE_MKDIR("fd_dir", 0700);
> + fd->fd = SAFE_OPEN("fd_dir", O_DIRECTORY);
> + SAFE_RMDIR("fd_dir");
> +}
> +
> +static void open_dev_zero(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_OPEN("/dev/zero", O_RDONLY);
> +}
> +
> +static void open_proc_self_maps(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_OPEN("/proc/self/maps", O_RDONLY);
> +}
> +
> +static void open_pipe_read(struct tst_fd *fd)
> +{
> + int pipe[2];
> +
> + SAFE_PIPE(pipe);
> + fd->fd = pipe[0];
> + fd->priv = pipe[1];
> +}
> +
> +static void open_pipe_write(struct tst_fd *fd)
> +{
> + int pipe[2];
> +
> + SAFE_PIPE(pipe);
> + fd->fd = pipe[1];
> + fd->priv = pipe[0];
> +}
> +
> +static void destroy_pipe(struct tst_fd *fd)
> +{
> + SAFE_CLOSE(fd->priv);
> +}
> +
> +static void open_unix_sock(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_SOCKET(AF_UNIX, SOCK_STREAM, 0);
> +}
> +
> +static void open_inet_sock(struct tst_fd *fd)
> +{
> + fd->fd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
> +}
> +
> +static void open_epoll(struct tst_fd *fd)
> +{
> + fd->fd = epoll_create(1);
> +
> + if (fd->fd < 0)
> + tst_brk(TBROK | TERRNO, "epoll_create()");
> +}
> +
> +static void open_eventfd(struct tst_fd *fd)
> +{
> + fd->fd = eventfd(0, 0);
> +
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_signalfd(struct tst_fd *fd)
> +{
> + sigset_t sfd_mask;
> + sigemptyset(&sfd_mask);
> +
> + fd->fd = signalfd(-1, &sfd_mask, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_timerfd(struct tst_fd *fd)
> +{
> + fd->fd = timerfd_create(CLOCK_REALTIME, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_pidfd(struct tst_fd *fd)
> +{
> + fd->fd = pidfd_open(getpid(), 0);
> + if (fd->fd < 0)
> + tst_brk(TBROK | TERRNO, "pidfd_open()");
> +}
> +
> +static void open_fanotify(struct tst_fd *fd)
> +{
> + fd->fd = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_inotify(struct tst_fd *fd)
> +{
> + fd->fd = inotify_init();
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_userfaultfd(struct tst_fd *fd)
> +{
> + fd->fd = syscall(__NR_userfaultfd, 0);
> +
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_perf_event(struct tst_fd *fd)
> +{
> + struct perf_event_attr pe_attr = {
> + .type = PERF_TYPE_SOFTWARE,
> + .size = sizeof(struct perf_event_attr),
> + .config = PERF_COUNT_SW_CPU_CLOCK,
> + .disabled = 1,
> + .exclude_kernel = 1,
> + .exclude_hv = 1,
> + };
> +
> + fd->fd = syscall(__NR_perf_event_open, &pe_attr, 0, -1, -1, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_io_uring(struct tst_fd *fd)
> +{
> + struct io_uring_params uring_params = {};
> +
> + fd->fd = io_uring_setup(1, &uring_params);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_bpf_map(struct tst_fd *fd)
> +{
> + union bpf_attr array_attr = {
> + .map_type = BPF_MAP_TYPE_ARRAY,
> + .key_size = 4,
> + .value_size = 8,
> + .max_entries = 1,
> + };
> +
> + fd->fd = bpf(BPF_MAP_CREATE, &array_attr, sizeof(array_attr));
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_fsopen(struct tst_fd *fd)
> +{
> + fd->fd = fsopen("ext2", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_fspick(struct tst_fd *fd)
> +{
> + fd->fd = fspick(AT_FDCWD, "/", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_open_tree(struct tst_fd *fd)
> +{
> + fd->fd = open_tree(AT_FDCWD, "/", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_memfd(struct tst_fd *fd)
> +{
> + fd->fd = syscall(__NR_memfd_create, "ltp_memfd", 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static void open_memfd_secret(struct tst_fd *fd)
> +{
> + fd->fd = syscall(__NR_memfd_secret, 0);
> + if (fd->fd < 0) {
> + tst_res(TCONF | TERRNO,
> + "Skipping %s", tst_fd_desc(fd));
> + }
> +}
> +
> +static struct tst_fd_desc fd_desc[] = {
> + [TST_FD_FILE] = {.open_fd = open_file, .desc = "file"},
> + [TST_FD_PATH] = {.open_fd = open_path, .desc = "O_PATH file"},
> + [TST_FD_DIR] = {.open_fd = open_dir, .desc = "directory"},
> + [TST_FD_DEV_ZERO] = {.open_fd = open_dev_zero, .desc = "/dev/zero"},
> + [TST_FD_PROC_MAPS] = {.open_fd = open_proc_self_maps, .desc = "/proc/self/maps"},
> + [TST_FD_PIPE_READ] = {.open_fd = open_pipe_read, .desc = "pipe read end", .destroy = destroy_pipe},
> + [TST_FD_PIPE_WRITE] = {.open_fd = open_pipe_write, .desc = "pipe write end", .destroy = destroy_pipe},
> + [TST_FD_UNIX_SOCK] = {.open_fd = open_unix_sock, .desc = "unix socket"},
> + [TST_FD_INET_SOCK] = {.open_fd = open_inet_sock, .desc = "inet socket"},
> + [TST_FD_EPOLL] = {.open_fd = open_epoll, .desc = "epoll"},
> + [TST_FD_EVENTFD] = {.open_fd = open_eventfd, .desc = "eventfd"},
> + [TST_FD_SIGNALFD] = {.open_fd = open_signalfd, .desc = "signalfd"},
> + [TST_FD_TIMERFD] = {.open_fd = open_timerfd, .desc = "timerfd"},
> + [TST_FD_PIDFD] = {.open_fd = open_pidfd, .desc = "pidfd"},
> + [TST_FD_FANOTIFY] = {.open_fd = open_fanotify, .desc = "fanotify"},
> + [TST_FD_INOTIFY] = {.open_fd = open_inotify, .desc = "inotify"},
> + [TST_FD_USERFAULTFD] = {.open_fd = open_userfaultfd, .desc = "userfaultfd"},
> + [TST_FD_PERF_EVENT] = {.open_fd = open_perf_event, .desc = "perf event"},
> + [TST_FD_IO_URING] = {.open_fd = open_io_uring, .desc = "io uring"},
> + [TST_FD_BPF_MAP] = {.open_fd = open_bpf_map, .desc = "bpf map"},
> + [TST_FD_FSOPEN] = {.open_fd = open_fsopen, .desc = "fsopen"},
> + [TST_FD_FSPICK] = {.open_fd = open_fspick, .desc = "fspick"},
> + [TST_FD_OPEN_TREE] = {.open_fd = open_open_tree, .desc = "open_tree"},
> + [TST_FD_MEMFD] = {.open_fd = open_memfd, .desc = "memfd"},
> + [TST_FD_MEMFD_SECRET] = {.open_fd = open_memfd_secret, .desc = "memfd secret"},
> +};
> +
> +const char *tst_fd_desc(struct tst_fd *fd)
> +{
> + if (fd->type >= ARRAY_SIZE(fd_desc))
> + return "invalid";
> +
> + return fd_desc[fd->type].desc;
> +}
> +
> +void tst_fd_init(struct tst_fd *fd)
> +{
> + fd->type = TST_FD_FILE;
> + fd->fd = -1;
> +}
> +
> +int tst_fd_next(struct tst_fd *fd)
> +{
> + size_t len = ARRAY_SIZE(fd_desc);
> +
> + if (fd->fd >= 0) {
> + SAFE_CLOSE(fd->fd);
> +
> + if (fd_desc[fd->type].destroy)
> + fd_desc[fd->type].destroy(fd);
> +
> + fd->type++;
> + }
> +
> + for (;;) {
> + if (fd->type >= len)
> + return 0;
> +
> + fd_desc[fd->type].open_fd(fd);
> +
> + if (fd->fd >= 0)
> + return 1;
> +
> + fd->type++;
> + }
> +}
> --
> 2.41.0
--
Thank you,
Richard.
next prev parent reply other threads:[~2023-10-24 9:40 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-16 12:33 [LTP] [PATCH v2 0/4] Add tst_fd iterator API Cyril Hrubis
2023-10-16 12:33 ` Cyril Hrubis
2023-10-16 12:33 ` [LTP] [PATCH v2 1/4] lib: Add tst_fd iterator Cyril Hrubis
2023-10-16 12:33 ` Cyril Hrubis
2023-10-24 9:39 ` Richard Palethorpe [this message]
2023-10-24 9:39 ` [LTP] " Richard Palethorpe
2024-01-05 0:42 ` Petr Vorel
2024-01-05 0:42 ` Petr Vorel
2024-01-15 12:19 ` Cyril Hrubis
2024-01-15 12:19 ` Cyril Hrubis
2024-01-15 22:52 ` Petr Vorel
2024-01-15 22:52 ` Petr Vorel
2023-10-16 12:33 ` [LTP] [PATCH v2 2/4] syscalls: readahead01: Make use of tst_fd Cyril Hrubis
2023-10-16 12:33 ` Cyril Hrubis
2023-10-24 9:31 ` [LTP] " Richard Palethorpe
2023-10-24 9:31 ` Richard Palethorpe
2023-10-16 12:33 ` [LTP] [PATCH v2 3/4] syscalls: accept: Add tst_fd test Cyril Hrubis
2023-10-16 12:33 ` Cyril Hrubis
2023-10-24 9:26 ` [LTP] " Richard Palethorpe
2023-10-24 9:26 ` Richard Palethorpe
2023-10-24 9:34 ` Cyril Hrubis
2023-10-24 9:34 ` Cyril Hrubis
2023-10-16 12:33 ` [LTP] [PATCH v2 4/4] syscalls: splice07: New splice tst_fd iterator test Cyril Hrubis
2023-10-16 12:33 ` Cyril Hrubis
2023-10-23 15:59 ` [LTP] " Richard Palethorpe
2023-10-23 15:59 ` Richard Palethorpe
2023-10-24 7:56 ` Cyril Hrubis
2023-10-24 7:56 ` Cyril Hrubis
2023-10-24 9:33 ` Jan Kara
2023-10-24 9:33 ` Jan Kara
2024-01-04 23:11 ` Petr Vorel
2024-01-04 23:11 ` Petr Vorel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=877cncuzns.fsf@suse.de \
--to=rpalethorpe@suse.de \
--cc=brauner@kernel.org \
--cc=chrubis@suse.cz \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=ltp@lists.linux.it \
--cc=mszeredi@redhat.com \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.