uringmachine 0.3 → 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -1
  3. data/CHANGELOG.md +23 -0
  4. data/README.md +128 -0
  5. data/TODO.md +14 -0
  6. data/examples/bm_snooze.rb +89 -0
  7. data/examples/bm_write.rb +56 -0
  8. data/examples/dns_client.rb +12 -0
  9. data/examples/echo_server.rb +18 -40
  10. data/examples/http_server.rb +42 -43
  11. data/examples/inout.rb +19 -0
  12. data/examples/nc.rb +36 -0
  13. data/examples/server_client.rb +64 -0
  14. data/examples/snooze.rb +44 -0
  15. data/examples/write_dev_null.rb +16 -0
  16. data/ext/um/extconf.rb +24 -23
  17. data/ext/um/um.c +524 -278
  18. data/ext/um/um.h +146 -44
  19. data/ext/um/um_buffer.c +49 -0
  20. data/ext/um/um_class.c +217 -106
  21. data/ext/um/um_const.c +213 -0
  22. data/ext/um/um_ext.c +4 -0
  23. data/ext/um/um_mutex_class.c +47 -0
  24. data/ext/um/um_op.c +86 -114
  25. data/ext/um/um_queue_class.c +58 -0
  26. data/ext/um/um_sync.c +273 -0
  27. data/ext/um/um_utils.c +49 -4
  28. data/lib/uringmachine/dns_resolver.rb +84 -0
  29. data/lib/uringmachine/version.rb +1 -1
  30. data/lib/uringmachine.rb +28 -0
  31. data/supressions/ruby.supp +71 -0
  32. data/test/helper.rb +8 -0
  33. data/test/test_um.rb +685 -46
  34. data/vendor/liburing/.github/workflows/build.yml +29 -1
  35. data/vendor/liburing/.gitignore +6 -0
  36. data/vendor/liburing/CHANGELOG +16 -0
  37. data/vendor/liburing/CONTRIBUTING.md +165 -0
  38. data/vendor/liburing/configure +64 -0
  39. data/vendor/liburing/examples/Makefile +9 -1
  40. data/vendor/liburing/examples/kdigest.c +405 -0
  41. data/vendor/liburing/examples/proxy.c +75 -8
  42. data/vendor/liburing/examples/reg-wait.c +159 -0
  43. data/vendor/liburing/liburing.pc.in +1 -1
  44. data/vendor/liburing/liburing.spec +1 -1
  45. data/vendor/liburing/src/Makefile +16 -2
  46. data/vendor/liburing/src/include/liburing/io_uring.h +77 -0
  47. data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
  48. data/vendor/liburing/src/include/liburing.h +59 -6
  49. data/vendor/liburing/src/int_flags.h +10 -3
  50. data/vendor/liburing/src/liburing-ffi.map +16 -0
  51. data/vendor/liburing/src/liburing.map +10 -0
  52. data/vendor/liburing/src/queue.c +28 -16
  53. data/vendor/liburing/src/register.c +106 -1
  54. data/vendor/liburing/src/sanitize.c +176 -0
  55. data/vendor/liburing/src/setup.c +47 -19
  56. data/vendor/liburing/src/setup.h +6 -0
  57. data/vendor/liburing/test/35fa71a030ca.c +7 -0
  58. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  59. data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
  60. data/vendor/liburing/test/917257daa0fe.c +7 -0
  61. data/vendor/liburing/test/Makefile +38 -4
  62. data/vendor/liburing/test/a0908ae19763.c +7 -0
  63. data/vendor/liburing/test/a4c0b3decb33.c +7 -0
  64. data/vendor/liburing/test/accept.c +14 -4
  65. data/vendor/liburing/test/b19062a56726.c +7 -0
  66. data/vendor/liburing/test/bind-listen.c +2 -2
  67. data/vendor/liburing/test/buf-ring-nommap.c +10 -3
  68. data/vendor/liburing/test/buf-ring.c +2 -0
  69. data/vendor/liburing/test/cmd-discard.c +427 -0
  70. data/vendor/liburing/test/coredump.c +7 -0
  71. data/vendor/liburing/test/cq-overflow.c +13 -1
  72. data/vendor/liburing/test/d4ae271dfaae.c +11 -3
  73. data/vendor/liburing/test/defer-taskrun.c +2 -2
  74. data/vendor/liburing/test/defer-tw-timeout.c +4 -1
  75. data/vendor/liburing/test/defer.c +2 -2
  76. data/vendor/liburing/test/double-poll-crash.c +1 -1
  77. data/vendor/liburing/test/eeed8b54e0df.c +2 -0
  78. data/vendor/liburing/test/eventfd.c +0 -1
  79. data/vendor/liburing/test/exit-no-cleanup.c +11 -0
  80. data/vendor/liburing/test/fadvise.c +9 -26
  81. data/vendor/liburing/test/fdinfo.c +9 -1
  82. data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
  83. data/vendor/liburing/test/file-exit-unreg.c +48 -0
  84. data/vendor/liburing/test/file-register.c +14 -2
  85. data/vendor/liburing/test/file-update.c +1 -1
  86. data/vendor/liburing/test/file-verify.c +27 -16
  87. data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
  88. data/vendor/liburing/test/fixed-buf-iter.c +3 -1
  89. data/vendor/liburing/test/fixed-hugepage.c +12 -1
  90. data/vendor/liburing/test/fsnotify.c +1 -0
  91. data/vendor/liburing/test/futex.c +16 -4
  92. data/vendor/liburing/test/helpers.c +47 -0
  93. data/vendor/liburing/test/helpers.h +6 -0
  94. data/vendor/liburing/test/init-mem.c +5 -3
  95. data/vendor/liburing/test/io-cancel.c +0 -24
  96. data/vendor/liburing/test/io_uring_passthrough.c +4 -0
  97. data/vendor/liburing/test/io_uring_register.c +38 -8
  98. data/vendor/liburing/test/iopoll-leak.c +4 -0
  99. data/vendor/liburing/test/iopoll-overflow.c +1 -1
  100. data/vendor/liburing/test/iopoll.c +3 -3
  101. data/vendor/liburing/test/kallsyms.c +203 -0
  102. data/vendor/liburing/test/link-timeout.c +159 -0
  103. data/vendor/liburing/test/linked-defer-close.c +224 -0
  104. data/vendor/liburing/test/madvise.c +12 -25
  105. data/vendor/liburing/test/min-timeout-wait.c +0 -25
  106. data/vendor/liburing/test/min-timeout.c +0 -25
  107. data/vendor/liburing/test/mkdir.c +6 -0
  108. data/vendor/liburing/test/msg-ring.c +8 -2
  109. data/vendor/liburing/test/napi-test.c +16 -3
  110. data/vendor/liburing/test/no-mmap-inval.c +3 -1
  111. data/vendor/liburing/test/nop.c +44 -0
  112. data/vendor/liburing/test/ooo-file-unreg.c +1 -1
  113. data/vendor/liburing/test/open-close.c +40 -0
  114. data/vendor/liburing/test/openat2.c +37 -14
  115. data/vendor/liburing/test/poll-many.c +13 -7
  116. data/vendor/liburing/test/poll-mshot-update.c +17 -10
  117. data/vendor/liburing/test/poll-v-poll.c +6 -3
  118. data/vendor/liburing/test/pollfree.c +148 -0
  119. data/vendor/liburing/test/read-mshot-empty.c +158 -153
  120. data/vendor/liburing/test/read-mshot-stdin.c +121 -0
  121. data/vendor/liburing/test/read-mshot.c +282 -27
  122. data/vendor/liburing/test/read-write.c +78 -13
  123. data/vendor/liburing/test/recv-msgall-stream.c +3 -0
  124. data/vendor/liburing/test/recv-msgall.c +5 -0
  125. data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
  126. data/vendor/liburing/test/recvsend_bundle.c +94 -31
  127. data/vendor/liburing/test/reg-fd-only.c +15 -5
  128. data/vendor/liburing/test/reg-wait.c +251 -0
  129. data/vendor/liburing/test/regbuf-clone.c +645 -0
  130. data/vendor/liburing/test/regbuf-merge.c +7 -0
  131. data/vendor/liburing/test/register-restrictions.c +86 -85
  132. data/vendor/liburing/test/rename.c +59 -1
  133. data/vendor/liburing/test/resize-rings.c +643 -0
  134. data/vendor/liburing/test/ringbuf-read.c +5 -0
  135. data/vendor/liburing/test/ringbuf-status.c +5 -1
  136. data/vendor/liburing/test/rsrc_tags.c +1 -1
  137. data/vendor/liburing/test/runtests.sh +16 -1
  138. data/vendor/liburing/test/send-zerocopy.c +59 -0
  139. data/vendor/liburing/test/short-read.c +1 -0
  140. data/vendor/liburing/test/socket.c +43 -0
  141. data/vendor/liburing/test/splice.c +3 -1
  142. data/vendor/liburing/test/sq-poll-dup.c +1 -1
  143. data/vendor/liburing/test/sq-poll-share.c +2 -0
  144. data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
  145. data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
  146. data/vendor/liburing/test/sqpoll-sleep.c +40 -33
  147. data/vendor/liburing/test/sqwait.c +136 -0
  148. data/vendor/liburing/test/statx.c +89 -0
  149. data/vendor/liburing/test/stdout.c +2 -0
  150. data/vendor/liburing/test/submit-and-wait.c +1 -25
  151. data/vendor/liburing/test/submit-reuse.c +4 -26
  152. data/vendor/liburing/test/symlink.c +12 -1
  153. data/vendor/liburing/test/sync-cancel.c +56 -22
  154. data/vendor/liburing/test/thread-exit.c +5 -0
  155. data/vendor/liburing/test/timeout-new.c +1 -26
  156. data/vendor/liburing/test/timeout.c +25 -34
  157. data/vendor/liburing/test/unlink.c +94 -1
  158. data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
  159. data/vendor/liburing/test/waitid.c +62 -8
  160. data/vendor/liburing/test/wq-aff.c +35 -0
  161. data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
  162. data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
  163. metadata +37 -6
  164. data/examples/event_loop.rb +0 -69
  165. data/examples/fibers.rb +0 -105
  166. data/examples/http_server_multishot.rb +0 -57
  167. data/examples/http_server_simpler.rb +0 -34
@@ -0,0 +1,427 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+
3
+ #include <stdio.h>
4
+ #include <assert.h>
5
+ #include <string.h>
6
+ #include <unistd.h>
7
+ #include <stdlib.h>
8
+ #include <sys/ioctl.h>
9
+ #include <linux/fs.h>
10
+
11
+ #include "liburing.h"
12
+ #include "helpers.h"
13
+
14
+ #define MAX_TEST_LBAS 1024
15
+
16
+ static const char *filename;
17
+ struct opcode {
18
+ int op;
19
+ bool test;
20
+ bool not_supported;
21
+ };
22
+
23
+ #define TEST_BLOCK_URING_CMD_MAX 3
24
+
25
+ static struct opcode opcodes[TEST_BLOCK_URING_CMD_MAX] = {
26
+ { .op = BLOCK_URING_CMD_DISCARD, .test = true, },
27
+ { .test = false, },
28
+ { .test = false, },
29
+ };
30
+
31
+ static int lba_size;
32
+ static uint64_t bdev_size;
33
+ static uint64_t bdev_size_lbas;
34
+ static char *buffer;
35
+
36
+ static void prep_blk_cmd(struct io_uring_sqe *sqe, int fd,
37
+ uint64_t from, uint64_t len,
38
+ int cmd_op)
39
+ {
40
+ assert(cmd_op == BLOCK_URING_CMD_DISCARD);
41
+
42
+ io_uring_prep_cmd_discard(sqe, fd, from, len);
43
+ }
44
+
45
+ static int queue_cmd_range(struct io_uring *ring, int bdev_fd,
46
+ uint64_t from, uint64_t len, int cmd_op)
47
+ {
48
+ struct io_uring_sqe *sqe;
49
+ struct io_uring_cqe *cqe;
50
+ int err;
51
+
52
+ sqe = io_uring_get_sqe(ring);
53
+ assert(sqe != NULL);
54
+ prep_blk_cmd(sqe, bdev_fd, from, len, cmd_op);
55
+
56
+ err = io_uring_submit_and_wait(ring, 1);
57
+ if (err != 1) {
58
+ fprintf(stderr, "io_uring_submit_and_wait failed %d\n", err);
59
+ exit(1);
60
+ }
61
+
62
+ err = io_uring_wait_cqe(ring, &cqe);
63
+ if (err) {
64
+ fprintf(stderr, "io_uring_wait_cqe failed %d (op %i)\n",
65
+ err, cmd_op);
66
+ exit(1);
67
+ }
68
+
69
+ err = cqe->res;
70
+ io_uring_cqe_seen(ring, cqe);
71
+ return err;
72
+ }
73
+
74
+ static int queue_cmd_lba(struct io_uring *ring, int bdev_fd,
75
+ uint64_t from, uint64_t nr_lba, int cmd_op)
76
+ {
77
+ return queue_cmd_range(ring, bdev_fd, from * lba_size,
78
+ nr_lba * lba_size, cmd_op);
79
+ }
80
+
81
+ static int queue_discard_lba(struct io_uring *ring, int bdev_fd,
82
+ uint64_t from, uint64_t nr_lba)
83
+ {
84
+ return queue_cmd_lba(ring, bdev_fd, from, nr_lba,
85
+ BLOCK_URING_CMD_DISCARD);
86
+ }
87
+
88
+ static int test_parallel(struct io_uring *ring, int fd, int cmd_op)
89
+ {
90
+ struct io_uring_sqe *sqe;
91
+ struct io_uring_cqe *cqe;
92
+ int inflight = 0;
93
+ int max_inflight = 16;
94
+ int left = 1000;
95
+ int ret;
96
+
97
+ while (left || inflight) {
98
+ int queued = 0;
99
+ unsigned head, nr_cqes = 0;
100
+ int lba_len = 8;
101
+
102
+ while (inflight < max_inflight && left) {
103
+ int off = rand() % (MAX_TEST_LBAS - lba_len);
104
+ sqe = io_uring_get_sqe(ring);
105
+ assert(sqe != NULL);
106
+
107
+ prep_blk_cmd(sqe, fd, off * lba_size,
108
+ lba_len * lba_size, cmd_op);
109
+ if (rand() & 1)
110
+ sqe->flags |= IOSQE_ASYNC;
111
+
112
+ queued++;
113
+ left--;
114
+ inflight++;
115
+ }
116
+ if (queued) {
117
+ ret = io_uring_submit(ring);
118
+ if (ret != queued) {
119
+ fprintf(stderr, "io_uring_submit failed %d\n", ret);
120
+ return T_EXIT_FAIL;
121
+ }
122
+ }
123
+
124
+ ret = io_uring_wait_cqe(ring, &cqe);
125
+ if (ret) {
126
+ fprintf(stderr, "io_uring_wait_cqe failed %d\n", ret);
127
+ exit(1);
128
+ }
129
+
130
+ io_uring_for_each_cqe(ring, head, cqe) {
131
+ nr_cqes++;
132
+ inflight--;
133
+ if (cqe->res != 0) {
134
+ fprintf(stderr, "cmd %i failed %i\n", cmd_op,
135
+ cqe->res);
136
+ return T_EXIT_FAIL;
137
+ }
138
+ }
139
+ io_uring_cq_advance(ring, nr_cqes);
140
+ }
141
+
142
+ return 0;
143
+ }
144
+
145
+ static int cmd_issue_verify(struct io_uring *ring, int fd, int lba, int len,
146
+ int cmd_op)
147
+ {
148
+ int verify = (cmd_op != BLOCK_URING_CMD_DISCARD);
149
+ int ret, i;
150
+ ssize_t res;
151
+
152
+ if (verify) {
153
+ for (i = 0; i < len; i++) {
154
+ size_t off = (i + lba) * lba_size;
155
+
156
+ res = pwrite(fd, buffer, lba_size, off);
157
+ if (res == -1) {
158
+ fprintf(stderr, "pwrite failed\n");
159
+ return T_EXIT_FAIL;
160
+ }
161
+ }
162
+ }
163
+
164
+ ret = queue_cmd_lba(ring, fd, lba, len, cmd_op);
165
+ if (ret) {
166
+ if (ret == -EINVAL || ret == -EOPNOTSUPP)
167
+ return T_EXIT_SKIP;
168
+
169
+ fprintf(stderr, "cmd_issue_verify %i fail lba %i len %i ret %i\n",
170
+ cmd_op, lba, len, ret);
171
+ return T_EXIT_FAIL;
172
+ }
173
+
174
+ if (verify) {
175
+ for (i = 0; i < len; i++) {
176
+ size_t off = (i + lba) * lba_size;
177
+
178
+ res = pread(fd, buffer, lba_size, off);
179
+ if (res == -1) {
180
+ fprintf(stderr, "pread failed\n");
181
+ return T_EXIT_FAIL;
182
+ }
183
+ if (!memchr(buffer, 0, lba_size)) {
184
+ fprintf(stderr, "mem cmp failed, lba %i\n", lba + i);
185
+ return T_EXIT_FAIL;
186
+ }
187
+ }
188
+ }
189
+ return 0;
190
+ }
191
+
192
+ static int basic_cmd_test(struct io_uring *ring, int op)
193
+ {
194
+ int cmd_op = opcodes[op].op;
195
+ int ret, fd;
196
+
197
+ if (!opcodes[op].test)
198
+ return T_EXIT_SKIP;
199
+
200
+ fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
201
+ if (fd < 0) {
202
+ if (errno == -EINVAL || errno == -EBUSY)
203
+ return T_EXIT_SKIP;
204
+ fprintf(stderr, "open failed %i\n", errno);
205
+ return T_EXIT_FAIL;
206
+ }
207
+
208
+ ret = cmd_issue_verify(ring, fd, 0, 1, cmd_op);
209
+ if (ret == T_EXIT_SKIP) {
210
+ printf("cmd %i not supported, skip\n", cmd_op);
211
+ opcodes[op].not_supported = 1;
212
+ close(fd);
213
+ return T_EXIT_SKIP;
214
+ } else if (ret) {
215
+ fprintf(stderr, "cmd %i fail 0 1\n", cmd_op);
216
+ return T_EXIT_FAIL;
217
+ }
218
+
219
+ ret = cmd_issue_verify(ring, fd, 7, 15, cmd_op);
220
+ if (ret) {
221
+ fprintf(stderr, "cmd %i fail 7 15 %i\n", cmd_op, ret);
222
+ return T_EXIT_FAIL;
223
+ }
224
+
225
+ ret = cmd_issue_verify(ring, fd, 1, MAX_TEST_LBAS - 1, cmd_op);
226
+ if (ret) {
227
+ fprintf(stderr, "large cmd %i failed %i\n", cmd_op, ret);
228
+ return T_EXIT_FAIL;
229
+ }
230
+
231
+ ret = test_parallel(ring, fd, cmd_op);
232
+ if (ret) {
233
+ fprintf(stderr, "test_parallel() %i failed %i\n", cmd_op, ret);
234
+ return T_EXIT_FAIL;
235
+ }
236
+
237
+ close(fd);
238
+ return 0;
239
+ }
240
+
241
+ static int test_fail_edge_cases(struct io_uring *ring, int op)
242
+ {
243
+ int cmd_op = opcodes[op].op;
244
+ int ret, fd;
245
+
246
+ if (!opcodes[op].test)
247
+ return T_EXIT_SKIP;
248
+
249
+ fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
250
+ if (fd < 0) {
251
+ fprintf(stderr, "open failed %i\n", errno);
252
+ return T_EXIT_FAIL;
253
+ }
254
+
255
+ ret = queue_cmd_lba(ring, fd, bdev_size_lbas, 1, cmd_op);
256
+ if (ret >= 0) {
257
+ fprintf(stderr, "cmd %i beyond capacity %i\n",
258
+ cmd_op, ret);
259
+ return 1;
260
+ }
261
+
262
+ ret = queue_cmd_lba(ring, fd, bdev_size_lbas - 1, 2, cmd_op);
263
+ if (ret >= 0) {
264
+ fprintf(stderr, "cmd %i beyond capacity with overlap %i\n",
265
+ cmd_op, ret);
266
+ return 1;
267
+ }
268
+
269
+ ret = queue_cmd_range(ring, fd, (uint64_t)-lba_size, lba_size + 2,
270
+ cmd_op);
271
+ if (ret >= 0) {
272
+ fprintf(stderr, "cmd %i range overflow %i\n",
273
+ cmd_op, ret);
274
+ return 1;
275
+ }
276
+
277
+ ret = queue_cmd_range(ring, fd, lba_size / 2, lba_size, cmd_op);
278
+ if (ret >= 0) {
279
+ fprintf(stderr, "cmd %i unaligned offset %i\n",
280
+ cmd_op, ret);
281
+ return 1;
282
+ }
283
+
284
+ ret = queue_cmd_range(ring, fd, 0, lba_size / 2, cmd_op);
285
+ if (ret >= 0) {
286
+ fprintf(stderr, "cmd %i unaligned size %i\n",
287
+ cmd_op, ret);
288
+ return 1;
289
+ }
290
+
291
+ close(fd);
292
+ return 0;
293
+ }
294
+
295
+ static int test_rdonly(struct io_uring *ring, int op)
296
+ {
297
+ int ret, fd;
298
+ int ro;
299
+
300
+ if (!opcodes[op].test)
301
+ return T_EXIT_SKIP;
302
+
303
+ fd = open(filename, O_DIRECT | O_RDONLY | O_EXCL);
304
+ if (fd < 0) {
305
+ fprintf(stderr, "open failed %i\n", errno);
306
+ return T_EXIT_FAIL;
307
+ }
308
+
309
+ ret = queue_discard_lba(ring, fd, 0, 1);
310
+ if (ret >= 0) {
311
+ fprintf(stderr, "discarded with O_RDONLY %i\n", ret);
312
+ return 1;
313
+ }
314
+ close(fd);
315
+
316
+ fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
317
+ if (fd < 0) {
318
+ fprintf(stderr, "open failed %i\n", errno);
319
+ return T_EXIT_FAIL;
320
+ }
321
+
322
+ ro = 1;
323
+ ret = ioctl(fd, BLKROSET, &ro);
324
+ if (ret) {
325
+ fprintf(stderr, "BLKROSET 1 failed %i\n", errno);
326
+ return T_EXIT_FAIL;
327
+ }
328
+
329
+ ret = queue_discard_lba(ring, fd, 0, 1);
330
+ if (ret >= 0) {
331
+ fprintf(stderr, "discarded with O_RDONLY %i\n", ret);
332
+ return 1;
333
+ }
334
+
335
+ ro = 0;
336
+ ret = ioctl(fd, BLKROSET, &ro);
337
+ if (ret) {
338
+ fprintf(stderr, "BLKROSET 0 failed %i\n", errno);
339
+ return T_EXIT_FAIL;
340
+ }
341
+ close(fd);
342
+ return 0;
343
+ }
344
+
345
+ int main(int argc, char *argv[])
346
+ {
347
+ struct io_uring ring;
348
+ int fd, ret, i, fret;
349
+ int cmd_op;
350
+
351
+ if (argc != 2)
352
+ return T_EXIT_SKIP;
353
+ filename = argv[1];
354
+
355
+ fd = open(filename, O_DIRECT | O_RDONLY | O_EXCL);
356
+ if (fd < 0) {
357
+ fprintf(stderr, "open failed %i\n", errno);
358
+ return T_EXIT_FAIL;
359
+ }
360
+
361
+ ret = ioctl(fd, BLKGETSIZE64, &bdev_size);
362
+ if (ret < 0) {
363
+ fprintf(stderr, "BLKGETSIZE64 failed %i\n", errno);
364
+ return T_EXIT_FAIL;
365
+ }
366
+ ret = ioctl(fd, BLKSSZGET, &lba_size);
367
+ if (ret < 0) {
368
+ fprintf(stderr, "BLKSSZGET failed %i\n", errno);
369
+ return T_EXIT_FAIL;
370
+ }
371
+ assert(bdev_size % lba_size == 0);
372
+ bdev_size_lbas = bdev_size / lba_size;
373
+ close(fd);
374
+
375
+ buffer = aligned_alloc(lba_size, lba_size);
376
+ if (!buffer) {
377
+ fprintf(stderr, "aligned_alloc failed\n");
378
+ return T_EXIT_FAIL;
379
+ }
380
+ for (i = 0; i < lba_size; i++)
381
+ buffer[i] = i ^ 0xA7;
382
+
383
+ if (bdev_size_lbas < MAX_TEST_LBAS) {
384
+ fprintf(stderr, "the device is too small, skip\n");
385
+ return T_EXIT_SKIP;
386
+ }
387
+
388
+ ret = io_uring_queue_init(16, &ring, 0);
389
+ if (ret) {
390
+ fprintf(stderr, "queue init failed: %d\n", ret);
391
+ return T_EXIT_FAIL;
392
+ }
393
+
394
+ fret = T_EXIT_SKIP;
395
+ for (cmd_op = 0; cmd_op < TEST_BLOCK_URING_CMD_MAX; cmd_op++) {
396
+ if (!opcodes[cmd_op].test)
397
+ continue;
398
+ ret = basic_cmd_test(&ring, cmd_op);
399
+ if (ret) {
400
+ if (ret == T_EXIT_SKIP)
401
+ continue;
402
+
403
+ fprintf(stderr, "basic_cmd_test() failed, cmd %i\n",
404
+ cmd_op);
405
+ return T_EXIT_FAIL;
406
+ }
407
+
408
+ ret = test_rdonly(&ring, cmd_op);
409
+ if (ret) {
410
+ fprintf(stderr, "test_rdonly() failed, cmd %i\n",
411
+ cmd_op);
412
+ return T_EXIT_FAIL;
413
+ }
414
+
415
+ ret = test_fail_edge_cases(&ring, cmd_op);
416
+ if (ret) {
417
+ fprintf(stderr, "test_fail_edge_cases() failed, cmd %i\n",
418
+ cmd_op);
419
+ return T_EXIT_FAIL;
420
+ }
421
+ fret = T_EXIT_PASS;
422
+ }
423
+
424
+ io_uring_queue_exit(&ring);
425
+ free(buffer);
426
+ return fret;
427
+ }
@@ -16,6 +16,7 @@
16
16
  #include "liburing.h"
17
17
  #include "helpers.h"
18
18
 
19
+ #ifndef CONFIG_USE_SANITIZER
19
20
  static void test(void)
20
21
  {
21
22
  struct io_uring_sqe *sqe;
@@ -58,3 +59,9 @@ int main(int argc, char *argv[])
58
59
  unlink("core");
59
60
  return T_EXIT_PASS;
60
61
  }
62
+ #else
63
+ int main(int argc, char *argv[])
64
+ {
65
+ return T_EXIT_SKIP;
66
+ }
67
+ #endif
@@ -88,8 +88,10 @@ static int test_io(const char *file, unsigned long usecs, unsigned *drops,
88
88
  goto err;
89
89
  }
90
90
  offset = BS * (rand() % BUFFERS);
91
- if (fault && i == ENTRIES + 4)
91
+ if (fault && i == ENTRIES + 4) {
92
+ free(vecs[i].iov_base);
92
93
  vecs[i].iov_base = NULL;
94
+ }
93
95
  io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
94
96
 
95
97
  ret = io_uring_submit(&ring);
@@ -523,8 +525,18 @@ int main(int argc, char *argv[])
523
525
  }
524
526
 
525
527
  unlink(fname);
528
+ if(vecs != NULL) {
529
+ for (i = 0; i < BUFFERS; i++)
530
+ free(vecs[i].iov_base);
531
+ }
532
+ free(vecs);
526
533
  return T_EXIT_PASS;
527
534
  err:
528
535
  unlink(fname);
536
+ if(vecs != NULL) {
537
+ for (i = 0; i < BUFFERS; i++)
538
+ free(vecs[i].iov_base);
539
+ }
540
+ free(vecs);
529
541
  return T_EXIT_FAIL;
530
542
  }
@@ -19,10 +19,10 @@
19
19
  int main(int argc, char *argv[])
20
20
  {
21
21
  struct io_uring ring;
22
- int i, fd, ret;
22
+ int i, fd, ret, __e;
23
23
  struct io_uring_sqe *sqe;
24
24
  struct io_uring_cqe *cqe;
25
- struct iovec *iovecs;
25
+ struct iovec *iovecs = NULL;
26
26
  struct io_uring_params p;
27
27
  char *fname;
28
28
  void *buf;
@@ -43,10 +43,13 @@ int main(int argc, char *argv[])
43
43
  }
44
44
 
45
45
  fd = open(fname, O_RDONLY | O_DIRECT);
46
+ __e = errno;
46
47
  if (fname != argv[1])
47
48
  unlink(fname);
48
49
  if (fd < 0) {
49
- perror("open");
50
+ if (__e == EINVAL || __e == EPERM || __e == EACCES)
51
+ return T_EXIT_SKIP;
52
+ fprintf(stderr, "open: %s\n", strerror(__e));
50
53
  goto out;
51
54
  }
52
55
 
@@ -92,5 +95,10 @@ int main(int argc, char *argv[])
92
95
  close(fd);
93
96
  out:
94
97
  io_uring_queue_exit(&ring);
98
+ if (iovecs != NULL) { //
99
+ for (i = 0; i < 10; i++)
100
+ free(iovecs[i].iov_base);
101
+ free(iovecs);
102
+ }
95
103
  return ret;
96
104
  }
@@ -196,12 +196,12 @@ static int test_exec(const char *filename)
196
196
 
197
197
  if (filename) {
198
198
  fd = open(filename, O_RDONLY | O_DIRECT);
199
- if (fd < 0 && errno == EINVAL)
199
+ if (fd < 0 && (errno == EINVAL || errno == EPERM || errno == EACCES))
200
200
  return T_EXIT_SKIP;
201
201
  } else {
202
202
  t_create_file(EXEC_FILENAME, EXEC_FILESIZE);
203
203
  fd = open(EXEC_FILENAME, O_RDONLY | O_DIRECT);
204
- if (fd < 0 && errno == EINVAL) {
204
+ if (fd < 0 && (errno == EINVAL || errno == EPERM || errno == EACCES)) {
205
205
  unlink(EXEC_FILENAME);
206
206
  return T_EXIT_SKIP;
207
207
  }
@@ -99,7 +99,7 @@ static int test_file(struct io_uring *ring, char *__fname)
99
99
 
100
100
  fd = open(fname, O_RDONLY | O_DIRECT);
101
101
  if (fd < 0) {
102
- if (errno == EINVAL) {
102
+ if (errno == EINVAL || errno == EPERM || errno == EACCES) {
103
103
  if (!__fname)
104
104
  unlink(fname);
105
105
  return T_EXIT_SKIP;
@@ -128,6 +128,7 @@ static int test_file(struct io_uring *ring, char *__fname)
128
128
  if (ret != 1) {
129
129
  fprintf(stderr, "unexpected wait ret %d\n", ret);
130
130
  close(fd);
131
+ free(buf);
131
132
  return T_EXIT_FAIL;
132
133
  }
133
134
 
@@ -141,10 +142,12 @@ static int test_file(struct io_uring *ring, char *__fname)
141
142
  if (i != 1) {
142
143
  fprintf(stderr, "Got %d request, expected 1\n", i);
143
144
  close(fd);
145
+ free(buf);
144
146
  return T_EXIT_FAIL;
145
147
  }
146
148
 
147
149
  close(fd);
150
+ free(buf);
148
151
  return T_EXIT_PASS;
149
152
  }
150
153
 
@@ -96,7 +96,7 @@ static int test_canceled_userdata(struct io_uring *ring)
96
96
  if (init_context(&ctx, ring, nr, OP_NOP))
97
97
  return 1;
98
98
 
99
- for (i = 0; i < nr; i++)
99
+ for (i = 0; i < nr - 1; i++)
100
100
  ctx.sqes[i]->flags |= IOSQE_IO_LINK;
101
101
 
102
102
  ret = io_uring_submit(ring);
@@ -130,7 +130,7 @@ static int test_thread_link_cancel(struct io_uring *ring)
130
130
  if (init_context(&ctx, ring, nr, OP_REMOVE_BUFFERS))
131
131
  return 1;
132
132
 
133
- for (i = 0; i < nr; i++)
133
+ for (i = 0; i < nr - 1; i++)
134
134
  ctx.sqes[i]->flags |= IOSQE_IO_LINK;
135
135
 
136
136
  ret = io_uring_submit(ring);
@@ -114,7 +114,7 @@ static uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff};
114
114
  int main(int argc, char *argv[])
115
115
  {
116
116
  void *mmap_ret;
117
- #if !defined(__i386) && !defined(__x86_64__)
117
+ #if (!defined(__i386) && !defined(__x86_64__)) || defined(CONFIG_USE_SANITIZER)
118
118
  return T_EXIT_SKIP;
119
119
  #endif
120
120
 
@@ -113,8 +113,10 @@ int main(int argc, char *argv[])
113
113
  }
114
114
 
115
115
  close(fd);
116
+ free(iov.iov_base);
116
117
  return ret;
117
118
  err:
118
119
  close(fd);
120
+ free(iov.iov_base);
119
121
  return T_EXIT_FAIL;
120
122
  }
@@ -60,7 +60,6 @@ int main(int argc, char *argv[])
60
60
 
61
61
  sqe = io_uring_get_sqe(&ring);
62
62
  io_uring_prep_readv(sqe, evfd, &vec, 1, 0);
63
- sqe->flags |= IOSQE_IO_LINK;
64
63
  sqe->user_data = 2;
65
64
 
66
65
  ret = io_uring_submit(&ring);
@@ -19,6 +19,11 @@
19
19
  #include "liburing.h"
20
20
  #include "helpers.h"
21
21
 
22
+ // on fast enough machines with enough cores, the first few threads will post
23
+ // enough sem's to cause the main thread to exit while some threads are half way
24
+ // initialization. This causes a null deference somewhere in thread cleanup,
25
+ // which trips ASAN.
26
+ #ifndef CONFIG_USE_SANITIZER
22
27
  #define IORING_ENTRIES 8
23
28
 
24
29
  static pthread_t *threads;
@@ -115,3 +120,9 @@ int main(int argc, char *argv[])
115
120
  // Exit without resource cleanup
116
121
  exit(EXIT_SUCCESS);
117
122
  }
123
+ #else
124
+ int main(int argc, char *argv[])
125
+ {
126
+ return T_EXIT_SKIP;
127
+ }
128
+ #endif
@@ -18,30 +18,6 @@
18
18
  #define LOOPS 100
19
19
  #define MIN_LOOPS 10
20
20
 
21
- static unsigned long long utime_since(const struct timeval *s,
22
- const struct timeval *e)
23
- {
24
- long long sec, usec;
25
-
26
- sec = e->tv_sec - s->tv_sec;
27
- usec = (e->tv_usec - s->tv_usec);
28
- if (sec > 0 && usec < 0) {
29
- sec--;
30
- usec += 1000000;
31
- }
32
-
33
- sec *= 1000000;
34
- return sec + usec;
35
- }
36
-
37
- static unsigned long long utime_since_now(struct timeval *tv)
38
- {
39
- struct timeval end;
40
-
41
- gettimeofday(&end, NULL);
42
- return utime_since(tv, &end);
43
- }
44
-
45
21
  static int do_fadvise(struct io_uring *ring, int fd, off_t offset, off_t len,
46
22
  int advice)
47
23
  {
@@ -92,7 +68,7 @@ static long do_read(int fd, char *buf)
92
68
  perror("lseek");
93
69
  return -1;
94
70
  }
95
-
71
+
96
72
  gettimeofday(&tv, NULL);
97
73
  ret = read(fd, buf, FILE_SIZE);
98
74
  t = utime_since_now(&tv);
@@ -115,6 +91,8 @@ static int test_fadvise(struct io_uring *ring, const char *filename)
115
91
 
116
92
  fd = open(filename, O_RDONLY);
117
93
  if (fd < 0) {
94
+ if (errno == EPERM || errno == EACCES)
95
+ return T_EXIT_SKIP;
118
96
  perror("open");
119
97
  return 1;
120
98
  }
@@ -148,9 +126,12 @@ static int test_fadvise(struct io_uring *ring, const char *filename)
148
126
  return 1;
149
127
 
150
128
  if (cached_read < uncached_read &&
151
- cached_read2 < uncached_read)
129
+ cached_read2 < uncached_read) {
130
+ free(buf);
152
131
  return 0;
132
+ }
153
133
 
134
+ free(buf);
154
135
  return 2;
155
136
  }
156
137
 
@@ -174,6 +155,8 @@ int main(int argc, char *argv[])
174
155
  good = bad = 0;
175
156
  for (i = 0; i < LOOPS; i++) {
176
157
  ret = test_fadvise(&ring, fname);
158
+ if (ret == T_EXIT_SKIP)
159
+ return T_EXIT_SKIP;
177
160
  if (ret == 1) {
178
161
  fprintf(stderr, "read_fadvise failed\n");
179
162
  goto err;