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,408 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Configure and operate a TCP socket solely with io_uring.
4
+ */
5
+ #include <stdio.h>
6
+ #include <string.h>
7
+ #include <liburing.h>
8
+ #include <err.h>
9
+ #include <sys/mman.h>
10
+ #include <sys/wait.h>
11
+ #include <sys/socket.h>
12
+ #include <unistd.h>
13
+ #include <stdlib.h>
14
+ #include <netinet/ip.h>
15
+ #include "liburing.h"
16
+ #include "helpers.h"
17
+
18
+ static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
19
+ {
20
+ ts->tv_sec = msec / 1000;
21
+ ts->tv_nsec = (msec % 1000) * 1000000;
22
+ }
23
+
24
+ static const char *magic = "Hello World!";
25
+ static int use_port = 8000;
26
+
27
+ enum {
28
+ SRV_INDEX = 0,
29
+ CLI_INDEX,
30
+ CONN_INDEX,
31
+ };
32
+
33
+ static int connect_client(struct io_uring *ring, unsigned short peer_port)
34
+ {
35
+ struct __kernel_timespec ts;
36
+ struct io_uring_sqe *sqe;
37
+ struct io_uring_cqe *cqe;
38
+ int head, ret, submitted = 0;
39
+ struct sockaddr_in peer_addr;
40
+ socklen_t addr_len = sizeof(peer_addr);
41
+
42
+ peer_addr.sin_family = AF_INET;
43
+ peer_addr.sin_port = peer_port;
44
+ peer_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
45
+
46
+ sqe = io_uring_get_sqe(ring);
47
+ io_uring_prep_socket_direct(sqe, AF_INET, SOCK_STREAM, 0,
48
+ CLI_INDEX, 0);
49
+ sqe->flags |= IOSQE_IO_LINK;
50
+
51
+ sqe = io_uring_get_sqe(ring);
52
+ io_uring_prep_connect(sqe, CLI_INDEX, (struct sockaddr*) &peer_addr, addr_len);
53
+ sqe->flags |= IOSQE_FIXED_FILE | IOSQE_IO_LINK;
54
+
55
+ sqe = io_uring_get_sqe(ring);
56
+ io_uring_prep_send(sqe, CLI_INDEX, magic, strlen(magic), 0);
57
+ sqe->flags |= IOSQE_FIXED_FILE | IOSQE_IO_LINK;
58
+
59
+ submitted = ret = io_uring_submit(ring);
60
+ if (ret < 0)
61
+ return T_SETUP_SKIP;
62
+
63
+ msec_to_ts(&ts, 300);
64
+ ret = io_uring_wait_cqes(ring, &cqe, submitted, &ts, NULL);
65
+ if (ret < 0)
66
+ return T_SETUP_SKIP;
67
+
68
+ io_uring_for_each_cqe(ring, head, cqe) {
69
+ ret = cqe->res;
70
+ if (ret < 0)
71
+ return T_SETUP_SKIP;
72
+ } io_uring_cq_advance(ring, submitted);
73
+
74
+ return T_SETUP_OK;
75
+ }
76
+
77
+ static int setup_srv(struct io_uring *ring, struct sockaddr_in *server_addr)
78
+ {
79
+ struct io_uring_sqe *sqe;
80
+ struct io_uring_cqe *cqe;
81
+ struct __kernel_timespec ts;
82
+ int ret, val, submitted;
83
+ unsigned head;
84
+
85
+ memset(server_addr, 0, sizeof(struct sockaddr_in));
86
+ server_addr->sin_family = AF_INET;
87
+ server_addr->sin_port = htons(use_port++);
88
+ server_addr->sin_addr.s_addr = htons(INADDR_ANY);
89
+
90
+ sqe = io_uring_get_sqe(ring);
91
+ io_uring_prep_socket_direct(sqe, AF_INET, SOCK_STREAM, 0, SRV_INDEX, 0);
92
+ sqe->flags |= IOSQE_IO_LINK;
93
+
94
+ sqe = io_uring_get_sqe(ring);
95
+ val = 1;
96
+ io_uring_prep_cmd_sock(sqe, SOCKET_URING_OP_SETSOCKOPT, 0, SOL_SOCKET,
97
+ SO_REUSEADDR, &val, sizeof(val));
98
+ sqe->flags |= IOSQE_FIXED_FILE | IOSQE_IO_LINK;
99
+
100
+ sqe = io_uring_get_sqe(ring);
101
+ io_uring_prep_bind(sqe, SRV_INDEX, (struct sockaddr *) server_addr,
102
+ sizeof(struct sockaddr_in));
103
+ sqe->flags |= IOSQE_FIXED_FILE | IOSQE_IO_LINK;
104
+
105
+ sqe = io_uring_get_sqe(ring);
106
+ io_uring_prep_listen(sqe, SRV_INDEX, 1);
107
+ sqe->flags |= IOSQE_FIXED_FILE;
108
+
109
+ submitted = ret = io_uring_submit(ring);
110
+ if (ret < 0) {
111
+ fprintf(stderr, "submission failed. %d\n", ret);
112
+ return T_EXIT_FAIL;
113
+ }
114
+
115
+ msec_to_ts(&ts, 300);
116
+ ret = io_uring_wait_cqes(ring, &cqe, ret, &ts, NULL);
117
+ if (ret < 0) {
118
+ fprintf(stderr, "submission failed. %d\n", ret);
119
+ return T_EXIT_FAIL;
120
+ }
121
+
122
+ io_uring_for_each_cqe(ring, head, cqe) {
123
+ ret = cqe->res;
124
+ if (ret < 0) {
125
+ fprintf(stderr, "Server startup failed. step %d got %d \n", head, ret);
126
+ return T_EXIT_FAIL;
127
+ }
128
+ } io_uring_cq_advance(ring, submitted);
129
+
130
+ return T_SETUP_OK;
131
+ }
132
+
133
+ static int test_good_server(unsigned int ring_flags)
134
+ {
135
+ struct sockaddr_in server_addr;
136
+ struct __kernel_timespec ts;
137
+ struct io_uring_sqe *sqe;
138
+ struct io_uring_cqe *cqe;
139
+ struct io_uring ring;
140
+ int ret;
141
+ int fds[3];
142
+ char buf[1024];
143
+
144
+ memset(fds, -1, sizeof(fds));
145
+
146
+ ret = t_create_ring(10, &ring, ring_flags | IORING_SETUP_SUBMIT_ALL);
147
+ if (ret < 0) {
148
+ fprintf(stderr, "queue_init: %s\n", strerror(-ret));
149
+ return T_SETUP_SKIP;
150
+ }
151
+
152
+ ret = io_uring_register_files(&ring, fds, 3);
153
+ if (ret) {
154
+ fprintf(stderr, "server file register %d\n", ret);
155
+ return T_SETUP_SKIP;
156
+ }
157
+
158
+ ret = setup_srv(&ring, &server_addr);
159
+ if (ret != T_SETUP_OK) {
160
+ fprintf(stderr, "srv startup failed.\n");
161
+ return T_EXIT_FAIL;
162
+ }
163
+
164
+ if (connect_client(&ring, server_addr.sin_port) != T_SETUP_OK) {
165
+ fprintf(stderr, "cli startup failed.\n");
166
+ return T_SETUP_SKIP;
167
+ }
168
+
169
+ /* Wait for a request */
170
+ sqe = io_uring_get_sqe(&ring);
171
+ io_uring_prep_accept_direct(sqe, SRV_INDEX, NULL, NULL, 0, CONN_INDEX);
172
+ sqe->flags |= IOSQE_FIXED_FILE;
173
+
174
+ io_uring_submit(&ring);
175
+ io_uring_wait_cqe(&ring, &cqe);
176
+ if (cqe->res < 0) {
177
+ fprintf(stderr, "accept failed. %d\n", cqe->res);
178
+ return T_EXIT_FAIL;
179
+ }
180
+ io_uring_cqe_seen(&ring, cqe);
181
+
182
+ sqe = io_uring_get_sqe(&ring);
183
+ io_uring_prep_recv(sqe, CONN_INDEX, buf, BUFSIZ, 0);
184
+ sqe->flags |= IOSQE_FIXED_FILE;
185
+
186
+ io_uring_submit(&ring);
187
+ io_uring_wait_cqe_timeout(&ring, &cqe, &ts);
188
+
189
+ if (cqe->res < 0) {
190
+ fprintf(stderr, "bad receive cqe. %d\n", cqe->res);
191
+ return T_EXIT_FAIL;
192
+ }
193
+ ret = cqe->res;
194
+ io_uring_cqe_seen(&ring, cqe);
195
+
196
+ io_uring_queue_exit(&ring);
197
+
198
+ if (ret != strlen(magic) || strncmp(buf, magic, ret)) {
199
+ fprintf(stderr, "didn't receive expected string. Got %d '%s'\n", ret, buf);
200
+ return T_EXIT_FAIL;
201
+ }
202
+
203
+ return T_EXIT_PASS;
204
+ }
205
+
206
+ static int test_bad_bind(void)
207
+ {
208
+ struct sockaddr_in server_addr;
209
+ struct io_uring_sqe *sqe;
210
+ struct io_uring_cqe *cqe;
211
+ struct io_uring ring;
212
+ int sock = -1, err;
213
+ int ret = T_EXIT_FAIL;
214
+
215
+ memset(&server_addr, 0, sizeof(struct sockaddr_in));
216
+ server_addr.sin_family = AF_INET;
217
+ server_addr.sin_port = htons(9001);
218
+ server_addr.sin_addr.s_addr = htons(INADDR_ANY);
219
+
220
+ err = t_create_ring(1, &ring, 0);
221
+ if (err < 0) {
222
+ fprintf(stderr, "queue_init: %s\n", strerror(-ret));
223
+ return T_SETUP_SKIP;
224
+ }
225
+
226
+ sock = socket(AF_INET, SOCK_STREAM, 0);
227
+ if (sock < 0) {
228
+ perror("socket");
229
+ goto fail;
230
+ }
231
+
232
+ /* Bind with size 0 */
233
+ sqe = io_uring_get_sqe(&ring);
234
+ io_uring_prep_bind(sqe, sock, (struct sockaddr *) &server_addr, 0);
235
+ err = io_uring_submit(&ring);
236
+ if (err < 0)
237
+ goto fail;
238
+
239
+ err = io_uring_wait_cqe(&ring, &cqe);
240
+ if (err)
241
+ goto fail;
242
+
243
+ if (cqe->res != -EINVAL)
244
+ goto fail;
245
+ io_uring_cqe_seen(&ring, cqe);
246
+
247
+ /* Bind with bad fd */
248
+ sqe = io_uring_get_sqe(&ring);
249
+ io_uring_prep_bind(sqe, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
250
+ err = io_uring_submit(&ring);
251
+ if (err < 0)
252
+ goto fail;
253
+
254
+ err = io_uring_wait_cqe(&ring, &cqe);
255
+ if (err)
256
+ goto fail;
257
+ if (cqe->res != -ENOTSOCK)
258
+ goto fail;
259
+ io_uring_cqe_seen(&ring, cqe);
260
+
261
+ ret = T_EXIT_PASS;
262
+
263
+ /* bind with weird value */
264
+ sqe = io_uring_get_sqe(&ring);
265
+ io_uring_prep_bind(sqe, sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
266
+ sqe->rw_flags = 1;
267
+ err = io_uring_submit(&ring);
268
+ if (err < 0)
269
+ goto fail;
270
+
271
+ err = io_uring_wait_cqe(&ring, &cqe);
272
+ if (err)
273
+ goto fail;
274
+ if (cqe->res != -EINVAL)
275
+ goto fail;
276
+ io_uring_cqe_seen(&ring, cqe);
277
+
278
+ ret = T_EXIT_PASS;
279
+
280
+ fail:
281
+ io_uring_queue_exit(&ring);
282
+ if (sock != -1)
283
+ close(sock);
284
+ return ret;
285
+ }
286
+
287
+ static int test_bad_listen(void)
288
+ {
289
+ struct sockaddr_in server_addr;
290
+ struct io_uring_sqe *sqe;
291
+ struct io_uring_cqe *cqe;
292
+ struct io_uring ring;
293
+ int sock = -1, err;
294
+ int ret = T_EXIT_FAIL;
295
+
296
+ memset(&server_addr, 0, sizeof(struct sockaddr_in));
297
+ server_addr.sin_family = AF_INET;
298
+ server_addr.sin_port = htons(8001);
299
+ server_addr.sin_addr.s_addr = htons(INADDR_ANY);
300
+
301
+ err = t_create_ring(1, &ring, 0);
302
+ if (err < 0) {
303
+ fprintf(stderr, "queue_init: %d\n", err);
304
+ return T_SETUP_SKIP;
305
+ }
306
+
307
+ sock = socket(AF_INET, SOCK_STREAM, 0);
308
+ if (sock < 0) {
309
+ perror("socket");
310
+ goto fail;
311
+ }
312
+
313
+ err = t_bind_ephemeral_port(sock, &server_addr);
314
+ if (err) {
315
+ fprintf(stderr, "bind: %s\n", strerror(-err));
316
+ goto fail;
317
+ }
318
+
319
+ /* listen on bad sock */
320
+ sqe = io_uring_get_sqe(&ring);
321
+ io_uring_prep_listen(sqe, 0, 1);
322
+ err = io_uring_submit(&ring);
323
+ if (err < 0)
324
+ goto fail;
325
+
326
+ err = io_uring_wait_cqe(&ring, &cqe);
327
+ if (err)
328
+ goto fail;
329
+
330
+ if (cqe->res != -ENOTSOCK)
331
+ goto fail;
332
+ io_uring_cqe_seen(&ring, cqe);
333
+
334
+ /* listen with weird parameters */
335
+ sqe = io_uring_get_sqe(&ring);
336
+ io_uring_prep_listen(sqe, sock, 1);
337
+ sqe->addr2 = 0xffffff;
338
+ err = io_uring_submit(&ring);
339
+ if (err < 0)
340
+ goto fail;
341
+
342
+ err = io_uring_wait_cqe(&ring, &cqe);
343
+ if (err)
344
+ goto fail;
345
+
346
+ if (cqe->res != -EINVAL)
347
+ goto fail;
348
+ io_uring_cqe_seen(&ring, cqe);
349
+
350
+ ret = T_EXIT_PASS;
351
+ fail:
352
+ io_uring_queue_exit(&ring);
353
+ if (sock != -1)
354
+ close(sock);
355
+ return ret;
356
+ }
357
+
358
+ int main(int argc, char *argv[])
359
+ {
360
+ struct io_uring_probe *probe;
361
+ int ret;
362
+
363
+ if (argc > 1)
364
+ return 0;
365
+
366
+ /*
367
+ * This test is not supported on older kernels. Check for
368
+ * OP_LISTEN, since that is the last feature required to support
369
+ * it.
370
+ */
371
+ probe = io_uring_get_probe();
372
+ if (!probe)
373
+ return T_EXIT_SKIP;
374
+ if (!io_uring_opcode_supported(probe, IORING_OP_LISTEN))
375
+ return T_EXIT_SKIP;
376
+
377
+ ret = test_good_server(0);
378
+ if (ret) {
379
+ fprintf(stderr, "good 0 failed\n");
380
+ return T_EXIT_FAIL;
381
+ }
382
+
383
+ ret = test_good_server(IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN);
384
+ if (ret) {
385
+ fprintf(stderr, "good defer failed\n");
386
+ return T_EXIT_FAIL;
387
+ }
388
+
389
+ ret = test_good_server(IORING_SETUP_SQPOLL);
390
+ if (ret) {
391
+ fprintf(stderr, "good sqpoll failed\n");
392
+ return T_EXIT_FAIL;
393
+ }
394
+
395
+ ret = test_bad_bind();
396
+ if (ret) {
397
+ fprintf(stderr, "bad bind failed\n");
398
+ return T_EXIT_FAIL;
399
+ }
400
+
401
+ ret = test_bad_listen();
402
+ if (ret) {
403
+ fprintf(stderr, "bad listen failed\n");
404
+ return T_EXIT_FAIL;
405
+ }
406
+
407
+ return T_EXIT_PASS;
408
+ }
@@ -0,0 +1,123 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test IOU_PBUF_RING_MMAP with a ring setup with a ring
4
+ * setup without mmap'ing sq/cq arrays
5
+ *
6
+ */
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <unistd.h>
10
+ #include <fcntl.h>
11
+ #include <string.h>
12
+ #include <sys/mman.h>
13
+
14
+ #include "liburing.h"
15
+ #include "helpers.h"
16
+
17
+ static int bgid = 5;
18
+ static int bid = 89;
19
+
20
+ int main(int argc, char *argv[])
21
+ {
22
+ struct io_uring_buf_ring *br;
23
+ struct io_uring_sqe *sqe;
24
+ struct io_uring_cqe *cqe;
25
+ struct io_uring ring;
26
+ size_t ring_size;
27
+ int ret, ring_mask, fds[2];
28
+ struct io_uring_buf_reg reg = {
29
+ .ring_entries = 1,
30
+ .bgid = bgid,
31
+ .flags = IOU_PBUF_RING_MMAP,
32
+ };
33
+ struct io_uring_params p = { };
34
+ void *ring_mem;
35
+ char buf[32];
36
+ off_t off;
37
+
38
+ if (argc > 1)
39
+ return T_EXIT_SKIP;
40
+
41
+ if (posix_memalign(&ring_mem, 16384, 16384))
42
+ return T_EXIT_FAIL;
43
+
44
+ memset(ring_mem, 0, 16384);
45
+
46
+ p.flags = IORING_SETUP_NO_MMAP;
47
+ ret = io_uring_queue_init_mem(1, &ring, &p, ring_mem, 16384);
48
+ if (ret < 0) {
49
+ if (ret == -EINVAL || ret == -ENOMEM)
50
+ return T_EXIT_SKIP;
51
+ fprintf(stderr, "queue init failed %d\n", ret);
52
+ return T_EXIT_FAIL;
53
+ }
54
+
55
+ if (pipe(fds) < 0) {
56
+ perror("pipe");
57
+ return T_EXIT_FAIL;
58
+ }
59
+
60
+ ring_size = sizeof(struct io_uring_buf);
61
+ ring_mask = io_uring_buf_ring_mask(1);
62
+
63
+ ret = io_uring_register_buf_ring(&ring, &reg, 0);
64
+ if (ret) {
65
+ if (ret == -EINVAL)
66
+ return T_EXIT_SKIP;
67
+ fprintf(stderr, "reg buf ring: %d\n", ret);
68
+ return T_EXIT_FAIL;
69
+ }
70
+
71
+ off = IORING_OFF_PBUF_RING |
72
+ (unsigned long long) bgid << IORING_OFF_PBUF_SHIFT;
73
+ br = mmap(NULL, ring_size, PROT_READ | PROT_WRITE,
74
+ MAP_SHARED | MAP_POPULATE, ring.ring_fd, off);
75
+ if (br == MAP_FAILED) {
76
+ if (errno == ENOMEM)
77
+ return T_EXIT_SKIP;
78
+ perror("mmap");
79
+ return T_EXIT_FAIL;
80
+ }
81
+
82
+ io_uring_buf_ring_add(br, buf, sizeof(buf), bid, ring_mask, 0);
83
+ io_uring_buf_ring_advance(br, 1);
84
+
85
+ sqe = io_uring_get_sqe(&ring);
86
+ io_uring_prep_read(sqe, fds[0], NULL, 0, 0);
87
+ sqe->flags |= IOSQE_BUFFER_SELECT;
88
+ sqe->buf_group = bgid;
89
+
90
+ io_uring_submit(&ring);
91
+
92
+ ret = write(fds[1], "Hello", 5);
93
+ if (ret < 0) {
94
+ perror("write");
95
+ return T_EXIT_FAIL;
96
+ } else if (ret != 5) {
97
+ fprintf(stderr, "short write %d\n", ret);
98
+ return T_EXIT_FAIL;
99
+ }
100
+
101
+ ret = io_uring_wait_cqe(&ring, &cqe);
102
+ if (ret) {
103
+ fprintf(stderr, "wait %d\n", ret);
104
+ return T_EXIT_FAIL;
105
+ }
106
+ if (cqe->res < 0) {
107
+ fprintf(stderr, "cqe res %d\n", cqe->res);
108
+ return T_EXIT_FAIL;
109
+ }
110
+ if (!(cqe->flags & IORING_CQE_F_BUFFER)) {
111
+ fprintf(stderr, "buffer not selected in cqe\n");
112
+ return T_EXIT_FAIL;
113
+ }
114
+ if ((cqe->flags >> IORING_CQE_BUFFER_SHIFT) != bid) {
115
+ fprintf(stderr, "wrong buffer id returned\n");
116
+ return T_EXIT_FAIL;
117
+ }
118
+
119
+ io_uring_cqe_seen(&ring, cqe);
120
+
121
+ io_uring_queue_exit(&ring);
122
+ return T_EXIT_PASS;
123
+ }
@@ -0,0 +1,83 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test persistence of mmap'ed provided ring buffers. Use a range
4
+ * of buffer group IDs that puts us into both the lower end array
5
+ * and higher end xarry.
6
+ *
7
+ */
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <unistd.h>
11
+ #include <fcntl.h>
12
+ #include <string.h>
13
+ #include <sys/mman.h>
14
+
15
+ #include "liburing.h"
16
+ #include "helpers.h"
17
+
18
+ #define BGID_START 60
19
+ #define BGID_NR 10
20
+ #define ENTRIES 512
21
+
22
+ int main(int argc, char *argv[])
23
+ {
24
+ struct io_uring_buf_ring *br[BGID_NR];
25
+ struct io_uring ring;
26
+ size_t ring_size;
27
+ int ret, i, j;
28
+
29
+ if (argc > 1)
30
+ return T_EXIT_SKIP;
31
+
32
+ ret = io_uring_queue_init(1, &ring, 0);
33
+ if (ret) {
34
+ fprintf(stderr, "queue init failed %d\n", ret);
35
+ return T_EXIT_FAIL;
36
+ }
37
+
38
+ ring_size = ENTRIES * sizeof(struct io_uring_buf);
39
+
40
+ for (i = 0; i < BGID_NR; i++) {
41
+ int bgid = BGID_START + i;
42
+ struct io_uring_buf_reg reg = {
43
+ .ring_entries = ENTRIES,
44
+ .bgid = bgid,
45
+ .flags = IOU_PBUF_RING_MMAP,
46
+ };
47
+ off_t off;
48
+
49
+ ret = io_uring_register_buf_ring(&ring, &reg, 0);
50
+ if (ret) {
51
+ if (ret == -EINVAL)
52
+ return T_EXIT_SKIP;
53
+ fprintf(stderr, "reg buf ring: %d\n", ret);
54
+ return T_EXIT_FAIL;
55
+ }
56
+
57
+ off = IORING_OFF_PBUF_RING |
58
+ (unsigned long long) bgid << IORING_OFF_PBUF_SHIFT;
59
+ br[i] = mmap(NULL, ring_size, PROT_READ | PROT_WRITE,
60
+ MAP_SHARED | MAP_POPULATE, ring.ring_fd, off);
61
+ if (br[i] == MAP_FAILED) {
62
+ perror("mmap");
63
+ return T_EXIT_FAIL;
64
+ }
65
+ }
66
+
67
+ for (i = 0; i < BGID_NR; i++) {
68
+ ret = io_uring_unregister_buf_ring(&ring, BGID_START + i);
69
+ if (ret) {
70
+ fprintf(stderr, "reg buf ring: %d\n", ret);
71
+ return T_EXIT_FAIL;
72
+ }
73
+ }
74
+
75
+ for (j = 0; j < 1000; j++) {
76
+ for (i = 0; i < BGID_NR; i++)
77
+ memset(br[i], 0x5a, ring_size);
78
+ usleep(1000);
79
+ }
80
+
81
+ io_uring_queue_exit(&ring);
82
+ return T_EXIT_PASS;
83
+ }