1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
4 *
5 * Description:
6 * Basic io_pgetevents() test to check various failures.
7 */
8 #include "tst_test.h"
9 #include "lapi/io_pgetevents.h"
10
11 #ifdef HAVE_LIBAIO
12 static sigset_t sigmask;
13 static struct io_event events[1];
14 static io_context_t ctx, invalid_ctx = 0;
15 static int fd, ctx_initialized;
16
17 static struct tcase {
18 char *name;
19 io_context_t *ctx;
20 long min_nr;
21 long max_nr;
22 struct io_event *events;
23 struct timespec *timeout;
24 sigset_t *sigmask;
25 int exp_errno;
26 } tcases[] = {
27 {"invalid ctx", &invalid_ctx, 1, 1, events, NULL, &sigmask, EINVAL},
28 {"invalid min_nr", &ctx, -1, 1, events, NULL, &sigmask, EINVAL},
29 {"invalid max_nr", &ctx, 1, -1, events, NULL, &sigmask, EINVAL},
30 {"invalid events", &ctx, 1, 1, NULL, NULL, &sigmask, EFAULT},
31 {"invalid timeout", &ctx, 1, 1, events, (void *)(0xDEAD), &sigmask, EFAULT},
32 {"invalid sigmask", &ctx, 1, 1, events, NULL, (void *)(0xDEAD), EFAULT},
33 };
34
setup(void)35 static void setup(void)
36 {
37 struct iocb cb, *cbs[1];
38 char data[4096];
39 int ret;
40
41 cbs[0] = &cb;
42
43 sigemptyset(&sigmask);
44
45 fd = SAFE_OPEN("io_pgetevents_file", O_RDWR | O_CREAT, 0644);
46 io_prep_pwrite(&cb, fd, data, 4096, 0);
47
48 ret = io_setup(1, &ctx);
49 if (ret < 0)
50 tst_brk(TBROK | TERRNO, "io_setup() failed");
51
52 ctx_initialized = 1;
53
54 ret = io_submit(ctx, 1, cbs);
55 if (ret != 1)
56 tst_brk(TBROK | TERRNO, "io_submit() failed");
57 }
58
cleanup(void)59 static void cleanup(void)
60 {
61 if (ctx_initialized) {
62 if (io_destroy(ctx) < 0)
63 tst_res(TWARN | TERRNO, "io_destroy() failed");
64 }
65
66 if (fd > 0)
67 SAFE_CLOSE(fd);
68 }
69
run(unsigned int n)70 static void run(unsigned int n)
71 {
72 struct tcase *tc = &tcases[n];
73
74 TEST(io_pgetevents(*tc->ctx, tc->min_nr, tc->max_nr, tc->events,
75 tc->timeout, tc->sigmask));
76
77 if (TST_RET == 1) {
78 tst_res(TFAIL, "%s: io_pgetevents() passed unexpectedly",
79 tc->name);
80 return;
81 }
82
83 if (tc->exp_errno != TST_ERR) {
84 tst_res(TFAIL | TTERRNO, "%s: io_pgetevents() should fail with %s",
85 tc->name, tst_strerrno(tc->exp_errno));
86 return;
87 }
88
89 tst_res(TPASS | TTERRNO, "%s: io_pgetevents() failed as expected",
90 tc->name);
91 }
92
93 static struct tst_test test = {
94 .min_kver = "4.18",
95 .needs_tmpdir = 1,
96 .tcnt = ARRAY_SIZE(tcases),
97 .test = run,
98 .setup = setup,
99 .cleanup = cleanup,
100 };
101
102 #else
103 TST_TEST_TCONF("test requires libaio and it's development packages");
104 #endif
105