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, "READV 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 struct io_uring_probe *p;
49
50 p = io_uring_get_probe_ring(ring);
51 if (!p) {
52 fprintf(stderr, "Failed getting probe data\n");
53 return 1;
54 }
55
56 if (verify_probe(p, 1)) {
57 free(p);
58 return 1;
59 }
60
61 return 0;
62 }
63
test_probe(struct io_uring * ring)64 static int test_probe(struct io_uring *ring)
65 {
66 struct io_uring_probe *p;
67 size_t len;
68 int ret;
69
70 len = sizeof(*p) + 256 * sizeof(struct io_uring_probe_op);
71 p = t_calloc(1, len);
72 ret = io_uring_register_probe(ring, p, 0);
73 if (ret == -EINVAL) {
74 fprintf(stdout, "Probe not supported, skipping\n");
75 no_probe = 1;
76 goto out;
77 } else if (ret) {
78 fprintf(stdout, "Probe returned %d\n", ret);
79 goto err;
80 }
81
82 if (verify_probe(p, 0))
83 goto err;
84
85 /* now grab for all entries */
86 memset(p, 0, len);
87 ret = io_uring_register_probe(ring, p, 256);
88 if (ret == -EINVAL) {
89 fprintf(stdout, "Probe not supported, skipping\n");
90 goto err;
91 } else if (ret) {
92 fprintf(stdout, "Probe returned %d\n", ret);
93 goto err;
94 }
95
96 if (verify_probe(p, 1))
97 goto err;
98
99 out:
100 free(p);
101 return 0;
102 err:
103 free(p);
104 return 1;
105 }
106
main(int argc,char * argv[])107 int main(int argc, char *argv[])
108 {
109 struct io_uring ring;
110 int ret;
111
112 if (argc > 1)
113 return 0;
114
115 ret = io_uring_queue_init(8, &ring, 0);
116 if (ret) {
117 fprintf(stderr, "ring setup failed\n");
118 return 1;
119 }
120
121 ret = test_probe(&ring);
122 if (ret) {
123 fprintf(stderr, "test_probe failed\n");
124 return ret;
125 }
126 if (no_probe)
127 return 0;
128
129 ret = test_probe_helper(&ring);
130 if (ret) {
131 fprintf(stderr, "test_probe failed\n");
132 return ret;
133 }
134
135
136 return 0;
137 }
138