polyphony 0.98 → 0.99

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/examples/io/https_server_sni_2.rb +14 -8
  4. data/ext/polyphony/extconf.rb +6 -5
  5. data/ext/polyphony/libev.h +0 -2
  6. data/lib/polyphony/core/sync.rb +53 -0
  7. data/lib/polyphony/extensions/io.rb +37 -14
  8. data/lib/polyphony/extensions/openssl.rb +1 -1
  9. data/lib/polyphony/version.rb +1 -1
  10. data/test/test_io.rb +6 -7
  11. data/test/test_socket.rb +61 -0
  12. data/test/test_sync.rb +42 -1
  13. data/vendor/liburing/.github/workflows/build.yml +7 -16
  14. data/vendor/liburing/.gitignore +5 -0
  15. data/vendor/liburing/CHANGELOG +23 -1
  16. data/vendor/liburing/Makefile +4 -3
  17. data/vendor/liburing/Makefile.common +1 -0
  18. data/vendor/liburing/README +48 -0
  19. data/vendor/liburing/configure +76 -6
  20. data/vendor/liburing/debian/changelog +11 -0
  21. data/vendor/liburing/debian/control +7 -16
  22. data/vendor/liburing/debian/liburing-dev.manpages +3 -6
  23. data/vendor/liburing/debian/liburing2.install +1 -0
  24. data/vendor/liburing/debian/liburing2.symbols +56 -0
  25. data/vendor/liburing/debian/rules +15 -68
  26. data/vendor/liburing/examples/Makefile +4 -0
  27. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  28. data/vendor/liburing/examples/io_uring-udp.c +1 -1
  29. data/vendor/liburing/examples/send-zerocopy.c +315 -56
  30. data/vendor/liburing/examples/ucontext-cp.c +2 -17
  31. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  32. data/vendor/liburing/liburing.pc.in +1 -1
  33. data/vendor/liburing/liburing.spec +1 -1
  34. data/vendor/liburing/make-debs.sh +3 -3
  35. data/vendor/liburing/man/IO_URING_CHECK_VERSION.3 +1 -0
  36. data/vendor/liburing/man/IO_URING_VERSION_MAJOR.3 +1 -0
  37. data/vendor/liburing/man/IO_URING_VERSION_MINOR.3 +1 -0
  38. data/vendor/liburing/man/io_uring_buf_ring_add.3 +6 -6
  39. data/vendor/liburing/man/io_uring_check_version.3 +72 -0
  40. data/vendor/liburing/man/io_uring_close_ring_fd.3 +43 -0
  41. data/vendor/liburing/man/io_uring_major_version.3 +1 -0
  42. data/vendor/liburing/man/io_uring_minor_version.3 +1 -0
  43. data/vendor/liburing/man/io_uring_prep_accept.3 +1 -1
  44. data/vendor/liburing/man/io_uring_prep_fgetxattr.3 +1 -0
  45. data/vendor/liburing/man/io_uring_prep_fsetxattr.3 +1 -0
  46. data/vendor/liburing/man/io_uring_prep_getxattr.3 +61 -0
  47. data/vendor/liburing/man/io_uring_prep_link_timeout.3 +94 -0
  48. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +22 -2
  49. data/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3 +1 -0
  50. data/vendor/liburing/man/io_uring_prep_poll_add.3 +1 -1
  51. data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +18 -9
  52. data/vendor/liburing/man/io_uring_prep_readv.3 +3 -3
  53. data/vendor/liburing/man/io_uring_prep_readv2.3 +3 -3
  54. data/vendor/liburing/man/io_uring_prep_recv.3 +5 -5
  55. data/vendor/liburing/man/io_uring_prep_recvmsg.3 +4 -4
  56. data/vendor/liburing/man/io_uring_prep_send.3 +9 -0
  57. data/vendor/liburing/man/io_uring_prep_send_set_addr.3 +38 -0
  58. data/vendor/liburing/man/io_uring_prep_send_zc.3 +39 -7
  59. data/vendor/liburing/man/io_uring_prep_send_zc_fixed.3 +1 -0
  60. data/vendor/liburing/man/io_uring_prep_sendmsg.3 +20 -0
  61. data/vendor/liburing/man/io_uring_prep_sendmsg_zc.3 +1 -0
  62. data/vendor/liburing/man/io_uring_prep_setxattr.3 +64 -0
  63. data/vendor/liburing/man/io_uring_prep_splice.3 +40 -0
  64. data/vendor/liburing/man/io_uring_prep_writev.3 +2 -2
  65. data/vendor/liburing/man/io_uring_prep_writev2.3 +2 -2
  66. data/vendor/liburing/man/io_uring_recvmsg_out.3 +13 -9
  67. data/vendor/liburing/man/io_uring_register.2 +15 -9
  68. data/vendor/liburing/man/io_uring_register_buf_ring.3 +4 -4
  69. data/vendor/liburing/man/io_uring_register_buffers.3 +49 -6
  70. data/vendor/liburing/man/io_uring_register_buffers_sparse.3 +1 -0
  71. data/vendor/liburing/man/io_uring_register_buffers_tags.3 +1 -0
  72. data/vendor/liburing/man/io_uring_register_buffers_update_tag.3 +1 -0
  73. data/vendor/liburing/man/io_uring_register_files.3 +60 -5
  74. data/vendor/liburing/man/io_uring_register_files_tags.3 +1 -0
  75. data/vendor/liburing/man/io_uring_register_files_update.3 +1 -0
  76. data/vendor/liburing/man/io_uring_register_files_update_tag.3 +1 -0
  77. data/vendor/liburing/man/io_uring_setup.2 +31 -2
  78. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +1 -1
  79. data/vendor/liburing/src/Makefile +25 -3
  80. data/vendor/liburing/src/ffi.c +15 -0
  81. data/vendor/liburing/src/include/liburing/io_uring.h +30 -7
  82. data/vendor/liburing/src/include/liburing.h +190 -148
  83. data/vendor/liburing/src/int_flags.h +1 -0
  84. data/vendor/liburing/src/lib.h +5 -16
  85. data/vendor/liburing/src/liburing-ffi.map +172 -0
  86. data/vendor/liburing/src/liburing.map +11 -0
  87. data/vendor/liburing/src/nolibc.c +9 -2
  88. data/vendor/liburing/src/queue.c +2 -2
  89. data/vendor/liburing/src/register.c +66 -96
  90. data/vendor/liburing/src/setup.c +5 -4
  91. data/vendor/liburing/src/version.c +21 -0
  92. data/vendor/liburing/test/232c93d07b74.c +3 -3
  93. data/vendor/liburing/test/35fa71a030ca.c +3 -3
  94. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  95. data/vendor/liburing/test/917257daa0fe.c +1 -1
  96. data/vendor/liburing/test/Makefile +27 -7
  97. data/vendor/liburing/test/a0908ae19763.c +2 -2
  98. data/vendor/liburing/test/a4c0b3decb33.c +2 -2
  99. data/vendor/liburing/test/accept-link.c +4 -4
  100. data/vendor/liburing/test/accept-reuse.c +5 -7
  101. data/vendor/liburing/test/accept.c +34 -31
  102. data/vendor/liburing/test/b19062a56726.c +1 -1
  103. data/vendor/liburing/test/buf-ring.c +58 -4
  104. data/vendor/liburing/test/ce593a6c480a.c +2 -2
  105. data/vendor/liburing/test/close-opath.c +2 -1
  106. data/vendor/liburing/test/connect.c +8 -0
  107. data/vendor/liburing/test/cq-overflow.c +14 -8
  108. data/vendor/liburing/test/d4ae271dfaae.c +1 -1
  109. data/vendor/liburing/test/defer-taskrun.c +64 -9
  110. data/vendor/liburing/test/defer.c +1 -1
  111. data/vendor/liburing/test/double-poll-crash.c +3 -3
  112. data/vendor/liburing/test/eeed8b54e0df.c +8 -3
  113. data/vendor/liburing/test/eploop.c +74 -0
  114. data/vendor/liburing/test/eventfd-ring.c +1 -1
  115. data/vendor/liburing/test/eventfd.c +1 -1
  116. data/vendor/liburing/test/evloop.c +73 -0
  117. data/vendor/liburing/test/exit-no-cleanup.c +1 -1
  118. data/vendor/liburing/test/fadvise.c +1 -1
  119. data/vendor/liburing/test/fc2a85cb02ef.c +3 -3
  120. data/vendor/liburing/test/fd-pass.c +35 -16
  121. data/vendor/liburing/test/file-register.c +61 -0
  122. data/vendor/liburing/test/file-verify.c +2 -2
  123. data/vendor/liburing/test/files-exit-hang-timeout.c +2 -2
  124. data/vendor/liburing/test/fixed-link.c +1 -1
  125. data/vendor/liburing/test/fsnotify.c +118 -0
  126. data/vendor/liburing/test/hardlink.c +1 -1
  127. data/vendor/liburing/test/helpers.c +54 -2
  128. data/vendor/liburing/test/helpers.h +4 -0
  129. data/vendor/liburing/test/io-cancel.c +3 -1
  130. data/vendor/liburing/test/io_uring_passthrough.c +39 -8
  131. data/vendor/liburing/test/io_uring_setup.c +3 -80
  132. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  133. data/vendor/liburing/test/iopoll.c +90 -4
  134. data/vendor/liburing/test/lfs-openat-write.c +7 -9
  135. data/vendor/liburing/test/lfs-openat.c +6 -8
  136. data/vendor/liburing/test/link_drain.c +31 -5
  137. data/vendor/liburing/test/madvise.c +1 -1
  138. data/vendor/liburing/test/msg-ring-flags.c +192 -0
  139. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  140. data/vendor/liburing/test/msg-ring.c +173 -13
  141. data/vendor/liburing/test/multicqes_drain.c +22 -19
  142. data/vendor/liburing/test/nvme.h +4 -3
  143. data/vendor/liburing/test/pipe-bug.c +95 -0
  144. data/vendor/liburing/test/poll-link.c +3 -3
  145. data/vendor/liburing/test/poll-many.c +41 -19
  146. data/vendor/liburing/test/poll-mshot-overflow.c +105 -2
  147. data/vendor/liburing/test/poll-race-mshot.c +292 -0
  148. data/vendor/liburing/test/poll-race.c +105 -0
  149. data/vendor/liburing/test/poll.c +244 -26
  150. data/vendor/liburing/test/pollfree.c +5 -5
  151. data/vendor/liburing/test/read-before-exit.c +20 -3
  152. data/vendor/liburing/test/read-write.c +2 -0
  153. data/vendor/liburing/test/recv-multishot.c +96 -3
  154. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  155. data/vendor/liburing/test/rename.c +1 -1
  156. data/vendor/liburing/test/ring-leak.c +0 -1
  157. data/vendor/liburing/test/ring-leak2.c +1 -1
  158. data/vendor/liburing/test/ringbuf-read.c +10 -6
  159. data/vendor/liburing/test/send-zerocopy.c +273 -103
  160. data/vendor/liburing/test/send_recv.c +7 -4
  161. data/vendor/liburing/test/sendmsg_fs_cve.c +2 -2
  162. data/vendor/liburing/test/single-issuer.c +7 -9
  163. data/vendor/liburing/test/skip-cqe.c +3 -4
  164. data/vendor/liburing/test/socket.c +0 -1
  165. data/vendor/liburing/test/sq-poll-dup.c +10 -3
  166. data/vendor/liburing/test/sq-poll-kthread.c +1 -1
  167. data/vendor/liburing/test/sq-poll-share.c +3 -2
  168. data/vendor/liburing/test/sqpoll-cancel-hang.c +17 -6
  169. data/vendor/liburing/test/sqpoll-disable-exit.c +4 -4
  170. data/vendor/liburing/test/symlink.c +2 -1
  171. data/vendor/liburing/test/test.h +2 -1
  172. data/vendor/liburing/test/timeout-new.c +11 -7
  173. data/vendor/liburing/test/timeout.c +1 -2
  174. data/vendor/liburing/test/unlink.c +1 -1
  175. data/vendor/liburing/test/version.c +25 -0
  176. data/vendor/liburing/test/wakeup-hang.c +1 -1
  177. data/vendor/liburing/test/xattr.c +8 -4
  178. metadata +42 -6
  179. data/vendor/liburing/debian/compat +0 -1
  180. data/vendor/liburing/debian/liburing1-udeb.install +0 -1
  181. data/vendor/liburing/debian/liburing1.install +0 -1
  182. data/vendor/liburing/debian/liburing1.symbols +0 -32
@@ -11,16 +11,27 @@
11
11
  #include <signal.h>
12
12
  #include <poll.h>
13
13
  #include <sys/wait.h>
14
+ #include <assert.h>
14
15
 
16
+ #include "helpers.h"
15
17
  #include "liburing.h"
16
18
 
17
- static void sig_alrm(int sig)
19
+ static void do_setsockopt(int fd, int level, int optname, int val)
18
20
  {
19
- fprintf(stderr, "Timed out!\n");
20
- exit(1);
21
+ if (setsockopt(fd, level, optname, &val, sizeof(val)))
22
+ t_error(1, errno, "setsockopt %d.%d: %d", level, optname, val);
21
23
  }
22
24
 
23
- int main(int argc, char *argv[])
25
+ static bool check_cq_empty(struct io_uring *ring)
26
+ {
27
+ struct io_uring_cqe *cqe = NULL;
28
+ int ret;
29
+
30
+ ret = io_uring_peek_cqe(ring, &cqe); /* nothing should be there */
31
+ return ret == -EAGAIN;
32
+ }
33
+
34
+ static int test_basic(void)
24
35
  {
25
36
  struct io_uring_cqe *cqe;
26
37
  struct io_uring_sqe *sqe;
@@ -29,34 +40,22 @@ int main(int argc, char *argv[])
29
40
  pid_t p;
30
41
  int ret;
31
42
 
32
- if (argc > 1)
33
- return 0;
34
-
35
43
  if (pipe(pipe1) != 0) {
36
44
  perror("pipe");
37
45
  return 1;
38
46
  }
39
47
 
40
48
  p = fork();
41
- switch (p) {
42
- case -1:
49
+ if (p == -1) {
43
50
  perror("fork");
44
51
  exit(2);
45
- case 0: {
46
- struct sigaction act;
47
-
52
+ } else if (p == 0) {
48
53
  ret = io_uring_queue_init(1, &ring, 0);
49
54
  if (ret) {
50
55
  fprintf(stderr, "child: ring setup failed: %d\n", ret);
51
56
  return 1;
52
57
  }
53
58
 
54
- memset(&act, 0, sizeof(act));
55
- act.sa_handler = sig_alrm;
56
- act.sa_flags = SA_RESTART;
57
- sigaction(SIGALRM, &act, NULL);
58
- alarm(1);
59
-
60
59
  sqe = io_uring_get_sqe(&ring);
61
60
  if (!sqe) {
62
61
  fprintf(stderr, "get sqe failed\n");
@@ -92,18 +91,237 @@ int main(int argc, char *argv[])
92
91
  (long) cqe->res);
93
92
  return 1;
94
93
  }
94
+
95
+ io_uring_queue_exit(&ring);
95
96
  exit(0);
96
- }
97
- default:
98
- do {
99
- errno = 0;
100
- ret = write(pipe1[1], "foo", 3);
101
- } while (ret == -1 && errno == EINTR);
97
+ }
98
+
99
+ do {
100
+ errno = 0;
101
+ ret = write(pipe1[1], "foo", 3);
102
+ } while (ret == -1 && errno == EINTR);
103
+
104
+ if (ret != 3) {
105
+ fprintf(stderr, "parent: bad write return %d\n", ret);
106
+ return 1;
107
+ }
108
+ close(pipe1[0]);
109
+ close(pipe1[1]);
110
+ return 0;
111
+ }
112
+
113
+ static int test_missing_events(void)
114
+ {
115
+ struct io_uring_cqe *cqe;
116
+ struct io_uring_sqe *sqe;
117
+ struct io_uring ring;
118
+ int i, ret, sp[2];
119
+ char buf[2] = {};
120
+ int res_mask = 0;
121
+
122
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
123
+ IORING_SETUP_DEFER_TASKRUN);
124
+ if (ret) {
125
+ fprintf(stderr, "ring setup failed: %d\n", ret);
126
+ return 1;
127
+ }
102
128
 
103
- if (ret != 3) {
104
- fprintf(stderr, "parent: bad write return %d\n", ret);
129
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) {
130
+ perror("Failed to create Unix-domain socket pair\n");
131
+ return 1;
132
+ }
133
+ do_setsockopt(sp[0], SOL_SOCKET, SO_SNDBUF, 1);
134
+ ret = send(sp[0], buf, sizeof(buf), 0);
135
+ if (ret != sizeof(buf)) {
136
+ perror("send failed\n");
137
+ return 1;
138
+ }
139
+
140
+ sqe = io_uring_get_sqe(&ring);
141
+ io_uring_prep_poll_multishot(sqe, sp[0], POLLIN|POLLOUT);
142
+ ret = io_uring_submit(&ring);
143
+ if (ret != 1) {
144
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
145
+ return 1;
146
+ }
147
+
148
+ /* trigger EPOLLIN */
149
+ ret = send(sp[1], buf, sizeof(buf), 0);
150
+ if (ret != sizeof(buf)) {
151
+ fprintf(stderr, "send sp[1] failed %i %i\n", ret, errno);
152
+ return 1;
153
+ }
154
+
155
+ /* trigger EPOLLOUT */
156
+ ret = recv(sp[1], buf, sizeof(buf), 0);
157
+ if (ret != sizeof(buf)) {
158
+ perror("recv failed\n");
159
+ return 1;
160
+ }
161
+
162
+ for (i = 0; ; i++) {
163
+ if (i == 0)
164
+ ret = io_uring_wait_cqe(&ring, &cqe);
165
+ else
166
+ ret = io_uring_peek_cqe(&ring, &cqe);
167
+
168
+ if (i != 0 && ret == -EAGAIN) {
169
+ break;
170
+ }
171
+ if (ret) {
172
+ fprintf(stderr, "wait completion %d, %i\n", ret, i);
105
173
  return 1;
106
174
  }
175
+ res_mask |= cqe->res;
176
+ io_uring_cqe_seen(&ring, cqe);
177
+ }
178
+
179
+ if ((res_mask & (POLLIN|POLLOUT)) != (POLLIN|POLLOUT)) {
180
+ fprintf(stderr, "missing poll events %i\n", res_mask);
181
+ return 1;
182
+ }
183
+ io_uring_queue_exit(&ring);
184
+ close(sp[0]);
185
+ close(sp[1]);
186
+ return 0;
187
+ }
188
+
189
+ #define NR_SQES 2048
190
+
191
+ static int test_self_poll(void)
192
+ {
193
+ struct io_uring_cqe *cqe;
194
+ struct io_uring_sqe *sqe;
195
+ struct io_uring ring;
196
+ int ret, i, j;
197
+
198
+ ret = io_uring_queue_init(NR_SQES, &ring, 0);
199
+ if (ret) {
200
+ fprintf(stderr, "ring setup failed: %d\n", ret);
201
+ return T_EXIT_FAIL;
202
+ }
203
+
204
+ for (j = 0; j < 32; j++) {
205
+ for (i = 0; i < NR_SQES; i++) {
206
+ sqe = io_uring_get_sqe(&ring);
207
+ io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
208
+ }
209
+
210
+ ret = io_uring_submit(&ring);
211
+ assert(ret == NR_SQES);
212
+ }
213
+
214
+ sqe = io_uring_get_sqe(&ring);
215
+ io_uring_prep_nop(sqe);
216
+ ret = io_uring_submit(&ring);
217
+ assert(ret == 1);
218
+
219
+ ret = io_uring_wait_cqe(&ring, &cqe);
220
+ io_uring_cqe_seen(&ring, cqe);
221
+
222
+ io_uring_queue_exit(&ring);
223
+ return T_EXIT_PASS;
224
+ }
225
+
226
+ static int test_disabled_ring_lazy_polling(int early_poll)
227
+ {
228
+ struct io_uring_cqe *cqe;
229
+ struct io_uring_sqe *sqe;
230
+ struct io_uring ring, ring2;
231
+ unsigned head;
232
+ int ret, i = 0;
233
+
234
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
235
+ IORING_SETUP_DEFER_TASKRUN |
236
+ IORING_SETUP_R_DISABLED);
237
+ if (ret) {
238
+ fprintf(stderr, "ring setup failed: %d\n", ret);
239
+ return 1;
240
+ }
241
+ ret = io_uring_queue_init(8, &ring2, 0);
242
+ if (ret) {
243
+ fprintf(stderr, "ring2 setup failed: %d\n", ret);
244
+ return 1;
245
+ }
246
+
247
+ if (early_poll) {
248
+ /* start polling disabled DEFER_TASKRUN ring */
249
+ sqe = io_uring_get_sqe(&ring2);
250
+ io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
251
+ ret = io_uring_submit(&ring2);
252
+ assert(ret == 1);
253
+ assert(check_cq_empty(&ring2));
254
+ }
255
+
256
+ /* enable rings, which should also activate pollwq */
257
+ ret = io_uring_enable_rings(&ring);
258
+ assert(ret >= 0);
259
+
260
+ if (!early_poll) {
261
+ /* start polling enabled DEFER_TASKRUN ring */
262
+ sqe = io_uring_get_sqe(&ring2);
263
+ io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
264
+ ret = io_uring_submit(&ring2);
265
+ assert(ret == 1);
266
+ assert(check_cq_empty(&ring2));
267
+ }
268
+
269
+ sqe = io_uring_get_sqe(&ring);
270
+ io_uring_prep_nop(sqe);
271
+ ret = io_uring_submit(&ring);
272
+ assert(ret == 1);
273
+
274
+ io_uring_for_each_cqe(&ring2, head, cqe) {
275
+ i++;
276
+ }
277
+ if (i != 1) {
278
+ fprintf(stderr, "fail, polling stuck\n");
279
+ return 1;
280
+ }
281
+ io_uring_queue_exit(&ring);
282
+ io_uring_queue_exit(&ring2);
283
+ return 0;
284
+ }
285
+
286
+ int main(int argc, char *argv[])
287
+ {
288
+ int ret;
289
+
290
+ if (argc > 1)
107
291
  return 0;
292
+
293
+ ret = test_basic();
294
+ if (ret) {
295
+ fprintf(stderr, "test_basic() failed %i\n", ret);
296
+ return T_EXIT_FAIL;
108
297
  }
298
+
299
+
300
+ if (t_probe_defer_taskrun()) {
301
+ ret = test_missing_events();
302
+ if (ret) {
303
+ fprintf(stderr, "test_missing_events() failed %i\n", ret);
304
+ return T_EXIT_FAIL;
305
+ }
306
+
307
+ ret = test_disabled_ring_lazy_polling(false);
308
+ if (ret) {
309
+ fprintf(stderr, "test_disabled_ring_lazy_polling(false) failed %i\n", ret);
310
+ return T_EXIT_FAIL;
311
+ }
312
+
313
+ ret = test_disabled_ring_lazy_polling(true);
314
+ if (ret) {
315
+ fprintf(stderr, "test_disabled_ring_lazy_polling(true) failed %i\n", ret);
316
+ return T_EXIT_FAIL;
317
+ }
318
+ }
319
+
320
+ ret = test_self_poll();
321
+ if (ret) {
322
+ fprintf(stderr, "test_self_poll failed\n");
323
+ return T_EXIT_FAIL;
324
+ }
325
+
326
+ return 0;
109
327
  }
@@ -252,7 +252,7 @@ static void kill_and_wait(int pid, int* status)
252
252
  }
253
253
  }
254
254
 
255
- static void setup_test()
255
+ static void setup_test(void)
256
256
  {
257
257
  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
258
258
  setpgrp();
@@ -342,7 +342,7 @@ static void loop(void)
342
342
  #define __NR_io_uring_enter 426
343
343
  #endif
344
344
 
345
- uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0};
345
+ static uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0};
346
346
 
347
347
  void execute_call(int call)
348
348
  {
@@ -403,13 +403,13 @@ int main(int argc, char *argv[])
403
403
  if (argc > 1)
404
404
  return 0;
405
405
 
406
- ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
406
+ ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
407
407
  if (ret == MAP_FAILED)
408
408
  return 0;
409
- ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
409
+ ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
410
410
  if (ret == MAP_FAILED)
411
411
  return 0;
412
- ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
412
+ ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
413
413
  if (ret == MAP_FAILED)
414
414
  return 0;
415
415
  loop();
@@ -14,6 +14,8 @@
14
14
  #include "liburing.h"
15
15
  #include "helpers.h"
16
16
 
17
+ static int no_iopoll;
18
+
17
19
  struct data {
18
20
  struct io_uring *ring;
19
21
  int timer_fd1;
@@ -22,7 +24,7 @@ struct data {
22
24
  uint64_t buf2;
23
25
  };
24
26
 
25
- void *submit(void *data)
27
+ static void *submit(void *data)
26
28
  {
27
29
  struct io_uring_sqe *sqe;
28
30
  struct data *d = data;
@@ -35,8 +37,21 @@ void *submit(void *data)
35
37
  io_uring_prep_read(sqe, d->timer_fd2, &d->buf2, sizeof(d->buf2), 0);
36
38
 
37
39
  ret = io_uring_submit(d->ring);
38
- if (ret != 2)
40
+ if (ret != 2) {
41
+ struct io_uring_cqe *cqe;
42
+
43
+ /*
44
+ * Kernels without submit-all-on-error behavior will
45
+ * fail submitting all, check if that's the case and
46
+ * don't error
47
+ */
48
+ ret = io_uring_peek_cqe(d->ring, &cqe);
49
+ if (!ret && cqe->res == -EOPNOTSUPP) {
50
+ no_iopoll = 1;
51
+ return NULL;
52
+ }
39
53
  return (void *) (uintptr_t) 1;
54
+ }
40
55
 
41
56
  /* Exit suddenly. */
42
57
  return NULL;
@@ -95,9 +110,11 @@ int main(int argc, char *argv[])
95
110
  for (i = 0; i < 1000; i++) {
96
111
  ret = test(IORING_SETUP_IOPOLL);
97
112
  if (ret) {
98
- fprintf(stderr, "Test IOPOLL failed\n");
113
+ fprintf(stderr, "Test IOPOLL failed loop %d\n", ret);
99
114
  return ret;
100
115
  }
116
+ if (no_iopoll)
117
+ break;
101
118
  }
102
119
 
103
120
  for (i = 0; i < 100; i++) {
@@ -76,6 +76,8 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
76
76
 
77
77
  fd = open(file, open_flags);
78
78
  if (fd < 0) {
79
+ if (errno == EINVAL)
80
+ return 0;
79
81
  perror("file open");
80
82
  goto err;
81
83
  }
@@ -9,6 +9,7 @@
9
9
  #include <sys/types.h>
10
10
  #include <sys/socket.h>
11
11
  #include <pthread.h>
12
+ #include <assert.h>
12
13
 
13
14
  #include "liburing.h"
14
15
  #include "helpers.h"
@@ -264,11 +265,19 @@ static int test(struct args *args)
264
265
 
265
266
  bool const is_last = i == recv_cqes - 1;
266
267
 
268
+ /*
269
+ * Older kernels could terminate multishot early due to overflow,
270
+ * but later ones will not. So discriminate based on the MORE flag.
271
+ */
272
+ bool const early_last = args->early_error == ERROR_EARLY_OVERFLOW &&
273
+ !args->wait_each &&
274
+ i == N_CQE_OVERFLOW &&
275
+ !(cqe->flags & IORING_CQE_F_MORE);
276
+
267
277
  bool const should_be_last =
268
278
  (cqe->res <= 0) ||
269
279
  (args->stream && is_last) ||
270
- (args->early_error == ERROR_EARLY_OVERFLOW &&
271
- !args->wait_each && i == N_CQE_OVERFLOW);
280
+ early_last;
272
281
  int *this_recv;
273
282
  int orig_payload_size = cqe->res;
274
283
 
@@ -328,7 +337,7 @@ static int test(struct args *args)
328
337
  case ERROR_EARLY_LAST:
329
338
  fprintf(stderr, "bad error_early\n");
330
339
  goto cleanup;
331
- };
340
+ }
332
341
 
333
342
  if (cqe->res <= 0 && cqe->flags & IORING_CQE_F_BUFFER) {
334
343
  fprintf(stderr, "final BUFFER flag set\n");
@@ -461,6 +470,84 @@ cleanup:
461
470
  return ret;
462
471
  }
463
472
 
473
+ static int test_enobuf(void)
474
+ {
475
+ struct io_uring ring;
476
+ struct io_uring_sqe *sqe;
477
+ struct io_uring_cqe *cqes[16];
478
+ char buffs[256];
479
+ int ret, i, fds[2];
480
+
481
+ if (t_create_ring(8, &ring, 0) != T_SETUP_OK) {
482
+ fprintf(stderr, "ring create\n");
483
+ return -1;
484
+ }
485
+
486
+ ret = t_create_socket_pair(fds, false);
487
+ if (ret) {
488
+ fprintf(stderr, "t_create_socket_pair\n");
489
+ return ret;
490
+ }
491
+
492
+ sqe = io_uring_get_sqe(&ring);
493
+ assert(sqe);
494
+ /* deliberately only 2 provided buffers */
495
+ io_uring_prep_provide_buffers(sqe, &buffs[0], 1, 2, 0, 0);
496
+ io_uring_sqe_set_data64(sqe, 0);
497
+
498
+ sqe = io_uring_get_sqe(&ring);
499
+ assert(sqe);
500
+ io_uring_prep_recv_multishot(sqe, fds[0], NULL, 0, 0);
501
+ io_uring_sqe_set_data64(sqe, 1);
502
+ sqe->buf_group = 0;
503
+ sqe->flags |= IOSQE_BUFFER_SELECT;
504
+
505
+ ret = io_uring_submit(&ring);
506
+ if (ret != 2) {
507
+ fprintf(stderr, "bad submit %d\n", ret);
508
+ return -1;
509
+ }
510
+ for (i = 0; i < 3; i++) {
511
+ do {
512
+ ret = write(fds[1], "?", 1);
513
+ } while (ret == -1 && errno == EINTR);
514
+ }
515
+
516
+ ret = io_uring_wait_cqes(&ring, &cqes[0], 4, NULL, NULL);
517
+ if (ret) {
518
+ fprintf(stderr, "wait cqes\n");
519
+ return ret;
520
+ }
521
+
522
+ ret = io_uring_peek_batch_cqe(&ring, &cqes[0], 4);
523
+ if (ret != 4) {
524
+ fprintf(stderr, "peek batch cqes\n");
525
+ return -1;
526
+ }
527
+
528
+ /* provide buffers */
529
+ assert(cqes[0]->user_data == 0);
530
+ assert(cqes[0]->res == 0);
531
+
532
+ /* valid recv */
533
+ assert(cqes[1]->user_data == 1);
534
+ assert(cqes[2]->user_data == 1);
535
+ assert(cqes[1]->res == 1);
536
+ assert(cqes[2]->res == 1);
537
+ assert(cqes[1]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE));
538
+ assert(cqes[2]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE));
539
+
540
+ /* missing buffer */
541
+ assert(cqes[3]->user_data == 1);
542
+ assert(cqes[3]->res == -ENOBUFS);
543
+ assert(!(cqes[3]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE)));
544
+
545
+ close(fds[0]);
546
+ close(fds[1]);
547
+ io_uring_queue_exit(&ring);
548
+ return 0;
549
+ }
550
+
464
551
  int main(int argc, char *argv[])
465
552
  {
466
553
  int ret;
@@ -501,5 +588,11 @@ int main(int argc, char *argv[])
501
588
  }
502
589
  }
503
590
 
591
+ ret = test_enobuf();
592
+ if (ret) {
593
+ fprintf(stderr, "test_enobuf() failed: %d\n", ret);
594
+ return T_EXIT_FAIL;
595
+ }
596
+
504
597
  return T_EXIT_PASS;
505
598
  }
@@ -0,0 +1,90 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Test io_uring_register with a registered ring (IORING_REGISTER_USE_REGISTERED_RING)
4
+ *
5
+ */
6
+ #include <stdio.h>
7
+
8
+ #include "helpers.h"
9
+
10
+ int main(int argc, char *argv[])
11
+ {
12
+ struct io_uring ring;
13
+ unsigned values[2];
14
+ int ret;
15
+
16
+ if (argc > 1)
17
+ return T_EXIT_SKIP;
18
+
19
+ ret = io_uring_queue_init(8, &ring, 0);
20
+ if (ret) {
21
+ fprintf(stderr, "ring setup failed\n");
22
+ return T_EXIT_FAIL;
23
+ }
24
+
25
+ if (!(ring.features & IORING_FEAT_REG_REG_RING)) {
26
+ fprintf(stderr, "IORING_FEAT_REG_REG_RING not available in kernel\n");
27
+ io_uring_queue_exit(&ring);
28
+ return T_EXIT_SKIP;
29
+ }
30
+
31
+ ret = io_uring_close_ring_fd(&ring);
32
+ if (ret != -EINVAL) {
33
+ fprintf(stderr, "closing ring fd should EINVAL before register\n");
34
+ goto err;
35
+ }
36
+
37
+ ret = io_uring_unregister_ring_fd(&ring);
38
+ if (ret != -EINVAL) {
39
+ fprintf(stderr, "unregistering not-registered ring fd should fail\n");
40
+ goto err;
41
+ }
42
+
43
+ ret = io_uring_register_ring_fd(&ring);
44
+ if (ret != 1) {
45
+ fprintf(stderr, "registering ring fd failed\n");
46
+ goto err;
47
+ }
48
+
49
+ ret = io_uring_register_ring_fd(&ring);
50
+ if (ret != -EEXIST) {
51
+ fprintf(stderr, "registering already-registered ring fd should fail\n");
52
+ goto err;
53
+ }
54
+
55
+ /* Test a simple io_uring_register operation expected to work.
56
+ * io_uring_register_iowq_max_workers is arbitrary.
57
+ */
58
+ values[0] = values[1] = 0;
59
+ ret = io_uring_register_iowq_max_workers(&ring, values);
60
+ if (ret || (values[0] == 0 && values[1] == 0)) {
61
+ fprintf(stderr, "io_uring_register operation failed before closing ring fd\n");
62
+ goto err;
63
+ }
64
+
65
+ ret = io_uring_close_ring_fd(&ring);
66
+ if (ret != 1) {
67
+ fprintf(stderr, "closing ring fd failed\n");
68
+ goto err;
69
+ }
70
+
71
+ values[0] = values[1] = 0;
72
+ ret = io_uring_register_iowq_max_workers(&ring, values);
73
+ if (ret || (values[0] == 0 && values[1] == 0)) {
74
+ fprintf(stderr, "io_uring_register operation failed after closing ring fd\n");
75
+ goto err;
76
+ }
77
+
78
+ ret = io_uring_close_ring_fd(&ring);
79
+ if (ret != -EBADF) {
80
+ fprintf(stderr, "closing already-closed ring fd should fail\n");
81
+ goto err;
82
+ }
83
+
84
+ io_uring_queue_exit(&ring);
85
+ return T_EXIT_PASS;
86
+
87
+ err:
88
+ io_uring_queue_exit(&ring);
89
+ return T_EXIT_FAIL;
90
+ }
@@ -1,6 +1,6 @@
1
1
  /* SPDX-License-Identifier: MIT */
2
2
  /*
3
- * Description: run various nop tests
3
+ * Description: run various rename tests
4
4
  *
5
5
  */
6
6
  #include <errno.h>
@@ -241,7 +241,6 @@ int main(int argc, char *argv[])
241
241
  update);
242
242
  return 1;
243
243
  }
244
- break;
245
244
  }
246
245
 
247
246
  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) {
@@ -46,7 +46,7 @@ static struct io_uring *client_ring;
46
46
 
47
47
  static int client_eventfd = -1;
48
48
 
49
- int setup_io_uring(struct io_uring *ring)
49
+ static int setup_io_uring(struct io_uring *ring)
50
50
  {
51
51
  struct io_uring_params p = { };
52
52
  int ret;