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
@@ -23,7 +23,134 @@
23
23
 
24
24
  #define NR_OVERFLOW (NR_BUFS / 4)
25
25
 
26
- static int no_buf_ring, no_read_mshot;
26
+ static int no_buf_ring, no_read_mshot, no_buf_ring_inc;
27
+
28
+ static void arm_read(struct io_uring *ring, int fd, int use_mshot)
29
+ {
30
+ struct io_uring_sqe *sqe;
31
+
32
+ sqe = io_uring_get_sqe(ring);
33
+ if (use_mshot) {
34
+ io_uring_prep_read_multishot(sqe, fd, 0, 0, BUF_BGID);
35
+ } else {
36
+ io_uring_prep_read(sqe, fd, NULL, 0, 0);
37
+ sqe->flags = IOSQE_BUFFER_SELECT;
38
+ sqe->buf_group = BUF_BGID;
39
+ }
40
+
41
+ io_uring_submit(ring);
42
+ }
43
+
44
+ static int test_inc(int use_mshot, int flags)
45
+ {
46
+ struct io_uring_buf_ring *br;
47
+ struct io_uring_params p = { };
48
+ struct io_uring_cqe *cqe;
49
+ struct io_uring ring;
50
+ int nbytes = 65536;
51
+ int ret, fds[2], i;
52
+ char tmp[31];
53
+ char *buf;
54
+ void *ptr;
55
+ int bid = -1;
56
+ int bid_bytes;
57
+
58
+ if (no_buf_ring)
59
+ return 0;
60
+
61
+ p.flags = flags;
62
+ ret = io_uring_queue_init_params(64, &ring, &p);
63
+ if (ret) {
64
+ fprintf(stderr, "ring setup failed: %d\n", ret);
65
+ return 1;
66
+ }
67
+
68
+ if (pipe(fds) < 0) {
69
+ perror("pipe");
70
+ return 1;
71
+ }
72
+
73
+ if (posix_memalign((void **) &buf, 4096, 65536))
74
+ return 1;
75
+
76
+ br = io_uring_setup_buf_ring(&ring, 32, BUF_BGID, IOU_PBUF_RING_INC, &ret);
77
+ if (!br) {
78
+ if (ret == -EINVAL) {
79
+ no_buf_ring_inc = 1;
80
+ free(buf);
81
+ return 0;
82
+ }
83
+ fprintf(stderr, "Buffer ring register failed %d\n", ret);
84
+ return 1;
85
+ }
86
+
87
+ ptr = buf;
88
+ buf = ptr + 65536 - 2048;
89
+ for (i = 0; i < 32; i++) {
90
+ io_uring_buf_ring_add(br, buf, 2048, i, 31, i);
91
+ buf -= 2048;
92
+ }
93
+ io_uring_buf_ring_advance(br, 32);
94
+
95
+ memset(tmp, 0x5a, sizeof(tmp));
96
+
97
+ arm_read(&ring, fds[0], use_mshot);
98
+
99
+ bid_bytes = 0;
100
+ do {
101
+ int write_size = sizeof(tmp);
102
+
103
+ if (write_size > nbytes)
104
+ write_size = nbytes;
105
+
106
+ io_uring_get_events(&ring);
107
+ ret = io_uring_peek_cqe(&ring, &cqe);
108
+ if (!ret) {
109
+ int this_bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
110
+ if (bid == -1) {
111
+ bid = this_bid;
112
+ } else if (bid != this_bid) {
113
+ if (bid_bytes != 2048) {
114
+ fprintf(stderr, "unexpected bid bytes %d\n",
115
+ bid_bytes);
116
+ return 1;
117
+ }
118
+ bid = this_bid;
119
+ bid_bytes = 0;
120
+ }
121
+ bid_bytes += cqe->res;
122
+ nbytes -= cqe->res;
123
+ if (!(cqe->flags & IORING_CQE_F_MORE))
124
+ arm_read(&ring, fds[0], use_mshot);
125
+ io_uring_cqe_seen(&ring, cqe);
126
+ if (!nbytes)
127
+ break;
128
+ }
129
+ usleep(1000);
130
+ ret = write(fds[1], tmp, write_size);
131
+ if (ret < 0) {
132
+ perror("write");
133
+ return 1;
134
+ } else if (ret != write_size) {
135
+ printf("short write %d\n", ret);
136
+ return 1;
137
+ }
138
+ } while (nbytes);
139
+
140
+ if (bid_bytes) {
141
+ if (bid_bytes != 2048) {
142
+ fprintf(stderr, "unexpected bid bytes %d\n", bid_bytes);
143
+ return 1;
144
+ }
145
+ }
146
+
147
+ io_uring_free_buf_ring(&ring, br, 32, BUF_BGID);
148
+ io_uring_queue_exit(&ring);
149
+ free(ptr);
150
+ close(fds[0]);
151
+ close(fds[1]);
152
+ return 0;
153
+ }
27
154
 
28
155
  static int test_clamp(void)
29
156
  {
@@ -129,21 +256,24 @@ static int test_clamp(void)
129
256
  io_uring_cqe_seen(&ring, cqe);
130
257
  }
131
258
 
259
+ io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
132
260
  io_uring_queue_exit(&ring);
133
261
  free(ptr);
134
262
  return 0;
135
263
  }
136
264
 
137
- static int test(int first_good, int async, int overflow)
265
+ static int test(int first_good, int async, int overflow, int incremental)
138
266
  {
139
267
  struct io_uring_buf_ring *br;
140
268
  struct io_uring_params p = { };
141
269
  struct io_uring_sqe *sqe;
142
270
  struct io_uring_cqe *cqe;
143
271
  struct io_uring ring;
144
- int ret, fds[2], i;
272
+ int ret, fds[2], i, start_msg = 0;
273
+ int br_flags = 0;
145
274
  char tmp[32];
146
275
  void *ptr[NR_BUFS];
276
+ char *inc_index;
147
277
 
148
278
  p.flags = IORING_SETUP_CQSIZE;
149
279
  if (!overflow)
@@ -156,14 +286,19 @@ static int test(int first_good, int async, int overflow)
156
286
  return 1;
157
287
  }
158
288
 
159
- if (pipe(fds) < 0) {
160
- perror("pipe");
161
- return 1;
289
+ if (incremental) {
290
+ if (no_buf_ring_inc)
291
+ return 0;
292
+ br_flags |= IOU_PBUF_RING_INC;
162
293
  }
163
294
 
164
- br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, 0, &ret);
295
+ br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, br_flags, &ret);
165
296
  if (!br) {
166
297
  if (ret == -EINVAL) {
298
+ if (incremental) {
299
+ no_buf_ring_inc = 1;
300
+ return 0;
301
+ }
167
302
  no_buf_ring = 1;
168
303
  return 0;
169
304
  }
@@ -171,17 +306,30 @@ static int test(int first_good, int async, int overflow)
171
306
  return 1;
172
307
  }
173
308
 
174
- for (i = 0; i < NR_BUFS; i++) {
175
- unsigned size = i <= 1 ? BUF_SIZE_FIRST : BUF_SIZE;
176
- ptr[i] = malloc(size);
177
- if (!ptr[i])
178
- return 1;
179
- io_uring_buf_ring_add(br, ptr[i], size, i + 1, BR_MASK, i);
309
+ if (pipe(fds) < 0) {
310
+ perror("pipe");
311
+ return 1;
312
+ }
313
+
314
+ if (!incremental) {
315
+ for (i = 0; i < NR_BUFS; i++) {
316
+ unsigned size = i <= 1 ? BUF_SIZE_FIRST : BUF_SIZE;
317
+ ptr[i] = malloc(size);
318
+ if (!ptr[i])
319
+ return 1;
320
+ io_uring_buf_ring_add(br, ptr[i], size, i + 1, BR_MASK, i);
321
+ }
322
+ inc_index = NULL;
323
+ io_uring_buf_ring_advance(br, NR_BUFS);
324
+ } else {
325
+ inc_index = ptr[0] = malloc(NR_BUFS * BUF_SIZE);
326
+ memset(inc_index, 0, NR_BUFS * BUF_SIZE);
327
+ io_uring_buf_ring_add(br, ptr[0], NR_BUFS * BUF_SIZE, 1, BR_MASK, 0);
328
+ io_uring_buf_ring_advance(br, 1);
180
329
  }
181
- io_uring_buf_ring_advance(br, NR_BUFS);
182
330
 
183
331
  if (first_good) {
184
- sprintf(tmp, "this is buffer %d\n", 0);
332
+ sprintf(tmp, "this is buffer %d\n", start_msg++);
185
333
  ret = write(fds[1], tmp, strlen(tmp));
186
334
  }
187
335
 
@@ -201,7 +349,7 @@ static int test(int first_good, int async, int overflow)
201
349
  for (i = 0; i < NR_BUFS + !first_good; i++) {
202
350
  /* prevent pipe buffer merging */
203
351
  usleep(1000);
204
- sprintf(tmp, "this is buffer %d\n", i + 1);
352
+ sprintf(tmp, "this is buffer %d\n", i + start_msg);
205
353
  ret = write(fds[1], tmp, strlen(tmp));
206
354
  if (ret != strlen(tmp)) {
207
355
  fprintf(stderr, "write ret %d\n", ret);
@@ -210,6 +358,8 @@ static int test(int first_good, int async, int overflow)
210
358
  }
211
359
 
212
360
  for (i = 0; i < NR_BUFS + 1; i++) {
361
+ int bid;
362
+
213
363
  ret = io_uring_wait_cqe(&ring, &cqe);
214
364
  if (ret) {
215
365
  fprintf(stderr, "wait cqe failed %d\n", ret);
@@ -234,6 +384,18 @@ static int test(int first_good, int async, int overflow)
234
384
  fprintf(stderr, "no buffer selected\n");
235
385
  return 1;
236
386
  }
387
+ bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
388
+ if (incremental && bid != 1) {
389
+ fprintf(stderr, "bid %d for incremental\n", bid);
390
+ return 1;
391
+ }
392
+ if (incremental && !first_good) {
393
+ char out_buf[64];
394
+ sprintf(out_buf, "this is buffer %d\n", i + start_msg);
395
+ if (strncmp(inc_index, out_buf, strlen(out_buf)))
396
+ return 1;
397
+ inc_index += cqe->res;
398
+ }
237
399
  if (!(cqe->flags & IORING_CQE_F_MORE)) {
238
400
  /* we expect this on overflow */
239
401
  if (overflow && i >= NR_OVERFLOW)
@@ -249,9 +411,15 @@ static int test(int first_good, int async, int overflow)
249
411
  io_uring_cqe_seen(&ring, cqe);
250
412
  }
251
413
 
414
+
415
+ io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
252
416
  io_uring_queue_exit(&ring);
253
- for (i = 0; i < NR_BUFS; i++)
254
- free(ptr[i]);
417
+ if (incremental) {
418
+ free(ptr[0]);
419
+ } else {
420
+ for (i = 0; i < NR_BUFS; i++)
421
+ free(ptr[i]);
422
+ }
255
423
  return 0;
256
424
  }
257
425
 
@@ -320,6 +488,7 @@ static int test_invalid(int async)
320
488
  }
321
489
 
322
490
  io_uring_cqe_seen(&ring, cqe);
491
+ io_uring_free_buf_ring(&ring, br, 1, BUF_BGID);
323
492
  io_uring_queue_exit(&ring);
324
493
  free(buf);
325
494
  return 0;
@@ -332,56 +501,106 @@ int main(int argc, char *argv[])
332
501
  if (argc > 1)
333
502
  return T_EXIT_SKIP;
334
503
 
335
- ret = test(0, 0, 0);
504
+ ret = test(0, 0, 0, 0);
336
505
  if (ret) {
337
506
  fprintf(stderr, "test 0 0 0 failed\n");
338
507
  return T_EXIT_FAIL;
339
508
  }
340
- if (no_buf_ring || no_read_mshot)
509
+ if (no_buf_ring || no_read_mshot) {
510
+ printf("skip\n");
341
511
  return T_EXIT_SKIP;
512
+ }
342
513
 
343
- ret = test(0, 1, 0);
514
+ ret = test(0, 1, 0, 0);
344
515
  if (ret) {
345
516
  fprintf(stderr, "test 0 1 0, failed\n");
346
517
  return T_EXIT_FAIL;
347
518
  }
348
519
 
349
- ret = test(1, 0, 0);
520
+ ret = test(1, 0, 0, 0);
350
521
  if (ret) {
351
522
  fprintf(stderr, "test 1 0 0 failed\n");
352
523
  return T_EXIT_FAIL;
353
524
  }
354
525
 
355
- ret = test(0, 0, 1);
526
+ ret = test(0, 0, 1, 0);
356
527
  if (ret) {
357
528
  fprintf(stderr, "test 0 0 1 failed\n");
358
529
  return T_EXIT_FAIL;
359
530
  }
360
531
 
361
- ret = test(0, 1, 1);
532
+ ret = test(0, 1, 1, 0);
362
533
  if (ret) {
363
534
  fprintf(stderr, "test 0 1 1 failed\n");
364
535
  return T_EXIT_FAIL;
365
536
  }
366
537
 
367
- ret = test(1, 0, 1);
538
+ ret = test(1, 0, 1, 0);
368
539
  if (ret) {
369
540
  fprintf(stderr, "test 1 0 1, failed\n");
370
541
  return T_EXIT_FAIL;
371
542
  }
372
543
 
373
- ret = test(1, 0, 1);
544
+ ret = test(1, 0, 1, 0);
374
545
  if (ret) {
375
546
  fprintf(stderr, "test 1 0 1 failed\n");
376
547
  return T_EXIT_FAIL;
377
548
  }
378
549
 
379
- ret = test(1, 1, 1);
550
+ ret = test(1, 1, 1, 0);
380
551
  if (ret) {
381
552
  fprintf(stderr, "test 1 1 1 failed\n");
382
553
  return T_EXIT_FAIL;
383
554
  }
384
555
 
556
+ ret = test(0, 0, 0, 1);
557
+ if (ret) {
558
+ fprintf(stderr, "test 0 0 0 1 failed\n");
559
+ return T_EXIT_FAIL;
560
+ }
561
+
562
+ ret = test(0, 0, 1, 1);
563
+ if (ret) {
564
+ fprintf(stderr, "test 0 0 1 1 failed\n");
565
+ return T_EXIT_FAIL;
566
+ }
567
+
568
+ ret = test(0, 1, 0, 1);
569
+ if (ret) {
570
+ fprintf(stderr, "test 0 1 0 1 failed\n");
571
+ return T_EXIT_FAIL;
572
+ }
573
+
574
+ ret = test(0, 1, 1, 1);
575
+ if (ret) {
576
+ fprintf(stderr, "test 0 1 1 1 failed\n");
577
+ return T_EXIT_FAIL;
578
+ }
579
+
580
+ ret = test(1, 0, 0, 1);
581
+ if (ret) {
582
+ fprintf(stderr, "test 1 0 0 1 failed\n");
583
+ return T_EXIT_FAIL;
584
+ }
585
+
586
+ ret = test(1, 0, 1, 1);
587
+ if (ret) {
588
+ fprintf(stderr, "test 1 0 1 1 failed\n");
589
+ return T_EXIT_FAIL;
590
+ }
591
+
592
+ ret = test(1, 1, 0, 1);
593
+ if (ret) {
594
+ fprintf(stderr, "test 1 1 0 1 failed\n");
595
+ return T_EXIT_FAIL;
596
+ }
597
+
598
+ ret = test(1, 1, 1, 1);
599
+ if (ret) {
600
+ fprintf(stderr, "test 1 1 1 1 failed\n");
601
+ return T_EXIT_FAIL;
602
+ }
603
+
385
604
  ret = test_invalid(0);
386
605
  if (ret) {
387
606
  fprintf(stderr, "test_invalid 0 failed\n");
@@ -400,5 +619,41 @@ int main(int argc, char *argv[])
400
619
  return T_EXIT_FAIL;
401
620
  }
402
621
 
622
+ ret = test_inc(0, 0);
623
+ if (ret) {
624
+ fprintf(stderr, "test_inc 0 0 failed\n");
625
+ return T_EXIT_FAIL;
626
+ }
627
+
628
+ ret = test_inc(0, IORING_SETUP_SQPOLL);
629
+ if (ret) {
630
+ fprintf(stderr, "test_inc 0 sqpoll failed\n");
631
+ return T_EXIT_FAIL;
632
+ }
633
+
634
+ ret = test_inc(0, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
635
+ if (ret) {
636
+ fprintf(stderr, "test_inc 0 defer failed\n");
637
+ return T_EXIT_FAIL;
638
+ }
639
+
640
+ ret = test_inc(1, 0);
641
+ if (ret) {
642
+ fprintf(stderr, "test_inc 1 0 failed\n");
643
+ return T_EXIT_FAIL;
644
+ }
645
+
646
+ ret = test_inc(1, IORING_SETUP_SQPOLL);
647
+ if (ret) {
648
+ fprintf(stderr, "test_inc 1 sqpoll failed\n");
649
+ return T_EXIT_FAIL;
650
+ }
651
+
652
+ ret = test_inc(1, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
653
+ if (ret) {
654
+ fprintf(stderr, "test_inc 1 defer failed\n");
655
+ return T_EXIT_FAIL;
656
+ }
657
+
403
658
  return T_EXIT_PASS;
404
659
  }
@@ -15,6 +15,7 @@
15
15
 
16
16
  #include "helpers.h"
17
17
  #include "liburing.h"
18
+ #include "../src/syscall.h"
18
19
 
19
20
  #define FILE_SIZE (256 * 1024)
20
21
  #define BS 8192
@@ -23,6 +24,7 @@
23
24
  static struct iovec *vecs;
24
25
  static int no_read;
25
26
  static int no_buf_select;
27
+ static int no_buf_copy;
26
28
  static int warned;
27
29
 
28
30
  static int create_nonaligned_buffers(void)
@@ -42,9 +44,9 @@ static int create_nonaligned_buffers(void)
42
44
  return 0;
43
45
  }
44
46
 
45
- static int __test_io(const char *file, struct io_uring *ring, int write,
46
- int buffered, int sqthread, int fixed, int nonvec,
47
- int buf_select, int seq, int exp_len)
47
+ static int _test_io(const char *file, struct io_uring *ring, int write,
48
+ int buffered, int sqthread, int fixed, int nonvec,
49
+ int buf_select, int seq, int exp_len)
48
50
  {
49
51
  struct io_uring_sqe *sqe;
50
52
  struct io_uring_cqe *cqe;
@@ -64,7 +66,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
64
66
  if (!buffered)
65
67
  open_flags |= O_DIRECT;
66
68
 
67
- if (fixed) {
69
+ if (fixed == 1) {
68
70
  ret = t_register_buffers(ring, vecs, BUFFERS);
69
71
  if (ret == T_SETUP_SKIP)
70
72
  return 0;
@@ -76,7 +78,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
76
78
 
77
79
  fd = open(file, open_flags);
78
80
  if (fd < 0) {
79
- if (errno == EINVAL)
81
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
80
82
  return 0;
81
83
  perror("file open");
82
84
  goto err;
@@ -201,13 +203,6 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
201
203
  io_uring_cqe_seen(ring, cqe);
202
204
  }
203
205
 
204
- if (fixed) {
205
- ret = io_uring_unregister_buffers(ring);
206
- if (ret) {
207
- fprintf(stderr, "buffer unreg failed: %d\n", ret);
208
- goto err;
209
- }
210
- }
211
206
  if (sqthread) {
212
207
  ret = io_uring_unregister_files(ring);
213
208
  if (ret) {
@@ -229,6 +224,65 @@ err:
229
224
  close(fd);
230
225
  return 1;
231
226
  }
227
+
228
+ static int __test_io(const char *file, struct io_uring *ring, int write,
229
+ int buffered, int sqthread, int fixed, int nonvec,
230
+ int buf_select, int seq, int exp_len)
231
+ {
232
+ int ret;
233
+
234
+ ret = _test_io(file, ring, write, buffered, sqthread, fixed, nonvec,
235
+ buf_select, seq, exp_len);
236
+ if (ret)
237
+ return ret;
238
+
239
+ if (fixed) {
240
+ struct io_uring ring2;
241
+ int ring_flags = 0;
242
+
243
+ if (no_buf_copy)
244
+ return 0;
245
+ if (sqthread)
246
+ ring_flags = IORING_SETUP_SQPOLL;
247
+ ret = t_create_ring(64, &ring2, ring_flags);
248
+ if (ret == T_SETUP_SKIP)
249
+ return 0;
250
+ if (ret != T_SETUP_OK) {
251
+ fprintf(stderr, "ring create failed: %d\n", ret);
252
+ return 1;
253
+ }
254
+
255
+ ret = io_uring_clone_buffers(&ring2, ring);
256
+ if (ret) {
257
+ if (ret == -EINVAL) {
258
+ no_buf_copy = 1;
259
+ io_uring_queue_exit(&ring2);
260
+ return 0;
261
+ }
262
+ fprintf(stderr, "copy buffers: %d\n", ret);
263
+ return ret;
264
+ }
265
+ ret = _test_io(file, &ring2, write, buffered, sqthread, 2,
266
+ nonvec, buf_select, seq, exp_len);
267
+ if (ret)
268
+ return ret;
269
+
270
+ ret = io_uring_unregister_buffers(ring);
271
+ if (ret) {
272
+ fprintf(stderr, "buffer unreg failed: %d\n", ret);
273
+ return ret;
274
+ }
275
+ ret = io_uring_unregister_buffers(&ring2);
276
+ if (ret) {
277
+ fprintf(stderr, "buffer copy unreg failed: %d\n", ret);
278
+ return ret;
279
+ }
280
+ io_uring_queue_exit(&ring2);
281
+ }
282
+
283
+ return ret;
284
+ }
285
+
232
286
  static int test_io(const char *file, int write, int buffered, int sqthread,
233
287
  int fixed, int nonvec, int exp_len)
234
288
  {
@@ -266,6 +320,8 @@ static int read_poll_link(const char *file)
266
320
 
267
321
  fd = open(file, O_WRONLY);
268
322
  if (fd < 0) {
323
+ if (errno == EACCES || errno == EPERM)
324
+ return T_EXIT_SKIP;
269
325
  perror("open");
270
326
  return 1;
271
327
  }
@@ -338,6 +394,7 @@ out:
338
394
  if (!(p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED))
339
395
  goto out;
340
396
  io_uring_queue_exit(&ring);
397
+ free(p);
341
398
  return 1;
342
399
  }
343
400
 
@@ -696,6 +753,8 @@ static int test_io_link(const char *file)
696
753
 
697
754
  fd = open(file, O_WRONLY);
698
755
  if (fd < 0) {
756
+ if (errno == EPERM || errno == EACCES)
757
+ return 0;
699
758
  perror("file open");
700
759
  goto err;
701
760
  }
@@ -929,7 +988,7 @@ int main(int argc, char *argv[])
929
988
  }
930
989
 
931
990
  ret = read_poll_link(fname);
932
- if (ret) {
991
+ if (ret == T_EXIT_FAIL) {
933
992
  fprintf(stderr, "read_poll_link failed\n");
934
993
  goto err;
935
994
  }
@@ -970,6 +1029,12 @@ int main(int argc, char *argv[])
970
1029
  goto err;
971
1030
  }
972
1031
 
1032
+ if(vecs != NULL) {
1033
+ for (i = 0; i < BUFFERS; i++)
1034
+ free(vecs[i].iov_base);
1035
+ }
1036
+ free(vecs);
1037
+
973
1038
  srand((unsigned)time(NULL));
974
1039
  if (create_nonaligned_buffers()) {
975
1040
  fprintf(stderr, "file creation failed\n");
@@ -317,6 +317,7 @@ static int do_send(struct recv_data *rd)
317
317
  if (cqe->res == -EINVAL) {
318
318
  fprintf(stdout, "send not supported, skipping\n");
319
319
  close(sockfd);
320
+ free(buf);
320
321
  return 0;
321
322
  }
322
323
  if (cqe->res != iov.iov_len) {
@@ -328,10 +329,12 @@ static int do_send(struct recv_data *rd)
328
329
 
329
330
  shutdown(sockfd, SHUT_RDWR);
330
331
  close(sockfd);
332
+ free(buf);
331
333
  return 0;
332
334
  err:
333
335
  shutdown(sockfd, SHUT_RDWR);
334
336
  close(sockfd);
337
+ free(buf);
335
338
  return 1;
336
339
  }
337
340
 
@@ -171,12 +171,14 @@ static int do_send(void)
171
171
  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
172
172
  if (sockfd < 0) {
173
173
  perror("socket");
174
+ free(buf);
174
175
  return 1;
175
176
  }
176
177
 
177
178
  ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
178
179
  if (ret < 0) {
179
180
  perror("connect");
181
+ free(buf);
180
182
  return 1;
181
183
  }
182
184
 
@@ -201,6 +203,7 @@ static int do_send(void)
201
203
  if (cqe->res == -EINVAL) {
202
204
  fprintf(stdout, "send not supported, skipping\n");
203
205
  close(sockfd);
206
+ free(buf);
204
207
  return 0;
205
208
  }
206
209
  if (cqe->res != iov.iov_len) {
@@ -211,9 +214,11 @@ static int do_send(void)
211
214
  }
212
215
 
213
216
  close(sockfd);
217
+ free(buf);
214
218
  return 0;
215
219
  err:
216
220
  close(sockfd);
221
+ free(buf);
217
222
  return 1;
218
223
  }
219
224