1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Description: test IORING_REGISTER_PROBE
4 */
5 #include <errno.h>
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <fcntl.h>
11
12 #include "helpers.h"
13 #include "liburing.h"
14
15 static int no_probe;
16
verify_probe(struct io_uring_probe * p,int full)17 static int verify_probe(struct io_uring_probe *p, int full)
18 {
19 if (!full && p->ops_len) {
20 fprintf(stderr, "Got ops_len=%u\n", p->ops_len);
21 return 1;
22 }
23 if (!p->last_op) {
24 fprintf(stderr, "Got last_op=%u\n", p->last_op);
25 return 1;
26 }
27 if (!full)
28 return 0;
29 /* check a few ops that must be supported */
30 if (!(p->ops[IORING_OP_NOP].flags & IO_URING_OP_SUPPORTED)) {
31 fprintf(stderr, "NOP not supported!?\n");
32 return 1;
33 }
34 if (!(p->ops[IORING_OP_READV].flags & IO_URING_OP_SUPPORTED)) {
35 fprintf(stderr, "READV not supported!?\n");
36 return 1;
37 }
38 if (!(p->ops[IORING_OP_WRITE].flags & IO_URING_OP_SUPPORTED)) {
39 fprintf(stderr, "WRITE not supported!?\n");
40 return 1;
41 }
42
43 return 0;
44 }
45
test_probe_helper(struct io_uring * ring)46 static int test_probe_helper(struct io_uring *ring)
47 {
48 int ret;
49 struct io_uring_probe *p;
50
51 p = io_uring_get_probe_ring(ring);
52 if (!p) {
53 fprintf(stderr, "Failed getting probe data\n");
54 return 1;
55 }
56
57 ret = verify_probe(p, 1);
58 io_uring_free_probe(p);
59 return ret;
60 }
61
test_probe(struct io_uring * ring)62 static int test_probe(struct io_uring *ring)
63 {
64 struct io_uring_probe *p;
65 size_t len;
66 int ret;
67
68 len = sizeof(*p) + 256 * sizeof(struct io_uring_probe_op);
69 p = t_calloc(1, len);
70 ret = io_uring_register_probe(ring, p, 0);
71 if (ret == -EINVAL) {
72 fprintf(stdout, "Probe not supported, skipping\n");
73 no_probe = 1;
74 goto out;
75 } else if (ret) {
76 fprintf(stdout, "Probe returned %d\n", ret);
77 goto err;
78 }
79
80 if (verify_probe(p, 0))
81 goto err;
82
83 /* now grab for all entries */
84 memset(p, 0, len);
85 ret = io_uring_register_probe(ring, p, 256);
86 if (ret == -EINVAL) {
87 fprintf(stdout, "Probe not supported, skipping\n");
88 goto err;
89 } else if (ret) {
90 fprintf(stdout, "Probe returned %d\n", ret);
91 goto err;
92 }
93
94 if (verify_probe(p, 1))
95 goto err;
96
97 out:
98 free(p);
99 return 0;
100 err:
101 free(p);
102 return 1;
103 }
104
main(int argc,char * argv[])105 int main(int argc, char *argv[])
106 {
107 struct io_uring ring;
108 int ret;
109
110 if (argc > 1)
111 return 0;
112
113 ret = io_uring_queue_init(8, &ring, 0);
114 if (ret) {
115 fprintf(stderr, "ring setup failed\n");
116 return 1;
117 }
118
119 ret = test_probe(&ring);
120 if (ret) {
121 fprintf(stderr, "test_probe failed\n");
122 return ret;
123 }
124 if (no_probe)
125 return 0;
126
127 ret = test_probe_helper(&ring);
128 if (ret) {
129 fprintf(stderr, "test_probe failed\n");
130 return ret;
131 }
132
133
134 return 0;
135 }
136