1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (c) Crackerjack Project., 2007
4  *   Copyright (c) 2011 Cyril Hrubis <chrubis@suse.cz>
5  *   Copyright (c) 2017 Xiao Yang <yangx.jy@cn.fujitsu.com>
6  */
7 
8 /* Porting from Crackerjack to LTP is done
9  * by Masatake YAMATO <yamato@redhat.com>
10  *
11  * Description:
12  * 1) io_setup(2) succeeds if both nr_events and ctxp are valid.
13  * 2) io_setup(2) fails and returns -EINVAL if ctxp is not initialized to 0.
14  * 3) io_setup(2) fails and returns -EINVAL if nr_events is invalid.
15  * 4) io_setup(2) fails and returns -EFAULT if ctxp is NULL.
16  * 5) io_setup(2) fails and returns -EAGAIN if nr_events exceeds the limit
17  *    of available events.
18  */
19 
20 #include <errno.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include "config.h"
24 #include "tst_test.h"
25 
26 #ifdef HAVE_LIBAIO
27 #include <libaio.h>
28 
verify_failure(unsigned int nr,io_context_t * ctx,int init_val,long exp_err)29 static void verify_failure(unsigned int nr, io_context_t *ctx, int init_val, long exp_err)
30 {
31 	if (ctx)
32 		memset(ctx, init_val, sizeof(*ctx));
33 
34 	TEST(io_setup(nr, ctx));
35 	if (TST_RET == 0) {
36 		tst_res(TFAIL, "io_setup() passed unexpectedly");
37 		io_destroy(*ctx);
38 		return;
39 	}
40 
41 	if (TST_RET == -exp_err) {
42 		tst_res(TPASS, "io_setup() failed as expected, returned -%s",
43 			tst_strerrno(exp_err));
44 	} else {
45 		tst_res(TFAIL, "io_setup() failed unexpectedly, returned -%s "
46 			"expected -%s", tst_strerrno(-TST_RET),
47 			tst_strerrno(exp_err));
48 	}
49 }
50 
verify_success(unsigned int nr,io_context_t * ctx,int init_val)51 static void verify_success(unsigned int nr, io_context_t *ctx, int init_val)
52 {
53 	memset(ctx, init_val, sizeof(*ctx));
54 
55 	TEST(io_setup(nr, ctx));
56 	if (TST_RET != 0) {
57 		tst_res(TFAIL, "io_setup() failed unexpectedly with %li (%s)",
58 			TST_RET, tst_strerrno(-TST_RET));
59 		return;
60 	}
61 
62 	tst_res(TPASS, "io_setup() passed as expected");
63 	io_destroy(*ctx);
64 }
65 
verify_io_setup(void)66 static void verify_io_setup(void)
67 {
68 	io_context_t ctx;
69 	unsigned int aio_max = 0;
70 
71 	verify_success(1, &ctx, 0);
72 	verify_failure(1, &ctx, 1, EINVAL);
73 	verify_failure(-1, &ctx, 0, EINVAL);
74 	verify_failure(1, NULL, 0, EFAULT);
75 
76 	if (!access("/proc/sys/fs/aio-max-nr", F_OK)) {
77 		SAFE_FILE_SCANF("/proc/sys/fs/aio-max-nr", "%u", &aio_max);
78 		verify_failure(aio_max + 1, &ctx, 0, EAGAIN);
79 	} else {
80 		tst_res(TCONF, "the aio-max-nr file did not exist");
81 	}
82 }
83 
84 static struct tst_test test = {
85 	.test_all = verify_io_setup,
86 };
87 
88 #else
89 	TST_TEST_TCONF("test requires libaio and it's development packages");
90 #endif
91