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,461 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: run various file registration tests
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+ #include <assert.h>
13
+
14
+ #include "../src/syscall.h"
15
+ #include "helpers.h"
16
+ #include "liburing.h"
17
+
18
+ static int pipes[2];
19
+
20
+ enum {
21
+ TEST_IORING_RSRC_FILE = 0,
22
+ TEST_IORING_RSRC_BUFFER = 1,
23
+ };
24
+
25
+ static bool check_cq_empty(struct io_uring *ring)
26
+ {
27
+ struct io_uring_cqe *cqe = NULL;
28
+ int ret;
29
+
30
+ usleep(1000); /* doesn't happen immediately, so wait */
31
+ ret = io_uring_peek_cqe(ring, &cqe); /* nothing should be there */
32
+ return ret == -EAGAIN;
33
+ }
34
+
35
+ /*
36
+ * There are io_uring_register_buffers_tags() and other wrappers,
37
+ * but they may change, so hand-code to specifically test this ABI.
38
+ */
39
+ static int register_rsrc(struct io_uring *ring, int type, int nr,
40
+ const void *arg, const __u64 *tags)
41
+ {
42
+ struct io_uring_rsrc_register reg;
43
+ int reg_type;
44
+
45
+ memset(&reg, 0, sizeof(reg));
46
+ reg.nr = nr;
47
+ reg.data = (__u64)(uintptr_t)arg;
48
+ reg.tags = (__u64)(uintptr_t)tags;
49
+
50
+ reg_type = IORING_REGISTER_FILES2;
51
+ if (type != TEST_IORING_RSRC_FILE)
52
+ reg_type = IORING_REGISTER_BUFFERS2;
53
+
54
+ return __sys_io_uring_register(ring->ring_fd, reg_type, &reg,
55
+ sizeof(reg));
56
+ }
57
+
58
+ /*
59
+ * There are io_uring_register_buffers_update_tag() and other wrappers,
60
+ * but they may change, so hand-code to specifically test this ABI.
61
+ */
62
+ static int update_rsrc(struct io_uring *ring, int type, int nr, int off,
63
+ const void *arg, const __u64 *tags)
64
+ {
65
+ struct io_uring_rsrc_update2 up;
66
+ int up_type;
67
+
68
+ memset(&up, 0, sizeof(up));
69
+ up.offset = off;
70
+ up.data = (__u64)(uintptr_t)arg;
71
+ up.tags = (__u64)(uintptr_t)tags;
72
+ up.nr = nr;
73
+
74
+ up_type = IORING_REGISTER_FILES_UPDATE2;
75
+ if (type != TEST_IORING_RSRC_FILE)
76
+ up_type = IORING_REGISTER_BUFFERS_UPDATE;
77
+ return __sys_io_uring_register(ring->ring_fd, up_type, &up, sizeof(up));
78
+ }
79
+
80
+ static bool has_rsrc_update(void)
81
+ {
82
+ struct io_uring ring;
83
+ int ret;
84
+
85
+ ret = io_uring_queue_init(1, &ring, 0);
86
+ if (ret) {
87
+ fprintf(stderr, "io_uring_queue_init() failed, %d\n", ret);
88
+ exit(1);
89
+ }
90
+
91
+ ret = ring.features & IORING_FEAT_RSRC_TAGS;
92
+ io_uring_queue_exit(&ring);
93
+ return ret;
94
+ }
95
+
96
+ static int test_tags_generic(int nr, int type, void *rsrc, int ring_flags)
97
+ {
98
+ struct io_uring_cqe *cqe = NULL;
99
+ struct io_uring ring;
100
+ int i, ret;
101
+ __u64 *tags;
102
+
103
+ tags = malloc(nr * sizeof(*tags));
104
+ if (!tags)
105
+ return 1;
106
+ for (i = 0; i < nr; i++)
107
+ tags[i] = i + 1;
108
+ ret = io_uring_queue_init(1, &ring, 0);
109
+ if (ret) {
110
+ printf("ring setup failed\n");
111
+ return 1;
112
+ }
113
+
114
+ ret = register_rsrc(&ring, type, nr, rsrc, tags);
115
+ if (ret) {
116
+ fprintf(stderr, "rsrc register failed %i\n", ret);
117
+ return 1;
118
+ }
119
+
120
+ /* test that tags are set */
121
+ tags[0] = 666;
122
+ ret = update_rsrc(&ring, type, 1, 0, rsrc, &tags[0]);
123
+ assert(ret == 1);
124
+ ret = io_uring_wait_cqe(&ring, &cqe);
125
+ assert(!ret && cqe->user_data == 1);
126
+ io_uring_cqe_seen(&ring, cqe);
127
+
128
+ /* test that tags are updated */
129
+ tags[0] = 0;
130
+ ret = update_rsrc(&ring, type, 1, 0, rsrc, &tags[0]);
131
+ assert(ret == 1);
132
+ ret = io_uring_wait_cqe(&ring, &cqe);
133
+ assert(!ret && cqe->user_data == 666);
134
+ io_uring_cqe_seen(&ring, cqe);
135
+
136
+ /* test tag=0 doesn't emit CQE */
137
+ tags[0] = 1;
138
+ ret = update_rsrc(&ring, type, 1, 0, rsrc, &tags[0]);
139
+ assert(ret == 1);
140
+ assert(check_cq_empty(&ring));
141
+
142
+ free(tags);
143
+ io_uring_queue_exit(&ring);
144
+ return 0;
145
+ }
146
+
147
+ static int test_buffers_update(void)
148
+ {
149
+ struct io_uring_sqe *sqe;
150
+ struct io_uring_cqe *cqe = NULL;
151
+ struct io_uring ring;
152
+ const int nr = 5;
153
+ int buf_idx = 1, i, ret;
154
+ int pipes[2];
155
+ char tmp_buf[1024];
156
+ char tmp_buf2[1024];
157
+ struct iovec vecs[nr];
158
+ __u64 tags[nr];
159
+
160
+ for (i = 0; i < nr; i++) {
161
+ vecs[i].iov_base = tmp_buf;
162
+ vecs[i].iov_len = 1024;
163
+ tags[i] = i + 1;
164
+ }
165
+
166
+ ret = test_tags_generic(nr, TEST_IORING_RSRC_BUFFER, vecs, 0);
167
+ if (ret)
168
+ return 1;
169
+
170
+ ret = io_uring_queue_init(1, &ring, 0);
171
+ if (ret) {
172
+ printf("ring setup failed\n");
173
+ return 1;
174
+ }
175
+ if (pipe(pipes) < 0) {
176
+ perror("pipe");
177
+ return 1;
178
+ }
179
+ ret = register_rsrc(&ring, TEST_IORING_RSRC_BUFFER, nr, vecs, tags);
180
+ if (ret) {
181
+ fprintf(stderr, "rsrc register failed %i\n", ret);
182
+ return 1;
183
+ }
184
+
185
+ /* test that CQE is not emitted before we're done with a buffer */
186
+ sqe = io_uring_get_sqe(&ring);
187
+ io_uring_prep_read_fixed(sqe, pipes[0], tmp_buf, 10, 0, 0);
188
+ sqe->user_data = 100;
189
+ ret = io_uring_submit(&ring);
190
+ if (ret != 1) {
191
+ fprintf(stderr, "%s: got %d, wanted 1\n", __FUNCTION__, ret);
192
+ return 1;
193
+ }
194
+ ret = io_uring_peek_cqe(&ring, &cqe);
195
+ assert(ret == -EAGAIN);
196
+
197
+ vecs[buf_idx].iov_base = tmp_buf2;
198
+ ret = update_rsrc(&ring, TEST_IORING_RSRC_BUFFER, 1, buf_idx,
199
+ &vecs[buf_idx], &tags[buf_idx]);
200
+ if (ret != 1) {
201
+ fprintf(stderr, "rsrc update failed %i %i\n", ret, errno);
202
+ return 1;
203
+ }
204
+
205
+ ret = io_uring_peek_cqe(&ring, &cqe); /* nothing should be there */
206
+ assert(ret == -EAGAIN);
207
+ close(pipes[0]);
208
+ close(pipes[1]);
209
+
210
+ ret = io_uring_wait_cqe(&ring, &cqe);
211
+ assert(!ret && cqe->user_data == 100);
212
+ io_uring_cqe_seen(&ring, cqe);
213
+ ret = io_uring_wait_cqe(&ring, &cqe);
214
+ assert(!ret && cqe->user_data == buf_idx + 1);
215
+ io_uring_cqe_seen(&ring, cqe);
216
+
217
+ io_uring_queue_exit(&ring);
218
+ return 0;
219
+ }
220
+
221
+ static int test_buffers_empty_buffers(void)
222
+ {
223
+ struct io_uring_sqe *sqe;
224
+ struct io_uring_cqe *cqe = NULL;
225
+ struct io_uring ring;
226
+ const int nr = 5;
227
+ int ret, i;
228
+ char tmp_buf[1024];
229
+ struct iovec vecs[nr];
230
+
231
+ for (i = 0; i < nr; i++) {
232
+ vecs[i].iov_base = 0;
233
+ vecs[i].iov_len = 0;
234
+ }
235
+ vecs[0].iov_base = tmp_buf;
236
+ vecs[0].iov_len = 10;
237
+
238
+ ret = io_uring_queue_init(1, &ring, 0);
239
+ if (ret) {
240
+ printf("ring setup failed\n");
241
+ return 1;
242
+ }
243
+
244
+ ret = register_rsrc(&ring, TEST_IORING_RSRC_BUFFER, nr, vecs, NULL);
245
+ if (ret) {
246
+ fprintf(stderr, "rsrc register failed %i\n", ret);
247
+ return 1;
248
+ }
249
+
250
+ /* empty to buffer */
251
+ vecs[1].iov_base = tmp_buf;
252
+ vecs[1].iov_len = 10;
253
+ ret = update_rsrc(&ring, TEST_IORING_RSRC_BUFFER, 1, 1, &vecs[1], NULL);
254
+ if (ret != 1) {
255
+ fprintf(stderr, "rsrc update failed %i %i\n", ret, errno);
256
+ return 1;
257
+ }
258
+
259
+ /* buffer to empty */
260
+ vecs[0].iov_base = 0;
261
+ vecs[0].iov_len = 0;
262
+ ret = update_rsrc(&ring, TEST_IORING_RSRC_BUFFER, 1, 0, &vecs[0], NULL);
263
+ if (ret != 1) {
264
+ fprintf(stderr, "rsrc update failed %i %i\n", ret, errno);
265
+ return 1;
266
+ }
267
+
268
+ /* zero to zero is ok */
269
+ ret = update_rsrc(&ring, TEST_IORING_RSRC_BUFFER, 1, 2, &vecs[2], NULL);
270
+ if (ret != 1) {
271
+ fprintf(stderr, "rsrc update failed %i %i\n", ret, errno);
272
+ return 1;
273
+ }
274
+
275
+ /* empty buf with non-zero len fails */
276
+ vecs[3].iov_base = 0;
277
+ vecs[3].iov_len = 1;
278
+ ret = update_rsrc(&ring, TEST_IORING_RSRC_BUFFER, 1, 3, &vecs[3], NULL);
279
+ if (ret >= 0) {
280
+ fprintf(stderr, "rsrc update failed %i %i\n", ret, errno);
281
+ return 1;
282
+ }
283
+
284
+ /* test rw on empty ubuf is failed */
285
+ sqe = io_uring_get_sqe(&ring);
286
+ io_uring_prep_read_fixed(sqe, pipes[0], tmp_buf, 10, 0, 2);
287
+ sqe->user_data = 100;
288
+ ret = io_uring_submit(&ring);
289
+ if (ret != 1) {
290
+ fprintf(stderr, "%s: got %d, wanted 1\n", __FUNCTION__, ret);
291
+ return 1;
292
+ }
293
+ ret = io_uring_wait_cqe(&ring, &cqe);
294
+ assert(!ret && cqe->user_data == 100);
295
+ assert(cqe->res);
296
+ io_uring_cqe_seen(&ring, cqe);
297
+
298
+ sqe = io_uring_get_sqe(&ring);
299
+ io_uring_prep_read_fixed(sqe, pipes[0], tmp_buf, 0, 0, 2);
300
+ sqe->user_data = 100;
301
+ ret = io_uring_submit(&ring);
302
+ if (ret != 1) {
303
+ fprintf(stderr, "%s: got %d, wanted 1\n", __FUNCTION__, ret);
304
+ return 1;
305
+ }
306
+ ret = io_uring_wait_cqe(&ring, &cqe);
307
+ assert(!ret && cqe->user_data == 100);
308
+ assert(cqe->res);
309
+ io_uring_cqe_seen(&ring, cqe);
310
+
311
+ io_uring_queue_exit(&ring);
312
+ return 0;
313
+ }
314
+
315
+
316
+ static int test_files(int ring_flags)
317
+ {
318
+ struct io_uring_cqe *cqe = NULL;
319
+ struct io_uring ring;
320
+ const int nr = 50;
321
+ int off = 5, i, ret, fd;
322
+ __s32 files[nr];
323
+ __u64 tags[nr], tag;
324
+
325
+ for (i = 0; i < nr; ++i) {
326
+ files[i] = pipes[0];
327
+ tags[i] = i + 1;
328
+ }
329
+
330
+ ret = test_tags_generic(nr, TEST_IORING_RSRC_FILE, files, ring_flags);
331
+ if (ret)
332
+ return 1;
333
+
334
+ ret = io_uring_queue_init(1, &ring, ring_flags);
335
+ if (ret) {
336
+ printf("ring setup failed\n");
337
+ return 1;
338
+ }
339
+ ret = register_rsrc(&ring, TEST_IORING_RSRC_FILE, nr, files, tags);
340
+ if (ret) {
341
+ fprintf(stderr, "rsrc register failed %i\n", ret);
342
+ return 1;
343
+ }
344
+
345
+ /* check update did update tag */
346
+ fd = -1;
347
+ ret = io_uring_register_files_update(&ring, off, &fd, 1);
348
+ assert(ret == 1);
349
+ ret = io_uring_wait_cqe(&ring, &cqe);
350
+ if (ret) {
351
+ fprintf(stderr, "io_uring wait ret=%d\n", ret);
352
+ return 1;
353
+ }
354
+ if (cqe->user_data != tags[off]) {
355
+ fprintf(stderr, "data %lx != %lx\n",
356
+ (unsigned long) cqe->user_data,
357
+ (unsigned long) tags[off]);
358
+ return 1;
359
+ }
360
+ io_uring_cqe_seen(&ring, cqe);
361
+
362
+ /* remove removed file, shouldn't emit old tag */
363
+ ret = io_uring_register_files_update(&ring, off, &fd, 1);
364
+ assert(ret <= 1);
365
+ assert(check_cq_empty(&ring));
366
+
367
+ /* non-zero tag with remove update is disallowed */
368
+ tag = 1;
369
+ fd = -1;
370
+ ret = update_rsrc(&ring, TEST_IORING_RSRC_FILE, 1, off + 1, &fd, &tag);
371
+ assert(ret);
372
+
373
+ io_uring_queue_exit(&ring);
374
+ return 0;
375
+ }
376
+
377
+ static int test_notag(void)
378
+ {
379
+ struct io_uring_cqe *cqe = NULL;
380
+ struct io_uring ring;
381
+ int i, ret, fd;
382
+ const int nr = 50;
383
+ int files[nr];
384
+
385
+ ret = io_uring_queue_init(1, &ring, 0);
386
+ if (ret) {
387
+ printf("ring setup failed\n");
388
+ return 1;
389
+ }
390
+ for (i = 0; i < nr; ++i)
391
+ files[i] = pipes[0];
392
+
393
+ ret = io_uring_register_files(&ring, files, nr);
394
+ assert(!ret);
395
+
396
+ /* default register, update shouldn't emit CQE */
397
+ fd = -1;
398
+ ret = io_uring_register_files_update(&ring, 0, &fd, 1);
399
+ assert(ret == 1);
400
+ assert(check_cq_empty(&ring));
401
+
402
+ ret = io_uring_unregister_files(&ring);
403
+ assert(!ret);
404
+ ret = io_uring_peek_cqe(&ring, &cqe); /* nothing should be there */
405
+ assert(ret);
406
+
407
+ io_uring_queue_exit(&ring);
408
+ return 0;
409
+ }
410
+
411
+ int main(int argc, char *argv[])
412
+ {
413
+ int ring_flags[] = {0, IORING_SETUP_IOPOLL, IORING_SETUP_SQPOLL,
414
+ IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN};
415
+ int i, ret;
416
+
417
+ if (argc > 1)
418
+ return 0;
419
+ if (!has_rsrc_update()) {
420
+ fprintf(stderr, "doesn't support rsrc tags, skip\n");
421
+ return 0;
422
+ }
423
+
424
+ if (pipe(pipes) < 0) {
425
+ perror("pipe");
426
+ return 1;
427
+ }
428
+
429
+ ret = test_notag();
430
+ if (ret) {
431
+ printf("test_notag failed\n");
432
+ return ret;
433
+ }
434
+
435
+ for (i = 0; i < sizeof(ring_flags) / sizeof(ring_flags[0]); i++) {
436
+ int flag = ring_flags[i];
437
+
438
+ if (flag & IORING_SETUP_DEFER_TASKRUN && !t_probe_defer_taskrun())
439
+ continue;
440
+
441
+ ret = test_files(flag);
442
+ if (ret) {
443
+ printf("test_tag failed, type %i\n", i);
444
+ return ret;
445
+ }
446
+ }
447
+
448
+ ret = test_buffers_update();
449
+ if (ret) {
450
+ printf("test_buffers_update failed\n");
451
+ return ret;
452
+ }
453
+
454
+ ret = test_buffers_empty_buffers();
455
+ if (ret) {
456
+ printf("test_buffers_empty_buffers failed\n");
457
+ return ret;
458
+ }
459
+
460
+ return 0;
461
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env bash
2
+
3
+ TESTS=("$@")
4
+ ITER=0
5
+
6
+ while true; do
7
+ ./runtests.sh "${TESTS[@]}"
8
+ RET="$?"
9
+ if [ "${RET}" -ne 0 ]; then
10
+ echo "Tests failed at loop $ITER"
11
+ break
12
+ fi
13
+ echo "Finished loop $ITER"
14
+ ((ITER++))
15
+ done
16
+
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+
3
+ TESTS=("$@")
4
+ RESULT_FILE=$(mktemp)
5
+ ./runtests.sh "${TESTS[@]}" > "$RESULT_FILE" 2>&1
6
+ RET="$?"
7
+ if [ "${RET}" -ne 0 ]; then
8
+ cat "$RESULT_FILE"
9
+ fi
10
+ rm "$RESULT_FILE"
11
+ exit $RET
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env bash
2
+
3
+ TESTS=("$@")
4
+ TIMEOUT=60
5
+ DMESG_FILTER="cat"
6
+ TEST_DIR=$(dirname "$0")
7
+ FAILED=()
8
+ SKIPPED=()
9
+ TIMED_OUT=()
10
+ TEST_FILES=""
11
+ declare -A TEST_MAP
12
+
13
+ # Only use /dev/kmsg if running as root
14
+ DO_KMSG="1"
15
+ [ "$(id -u)" != "0" ] && DO_KMSG="0"
16
+
17
+ # Include config.local if exists and check TEST_FILES for valid devices
18
+ if [ -f "$TEST_DIR/config.local" ]; then
19
+ # shellcheck source=/dev/null disable=SC1091
20
+ . "$TEST_DIR/config.local"
21
+ for dev in $TEST_FILES; do
22
+ if [ ! -e "$dev" ]; then
23
+ echo "Test file $dev not valid"
24
+ exit 1
25
+ fi
26
+ done
27
+ for dev in "${TEST_MAP[@]}"; do
28
+ if [ ! -e "$dev" ]; then
29
+ echo "Test file in map $dev not valid"
30
+ exit 1
31
+ fi
32
+ done
33
+ fi
34
+
35
+ _check_dmesg()
36
+ {
37
+ local dmesg_marker="$1"
38
+ local seqres="$2.seqres"
39
+
40
+ if [ "$DO_KMSG" -eq 0 ]; then
41
+ return 0
42
+ fi
43
+
44
+ dmesg | bash -c "$DMESG_FILTER" | grep -A 9999 "$dmesg_marker" >"${seqres}.dmesg"
45
+ grep -q -e "kernel BUG at" \
46
+ -e "WARNING:" \
47
+ -e "BUG:" \
48
+ -e "Oops:" \
49
+ -e "possible recursive locking detected" \
50
+ -e "Internal error" \
51
+ -e "INFO: suspicious RCU usage" \
52
+ -e "INFO: possible circular locking dependency detected" \
53
+ -e "general protection fault:" \
54
+ -e "blktests failure" \
55
+ "${seqres}.dmesg"
56
+ # shellcheck disable=SC2181
57
+ if [[ $? -eq 0 ]]; then
58
+ return 1
59
+ else
60
+ rm -f "${seqres}.dmesg"
61
+ return 0
62
+ fi
63
+ }
64
+
65
+ run_test()
66
+ {
67
+ local test_name="$1"
68
+ local dev="$2"
69
+ local test_exec=("./$test_name")
70
+ local test_string="$test_name"
71
+ local out_name="$test_name"
72
+
73
+ # Specify test string to print
74
+ if [ -n "$dev" ]; then
75
+ test_exec+=("$dev")
76
+ test_string="$test_name $dev"
77
+ local suffix
78
+ suffix=$(basename "$dev")
79
+ out_name="$out_name.$suffix"
80
+ fi
81
+
82
+ # Log start of the test
83
+ if [ "$DO_KMSG" -eq 1 ]; then
84
+ local dmesg_marker="Running test $test_string:"
85
+ echo "$dmesg_marker" > /dev/kmsg
86
+ else
87
+ local dmesg_marker=""
88
+ fi
89
+ printf "Running test %-55s" "$test_string"
90
+
91
+ # Do we have to exclude the test ?
92
+ echo "$TEST_EXCLUDE" | grep -w "$test_name" > /dev/null 2>&1
93
+ # shellcheck disable=SC2181
94
+ if [ $? -eq 0 ]; then
95
+ echo "Test skipped"
96
+ SKIPPED+=("<$test_string>")
97
+ return
98
+ fi
99
+
100
+ # Run the test
101
+ T_START=$(date +%s)
102
+ timeout -s INT -k $TIMEOUT $TIMEOUT "${test_exec[@]}"
103
+ local status=$?
104
+ T_END=$(date +%s)
105
+
106
+ if [ -e ./core ]; then
107
+ mv core "core-$test_name"
108
+ fi
109
+
110
+ # Check test status
111
+ if [ "$status" -eq 124 ]; then
112
+ echo "Test $test_name timed out (may not be a failure)"
113
+ TIMED_OUT+=("<$test_string>")
114
+ elif [ "$status" -eq 77 ]; then
115
+ echo "Skipped"
116
+ SKIPPED+=("<$test_string>")
117
+ elif [ "$status" -ne 0 ]; then
118
+ echo "Test $test_name failed with ret $status"
119
+ FAILED+=("<$test_string>")
120
+ elif ! _check_dmesg "$dmesg_marker" "$test_name"; then
121
+ echo "Test $test_name failed dmesg check"
122
+ FAILED+=("<$test_string>")
123
+ else
124
+ if [ -f "output/$out_name" ]; then
125
+ T_PREV=$(cat "output/$out_name")
126
+ else
127
+ T_PREV=""
128
+ fi
129
+ T_DIFF=$((T_END-T_START))
130
+ if [ -n "$T_PREV" ]; then
131
+ echo "$T_DIFF sec [$T_PREV]"
132
+ else
133
+ echo "$T_DIFF sec"
134
+ fi
135
+ echo $T_DIFF > "output/$out_name"
136
+ fi
137
+ }
138
+
139
+ # Run all specified tests
140
+ for tst in "${TESTS[@]}"; do
141
+ if [ ! -d output ]; then
142
+ mkdir -p output
143
+ fi
144
+ if [ -z "${TEST_MAP[$tst]}" ]; then
145
+ run_test "$tst"
146
+ if [ -n "$TEST_FILES" ]; then
147
+ for dev in $TEST_FILES; do
148
+ run_test "$tst" "$dev"
149
+ done
150
+ fi
151
+ else
152
+ run_test "$tst" "${TEST_MAP[$tst]}"
153
+ fi
154
+ done
155
+
156
+ if [ "${#TIMED_OUT[*]}" -ne 0 ]; then
157
+ echo "Tests timed out (${#TIMED_OUT[*]}): ${TIMED_OUT[*]}"
158
+ fi
159
+
160
+ if [ "${#FAILED[*]}" -ne 0 ]; then
161
+ echo "Tests failed (${#FAILED[*]}): ${FAILED[*]}"
162
+ exit 1
163
+ elif [ "${#SKIPPED[*]}" -ne 0 ] && [ -n "$TEST_GNU_EXITCODE" ]; then
164
+ exit 77
165
+ else
166
+ echo "All tests passed"
167
+ exit 0
168
+ fi