uringmachine 0.1

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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/workflows/test.yml +35 -0
  4. data/.gitignore +59 -0
  5. data/.gitmodules +3 -0
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +11 -0
  10. data/Rakefile +39 -0
  11. data/TODO.md +0 -0
  12. data/examples/echo_server.rb +52 -0
  13. data/examples/event_loop.rb +69 -0
  14. data/examples/fibers.rb +105 -0
  15. data/examples/http_server.rb +56 -0
  16. data/examples/http_server_multishot.rb +57 -0
  17. data/examples/http_server_simpler.rb +34 -0
  18. data/ext/um/extconf.rb +71 -0
  19. data/ext/um/iou.h +101 -0
  20. data/ext/um/op_ctx.c +138 -0
  21. data/ext/um/ring.c +755 -0
  22. data/ext/um/um.c +267 -0
  23. data/ext/um/um.h +97 -0
  24. data/ext/um/um_class.c +175 -0
  25. data/ext/um/um_ext.c +11 -0
  26. data/ext/um/um_op.c +87 -0
  27. data/ext/um/um_utils.c +23 -0
  28. data/lib/uringmachine/version.rb +3 -0
  29. data/lib/uringmachine.rb +8 -0
  30. data/test/helper.rb +70 -0
  31. data/test/test_iou.rb +876 -0
  32. data/test/test_um.rb +168 -0
  33. data/uringmachine.gemspec +27 -0
  34. data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
  35. data/vendor/liburing/.github/pull_request_template.md +86 -0
  36. data/vendor/liburing/.github/workflows/build.yml +137 -0
  37. data/vendor/liburing/.github/workflows/codespell.yml +25 -0
  38. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  39. data/vendor/liburing/.gitignore +41 -0
  40. data/vendor/liburing/CHANGELOG +111 -0
  41. data/vendor/liburing/CITATION.cff +11 -0
  42. data/vendor/liburing/COPYING +502 -0
  43. data/vendor/liburing/COPYING.GPL +339 -0
  44. data/vendor/liburing/LICENSE +20 -0
  45. data/vendor/liburing/Makefile +96 -0
  46. data/vendor/liburing/Makefile.common +7 -0
  47. data/vendor/liburing/Makefile.quiet +11 -0
  48. data/vendor/liburing/README +106 -0
  49. data/vendor/liburing/SECURITY.md +6 -0
  50. data/vendor/liburing/configure +624 -0
  51. data/vendor/liburing/debian/README.Debian +7 -0
  52. data/vendor/liburing/debian/changelog +38 -0
  53. data/vendor/liburing/debian/control +39 -0
  54. data/vendor/liburing/debian/copyright +49 -0
  55. data/vendor/liburing/debian/liburing-dev.install +4 -0
  56. data/vendor/liburing/debian/liburing-dev.manpages +5 -0
  57. data/vendor/liburing/debian/liburing2.install +1 -0
  58. data/vendor/liburing/debian/liburing2.symbols +56 -0
  59. data/vendor/liburing/debian/patches/series +1 -0
  60. data/vendor/liburing/debian/rules +29 -0
  61. data/vendor/liburing/debian/source/format +1 -0
  62. data/vendor/liburing/debian/source/local-options +2 -0
  63. data/vendor/liburing/debian/source/options +1 -0
  64. data/vendor/liburing/debian/watch +3 -0
  65. data/vendor/liburing/examples/Makefile +53 -0
  66. data/vendor/liburing/examples/helpers.c +62 -0
  67. data/vendor/liburing/examples/helpers.h +7 -0
  68. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  69. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  70. data/vendor/liburing/examples/io_uring-test.c +112 -0
  71. data/vendor/liburing/examples/io_uring-udp.c +403 -0
  72. data/vendor/liburing/examples/link-cp.c +193 -0
  73. data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
  74. data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
  75. data/vendor/liburing/examples/poll-bench.c +101 -0
  76. data/vendor/liburing/examples/proxy.c +2461 -0
  77. data/vendor/liburing/examples/proxy.h +102 -0
  78. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  79. data/vendor/liburing/examples/send-zerocopy.c +658 -0
  80. data/vendor/liburing/examples/ucontext-cp.c +258 -0
  81. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  82. data/vendor/liburing/liburing.pc.in +12 -0
  83. data/vendor/liburing/liburing.spec +66 -0
  84. data/vendor/liburing/make-debs.sh +55 -0
  85. data/vendor/liburing/src/Makefile +129 -0
  86. data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
  87. data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
  88. data/vendor/liburing/src/arch/generic/lib.h +17 -0
  89. data/vendor/liburing/src/arch/generic/syscall.h +100 -0
  90. data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
  91. data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
  92. data/vendor/liburing/src/arch/syscall-defs.h +94 -0
  93. data/vendor/liburing/src/arch/x86/lib.h +11 -0
  94. data/vendor/liburing/src/arch/x86/syscall.h +296 -0
  95. data/vendor/liburing/src/ffi.c +15 -0
  96. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  97. data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
  98. data/vendor/liburing/src/include/liburing.h +1602 -0
  99. data/vendor/liburing/src/int_flags.h +11 -0
  100. data/vendor/liburing/src/lib.h +52 -0
  101. data/vendor/liburing/src/liburing-ffi.map +211 -0
  102. data/vendor/liburing/src/liburing.map +104 -0
  103. data/vendor/liburing/src/nolibc.c +55 -0
  104. data/vendor/liburing/src/queue.c +468 -0
  105. data/vendor/liburing/src/register.c +374 -0
  106. data/vendor/liburing/src/setup.c +689 -0
  107. data/vendor/liburing/src/setup.h +9 -0
  108. data/vendor/liburing/src/syscall.c +29 -0
  109. data/vendor/liburing/src/syscall.h +53 -0
  110. data/vendor/liburing/src/version.c +21 -0
  111. data/vendor/liburing/test/232c93d07b74.c +305 -0
  112. data/vendor/liburing/test/35fa71a030ca.c +329 -0
  113. data/vendor/liburing/test/500f9fbadef8.c +91 -0
  114. data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
  115. data/vendor/liburing/test/8a9973408177.c +107 -0
  116. data/vendor/liburing/test/917257daa0fe.c +54 -0
  117. data/vendor/liburing/test/Makefile +297 -0
  118. data/vendor/liburing/test/a0908ae19763.c +59 -0
  119. data/vendor/liburing/test/a4c0b3decb33.c +181 -0
  120. data/vendor/liburing/test/accept-link.c +255 -0
  121. data/vendor/liburing/test/accept-non-empty.c +256 -0
  122. data/vendor/liburing/test/accept-reuse.c +163 -0
  123. data/vendor/liburing/test/accept-test.c +83 -0
  124. data/vendor/liburing/test/accept.c +919 -0
  125. data/vendor/liburing/test/across-fork.c +284 -0
  126. data/vendor/liburing/test/b19062a56726.c +54 -0
  127. data/vendor/liburing/test/b5837bd5311d.c +78 -0
  128. data/vendor/liburing/test/bind-listen.c +408 -0
  129. data/vendor/liburing/test/buf-ring-nommap.c +123 -0
  130. data/vendor/liburing/test/buf-ring-put.c +83 -0
  131. data/vendor/liburing/test/buf-ring.c +473 -0
  132. data/vendor/liburing/test/ce593a6c480a.c +139 -0
  133. data/vendor/liburing/test/close-opath.c +123 -0
  134. data/vendor/liburing/test/config +14 -0
  135. data/vendor/liburing/test/connect-rep.c +204 -0
  136. data/vendor/liburing/test/connect.c +442 -0
  137. data/vendor/liburing/test/coredump.c +60 -0
  138. data/vendor/liburing/test/cq-full.c +97 -0
  139. data/vendor/liburing/test/cq-overflow.c +530 -0
  140. data/vendor/liburing/test/cq-peek-batch.c +103 -0
  141. data/vendor/liburing/test/cq-ready.c +95 -0
  142. data/vendor/liburing/test/cq-size.c +65 -0
  143. data/vendor/liburing/test/d4ae271dfaae.c +96 -0
  144. data/vendor/liburing/test/d77a67ed5f27.c +65 -0
  145. data/vendor/liburing/test/defer-taskrun.c +391 -0
  146. data/vendor/liburing/test/defer-tw-timeout.c +173 -0
  147. data/vendor/liburing/test/defer.c +319 -0
  148. data/vendor/liburing/test/double-poll-crash.c +195 -0
  149. data/vendor/liburing/test/drop-submit.c +94 -0
  150. data/vendor/liburing/test/eeed8b54e0df.c +120 -0
  151. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  152. data/vendor/liburing/test/eploop.c +74 -0
  153. data/vendor/liburing/test/eventfd-disable.c +179 -0
  154. data/vendor/liburing/test/eventfd-reg.c +77 -0
  155. data/vendor/liburing/test/eventfd-ring.c +98 -0
  156. data/vendor/liburing/test/eventfd.c +113 -0
  157. data/vendor/liburing/test/evloop.c +73 -0
  158. data/vendor/liburing/test/exec-target.c +6 -0
  159. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  160. data/vendor/liburing/test/fadvise.c +202 -0
  161. data/vendor/liburing/test/fallocate.c +265 -0
  162. data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
  163. data/vendor/liburing/test/fd-install.c +500 -0
  164. data/vendor/liburing/test/fd-pass.c +237 -0
  165. data/vendor/liburing/test/fdinfo.c +419 -0
  166. data/vendor/liburing/test/file-register.c +1189 -0
  167. data/vendor/liburing/test/file-update.c +231 -0
  168. data/vendor/liburing/test/file-verify.c +654 -0
  169. data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
  170. data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
  171. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  172. data/vendor/liburing/test/fixed-buf-merge.c +101 -0
  173. data/vendor/liburing/test/fixed-hugepage.c +411 -0
  174. data/vendor/liburing/test/fixed-link.c +90 -0
  175. data/vendor/liburing/test/fixed-reuse.c +160 -0
  176. data/vendor/liburing/test/fpos.c +255 -0
  177. data/vendor/liburing/test/fsnotify.c +118 -0
  178. data/vendor/liburing/test/fsync.c +224 -0
  179. data/vendor/liburing/test/futex.c +571 -0
  180. data/vendor/liburing/test/hardlink.c +170 -0
  181. data/vendor/liburing/test/helpers.c +318 -0
  182. data/vendor/liburing/test/helpers.h +108 -0
  183. data/vendor/liburing/test/ignore-single-mmap.c +48 -0
  184. data/vendor/liburing/test/init-mem.c +164 -0
  185. data/vendor/liburing/test/io-cancel.c +561 -0
  186. data/vendor/liburing/test/io_uring_enter.c +264 -0
  187. data/vendor/liburing/test/io_uring_passthrough.c +482 -0
  188. data/vendor/liburing/test/io_uring_register.c +503 -0
  189. data/vendor/liburing/test/io_uring_setup.c +110 -0
  190. data/vendor/liburing/test/iopoll-leak.c +85 -0
  191. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  192. data/vendor/liburing/test/iopoll.c +465 -0
  193. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  194. data/vendor/liburing/test/lfs-openat.c +273 -0
  195. data/vendor/liburing/test/link-timeout.c +1108 -0
  196. data/vendor/liburing/test/link.c +497 -0
  197. data/vendor/liburing/test/link_drain.c +255 -0
  198. data/vendor/liburing/test/madvise.c +195 -0
  199. data/vendor/liburing/test/min-timeout-wait.c +354 -0
  200. data/vendor/liburing/test/min-timeout.c +233 -0
  201. data/vendor/liburing/test/mkdir.c +112 -0
  202. data/vendor/liburing/test/msg-ring-fd.c +331 -0
  203. data/vendor/liburing/test/msg-ring-flags.c +212 -0
  204. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  205. data/vendor/liburing/test/msg-ring.c +467 -0
  206. data/vendor/liburing/test/multicqes_drain.c +429 -0
  207. data/vendor/liburing/test/napi-test.c +215 -0
  208. data/vendor/liburing/test/napi-test.sh +48 -0
  209. data/vendor/liburing/test/no-mmap-inval.c +42 -0
  210. data/vendor/liburing/test/nolibc.c +62 -0
  211. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  212. data/vendor/liburing/test/nop.c +177 -0
  213. data/vendor/liburing/test/nvme.h +169 -0
  214. data/vendor/liburing/test/ooo-file-unreg.c +82 -0
  215. data/vendor/liburing/test/open-close.c +261 -0
  216. data/vendor/liburing/test/open-direct-link.c +188 -0
  217. data/vendor/liburing/test/open-direct-pick.c +180 -0
  218. data/vendor/liburing/test/openat2.c +312 -0
  219. data/vendor/liburing/test/personality.c +204 -0
  220. data/vendor/liburing/test/pipe-bug.c +95 -0
  221. data/vendor/liburing/test/pipe-eof.c +83 -0
  222. data/vendor/liburing/test/pipe-reuse.c +105 -0
  223. data/vendor/liburing/test/poll-cancel-all.c +496 -0
  224. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  225. data/vendor/liburing/test/poll-cancel.c +228 -0
  226. data/vendor/liburing/test/poll-link.c +221 -0
  227. data/vendor/liburing/test/poll-many.c +230 -0
  228. data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
  229. data/vendor/liburing/test/poll-mshot-update.c +323 -0
  230. data/vendor/liburing/test/poll-race-mshot.c +276 -0
  231. data/vendor/liburing/test/poll-race.c +105 -0
  232. data/vendor/liburing/test/poll-ring.c +48 -0
  233. data/vendor/liburing/test/poll-v-poll.c +353 -0
  234. data/vendor/liburing/test/poll.c +327 -0
  235. data/vendor/liburing/test/probe.c +135 -0
  236. data/vendor/liburing/test/read-before-exit.c +129 -0
  237. data/vendor/liburing/test/read-mshot-empty.c +153 -0
  238. data/vendor/liburing/test/read-mshot.c +404 -0
  239. data/vendor/liburing/test/read-write.c +1013 -0
  240. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  241. data/vendor/liburing/test/recv-msgall.c +263 -0
  242. data/vendor/liburing/test/recv-multishot.c +602 -0
  243. data/vendor/liburing/test/recvsend_bundle.c +691 -0
  244. data/vendor/liburing/test/reg-fd-only.c +131 -0
  245. data/vendor/liburing/test/reg-hint.c +56 -0
  246. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  247. data/vendor/liburing/test/regbuf-merge.c +91 -0
  248. data/vendor/liburing/test/register-restrictions.c +633 -0
  249. data/vendor/liburing/test/rename.c +132 -0
  250. data/vendor/liburing/test/ring-leak.c +283 -0
  251. data/vendor/liburing/test/ring-leak2.c +249 -0
  252. data/vendor/liburing/test/ringbuf-read.c +196 -0
  253. data/vendor/liburing/test/ringbuf-status.c +242 -0
  254. data/vendor/liburing/test/rsrc_tags.c +461 -0
  255. data/vendor/liburing/test/runtests-loop.sh +16 -0
  256. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  257. data/vendor/liburing/test/runtests.sh +168 -0
  258. data/vendor/liburing/test/rw_merge_test.c +98 -0
  259. data/vendor/liburing/test/self.c +91 -0
  260. data/vendor/liburing/test/send-zerocopy.c +971 -0
  261. data/vendor/liburing/test/send_recv.c +412 -0
  262. data/vendor/liburing/test/send_recvmsg.c +444 -0
  263. data/vendor/liburing/test/shared-wq.c +84 -0
  264. data/vendor/liburing/test/short-read.c +75 -0
  265. data/vendor/liburing/test/shutdown.c +165 -0
  266. data/vendor/liburing/test/sigfd-deadlock.c +88 -0
  267. data/vendor/liburing/test/single-issuer.c +169 -0
  268. data/vendor/liburing/test/skip-cqe.c +428 -0
  269. data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
  270. data/vendor/liburing/test/socket-io-cmd.c +237 -0
  271. data/vendor/liburing/test/socket-rw-eagain.c +149 -0
  272. data/vendor/liburing/test/socket-rw-offset.c +149 -0
  273. data/vendor/liburing/test/socket-rw.c +137 -0
  274. data/vendor/liburing/test/socket.c +408 -0
  275. data/vendor/liburing/test/splice.c +512 -0
  276. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  277. data/vendor/liburing/test/sq-full.c +45 -0
  278. data/vendor/liburing/test/sq-poll-dup.c +211 -0
  279. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  280. data/vendor/liburing/test/sq-poll-share.c +138 -0
  281. data/vendor/liburing/test/sq-space_left.c +159 -0
  282. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  283. data/vendor/liburing/test/sqpoll-exec.c +132 -0
  284. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  285. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  286. data/vendor/liburing/test/statx.c +172 -0
  287. data/vendor/liburing/test/stdout.c +232 -0
  288. data/vendor/liburing/test/submit-and-wait.c +108 -0
  289. data/vendor/liburing/test/submit-link-fail.c +156 -0
  290. data/vendor/liburing/test/submit-reuse.c +237 -0
  291. data/vendor/liburing/test/symlink.c +117 -0
  292. data/vendor/liburing/test/sync-cancel.c +235 -0
  293. data/vendor/liburing/test/teardowns.c +58 -0
  294. data/vendor/liburing/test/test.h +36 -0
  295. data/vendor/liburing/test/thread-exit.c +143 -0
  296. data/vendor/liburing/test/timeout-new.c +256 -0
  297. data/vendor/liburing/test/timeout.c +1798 -0
  298. data/vendor/liburing/test/truncate.c +186 -0
  299. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  300. data/vendor/liburing/test/unlink.c +112 -0
  301. data/vendor/liburing/test/version.c +25 -0
  302. data/vendor/liburing/test/wait-timeout.c +287 -0
  303. data/vendor/liburing/test/waitid.c +373 -0
  304. data/vendor/liburing/test/wakeup-hang.c +162 -0
  305. data/vendor/liburing/test/wq-aff.c +146 -0
  306. data/vendor/liburing/test/xattr.c +442 -0
  307. metadata +412 -0
@@ -0,0 +1,14 @@
1
+ # Copy this to config.local, uncomment and define values
2
+ #
3
+ # NOTE: any files or devices added here will be used by tests that take
4
+ # a file or device arguments This includes tests that are destructive with
5
+ # respect to data contents. They may get erased or overwritten as part of tests.
6
+ #
7
+ # Define tests to exclude from running
8
+ # TEST_EXCLUDE=""
9
+ #
10
+ # Define raw test devices (or files) for test cases, if any
11
+ # declare -A TEST_MAP=()
12
+ #
13
+ # If no TEST_MAP entry exists for a test, use the ones given in TEST_FILES
14
+ # TEST_FILES="/dev/somedevice /data/somefile"
@@ -0,0 +1,204 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Check that repeated IORING_OP_CONNECT to a socket without a listener keeps
4
+ * yielding -ECONNREFUSED rather than -ECONNABORTED. Based on a reproducer
5
+ * from:
6
+ *
7
+ * https://github.com/axboe/liburing/issues/828
8
+ *
9
+ * and adopted to our usual test cases. Other changes made like looping,
10
+ * using different ring types, adding a memset() for reuse, etc.
11
+ *
12
+ */
13
+ #include <stdio.h>
14
+ #include <netinet/in.h>
15
+ #include <string.h>
16
+ #include <unistd.h>
17
+ #include <stdlib.h>
18
+ #include <arpa/inet.h>
19
+
20
+ #include "liburing.h"
21
+ #include "helpers.h"
22
+
23
+ static unsigned long ud;
24
+
25
+ static int init_test_server(struct sockaddr_in *serv_addr)
26
+ {
27
+ socklen_t servaddr_len = sizeof(struct sockaddr_in);
28
+ int fd;
29
+
30
+ /* Init server socket. Bind but don't listen */
31
+ fd = socket(AF_INET, SOCK_STREAM, 0);
32
+ if (fd < 0) {
33
+ perror("socket");
34
+ return -1;
35
+ }
36
+
37
+ serv_addr->sin_family = AF_INET;
38
+ serv_addr->sin_addr.s_addr = inet_addr("127.0.0.1");
39
+
40
+ if (bind(fd, (struct sockaddr *) serv_addr, servaddr_len) < 0) {
41
+ perror("bind");
42
+ return -1;
43
+ }
44
+
45
+ /*
46
+ * Get the addresses the socket is bound to because the port is chosen
47
+ * by the network stack.
48
+ */
49
+ if (getsockname(fd, (struct sockaddr *)serv_addr, &servaddr_len) < 0) {
50
+ perror("getsockname");
51
+ return -1;
52
+ }
53
+
54
+ return fd;
55
+ }
56
+
57
+ static int init_test_client(void)
58
+ {
59
+ socklen_t addr_len = sizeof(struct sockaddr_in);
60
+ struct sockaddr_in client_addr = {};
61
+ int clientfd;
62
+
63
+ clientfd = socket(AF_INET, SOCK_STREAM, 0);
64
+ if (clientfd < 0) {
65
+ perror("socket");
66
+ return -1;
67
+ }
68
+
69
+ client_addr.sin_family = AF_INET;
70
+ client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
71
+
72
+ if (bind(clientfd, (struct sockaddr *)&client_addr, addr_len) < 0) {
73
+ perror("bind");
74
+ close(clientfd);
75
+ return -1;
76
+ }
77
+
78
+ /*
79
+ * Get the addresses the socket is bound to because the port is chosen
80
+ * by the network stack.
81
+ */
82
+ if (getsockname(clientfd, (struct sockaddr *)&client_addr, &addr_len) < 0) {
83
+ perror("getsockname");
84
+ close(clientfd);
85
+ return -1;
86
+ }
87
+
88
+ return clientfd;
89
+ }
90
+
91
+ static int get_completion_and_print(struct io_uring *ring)
92
+ {
93
+ struct io_uring_cqe *cqe;
94
+ int ret, res;
95
+
96
+ ret = io_uring_wait_cqe(ring, &cqe);
97
+ if (ret < 0) {
98
+ fprintf(stderr, "wait_cqe=%d\n", ret);
99
+ return -1;
100
+ }
101
+
102
+ /* Mark this completion as seen */
103
+ res = cqe->res;
104
+ io_uring_cqe_seen(ring, cqe);
105
+ return res;
106
+ }
107
+
108
+ static int test_connect(struct io_uring *ring,
109
+ int clientfd, struct sockaddr_in *serv_addr)
110
+ {
111
+ struct sockaddr_in local_sa;
112
+ struct io_uring_sqe *sqe;
113
+ int ret;
114
+
115
+ sqe = io_uring_get_sqe(ring);
116
+ io_uring_prep_connect(sqe, clientfd, (const struct sockaddr *)serv_addr,
117
+ sizeof(struct sockaddr_in));
118
+ sqe->user_data = ++ud;
119
+
120
+ memcpy(&local_sa, serv_addr, sizeof(local_sa));
121
+
122
+ ret = io_uring_submit_and_wait(ring, 1);
123
+ if (ret != 1) {
124
+ fprintf(stderr, "submit=%d\n", ret);
125
+ return T_EXIT_FAIL;
126
+ }
127
+
128
+ /* check for reuse at the same time */
129
+ memset(&local_sa, 0xff, sizeof(local_sa));
130
+
131
+ ret = get_completion_and_print(ring);
132
+ if (ret != -ECONNREFUSED) {
133
+ fprintf(stderr, "Connect got %d\n", ret);
134
+ return T_EXIT_FAIL;
135
+ }
136
+ return T_EXIT_PASS;
137
+ }
138
+
139
+ static int test(int flags)
140
+ {
141
+ struct io_uring_params params = { .flags = flags, };
142
+ struct sockaddr_in serv_addr = {};
143
+ struct io_uring ring;
144
+ int ret, clientfd, s_fd, i;
145
+
146
+ if (flags & IORING_SETUP_SQPOLL)
147
+ params.sq_thread_idle = 50;
148
+
149
+ ret = io_uring_queue_init_params(8, &ring, &params);
150
+ if (ret < 0) {
151
+ fprintf(stderr, "Queue init: %d\n", ret);
152
+ return T_EXIT_FAIL;
153
+ }
154
+
155
+ s_fd = init_test_server(&serv_addr);
156
+ if (s_fd < 0)
157
+ return T_EXIT_FAIL;
158
+
159
+ clientfd = init_test_client();
160
+ if (clientfd < 0) {
161
+ close(s_fd);
162
+ return T_EXIT_FAIL;
163
+ }
164
+
165
+ /* make sure SQPOLL thread is sleeping */
166
+ if (flags & IORING_SETUP_SQPOLL)
167
+ usleep(100000);
168
+
169
+ for (i = 0; i < 32; i++) {
170
+ ret = test_connect(&ring, clientfd, &serv_addr);
171
+ if (ret == T_EXIT_SKIP)
172
+ return T_EXIT_SKIP;
173
+ else if (ret == T_EXIT_PASS)
174
+ continue;
175
+
176
+ return T_EXIT_FAIL;
177
+ }
178
+
179
+ close(s_fd);
180
+ close(clientfd);
181
+ return T_EXIT_PASS;
182
+ }
183
+
184
+ int main(int argc, char *argv[])
185
+ {
186
+ int ret;
187
+
188
+ if (argc > 1)
189
+ return T_EXIT_SKIP;
190
+
191
+ ret = test(0);
192
+ if (ret == T_EXIT_FAIL) {
193
+ fprintf(stderr, "test(0) failed\n");
194
+ return T_EXIT_FAIL;
195
+ }
196
+
197
+ ret = test(IORING_SETUP_SQPOLL);
198
+ if (ret == T_EXIT_FAIL) {
199
+ fprintf(stderr, "test(SQPOLL) failed\n");
200
+ return T_EXIT_FAIL;
201
+ }
202
+
203
+ return 0;
204
+ }
@@ -0,0 +1,442 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Check that IORING_OP_CONNECT works, with and without other side
4
+ * being open.
5
+ */
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+ #include <string.h>
9
+
10
+ #include <errno.h>
11
+ #include <fcntl.h>
12
+ #include <unistd.h>
13
+ #include <poll.h>
14
+ #include <sys/socket.h>
15
+ #include <netinet/in.h>
16
+ #include <netinet/tcp.h>
17
+ #include <arpa/inet.h>
18
+ #include <sys/stat.h>
19
+
20
+ #include "liburing.h"
21
+ #include "helpers.h"
22
+
23
+ static int no_connect;
24
+ static unsigned short use_port;
25
+ static unsigned int use_addr;
26
+
27
+ static int create_socket(void)
28
+ {
29
+ int fd;
30
+
31
+ fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
32
+ if (fd == -1) {
33
+ perror("socket()");
34
+ return -1;
35
+ }
36
+
37
+ return fd;
38
+ }
39
+
40
+ static int submit_and_wait(struct io_uring *ring, int *res)
41
+ {
42
+ struct io_uring_cqe *cqe;
43
+ int ret;
44
+
45
+ ret = io_uring_submit_and_wait(ring, 1);
46
+ if (ret != 1) {
47
+ fprintf(stderr, "io_using_submit: got %d\n", ret);
48
+ return 1;
49
+ }
50
+
51
+ ret = io_uring_peek_cqe(ring, &cqe);
52
+ if (ret) {
53
+ fprintf(stderr, "io_uring_peek_cqe(): no cqe returned");
54
+ return 1;
55
+ }
56
+
57
+ *res = cqe->res;
58
+ io_uring_cqe_seen(ring, cqe);
59
+ return 0;
60
+ }
61
+
62
+ static int wait_for(struct io_uring *ring, int fd, int mask)
63
+ {
64
+ struct io_uring_sqe *sqe;
65
+ int ret, res;
66
+
67
+ sqe = io_uring_get_sqe(ring);
68
+ if (!sqe) {
69
+ fprintf(stderr, "unable to get sqe\n");
70
+ return -1;
71
+ }
72
+
73
+ io_uring_prep_poll_add(sqe, fd, mask);
74
+ sqe->user_data = 2;
75
+
76
+ ret = submit_and_wait(ring, &res);
77
+ if (ret)
78
+ return -1;
79
+
80
+ if (res < 0) {
81
+ fprintf(stderr, "poll(): failed with %d\n", res);
82
+ return -1;
83
+ }
84
+
85
+ return res;
86
+ }
87
+
88
+ static int listen_on_socket(int fd)
89
+ {
90
+ struct sockaddr_in addr;
91
+ int ret;
92
+
93
+ memset(&addr, 0, sizeof(addr));
94
+ addr.sin_family = AF_INET;
95
+ addr.sin_port = use_port;
96
+ addr.sin_addr.s_addr = use_addr;
97
+
98
+ ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
99
+ if (ret == -1) {
100
+ perror("bind()");
101
+ return -1;
102
+ }
103
+
104
+ ret = listen(fd, 128);
105
+ if (ret == -1) {
106
+ perror("listen()");
107
+ return -1;
108
+ }
109
+
110
+ return 0;
111
+ }
112
+
113
+ static int configure_connect(int fd, struct sockaddr_in* addr)
114
+ {
115
+ int ret, val = 1;
116
+
117
+ ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
118
+ if (ret == -1) {
119
+ perror("setsockopt()");
120
+ return -1;
121
+ }
122
+
123
+ ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
124
+ if (ret == -1) {
125
+ perror("setsockopt()");
126
+ return -1;
127
+ }
128
+
129
+ memset(addr, 0, sizeof(*addr));
130
+ addr->sin_family = AF_INET;
131
+ addr->sin_port = use_port;
132
+ ret = inet_aton("127.0.0.1", &addr->sin_addr);
133
+ return ret;
134
+ }
135
+
136
+ static int connect_socket(struct io_uring *ring, int fd, int *code, int async)
137
+ {
138
+ struct sockaddr_in addr;
139
+ int ret, res;
140
+ socklen_t code_len = sizeof(*code);
141
+ struct io_uring_sqe *sqe;
142
+
143
+ if (configure_connect(fd, &addr) == -1)
144
+ return -1;
145
+
146
+ sqe = io_uring_get_sqe(ring);
147
+ if (!sqe) {
148
+ fprintf(stderr, "unable to get sqe\n");
149
+ return -1;
150
+ }
151
+
152
+ io_uring_prep_connect(sqe, fd, (struct sockaddr*)&addr, sizeof(addr));
153
+ if (async)
154
+ sqe->flags |= IOSQE_ASYNC;
155
+ sqe->user_data = 1;
156
+
157
+ ret = submit_and_wait(ring, &res);
158
+ if (ret)
159
+ return -1;
160
+
161
+ if (res == -EINPROGRESS) {
162
+ ret = wait_for(ring, fd, POLLOUT | POLLHUP | POLLERR);
163
+ if (ret == -1)
164
+ return -1;
165
+
166
+ int ev = (ret & POLLOUT) || (ret & POLLHUP) || (ret & POLLERR);
167
+ if (!ev) {
168
+ fprintf(stderr, "poll(): returned invalid value %#x\n", ret);
169
+ return -1;
170
+ }
171
+
172
+ ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, code, &code_len);
173
+ if (ret == -1) {
174
+ perror("getsockopt()");
175
+ return -1;
176
+ }
177
+ } else
178
+ *code = res;
179
+ return 0;
180
+ }
181
+
182
+ static int test_connect_with_no_peer(struct io_uring *ring)
183
+ {
184
+ int connect_fd;
185
+ int ret, code;
186
+
187
+ connect_fd = create_socket();
188
+ if (connect_fd == -1)
189
+ return -1;
190
+
191
+ ret = connect_socket(ring, connect_fd, &code, 0);
192
+ if (ret == -1)
193
+ goto err;
194
+
195
+ if (code != -ECONNREFUSED) {
196
+ if (code == -EINVAL || code == -EBADF || code == -EOPNOTSUPP) {
197
+ fprintf(stdout, "No connect support, skipping\n");
198
+ no_connect = 1;
199
+ goto out;
200
+ }
201
+ fprintf(stderr, "connect failed with %d\n", code);
202
+ goto err;
203
+ }
204
+
205
+ out:
206
+ close(connect_fd);
207
+ return 0;
208
+
209
+ err:
210
+ close(connect_fd);
211
+ return -1;
212
+ }
213
+
214
+ static int test_connect(struct io_uring *ring, int async)
215
+ {
216
+ int accept_fd;
217
+ int connect_fd;
218
+ int ret, code;
219
+
220
+ accept_fd = create_socket();
221
+ if (accept_fd == -1)
222
+ return -1;
223
+
224
+ ret = listen_on_socket(accept_fd);
225
+ if (ret == -1)
226
+ goto err1;
227
+
228
+ connect_fd = create_socket();
229
+ if (connect_fd == -1)
230
+ goto err1;
231
+
232
+ ret = connect_socket(ring, connect_fd, &code, async);
233
+ if (ret == -1)
234
+ goto err2;
235
+
236
+ if (code != 0) {
237
+ fprintf(stderr, "connect failed with %d\n", code);
238
+ goto err2;
239
+ }
240
+
241
+ close(connect_fd);
242
+ close(accept_fd);
243
+
244
+ return 0;
245
+
246
+ err2:
247
+ close(connect_fd);
248
+
249
+ err1:
250
+ close(accept_fd);
251
+ return -1;
252
+ }
253
+
254
+ static int test_connect_timeout(struct io_uring *ring)
255
+ {
256
+ int connect_fd[2] = {-1, -1};
257
+ int accept_fd = -1;
258
+ int ret, code;
259
+ struct sockaddr_in addr;
260
+ struct io_uring_sqe *sqe;
261
+ struct __kernel_timespec ts = {.tv_sec = 0, .tv_nsec = 100000};
262
+ struct stat sb;
263
+
264
+ /*
265
+ * Test reliably fails if syncookies isn't enabled
266
+ */
267
+ if (stat("/proc/sys/net/ipv4/tcp_syncookies", &sb) < 0)
268
+ return T_EXIT_SKIP;
269
+
270
+ connect_fd[0] = create_socket();
271
+ if (connect_fd[0] == -1)
272
+ return -1;
273
+
274
+ connect_fd[1] = create_socket();
275
+ if (connect_fd[1] == -1)
276
+ goto err;
277
+
278
+ accept_fd = create_socket();
279
+ if (accept_fd == -1)
280
+ goto err;
281
+
282
+ if (configure_connect(connect_fd[0], &addr) == -1)
283
+ goto err;
284
+
285
+ if (configure_connect(connect_fd[1], &addr) == -1)
286
+ goto err;
287
+
288
+ ret = bind(accept_fd, (struct sockaddr*)&addr, sizeof(addr));
289
+ if (ret == -1) {
290
+ perror("bind()");
291
+ goto err;
292
+ }
293
+
294
+ ret = listen(accept_fd, 0); // no backlog in order to block connect_fd[1]
295
+ if (ret == -1) {
296
+ perror("listen()");
297
+ goto err;
298
+ }
299
+
300
+ // We first connect with one client socket in order to fill the accept queue.
301
+ ret = connect_socket(ring, connect_fd[0], &code, 0);
302
+ if (ret == -1 || code != 0) {
303
+ fprintf(stderr, "unable to connect\n");
304
+ goto err;
305
+ }
306
+
307
+ // We do not offload completion events from listening socket on purpose.
308
+ // This way we create a state where the second connect request being stalled by OS.
309
+ sqe = io_uring_get_sqe(ring);
310
+ if (!sqe) {
311
+ fprintf(stderr, "unable to get sqe\n");
312
+ goto err;
313
+ }
314
+
315
+ io_uring_prep_connect(sqe, connect_fd[1], (struct sockaddr*)&addr, sizeof(addr));
316
+ sqe->user_data = 1;
317
+ sqe->flags |= IOSQE_IO_LINK;
318
+
319
+ sqe = io_uring_get_sqe(ring);
320
+ if (!sqe) {
321
+ fprintf(stderr, "unable to get sqe\n");
322
+ goto err;
323
+ }
324
+ io_uring_prep_link_timeout(sqe, &ts, 0);
325
+ sqe->user_data = 2;
326
+
327
+ ret = io_uring_submit(ring);
328
+ if (ret != 2) {
329
+ fprintf(stderr, "submitted %d\n", ret);
330
+ return -1;
331
+ }
332
+
333
+ for (int i = 0; i < 2; i++) {
334
+ int expected;
335
+ struct io_uring_cqe *cqe;
336
+
337
+ ret = io_uring_wait_cqe(ring, &cqe);
338
+ if (ret) {
339
+ fprintf(stderr, "wait_cqe=%d\n", ret);
340
+ return -1;
341
+ }
342
+
343
+ expected = (cqe->user_data == 1) ? -ECANCELED : -ETIME;
344
+ if (expected != cqe->res) {
345
+ fprintf(stderr, "cqe %d, res %d, wanted %d\n",
346
+ (int)cqe->user_data, cqe->res, expected);
347
+ goto err;
348
+ }
349
+ io_uring_cqe_seen(ring, cqe);
350
+ }
351
+
352
+ close(connect_fd[0]);
353
+ close(connect_fd[1]);
354
+ close(accept_fd);
355
+ return 0;
356
+
357
+ err:
358
+ if (connect_fd[0] != -1)
359
+ close(connect_fd[0]);
360
+ if (connect_fd[1] != -1)
361
+ close(connect_fd[1]);
362
+
363
+ if (accept_fd != -1)
364
+ close(accept_fd);
365
+ return -1;
366
+ }
367
+
368
+ static int test(int flags)
369
+ {
370
+ struct io_uring ring;
371
+ int ret;
372
+
373
+ ret = io_uring_queue_init(8, &ring, flags);
374
+ if (ret) {
375
+ fprintf(stderr, "io_uring_queue_setup() = %d\n", ret);
376
+ return T_EXIT_FAIL;
377
+ }
378
+
379
+ srand(getpid());
380
+ use_port = (rand() % 61440) + 4096;
381
+ use_port = htons(use_port);
382
+ use_addr = inet_addr("127.0.0.1");
383
+
384
+ ret = test_connect_with_no_peer(&ring);
385
+ if (ret == -1) {
386
+ fprintf(stderr, "test_connect_with_no_peer(): failed\n");
387
+ return T_EXIT_FAIL;
388
+ }
389
+ if (no_connect)
390
+ return T_EXIT_SKIP;
391
+
392
+ ret = test_connect(&ring, 0);
393
+ if (ret == -1) {
394
+ fprintf(stderr, "test_connect(): failed\n");
395
+ return T_EXIT_FAIL;
396
+ }
397
+
398
+ ret = test_connect(&ring, 1);
399
+ if (ret == -1) {
400
+ fprintf(stderr, "test_connect(): failed\n");
401
+ return T_EXIT_FAIL;
402
+ }
403
+
404
+ ret = test_connect_timeout(&ring);
405
+ if (ret == -1) {
406
+ fprintf(stderr, "test_connect_timeout(): failed\n");
407
+ return T_EXIT_FAIL;
408
+ }
409
+
410
+ io_uring_queue_exit(&ring);
411
+ return T_EXIT_PASS;
412
+ }
413
+
414
+ int main(int argc, char *argv[])
415
+ {
416
+ int ret;
417
+
418
+ if (argc > 1)
419
+ return T_EXIT_SKIP;
420
+
421
+ ret = test(0);
422
+ if (ret == -1) {
423
+ fprintf(stderr, "test 0 failed\n");
424
+ return T_EXIT_FAIL;
425
+ }
426
+ if (no_connect)
427
+ return T_EXIT_SKIP;
428
+
429
+ ret = test(IORING_SETUP_SQPOLL);
430
+ if (ret == -1) {
431
+ fprintf(stderr, "test SQPOLL failed\n");
432
+ return T_EXIT_FAIL;
433
+ }
434
+
435
+ ret = test(IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN);
436
+ if (ret == -1) {
437
+ fprintf(stderr, "test DEFER failed\n");
438
+ return T_EXIT_FAIL;
439
+ }
440
+
441
+ return T_EXIT_PASS;
442
+ }
@@ -0,0 +1,60 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: trigger segfault. A recent 6.4-rc kernel introduced a bug
4
+ * via vhost where segfaults for applications using io_uring
5
+ * would hang in D state forever upon trying to generate the
6
+ * core file. Perform a trivial test where a child process
7
+ * generates a NULL pointer dereference and ensure that we don't
8
+ * hang.
9
+ *
10
+ */
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+ #include <unistd.h>
14
+ #include <sys/wait.h>
15
+
16
+ #include "liburing.h"
17
+ #include "helpers.h"
18
+
19
+ static void test(void)
20
+ {
21
+ struct io_uring_sqe *sqe;
22
+ struct io_uring ring;
23
+ int *ptr = NULL;
24
+ int fds[2];
25
+ char r1;
26
+
27
+ if (pipe(fds) < 0) {
28
+ perror("pipe");
29
+ exit(0);
30
+ }
31
+
32
+ io_uring_queue_init(8, &ring, 0);
33
+
34
+ sqe = io_uring_get_sqe(&ring);
35
+ io_uring_prep_read(sqe, fds[0], &r1, sizeof(r1), 0);
36
+ sqe->flags = IOSQE_ASYNC;
37
+ sqe->user_data = 1;
38
+
39
+ io_uring_submit(&ring);
40
+ *ptr = 0;
41
+ exit(0);
42
+ }
43
+
44
+ int main(int argc, char *argv[])
45
+ {
46
+ pid_t pid;
47
+ int wstat;
48
+
49
+ pid = fork();
50
+ if (pid < 0) {
51
+ perror("fork");
52
+ return T_EXIT_SKIP;
53
+ } else if (!pid) {
54
+ test();
55
+ }
56
+
57
+ wait(&wstat);
58
+ unlink("core");
59
+ return T_EXIT_PASS;
60
+ }