aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/liburing
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2024-11-09 19:14:48 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2024-11-09 19:25:43 +0300
commit9ade466e8683a2e3b45dacf45f74fcf4a3c40cee (patch)
tree5386d43454d677cb1239ed7a889dfcf101e99136 /contrib/libs/liburing
parent1f59ab019232ff97a73c7c13736b254925fa8b0b (diff)
downloadydb-9ade466e8683a2e3b45dacf45f74fcf4a3c40cee.tar.gz
Update contrib/libs/liburing to 2.8
commit_hash:761e2e80642a3d32073f0261b3f5b1992e54a74f
Diffstat (limited to 'contrib/libs/liburing')
-rw-r--r--contrib/libs/liburing/.yandex_meta/devtools.licenses.report16
-rw-r--r--contrib/libs/liburing/.yandex_meta/override.nix4
-rw-r--r--contrib/libs/liburing/CHANGELOG16
-rw-r--r--contrib/libs/liburing/CONTRIBUTING.md165
-rw-r--r--contrib/libs/liburing/src/include/liburing.h62
-rw-r--r--contrib/libs/liburing/src/include/liburing/compat.h7
-rw-r--r--contrib/libs/liburing/src/include/liburing/io_uring.h101
-rw-r--r--contrib/libs/liburing/src/include/liburing/io_uring_version.h2
-rw-r--r--contrib/libs/liburing/src/include/liburing/sanitize.h39
-rw-r--r--contrib/libs/liburing/src/int_flags.h13
-rw-r--r--contrib/libs/liburing/src/liburing.map8
-rw-r--r--contrib/libs/liburing/src/queue.c72
-rw-r--r--contrib/libs/liburing/src/register.c42
-rw-r--r--contrib/libs/liburing/src/setup.c24
-rw-r--r--contrib/libs/liburing/test/232c93d07b74.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/35fa71a030ca.c7
-rw-r--r--contrib/libs/liburing/test/35fa71a030ca.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/500f9fbadef8.c2
-rw-r--r--contrib/libs/liburing/test/500f9fbadef8.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/7ad0e4b2f83c.c25
-rw-r--r--contrib/libs/liburing/test/7ad0e4b2f83c.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/8a9973408177.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/917257daa0fe.c7
-rw-r--r--contrib/libs/liburing/test/917257daa0fe.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/a0908ae19763.c7
-rw-r--r--contrib/libs/liburing/test/a0908ae19763.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/a4c0b3decb33.c7
-rw-r--r--contrib/libs/liburing/test/a4c0b3decb33.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/accept-link.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/accept-non-empty.c84
-rw-r--r--contrib/libs/liburing/test/accept-non-empty.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/accept-reuse.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/accept-test.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/accept.c18
-rw-r--r--contrib/libs/liburing/test/accept.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/across-fork.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/b19062a56726.c7
-rw-r--r--contrib/libs/liburing/test/b19062a56726.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/b5837bd5311d.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/bind-listen.c4
-rw-r--r--contrib/libs/liburing/test/bind-listen.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/buf-ring-nommap.c13
-rw-r--r--contrib/libs/liburing/test/buf-ring-nommap.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/buf-ring-put.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/buf-ring.c2
-rw-r--r--contrib/libs/liburing/test/buf-ring.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/ce593a6c480a.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/close-opath.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/cmd-discard.c426
-rw-r--r--contrib/libs/liburing/test/cmd-discard.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/connect-rep.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/connect.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/coredump.c7
-rw-r--r--contrib/libs/liburing/test/coredump.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/cq-full.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/cq-overflow.c14
-rw-r--r--contrib/libs/liburing/test/cq-overflow.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/cq-peek-batch.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/cq-ready.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/cq-size.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/d4ae271dfaae.c14
-rw-r--r--contrib/libs/liburing/test/d4ae271dfaae.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/d77a67ed5f27.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/defer-taskrun.c4
-rw-r--r--contrib/libs/liburing/test/defer-taskrun.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/defer-tw-timeout.c5
-rw-r--r--contrib/libs/liburing/test/defer-tw-timeout.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/defer.c4
-rw-r--r--contrib/libs/liburing/test/defer.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/double-poll-crash.c2
-rw-r--r--contrib/libs/liburing/test/double-poll-crash.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/drop-submit.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/eeed8b54e0df.c2
-rw-r--r--contrib/libs/liburing/test/eeed8b54e0df.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/empty-eownerdead.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/eploop.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/eventfd-disable.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/eventfd-reg.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/eventfd-ring.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/eventfd.c1
-rw-r--r--contrib/libs/liburing/test/eventfd.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/evloop.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/exec-target.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/exit-no-cleanup.c11
-rw-r--r--contrib/libs/liburing/test/exit-no-cleanup.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fadvise.c35
-rw-r--r--contrib/libs/liburing/test/fadvise.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fallocate.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fc2a85cb02ef.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fd-install.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fd-pass.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fdinfo.c428
-rw-r--r--contrib/libs/liburing/test/fdinfo.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/fifo-nonblock-read.c70
-rw-r--r--contrib/libs/liburing/test/fifo-nonblock-read.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/file-register.c16
-rw-r--r--contrib/libs/liburing/test/file-register.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/file-update.c2
-rw-r--r--contrib/libs/liburing/test/file-update.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/file-verify.c43
-rw-r--r--contrib/libs/liburing/test/file-verify.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/files-exit-hang-poll.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/files-exit-hang-timeout.c3
-rw-r--r--contrib/libs/liburing/test/files-exit-hang-timeout.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fixed-buf-iter.c4
-rw-r--r--contrib/libs/liburing/test/fixed-buf-iter.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fixed-buf-merge.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fixed-hugepage.c13
-rw-r--r--contrib/libs/liburing/test/fixed-hugepage.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fixed-link.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fixed-reuse.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fpos.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/fsync.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/futex.c20
-rw-r--r--contrib/libs/liburing/test/futex.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/hardlink.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/helpers.c47
-rw-r--r--contrib/libs/liburing/test/helpers.h6
-rw-r--r--contrib/libs/liburing/test/ignore-single-mmap.c2
-rw-r--r--contrib/libs/liburing/test/ignore-single-mmap.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/init-mem.c10
-rw-r--r--contrib/libs/liburing/test/init-mem.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/io-cancel.c24
-rw-r--r--contrib/libs/liburing/test/io-cancel.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/io_uring_enter.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/io_uring_passthrough.c4
-rw-r--r--contrib/libs/liburing/test/io_uring_passthrough.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/io_uring_register.c46
-rw-r--r--contrib/libs/liburing/test/io_uring_register.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/io_uring_setup.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/iopoll-leak.c4
-rw-r--r--contrib/libs/liburing/test/iopoll-leak.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/iopoll-overflow.c2
-rw-r--r--contrib/libs/liburing/test/iopoll-overflow.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/iopoll.c6
-rw-r--r--contrib/libs/liburing/test/iopoll.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/kallsyms.c204
-rw-r--r--contrib/libs/liburing/test/kallsyms.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/lfs-openat-write.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/lfs-openat.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/link-timeout.c159
-rw-r--r--contrib/libs/liburing/test/link-timeout.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/link.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/link_drain.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/linked-defer-close.c225
-rw-r--r--contrib/libs/liburing/test/linked-defer-close.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/madvise.c37
-rw-r--r--contrib/libs/liburing/test/madvise.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/min-timeout-wait.c330
-rw-r--r--contrib/libs/liburing/test/min-timeout-wait.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/min-timeout.c209
-rw-r--r--contrib/libs/liburing/test/min-timeout.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/mkdir.c6
-rw-r--r--contrib/libs/liburing/test/mkdir.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/msg-ring-fd.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/msg-ring-flags.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/msg-ring-overflow.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/msg-ring.c10
-rw-r--r--contrib/libs/liburing/test/msg-ring.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/multicqes_drain.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/napi-test.c229
-rw-r--r--contrib/libs/liburing/test/napi-test.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/no-mmap-inval.c2
-rw-r--r--contrib/libs/liburing/test/no-mmap-inval.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/nolibc.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/nop-all-sizes.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/nop.c44
-rw-r--r--contrib/libs/liburing/test/nop.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/ooo-file-unreg.c2
-rw-r--r--contrib/libs/liburing/test/ooo-file-unreg.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/open-close.c40
-rw-r--r--contrib/libs/liburing/test/open-close.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/open-direct-link.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/open-direct-pick.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/openat2.c51
-rw-r--r--contrib/libs/liburing/test/openat2.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/personality.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/pipe-bug.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/pipe-eof.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/pipe-reuse.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-cancel-all.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-cancel-ton.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-cancel.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-link.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-many.c20
-rw-r--r--contrib/libs/liburing/test/poll-many.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-mshot-overflow.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-mshot-update.c27
-rw-r--r--contrib/libs/liburing/test/poll-mshot-update.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-race-mshot.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-race.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-ring.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll-v-poll.c9
-rw-r--r--contrib/libs/liburing/test/poll-v-poll.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/poll.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/pollfree.c149
-rw-r--r--contrib/libs/liburing/test/pollfree.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/probe.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/read-before-exit.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/read-mshot-empty.c7
-rw-r--r--contrib/libs/liburing/test/read-mshot-empty.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/read-mshot-stdin.c122
-rw-r--r--contrib/libs/liburing/test/read-mshot-stdin.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/read-mshot.c309
-rw-r--r--contrib/libs/liburing/test/read-mshot.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/read-write.c91
-rw-r--r--contrib/libs/liburing/test/read-write.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/recv-msgall-stream.c3
-rw-r--r--contrib/libs/liburing/test/recv-msgall-stream.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/recv-msgall.c5
-rw-r--r--contrib/libs/liburing/test/recv-msgall.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/recv-multishot.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/recvsend_bundle-inc.c681
-rw-r--r--contrib/libs/liburing/test/recvsend_bundle-inc.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/recvsend_bundle.c123
-rw-r--r--contrib/libs/liburing/test/recvsend_bundle.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/reg-fd-only.c20
-rw-r--r--contrib/libs/liburing/test/reg-fd-only.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/reg-hint.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/reg-reg-ring.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/regbuf-clone.c248
-rw-r--r--contrib/libs/liburing/test/regbuf-clone.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/regbuf-merge.c7
-rw-r--r--contrib/libs/liburing/test/regbuf-merge.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/register-restrictions.c171
-rw-r--r--contrib/libs/liburing/test/register-restrictions.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/rename.c60
-rw-r--r--contrib/libs/liburing/test/rename.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/ring-leak.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/ring-leak2.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/ringbuf-read.c5
-rw-r--r--contrib/libs/liburing/test/ringbuf-read.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/ringbuf-status.c6
-rw-r--r--contrib/libs/liburing/test/ringbuf-status.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/rsrc_tags.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/rw_merge_test.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/self.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/send-zerocopy.c62
-rw-r--r--contrib/libs/liburing/test/send-zerocopy.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/send_recv.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/send_recvmsg.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/shared-wq.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/short-read.c1
-rw-r--r--contrib/libs/liburing/test/short-read.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/shutdown.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sigfd-deadlock.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/single-issuer.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/skip-cqe.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/socket-getsetsock-cmd.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/socket-io-cmd.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/socket-rw-eagain.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/socket-rw-offset.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/socket-rw.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/socket.c43
-rw-r--r--contrib/libs/liburing/test/socket.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/splice.c4
-rw-r--r--contrib/libs/liburing/test/splice.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sq-full-cpp.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sq-full.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sq-poll-dup.c2
-rw-r--r--contrib/libs/liburing/test/sq-poll-dup.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sq-poll-kthread.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sq-poll-share.c2
-rw-r--r--contrib/libs/liburing/test/sq-poll-share.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sq-space_left.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sqpoll-disable-exit.c8
-rw-r--r--contrib/libs/liburing/test/sqpoll-disable-exit.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sqpoll-exec.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sqpoll-exit-hang.c26
-rw-r--r--contrib/libs/liburing/test/sqpoll-exit-hang.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sqpoll-sleep.c26
-rw-r--r--contrib/libs/liburing/test/sqpoll-sleep.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sqwait.c137
-rw-r--r--contrib/libs/liburing/test/sqwait.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/stdout.c2
-rw-r--r--contrib/libs/liburing/test/stdout.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/submit-and-wait.c26
-rw-r--r--contrib/libs/liburing/test/submit-and-wait.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/submit-link-fail.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/submit-reuse.c30
-rw-r--r--contrib/libs/liburing/test/submit-reuse.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/symlink.c13
-rw-r--r--contrib/libs/liburing/test/symlink.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/sync-cancel.c78
-rw-r--r--contrib/libs/liburing/test/sync-cancel.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/teardowns.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/thread-exit.c5
-rw-r--r--contrib/libs/liburing/test/thread-exit.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/timeout-new.c27
-rw-r--r--contrib/libs/liburing/test/timeout-new.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/timeout.c38
-rw-r--r--contrib/libs/liburing/test/timeout.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/truncate.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/tty-write-dpoll.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/unlink.c95
-rw-r--r--contrib/libs/liburing/test/unlink.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/uring_cmd_ublk.c1253
-rw-r--r--contrib/libs/liburing/test/uring_cmd_ublk.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/version.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/wait-timeout.c288
-rw-r--r--contrib/libs/liburing/test/wait-timeout.t/ya.make35
-rw-r--r--contrib/libs/liburing/test/waitid.c70
-rw-r--r--contrib/libs/liburing/test/waitid.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/wakeup-hang.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/wq-aff.c35
-rw-r--r--contrib/libs/liburing/test/wq-aff.t/ya.make2
-rw-r--r--contrib/libs/liburing/test/xattr.t/ya.make2
-rw-r--r--contrib/libs/liburing/ya.make19
308 files changed, 7966 insertions, 847 deletions
diff --git a/contrib/libs/liburing/.yandex_meta/devtools.licenses.report b/contrib/libs/liburing/.yandex_meta/devtools.licenses.report
index 94c6020f32..5677bdabba 100644
--- a/contrib/libs/liburing/.yandex_meta/devtools.licenses.report
+++ b/contrib/libs/liburing/.yandex_meta/devtools.licenses.report
@@ -87,6 +87,7 @@ BELONGS ya.make
src/include/liburing/barrier.h [1:1]
src/include/liburing/compat.h [1:1]
src/include/liburing/io_uring_version.h [1:1]
+ src/include/liburing/sanitize.h [1:1]
src/int_flags.h [1:1]
src/lib.h [1:1]
src/nolibc.c [2:2]
@@ -118,6 +119,7 @@ BELONGS ya.make
test/buf-ring-put.c [2:2]
test/buf-ring.c [2:2]
test/ce593a6c480a.c [2:2]
+ test/cmd-discard.c [2:2]
test/connect-rep.c [2:2]
test/connect.c [2:2]
test/coredump.c [2:2]
@@ -147,6 +149,8 @@ BELONGS ya.make
test/fc2a85cb02ef.c [2:2]
test/fd-install.c [2:2]
test/fd-pass.c [2:2]
+ test/fdinfo.c [2:2]
+ test/fifo-nonblock-read.c [2:2]
test/file-register.c [2:2]
test/file-update.c [2:2]
test/file-verify.c [2:2]
@@ -173,18 +177,23 @@ BELONGS ya.make
test/iopoll-leak.c [2:2]
test/iopoll-overflow.c [2:2]
test/iopoll.c [2:2]
+ test/kallsyms.c [2:2]
test/lfs-openat-write.c [2:2]
test/lfs-openat.c [2:2]
test/link-timeout.c [2:2]
test/link.c [2:2]
test/link_drain.c [2:2]
+ test/linked-defer-close.c [2:2]
test/madvise.c [2:2]
+ test/min-timeout-wait.c [2:2]
+ test/min-timeout.c [2:2]
test/mkdir.c [2:2]
test/msg-ring-fd.c [2:2]
test/msg-ring-flags.c [2:2]
test/msg-ring-overflow.c [2:2]
test/msg-ring.c [2:2]
test/multicqes_drain.c [2:2]
+ test/napi-test.c [2:2]
test/no-mmap-inval.c [2:2]
test/nolibc.c [2:2]
test/nop-all-sizes.c [2:2]
@@ -209,17 +218,21 @@ BELONGS ya.make
test/poll-ring.c [2:2]
test/poll-v-poll.c [2:2]
test/poll.c [2:2]
+ test/pollfree.c [2:2]
test/probe.c [2:2]
test/read-before-exit.c [2:2]
test/read-mshot-empty.c [2:2]
+ test/read-mshot-stdin.c [2:2]
test/read-mshot.c [2:2]
test/read-write.c [2:2]
test/recv-msgall-stream.c [2:2]
test/recv-msgall.c [2:2]
+ test/recvsend_bundle-inc.c [2:2]
test/recvsend_bundle.c [2:2]
test/reg-fd-only.c [2:2]
test/reg-hint.c [2:2]
test/reg-reg-ring.c [2:2]
+ test/regbuf-clone.c [2:2]
test/regbuf-merge.c [2:2]
test/register-restrictions.c [2:2]
test/rename.c [2:2]
@@ -256,6 +269,7 @@ BELONGS ya.make
test/sqpoll-exec.c [2:2]
test/sqpoll-exit-hang.c [2:2]
test/sqpoll-sleep.c [2:2]
+ test/sqwait.c [2:2]
test/stdout.c [2:2]
test/submit-and-wait.c [2:2]
test/submit-link-fail.c [2:2]
@@ -270,7 +284,9 @@ BELONGS ya.make
test/truncate.c [2:2]
test/tty-write-dpoll.c [2:2]
test/unlink.c [2:2]
+ test/uring_cmd_ublk.c [2:2]
test/version.c [2:2]
+ test/wait-timeout.c [2:2]
test/waitid.c [2:2]
test/wakeup-hang.c [2:2]
test/wq-aff.c [2:2]
diff --git a/contrib/libs/liburing/.yandex_meta/override.nix b/contrib/libs/liburing/.yandex_meta/override.nix
index afc13140e3..7118b3c759 100644
--- a/contrib/libs/liburing/.yandex_meta/override.nix
+++ b/contrib/libs/liburing/.yandex_meta/override.nix
@@ -1,12 +1,12 @@
pkgs: attrs: with pkgs; with attrs; rec {
name = "liburing";
- version = "2.7";
+ version = "2.8";
src = fetchFromGitHub {
owner = "axboe";
repo = "liburing";
rev = "liburing-${version}";
- hash = "sha256-WhNlO2opPM7v4LOLWpmzPv31++zmn5Hmb6Su9IQBDH8=";
+ hash = "sha256-10zmoMDzO41oNRVXE/6FzDGPVRVJTJTARVUmc1b7f+o=";
};
buildPhase = ''
diff --git a/contrib/libs/liburing/CHANGELOG b/contrib/libs/liburing/CHANGELOG
index 4eb15f38a4..ca1056ed4f 100644
--- a/contrib/libs/liburing/CHANGELOG
+++ b/contrib/libs/liburing/CHANGELOG
@@ -1,3 +1,19 @@
+liburing-2.8 release
+- Add support for incrementally/partially consumed provided buffers,
+ usable with the provided buffer ring support.
+- Add support for foo_and_wait_min_timeout(), where it's possible to
+ define a minimum timeout for waiting to get batches of completions,
+ but if that fails, extend for a longer timeout without having any
+ extra context switches.
+- Add support for using different clock sources for completion waiting.
+- Great increase coverage of test cases, test case improvements and
+ fixes.
+- Man page updates
+- Don't leak _GNU_SOURCE via pkb-config --cflags
+- Support for address sanitizer
+- Add examples/kdigest sample program
+- Add discard helper, test, and man page
+
liburing-2.7 release
- Man page updates
diff --git a/contrib/libs/liburing/CONTRIBUTING.md b/contrib/libs/liburing/CONTRIBUTING.md
new file mode 100644
index 0000000000..8bbce78a6c
--- /dev/null
+++ b/contrib/libs/liburing/CONTRIBUTING.md
@@ -0,0 +1,165 @@
+Introduction
+============
+
+liburing welcomes contributions, whether they be bug fixes, features, or
+documentation additions/updates. However, we do have some rules in place
+to govern the sanity of the project, and all contributions should follow
+the guidelines in this document. The main reasons for the rules are:
+
+1) Keep the code consistent
+2) Keep the git repository consistent
+3) Maintain bisectability
+
+Coding style
+============
+
+Generally, all the code in liburing should follow the same style. A few
+known exceptions exist, like syzbot test cases that got committed rather
+than re-writing them in a saner format. Any change you make, please
+follow the style of the code around you.
+
+Commit format
+=============
+
+Each commit should do one thing, and one thing only. If you find yourself,
+in the commit message, adding phrases like "Also do [...]" or "While in
+here [...]", then that's a sign that the change should have been split
+into multiple commits. If your change includes some refactoring of code to
+make your change possible, then that refactoring should be a separate
+commit, done first. That means this preparatory commit won't have any
+functional changes, and hence should be a no-op. It also means that your
+main commit, with the change that you actually care about, will be smaller
+and easier to review.
+
+Each commit must stand on its own in terms of what it provides, and how it
+works. Lots of changes are just a single commit, but for something a bit
+more involved, it's not uncommon to have a pull request contain multiple
+commits. Make each commit as simple as possible, and not any simpler. We'd
+much rather see 10 simple commits than 2 more complicated ones. If you
+stumble across something that needs fixing while making an unrelated
+change, then please make that change as a separate commit, explaining why
+it's being made.
+
+Each commit in a series must be buildable, it's not enough that the end
+result is buildable. See reason 3 in the introduction for why that's the
+case.
+
+No fixup commits! Sometimes people post a change and errors are pointed
+out in the commit, and the author then does a followup fix for that
+error. This isn't acceptable, please squash fixup commits into the
+commit that introduced the problem in the first place. This is done by
+amending the fix into the original commit that caused the issue. You can
+do that with git rebase -i <sha> and arrange the commit order such that
+the fixup is right after the original commit, and then use 's' (for
+squash) to squash the fixup into the original commit. Don't forget to
+edit the commit message while doing that, as git will combine the two
+commit messages into one. Or you can do it manually. Once done, force
+push your rewritten git history. See reasons 1-3 in the introduction
+series for why that is.
+
+Commit message
+==============
+
+A good commit explains the WHY of a commit - explain the reason for this
+commit to exist. Don't explain what the code in commit does, that should
+be readily apparent from just reading the code. If that isn't the case,
+then a comment in the code is going to be more useful than a lengthy
+explanation in the commit message. liburing commits use the following
+format:
+
+Title
+
+Body of commit
+
+Signed-off-by: ```My Identity <my@email.com>```
+
+That is, a descriptive title on the first line, then an empty line, then
+the body of the commit message, then an empty line, and finally an SOB
+tag. The signed-off-by exists to provide proof of origin, see the
+[DCO](https://developercertificate.org/).
+
+Example commit:
+
+```
+commit 0fe5c09195c0918f89582dd6ff098a58a0bdf62a
+Author: Jens Axboe <axboe@kernel.dk>
+Date: Fri Sep 6 15:54:04 2024 -0600
+
+ configure: fix ublk_cmd header check
+
+ The previous commit is mixing private structures and defines with public
+ uapi ones. Testing for UBLK_U_CMD_START_DEV is fine, CTRL_CMD_HAS_DATA
+ is not. And struct ublk_ctrl_cmd_data is not a public struct.
+
+ Fixes: 83bc535a3118 ("configure: don't enable ublk if modern commands not available")
+ Signed-off-by: Jens Axboe <axboe@kernel.dk>
+```
+
+Since this change is pretty trivial, a huge explanation need not be given
+as to the reasonings for the change. However, for more complicated
+changes, better reasonings should be given.
+
+A Fixes line can be added if this commit fixes an issue in a previous
+commit. That kind of meta data can be useful down the line for finding
+dependencies between commits. Adding the following to your .gitconfig:
+
+```
+[pretty]
+ fixes = Fixes: %h (\"%s\")
+```
+
+and running ```git fixes <sha>``` will then generate the correctly
+formatted Fixes line for the commit. Likewise, other meta data can be:
+
+Link: https://somesite/somewhere
+
+can be useful to link to a discussion around the issue that led to this
+commit, perhaps a bug report. This can be a GitHub issue as well. If a
+commit closes/solves a GitHub issue, than:
+
+Closes: https://github.com/axboe/liburing/issues/XXXX
+
+can also be used.
+
+Each commit message should be formatted so each full line is 72-74 chars
+wide. For many of us, GitHub is not the primary location, and git log is
+often used in a terminal to browse the repo. Breaking lines at 72-74
+characters retains readability in an xterm/terminal.
+
+Pull Requests
+=============
+
+The git repository itself is the canonical location for information. It's
+quite fine to provide a lengthy explanation for a pull request on GitHub,
+however please ensure that this doesn't come at the expense of the commit
+messages themselves being lacking. The commit messages should stand on
+their own and contain everything that you'd otherwise put in the PR
+message. If you've worked on projects that send patches before, consider
+the PR message similar to the cover letter for a series of patches.
+
+Most contributors seem to use GH for sending patches, which is fine. If
+you prefer using email, then patches can also be sent to the io_uring
+mailing list: io-uring@vger.kernel.org.
+
+liburing doesn't squash/rebase-on-merge, or other heinous practices
+sometimes seen elsewhere. Whatever sha your commit has in your tree is
+what it'll have in the upstream tree. Patches are applied directly, and
+pull requests are merged with a merge commit. If meta data needs to go
+into the merge commit, then it will go into the merge commit message.
+This means that you don't need to continually rebase your changes on top
+of the master branch.
+
+Testing changes
+===============
+
+You should ALWAYS test your changes, no matter how trivial or obviously
+correct they may seem. Nobody is infallible, and making mistakes is only
+human.
+
+liburing contains a wide variety of functional tests. If you make changes
+to liburing, then you should run the test cases. This is done by building
+the repo and running ```make runtests```. Note that some of the liburing
+tests test for defects in older kernels, and hence it's possible that they
+will crash on an outdated kernel that doesn't contain fixes from the
+stable kernel tree. If in doubt, building and running the tests in a vm is
+encouraged.
diff --git a/contrib/libs/liburing/src/include/liburing.h b/contrib/libs/liburing/src/include/liburing.h
index 1092f3b10b..6eae138975 100644
--- a/contrib/libs/liburing/src/include/liburing.h
+++ b/contrib/libs/liburing/src/include/liburing.h
@@ -19,6 +19,7 @@
#include "liburing/io_uring_version.h"
#include "liburing/barrier.h"
+
#ifndef uring_unlikely
#define uring_unlikely(cond) __builtin_expect(!!(cond), 0)
#endif
@@ -173,6 +174,12 @@ unsigned io_uring_peek_batch_cqe(struct io_uring *ring,
int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
unsigned wait_nr, struct __kernel_timespec *ts,
sigset_t *sigmask);
+int io_uring_wait_cqes_min_timeout(struct io_uring *ring,
+ struct io_uring_cqe **cqe_ptr,
+ unsigned wait_nr,
+ struct __kernel_timespec *ts,
+ unsigned int min_ts_usec,
+ sigset_t *sigmask);
int io_uring_wait_cqe_timeout(struct io_uring *ring,
struct io_uring_cqe **cqe_ptr,
struct __kernel_timespec *ts);
@@ -183,7 +190,14 @@ int io_uring_submit_and_wait_timeout(struct io_uring *ring,
unsigned wait_nr,
struct __kernel_timespec *ts,
sigset_t *sigmask);
+int io_uring_submit_and_wait_min_timeout(struct io_uring *ring,
+ struct io_uring_cqe **cqe_ptr,
+ unsigned wait_nr,
+ struct __kernel_timespec *ts,
+ unsigned min_wait,
+ sigset_t *sigmask);
+int io_uring_clone_buffers(struct io_uring *dst, struct io_uring *src);
int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs,
unsigned nr_iovecs);
int io_uring_register_buffers_tags(struct io_uring *ring,
@@ -220,8 +234,10 @@ int io_uring_register_restrictions(struct io_uring *ring,
unsigned int nr_res);
int io_uring_enable_rings(struct io_uring *ring);
int __io_uring_sqring_wait(struct io_uring *ring);
+#ifdef _GNU_SOURCE
int io_uring_register_iowq_aff(struct io_uring *ring, size_t cpusz,
const cpu_set_t *mask);
+#endif
int io_uring_unregister_iowq_aff(struct io_uring *ring);
int io_uring_register_iowq_max_workers(struct io_uring *ring,
unsigned int *values);
@@ -241,6 +257,9 @@ int io_uring_register_file_alloc_range(struct io_uring *ring,
int io_uring_register_napi(struct io_uring *ring, struct io_uring_napi *napi);
int io_uring_unregister_napi(struct io_uring *ring, struct io_uring_napi *napi);
+int io_uring_register_clock(struct io_uring *ring,
+ struct io_uring_clock_register *arg);
+
int io_uring_get_events(struct io_uring *ring);
int io_uring_submit_and_get_events(struct io_uring *ring);
@@ -262,7 +281,7 @@ int io_uring_register(unsigned int fd, unsigned int opcode, const void *arg,
struct io_uring_buf_ring *io_uring_setup_buf_ring(struct io_uring *ring,
unsigned int nentries,
int bgid, unsigned int flags,
- int *ret);
+ int *err);
int io_uring_free_buf_ring(struct io_uring *ring, struct io_uring_buf_ring *br,
unsigned int nentries, int bgid);
@@ -286,15 +305,22 @@ int __io_uring_get_cqe(struct io_uring *ring,
#define io_uring_cqe_index(ring,ptr,mask) \
(((ptr) & (mask)) << io_uring_cqe_shift(ring))
+/*
+ * NOTE: we should just get rid of the 'head' being passed in here, it doesn't
+ * serve a purpose anymore. The below is a bit of a work-around to ensure that
+ * the compiler doesn't complain about 'head' being unused (or only written,
+ * never read), as we use a local iterator for both the head and tail tracking.
+ */
#define io_uring_for_each_cqe(ring, head, cqe) \
/* \
* io_uring_smp_load_acquire() enforces the order of tail \
* and CQE reads. \
*/ \
- for (head = *(ring)->cq.khead; \
- (cqe = (head != io_uring_smp_load_acquire((ring)->cq.ktail) ? \
- &(ring)->cq.cqes[io_uring_cqe_index(ring, head, (ring)->cq.ring_mask)] : NULL)); \
- head++) \
+ for (__u32 __HEAD__ = (head) = *(ring)->cq.khead, \
+ __TAIL__ = io_uring_smp_load_acquire((ring)->cq.ktail); \
+ (cqe = ((head) != __TAIL__ ? \
+ &(ring)->cq.cqes[io_uring_cqe_index(ring, __HEAD__, (ring)->cq.ring_mask)] : NULL)); \
+ (head) = ++__HEAD__)
/*
* Must be called after io_uring_for_each_cqe()
@@ -719,6 +745,20 @@ IOURINGINLINE void io_uring_prep_openat_direct(struct io_uring_sqe *sqe,
__io_uring_set_target_fixed_file(sqe, file_index);
}
+IOURINGINLINE void io_uring_prep_open(struct io_uring_sqe *sqe,
+ const char *path, int flags, mode_t mode)
+{
+ io_uring_prep_openat(sqe, AT_FDCWD, path, flags, mode);
+}
+
+/* open directly into the fixed file table */
+IOURINGINLINE void io_uring_prep_open_direct(struct io_uring_sqe *sqe,
+ const char *path, int flags, mode_t mode,
+ unsigned file_index)
+{
+ io_uring_prep_openat_direct(sqe, AT_FDCWD, path, flags, mode, file_index);
+}
+
IOURINGINLINE void io_uring_prep_close(struct io_uring_sqe *sqe, int fd)
{
io_uring_prep_rw(IORING_OP_CLOSE, sqe, fd, NULL, 0, 0);
@@ -1244,11 +1284,23 @@ IOURINGINLINE void io_uring_prep_fixed_fd_install(struct io_uring_sqe *sqe,
sqe->install_fd_flags = flags;
}
+#ifdef _GNU_SOURCE
IOURINGINLINE void io_uring_prep_ftruncate(struct io_uring_sqe *sqe,
int fd, loff_t len)
{
io_uring_prep_rw(IORING_OP_FTRUNCATE, sqe, fd, 0, 0, len);
}
+#endif
+
+IOURINGINLINE void io_uring_prep_cmd_discard(struct io_uring_sqe *sqe,
+ int fd,
+ uint64_t offset, uint64_t nbytes)
+{
+ io_uring_prep_rw(IORING_OP_URING_CMD, sqe, fd, 0, 0, 0);
+ sqe->cmd_op = BLOCK_URING_CMD_DISCARD;
+ sqe->addr = offset;
+ sqe->addr3 = nbytes;
+}
/*
* Returns number of unconsumed (if SQPOLL) or unsubmitted entries exist in
diff --git a/contrib/libs/liburing/src/include/liburing/compat.h b/contrib/libs/liburing/src/include/liburing/compat.h
index 717f81cb7f..6a5678beae 100644
--- a/contrib/libs/liburing/src/include/liburing/compat.h
+++ b/contrib/libs/liburing/src/include/liburing/compat.h
@@ -8,4 +8,11 @@
#include <linux/openat2.h>
+
+#include <linux/ioctl.h>
+
+#ifndef BLOCK_URING_CMD_DISCARD
+#define BLOCK_URING_CMD_DISCARD _IO(0x12, 0)
+#endif
+
#endif
diff --git a/contrib/libs/liburing/src/include/liburing/io_uring.h b/contrib/libs/liburing/src/include/liburing/io_uring.h
index 01c36a83f3..4ac13f7327 100644
--- a/contrib/libs/liburing/src/include/liburing/io_uring.h
+++ b/contrib/libs/liburing/src/include/liburing/io_uring.h
@@ -116,7 +116,7 @@ struct io_uring_sqe {
*/
#define IORING_FILE_INDEX_ALLOC (~0U)
-enum {
+enum io_uring_sqe_flags_bit {
IOSQE_FIXED_FILE_BIT,
IOSQE_IO_DRAIN_BIT,
IOSQE_IO_LINK_BIT,
@@ -184,7 +184,7 @@ enum {
#define IORING_SETUP_DEFER_TASKRUN (1U << 13)
/*
- * Application provides ring memory
+ * Application provides the memory for the rings
*/
#define IORING_SETUP_NO_MMAP (1U << 14)
@@ -265,11 +265,12 @@ enum io_uring_op {
};
/*
- * sqe->uring_cmd_flags
+ * sqe->uring_cmd_flags top 8bits aren't available for userspace
* IORING_URING_CMD_FIXED use registered buffer; pass this flag
* along with setting sqe->buf_index.
*/
#define IORING_URING_CMD_FIXED (1U << 0)
+#define IORING_URING_CMD_MASK IORING_URING_CMD_FIXED
/*
@@ -317,15 +318,19 @@ enum io_uring_op {
* ASYNC_CANCEL flags.
*
* IORING_ASYNC_CANCEL_ALL Cancel all requests that match the given key
- * IORING_ASYNC_CANCEL_FD Key off 'fd' for cancelation rather than the
+ * IORING_ASYNC_CANCEL_FD Key off 'fd' for cancelation rather than the
* request 'user_data'
* IORING_ASYNC_CANCEL_ANY Match any request
* IORING_ASYNC_CANCEL_FD_FIXED 'fd' passed in is a fixed descriptor
+ * IORING_ASYNC_CANCEL_USERDATA Match on user_data, default for no other key
+ * IORING_ASYNC_CANCEL_OP Match request based on opcode
*/
#define IORING_ASYNC_CANCEL_ALL (1U << 0)
#define IORING_ASYNC_CANCEL_FD (1U << 1)
#define IORING_ASYNC_CANCEL_ANY (1U << 2)
#define IORING_ASYNC_CANCEL_FD_FIXED (1U << 3)
+#define IORING_ASYNC_CANCEL_USERDATA (1U << 4)
+#define IORING_ASYNC_CANCEL_OP (1U << 5)
/*
* send/sendmsg and recv/recvmsg flags (sqe->ioprio)
@@ -350,13 +355,13 @@ enum io_uring_op {
* IORING_NOTIF_USAGE_ZC_COPIED if data was copied
* (at least partially).
*
- * IORING_RECVSEND_BUNDLE Used with IOSQE_BUFFER_SELECT. If set, send wil
- * grab as many buffers from the buffer group ID
- * given and send them all. The completion result
- * will be the number of buffers send, with the
- * starting buffer ID in cqe->flags as per usual
- * for provided buffer usage. The buffers will be
- * contigious from the starting buffer ID.
+ * IORING_RECVSEND_BUNDLE Used with IOSQE_BUFFER_SELECT. If set, send or
+ * recv will grab as many buffers from the buffer
+ * group ID given and send them all. The completion
+ * result will be the number of buffers send, with
+ * the starting buffer ID in cqe->flags as per
+ * usual for provided buffer usage. The buffers
+ * will be contiguous from the starting buffer ID.
*/
#define IORING_RECVSEND_POLL_FIRST (1U << 0)
#define IORING_RECV_MULTISHOT (1U << 1)
@@ -383,7 +388,7 @@ enum io_uring_op {
/*
* IORING_OP_MSG_RING command types, stored in sqe->addr
*/
-enum {
+enum io_uring_msg_ring_flags {
IORING_MSG_DATA, /* pass sqe->len as 'res' and off as user_data */
IORING_MSG_SEND_FD, /* send a registered fd to another ring */
};
@@ -416,7 +421,7 @@ enum {
* IO completion data structure (Completion Queue Entry)
*/
struct io_uring_cqe {
- __u64 user_data; /* sqe->user_data value passed back */
+ __u64 user_data; /* sqe->user_data submission passed back */
__s32 res; /* result code for this event */
__u32 flags;
@@ -435,15 +440,23 @@ struct io_uring_cqe {
* IORING_CQE_F_SOCK_NONEMPTY If set, more data to read after socket recv
* IORING_CQE_F_NOTIF Set for notification CQEs. Can be used to distinct
* them from sends.
+ * IORING_CQE_F_BUF_MORE If set, the buffer ID set in the completion will get
+ * more completions. In other words, the buffer is being
+ * partially consumed, and will be used by the kernel for
+ * more completions. This is only set for buffers used via
+ * the incremental buffer consumption, as provided by
+ * a ring buffer setup with IOU_PBUF_RING_INC. For any
+ * other provided buffer type, all completions with a
+ * buffer passed back is automatically returned to the
+ * application.
*/
#define IORING_CQE_F_BUFFER (1U << 0)
#define IORING_CQE_F_MORE (1U << 1)
#define IORING_CQE_F_SOCK_NONEMPTY (1U << 2)
#define IORING_CQE_F_NOTIF (1U << 3)
+#define IORING_CQE_F_BUF_MORE (1U << 4)
-enum {
- IORING_CQE_BUFFER_SHIFT = 16,
-};
+#define IORING_CQE_BUFFER_SHIFT 16
/*
* Magic offsets for the application to mmap the data it needs
@@ -504,6 +517,7 @@ struct io_cqring_offsets {
#define IORING_ENTER_SQ_WAIT (1U << 2)
#define IORING_ENTER_EXT_ARG (1U << 3)
#define IORING_ENTER_REGISTERED_RING (1U << 4)
+#define IORING_ENTER_ABS_TIMER (1U << 5)
/*
* Passed in for io_uring_setup(2). Copied back with updated info on success
@@ -539,11 +553,12 @@ struct io_uring_params {
#define IORING_FEAT_LINKED_FILE (1U << 12)
#define IORING_FEAT_REG_REG_RING (1U << 13)
#define IORING_FEAT_RECVSEND_BUNDLE (1U << 14)
+#define IORING_FEAT_MIN_TIMEOUT (1U << 15)
/*
* io_uring_register(2) opcodes and arguments
*/
-enum {
+enum io_uring_register_op {
IORING_REGISTER_BUFFERS = 0,
IORING_UNREGISTER_BUFFERS = 1,
IORING_REGISTER_FILES = 2,
@@ -592,6 +607,11 @@ enum {
IORING_REGISTER_NAPI = 27,
IORING_UNREGISTER_NAPI = 28,
+ IORING_REGISTER_CLOCK = 29,
+
+ /* clone registered buffers from source ring to current ring */
+ IORING_REGISTER_CLONE_BUFFERS = 30,
+
/* this goes last */
IORING_REGISTER_LAST,
@@ -600,7 +620,7 @@ enum {
};
/* io-wq worker categories */
-enum {
+enum io_wq_type {
IO_WQ_BOUND,
IO_WQ_UNBOUND,
};
@@ -672,6 +692,21 @@ struct io_uring_restriction {
__u32 resv2[3];
};
+struct io_uring_clock_register {
+ __u32 clockid;
+ __u32 __resv[3];
+};
+
+enum {
+ IORING_REGISTER_SRC_REGISTERED = 1,
+};
+
+struct io_uring_clone_buffers {
+ __u32 src_fd;
+ __u32 flags;
+ __u32 pad[6];
+};
+
struct io_uring_buf {
__u64 addr;
__u32 len;
@@ -704,9 +739,17 @@ struct io_uring_buf_ring {
* mmap(2) with the offset set as:
* IORING_OFF_PBUF_RING | (bgid << IORING_OFF_PBUF_SHIFT)
* to get a virtual mapping for the ring.
- */
-enum {
+ * IOU_PBUF_RING_INC: If set, buffers consumed from this buffer ring can be
+ * consumed incrementally. Normally one (or more) buffers
+ * are fully consumed. With incremental consumptions, it's
+ * feasible to register big ranges of buffers, and each
+ * use of it will consume only as much as it needs. This
+ * requires that both the kernel and application keep
+ * track of where the current read/recv index is at.
+ */
+enum io_uring_register_pbuf_ring_flags {
IOU_PBUF_RING_MMAP = 1,
+ IOU_PBUF_RING_INC = 2,
};
/* argument for IORING_(UN)REGISTER_PBUF_RING */
@@ -727,16 +770,16 @@ struct io_uring_buf_status {
/* argument for IORING_(UN)REGISTER_NAPI */
struct io_uring_napi {
- __u32 busy_poll_to;
- __u8 prefer_busy_poll;
- __u8 pad[3];
- __u64 resv;
+ __u32 busy_poll_to;
+ __u8 prefer_busy_poll;
+ __u8 pad[3];
+ __u64 resv;
};
/*
* io_uring_restriction->opcode values
*/
-enum {
+enum io_uring_register_restriction_op {
/* Allow an io_uring_register(2) opcode */
IORING_RESTRICTION_REGISTER_OP = 0,
@@ -755,7 +798,7 @@ enum {
struct io_uring_getevents_arg {
__u64 sigmask;
__u32 sigmask_sz;
- __u32 pad;
+ __u32 min_wait_usec;
__u64 ts;
};
@@ -767,7 +810,9 @@ struct io_uring_sync_cancel_reg {
__s32 fd;
__u32 flags;
struct __kernel_timespec timeout;
- __u64 pad[4];
+ __u8 opcode;
+ __u8 pad[7];
+ __u64 pad2[3];
};
/*
@@ -790,7 +835,7 @@ struct io_uring_recvmsg_out {
/*
* Argument for IORING_OP_URING_CMD when file is a socket
*/
-enum {
+enum io_uring_socket_op {
SOCKET_URING_OP_SIOCINQ = 0,
SOCKET_URING_OP_SIOCOUTQ,
SOCKET_URING_OP_GETSOCKOPT,
diff --git a/contrib/libs/liburing/src/include/liburing/io_uring_version.h b/contrib/libs/liburing/src/include/liburing/io_uring_version.h
index 37aba1d0b4..6705e52610 100644
--- a/contrib/libs/liburing/src/include/liburing/io_uring_version.h
+++ b/contrib/libs/liburing/src/include/liburing/io_uring_version.h
@@ -3,6 +3,6 @@
#define LIBURING_VERSION_H
#define IO_URING_VERSION_MAJOR 2
-#define IO_URING_VERSION_MINOR 7
+#define IO_URING_VERSION_MINOR 8
#endif
diff --git a/contrib/libs/liburing/src/include/liburing/sanitize.h b/contrib/libs/liburing/src/include/liburing/sanitize.h
new file mode 100644
index 0000000000..9a539613d7
--- /dev/null
+++ b/contrib/libs/liburing/src/include/liburing/sanitize.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef LIBURING_SANITIZE_H
+#define LIBURING_SANITIZE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct io_uring;
+struct iovec;
+
+#if defined(CONFIG_USE_SANITIZER)
+void liburing_sanitize_ring(struct io_uring *ring);
+void liburing_sanitize_address(const void *addr);
+void liburing_sanitize_region(const void *addr, unsigned int len);
+void liburing_sanitize_iovecs(const struct iovec *iovecs, unsigned nr);
+#else
+#define __maybe_unused __attribute__((__unused__))
+static inline void liburing_sanitize_ring(struct io_uring __maybe_unused *ring)
+{
+}
+static inline void liburing_sanitize_address(const void __maybe_unused *addr)
+{
+}
+static inline void liburing_sanitize_region(const void __maybe_unused *addr,
+ unsigned int __maybe_unused len)
+{
+}
+static inline void liburing_sanitize_iovecs(const struct iovec __maybe_unused *iovecs,
+ unsigned __maybe_unused nr)
+{
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/libs/liburing/src/int_flags.h b/contrib/libs/liburing/src/int_flags.h
index 548dd1094c..7cfdd3c4d8 100644
--- a/contrib/libs/liburing/src/int_flags.h
+++ b/contrib/libs/liburing/src/int_flags.h
@@ -2,10 +2,17 @@
#ifndef LIBURING_INT_FLAGS
#define LIBURING_INT_FLAGS
+#define INT_FLAGS_MASK (IORING_ENTER_REGISTERED_RING)
+
enum {
- INT_FLAG_REG_RING = 1,
- INT_FLAG_REG_REG_RING = 2,
- INT_FLAG_APP_MEM = 4,
+ INT_FLAG_REG_RING = IORING_ENTER_REGISTERED_RING,
+ INT_FLAG_REG_REG_RING = 1,
+ INT_FLAG_APP_MEM = 2,
};
+static inline int ring_enter_flags(struct io_uring *ring)
+{
+ return ring->int_flags & INT_FLAGS_MASK;
+}
+
#endif
diff --git a/contrib/libs/liburing/src/liburing.map b/contrib/libs/liburing/src/liburing.map
index 28e35c889a..c13cd36ece 100644
--- a/contrib/libs/liburing/src/liburing.map
+++ b/contrib/libs/liburing/src/liburing.map
@@ -95,3 +95,11 @@ LIBURING_2.6 {
LIBURING_2.7 {
} LIBURING_2.6;
+
+LIBURING_2.8 {
+ global:
+ io_uring_register_clock;
+ io_uring_submit_and_wait_min_timeout;
+ io_uring_wait_cqes_min_timeout;
+ io_uring_clone_buffers;
+} LIBURING_2.7;
diff --git a/contrib/libs/liburing/src/queue.c b/contrib/libs/liburing/src/queue.c
index 79457c35ae..6e855a2d3d 100644
--- a/contrib/libs/liburing/src/queue.c
+++ b/contrib/libs/liburing/src/queue.c
@@ -6,6 +6,7 @@
#include "syscall.h"
#include "liburing.h"
#include "int_flags.h"
+#include "liburing/sanitize.h"
#include "liburing/compat.h"
#include "liburing/io_uring.h"
@@ -70,7 +71,7 @@ static int _io_uring_get_cqe(struct io_uring *ring,
do {
bool need_enter = false;
- unsigned flags = 0;
+ unsigned flags = ring_enter_flags(ring);
unsigned nr_available;
int ret;
@@ -94,7 +95,7 @@ static int _io_uring_get_cqe(struct io_uring *ring,
need_enter = true;
}
if (data->wait_nr > nr_available || need_enter) {
- flags = IORING_ENTER_GETEVENTS | data->get_flags;
+ flags |= IORING_ENTER_GETEVENTS | data->get_flags;
need_enter = true;
}
if (sq_ring_needs_enter(ring, data->submit, &flags))
@@ -109,8 +110,6 @@ static int _io_uring_get_cqe(struct io_uring *ring,
break;
}
- if (ring->int_flags & INT_FLAG_REG_RING)
- flags |= IORING_ENTER_REGISTERED_RING;
ret = __sys_io_uring_enter2(ring->enter_ring_fd, data->submit,
data->wait_nr, flags, data->arg,
data->sz);
@@ -149,10 +148,8 @@ int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
int io_uring_get_events(struct io_uring *ring)
{
- int flags = IORING_ENTER_GETEVENTS;
+ int flags = IORING_ENTER_GETEVENTS | ring_enter_flags(ring);
- if (ring->int_flags & INT_FLAG_REG_RING)
- flags |= IORING_ENTER_REGISTERED_RING;
return __sys_io_uring_enter(ring->enter_ring_fd, 0, 0, flags, NULL);
}
@@ -235,6 +232,7 @@ static int io_uring_wait_cqes_new(struct io_uring *ring,
struct io_uring_cqe **cqe_ptr,
unsigned wait_nr,
struct __kernel_timespec *ts,
+ unsigned int min_wait_usec,
sigset_t *sigmask)
{
struct io_uring_getevents_arg arg = {
@@ -250,6 +248,9 @@ static int io_uring_wait_cqes_new(struct io_uring *ring,
.arg = &arg
};
+ if (min_wait_usec && ring->features & IORING_FEAT_MIN_TIMEOUT)
+ arg.min_wait_usec = min_wait_usec;
+
return _io_uring_get_cqe(ring, cqe_ptr, &data);
}
@@ -302,7 +303,7 @@ int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
if (ts) {
if (ring->features & IORING_FEAT_EXT_ARG)
return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr,
- ts, sigmask);
+ ts, 0, sigmask);
to_submit = __io_uring_submit_timeout(ring, wait_nr, ts);
if (to_submit < 0)
return to_submit;
@@ -311,11 +312,20 @@ int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
return __io_uring_get_cqe(ring, cqe_ptr, to_submit, wait_nr, sigmask);
}
-int io_uring_submit_and_wait_timeout(struct io_uring *ring,
- struct io_uring_cqe **cqe_ptr,
- unsigned wait_nr,
- struct __kernel_timespec *ts,
- sigset_t *sigmask)
+int io_uring_wait_cqes_min_timeout(struct io_uring *ring,
+ struct io_uring_cqe **cqe_ptr,
+ unsigned wait_nr,
+ struct __kernel_timespec *ts,
+ unsigned int min_wait_usec, sigset_t *sigmask)
+{
+ return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr, ts, min_wait_usec,
+ sigmask);
+}
+
+static int __io_uring_submit_and_wait_timeout(struct io_uring *ring,
+ struct io_uring_cqe **cqe_ptr, unsigned wait_nr,
+ struct __kernel_timespec *ts,
+ unsigned int min_wait, sigset_t *sigmask)
{
int to_submit;
@@ -324,6 +334,7 @@ int io_uring_submit_and_wait_timeout(struct io_uring *ring,
struct io_uring_getevents_arg arg = {
.sigmask = (unsigned long) sigmask,
.sigmask_sz = _NSIG / 8,
+ .min_wait_usec = min_wait,
.ts = (unsigned long) ts
};
struct get_data data = {
@@ -346,6 +357,29 @@ int io_uring_submit_and_wait_timeout(struct io_uring *ring,
return __io_uring_get_cqe(ring, cqe_ptr, to_submit, wait_nr, sigmask);
}
+int io_uring_submit_and_wait_min_timeout(struct io_uring *ring,
+ struct io_uring_cqe **cqe_ptr,
+ unsigned wait_nr,
+ struct __kernel_timespec *ts,
+ unsigned min_wait,
+ sigset_t *sigmask)
+{
+ if (!(ring->features & IORING_FEAT_MIN_TIMEOUT))
+ return -EINVAL;
+ return __io_uring_submit_and_wait_timeout(ring, cqe_ptr, wait_nr, ts,
+ min_wait, sigmask);
+}
+
+int io_uring_submit_and_wait_timeout(struct io_uring *ring,
+ struct io_uring_cqe **cqe_ptr,
+ unsigned wait_nr,
+ struct __kernel_timespec *ts,
+ sigset_t *sigmask)
+{
+ return __io_uring_submit_and_wait_timeout(ring, cqe_ptr, wait_nr, ts, 0,
+ sigmask);
+}
+
/*
* See io_uring_wait_cqes() - this function is the same, it just always uses
* '1' as the wait_nr.
@@ -366,15 +400,14 @@ static int __io_uring_submit(struct io_uring *ring, unsigned submitted,
unsigned wait_nr, bool getevents)
{
bool cq_needs_enter = getevents || wait_nr || cq_ring_needs_enter(ring);
- unsigned flags;
+ unsigned flags = ring_enter_flags(ring);
int ret;
- flags = 0;
+ liburing_sanitize_ring(ring);
+
if (sq_ring_needs_enter(ring, submitted, &flags) || cq_needs_enter) {
if (cq_needs_enter)
flags |= IORING_ENTER_GETEVENTS;
- if (ring->int_flags & INT_FLAG_REG_RING)
- flags |= IORING_ENTER_REGISTERED_RING;
ret = __sys_io_uring_enter(ring->enter_ring_fd, submitted,
wait_nr, flags, NULL);
@@ -423,10 +456,7 @@ struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring)
int __io_uring_sqring_wait(struct io_uring *ring)
{
- int flags = IORING_ENTER_SQ_WAIT;
-
- if (ring->int_flags & INT_FLAG_REG_RING)
- flags |= IORING_ENTER_REGISTERED_RING;
+ int flags = IORING_ENTER_SQ_WAIT | ring_enter_flags(ring);
return __sys_io_uring_enter(ring->enter_ring_fd, 0, 0, flags, NULL);
}
diff --git a/contrib/libs/liburing/src/register.c b/contrib/libs/liburing/src/register.c
index 7a97303a0e..c215da7f21 100644
--- a/contrib/libs/liburing/src/register.c
+++ b/contrib/libs/liburing/src/register.c
@@ -8,12 +8,15 @@
#include "int_flags.h"
#include "liburing/compat.h"
#include "liburing/io_uring.h"
+#include "liburing/sanitize.h"
static inline int do_register(struct io_uring *ring, unsigned int opcode,
const void *arg, unsigned int nr_args)
{
int fd;
+ liburing_sanitize_address(arg);
+
if (ring->int_flags & INT_FLAG_REG_REG_RING) {
opcode |= IORING_REGISTER_USE_REGISTERED_RING;
fd = ring->enter_ring_fd;
@@ -29,6 +32,8 @@ int io_uring_register_buffers_update_tag(struct io_uring *ring, unsigned off,
const __u64 *tags,
unsigned nr)
{
+ liburing_sanitize_iovecs(iovecs, nr);
+
struct io_uring_rsrc_update2 up = {
.offset = off,
.data = (unsigned long)iovecs,
@@ -44,6 +49,8 @@ int io_uring_register_buffers_tags(struct io_uring *ring,
const __u64 *tags,
unsigned nr)
{
+ liburing_sanitize_iovecs(iovecs, nr);
+
struct io_uring_rsrc_register reg = {
.nr = nr,
.data = (unsigned long)iovecs,
@@ -66,6 +73,8 @@ int io_uring_register_buffers_sparse(struct io_uring *ring, unsigned nr)
int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs,
unsigned nr_iovecs)
{
+ liburing_sanitize_iovecs(iovecs, nr_iovecs);
+
return do_register(ring, IORING_REGISTER_BUFFERS, iovecs, nr_iovecs);
}
@@ -78,6 +87,9 @@ int io_uring_register_files_update_tag(struct io_uring *ring, unsigned off,
const int *files, const __u64 *tags,
unsigned nr_files)
{
+ liburing_sanitize_address(files);
+ liburing_sanitize_address(tags);
+
struct io_uring_rsrc_update2 up = {
.offset = off,
.data = (unsigned long)files,
@@ -98,6 +110,8 @@ int io_uring_register_files_update_tag(struct io_uring *ring, unsigned off,
int io_uring_register_files_update(struct io_uring *ring, unsigned off,
const int *files, unsigned nr_files)
{
+ liburing_sanitize_address(files);
+
struct io_uring_files_update up = {
.offset = off,
.fds = (unsigned long) files,
@@ -149,6 +163,9 @@ int io_uring_register_files_sparse(struct io_uring *ring, unsigned nr)
int io_uring_register_files_tags(struct io_uring *ring, const int *files,
const __u64 *tags, unsigned nr)
{
+ liburing_sanitize_address(files);
+ liburing_sanitize_address(tags);
+
struct io_uring_rsrc_register reg = {
.nr = nr,
.data = (unsigned long)files,
@@ -176,6 +193,8 @@ int io_uring_register_files(struct io_uring *ring, const int *files,
{
int ret, did_increase = 0;
+ liburing_sanitize_address(files);
+
do {
ret = do_register(ring, IORING_REGISTER_FILES, files, nr_files);
if (ret >= 0)
@@ -317,6 +336,7 @@ int io_uring_register_buf_ring(struct io_uring *ring,
struct io_uring_buf_reg *reg,
unsigned int __maybe_unused flags)
{
+ reg->flags |= flags;
return do_register(ring, IORING_REGISTER_PBUF_RING, reg, 1);
}
@@ -329,6 +349,8 @@ int io_uring_unregister_buf_ring(struct io_uring *ring, int bgid)
int io_uring_buf_ring_head(struct io_uring *ring, int buf_group, uint16_t *head)
{
+ liburing_sanitize_address(head);
+
struct io_uring_buf_status buf_status = {
.buf_group = buf_group,
};
@@ -367,3 +389,23 @@ int io_uring_unregister_napi(struct io_uring *ring, struct io_uring_napi *napi)
{
return do_register(ring, IORING_UNREGISTER_NAPI, napi, 1);
}
+
+int io_uring_register_clock(struct io_uring *ring,
+ struct io_uring_clock_register *arg)
+{
+ return do_register(ring, IORING_REGISTER_CLOCK, arg, 0);
+}
+
+int io_uring_clone_buffers(struct io_uring *dst, struct io_uring *src)
+{
+ struct io_uring_clone_buffers buf = { .src_fd = src->ring_fd, };
+
+ if (src->int_flags & INT_FLAG_REG_REG_RING) {
+ buf.src_fd = src->enter_ring_fd;
+ buf.flags = IORING_REGISTER_SRC_REGISTERED;
+ } else {
+ buf.src_fd = src->ring_fd;
+ }
+
+ return do_register(dst, IORING_REGISTER_CLONE_BUFFERS, &buf, 1);
+}
diff --git a/contrib/libs/liburing/src/setup.c b/contrib/libs/liburing/src/setup.c
index aa0fcaaaa5..fef92dbd48 100644
--- a/contrib/libs/liburing/src/setup.c
+++ b/contrib/libs/liburing/src/setup.c
@@ -223,9 +223,9 @@ static int io_uring_alloc_huge(unsigned entries, struct io_uring_params *p,
ring_mem = KRING_SIZE;
sqes_mem = sq_entries * sizeof(struct io_uring_sqe);
- sqes_mem = (sqes_mem + page_size - 1) & ~(page_size - 1);
if (!(p->flags & IORING_SETUP_NO_SQARRAY))
sqes_mem += sq_entries * sizeof(unsigned);
+ sqes_mem = (sqes_mem + page_size - 1) & ~(page_size - 1);
cqes_mem = cq_entries * sizeof(struct io_uring_cqe);
if (p->flags & IORING_SETUP_CQE32)
@@ -434,7 +434,7 @@ __cold void io_uring_queue_exit(struct io_uring *ring)
struct io_uring_cq *cq = &ring->cq;
size_t sqe_size;
- if (!sq->ring_sz) {
+ if (!sq->ring_sz && !(ring->int_flags & INT_FLAG_APP_MEM)) {
sqe_size = sizeof(struct io_uring_sqe);
if (ring->flags & IORING_SETUP_SQE128)
sqe_size += 64;
@@ -596,7 +596,7 @@ __cold ssize_t io_uring_mlock_size(unsigned entries, unsigned flags)
#if defined(__hppa__)
static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
unsigned int nentries, int bgid,
- unsigned int flags, int *ret)
+ unsigned int flags, int *err)
{
struct io_uring_buf_ring *br;
struct io_uring_buf_reg reg;
@@ -609,10 +609,10 @@ static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
reg.bgid = bgid;
reg.flags = IOU_PBUF_RING_MMAP;
- *ret = 0;
+ *err = 0;
lret = io_uring_register_buf_ring(ring, &reg, flags);
if (lret) {
- *ret = lret;
+ *err = lret;
return NULL;
}
@@ -621,7 +621,7 @@ static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
br = __sys_mmap(NULL, ring_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_POPULATE, ring->ring_fd, off);
if (IS_ERR(br)) {
- *ret = PTR_ERR(br);
+ *err = PTR_ERR(br);
return NULL;
}
@@ -630,7 +630,7 @@ static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
#else
static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
unsigned int nentries, int bgid,
- unsigned int flags, int *ret)
+ unsigned int flags, int *err)
{
struct io_uring_buf_ring *br;
struct io_uring_buf_reg reg;
@@ -642,7 +642,7 @@ static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
br = __sys_mmap(NULL, ring_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (IS_ERR(br)) {
- *ret = PTR_ERR(br);
+ *err = PTR_ERR(br);
return NULL;
}
@@ -650,11 +650,11 @@ static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
reg.ring_entries = nentries;
reg.bgid = bgid;
- *ret = 0;
+ *err = 0;
lret = io_uring_register_buf_ring(ring, &reg, flags);
if (lret) {
__sys_munmap(br, ring_size);
- *ret = lret;
+ *err = lret;
br = NULL;
}
@@ -665,11 +665,11 @@ static struct io_uring_buf_ring *br_setup(struct io_uring *ring,
struct io_uring_buf_ring *io_uring_setup_buf_ring(struct io_uring *ring,
unsigned int nentries,
int bgid, unsigned int flags,
- int *ret)
+ int *err)
{
struct io_uring_buf_ring *br;
- br = br_setup(ring, nentries, bgid, flags, ret);
+ br = br_setup(ring, nentries, bgid, flags, err);
if (br)
io_uring_buf_ring_init(br);
diff --git a/contrib/libs/liburing/test/232c93d07b74.t/ya.make b/contrib/libs/liburing/test/232c93d07b74.t/ya.make
index b1d0260eef..c8a2631965 100644
--- a/contrib/libs/liburing/test/232c93d07b74.t/ya.make
+++ b/contrib/libs/liburing/test/232c93d07b74.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/35fa71a030ca.c b/contrib/libs/liburing/test/35fa71a030ca.c
index b21f95a54e..a6b964bada 100644
--- a/contrib/libs/liburing/test/35fa71a030ca.c
+++ b/contrib/libs/liburing/test/35fa71a030ca.c
@@ -29,6 +29,7 @@
#include "helpers.h"
#include "../src/syscall.h"
+#ifndef CONFIG_USE_SANITIZER
#if !defined(SYS_futex) && defined(SYS_futex_time64)
# define SYS_futex SYS_futex_time64
#endif
@@ -328,3 +329,9 @@ int main(int argc, char *argv[])
loop();
return T_EXIT_PASS;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/35fa71a030ca.t/ya.make b/contrib/libs/liburing/test/35fa71a030ca.t/ya.make
index 38988d083d..158d478ea4 100644
--- a/contrib/libs/liburing/test/35fa71a030ca.t/ya.make
+++ b/contrib/libs/liburing/test/35fa71a030ca.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/500f9fbadef8.c b/contrib/libs/liburing/test/500f9fbadef8.c
index 5306d09431..25e7533ca7 100644
--- a/contrib/libs/liburing/test/500f9fbadef8.c
+++ b/contrib/libs/liburing/test/500f9fbadef8.c
@@ -79,10 +79,12 @@ int main(int argc, char *argv[])
close(fd);
unlink(buf);
+ free(iov.iov_base);
return T_EXIT_PASS;
err:
close(fd);
unlink(buf);
+ free(iov.iov_base);
return T_EXIT_FAIL;
skipped:
fprintf(stderr, "Polling not supported in current dir, test skipped\n");
diff --git a/contrib/libs/liburing/test/500f9fbadef8.t/ya.make b/contrib/libs/liburing/test/500f9fbadef8.t/ya.make
index f4f3bdc390..fd66f1bf0b 100644
--- a/contrib/libs/liburing/test/500f9fbadef8.t/ya.make
+++ b/contrib/libs/liburing/test/500f9fbadef8.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/7ad0e4b2f83c.c b/contrib/libs/liburing/test/7ad0e4b2f83c.c
index 067def169a..f063708bc5 100644
--- a/contrib/libs/liburing/test/7ad0e4b2f83c.c
+++ b/contrib/libs/liburing/test/7ad0e4b2f83c.c
@@ -6,31 +6,6 @@
#include "liburing.h"
#include "helpers.h"
-static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
-}
-
-static unsigned long long mtime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
-}
-
int main(int argc, char *argv[])
{
struct __kernel_timespec ts1, ts2;
diff --git a/contrib/libs/liburing/test/7ad0e4b2f83c.t/ya.make b/contrib/libs/liburing/test/7ad0e4b2f83c.t/ya.make
index 681c052f9f..fc918253a0 100644
--- a/contrib/libs/liburing/test/7ad0e4b2f83c.t/ya.make
+++ b/contrib/libs/liburing/test/7ad0e4b2f83c.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/8a9973408177.t/ya.make b/contrib/libs/liburing/test/8a9973408177.t/ya.make
index fdab64253a..8ebec8a2a8 100644
--- a/contrib/libs/liburing/test/8a9973408177.t/ya.make
+++ b/contrib/libs/liburing/test/8a9973408177.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/917257daa0fe.c b/contrib/libs/liburing/test/917257daa0fe.c
index 0fc8e57178..8e5ec96398 100644
--- a/contrib/libs/liburing/test/917257daa0fe.c
+++ b/contrib/libs/liburing/test/917257daa0fe.c
@@ -15,6 +15,7 @@
#include "helpers.h"
#include "../src/syscall.h"
+#ifndef CONFIG_USE_SANITIZER
int main(int argc, char *argv[])
{
if (argc > 1)
@@ -53,3 +54,9 @@ int main(int argc, char *argv[])
__sys_io_uring_setup(0x7a6, (struct io_uring_params *) 0x20000000UL);
return T_EXIT_PASS;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/917257daa0fe.t/ya.make b/contrib/libs/liburing/test/917257daa0fe.t/ya.make
index b7cf6b187d..cc31d0b3fe 100644
--- a/contrib/libs/liburing/test/917257daa0fe.t/ya.make
+++ b/contrib/libs/liburing/test/917257daa0fe.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/a0908ae19763.c b/contrib/libs/liburing/test/a0908ae19763.c
index 0b0f6a0eac..0ffd422bb0 100644
--- a/contrib/libs/liburing/test/a0908ae19763.c
+++ b/contrib/libs/liburing/test/a0908ae19763.c
@@ -15,6 +15,7 @@
#include "helpers.h"
#include "../src/syscall.h"
+#ifndef CONFIG_USE_SANITIZER
static uint64_t r[1] = {0xffffffffffffffff};
int main(int argc, char *argv[])
@@ -58,3 +59,9 @@ int main(int argc, char *argv[])
__sys_io_uring_register(r[0], 2, (const void *) 0x20000280, 1);
return T_EXIT_PASS;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/a0908ae19763.t/ya.make b/contrib/libs/liburing/test/a0908ae19763.t/ya.make
index c6aca489f1..1d5a693e2b 100644
--- a/contrib/libs/liburing/test/a0908ae19763.t/ya.make
+++ b/contrib/libs/liburing/test/a0908ae19763.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/a4c0b3decb33.c b/contrib/libs/liburing/test/a4c0b3decb33.c
index 0e77ba8ee7..0207f4946b 100644
--- a/contrib/libs/liburing/test/a4c0b3decb33.c
+++ b/contrib/libs/liburing/test/a4c0b3decb33.c
@@ -25,6 +25,7 @@
#include "helpers.h"
#include "../src/syscall.h"
+#ifndef CONFIG_USE_SANITIZER
static void sleep_ms(uint64_t ms)
{
usleep(ms * 1000);
@@ -180,3 +181,9 @@ int main(int argc, char *argv[])
loop();
return T_EXIT_PASS;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/a4c0b3decb33.t/ya.make b/contrib/libs/liburing/test/a4c0b3decb33.t/ya.make
index f73ec56c45..176165931b 100644
--- a/contrib/libs/liburing/test/a4c0b3decb33.t/ya.make
+++ b/contrib/libs/liburing/test/a4c0b3decb33.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/accept-link.t/ya.make b/contrib/libs/liburing/test/accept-link.t/ya.make
index 9a7e139107..e110bf5975 100644
--- a/contrib/libs/liburing/test/accept-link.t/ya.make
+++ b/contrib/libs/liburing/test/accept-link.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/accept-non-empty.c b/contrib/libs/liburing/test/accept-non-empty.c
index f85f30ca87..ff92c8a79c 100644
--- a/contrib/libs/liburing/test/accept-non-empty.c
+++ b/contrib/libs/liburing/test/accept-non-empty.c
@@ -60,6 +60,46 @@ static int start_accept_listen(int port_off, int extra_flags)
return fd;
}
+static void *connect_fn(void *data)
+{
+ struct sockaddr_in addr = { };
+ struct data *d = data;
+ int i;
+
+ pthread_barrier_wait(&d->barrier);
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(0x1235);
+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ for (i = 0; i < d->connects; i++) {
+ int s;
+
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (s < 0) {
+ perror("socket");
+ break;
+ }
+ if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ perror("connect");
+ break;
+ }
+ }
+
+ if (i)
+ pthread_barrier_wait(&d->conn_barrier);
+
+ return NULL;
+}
+
+static void setup_thread(struct data *d, int nconns)
+{
+ d->connects = nconns;
+ pthread_barrier_init(&d->barrier, NULL, 2);
+ pthread_barrier_init(&d->conn_barrier, NULL, 2);
+ pthread_create(&d->thread, NULL, connect_fn, d);
+}
+
static int test_maccept(struct data *d, int flags, int fixed)
{
struct io_uring_params p = { };
@@ -82,6 +122,8 @@ static int test_maccept(struct data *d, int flags, int fixed)
return 0;
}
+ setup_thread(d, MAX_ACCEPTS);
+
fds = malloc(MAX_ACCEPTS * sizeof(int));
memset(fds, -1, MAX_ACCEPTS * sizeof(int));
@@ -152,53 +194,12 @@ static int test_maccept(struct data *d, int flags, int fixed)
return err;
}
-static void *connect_fn(void *data)
-{
- struct sockaddr_in addr = { };
- struct data *d = data;
- int i;
-
- pthread_barrier_wait(&d->barrier);
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(0x1235);
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
-
- for (i = 0; i < d->connects; i++) {
- int s;
-
- s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (s < 0) {
- perror("socket");
- break;
- }
- if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("connect");
- break;
- }
- }
-
- if (d->connects > 1)
- pthread_barrier_wait(&d->conn_barrier);
-
- return NULL;
-}
-
-static void setup_thread(struct data *d, int nconns)
-{
- d->connects = nconns;
- pthread_barrier_init(&d->barrier, NULL, 2);
- pthread_barrier_init(&d->conn_barrier, NULL, 2);
- pthread_create(&d->thread, NULL, connect_fn, d);
-}
-
static int test(int flags, int fixed)
{
struct data d;
void *tret;
int ret;
- setup_thread(&d, 1);
ret = test_maccept(&d, flags, fixed);
if (ret) {
fprintf(stderr, "test conns=1 failed\n");
@@ -209,7 +210,6 @@ static int test(int flags, int fixed)
pthread_join(d.thread, &tret);
- setup_thread(&d, MAX_ACCEPTS);
ret = test_maccept(&d, flags, fixed);
if (ret) {
fprintf(stderr, "test conns=MAX failed\n");
diff --git a/contrib/libs/liburing/test/accept-non-empty.t/ya.make b/contrib/libs/liburing/test/accept-non-empty.t/ya.make
index c6df3eb032..27ec536d0d 100644
--- a/contrib/libs/liburing/test/accept-non-empty.t/ya.make
+++ b/contrib/libs/liburing/test/accept-non-empty.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/accept-reuse.t/ya.make b/contrib/libs/liburing/test/accept-reuse.t/ya.make
index 6624289a0e..d2ef8e2bd6 100644
--- a/contrib/libs/liburing/test/accept-reuse.t/ya.make
+++ b/contrib/libs/liburing/test/accept-reuse.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/accept-test.t/ya.make b/contrib/libs/liburing/test/accept-test.t/ya.make
index c82e260ee9..26bf93d787 100644
--- a/contrib/libs/liburing/test/accept-test.t/ya.make
+++ b/contrib/libs/liburing/test/accept-test.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/accept.c b/contrib/libs/liburing/test/accept.c
index 49b1ca1345..279e739290 100644
--- a/contrib/libs/liburing/test/accept.c
+++ b/contrib/libs/liburing/test/accept.c
@@ -61,7 +61,7 @@ static void close_sock_fds(int s_fd[], int c_fd[], int nr, bool fixed)
close_fds(c_fd, nr);
}
-static void queue_send(struct io_uring *ring, int fd)
+static void *queue_send(struct io_uring *ring, int fd)
{
struct io_uring_sqe *sqe;
struct data *d;
@@ -73,9 +73,11 @@ static void queue_send(struct io_uring *ring, int fd)
sqe = io_uring_get_sqe(ring);
io_uring_prep_writev(sqe, fd, &d->iov, 1, 0);
sqe->user_data = 1;
+
+ return d;
}
-static void queue_recv(struct io_uring *ring, int fd, bool fixed)
+static void *queue_recv(struct io_uring *ring, int fd, bool fixed)
{
struct io_uring_sqe *sqe;
struct data *d;
@@ -89,6 +91,8 @@ static void queue_recv(struct io_uring *ring, int fd, bool fixed)
sqe->user_data = 2;
if (fixed)
sqe->flags |= IOSQE_FIXED_FILE;
+
+ return d;
}
static void queue_accept_multishot(struct io_uring *ring, int fd,
@@ -275,6 +279,8 @@ static int test_loop(struct io_uring *ring,
int nr_fds = multishot ? MAX_FDS : 1;
int multishot_idx = multishot ? INITIAL_USER_DATA : 0;
int err_ret = T_EXIT_FAIL;
+ void* send_d = 0;
+ void* recv_d = 0;
if (args.overflow)
cause_overflow(ring);
@@ -341,8 +347,8 @@ static int test_loop(struct io_uring *ring,
goto out;
}
- queue_send(ring, c_fd[0]);
- queue_recv(ring, s_fd[0], fixed);
+ send_d = queue_send(ring, c_fd[0]);
+ recv_d = queue_recv(ring, s_fd[0], fixed);
ret = io_uring_submit_and_wait(ring, 2);
assert(ret != -1);
@@ -366,9 +372,13 @@ static int test_loop(struct io_uring *ring,
}
out:
+ free(send_d);
+ free(recv_d);
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
return T_EXIT_PASS;
err:
+ free(send_d);
+ free(recv_d);
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
return err_ret;
}
diff --git a/contrib/libs/liburing/test/accept.t/ya.make b/contrib/libs/liburing/test/accept.t/ya.make
index 95bb00c414..294a2c4213 100644
--- a/contrib/libs/liburing/test/accept.t/ya.make
+++ b/contrib/libs/liburing/test/accept.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/across-fork.t/ya.make b/contrib/libs/liburing/test/across-fork.t/ya.make
index 1b12588baf..c233f57ffb 100644
--- a/contrib/libs/liburing/test/across-fork.t/ya.make
+++ b/contrib/libs/liburing/test/across-fork.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/b19062a56726.c b/contrib/libs/liburing/test/b19062a56726.c
index 9356769818..b0683c5837 100644
--- a/contrib/libs/liburing/test/b19062a56726.c
+++ b/contrib/libs/liburing/test/b19062a56726.c
@@ -15,6 +15,7 @@
#include "helpers.h"
#include "../src/syscall.h"
+#ifndef CONFIG_USE_SANITIZER
int main(int argc, char *argv[])
{
if (argc > 1)
@@ -53,3 +54,9 @@ int main(int argc, char *argv[])
__sys_io_uring_setup(0xc9f, (struct io_uring_params *) 0x20000200);
return T_EXIT_PASS;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/b19062a56726.t/ya.make b/contrib/libs/liburing/test/b19062a56726.t/ya.make
index 5c7a8603ad..5b5cad9153 100644
--- a/contrib/libs/liburing/test/b19062a56726.t/ya.make
+++ b/contrib/libs/liburing/test/b19062a56726.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/b5837bd5311d.t/ya.make b/contrib/libs/liburing/test/b5837bd5311d.t/ya.make
index 74e7ca4d07..9e44b2fbcd 100644
--- a/contrib/libs/liburing/test/b5837bd5311d.t/ya.make
+++ b/contrib/libs/liburing/test/b5837bd5311d.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/bind-listen.c b/contrib/libs/liburing/test/bind-listen.c
index 25f41b48b5..5ed4a2d1da 100644
--- a/contrib/libs/liburing/test/bind-listen.c
+++ b/contrib/libs/liburing/test/bind-listen.c
@@ -55,7 +55,7 @@ static int connect_client(struct io_uring *ring, unsigned short peer_port)
sqe = io_uring_get_sqe(ring);
io_uring_prep_send(sqe, CLI_INDEX, magic, strlen(magic), 0);
- sqe->flags |= IOSQE_FIXED_FILE | IOSQE_IO_LINK;
+ sqe->flags |= IOSQE_FIXED_FILE;
submitted = ret = io_uring_submit(ring);
if (ret < 0)
@@ -181,7 +181,7 @@ static int test_good_server(unsigned int ring_flags)
io_uring_cqe_seen(&ring, cqe);
sqe = io_uring_get_sqe(&ring);
- io_uring_prep_recv(sqe, CONN_INDEX, buf, BUFSIZ, 0);
+ io_uring_prep_recv(sqe, CONN_INDEX, buf, sizeof(buf), 0);
sqe->flags |= IOSQE_FIXED_FILE;
io_uring_submit(&ring);
diff --git a/contrib/libs/liburing/test/bind-listen.t/ya.make b/contrib/libs/liburing/test/bind-listen.t/ya.make
index 06ac130345..25e4ebe79e 100644
--- a/contrib/libs/liburing/test/bind-listen.t/ya.make
+++ b/contrib/libs/liburing/test/bind-listen.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/buf-ring-nommap.c b/contrib/libs/liburing/test/buf-ring-nommap.c
index ac4f199c8b..ee9ebd1601 100644
--- a/contrib/libs/liburing/test/buf-ring-nommap.c
+++ b/contrib/libs/liburing/test/buf-ring-nommap.c
@@ -47,8 +47,10 @@ int main(int argc, char *argv[])
p.flags = IORING_SETUP_NO_MMAP;
ret = io_uring_queue_init_mem(1, &ring, &p, ring_mem, 16384);
if (ret < 0) {
- if (ret == -EINVAL || ret == -ENOMEM)
+ if (ret == -EINVAL || ret == -ENOMEM) {
+ free(ring_mem);
return T_EXIT_SKIP;
+ }
fprintf(stderr, "queue init failed %d\n", ret);
return T_EXIT_FAIL;
}
@@ -63,8 +65,10 @@ int main(int argc, char *argv[])
ret = io_uring_register_buf_ring(&ring, &reg, 0);
if (ret) {
- if (ret == -EINVAL)
+ if (ret == -EINVAL) {
+ free(ring_mem);
return T_EXIT_SKIP;
+ }
fprintf(stderr, "reg buf ring: %d\n", ret);
return T_EXIT_FAIL;
}
@@ -74,8 +78,10 @@ int main(int argc, char *argv[])
br = mmap(NULL, ring_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_POPULATE, ring.ring_fd, off);
if (br == MAP_FAILED) {
- if (errno == ENOMEM)
+ if (errno == ENOMEM) {
+ free(ring_mem);
return T_EXIT_SKIP;
+ }
perror("mmap");
return T_EXIT_FAIL;
}
@@ -120,5 +126,6 @@ int main(int argc, char *argv[])
io_uring_cqe_seen(&ring, cqe);
io_uring_queue_exit(&ring);
+ free(ring_mem);
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/buf-ring-nommap.t/ya.make b/contrib/libs/liburing/test/buf-ring-nommap.t/ya.make
index 1acf0938dc..645e84c91d 100644
--- a/contrib/libs/liburing/test/buf-ring-nommap.t/ya.make
+++ b/contrib/libs/liburing/test/buf-ring-nommap.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/buf-ring-put.t/ya.make b/contrib/libs/liburing/test/buf-ring-put.t/ya.make
index f8f026e2a2..5dba623a0a 100644
--- a/contrib/libs/liburing/test/buf-ring-put.t/ya.make
+++ b/contrib/libs/liburing/test/buf-ring-put.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/buf-ring.c b/contrib/libs/liburing/test/buf-ring.c
index 526dddaddc..44da27f619 100644
--- a/contrib/libs/liburing/test/buf-ring.c
+++ b/contrib/libs/liburing/test/buf-ring.c
@@ -58,6 +58,7 @@ static int test_mixed_reg2(int bgid)
io_uring_free_buf_ring(&ring, br, 32, bgid);
io_uring_queue_exit(&ring);
+ free(bufs);
return 0;
}
@@ -100,6 +101,7 @@ static int test_mixed_reg(int bgid)
}
io_uring_queue_exit(&ring);
+ free(bufs);
return 0;
}
diff --git a/contrib/libs/liburing/test/buf-ring.t/ya.make b/contrib/libs/liburing/test/buf-ring.t/ya.make
index 63b3bac811..131f914b8b 100644
--- a/contrib/libs/liburing/test/buf-ring.t/ya.make
+++ b/contrib/libs/liburing/test/buf-ring.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/ce593a6c480a.t/ya.make b/contrib/libs/liburing/test/ce593a6c480a.t/ya.make
index 2a1a37f183..ecb3520c84 100644
--- a/contrib/libs/liburing/test/ce593a6c480a.t/ya.make
+++ b/contrib/libs/liburing/test/ce593a6c480a.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/close-opath.t/ya.make b/contrib/libs/liburing/test/close-opath.t/ya.make
index 0f156c6373..71f3acf824 100644
--- a/contrib/libs/liburing/test/close-opath.t/ya.make
+++ b/contrib/libs/liburing/test/close-opath.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/cmd-discard.c b/contrib/libs/liburing/test/cmd-discard.c
new file mode 100644
index 0000000000..864791754c
--- /dev/null
+++ b/contrib/libs/liburing/test/cmd-discard.c
@@ -0,0 +1,426 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define MAX_TEST_LBAS 1024
+
+static const char *filename;
+struct opcode {
+ int op;
+ bool test;
+ bool not_supported;
+};
+
+#define TEST_BLOCK_URING_CMD_MAX 3
+
+static struct opcode opcodes[TEST_BLOCK_URING_CMD_MAX] = {
+ { .op = BLOCK_URING_CMD_DISCARD, .test = true, },
+ { .test = false, },
+ { .test = false, },
+};
+
+static int lba_size;
+static uint64_t bdev_size;
+static uint64_t bdev_size_lbas;
+static char *buffer;
+
+static void prep_blk_cmd(struct io_uring_sqe *sqe, int fd,
+ uint64_t from, uint64_t len,
+ int cmd_op)
+{
+ assert(cmd_op == BLOCK_URING_CMD_DISCARD);
+
+ io_uring_prep_cmd_discard(sqe, fd, from, len);
+}
+
+static int queue_cmd_range(struct io_uring *ring, int bdev_fd,
+ uint64_t from, uint64_t len, int cmd_op)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int err;
+
+ sqe = io_uring_get_sqe(ring);
+ assert(sqe != NULL);
+ prep_blk_cmd(sqe, bdev_fd, from, len, cmd_op);
+
+ err = io_uring_submit_and_wait(ring, 1);
+ if (err != 1) {
+ fprintf(stderr, "io_uring_submit_and_wait failed %d\n", err);
+ exit(1);
+ }
+
+ err = io_uring_wait_cqe(ring, &cqe);
+ if (err) {
+ fprintf(stderr, "io_uring_wait_cqe failed %d (op %i)\n",
+ err, cmd_op);
+ exit(1);
+ }
+
+ err = cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ return err;
+}
+
+static int queue_cmd_lba(struct io_uring *ring, int bdev_fd,
+ uint64_t from, uint64_t nr_lba, int cmd_op)
+{
+ return queue_cmd_range(ring, bdev_fd, from * lba_size,
+ nr_lba * lba_size, cmd_op);
+}
+
+static int queue_discard_lba(struct io_uring *ring, int bdev_fd,
+ uint64_t from, uint64_t nr_lba)
+{
+ return queue_cmd_lba(ring, bdev_fd, from, nr_lba,
+ BLOCK_URING_CMD_DISCARD);
+}
+
+static int test_parallel(struct io_uring *ring, int fd, int cmd_op)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int inflight = 0;
+ int max_inflight = 16;
+ int left = 1000;
+ int ret;
+
+ while (left || inflight) {
+ int queued = 0;
+ unsigned head, nr_cqes = 0;
+ int lba_len = 8;
+
+ while (inflight < max_inflight && left) {
+ int off = rand() % (MAX_TEST_LBAS - lba_len);
+ sqe = io_uring_get_sqe(ring);
+ assert(sqe != NULL);
+
+ prep_blk_cmd(sqe, fd, off * lba_size,
+ lba_len * lba_size, cmd_op);
+ if (rand() & 1)
+ sqe->flags |= IOSQE_ASYNC;
+
+ queued++;
+ left--;
+ inflight++;
+ }
+ if (queued) {
+ ret = io_uring_submit(ring);
+ if (ret != queued) {
+ fprintf(stderr, "io_uring_submit failed %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "io_uring_wait_cqe failed %d\n", ret);
+ exit(1);
+ }
+
+ io_uring_for_each_cqe(ring, head, cqe) {
+ nr_cqes++;
+ inflight--;
+ if (cqe->res != 0) {
+ fprintf(stderr, "cmd %i failed %i\n", cmd_op,
+ cqe->res);
+ return T_EXIT_FAIL;
+ }
+ }
+ io_uring_cq_advance(ring, nr_cqes);
+ }
+
+ return 0;
+}
+
+static int cmd_issue_verify(struct io_uring *ring, int fd, int lba, int len,
+ int cmd_op)
+{
+ int verify = (cmd_op != BLOCK_URING_CMD_DISCARD);
+ int ret, i;
+ ssize_t res;
+
+ if (verify) {
+ for (i = 0; i < len; i++) {
+ size_t off = (i + lba) * lba_size;
+
+ res = pwrite(fd, buffer, lba_size, off);
+ if (res == -1) {
+ fprintf(stderr, "pwrite failed\n");
+ return T_EXIT_FAIL;
+ }
+ }
+ }
+
+ ret = queue_cmd_lba(ring, fd, lba, len, cmd_op);
+ if (ret) {
+ if (ret == -EINVAL || ret == -EOPNOTSUPP)
+ return T_EXIT_SKIP;
+
+ fprintf(stderr, "cmd_issue_verify %i fail lba %i len %i ret %i\n",
+ cmd_op, lba, len, ret);
+ return T_EXIT_FAIL;
+ }
+
+ if (verify) {
+ for (i = 0; i < len; i++) {
+ size_t off = (i + lba) * lba_size;
+
+ res = pread(fd, buffer, lba_size, off);
+ if (res == -1) {
+ fprintf(stderr, "pread failed\n");
+ return T_EXIT_FAIL;
+ }
+ if (!memchr(buffer, 0, lba_size)) {
+ fprintf(stderr, "mem cmp failed, lba %i\n", lba + i);
+ return T_EXIT_FAIL;
+ }
+ }
+ }
+ return 0;
+}
+
+static int basic_cmd_test(struct io_uring *ring, int op)
+{
+ int cmd_op = opcodes[op].op;
+ int ret, fd;
+
+ if (!opcodes[op].test)
+ return T_EXIT_SKIP;
+
+ fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
+ if (fd < 0) {
+ fprintf(stderr, "open failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+
+ ret = cmd_issue_verify(ring, fd, 0, 1, cmd_op);
+ if (ret == T_EXIT_SKIP) {
+ printf("cmd %i not supported, skip\n", cmd_op);
+ opcodes[op].not_supported = 1;
+ close(fd);
+ return T_EXIT_SKIP;
+ } else if (ret) {
+ fprintf(stderr, "cmd %i fail 0 1\n", cmd_op);
+ return T_EXIT_FAIL;
+ }
+
+ ret = cmd_issue_verify(ring, fd, 7, 15, cmd_op);
+ if (ret) {
+ fprintf(stderr, "cmd %i fail 7 15 %i\n", cmd_op, ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = cmd_issue_verify(ring, fd, 1, MAX_TEST_LBAS - 1, cmd_op);
+ if (ret) {
+ fprintf(stderr, "large cmd %i failed %i\n", cmd_op, ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_parallel(ring, fd, cmd_op);
+ if (ret) {
+ fprintf(stderr, "test_parallel() %i failed %i\n", cmd_op, ret);
+ return T_EXIT_FAIL;
+ }
+
+ close(fd);
+ return 0;
+}
+
+static int test_fail_edge_cases(struct io_uring *ring, int op)
+{
+ int cmd_op = opcodes[op].op;
+ int ret, fd;
+
+ if (!opcodes[op].test)
+ return T_EXIT_SKIP;
+
+ fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
+ if (fd < 0) {
+ fprintf(stderr, "open failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+
+ ret = queue_cmd_lba(ring, fd, bdev_size_lbas, 1, cmd_op);
+ if (ret >= 0) {
+ fprintf(stderr, "cmd %i beyond capacity %i\n",
+ cmd_op, ret);
+ return 1;
+ }
+
+ ret = queue_cmd_lba(ring, fd, bdev_size_lbas - 1, 2, cmd_op);
+ if (ret >= 0) {
+ fprintf(stderr, "cmd %i beyond capacity with overlap %i\n",
+ cmd_op, ret);
+ return 1;
+ }
+
+ ret = queue_cmd_range(ring, fd, (uint64_t)-lba_size, lba_size + 2,
+ cmd_op);
+ if (ret >= 0) {
+ fprintf(stderr, "cmd %i range overflow %i\n",
+ cmd_op, ret);
+ return 1;
+ }
+
+ ret = queue_cmd_range(ring, fd, lba_size / 2, lba_size, cmd_op);
+ if (ret >= 0) {
+ fprintf(stderr, "cmd %i unaligned offset %i\n",
+ cmd_op, ret);
+ return 1;
+ }
+
+ ret = queue_cmd_range(ring, fd, 0, lba_size / 2, cmd_op);
+ if (ret >= 0) {
+ fprintf(stderr, "cmd %i unaligned size %i\n",
+ cmd_op, ret);
+ return 1;
+ }
+
+ close(fd);
+ return 0;
+}
+
+static int test_rdonly(struct io_uring *ring, int op)
+{
+ int ret, fd;
+ int ro;
+
+ if (!opcodes[op].test)
+ return T_EXIT_SKIP;
+
+ fd = open(filename, O_DIRECT | O_RDONLY | O_EXCL);
+ if (fd < 0) {
+ fprintf(stderr, "open failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+
+ ret = queue_discard_lba(ring, fd, 0, 1);
+ if (ret >= 0) {
+ fprintf(stderr, "discarded with O_RDONLY %i\n", ret);
+ return 1;
+ }
+ close(fd);
+
+ fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
+ if (fd < 0) {
+ fprintf(stderr, "open failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+
+ ro = 1;
+ ret = ioctl(fd, BLKROSET, &ro);
+ if (ret) {
+ fprintf(stderr, "BLKROSET 1 failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+
+ ret = queue_discard_lba(ring, fd, 0, 1);
+ if (ret >= 0) {
+ fprintf(stderr, "discarded with O_RDONLY %i\n", ret);
+ return 1;
+ }
+
+ ro = 0;
+ ret = ioctl(fd, BLKROSET, &ro);
+ if (ret) {
+ fprintf(stderr, "BLKROSET 0 failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+ close(fd);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ int fd, ret, i, fret;
+ int cmd_op;
+
+ if (argc != 2)
+ return T_EXIT_SKIP;
+ filename = argv[1];
+
+ fd = open(filename, O_DIRECT | O_RDONLY | O_EXCL);
+ if (fd < 0) {
+ fprintf(stderr, "open failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+
+ ret = ioctl(fd, BLKGETSIZE64, &bdev_size);
+ if (ret < 0) {
+ fprintf(stderr, "BLKGETSIZE64 failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+ ret = ioctl(fd, BLKSSZGET, &lba_size);
+ if (ret < 0) {
+ fprintf(stderr, "BLKSSZGET failed %i\n", errno);
+ return T_EXIT_FAIL;
+ }
+ assert(bdev_size % lba_size == 0);
+ bdev_size_lbas = bdev_size / lba_size;
+ close(fd);
+
+ buffer = aligned_alloc(lba_size, lba_size);
+ if (!buffer) {
+ fprintf(stderr, "aligned_alloc failed\n");
+ return T_EXIT_FAIL;
+ }
+ for (i = 0; i < lba_size; i++)
+ buffer[i] = i ^ 0xA7;
+
+ if (bdev_size_lbas < MAX_TEST_LBAS) {
+ fprintf(stderr, "the device is too small, skip\n");
+ return T_EXIT_SKIP;
+ }
+
+ ret = io_uring_queue_init(16, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ fret = T_EXIT_SKIP;
+ for (cmd_op = 0; cmd_op < TEST_BLOCK_URING_CMD_MAX; cmd_op++) {
+ if (!opcodes[cmd_op].test)
+ continue;
+ ret = basic_cmd_test(&ring, cmd_op);
+ if (ret) {
+ if (ret == T_EXIT_SKIP)
+ continue;
+
+ fprintf(stderr, "basic_cmd_test() failed, cmd %i\n",
+ cmd_op);
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_rdonly(&ring, cmd_op);
+ if (ret) {
+ fprintf(stderr, "test_rdonly() failed, cmd %i\n",
+ cmd_op);
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_fail_edge_cases(&ring, cmd_op);
+ if (ret) {
+ fprintf(stderr, "test_fail_edge_cases() failed, cmd %i\n",
+ cmd_op);
+ return T_EXIT_FAIL;
+ }
+ fret = T_EXIT_PASS;
+ }
+
+ io_uring_queue_exit(&ring);
+ free(buffer);
+ return fret;
+}
diff --git a/contrib/libs/liburing/test/cmd-discard.t/ya.make b/contrib/libs/liburing/test/cmd-discard.t/ya.make
new file mode 100644
index 0000000000..4c39cb59bd
--- /dev/null
+++ b/contrib/libs/liburing/test/cmd-discard.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ cmd-discard.c
+ helpers.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/connect-rep.t/ya.make b/contrib/libs/liburing/test/connect-rep.t/ya.make
index 4a22b223ac..bed485eb58 100644
--- a/contrib/libs/liburing/test/connect-rep.t/ya.make
+++ b/contrib/libs/liburing/test/connect-rep.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/connect.t/ya.make b/contrib/libs/liburing/test/connect.t/ya.make
index 15d4aeedae..761dfdedbc 100644
--- a/contrib/libs/liburing/test/connect.t/ya.make
+++ b/contrib/libs/liburing/test/connect.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/coredump.c b/contrib/libs/liburing/test/coredump.c
index d390b78be9..fc29e61e1c 100644
--- a/contrib/libs/liburing/test/coredump.c
+++ b/contrib/libs/liburing/test/coredump.c
@@ -17,6 +17,7 @@
#include "liburing.h"
#include "helpers.h"
+#ifndef CONFIG_USE_SANITIZER
static void test(void)
{
struct io_uring_sqe *sqe;
@@ -59,3 +60,9 @@ int main(int argc, char *argv[])
unlink("core");
return T_EXIT_PASS;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/coredump.t/ya.make b/contrib/libs/liburing/test/coredump.t/ya.make
index cad32c9a7b..f4df921c4a 100644
--- a/contrib/libs/liburing/test/coredump.t/ya.make
+++ b/contrib/libs/liburing/test/coredump.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/cq-full.t/ya.make b/contrib/libs/liburing/test/cq-full.t/ya.make
index 3ac0b9d38b..b968925073 100644
--- a/contrib/libs/liburing/test/cq-full.t/ya.make
+++ b/contrib/libs/liburing/test/cq-full.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/cq-overflow.c b/contrib/libs/liburing/test/cq-overflow.c
index 569c733752..b43bf69131 100644
--- a/contrib/libs/liburing/test/cq-overflow.c
+++ b/contrib/libs/liburing/test/cq-overflow.c
@@ -89,8 +89,10 @@ static int test_io(const char *file, unsigned long usecs, unsigned *drops,
goto err;
}
offset = BS * (rand() % BUFFERS);
- if (fault && i == ENTRIES + 4)
+ if (fault && i == ENTRIES + 4) {
+ free(vecs[i].iov_base);
vecs[i].iov_base = NULL;
+ }
io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
ret = io_uring_submit(&ring);
@@ -524,8 +526,18 @@ int main(int argc, char *argv[])
}
unlink(fname);
+ if(vecs != NULL) {
+ for (i = 0; i < BUFFERS; i++)
+ free(vecs[i].iov_base);
+ }
+ free(vecs);
return T_EXIT_PASS;
err:
unlink(fname);
+ if(vecs != NULL) {
+ for (i = 0; i < BUFFERS; i++)
+ free(vecs[i].iov_base);
+ }
+ free(vecs);
return T_EXIT_FAIL;
}
diff --git a/contrib/libs/liburing/test/cq-overflow.t/ya.make b/contrib/libs/liburing/test/cq-overflow.t/ya.make
index 4d67475587..d1ef4cab6f 100644
--- a/contrib/libs/liburing/test/cq-overflow.t/ya.make
+++ b/contrib/libs/liburing/test/cq-overflow.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/cq-peek-batch.t/ya.make b/contrib/libs/liburing/test/cq-peek-batch.t/ya.make
index 608e643c84..ce3845ab9e 100644
--- a/contrib/libs/liburing/test/cq-peek-batch.t/ya.make
+++ b/contrib/libs/liburing/test/cq-peek-batch.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/cq-ready.t/ya.make b/contrib/libs/liburing/test/cq-ready.t/ya.make
index e3ec30727e..02f8f754b8 100644
--- a/contrib/libs/liburing/test/cq-ready.t/ya.make
+++ b/contrib/libs/liburing/test/cq-ready.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/cq-size.t/ya.make b/contrib/libs/liburing/test/cq-size.t/ya.make
index 5f6423089a..199bddbcd3 100644
--- a/contrib/libs/liburing/test/cq-size.t/ya.make
+++ b/contrib/libs/liburing/test/cq-size.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/d4ae271dfaae.c b/contrib/libs/liburing/test/d4ae271dfaae.c
index af47047be8..2a95b844db 100644
--- a/contrib/libs/liburing/test/d4ae271dfaae.c
+++ b/contrib/libs/liburing/test/d4ae271dfaae.c
@@ -20,10 +20,10 @@
int main(int argc, char *argv[])
{
struct io_uring ring;
- int i, fd, ret;
+ int i, fd, ret, __e;
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
- struct iovec *iovecs;
+ struct iovec *iovecs = NULL;
struct io_uring_params p;
char *fname;
void *buf;
@@ -44,10 +44,13 @@ int main(int argc, char *argv[])
}
fd = open(fname, O_RDONLY | O_DIRECT);
+ __e = errno;
if (fname != argv[1])
unlink(fname);
if (fd < 0) {
- perror("open");
+ if (__e == EINVAL || __e == EPERM || __e == EACCES)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "open: %s\n", strerror(__e));
goto out;
}
@@ -93,5 +96,10 @@ int main(int argc, char *argv[])
close(fd);
out:
io_uring_queue_exit(&ring);
+ if (iovecs != NULL) { //
+ for (i = 0; i < 10; i++)
+ free(iovecs[i].iov_base);
+ free(iovecs);
+ }
return ret;
}
diff --git a/contrib/libs/liburing/test/d4ae271dfaae.t/ya.make b/contrib/libs/liburing/test/d4ae271dfaae.t/ya.make
index 30095cf271..28e901964b 100644
--- a/contrib/libs/liburing/test/d4ae271dfaae.t/ya.make
+++ b/contrib/libs/liburing/test/d4ae271dfaae.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/d77a67ed5f27.t/ya.make b/contrib/libs/liburing/test/d77a67ed5f27.t/ya.make
index d8eac8b261..6e1723d53f 100644
--- a/contrib/libs/liburing/test/d77a67ed5f27.t/ya.make
+++ b/contrib/libs/liburing/test/d77a67ed5f27.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/defer-taskrun.c b/contrib/libs/liburing/test/defer-taskrun.c
index c2543f4b26..82dfa2eef3 100644
--- a/contrib/libs/liburing/test/defer-taskrun.c
+++ b/contrib/libs/liburing/test/defer-taskrun.c
@@ -197,12 +197,12 @@ static int test_exec(const char *filename)
if (filename) {
fd = open(filename, O_RDONLY | O_DIRECT);
- if (fd < 0 && errno == EINVAL)
+ if (fd < 0 && (errno == EINVAL || errno == EPERM || errno == EACCES))
return T_EXIT_SKIP;
} else {
t_create_file(EXEC_FILENAME, EXEC_FILESIZE);
fd = open(EXEC_FILENAME, O_RDONLY | O_DIRECT);
- if (fd < 0 && errno == EINVAL) {
+ if (fd < 0 && (errno == EINVAL || errno == EPERM || errno == EACCES)) {
unlink(EXEC_FILENAME);
return T_EXIT_SKIP;
}
diff --git a/contrib/libs/liburing/test/defer-taskrun.t/ya.make b/contrib/libs/liburing/test/defer-taskrun.t/ya.make
index a4303270da..9ed40ffc04 100644
--- a/contrib/libs/liburing/test/defer-taskrun.t/ya.make
+++ b/contrib/libs/liburing/test/defer-taskrun.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/defer-tw-timeout.c b/contrib/libs/liburing/test/defer-tw-timeout.c
index b3489abe62..b521823d92 100644
--- a/contrib/libs/liburing/test/defer-tw-timeout.c
+++ b/contrib/libs/liburing/test/defer-tw-timeout.c
@@ -100,7 +100,7 @@ static int test_file(struct io_uring *ring, char *__fname)
fd = open(fname, O_RDONLY | O_DIRECT);
if (fd < 0) {
- if (errno == EINVAL) {
+ if (errno == EINVAL || errno == EPERM || errno == EACCES) {
if (!__fname)
unlink(fname);
return T_EXIT_SKIP;
@@ -129,6 +129,7 @@ static int test_file(struct io_uring *ring, char *__fname)
if (ret != 1) {
fprintf(stderr, "unexpected wait ret %d\n", ret);
close(fd);
+ free(buf);
return T_EXIT_FAIL;
}
@@ -142,10 +143,12 @@ static int test_file(struct io_uring *ring, char *__fname)
if (i != 1) {
fprintf(stderr, "Got %d request, expected 1\n", i);
close(fd);
+ free(buf);
return T_EXIT_FAIL;
}
close(fd);
+ free(buf);
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/defer-tw-timeout.t/ya.make b/contrib/libs/liburing/test/defer-tw-timeout.t/ya.make
index e255116361..fd56a7f4b5 100644
--- a/contrib/libs/liburing/test/defer-tw-timeout.t/ya.make
+++ b/contrib/libs/liburing/test/defer-tw-timeout.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/defer.c b/contrib/libs/liburing/test/defer.c
index 1e52dcbf4e..dbad205d8f 100644
--- a/contrib/libs/liburing/test/defer.c
+++ b/contrib/libs/liburing/test/defer.c
@@ -97,7 +97,7 @@ static int test_canceled_userdata(struct io_uring *ring)
if (init_context(&ctx, ring, nr, OP_NOP))
return 1;
- for (i = 0; i < nr; i++)
+ for (i = 0; i < nr - 1; i++)
ctx.sqes[i]->flags |= IOSQE_IO_LINK;
ret = io_uring_submit(ring);
@@ -131,7 +131,7 @@ static int test_thread_link_cancel(struct io_uring *ring)
if (init_context(&ctx, ring, nr, OP_REMOVE_BUFFERS))
return 1;
- for (i = 0; i < nr; i++)
+ for (i = 0; i < nr - 1; i++)
ctx.sqes[i]->flags |= IOSQE_IO_LINK;
ret = io_uring_submit(ring);
diff --git a/contrib/libs/liburing/test/defer.t/ya.make b/contrib/libs/liburing/test/defer.t/ya.make
index 1a043bd93a..dd18ffdd04 100644
--- a/contrib/libs/liburing/test/defer.t/ya.make
+++ b/contrib/libs/liburing/test/defer.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/double-poll-crash.c b/contrib/libs/liburing/test/double-poll-crash.c
index 67be0682c4..ef636c0072 100644
--- a/contrib/libs/liburing/test/double-poll-crash.c
+++ b/contrib/libs/liburing/test/double-poll-crash.c
@@ -115,7 +115,7 @@ static uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff};
int main(int argc, char *argv[])
{
void *mmap_ret;
-#if !defined(__i386) && !defined(__x86_64__)
+#if (!defined(__i386) && !defined(__x86_64__)) || defined(CONFIG_USE_SANITIZER)
return T_EXIT_SKIP;
#endif
diff --git a/contrib/libs/liburing/test/double-poll-crash.t/ya.make b/contrib/libs/liburing/test/double-poll-crash.t/ya.make
index 69683beddc..d3480d8b17 100644
--- a/contrib/libs/liburing/test/double-poll-crash.t/ya.make
+++ b/contrib/libs/liburing/test/double-poll-crash.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/drop-submit.t/ya.make b/contrib/libs/liburing/test/drop-submit.t/ya.make
index 709c282398..829e75c6b7 100644
--- a/contrib/libs/liburing/test/drop-submit.t/ya.make
+++ b/contrib/libs/liburing/test/drop-submit.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/eeed8b54e0df.c b/contrib/libs/liburing/test/eeed8b54e0df.c
index 6b73a35db6..bdb91235e9 100644
--- a/contrib/libs/liburing/test/eeed8b54e0df.c
+++ b/contrib/libs/liburing/test/eeed8b54e0df.c
@@ -114,8 +114,10 @@ int main(int argc, char *argv[])
}
close(fd);
+ free(iov.iov_base);
return ret;
err:
close(fd);
+ free(iov.iov_base);
return T_EXIT_FAIL;
}
diff --git a/contrib/libs/liburing/test/eeed8b54e0df.t/ya.make b/contrib/libs/liburing/test/eeed8b54e0df.t/ya.make
index a602da28d2..957ea0974b 100644
--- a/contrib/libs/liburing/test/eeed8b54e0df.t/ya.make
+++ b/contrib/libs/liburing/test/eeed8b54e0df.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/empty-eownerdead.t/ya.make b/contrib/libs/liburing/test/empty-eownerdead.t/ya.make
index 412814da83..0a5793fc38 100644
--- a/contrib/libs/liburing/test/empty-eownerdead.t/ya.make
+++ b/contrib/libs/liburing/test/empty-eownerdead.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/eploop.t/ya.make b/contrib/libs/liburing/test/eploop.t/ya.make
index 6461e6be2c..68badedcda 100644
--- a/contrib/libs/liburing/test/eploop.t/ya.make
+++ b/contrib/libs/liburing/test/eploop.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/eventfd-disable.t/ya.make b/contrib/libs/liburing/test/eventfd-disable.t/ya.make
index 01b42db6c5..c1a4ac6945 100644
--- a/contrib/libs/liburing/test/eventfd-disable.t/ya.make
+++ b/contrib/libs/liburing/test/eventfd-disable.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/eventfd-reg.t/ya.make b/contrib/libs/liburing/test/eventfd-reg.t/ya.make
index 193586f9bc..8564f783bb 100644
--- a/contrib/libs/liburing/test/eventfd-reg.t/ya.make
+++ b/contrib/libs/liburing/test/eventfd-reg.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/eventfd-ring.t/ya.make b/contrib/libs/liburing/test/eventfd-ring.t/ya.make
index 45d2e55520..fb4c4ffce2 100644
--- a/contrib/libs/liburing/test/eventfd-ring.t/ya.make
+++ b/contrib/libs/liburing/test/eventfd-ring.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/eventfd.c b/contrib/libs/liburing/test/eventfd.c
index 081987f520..392eebe414 100644
--- a/contrib/libs/liburing/test/eventfd.c
+++ b/contrib/libs/liburing/test/eventfd.c
@@ -61,7 +61,6 @@ int main(int argc, char *argv[])
sqe = io_uring_get_sqe(&ring);
io_uring_prep_readv(sqe, evfd, &vec, 1, 0);
- sqe->flags |= IOSQE_IO_LINK;
sqe->user_data = 2;
ret = io_uring_submit(&ring);
diff --git a/contrib/libs/liburing/test/eventfd.t/ya.make b/contrib/libs/liburing/test/eventfd.t/ya.make
index b64217ee96..f8b1939032 100644
--- a/contrib/libs/liburing/test/eventfd.t/ya.make
+++ b/contrib/libs/liburing/test/eventfd.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/evloop.t/ya.make b/contrib/libs/liburing/test/evloop.t/ya.make
index a5c92be9ca..084615c89e 100644
--- a/contrib/libs/liburing/test/evloop.t/ya.make
+++ b/contrib/libs/liburing/test/evloop.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/exec-target.t/ya.make b/contrib/libs/liburing/test/exec-target.t/ya.make
index b47e7f3a0f..bc92a41119 100644
--- a/contrib/libs/liburing/test/exec-target.t/ya.make
+++ b/contrib/libs/liburing/test/exec-target.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/exit-no-cleanup.c b/contrib/libs/liburing/test/exit-no-cleanup.c
index abf63ab2b0..8b1346ffbe 100644
--- a/contrib/libs/liburing/test/exit-no-cleanup.c
+++ b/contrib/libs/liburing/test/exit-no-cleanup.c
@@ -20,6 +20,11 @@
#include "liburing.h"
#include "helpers.h"
+// on fast enough machines with enough cores, the first few threads will post
+// enough sem's to cause the main thread to exit while some threads are half way
+// initialization. This causes a null deference somewhere in thread cleanup,
+// which trips ASAN.
+#ifndef CONFIG_USE_SANITIZER
#define IORING_ENTRIES 8
static pthread_t *threads;
@@ -116,3 +121,9 @@ int main(int argc, char *argv[])
// Exit without resource cleanup
exit(EXIT_SUCCESS);
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/exit-no-cleanup.t/ya.make b/contrib/libs/liburing/test/exit-no-cleanup.t/ya.make
index 6043dd7ec9..e068bc8fd0 100644
--- a/contrib/libs/liburing/test/exit-no-cleanup.t/ya.make
+++ b/contrib/libs/liburing/test/exit-no-cleanup.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fadvise.c b/contrib/libs/liburing/test/fadvise.c
index 12b7ffd912..41ba0b6930 100644
--- a/contrib/libs/liburing/test/fadvise.c
+++ b/contrib/libs/liburing/test/fadvise.c
@@ -19,30 +19,6 @@
#define LOOPS 100
#define MIN_LOOPS 10
-static unsigned long long utime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000000;
- return sec + usec;
-}
-
-static unsigned long long utime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return utime_since(tv, &end);
-}
-
static int do_fadvise(struct io_uring *ring, int fd, off_t offset, off_t len,
int advice)
{
@@ -93,7 +69,7 @@ static long do_read(int fd, char *buf)
perror("lseek");
return -1;
}
-
+
gettimeofday(&tv, NULL);
ret = read(fd, buf, FILE_SIZE);
t = utime_since_now(&tv);
@@ -116,6 +92,8 @@ static int test_fadvise(struct io_uring *ring, const char *filename)
fd = open(filename, O_RDONLY);
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -149,9 +127,12 @@ static int test_fadvise(struct io_uring *ring, const char *filename)
return 1;
if (cached_read < uncached_read &&
- cached_read2 < uncached_read)
+ cached_read2 < uncached_read) {
+ free(buf);
return 0;
+ }
+ free(buf);
return 2;
}
@@ -175,6 +156,8 @@ int main(int argc, char *argv[])
good = bad = 0;
for (i = 0; i < LOOPS; i++) {
ret = test_fadvise(&ring, fname);
+ if (ret == T_EXIT_SKIP)
+ return T_EXIT_SKIP;
if (ret == 1) {
fprintf(stderr, "read_fadvise failed\n");
goto err;
diff --git a/contrib/libs/liburing/test/fadvise.t/ya.make b/contrib/libs/liburing/test/fadvise.t/ya.make
index 05e6a24928..38376037fd 100644
--- a/contrib/libs/liburing/test/fadvise.t/ya.make
+++ b/contrib/libs/liburing/test/fadvise.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fallocate.t/ya.make b/contrib/libs/liburing/test/fallocate.t/ya.make
index 93b93c9d99..ecba017172 100644
--- a/contrib/libs/liburing/test/fallocate.t/ya.make
+++ b/contrib/libs/liburing/test/fallocate.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fc2a85cb02ef.t/ya.make b/contrib/libs/liburing/test/fc2a85cb02ef.t/ya.make
index 96ffd42829..ab94c228da 100644
--- a/contrib/libs/liburing/test/fc2a85cb02ef.t/ya.make
+++ b/contrib/libs/liburing/test/fc2a85cb02ef.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fd-install.t/ya.make b/contrib/libs/liburing/test/fd-install.t/ya.make
index 55f72f4d28..714c7d216c 100644
--- a/contrib/libs/liburing/test/fd-install.t/ya.make
+++ b/contrib/libs/liburing/test/fd-install.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fd-pass.t/ya.make b/contrib/libs/liburing/test/fd-pass.t/ya.make
index d7cf684aab..913a1e7929 100644
--- a/contrib/libs/liburing/test/fd-pass.t/ya.make
+++ b/contrib/libs/liburing/test/fd-pass.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fdinfo.c b/contrib/libs/liburing/test/fdinfo.c
new file mode 100644
index 0000000000..ffd82b5133
--- /dev/null
+++ b/contrib/libs/liburing/test/fdinfo.c
@@ -0,0 +1,428 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: basic read/write tests with buffered, O_DIRECT, and SQPOLL
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <poll.h>
+#include <sys/eventfd.h>
+#include <sys/resource.h>
+
+#include "helpers.h"
+#include "liburing.h"
+
+#define FILE_SIZE (256 * 1024)
+#define BS 8192
+#define BUFFERS (FILE_SIZE / BS)
+
+static struct iovec *vecs;
+static int no_read;
+static int warned;
+
+static void fdinfo_read(struct io_uring *ring)
+{
+ char fd_name[128];
+ char *buf;
+ int fd;
+
+ buf = malloc(4096);
+
+ sprintf(fd_name, "/proc/self/fdinfo/%d", ring->ring_fd);
+ fd = open(fd_name, O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return;
+ }
+
+ do {
+ int ret = read(fd, buf, 4096);
+
+ if (ret < 0) {
+ perror("fdinfo read");
+ break;
+ } else if (ret == 4096) {
+ continue;
+ }
+ break;
+ } while (1);
+
+ close(fd);
+ free(buf);
+}
+
+static int __test_io(const char *file, struct io_uring *ring, int write,
+ int buffered, int sqthread, int fixed, int nonvec,
+ int buf_select, int seq, int exp_len)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int open_flags;
+ int i, fd = -1, ret;
+ off_t offset;
+
+#ifdef VERBOSE
+ fprintf(stdout, "%s: start %d/%d/%d/%d/%d: ", __FUNCTION__, write,
+ buffered, sqthread,
+ fixed, nonvec);
+#endif
+ if (write)
+ open_flags = O_WRONLY;
+ else
+ open_flags = O_RDONLY;
+ if (!buffered)
+ open_flags |= O_DIRECT;
+
+ if (fixed) {
+ ret = t_register_buffers(ring, vecs, BUFFERS);
+ if (ret == T_SETUP_SKIP)
+ return T_EXIT_SKIP;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "buffer reg failed: %d\n", ret);
+ goto err;
+ }
+ }
+
+ fd = open(file, open_flags);
+ if (fd < 0) {
+ if (errno == EINVAL)
+ return 0;
+ if (errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
+ perror("file open");
+ goto err;
+ }
+
+ if (sqthread) {
+ ret = io_uring_register_files(ring, &fd, 1);
+ if (ret) {
+ fprintf(stderr, "file reg failed: %d\n", ret);
+ goto err;
+ }
+ }
+
+ offset = 0;
+ for (i = 0; i < BUFFERS; i++) {
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "sqe get failed\n");
+ goto err;
+ }
+ if (!seq)
+ offset = BS * (rand() % BUFFERS);
+ if (write) {
+ int do_fixed = fixed;
+ int use_fd = fd;
+
+ if (sqthread)
+ use_fd = 0;
+ if (fixed && (i & 1))
+ do_fixed = 0;
+ if (do_fixed) {
+ io_uring_prep_write_fixed(sqe, use_fd, vecs[i].iov_base,
+ vecs[i].iov_len,
+ offset, i);
+ } else if (nonvec) {
+ io_uring_prep_write(sqe, use_fd, vecs[i].iov_base,
+ vecs[i].iov_len, offset);
+ } else {
+ io_uring_prep_writev(sqe, use_fd, &vecs[i], 1,
+ offset);
+ }
+ } else {
+ int do_fixed = fixed;
+ int use_fd = fd;
+
+ if (sqthread)
+ use_fd = 0;
+ if (fixed && (i & 1))
+ do_fixed = 0;
+ if (do_fixed) {
+ io_uring_prep_read_fixed(sqe, use_fd, vecs[i].iov_base,
+ vecs[i].iov_len,
+ offset, i);
+ } else if (nonvec) {
+ io_uring_prep_read(sqe, use_fd, vecs[i].iov_base,
+ vecs[i].iov_len, offset);
+ } else {
+ io_uring_prep_readv(sqe, use_fd, &vecs[i], 1,
+ offset);
+ }
+
+ }
+ sqe->user_data = i;
+ if (sqthread)
+ sqe->flags |= IOSQE_FIXED_FILE;
+ if (buf_select) {
+ if (nonvec)
+ sqe->addr = 0;
+ sqe->flags |= IOSQE_BUFFER_SELECT;
+ sqe->buf_group = buf_select;
+ }
+ if (seq)
+ offset += BS;
+ }
+
+ fdinfo_read(ring);
+
+ ret = io_uring_submit(ring);
+ if (ret != BUFFERS) {
+ fprintf(stderr, "submit got %d, wanted %d\n", ret, BUFFERS);
+ goto err;
+ }
+
+ for (i = 0; i < 10; i++) {
+ fdinfo_read(ring);
+ usleep(2);
+ }
+
+ for (i = 0; i < BUFFERS; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe=%d\n", ret);
+ goto err;
+ }
+ if (cqe->res == -EINVAL && nonvec) {
+ if (!warned) {
+ fprintf(stdout, "Non-vectored IO not "
+ "supported, skipping\n");
+ warned = 1;
+ no_read = 1;
+ }
+ } else if (exp_len == -1) {
+ int iov_len = vecs[cqe->user_data].iov_len;
+
+ if (cqe->res != iov_len) {
+ fprintf(stderr, "cqe res %d, wanted %d\n",
+ cqe->res, iov_len);
+ goto err;
+ }
+ } else if (cqe->res != exp_len) {
+ fprintf(stderr, "cqe res %d, wanted %d\n", cqe->res, exp_len);
+ goto err;
+ }
+ if (buf_select && exp_len == BS) {
+ int bid = cqe->flags >> 16;
+ unsigned char *ptr = vecs[bid].iov_base;
+ int j;
+
+ for (j = 0; j < BS; j++) {
+ if (ptr[j] == cqe->user_data)
+ continue;
+
+ fprintf(stderr, "Data mismatch! bid=%d, "
+ "wanted=%d, got=%d\n", bid,
+ (int)cqe->user_data, ptr[j]);
+ return 1;
+ }
+ }
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ if (fixed) {
+ ret = io_uring_unregister_buffers(ring);
+ if (ret) {
+ fprintf(stderr, "buffer unreg failed: %d\n", ret);
+ goto err;
+ }
+ }
+ if (sqthread) {
+ ret = io_uring_unregister_files(ring);
+ if (ret) {
+ fprintf(stderr, "file unreg failed: %d\n", ret);
+ goto err;
+ }
+ }
+
+ close(fd);
+#ifdef VERBOSE
+ fprintf(stdout, "PASS\n");
+#endif
+ return 0;
+err:
+#ifdef VERBOSE
+ fprintf(stderr, "FAILED\n");
+#endif
+ if (fd != -1)
+ close(fd);
+ return 1;
+}
+static int test_io(const char *file, int write, int buffered, int sqthread,
+ int fixed, int nonvec, int exp_len)
+{
+ struct io_uring ring;
+ int ret, ring_flags = 0;
+
+ if (sqthread)
+ ring_flags = IORING_SETUP_SQPOLL;
+
+ ret = t_create_ring(64, &ring, ring_flags);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ ret = __test_io(file, &ring, write, buffered, sqthread, fixed, nonvec,
+ 0, 0, exp_len);
+ io_uring_queue_exit(&ring);
+ return ret;
+}
+
+static int has_nonvec_read(void)
+{
+ struct io_uring_probe *p;
+ struct io_uring ring;
+ int ret;
+
+ ret = io_uring_queue_init(1, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ exit(ret);
+ }
+
+ p = t_calloc(1, sizeof(*p) + 256 * sizeof(struct io_uring_probe_op));
+ ret = io_uring_register_probe(&ring, p, 256);
+ /* if we don't have PROBE_REGISTER, we don't have OP_READ/WRITE */
+ if (ret == -EINVAL) {
+out:
+ io_uring_queue_exit(&ring);
+ free(p);
+ return 0;
+ } else if (ret) {
+ fprintf(stderr, "register_probe: %d\n", ret);
+ goto out;
+ }
+
+ if (p->ops_len <= IORING_OP_READ)
+ goto out;
+ if (!(p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED))
+ goto out;
+ io_uring_queue_exit(&ring);
+ free(p);
+ return 1;
+}
+
+static int test_eventfd_read(int flags)
+{
+ struct io_uring ring;
+ int fd, ret;
+ eventfd_t event;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+
+ if (no_read)
+ return 0;
+ ret = t_create_ring(64, &ring, flags);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ if (ret == -EINVAL)
+ return 0;
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ fd = eventfd(1, 0);
+ if (fd < 0) {
+ perror("eventfd");
+ return 1;
+ }
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read(sqe, fd, &event, sizeof(eventfd_t), 0);
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "submitted %d\n", ret);
+ return 1;
+ }
+ fdinfo_read(&ring);
+ eventfd_write(fd, 1);
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe=%d\n", ret);
+ return 1;
+ }
+ if (cqe->res == -EINVAL) {
+ fprintf(stdout, "eventfd IO not supported, skipping\n");
+ } else if (cqe->res != sizeof(eventfd_t)) {
+ fprintf(stderr, "cqe res %d, wanted %d\n", cqe->res,
+ (int) sizeof(eventfd_t));
+ return 1;
+ }
+ io_uring_cqe_seen(&ring, cqe);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int i, ret, nr;
+ char buf[256];
+ char *fname;
+
+ if (argc > 1) {
+ fname = argv[1];
+ } else {
+ srand((unsigned)time(NULL));
+ snprintf(buf, sizeof(buf), ".basic-rw-%u-%u",
+ (unsigned)rand(), (unsigned)getpid());
+ fname = buf;
+ t_create_file(fname, FILE_SIZE);
+ }
+
+ signal(SIGXFSZ, SIG_IGN);
+
+ vecs = t_create_buffers(BUFFERS, BS);
+
+ /* if we don't have nonvec read, skip testing that */
+ nr = has_nonvec_read() ? 32 : 16;
+
+ for (i = 0; i < nr; i++) {
+ int write = (i & 1) != 0;
+ int buffered = (i & 2) != 0;
+ int sqthread = (i & 4) != 0;
+ int fixed = (i & 8) != 0;
+ int nonvec = (i & 16) != 0;
+
+ ret = test_io(fname, write, buffered, sqthread, fixed, nonvec,
+ BS);
+ if (ret == T_EXIT_SKIP)
+ continue;
+ if (ret) {
+ fprintf(stderr, "test_io failed %d/%d/%d/%d/%d\n",
+ write, buffered, sqthread, fixed, nonvec);
+ goto err;
+ }
+ }
+
+ ret = test_eventfd_read(0);
+ if (ret) {
+ fprintf(stderr, "eventfd read 0 failed\n");
+ goto err;
+ }
+
+ ret = test_eventfd_read(IORING_SETUP_DEFER_TASKRUN|IORING_SETUP_SINGLE_ISSUER);
+ if (ret) {
+ fprintf(stderr, "eventfd read defer failed\n");
+ goto err;
+ }
+
+ ret = test_eventfd_read(IORING_SETUP_SQPOLL);
+ if (ret) {
+ fprintf(stderr, "eventfd read sqpoll failed\n");
+ goto err;
+ }
+
+ if (fname != argv[1])
+ unlink(fname);
+ return 0;
+err:
+ if (fname != argv[1])
+ unlink(fname);
+ return 1;
+}
diff --git a/contrib/libs/liburing/test/fdinfo.t/ya.make b/contrib/libs/liburing/test/fdinfo.t/ya.make
new file mode 100644
index 0000000000..6dc3cfe9e9
--- /dev/null
+++ b/contrib/libs/liburing/test/fdinfo.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ fdinfo.c
+ helpers.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/fifo-nonblock-read.c b/contrib/libs/liburing/test/fifo-nonblock-read.c
new file mode 100644
index 0000000000..4f135c696d
--- /dev/null
+++ b/contrib/libs/liburing/test/fifo-nonblock-read.c
@@ -0,0 +1,70 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: Test O_NONBLOCK reading from fifo, should result in proper
+ * retry and a positive read results. Buggy result would be
+ * -EAGAIN being returned to the user.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+int main(int argc, char *argv[])
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct io_uring ring;
+ char buf[32];
+ int fds[2];
+ int flags;
+ int ret;
+
+ io_uring_queue_init(1, &ring, 0);
+
+ if (pipe(fds) < 0) {
+ perror("pipe");
+ return T_EXIT_FAIL;
+ }
+
+ flags = fcntl(fds[0], F_GETFL, 0);
+ if (flags < 0) {
+ perror("fcntl get");
+ return T_EXIT_FAIL;
+ }
+ flags |= O_NONBLOCK;
+ ret = fcntl(fds[0], F_SETFL, flags);
+ if (ret < 0) {
+ perror("fcntl set");
+ return T_EXIT_FAIL;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0);
+ io_uring_submit(&ring);
+
+ usleep(10000);
+
+ ret = write(fds[1], "Hello\n", 6);
+ if (ret < 0) {
+ perror("pipe write");
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait=%d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ if (cqe->res < 0) {
+ fprintf(stderr, "cqe res %d\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_cqe_seen(&ring, cqe);
+ io_uring_queue_exit(&ring);
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/fifo-nonblock-read.t/ya.make b/contrib/libs/liburing/test/fifo-nonblock-read.t/ya.make
new file mode 100644
index 0000000000..497262e908
--- /dev/null
+++ b/contrib/libs/liburing/test/fifo-nonblock-read.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ fifo-nonblock-read.c
+ helpers.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/file-register.c b/contrib/libs/liburing/test/file-register.c
index ce51022632..de35d16d2d 100644
--- a/contrib/libs/liburing/test/file-register.c
+++ b/contrib/libs/liburing/test/file-register.c
@@ -121,16 +121,21 @@ static int test_grow(struct io_uring *ring)
fds = open_files(1, 0, off);
ret = io_uring_register_files_update(ring, off, fds, 1);
if (ret != 1) {
- if (off == 300 && ret == -EINVAL)
+ if (off == 300 && ret == -EINVAL) {
+ free(fds);
break;
+ }
fprintf(stderr, "%s: update ret=%d\n", __FUNCTION__, ret);
+ free(fds);
break;
}
if (off >= 300) {
fprintf(stderr, "%s: Succeeded beyond end-of-list?\n", __FUNCTION__);
+ free(fds);
goto err;
}
off++;
+ free(fds);
} while (1);
ret = io_uring_unregister_files(ring);
@@ -364,8 +369,10 @@ static int test_basic(struct io_uring *ring, int fail)
ret = io_uring_register_files(ring, files, 100);
if (ret) {
if (fail) {
- if (ret == -EBADF || ret == -EFAULT)
+ if (ret == -EBADF || ret == -EFAULT) {
+ close_files(files, nr_files, 0);
return 0;
+ }
}
fprintf(stderr, "%s: register %d\n", __FUNCTION__, ret);
goto err;
@@ -632,6 +639,7 @@ static int test_sparse_updates(void)
ret = io_uring_register_files(&ring, fds, 256);
if (ret) {
fprintf(stderr, "file_register: %d\n", ret);
+ free(fds);
return ret;
}
@@ -640,6 +648,7 @@ static int test_sparse_updates(void)
ret = io_uring_register_files_update(&ring, i, &newfd, 1);
if (ret != 1) {
fprintf(stderr, "file_update: %d\n", ret);
+ free(fds);
return ret;
}
}
@@ -651,6 +660,7 @@ static int test_sparse_updates(void)
ret = io_uring_register_files(&ring, fds, 256);
if (ret) {
fprintf(stderr, "file_register: %d\n", ret);
+ free(fds);
return ret;
}
@@ -659,12 +669,14 @@ static int test_sparse_updates(void)
ret = io_uring_register_files_update(&ring, i, &newfd, 1);
if (ret != 1) {
fprintf(stderr, "file_update: %d\n", ret);
+ free(fds);
return ret;
}
}
io_uring_unregister_files(&ring);
io_uring_queue_exit(&ring);
+ free(fds);
return 0;
}
diff --git a/contrib/libs/liburing/test/file-register.t/ya.make b/contrib/libs/liburing/test/file-register.t/ya.make
index f7bc1cd23d..4961fbeb84 100644
--- a/contrib/libs/liburing/test/file-register.t/ya.make
+++ b/contrib/libs/liburing/test/file-register.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/file-update.c b/contrib/libs/liburing/test/file-update.c
index 0896807ddf..39bb8ae99c 100644
--- a/contrib/libs/liburing/test/file-update.c
+++ b/contrib/libs/liburing/test/file-update.c
@@ -175,7 +175,7 @@ static int test_update_no_table(void)
ret = cqe->res;
io_uring_cqe_seen(&ring, cqe);
if (ret != -EMFILE && ret != -EINVAL && ret != -EOVERFLOW &&
- ret != -ENXIO) {
+ ret != -ENXIO && ret != -EBADF) {
fprintf(stderr, "Bad cqe res: %d\n", ret);
goto fail;
}
diff --git a/contrib/libs/liburing/test/file-update.t/ya.make b/contrib/libs/liburing/test/file-update.t/ya.make
index 67491db91c..3c305603b6 100644
--- a/contrib/libs/liburing/test/file-update.t/ya.make
+++ b/contrib/libs/liburing/test/file-update.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/file-verify.c b/contrib/libs/liburing/test/file-verify.c
index 0014236f5c..a2b4b00397 100644
--- a/contrib/libs/liburing/test/file-verify.c
+++ b/contrib/libs/liburing/test/file-verify.c
@@ -91,6 +91,8 @@ static int test_truncate(struct io_uring *ring, const char *fname, int buffered,
else
fd = open(fname, O_DIRECT | O_RDWR);
if (fd < 0) {
+ if (!buffered && errno == EINVAL)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -347,6 +349,8 @@ static int test(struct io_uring *ring, const char *fname, int buffered,
flags |= O_DIRECT;
fd = open(fname, flags);
if (fd < 0) {
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -506,6 +510,8 @@ static int fill_pattern(const char *fname)
fd = open(fname, O_WRONLY);
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -558,89 +564,94 @@ int main(int argc, char *argv[])
goto err;
}
- if (fill_pattern(fname))
+ ret = fill_pattern(fname);
+ if (ret == T_EXIT_SKIP)
+ return T_EXIT_SKIP;
+ else if (ret)
goto err;
ret = test(&ring, fname, 1, 0, 0, 0, 0);
+ if (ret == T_EXIT_SKIP)
+ return T_EXIT_SKIP;
if (ret) {
fprintf(stderr, "Buffered novec test failed\n");
goto err;
}
ret = test(&ring, fname, 1, 0, 0, 1, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "Buffered novec reg test failed\n");
goto err;
}
ret = test(&ring, fname, 1, 0, 0, 0, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "Buffered novec provide test failed\n");
goto err;
}
ret = test(&ring, fname, 1, 1, 0, 0, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "Buffered vec test failed\n");
goto err;
}
ret = test(&ring, fname, 1, 1, 1, 0, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "Buffered small vec test failed\n");
goto err;
}
ret = test(&ring, fname, 0, 0, 0, 0, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT novec test failed\n");
goto err;
}
ret = test(&ring, fname, 0, 0, 0, 1, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT novec reg test failed\n");
goto err;
}
ret = test(&ring, fname, 0, 0, 0, 0, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT novec provide test failed\n");
goto err;
}
ret = test(&ring, fname, 0, 1, 0, 0, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT vec test failed\n");
goto err;
}
ret = test(&ring, fname, 0, 1, 1, 0, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT small vec test failed\n");
goto err;
}
ret = test_truncate(&ring, fname, 1, 0, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "Buffered end truncate read failed\n");
goto err;
}
ret = test_truncate(&ring, fname, 1, 1, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "Buffered end truncate vec read failed\n");
goto err;
}
ret = test_truncate(&ring, fname, 1, 0, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "Buffered end truncate pbuf read failed\n");
goto err;
}
ret = test_truncate(&ring, fname, 0, 0, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT end truncate read failed\n");
goto err;
}
ret = test_truncate(&ring, fname, 0, 1, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT end truncate vec read failed\n");
goto err;
}
ret = test_truncate(&ring, fname, 0, 0, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "O_DIRECT end truncate pbuf read failed\n");
goto err;
}
diff --git a/contrib/libs/liburing/test/file-verify.t/ya.make b/contrib/libs/liburing/test/file-verify.t/ya.make
index 263b811e95..0d3a52d017 100644
--- a/contrib/libs/liburing/test/file-verify.t/ya.make
+++ b/contrib/libs/liburing/test/file-verify.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/files-exit-hang-poll.t/ya.make b/contrib/libs/liburing/test/files-exit-hang-poll.t/ya.make
index cf7bf1f7b9..499443de7f 100644
--- a/contrib/libs/liburing/test/files-exit-hang-poll.t/ya.make
+++ b/contrib/libs/liburing/test/files-exit-hang-poll.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/files-exit-hang-timeout.c b/contrib/libs/liburing/test/files-exit-hang-timeout.c
index a549e92cdb..18c45eda81 100644
--- a/contrib/libs/liburing/test/files-exit-hang-timeout.c
+++ b/contrib/libs/liburing/test/files-exit-hang-timeout.c
@@ -44,13 +44,12 @@ static void add_accept(struct io_uring *ring, int fd)
sqe = io_uring_get_sqe(ring);
io_uring_prep_accept(sqe, fd, 0, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
- sqe->flags |= IOSQE_IO_LINK;
}
static int setup_io_uring(void)
{
int ret;
-
+
ret = io_uring_queue_init(16, &ring, 0);
if (ret) {
fprintf(stderr, "Unable to setup io_uring: %s\n", strerror(-ret));
diff --git a/contrib/libs/liburing/test/files-exit-hang-timeout.t/ya.make b/contrib/libs/liburing/test/files-exit-hang-timeout.t/ya.make
index e91c801769..96e4f2eb03 100644
--- a/contrib/libs/liburing/test/files-exit-hang-timeout.t/ya.make
+++ b/contrib/libs/liburing/test/files-exit-hang-timeout.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fixed-buf-iter.c b/contrib/libs/liburing/test/fixed-buf-iter.c
index 1cdb327166..d4df6cad9a 100644
--- a/contrib/libs/liburing/test/fixed-buf-iter.c
+++ b/contrib/libs/liburing/test/fixed-buf-iter.c
@@ -64,7 +64,7 @@ static int test(struct io_uring *ring)
return 1;
}
- if (cqe->res < 0) {
+ if (cqe->res < 0) {
fprintf(stderr, "Error in async operation: %s\n", strerror(-cqe->res));
return 1;
}
@@ -88,6 +88,8 @@ static int test(struct io_uring *ring)
return 1;
}
io_uring_cqe_seen(ring, cqe);
+ for (i = 0; i < BUFFERS; i++)
+ free(iov[i].iov_base);
return 0;
}
diff --git a/contrib/libs/liburing/test/fixed-buf-iter.t/ya.make b/contrib/libs/liburing/test/fixed-buf-iter.t/ya.make
index f4ea025d7f..bf3a2a7618 100644
--- a/contrib/libs/liburing/test/fixed-buf-iter.t/ya.make
+++ b/contrib/libs/liburing/test/fixed-buf-iter.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fixed-buf-merge.t/ya.make b/contrib/libs/liburing/test/fixed-buf-merge.t/ya.make
index 78178231cc..ad58a01cf8 100644
--- a/contrib/libs/liburing/test/fixed-buf-merge.t/ya.make
+++ b/contrib/libs/liburing/test/fixed-buf-merge.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fixed-hugepage.c b/contrib/libs/liburing/test/fixed-hugepage.c
index bbc28bb8a6..b95169fdaa 100644
--- a/contrib/libs/liburing/test/fixed-hugepage.c
+++ b/contrib/libs/liburing/test/fixed-hugepage.c
@@ -247,7 +247,8 @@ static int register_submit(struct io_uring *ring, struct iovec *iov,
ret = io_uring_register_buffers(ring, iov, nr_bufs);
if (ret) {
- fprintf(stderr, "Error registering buffers: %s\n", strerror(-ret));
+ if (ret != -ENOMEM)
+ fprintf(stderr, "Error registering buffers: %s\n", strerror(-ret));
return ret;
}
@@ -283,6 +284,8 @@ static int test_one_hugepage(struct io_uring *ring, int fd_in, int fd_out)
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
unmap(iov, NR_BUFS, 0);
+ if (ret == -ENOMEM)
+ return T_EXIT_SKIP;
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
}
@@ -297,6 +300,8 @@ static int test_multi_hugepages(struct io_uring *ring, int fd_in, int fd_out)
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
unmap(iov, NR_BUFS, 0);
+ if (ret == -ENOMEM)
+ return T_EXIT_SKIP;
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
}
@@ -312,6 +317,8 @@ static int test_unaligned_hugepage(struct io_uring *ring, int fd_in, int fd_out)
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
unmap(iov, NR_BUFS, offset);
+ if (ret == -ENOMEM)
+ return T_EXIT_SKIP;
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
}
@@ -327,6 +334,8 @@ static int test_multi_unaligned_mthps(struct io_uring *ring, int fd_in, int fd_o
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
free_bufs(iov, NR_BUFS, offset);
+ if (ret == -ENOMEM)
+ return T_EXIT_SKIP;
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
}
@@ -342,6 +351,8 @@ static int test_page_mixture(struct io_uring *ring, int fd_in, int fd_out, int h
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
unmap(iov, NR_BUFS, 0);
+ if (ret == -ENOMEM)
+ return T_EXIT_SKIP;
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/fixed-hugepage.t/ya.make b/contrib/libs/liburing/test/fixed-hugepage.t/ya.make
index 9c4ef3dbe4..ad560a9a58 100644
--- a/contrib/libs/liburing/test/fixed-hugepage.t/ya.make
+++ b/contrib/libs/liburing/test/fixed-hugepage.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fixed-link.t/ya.make b/contrib/libs/liburing/test/fixed-link.t/ya.make
index afc5190ea1..1e788313a8 100644
--- a/contrib/libs/liburing/test/fixed-link.t/ya.make
+++ b/contrib/libs/liburing/test/fixed-link.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fixed-reuse.t/ya.make b/contrib/libs/liburing/test/fixed-reuse.t/ya.make
index 711704cf4d..d0379a8966 100644
--- a/contrib/libs/liburing/test/fixed-reuse.t/ya.make
+++ b/contrib/libs/liburing/test/fixed-reuse.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fpos.t/ya.make b/contrib/libs/liburing/test/fpos.t/ya.make
index f9faf5bee7..2ad48f2c07 100644
--- a/contrib/libs/liburing/test/fpos.t/ya.make
+++ b/contrib/libs/liburing/test/fpos.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/fsync.t/ya.make b/contrib/libs/liburing/test/fsync.t/ya.make
index c3be5c5b45..5c383794b0 100644
--- a/contrib/libs/liburing/test/fsync.t/ya.make
+++ b/contrib/libs/liburing/test/fsync.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/futex.c b/contrib/libs/liburing/test/futex.c
index 7a7f0c235c..7b2d36ac98 100644
--- a/contrib/libs/liburing/test/futex.c
+++ b/contrib/libs/liburing/test/futex.c
@@ -121,6 +121,7 @@ static int __test(struct io_uring *ring, int vectored, int async,
if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) {
no_futex = 1;
+ free(futex);
return 0;
}
io_uring_cqe_seen(ring, cqe);
@@ -135,6 +136,7 @@ static int __test(struct io_uring *ring, int vectored, int async,
for (i = 0; i < nfutex; i++)
pthread_join(threads[i], &tret);
+ free(futex);
return 0;
}
@@ -146,7 +148,7 @@ static int test(int flags, int vectored)
ret = io_uring_queue_init(8, &ring, flags);
if (ret)
return ret;
-
+
for (i = 0; i < LOOPS; i++) {
int async_cancel = (!i % 2);
int async_wait = !(i % 3);
@@ -167,7 +169,8 @@ static int test_order(int vectored, int async)
{
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
- struct futex_waitv fw;
+ struct futex_waitv fw = { };
+ struct io_uring_sync_cancel_reg reg = { };
struct io_uring ring;
unsigned int *futex;
int ret, i;
@@ -179,10 +182,8 @@ static int test_order(int vectored, int async)
futex = malloc(sizeof(*futex));
*futex = 0;
- fw.val = 0;
fw.uaddr = (unsigned long) futex;
fw.flags = FUTEX2_SIZE_U32;
- fw.__reserved = 0;
/*
* Submit two futex waits
@@ -242,7 +243,15 @@ static int test_order(int vectored, int async)
return 1;
}
+ reg.addr = 2;
+ ret = io_uring_register_sync_cancel(&ring, &reg);
+ if (ret != 1) {
+ fprintf(stderr, "Failed to cancel pending futex wait: %d\n", ret);
+ return 1;
+ }
+
io_uring_queue_exit(&ring);
+ free(futex);
return 0;
}
@@ -323,6 +332,7 @@ static int test_multi_wake(int vectored)
}
io_uring_queue_exit(&ring);
+ free(futex);
return 0;
}
@@ -379,6 +389,7 @@ static int test_wake_zero(void)
}
io_uring_queue_exit(&ring);
+ free(futex);
return 0;
}
@@ -460,6 +471,7 @@ static int test_invalid(void)
io_uring_cqe_seen(&ring, cqe);
io_uring_queue_exit(&ring);
+ free(futex);
return 0;
}
diff --git a/contrib/libs/liburing/test/futex.t/ya.make b/contrib/libs/liburing/test/futex.t/ya.make
index 66ce3413c2..6dcd421f49 100644
--- a/contrib/libs/liburing/test/futex.t/ya.make
+++ b/contrib/libs/liburing/test/futex.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/hardlink.t/ya.make b/contrib/libs/liburing/test/hardlink.t/ya.make
index 970e1a324c..0c4c74ed38 100644
--- a/contrib/libs/liburing/test/hardlink.t/ya.make
+++ b/contrib/libs/liburing/test/hardlink.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/helpers.c b/contrib/libs/liburing/test/helpers.c
index 0d897271d8..2f09df4f23 100644
--- a/contrib/libs/liburing/test/helpers.c
+++ b/contrib/libs/liburing/test/helpers.c
@@ -317,3 +317,50 @@ void t_error(int status, int errnum, const char *format, ...)
va_end(args);
exit(status);
}
+
+unsigned long long mtime_since(const struct timeval *s, const struct timeval *e)
+{
+ long long sec, usec;
+
+ sec = e->tv_sec - s->tv_sec;
+ usec = (e->tv_usec - s->tv_usec);
+ if (sec > 0 && usec < 0) {
+ sec--;
+ usec += 1000000;
+ }
+
+ sec *= 1000;
+ usec /= 1000;
+ return sec + usec;
+}
+
+unsigned long long mtime_since_now(struct timeval *tv)
+{
+ struct timeval end;
+
+ gettimeofday(&end, NULL);
+ return mtime_since(tv, &end);
+}
+
+unsigned long long utime_since(const struct timeval *s, const struct timeval *e)
+{
+ long long sec, usec;
+
+ sec = e->tv_sec - s->tv_sec;
+ usec = (e->tv_usec - s->tv_usec);
+ if (sec > 0 && usec < 0) {
+ sec--;
+ usec += 1000000;
+ }
+
+ sec *= 1000000;
+ return sec + usec;
+}
+
+unsigned long long utime_since_now(struct timeval *tv)
+{
+ struct timeval end;
+
+ gettimeofday(&end, NULL);
+ return utime_since(tv, &end);
+}
diff --git a/contrib/libs/liburing/test/helpers.h b/contrib/libs/liburing/test/helpers.h
index 9f62a5f63f..9e1cdf5ec0 100644
--- a/contrib/libs/liburing/test/helpers.h
+++ b/contrib/libs/liburing/test/helpers.h
@@ -12,6 +12,7 @@ extern "C" {
#include "liburing.h"
#include "../src/setup.h"
#include <arpa/inet.h>
+#include <sys/time.h>
enum t_setup_ret {
T_SETUP_OK = 0,
@@ -101,6 +102,11 @@ static inline int t_io_uring_init_sqarray(unsigned entries, struct io_uring *rin
void t_error(int status, int errnum, const char *format, ...);
+unsigned long long mtime_since(const struct timeval *s, const struct timeval *e);
+unsigned long long mtime_since_now(struct timeval *tv);
+unsigned long long utime_since(const struct timeval *s, const struct timeval *e);
+unsigned long long utime_since_now(struct timeval *tv);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/libs/liburing/test/ignore-single-mmap.c b/contrib/libs/liburing/test/ignore-single-mmap.c
index 2790b871d3..4b772e3327 100644
--- a/contrib/libs/liburing/test/ignore-single-mmap.c
+++ b/contrib/libs/liburing/test/ignore-single-mmap.c
@@ -3,7 +3,7 @@
/*
* 6.10-rc merge window had a bug where the rewritten mmap support caused
* rings allocated with > 1 page, but asking for smaller mappings, would
- * cause -EFAULT to be returned rather than a succesful map. This hit
+ * cause -EFAULT to be returned rather than a successful map. This hit
* applications either using an ancient liburing with IORING_FEAT_SINGLE_MMAP
* support, or application just ignoring that feature flag and still doing
* 3 mmap operations to map the ring.
diff --git a/contrib/libs/liburing/test/ignore-single-mmap.t/ya.make b/contrib/libs/liburing/test/ignore-single-mmap.t/ya.make
index 3942706db9..82fc501ee6 100644
--- a/contrib/libs/liburing/test/ignore-single-mmap.t/ya.make
+++ b/contrib/libs/liburing/test/ignore-single-mmap.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/init-mem.c b/contrib/libs/liburing/test/init-mem.c
index 1909e2ac5f..ad71e8278b 100644
--- a/contrib/libs/liburing/test/init-mem.c
+++ b/contrib/libs/liburing/test/init-mem.c
@@ -14,7 +14,6 @@
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <net/if.h>
-#include <error.h>
#include "liburing.h"
#include "helpers.h"
@@ -43,7 +42,7 @@ static int setup_ctx(struct ctx *ctx, struct q_entries *q)
if (posix_memalign(&ctx->mem, 4096, 2*1024*1024))
return T_EXIT_FAIL;
- ctx->pre = ctx->mem + 4096 - sizeof(unsigned long);
+ ctx->pre = ctx->mem + 4096 - sizeof(unsigned long long);
*ctx->pre = PRE_RED;
ctx->ring_mem = ctx->mem + 4096;
@@ -69,6 +68,7 @@ static int setup_ctx(struct ctx *ctx, struct q_entries *q)
static void clean_ctx(struct ctx *ctx)
{
io_uring_queue_exit(&ctx->ring);
+ free(ctx->mem);
}
static int check_red(struct ctx *ctx, unsigned long i)
@@ -95,10 +95,12 @@ static int test(struct q_entries *q)
int j, ret, batch;
ret = setup_ctx(&ctx, q);
- if (ret == T_EXIT_SKIP)
+ if (ret == T_EXIT_SKIP) {
+ clean_ctx(&ctx);
return T_EXIT_SKIP;
- else if (ret != T_EXIT_PASS)
+ } else if (ret != T_EXIT_PASS) {
return ret;
+ }
batch = 64;
if (batch > q->sqes)
diff --git a/contrib/libs/liburing/test/init-mem.t/ya.make b/contrib/libs/liburing/test/init-mem.t/ya.make
index c60cfe5615..0cd8d18352 100644
--- a/contrib/libs/liburing/test/init-mem.t/ya.make
+++ b/contrib/libs/liburing/test/init-mem.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/io-cancel.c b/contrib/libs/liburing/test/io-cancel.c
index 16a385f44b..64725a7c6b 100644
--- a/contrib/libs/liburing/test/io-cancel.c
+++ b/contrib/libs/liburing/test/io-cancel.c
@@ -23,30 +23,6 @@
static struct iovec *vecs;
-static unsigned long long utime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000000;
- return sec + usec;
-}
-
-static unsigned long long utime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return utime_since(tv, &end);
-}
-
static int start_io(struct io_uring *ring, int fd, int do_write)
{
struct io_uring_sqe *sqe;
diff --git a/contrib/libs/liburing/test/io-cancel.t/ya.make b/contrib/libs/liburing/test/io-cancel.t/ya.make
index 12379a4a76..ef2974bef4 100644
--- a/contrib/libs/liburing/test/io-cancel.t/ya.make
+++ b/contrib/libs/liburing/test/io-cancel.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/io_uring_enter.t/ya.make b/contrib/libs/liburing/test/io_uring_enter.t/ya.make
index 83a0199127..ea11807c30 100644
--- a/contrib/libs/liburing/test/io_uring_enter.t/ya.make
+++ b/contrib/libs/liburing/test/io_uring_enter.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/io_uring_passthrough.c b/contrib/libs/liburing/test/io_uring_passthrough.c
index ad6b6d3e5f..e08b220d88 100644
--- a/contrib/libs/liburing/test/io_uring_passthrough.c
+++ b/contrib/libs/liburing/test/io_uring_passthrough.c
@@ -96,6 +96,8 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
fd = open(file, open_flags);
if (fd < 0) {
+ if (errno == EACCES || errno == EPERM)
+ return T_EXIT_SKIP;
perror("file open");
goto err;
}
@@ -166,6 +168,8 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
}
}
sqe->opcode = IORING_OP_URING_CMD;
+ if (do_fixed)
+ sqe->uring_cmd_flags |= IORING_URING_CMD_FIXED;
sqe->user_data = ((uint64_t)offset << 32) | i;
if (sqthread)
sqe->flags |= IOSQE_FIXED_FILE;
diff --git a/contrib/libs/liburing/test/io_uring_passthrough.t/ya.make b/contrib/libs/liburing/test/io_uring_passthrough.t/ya.make
index 63a2078929..5e3b4fc961 100644
--- a/contrib/libs/liburing/test/io_uring_passthrough.t/ya.make
+++ b/contrib/libs/liburing/test/io_uring_passthrough.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/io_uring_register.c b/contrib/libs/liburing/test/io_uring_register.c
index c315750adc..e5d65b18ec 100644
--- a/contrib/libs/liburing/test/io_uring_register.c
+++ b/contrib/libs/liburing/test/io_uring_register.c
@@ -22,6 +22,7 @@
#include <linux/mman.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <sys/vfs.h>
#include <limits.h>
#include "helpers.h"
@@ -77,8 +78,13 @@ static int new_io_uring(int entries, struct io_uring_params *p)
#define MAXFDS (UINT_MAX * sizeof(int))
+#define OFS_MAGIC 0x794c7630
+#define TMPFS_MAGIC 0x01021994
+#define RAMFS_MAGIC 0x858458f6
+
static void *map_filebacked(size_t size)
{
+ struct statfs buf;
int fd, ret;
void *addr;
char template[32] = "io_uring_register-test-XXXXXXXX";
@@ -88,8 +94,21 @@ static void *map_filebacked(size_t size)
perror("mkstemp");
return NULL;
}
+ if (statfs(template, &buf) < 0) {
+ perror("statfs");
+ unlink(template);
+ close(fd);
+ return NULL;
+ }
unlink(template);
+ /* virtual file systems may not present as file mapped */
+ if (buf.f_type == OFS_MAGIC || buf.f_type == RAMFS_MAGIC ||
+ buf.f_type == TMPFS_MAGIC) {
+ close(fd);
+ return NULL;
+ }
+
ret = ftruncate(fd, size);
if (ret < 0) {
perror("ftruncate");
@@ -366,12 +385,12 @@ static int test_iovec_size(int fd)
/* file-backed buffers -- not supported */
buf = map_filebacked(2*1024*1024);
- if (!buf)
- status = 1;
- iov.iov_base = buf;
- iov.iov_len = 2*1024*1024;
- status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, -EOPNOTSUPP);
- munmap(buf, 2*1024*1024);
+ if (buf) {
+ iov.iov_base = buf;
+ iov.iov_len = 2*1024*1024;
+ status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, -EOPNOTSUPP);
+ munmap(buf, 2*1024*1024);
+ }
/* bump up against the soft limit and make sure we get EFAULT
* or whatever we're supposed to get. NOTE: this requires
@@ -418,14 +437,14 @@ static int ioring_poll(struct io_uring *ring, int fd, int fixed)
return ret;
}
-static int test_poll_ringfd(void)
+static int __test_poll_ringfd(int ring_flags)
{
int status = 0;
int ret;
int fd;
struct io_uring ring;
- ret = io_uring_queue_init(1, &ring, 0);
+ ret = io_uring_queue_init(2, &ring, ring_flags);
if (ret) {
perror("io_uring_queue_init");
return 1;
@@ -448,6 +467,17 @@ static int test_poll_ringfd(void)
return status;
}
+static int test_poll_ringfd(void)
+{
+ int ret;
+
+ ret = __test_poll_ringfd(0);
+ if (ret)
+ return ret;
+
+ return __test_poll_ringfd(IORING_SETUP_SQPOLL);
+}
+
int main(int argc, char **argv)
{
int fd, ret;
diff --git a/contrib/libs/liburing/test/io_uring_register.t/ya.make b/contrib/libs/liburing/test/io_uring_register.t/ya.make
index 1d46c47686..ab97e7faba 100644
--- a/contrib/libs/liburing/test/io_uring_register.t/ya.make
+++ b/contrib/libs/liburing/test/io_uring_register.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/io_uring_setup.t/ya.make b/contrib/libs/liburing/test/io_uring_setup.t/ya.make
index e98edd9af6..04d49debbc 100644
--- a/contrib/libs/liburing/test/io_uring_setup.t/ya.make
+++ b/contrib/libs/liburing/test/io_uring_setup.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/iopoll-leak.c b/contrib/libs/liburing/test/iopoll-leak.c
index 01b98fb64a..53b92426d6 100644
--- a/contrib/libs/liburing/test/iopoll-leak.c
+++ b/contrib/libs/liburing/test/iopoll-leak.c
@@ -27,6 +27,8 @@ static int do_iopoll(const char *fname)
fd = open(fname, O_RDONLY | O_DIRECT);
if (fd < 0) {
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open");
return T_EXIT_SKIP;
}
@@ -40,6 +42,8 @@ static int do_iopoll(const char *fname)
io_uring_submit(&ring);
close(fd);
+ free(iov->iov_base);
+ free(iov);
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/iopoll-leak.t/ya.make b/contrib/libs/liburing/test/iopoll-leak.t/ya.make
index f6c3268667..6d067a1f63 100644
--- a/contrib/libs/liburing/test/iopoll-leak.t/ya.make
+++ b/contrib/libs/liburing/test/iopoll-leak.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/iopoll-overflow.c b/contrib/libs/liburing/test/iopoll-overflow.c
index 96152fcfe4..aa6db71735 100644
--- a/contrib/libs/liburing/test/iopoll-overflow.c
+++ b/contrib/libs/liburing/test/iopoll-overflow.c
@@ -96,7 +96,7 @@ int main(int argc, char *argv[])
fd = open(fname, O_RDONLY | O_DIRECT);
if (fd < 0) {
- if (errno == EINVAL) {
+ if (errno == EINVAL || errno == EACCES || errno == EPERM) {
if (fname != argv[1])
unlink(fname);
return T_EXIT_SKIP;
diff --git a/contrib/libs/liburing/test/iopoll-overflow.t/ya.make b/contrib/libs/liburing/test/iopoll-overflow.t/ya.make
index ee34ce968d..f363fa5cb2 100644
--- a/contrib/libs/liburing/test/iopoll-overflow.t/ya.make
+++ b/contrib/libs/liburing/test/iopoll-overflow.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/iopoll.c b/contrib/libs/liburing/test/iopoll.c
index b77b82d945..6de0e9b78b 100644
--- a/contrib/libs/liburing/test/iopoll.c
+++ b/contrib/libs/liburing/test/iopoll.c
@@ -88,7 +88,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write, int sqt
}
fd = open(file, open_flags);
if (fd < 0) {
- if (errno == EINVAL)
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
return 0;
perror("file open");
goto err;
@@ -231,7 +231,7 @@ static int test_io_uring_cqe_peek(const char *file)
fd = open(file, O_RDONLY | O_DIRECT);
if (fd < 0) {
- if (errno == EINVAL) {
+ if (errno == EINVAL || errno == EPERM || errno == EACCES) {
io_uring_queue_exit(&ring);
return T_EXIT_SKIP;
}
@@ -303,7 +303,7 @@ static int test_io_uring_submit_enters(const char *file)
open_flags = O_WRONLY | O_DIRECT;
fd = open(file, open_flags);
if (fd < 0) {
- if (errno == EINVAL)
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
return T_EXIT_SKIP;
perror("file open");
goto err;
diff --git a/contrib/libs/liburing/test/iopoll.t/ya.make b/contrib/libs/liburing/test/iopoll.t/ya.make
index fd11b7ce20..dadb9691e0 100644
--- a/contrib/libs/liburing/test/iopoll.t/ya.make
+++ b/contrib/libs/liburing/test/iopoll.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/kallsyms.c b/contrib/libs/liburing/test/kallsyms.c
new file mode 100644
index 0000000000..f4229b8771
--- /dev/null
+++ b/contrib/libs/liburing/test/kallsyms.c
@@ -0,0 +1,204 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: read /proc/kallsyms. Mostly just here so that fops->read() can
+ * get exercised, with and without registered buffers
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <poll.h>
+#include <sys/eventfd.h>
+#include <sys/resource.h>
+
+#include "helpers.h"
+#include "liburing.h"
+
+#define FILE_SIZE (8 * 1024)
+#define BS 8192
+#define BUFFERS (FILE_SIZE / BS)
+
+static struct iovec *vecs;
+static int warned;
+
+static int __test_io(const char *file, struct io_uring *ring, int fixed, int nonvec)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int open_flags;
+ int i, fd = -1, ret;
+ off_t offset;
+
+ open_flags = O_RDONLY;
+ if (fixed) {
+ ret = t_register_buffers(ring, vecs, BUFFERS);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "buffer reg failed: %d\n", ret);
+ goto err;
+ }
+ }
+
+ fd = open(file, open_flags);
+ if (fd < 0) {
+ if (errno == EINVAL || errno == EPERM || errno == ENOENT)
+ return 0;
+ perror("file open");
+ goto err;
+ }
+
+ offset = 0;
+ for (i = 0; i < BUFFERS; i++) {
+ int do_fixed = fixed;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "sqe get failed\n");
+ goto err;
+ }
+ if (fixed && (i & 1))
+ do_fixed = 0;
+ if (do_fixed) {
+ io_uring_prep_read_fixed(sqe, fd, vecs[i].iov_base,
+ vecs[i].iov_len, offset, i);
+ } else if (nonvec) {
+ io_uring_prep_read(sqe, fd, vecs[i].iov_base,
+ vecs[i].iov_len, offset);
+ } else {
+ io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
+ }
+ sqe->user_data = i;
+ offset += BS;
+ }
+
+ ret = io_uring_submit(ring);
+ if (ret != BUFFERS) {
+ fprintf(stderr, "submit got %d, wanted %d\n", ret, BUFFERS);
+ goto err;
+ }
+
+ for (i = 0; i < BUFFERS; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe=%d\n", ret);
+ goto err;
+ }
+ if (cqe->res == -EINVAL && nonvec) {
+ if (!warned) {
+ fprintf(stdout, "Non-vectored IO not "
+ "supported, skipping\n");
+ warned = 1;
+ }
+ }
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ if (fixed) {
+ ret = io_uring_unregister_buffers(ring);
+ if (ret) {
+ fprintf(stderr, "buffer unreg failed: %d\n", ret);
+ goto err;
+ }
+ }
+
+ close(fd);
+ return 0;
+err:
+ if (fd != -1)
+ close(fd);
+ return 1;
+}
+static int test_io(const char *file, int fixed, int nonvec)
+{
+ struct io_uring ring;
+ int ret, ring_flags = 0;
+
+ ret = t_create_ring(64, &ring, ring_flags);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ ret = __test_io(file, &ring, fixed, nonvec);
+ io_uring_queue_exit(&ring);
+ return ret;
+}
+
+static int has_nonvec_read(void)
+{
+ struct io_uring_probe *p;
+ struct io_uring ring;
+ int ret;
+
+ ret = io_uring_queue_init(1, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ exit(ret);
+ }
+
+ p = t_calloc(1, sizeof(*p) + 256 * sizeof(struct io_uring_probe_op));
+ ret = io_uring_register_probe(&ring, p, 256);
+ /* if we don't have PROBE_REGISTER, we don't have OP_READ/WRITE */
+ if (ret == -EINVAL) {
+out:
+ io_uring_queue_exit(&ring);
+ free(p);
+ return 0;
+ } else if (ret) {
+ fprintf(stderr, "register_probe: %d\n", ret);
+ goto out;
+ }
+
+ if (p->ops_len <= IORING_OP_READ)
+ goto out;
+ if (!(p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED))
+ goto out;
+ io_uring_queue_exit(&ring);
+ free(p);
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret, nonvec;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ vecs = t_create_buffers(BUFFERS, BS);
+
+ /* if we don't have nonvec read, skip testing that */
+ nonvec = has_nonvec_read();
+
+ if (nonvec) {
+ ret = test_io("/proc/kallsyms", 0, 0);
+ if (ret)
+ goto err;
+ }
+
+ ret = test_io("/proc/kallsyms", 0, 1);
+ if (ret)
+ goto err;
+
+ if (nonvec) {
+ ret = test_io("/proc/kallsyms", 1, 0);
+ if (ret)
+ goto err;
+ }
+
+ ret = test_io("/proc/kallsyms", 1, 1);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ fprintf(stderr, "Reading kallsyms failed\n");
+ return 1;
+}
diff --git a/contrib/libs/liburing/test/kallsyms.t/ya.make b/contrib/libs/liburing/test/kallsyms.t/ya.make
new file mode 100644
index 0000000000..03d83ab90c
--- /dev/null
+++ b/contrib/libs/liburing/test/kallsyms.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ kallsyms.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/lfs-openat-write.t/ya.make b/contrib/libs/liburing/test/lfs-openat-write.t/ya.make
index f577ca7b03..ce246ac97a 100644
--- a/contrib/libs/liburing/test/lfs-openat-write.t/ya.make
+++ b/contrib/libs/liburing/test/lfs-openat-write.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/lfs-openat.t/ya.make b/contrib/libs/liburing/test/lfs-openat.t/ya.make
index f0bc0c2b73..1e110f9554 100644
--- a/contrib/libs/liburing/test/lfs-openat.t/ya.make
+++ b/contrib/libs/liburing/test/lfs-openat.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/link-timeout.c b/contrib/libs/liburing/test/link-timeout.c
index c59543c53f..4d4f5d4c69 100644
--- a/contrib/libs/liburing/test/link-timeout.c
+++ b/contrib/libs/liburing/test/link-timeout.c
@@ -11,6 +11,7 @@
#include <string.h>
#include <fcntl.h>
#include <poll.h>
+#include <sys/time.h>
#include "liburing.h"
#include "helpers.h"
@@ -538,6 +539,139 @@ err:
return 1;
}
+static int test_link_timeout_update(struct io_uring *ring, int async)
+{
+ struct __kernel_timespec ts;
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct timeval start;
+ unsigned long msec;
+ int fds[2], ret, i;
+ struct iovec iov;
+ char buffer[128];
+
+ if (pipe(fds)) {
+ perror("pipe");
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ printf("get sqe failed\n");
+ goto err;
+ }
+ iov.iov_base = buffer;
+ iov.iov_len = sizeof(buffer);
+ io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
+ sqe->flags |= IOSQE_IO_LINK;
+ sqe->user_data = 1;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ printf("get sqe failed\n");
+ goto err;
+ }
+ ts.tv_sec = 5;
+ ts.tv_nsec = 0;
+ io_uring_prep_link_timeout(sqe, &ts, 0);
+ sqe->user_data = 2;
+
+ ret = io_uring_submit(ring);
+ if (ret != 2) {
+ printf("sqe submit failed: %d\n", ret);
+ goto err;
+ }
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000LL;
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_timeout_update(sqe, &ts, 2, IORING_LINK_TIMEOUT_UPDATE);
+ if (async)
+ sqe->flags |= IOSQE_ASYNC;
+ sqe->user_data = 3;
+
+ io_uring_submit(ring);
+
+ gettimeofday(&start, NULL);
+ for (i = 0; i < 3; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ printf("wait completion %d\n", ret);
+ goto err;
+ }
+ switch (cqe->user_data) {
+ case 1:
+ if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
+ fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
+ cqe->res);
+ goto err;
+ }
+ break;
+ case 2:
+ /* FASTPOLL kernels can cancel successfully */
+ if (cqe->res != -EALREADY && cqe->res != -ETIME) {
+ fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
+ cqe->res);
+ goto err;
+ }
+ break;
+ case 3:
+ if (cqe->res) {
+ fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
+ cqe->res);
+ goto err;
+ }
+ break;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ msec = mtime_since_now(&start);
+ if (msec < 10 || msec > 200) {
+ fprintf(stderr, "Timeout appears incorrect: %lu\n", msec);
+ goto err;
+ }
+
+ close(fds[0]);
+ close(fds[1]);
+ return 0;
+err:
+ return 1;
+}
+
+static int test_link_timeout_update_invalid(struct io_uring *ring, int async)
+{
+ struct __kernel_timespec ts;
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int ret;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000LL;
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_timeout_update(sqe, &ts, 2, IORING_LINK_TIMEOUT_UPDATE);
+ sqe->user_data = 0xcafe0000;
+ if (async)
+ sqe->flags |= IOSQE_ASYNC;
+
+ io_uring_submit(ring);
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ printf("wait completion %d\n", ret);
+ goto err;
+ }
+ if (cqe->res != -ENOENT) {
+ fprintf(stderr, "bad timeout update: %d\n", cqe->res);
+ goto err;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ return 0;
+err:
+ return 1;
+}
+
static int test_timeout_link_chain1(struct io_uring *ring)
{
struct __kernel_timespec ts;
@@ -1105,5 +1239,30 @@ int main(int argc, char *argv[])
return ret;
}
+ ret = test_link_timeout_update(&ring, 0);
+ if (ret) {
+ printf("test_link_timeout_update 0 failed\n");
+ return ret;
+ }
+
+ ret = test_link_timeout_update(&ring, 1);
+ if (ret) {
+ printf("test_link_timeout_update 1 failed\n");
+ return ret;
+ }
+
+ ret = test_link_timeout_update_invalid(&ring, 0);
+ if (ret) {
+ printf("test_link_timeout_update_invalid 0 failed\n");
+ return ret;
+ }
+
+ ret = test_link_timeout_update_invalid(&ring, 1);
+ if (ret) {
+ printf("test_link_timeout_update_invalid 1 failed\n");
+ return ret;
+ }
+
+
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/link-timeout.t/ya.make b/contrib/libs/liburing/test/link-timeout.t/ya.make
index 31f04f1799..947a3f1e2c 100644
--- a/contrib/libs/liburing/test/link-timeout.t/ya.make
+++ b/contrib/libs/liburing/test/link-timeout.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/link.t/ya.make b/contrib/libs/liburing/test/link.t/ya.make
index 31a9afdcfc..783e8bed46 100644
--- a/contrib/libs/liburing/test/link.t/ya.make
+++ b/contrib/libs/liburing/test/link.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/link_drain.t/ya.make b/contrib/libs/liburing/test/link_drain.t/ya.make
index 8951552fda..3f1d96ca1a 100644
--- a/contrib/libs/liburing/test/link_drain.t/ya.make
+++ b/contrib/libs/liburing/test/link_drain.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/linked-defer-close.c b/contrib/libs/liburing/test/linked-defer-close.c
new file mode 100644
index 0000000000..600887398f
--- /dev/null
+++ b/contrib/libs/liburing/test/linked-defer-close.c
@@ -0,0 +1,225 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Test that the final close of a file does indeed get it closed, if the
+ * ring is setup with DEFER_TASKRUN and the task is waiting in cqring_wait()
+ * during. Also see:
+ *
+ * https://github.com/axboe/liburing/issues/1235
+ *
+ * for a bug report, and the zig code on which this test program is based.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <pthread.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+enum {
+ IS_ACCEPT = 0,
+ IS_SEND = 0x100,
+ IS_SEND2 = 0x101,
+ IS_SEND3 = 0x102,
+ IS_CLOSE = 0x200,
+};
+
+struct thread_data {
+ int parent_pid;
+};
+
+static void *thread_fn(void *__data)
+{
+ struct thread_data *data = __data;
+ struct sockaddr_in saddr;
+ int sockfd, ret;
+ char msg[64];
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = htons(9999);
+ inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr);
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0) {
+ perror("socket");
+ goto done;
+ }
+
+ ret = connect(sockfd, (struct sockaddr *) &saddr, sizeof(saddr));
+ if (ret < 0) {
+ perror("connect");
+ close(sockfd);
+ goto done;
+ }
+
+ do {
+ memset(msg, 0, sizeof(msg));
+ ret = recv(sockfd, msg, sizeof(msg), 0);
+ } while (ret > 0);
+
+ close(sockfd);
+done:
+ kill(data->parent_pid, SIGUSR1);
+ return NULL;
+}
+
+/* we got SIGUSR1, exit normally */
+static void sig_usr1(int sig)
+{
+ exit(T_EXIT_PASS);
+}
+
+/* timed out, failure */
+static void sig_timeout(int sig)
+{
+ exit(T_EXIT_FAIL);
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct sockaddr_in saddr;
+ char *msg1 = "message number 1\n";
+ char *msg2 = "message number 2\n";
+ char *msg3 = "message number 3\n";
+ int val, send_fd, ret, sockfd;
+ struct sigaction act[2] = { };
+ struct thread_data td;
+ pthread_t thread;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ saddr.sin_port = htons(9999);
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0) {
+ perror("socket");
+ return T_EXIT_FAIL;
+ }
+
+ val = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+
+ ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
+ if (ret < 0) {
+ perror("bind");
+ close(sockfd);
+ return T_EXIT_FAIL;
+ }
+
+ ret = listen(sockfd, 1);
+ if (ret < 0) {
+ perror("listen");
+ close(sockfd);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN);
+ if (ret == -EINVAL) {
+ close(sockfd);
+ return T_EXIT_SKIP;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_multishot_accept(sqe, sockfd, NULL, NULL, 0);
+ sqe->user_data = IS_ACCEPT;
+ io_uring_submit(&ring);
+
+ /* check for no multishot accept */
+ ret = io_uring_peek_cqe(&ring, &cqe);
+ if (!ret && cqe->res == -EINVAL) {
+ close(sockfd);
+ return T_EXIT_SKIP;
+ }
+
+ /* expected exit */
+ act[0].sa_handler = sig_usr1;
+ sigaction(SIGUSR1, &act[0], NULL);
+
+ /* if this hits, we have failed */
+ act[1].sa_handler = sig_timeout;
+ sigaction(SIGALRM, &act[1], NULL);
+ alarm(5);
+
+ /* start receiver */
+ td.parent_pid = getpid();
+ pthread_create(&thread, NULL, thread_fn, &td);
+
+ do {
+ ret = io_uring_submit_and_wait(&ring, 1);
+ if (ret < 0) {
+ fprintf(stderr, "submit: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ ret = io_uring_peek_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "peek: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ switch (cqe->user_data) {
+ case IS_ACCEPT:
+ send_fd = cqe->res;
+ io_uring_cqe_seen(&ring, cqe);
+
+ /*
+ * prep two sends, with the 2nd linked to a close
+ * operation. Once the close has been completed, that
+ * will terminate the receiving thread and that will
+ * in turn send this task a SIGUSR1 signal. If the
+ * kernel is buggy, then we never get SIGUSR1 and we
+ * will sit forever waiting and be timed out.
+ */
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_send(sqe, send_fd, msg1, strlen(msg1), 0);
+ sqe->user_data = IS_SEND;
+ sqe->flags = IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_LINK;
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_send(sqe, send_fd, msg2, strlen(msg2), 0);
+ sqe->user_data = IS_SEND2;
+ sqe->flags = IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_LINK;
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_send(sqe, send_fd, msg3, strlen(msg3), 0);
+ sqe->user_data = IS_SEND3;
+ sqe->flags = IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_LINK;
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_close(sqe, send_fd);
+ sqe->user_data = IS_CLOSE;
+ sqe->flags = IOSQE_CQE_SKIP_SUCCESS;
+ break;
+ case IS_SEND:
+ case IS_SEND2:
+ fprintf(stderr, "Should not see send response\n");
+ io_uring_cqe_seen(&ring, cqe);
+ return T_EXIT_FAIL;
+ case IS_CLOSE:
+ fprintf(stderr, "Should not see close response\n");
+ io_uring_cqe_seen(&ring, cqe);
+ return T_EXIT_FAIL;
+ default:
+ fprintf(stderr, "got unknown cqe\n");
+ return T_EXIT_FAIL;
+ }
+ } while (1);
+
+ /* will never get here */
+ return T_EXIT_FAIL;
+}
diff --git a/contrib/libs/liburing/test/linked-defer-close.t/ya.make b/contrib/libs/liburing/test/linked-defer-close.t/ya.make
new file mode 100644
index 0000000000..810d4104ea
--- /dev/null
+++ b/contrib/libs/liburing/test/linked-defer-close.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ linked-defer-close.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/madvise.c b/contrib/libs/liburing/test/madvise.c
index 20c452c4a6..a6dc23a858 100644
--- a/contrib/libs/liburing/test/madvise.c
+++ b/contrib/libs/liburing/test/madvise.c
@@ -21,30 +21,6 @@
#define LOOPS 100
#define MIN_LOOPS 10
-static unsigned long long utime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000000;
- return sec + usec;
-}
-
-static unsigned long long utime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return utime_since(tv, &end);
-}
-
static int do_madvise(struct io_uring *ring, void *addr, off_t len, int advice)
{
struct io_uring_sqe *sqe;
@@ -101,6 +77,8 @@ static int test_madvise(struct io_uring *ring, const char *filename)
fd = open(filename, O_RDONLY);
if (fd < 0) {
+ if (errno == EACCES || errno == EPERM)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -144,9 +122,12 @@ static int test_madvise(struct io_uring *ring, const char *filename)
return 1;
if (cached_read < uncached_read &&
- cached_read2 < uncached_read)
+ cached_read2 < uncached_read) {
+ free(buf);
return 0;
+ }
+ free(buf);
return 2;
}
@@ -171,6 +152,8 @@ int main(int argc, char *argv[])
good = bad = 0;
for (i = 0; i < LOOPS; i++) {
ret = test_madvise(&ring, fname);
+ if (ret == T_EXIT_SKIP)
+ goto skip;
if (ret == 1) {
fprintf(stderr, "test_madvise failed\n");
goto err;
@@ -193,4 +176,8 @@ err:
if (fname != argv[1])
unlink(fname);
return T_EXIT_FAIL;
+skip:
+ if (fname != argv[1])
+ unlink(fname);
+ return T_EXIT_SKIP;
}
diff --git a/contrib/libs/liburing/test/madvise.t/ya.make b/contrib/libs/liburing/test/madvise.t/ya.make
index d0ac4fdc9f..d007a067eb 100644
--- a/contrib/libs/liburing/test/madvise.t/ya.make
+++ b/contrib/libs/liburing/test/madvise.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/min-timeout-wait.c b/contrib/libs/liburing/test/min-timeout-wait.c
new file mode 100644
index 0000000000..217864cdbc
--- /dev/null
+++ b/contrib/libs/liburing/test/min-timeout-wait.c
@@ -0,0 +1,330 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: run various min_timeout tests
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+struct data {
+ pthread_barrier_t startup;
+ unsigned long usec_sleep;
+ int out_fds[8];
+ int nr_fds;
+};
+
+static int time_pass(struct timeval *start, unsigned long min_t,
+ unsigned long max_t, const char *name)
+{
+ unsigned long elapsed;
+
+ elapsed = mtime_since_now(start);
+ if (elapsed < min_t || elapsed > max_t) {
+ fprintf(stderr, "%s fails time check\n", name);
+ fprintf(stderr, " elapsed=%lu, min=%lu, max=%lu\n", elapsed,
+ min_t, max_t);
+ return T_EXIT_FAIL;
+ }
+ return T_EXIT_PASS;
+}
+
+static void *pipe_write(void *data)
+{
+ struct data *d = data;
+ char buf[32];
+ int i;
+
+ memset(buf, 0x55, sizeof(buf));
+
+ pthread_barrier_wait(&d->startup);
+
+ if (d->usec_sleep)
+ usleep(d->usec_sleep);
+
+ for (i = 0; i < d->nr_fds; i++) {
+ int ret;
+
+ ret = write(d->out_fds[i], buf, sizeof(buf));
+ if (ret < 0) {
+ perror("write");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+static int __test_writes(struct io_uring *ring, int npipes, int usec_sleep,
+ int usec_wait, int min_t, int max_t, const char *name)
+{
+ struct __kernel_timespec ts;
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct timeval tv;
+ int ret, i, fds[4][2];
+ pthread_t thread;
+ struct data d;
+ char buf[32];
+ void *tret;
+
+ for (i = 0; i < npipes; i++) {
+ if (pipe(fds[i]) < 0) {
+ perror("pipe");
+ return T_EXIT_FAIL;
+ }
+ d.out_fds[i] = fds[i][1];
+ }
+ d.nr_fds = npipes;
+
+ pthread_barrier_init(&d.startup, NULL, 2);
+ d.usec_sleep = usec_sleep;
+
+ pthread_create(&thread, NULL, pipe_write, &d);
+ pthread_barrier_wait(&d.startup);
+
+ for (i = 0; i < npipes; i++) {
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_read(sqe, fds[i][0], buf, sizeof(buf), 0);
+ }
+
+ io_uring_submit(ring);
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = 0;
+ gettimeofday(&tv, NULL);
+ ret = io_uring_wait_cqes_min_timeout(ring, &cqe, 4, &ts, usec_wait, NULL);
+ if (ret) {
+ fprintf(stderr, "wait_cqes: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = time_pass(&tv, min_t, max_t, name);
+
+ io_uring_cq_advance(ring, npipes);
+
+ pthread_join(thread, &tret);
+ for (i = 0; i < npipes; i++) {
+ close(fds[i][0]);
+ close(fds[i][1]);
+ }
+ return ret;
+}
+/*
+ * Test doing min_wait for N events, where 0 events are already available
+ * on wait enter but N/2 are posted within the min_wait window. We'll expect to
+ * return when the min_wait window expires.
+ */
+static int test_some_wait(struct io_uring *ring)
+{
+ return __test_writes(ring, 2, 1000, 100000, 95, 120, __FUNCTION__);
+}
+
+/*
+ * Test doing min_wait for N events, where 0 events are already available
+ * on wait enter but N are posted within the min_wait window. We'll expect to
+ * return upon arrival of the N events, not the full min_wait window.
+ */
+static int test_post_wait(struct io_uring *ring)
+{
+ return __test_writes(ring, 4, 10000, 200000, 9, 12, __FUNCTION__);
+}
+
+/*
+ * Test doing min_wait for N events, where 0 events are already available
+ * on wait enter and one is posted after the min_wait timeout has expired.
+ * That first event should cause wait to abort, even if the task has asked
+ * for more to wait on.
+ */
+static int test_late(struct io_uring *ring)
+{
+ return __test_writes(ring, 1, 100000, 10000, 95, 120, __FUNCTION__);
+}
+
+static int __test_nop(struct io_uring *ring, int nr_nops, int min_t, int max_t,
+ unsigned long long_wait, const char *name)
+{
+ struct __kernel_timespec ts;
+ struct io_uring_cqe *cqe;
+ struct timeval tv;
+ int i, ret;
+
+ for (i = 0; i < nr_nops; i++) {
+ struct io_uring_sqe *sqe;
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_nop(sqe);
+ }
+
+ if (nr_nops)
+ io_uring_submit(ring);
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = long_wait * 1000;
+ gettimeofday(&tv, NULL);
+ ret = io_uring_wait_cqes_min_timeout(ring, &cqe, 4, &ts, 50000, NULL);
+ io_uring_cq_advance(ring, nr_nops);
+ if (nr_nops) {
+ if (ret) {
+ fprintf(stderr, "wait_cqes: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ } else {
+ if (ret != -ETIME) {
+ fprintf(stderr, "wait_cqes: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ }
+
+ return time_pass(&tv, min_t, max_t, name);
+}
+
+/*
+ * Test doing min_wait for N events, where N/2 events are already available
+ * on wait enter. This should abort waiting after min_wait, not do the full
+ * wait.
+ */
+static int test_some(struct io_uring *ring)
+{
+ return __test_nop(ring, 2, 45, 55, 100000, __FUNCTION__);
+}
+
+/*
+ * Test doing min_wait for N events, where N events are already available
+ * on wait enter.
+ */
+static int test_already(struct io_uring *ring)
+{
+ return __test_nop(ring, 4, 0, 1, 100000, __FUNCTION__);
+}
+
+/*
+ * Test doing min_wait for N events, and nothing ever gets posted. We'd
+ * expect the time to be the normal wait time, not the min_wait time.
+ */
+static int test_nothing(struct io_uring *ring)
+{
+ return __test_nop(ring, 0, 95, 110, 100000, __FUNCTION__);
+}
+
+/*
+ * Test doing min_wait for N events, and nothing ever gets posted, and use
+ * a min_wait time that's bigger than the total wait. We only expect the
+ * min_wait to elapse.
+ */
+static int test_min_wait_biggest(struct io_uring *ring)
+{
+ return __test_nop(ring, 0, 45, 55, 20000, __FUNCTION__);
+}
+
+/*
+ * Test doing min_wait for N events, and nothing ever gets posted, and use
+ * a min_wait time that's roughly equal to the total wait. We only expect the
+ * min_wait to elapse.
+ */
+static int test_min_wait_equal(struct io_uring *ring)
+{
+ return __test_nop(ring, 0, 45, 55, 50001, __FUNCTION__);
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring1, ring2;
+ struct io_uring_params p = { };
+ int ret;
+
+ if (argc > 1)
+ return 0;
+
+ ret = t_create_ring_params(8, &ring1, &p);
+ if (ret == T_SETUP_SKIP)
+ return T_EXIT_SKIP;
+ else if (ret != T_SETUP_OK)
+ return ret;
+ if (!(p.features & IORING_FEAT_MIN_TIMEOUT))
+ return T_EXIT_SKIP;
+
+ p.flags = IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN;
+ ret = t_create_ring_params(8, &ring2, &p);
+ if (ret == T_SETUP_SKIP)
+ return T_EXIT_SKIP;
+ else if (ret != T_SETUP_OK)
+ return ret;
+
+ ret = test_already(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_already(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test_some(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_some(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test_late(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_late(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test_post_wait(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_post_wait(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test_some_wait(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_some_wait(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test_nothing(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_nothing(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test_min_wait_biggest(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_min_wait_biggest(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test_min_wait_equal(&ring1);
+ if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+ return ret;
+
+ ret = test_min_wait_equal(&ring2);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ io_uring_queue_exit(&ring1);
+ io_uring_queue_exit(&ring2);
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/min-timeout-wait.t/ya.make b/contrib/libs/liburing/test/min-timeout-wait.t/ya.make
new file mode 100644
index 0000000000..ec59ad065d
--- /dev/null
+++ b/contrib/libs/liburing/test/min-timeout-wait.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ min-timeout-wait.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/min-timeout.c b/contrib/libs/liburing/test/min-timeout.c
new file mode 100644
index 0000000000..a5abd6152e
--- /dev/null
+++ b/contrib/libs/liburing/test/min-timeout.c
@@ -0,0 +1,209 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test min timeout handling
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define NPIPES 8
+#define NWRITES 6
+
+#define WAIT_USEC (250000)
+
+static int no_min_timeout;
+
+struct d {
+ int fd[NPIPES];
+ long delay;
+};
+
+static void *thread_fn(void *data)
+{
+ struct d *d = data;
+ char buf[32];
+ int i;
+
+ memset(buf, 0x55, sizeof(buf));
+
+ for (i = 0; i < NWRITES; i++) {
+ int ret;
+
+ usleep(d->delay);
+ ret = write(d->fd[i], buf, sizeof(buf));
+ if (ret != sizeof(buf)) {
+ fprintf(stderr, "bad write %d\n", ret);
+ break;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Allow 25% tolerance
+ */
+static int within_range(unsigned int target, unsigned int msec)
+{
+ unsigned int high, low;
+
+ low = (target * 3) / 4;
+ high = (target * 5) / 4;
+ return (msec >= low && msec <= high);
+}
+
+static int test(int flags, int expected_ctx, int min_wait, int write_delay,
+ int nr_cqes, int msec_target)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ struct __kernel_timespec ts;
+ struct rusage s, e;
+ pthread_t thread;
+ struct d d;
+ struct io_uring_params p = { .flags = flags, };
+ int ret, fds[NPIPES][2], i;
+ struct timeval start_time;
+ char buf[32];
+ void *tret;
+ long ttime;
+
+ ret = io_uring_queue_init_params(NPIPES, &ring, &p);
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+ if (!(p.features & IORING_FEAT_MIN_TIMEOUT)) {
+ no_min_timeout = 1;
+ return T_EXIT_SKIP;
+ }
+
+ for (i = 0; i < NPIPES; i++) {
+ if (pipe(fds[i]) < 0) {
+ perror("pipe");
+ return 1;
+ }
+ d.fd[i] = fds[i][1];
+ }
+
+ d.delay = write_delay;
+ pthread_create(&thread, NULL, thread_fn, &d);
+
+ for (i = 0; i < NPIPES; i++) {
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read(sqe, fds[i][0], buf, sizeof(buf), 0);
+ }
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = WAIT_USEC * 1000LL;
+
+ gettimeofday(&start_time, NULL);
+ getrusage(RUSAGE_THREAD, &s);
+ ret = io_uring_submit_and_wait_min_timeout(&ring, &cqe, 8, &ts, min_wait, NULL);
+ if (ret != NPIPES)
+ fprintf(stderr, "submit_and_wait=%d\n", ret);
+
+ getrusage(RUSAGE_THREAD, &e);
+ e.ru_nvcsw -= s.ru_nvcsw;
+ ttime = mtime_since_now(&start_time);
+ if (!within_range(msec_target, ttime)) {
+ fprintf(stderr, "Expected %d msec, got %ld msec\n", msec_target,
+ ttime);
+ fprintf(stderr, "flags=%x, min_wait=%d, write_delay=%d\n",
+ flags, min_wait, write_delay);
+ }
+ /* will usually be accurate, but allow for offset of 1 */
+ if (e.ru_nvcsw != expected_ctx &&
+ (e.ru_nvcsw - expected_ctx > 1))
+ fprintf(stderr, "%ld ctx switches, expected %d\n", e.ru_nvcsw,
+ expected_ctx);
+
+ for (i = 0; i < NPIPES; i++) {
+ ret = io_uring_peek_cqe(&ring, &cqe);
+ if (ret)
+ break;
+ io_uring_cqe_seen(&ring, cqe);
+ }
+
+ if (i != nr_cqes)
+ fprintf(stderr, "Got %d CQEs, expected %d\n", i, nr_cqes);
+
+ pthread_join(thread, &tret);
+
+ for (i = 0; i < NPIPES; i++) {
+ close(fds[i][0]);
+ close(fds[i][1]);
+ }
+
+ return T_EXIT_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test(0, NWRITES + 1, 0, 2000, NWRITES, WAIT_USEC / 1000);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+ if (no_min_timeout)
+ return T_EXIT_SKIP;
+
+ ret = test(0, NWRITES + 1, 50000, 2000, NWRITES, 50);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test(0, NWRITES + 1, 500000, 2000, NWRITES, 500);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ /* no writes within min timeout, but it's given. expect 1 cqe */
+ ret = test(0, 1, 10000, 20000, 1, 20);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ /* same as above, but no min timeout. should time out and we get 6 */
+ ret = test(0, NWRITES + 1, 0, 20000, NWRITES, WAIT_USEC / 1000);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test(IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN, 1,
+ 0, 2000, NWRITES, WAIT_USEC / 1000);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test(IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN, 1,
+ 50000, 2000, NWRITES, 50);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ ret = test(IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN, 1,
+ 500000, 2000, NWRITES, 500);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ /* no writes within min timeout, but it's given. expect 1 cqe */
+ ret = test(IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN, 1,
+ 10000, 20000, 1, 20);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ /* same as above, but no min timeout. should time out and we get 6 */
+ ret = test(IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN, 1,
+ 0, 20000, NWRITES, WAIT_USEC / 1000);
+ if (ret == T_EXIT_FAIL)
+ return T_EXIT_FAIL;
+
+ return ret;
+}
diff --git a/contrib/libs/liburing/test/min-timeout.t/ya.make b/contrib/libs/liburing/test/min-timeout.t/ya.make
new file mode 100644
index 0000000000..344cff1526
--- /dev/null
+++ b/contrib/libs/liburing/test/min-timeout.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ min-timeout.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/mkdir.c b/contrib/libs/liburing/test/mkdir.c
index 630672cc93..33e0bea772 100644
--- a/contrib/libs/liburing/test/mkdir.c
+++ b/contrib/libs/liburing/test/mkdir.c
@@ -98,6 +98,12 @@ int main(int argc, char *argv[])
goto err1;
}
+ ret = do_mkdirat(&ring, (const char *) (uintptr_t) 0x1234);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "do_mkdirat bad address: %d\n", ret);
+ goto err1;
+ }
+
unlinkat(AT_FDCWD, fn, AT_REMOVEDIR);
io_uring_queue_exit(&ring);
return T_EXIT_PASS;
diff --git a/contrib/libs/liburing/test/mkdir.t/ya.make b/contrib/libs/liburing/test/mkdir.t/ya.make
index 87fefb42d5..2c5a72cd17 100644
--- a/contrib/libs/liburing/test/mkdir.t/ya.make
+++ b/contrib/libs/liburing/test/mkdir.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/msg-ring-fd.t/ya.make b/contrib/libs/liburing/test/msg-ring-fd.t/ya.make
index e62d69d037..103941320c 100644
--- a/contrib/libs/liburing/test/msg-ring-fd.t/ya.make
+++ b/contrib/libs/liburing/test/msg-ring-fd.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/msg-ring-flags.t/ya.make b/contrib/libs/liburing/test/msg-ring-flags.t/ya.make
index ba23560940..75337d35df 100644
--- a/contrib/libs/liburing/test/msg-ring-flags.t/ya.make
+++ b/contrib/libs/liburing/test/msg-ring-flags.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/msg-ring-overflow.t/ya.make b/contrib/libs/liburing/test/msg-ring-overflow.t/ya.make
index cb95daef71..b92b8004e9 100644
--- a/contrib/libs/liburing/test/msg-ring-overflow.t/ya.make
+++ b/contrib/libs/liburing/test/msg-ring-overflow.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/msg-ring.c b/contrib/libs/liburing/test/msg-ring.c
index 843ba1f8ef..e87ee6d92a 100644
--- a/contrib/libs/liburing/test/msg-ring.c
+++ b/contrib/libs/liburing/test/msg-ring.c
@@ -310,6 +310,8 @@ static int test_disabled_ring(struct io_uring *ring, int flags)
flags |= IORING_SETUP_R_DISABLED;
ret = io_uring_queue_init(8, &disabled_ring, flags);
if (ret) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
fprintf(stderr, "ring setup failed: %d\n", ret);
return 1;
}
@@ -350,6 +352,8 @@ static int test(int ring_flags)
ret = io_uring_queue_init(8, &ring, ring_flags);
if (ret) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
fprintf(stderr, "ring setup failed: %d\n", ret);
return T_EXIT_FAIL;
}
@@ -453,13 +457,15 @@ int main(int argc, char *argv[])
return T_EXIT_SKIP;
ret = test(0);
- if (ret != T_EXIT_PASS) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "ring flags 0 failed\n");
return ret;
+ } else if (ret == T_EXIT_SKIP) {
+ return T_EXIT_SKIP;
}
ret = test(IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN);
- if (ret != T_EXIT_PASS) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "ring flags defer failed\n");
return ret;
}
diff --git a/contrib/libs/liburing/test/msg-ring.t/ya.make b/contrib/libs/liburing/test/msg-ring.t/ya.make
index a1038229eb..f2c1ed0c82 100644
--- a/contrib/libs/liburing/test/msg-ring.t/ya.make
+++ b/contrib/libs/liburing/test/msg-ring.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/multicqes_drain.t/ya.make b/contrib/libs/liburing/test/multicqes_drain.t/ya.make
index f14f880b47..604fb73e84 100644
--- a/contrib/libs/liburing/test/multicqes_drain.t/ya.make
+++ b/contrib/libs/liburing/test/multicqes_drain.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/napi-test.c b/contrib/libs/liburing/test/napi-test.c
new file mode 100644
index 0000000000..00a7204618
--- /dev/null
+++ b/contrib/libs/liburing/test/napi-test.c
@@ -0,0 +1,229 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: run NAPI receive test. Meant to be run from the associated
+ * script, napi-test.sh. That will invoke this test program
+ * as either a sender or receiver, with the queue flags passed
+ * in for testing.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <linux/if_packet.h>
+#include <linux/socket.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+static const char receiver_address[] = "10.10.10.20";
+static const int port = 9999;
+#define BUF_SIZE 4096
+
+static char buffer[BUF_SIZE];
+static unsigned current_byte = 0;
+
+static void do_setsockopt(int fd, int level, int optname, int val)
+{
+ int ret = setsockopt(fd, level, optname, &val, sizeof(val));
+
+ assert(ret == 0);
+}
+
+static int sender(int queue_flags)
+{
+ unsigned long long written = 0;
+ struct sockaddr_in addr;
+ struct io_uring ring;
+ int i, ret, fd;
+
+ /*
+ * Sender doesn't use the ring, but try and set one up with the same
+ * flags that the receiver will use. If that fails, we know the
+ * receiver will have failed too - just skip the test in that case.
+ */
+ ret = io_uring_queue_init(1, &ring, queue_flags);
+ if (ret)
+ return T_EXIT_SKIP;
+ io_uring_queue_exit(&ring);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ ret = inet_pton(AF_INET, receiver_address, &addr.sin_addr);
+ assert(ret == 1);
+
+ fd = socket(PF_INET, SOCK_STREAM, 0);
+ assert(fd >= 0);
+
+ /* don't race with receiver, give it 1 second to connect */
+ i = 0;
+ do {
+ ret = connect(fd, (void *)&addr, sizeof(addr));
+ if (!ret)
+ break;
+ if (ret == -1 && errno == ECONNREFUSED) {
+ if (i >= 10000) {
+ fprintf(stderr, "Gave up trying to connect\n");
+ return 1;
+ }
+ usleep(100);
+ continue;
+ }
+ i++;
+ } while (1);
+
+ while (written < 8 * 1024 * 1024) {
+ for (i = 0; i < BUF_SIZE; i++)
+ buffer[i] = current_byte + i;
+
+ ret = write(fd, buffer, BUF_SIZE);
+ if (ret <= 0) {
+ if (!ret || errno == ECONNRESET)
+ break;
+ fprintf(stderr, "write failed %i %i\n", ret, errno);
+ return 1;
+ }
+ written += ret;
+ current_byte += ret;
+ }
+
+ close(fd);
+ return 0;
+}
+
+static int receiver(int queue_flags)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct io_uring ring;
+ struct io_uring_napi napi = { };
+ struct sockaddr_in addr;
+ int fd, listen_fd;
+ int i, ret;
+
+ ret = io_uring_queue_init(8, &ring, queue_flags);
+ if (ret < 0) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "queue_init: %s\n", strerror(-ret));
+ return 1;
+ }
+
+ napi.prefer_busy_poll = 1;
+ napi.busy_poll_to = 50;
+ io_uring_register_napi(&ring, &napi);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ listen_fd = socket(AF_INET, SOCK_STREAM, 0);
+ assert(listen_fd >= 0);
+
+ do_setsockopt(listen_fd, SOL_SOCKET, SO_REUSEPORT, 1);
+ ret = bind(listen_fd, (void *)&addr, sizeof(addr));
+ if (ret) {
+ fprintf(stderr, "bind failed %i %i\n", ret, errno);
+ return 1;
+ }
+
+ ret = listen(listen_fd, 8);
+ assert(ret == 0);
+
+ fd = accept(listen_fd, NULL, NULL);
+ assert(fd >= 0);
+
+ while (1) {
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_recv(sqe, fd, buffer, BUF_SIZE, 0);
+
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "io_uring_submit: %i\n", ret);
+ return 1;
+ }
+
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "io_uring_wait_cqe: %i\n", ret);
+ return 1;
+ }
+
+ ret = cqe->res;
+ if (ret <= 0) {
+ if (!ret)
+ break;
+ fprintf(stderr, "recv failed %i %i\n", ret, errno);
+ return 1;
+ }
+
+ for (i = 0; i < ret; i++) {
+ char expected = current_byte + i;
+
+ if (buffer[i] != expected) {
+ fprintf(stderr, "data mismatch: idx %i, %c vs %c\n",
+ i, buffer[i], expected);
+ return 1;
+ }
+ }
+
+ current_byte += ret;
+ io_uring_cqe_seen(&ring, cqe);
+ }
+
+ close(fd);
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int queue_flags;
+ int is_rx;
+
+ if (geteuid()) {
+ fprintf(stdout, "NAPI test requires root\n");
+ return T_EXIT_SKIP;
+ }
+
+ if (argc == 1) {
+ struct stat sb;
+
+ if (!stat("napi-test.sh", &sb)) {
+ return system("bash napi-test.sh");
+ } else if (!stat("test/napi-test.sh", &sb)) {
+ return system("bash test/napi-test.sh");
+ } else {
+ fprintf(stderr, "Can't find napi-test.sh\n");
+ return T_EXIT_SKIP;
+ }
+ } else if (argc == 2) {
+ return T_EXIT_SKIP;
+ } else if (argc != 3) {
+ return T_EXIT_SKIP;
+ }
+
+ if (!strcmp(argv[1], "receive"))
+ is_rx = 1;
+ else if (!strcmp(argv[1], "send"))
+ is_rx = 0;
+ else
+ return T_EXIT_FAIL;
+
+ queue_flags = strtoul(argv[2], NULL, 16);
+
+ if (is_rx)
+ return receiver(queue_flags);
+
+ return sender(queue_flags);
+}
diff --git a/contrib/libs/liburing/test/napi-test.t/ya.make b/contrib/libs/liburing/test/napi-test.t/ya.make
new file mode 100644
index 0000000000..dd4a327f04
--- /dev/null
+++ b/contrib/libs/liburing/test/napi-test.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ napi-test.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/no-mmap-inval.c b/contrib/libs/liburing/test/no-mmap-inval.c
index 44d3be97d5..1d31688b27 100644
--- a/contrib/libs/liburing/test/no-mmap-inval.c
+++ b/contrib/libs/liburing/test/no-mmap-inval.c
@@ -33,11 +33,13 @@ int main(int argc, char *argv[])
ret = io_uring_queue_init_params(2, &ring, &p);
if (ret == -EINVAL) {
/* kernel doesn't support SETUP_NO_MMAP */
+ free(addr);
return T_EXIT_SKIP;
} else if (ret && (ret != -EFAULT && ret != -ENOMEM)) {
fprintf(stderr, "Got %d, wanted -EFAULT\n", ret);
return T_EXIT_FAIL;
}
+ free(addr);
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/no-mmap-inval.t/ya.make b/contrib/libs/liburing/test/no-mmap-inval.t/ya.make
index 9ec20bebad..5b03396796 100644
--- a/contrib/libs/liburing/test/no-mmap-inval.t/ya.make
+++ b/contrib/libs/liburing/test/no-mmap-inval.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/nolibc.t/ya.make b/contrib/libs/liburing/test/nolibc.t/ya.make
index 7f57ccae4b..17806776d3 100644
--- a/contrib/libs/liburing/test/nolibc.t/ya.make
+++ b/contrib/libs/liburing/test/nolibc.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/nop-all-sizes.t/ya.make b/contrib/libs/liburing/test/nop-all-sizes.t/ya.make
index 35fc683f9f..5b8e16ec68 100644
--- a/contrib/libs/liburing/test/nop-all-sizes.t/ya.make
+++ b/contrib/libs/liburing/test/nop-all-sizes.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/nop.c b/contrib/libs/liburing/test/nop.c
index a701b3d8ed..52810a1ae4 100644
--- a/contrib/libs/liburing/test/nop.c
+++ b/contrib/libs/liburing/test/nop.c
@@ -16,6 +16,45 @@
static int seq;
+static int test_nop_inject(struct io_uring *ring, unsigned req_flags)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ goto err;
+ }
+
+ io_uring_prep_nop(sqe);
+ sqe->user_data = ++seq;
+ sqe->nop_flags = IORING_NOP_INJECT_RESULT;
+ sqe->flags |= req_flags;
+ sqe->len = -EFAULT;
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ if (cqe->res != -EINVAL && cqe->res != -EFAULT) {
+ fprintf(stderr, "expected injected result, got %d\n", cqe->res);
+ goto err;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ return 0;
+err:
+ return 1;
+}
+
static int test_single_nop(struct io_uring *ring, unsigned req_flags)
{
struct io_uring_cqe *cqe;
@@ -152,6 +191,11 @@ static int test_ring(unsigned flags)
fprintf(stderr, "test_barrier_nop failed\n");
goto err;
}
+ ret = test_nop_inject(&ring, req_flags);
+ if (ret) {
+ fprintf(stderr, "test_nop_inject failed\n");
+ goto err;
+ }
}
err:
io_uring_queue_exit(&ring);
diff --git a/contrib/libs/liburing/test/nop.t/ya.make b/contrib/libs/liburing/test/nop.t/ya.make
index df373fd678..71170256b6 100644
--- a/contrib/libs/liburing/test/nop.t/ya.make
+++ b/contrib/libs/liburing/test/nop.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/ooo-file-unreg.c b/contrib/libs/liburing/test/ooo-file-unreg.c
index ee5faaf4f8..90f5375cfe 100644
--- a/contrib/libs/liburing/test/ooo-file-unreg.c
+++ b/contrib/libs/liburing/test/ooo-file-unreg.c
@@ -10,7 +10,7 @@
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
-#include <sys/poll.h>
+#include <poll.h>
#include "liburing.h"
#include "helpers.h"
diff --git a/contrib/libs/liburing/test/ooo-file-unreg.t/ya.make b/contrib/libs/liburing/test/ooo-file-unreg.t/ya.make
index 8df08c00b9..1e28dabbaa 100644
--- a/contrib/libs/liburing/test/ooo-file-unreg.t/ya.make
+++ b/contrib/libs/liburing/test/ooo-file-unreg.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/open-close.c b/contrib/libs/liburing/test/open-close.c
index 6b236e463a..bca8475f6d 100644
--- a/contrib/libs/liburing/test/open-close.c
+++ b/contrib/libs/liburing/test/open-close.c
@@ -36,6 +36,36 @@ static int submit_wait(struct io_uring *ring)
return ret;
}
+static int test_close_flush(void)
+{
+ struct io_uring ring;
+ struct io_uring_sqe *sqe;
+ char buf[128];
+ int ret, fd;
+
+ sprintf(buf, "/sys/kernel/debug/tracing/per_cpu/cpu0/trace_pipe_raw");
+ fd = open(buf, O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed\n");
+ return -1;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_close(sqe, fd);
+ ret = submit_wait(&ring);
+ if (ret) {
+ fprintf(stderr, "closefailed %i\n", ret);
+ return -1;
+ }
+
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
static inline int try_close(struct io_uring *ring, int fd, int slot)
{
struct io_uring_sqe *sqe;
@@ -221,12 +251,16 @@ int main(int argc, char *argv[])
fprintf(stdout, "Open not supported, skipping\n");
goto done;
}
+ if (ret == -EPERM || ret == -EACCES)
+ return T_EXIT_SKIP;
fprintf(stderr, "test_openat absolute failed: %d\n", ret);
goto err;
}
ret = test_openat(&ring, path_rel, AT_FDCWD);
if (ret < 0) {
+ if (ret == -EPERM || ret == -EACCES)
+ return T_EXIT_SKIP;
fprintf(stderr, "test_openat relative failed: %d\n", ret);
goto err;
}
@@ -249,6 +283,12 @@ int main(int argc, char *argv[])
goto err;
}
+ ret = test_close_flush();
+ if (ret) {
+ fprintf(stderr, "test_close_flush failed\n");
+ goto err;
+ }
+
done:
unlink(path);
if (do_unlink)
diff --git a/contrib/libs/liburing/test/open-close.t/ya.make b/contrib/libs/liburing/test/open-close.t/ya.make
index 1c96f6a744..306ecf4323 100644
--- a/contrib/libs/liburing/test/open-close.t/ya.make
+++ b/contrib/libs/liburing/test/open-close.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/open-direct-link.t/ya.make b/contrib/libs/liburing/test/open-direct-link.t/ya.make
index a526297eca..ef284c507a 100644
--- a/contrib/libs/liburing/test/open-direct-link.t/ya.make
+++ b/contrib/libs/liburing/test/open-direct-link.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/open-direct-pick.t/ya.make b/contrib/libs/liburing/test/open-direct-pick.t/ya.make
index 385643a111..2c3e6f496f 100644
--- a/contrib/libs/liburing/test/open-direct-pick.t/ya.make
+++ b/contrib/libs/liburing/test/open-direct-pick.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/openat2.c b/contrib/libs/liburing/test/openat2.c
index 5206b73f3a..833026d31c 100644
--- a/contrib/libs/liburing/test/openat2.c
+++ b/contrib/libs/liburing/test/openat2.c
@@ -16,25 +16,32 @@
#include "liburing.h"
static int test_openat2(struct io_uring *ring, const char *path, int dfd,
- bool direct, int fixed_index)
+ bool direct, int fixed_index, int bad_how)
{
struct io_uring_cqe *cqe;
struct io_uring_sqe *sqe;
- struct open_how how;
+ struct open_how __how, *how;
int ret;
+ if (bad_how)
+ how = (struct open_how *) (uintptr_t) 0x1234;
+ else
+ how = &__how;
+
sqe = io_uring_get_sqe(ring);
if (!sqe) {
fprintf(stderr, "get sqe failed\n");
return -1;
}
- memset(&how, 0, sizeof(how));
- how.flags = O_RDWR;
+ if (!bad_how) {
+ memset(how, 0, sizeof(*how));
+ how->flags = O_RDWR;
+ }
if (!direct)
- io_uring_prep_openat2(sqe, dfd, path, &how);
+ io_uring_prep_openat2(sqe, dfd, path, how);
else
- io_uring_prep_openat2_direct(sqe, dfd, path, &how, fixed_index);
+ io_uring_prep_openat2_direct(sqe, dfd, path, how, fixed_index);
ret = io_uring_submit(ring);
if (ret <= 0) {
@@ -79,7 +86,7 @@ static int test_open_fixed(const char *path, int dfd)
return -1;
}
- ret = test_openat2(&ring, path, dfd, true, 0);
+ ret = test_openat2(&ring, path, dfd, true, 0, 0);
if (ret == -EINVAL) {
printf("fixed open isn't supported\n");
return 1;
@@ -136,7 +143,7 @@ static int test_open_fixed_fail(const char *path, int dfd)
return -1;
}
- ret = test_openat2(&ring, path, dfd, true, 0);
+ ret = test_openat2(&ring, path, dfd, true, 0, 0);
if (ret != -ENXIO) {
fprintf(stderr, "install into not existing table, %i\n", ret);
return 1;
@@ -150,19 +157,19 @@ static int test_open_fixed_fail(const char *path, int dfd)
return -1;
}
- ret = test_openat2(&ring, path, dfd, true, 1);
+ ret = test_openat2(&ring, path, dfd, true, 1, 0);
if (ret != -EINVAL) {
fprintf(stderr, "install out of bounds, %i\n", ret);
return -1;
}
- ret = test_openat2(&ring, path, dfd, true, (1u << 16));
+ ret = test_openat2(&ring, path, dfd, true, (1u << 16), 0);
if (ret != -EINVAL) {
fprintf(stderr, "install out of bounds or u16 overflow, %i\n", ret);
return -1;
}
- ret = test_openat2(&ring, path, dfd, true, (1u << 16) + 1);
+ ret = test_openat2(&ring, path, dfd, true, (1u << 16) + 1, 0);
if (ret != -EINVAL) {
fprintf(stderr, "install out of bounds or u16 overflow, %i\n", ret);
return -1;
@@ -197,7 +204,7 @@ static int test_direct_reinstall(const char *path, int dfd)
}
/* reinstall into the second slot */
- ret = test_openat2(&ring, path, dfd, true, 1);
+ ret = test_openat2(&ring, path, dfd, true, 1, 0);
if (ret != 0) {
fprintf(stderr, "reinstall failed, %i\n", ret);
return -1;
@@ -265,18 +272,22 @@ int main(int argc, char *argv[])
if (do_unlink)
t_create_file(path_rel, 4096);
- ret = test_openat2(&ring, path, -1, false, 0);
+ ret = test_openat2(&ring, path, -1, false, 0, 0);
if (ret < 0) {
if (ret == -EINVAL) {
fprintf(stdout, "openat2 not supported, skipping\n");
goto done;
}
+ if (ret == -EPERM || ret == -EACCES)
+ return T_EXIT_SKIP;
fprintf(stderr, "test_openat2 absolute failed: %d\n", ret);
goto err;
}
- ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0);
+ ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0, 0);
if (ret < 0) {
+ if (ret == -EPERM || ret == -EACCES)
+ return T_EXIT_SKIP;
fprintf(stderr, "test_openat2 relative failed: %d\n", ret);
goto err;
}
@@ -300,6 +311,18 @@ int main(int argc, char *argv[])
goto err;
}
+ ret = test_openat2(&ring, (const char *) (uintptr_t) 0x1234, AT_FDCWD, false, 0, 0);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "test_openat2 bad address failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0, 1);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "test_openat2 bad how failed: %d\n", ret);
+ goto err;
+ }
+
done:
unlink(path);
if (do_unlink)
diff --git a/contrib/libs/liburing/test/openat2.t/ya.make b/contrib/libs/liburing/test/openat2.t/ya.make
index b7c98e6e2e..f6755732e2 100644
--- a/contrib/libs/liburing/test/openat2.t/ya.make
+++ b/contrib/libs/liburing/test/openat2.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/personality.t/ya.make b/contrib/libs/liburing/test/personality.t/ya.make
index 5d2750936e..3a58beb172 100644
--- a/contrib/libs/liburing/test/personality.t/ya.make
+++ b/contrib/libs/liburing/test/personality.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/pipe-bug.t/ya.make b/contrib/libs/liburing/test/pipe-bug.t/ya.make
index b4a71cf37e..8b44cb7a62 100644
--- a/contrib/libs/liburing/test/pipe-bug.t/ya.make
+++ b/contrib/libs/liburing/test/pipe-bug.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/pipe-eof.t/ya.make b/contrib/libs/liburing/test/pipe-eof.t/ya.make
index b53c087814..27e716bc4f 100644
--- a/contrib/libs/liburing/test/pipe-eof.t/ya.make
+++ b/contrib/libs/liburing/test/pipe-eof.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/pipe-reuse.t/ya.make b/contrib/libs/liburing/test/pipe-reuse.t/ya.make
index f393155c37..cb99dbb937 100644
--- a/contrib/libs/liburing/test/pipe-reuse.t/ya.make
+++ b/contrib/libs/liburing/test/pipe-reuse.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-cancel-all.t/ya.make b/contrib/libs/liburing/test/poll-cancel-all.t/ya.make
index d868fa9fb5..817d72989f 100644
--- a/contrib/libs/liburing/test/poll-cancel-all.t/ya.make
+++ b/contrib/libs/liburing/test/poll-cancel-all.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-cancel-ton.t/ya.make b/contrib/libs/liburing/test/poll-cancel-ton.t/ya.make
index 254f5d774b..967cf70af1 100644
--- a/contrib/libs/liburing/test/poll-cancel-ton.t/ya.make
+++ b/contrib/libs/liburing/test/poll-cancel-ton.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-cancel.t/ya.make b/contrib/libs/liburing/test/poll-cancel.t/ya.make
index 7f35cc137e..bb71bf99a0 100644
--- a/contrib/libs/liburing/test/poll-cancel.t/ya.make
+++ b/contrib/libs/liburing/test/poll-cancel.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-link.t/ya.make b/contrib/libs/liburing/test/poll-link.t/ya.make
index 9d6b445155..9e13c1959f 100644
--- a/contrib/libs/liburing/test/poll-link.t/ya.make
+++ b/contrib/libs/liburing/test/poll-link.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-many.c b/contrib/libs/liburing/test/poll-many.c
index fb00cf6327..12be9d8568 100644
--- a/contrib/libs/liburing/test/poll-many.c
+++ b/contrib/libs/liburing/test/poll-many.c
@@ -23,6 +23,8 @@
#define RING_SIZE 512
+static int nfiles = NFILES;
+
struct p {
int fd[2];
int triggered;
@@ -92,7 +94,7 @@ static int trigger_polls(void)
int off;
do {
- off = rand() % NFILES;
+ off = rand() % nfiles;
if (!p[off].triggered)
break;
} while (1);
@@ -110,7 +112,7 @@ static int trigger_polls(void)
static int arm_polls(struct io_uring *ring)
{
- int ret, to_arm = NFILES, i, off;
+ int ret, to_arm = nfiles, i, off;
off = 0;
while (to_arm) {
@@ -162,7 +164,7 @@ int main(int argc, char *argv[])
int i, ret;
if (argc > 1)
- return 0;
+ return T_EXIT_SKIP;
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
perror("getrlimit");
@@ -170,8 +172,12 @@ int main(int argc, char *argv[])
}
if (rlim.rlim_cur < (2 * NFILES + 5)) {
- rlim.rlim_cur = (2 * NFILES + 5);
- rlim.rlim_max = rlim.rlim_cur;
+ rlim.rlim_cur = rlim.rlim_max;
+ nfiles = (rlim.rlim_cur / 2) - 5;
+ if (nfiles > NFILES)
+ nfiles = NFILES;
+ if (nfiles <= 0)
+ goto err_nofail;
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
if (errno == EPERM)
goto err_nofail;
@@ -180,7 +186,7 @@ int main(int argc, char *argv[])
}
}
- for (i = 0; i < NFILES; i++) {
+ for (i = 0; i < nfiles; i++) {
if (pipe(p[i].fd) < 0) {
perror("pipe");
return T_EXIT_FAIL;
@@ -227,5 +233,5 @@ int main(int argc, char *argv[])
err_nofail:
fprintf(stderr, "poll-many: not enough files available (and not root), "
"skipped\n");
- return 0;
+ return T_EXIT_SKIP;
}
diff --git a/contrib/libs/liburing/test/poll-many.t/ya.make b/contrib/libs/liburing/test/poll-many.t/ya.make
index 67d9a682f6..88050fbf26 100644
--- a/contrib/libs/liburing/test/poll-many.t/ya.make
+++ b/contrib/libs/liburing/test/poll-many.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-mshot-overflow.t/ya.make b/contrib/libs/liburing/test/poll-mshot-overflow.t/ya.make
index ccc141a99b..a2a5ae3931 100644
--- a/contrib/libs/liburing/test/poll-mshot-overflow.t/ya.make
+++ b/contrib/libs/liburing/test/poll-mshot-overflow.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-mshot-update.c b/contrib/libs/liburing/test/poll-mshot-update.c
index c3b687260c..2014560f05 100644
--- a/contrib/libs/liburing/test/poll-mshot-update.c
+++ b/contrib/libs/liburing/test/poll-mshot-update.c
@@ -16,11 +16,14 @@
#include <pthread.h>
#include "liburing.h"
+#include "helpers.h"
#define NFILES 5000
#define BATCH 500
#define NLOOPS 1000
+static int nfiles = NFILES;
+
#define RING_SIZE 512
struct p {
@@ -161,7 +164,7 @@ static int trigger_polls(void)
int off;
do {
- off = rand() % NFILES;
+ off = rand() % nfiles;
if (!p[off].triggered)
break;
} while (1);
@@ -185,7 +188,7 @@ static void *trigger_polls_fn(void *data)
static int arm_polls(struct io_uring *ring)
{
- int ret, to_arm = NFILES, i, off;
+ int ret, to_arm = nfiles, i, off;
off = 0;
while (to_arm) {
@@ -221,7 +224,7 @@ static int run(int cqe)
pthread_t thread;
int i, j, ret;
- for (i = 0; i < NFILES; i++) {
+ for (i = 0; i < nfiles; i++) {
if (pipe(p[i].fd) < 0) {
perror("pipe");
return 1;
@@ -253,12 +256,12 @@ static int run(int cqe)
goto err;
pthread_join(thread, NULL);
- for (j = 0; j < NFILES; j++)
+ for (j = 0; j < nfiles; j++)
p[j].triggered = 0;
}
io_uring_queue_exit(&ring);
- for (i = 0; i < NFILES; i++) {
+ for (i = 0; i < nfiles; i++) {
close(p[i].fd[0]);
close(p[i].fd[1]);
}
@@ -274,7 +277,7 @@ int main(int argc, char *argv[])
int ret;
if (argc > 1)
- return 0;
+ return T_EXIT_SKIP;
ret = has_poll_update();
if (ret < 0) {
@@ -291,13 +294,17 @@ int main(int argc, char *argv[])
}
if (rlim.rlim_cur < (2 * NFILES + 5)) {
- rlim.rlim_cur = (2 * NFILES + 5);
- rlim.rlim_max = rlim.rlim_cur;
+ rlim.rlim_cur = rlim.rlim_max;
+ nfiles = (rlim.rlim_cur / 2) - 5;
+ if (nfiles > NFILES)
+ nfiles = NFILES;
+ if (nfiles <= 0)
+ goto err_nofail;
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
if (errno == EPERM)
goto err_nofail;
perror("setrlimit");
- goto err;
+ return T_EXIT_FAIL;
}
}
@@ -320,5 +327,5 @@ err:
err_nofail:
fprintf(stderr, "poll-many: not enough files available (and not root), "
"skipped\n");
- return 0;
+ return T_EXIT_SKIP;
}
diff --git a/contrib/libs/liburing/test/poll-mshot-update.t/ya.make b/contrib/libs/liburing/test/poll-mshot-update.t/ya.make
index 3453c214ee..87a58460d0 100644
--- a/contrib/libs/liburing/test/poll-mshot-update.t/ya.make
+++ b/contrib/libs/liburing/test/poll-mshot-update.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-race-mshot.t/ya.make b/contrib/libs/liburing/test/poll-race-mshot.t/ya.make
index 6fdf2c8491..130b4e495b 100644
--- a/contrib/libs/liburing/test/poll-race-mshot.t/ya.make
+++ b/contrib/libs/liburing/test/poll-race-mshot.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-race.t/ya.make b/contrib/libs/liburing/test/poll-race.t/ya.make
index 1fdc2798b0..decdc37fef 100644
--- a/contrib/libs/liburing/test/poll-race.t/ya.make
+++ b/contrib/libs/liburing/test/poll-race.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-ring.t/ya.make b/contrib/libs/liburing/test/poll-ring.t/ya.make
index 248be1c132..0b41888d72 100644
--- a/contrib/libs/liburing/test/poll-ring.t/ya.make
+++ b/contrib/libs/liburing/test/poll-ring.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll-v-poll.c b/contrib/libs/liburing/test/poll-v-poll.c
index 207f7bd5da..91362780e9 100644
--- a/contrib/libs/liburing/test/poll-v-poll.c
+++ b/contrib/libs/liburing/test/poll-v-poll.c
@@ -18,6 +18,7 @@
#include <sys/epoll.h>
#include "liburing.h"
+#include "helpers.h"
struct thread_data {
struct io_uring *ring;
@@ -175,6 +176,8 @@ static int do_fd_test(struct io_uring *ring, const char *fname, int events)
fd = open(fname, O_RDONLY);
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -332,19 +335,19 @@ int main(int argc, char *argv[])
fname = argv[0];
ret = do_fd_test(&ring, fname, POLLIN);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "fd test IN failed\n");
return ret;
}
ret = do_fd_test(&ring, fname, POLLOUT);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "fd test OUT failed\n");
return ret;
}
ret = do_fd_test(&ring, fname, POLLOUT | POLLIN);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "fd test IN|OUT failed\n");
return ret;
}
diff --git a/contrib/libs/liburing/test/poll-v-poll.t/ya.make b/contrib/libs/liburing/test/poll-v-poll.t/ya.make
index b48c0ff287..5f4c049f11 100644
--- a/contrib/libs/liburing/test/poll-v-poll.t/ya.make
+++ b/contrib/libs/liburing/test/poll-v-poll.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/poll.t/ya.make b/contrib/libs/liburing/test/poll.t/ya.make
index 809283fd40..5b2f985766 100644
--- a/contrib/libs/liburing/test/poll.t/ya.make
+++ b/contrib/libs/liburing/test/poll.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/pollfree.c b/contrib/libs/liburing/test/pollfree.c
new file mode 100644
index 0000000000..0ba3ce390d
--- /dev/null
+++ b/contrib/libs/liburing/test/pollfree.c
@@ -0,0 +1,149 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test pollfree wakeups
+ */
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/signalfd.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+static int no_signalfd;
+
+static int child(int flags)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ struct signalfd_siginfo si;
+ static unsigned long index;
+ sigset_t mask;
+ int ret, fd;
+
+ ret = io_uring_queue_init(4, &ring, flags);
+ if (ret) {
+ if (ret == -EINVAL)
+ return 0;
+ fprintf(stderr, "queue init failed %d\n", ret);
+ return ret;
+ }
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+
+ fd = signalfd(-1, &mask, SFD_NONBLOCK);
+ if (fd < 0) {
+ no_signalfd = 1;
+ perror("signalfd");
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
+ sqe->user_data = 1;
+ io_uring_submit(&ring);
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
+ sqe->user_data = 2;
+ sqe->flags |= IOSQE_ASYNC;
+ io_uring_submit(&ring);
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
+ sqe->user_data = 3;
+ io_uring_submit(&ring);
+
+ if (!(++index & 7))
+ usleep(100);
+
+ return 0;
+}
+
+static int run_test(int flags)
+{
+ pid_t pid;
+ int ret;
+
+ pid = fork();
+ if (pid < 0) {
+ perror("fork");
+ return 1;
+ } else if (!pid) {
+ ret = child(flags);
+ _exit(ret);
+ } else {
+ int wstatus;
+ pid_t childpid;
+
+ do {
+ childpid = waitpid(pid, &wstatus, 0);
+ } while (childpid == (pid_t) -1 && (errno == EINTR));
+
+ if (errno == ECHILD)
+ wstatus = 0;
+ return wstatus;
+ }
+}
+
+static int test(int flags)
+{
+ struct timeval start;
+ int ret;
+
+ gettimeofday(&start, NULL);
+ do {
+ ret = run_test(flags);
+ if (ret) {
+ fprintf(stderr, "test failed with flags %x\n", flags);
+ return 1;
+ }
+ if (no_signalfd)
+ break;
+ } while (mtime_since_now(&start) < 2500);
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test(0);
+ if (ret) {
+ fprintf(stderr, "test 0 failed: %d\n", ret);
+ return ret;
+ }
+
+ if (no_signalfd)
+ return T_EXIT_SKIP;
+
+ ret = test(IORING_SETUP_SQPOLL);
+ if (ret) {
+ fprintf(stderr, "test SQPOLL failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = test(IORING_SETUP_COOP_TASKRUN);
+ if (ret) {
+ fprintf(stderr, "test COOP failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = test(IORING_SETUP_DEFER_TASKRUN|IORING_SETUP_SINGLE_ISSUER);
+ if (ret) {
+ fprintf(stderr, "test DEFER failed: %d\n", ret);
+ return ret;
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/pollfree.t/ya.make b/contrib/libs/liburing/test/pollfree.t/ya.make
new file mode 100644
index 0000000000..250c998824
--- /dev/null
+++ b/contrib/libs/liburing/test/pollfree.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ pollfree.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/probe.t/ya.make b/contrib/libs/liburing/test/probe.t/ya.make
index abc6c4a41e..6ca9e5b012 100644
--- a/contrib/libs/liburing/test/probe.t/ya.make
+++ b/contrib/libs/liburing/test/probe.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/read-before-exit.t/ya.make b/contrib/libs/liburing/test/read-before-exit.t/ya.make
index d762a60d86..e063ffe60c 100644
--- a/contrib/libs/liburing/test/read-before-exit.t/ya.make
+++ b/contrib/libs/liburing/test/read-before-exit.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/read-mshot-empty.c b/contrib/libs/liburing/test/read-mshot-empty.c
index 2fc5a63184..66ed02d973 100644
--- a/contrib/libs/liburing/test/read-mshot-empty.c
+++ b/contrib/libs/liburing/test/read-mshot-empty.c
@@ -117,8 +117,10 @@ int main(int argc, char *argv[])
*/
ret = io_uring_peek_cqe(&ring, &cqe);
if (!ret) {
- if (cqe->res == -EINVAL || cqe->res == -EBADF)
+ if (cqe->res == -EINVAL || cqe->res == -EBADF) {
+ free(buf);
return T_EXIT_SKIP;
+ }
}
pthread_create(&thread, NULL, thread_fn, fds);
@@ -150,5 +152,8 @@ int main(int argc, char *argv[])
}
pthread_join(thread, &tret);
+ io_uring_free_buf_ring(&ring, br, NR_BUFS, BGID);
+ io_uring_queue_exit(&ring);
+ free(buf);
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/read-mshot-empty.t/ya.make b/contrib/libs/liburing/test/read-mshot-empty.t/ya.make
index bf50a15474..5c846118f3 100644
--- a/contrib/libs/liburing/test/read-mshot-empty.t/ya.make
+++ b/contrib/libs/liburing/test/read-mshot-empty.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/read-mshot-stdin.c b/contrib/libs/liburing/test/read-mshot-stdin.c
new file mode 100644
index 0000000000..9ac602204a
--- /dev/null
+++ b/contrib/libs/liburing/test/read-mshot-stdin.c
@@ -0,0 +1,122 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test multishot read on stdin. Not that this REQUIRES input
+ * to be received on stdin, and hence if invoked with no
+ * arguments, or without the single argument being 'stdin',
+ * the test will just return SKIPPED. Can't be run from the
+ * standard test harness, as it's interactive.
+ *
+ * To run, do run "test/read-mshot-stdin.t stdin" and then input text on
+ * the console, followed by enter / line feed. If it works as it should,
+ * it'll output the received CQE data. If an error is detected, it'll
+ * abort with an error.
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define BUF_SIZE 32
+#define NR_BUFS 64
+#define BUF_BGID 1
+
+#define BR_MASK (NR_BUFS - 1)
+
+static int test_stdin(void)
+{
+ struct io_uring_buf_ring *br;
+ struct io_uring_params p = { };
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct io_uring ring;
+ int ret, i, last_bid;
+ char *buf, *ptr;
+
+ p.flags = IORING_SETUP_CQSIZE;
+ p.cq_entries = NR_BUFS;
+ ret = io_uring_queue_init_params(1, &ring, &p);
+ if (ret) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ if (posix_memalign((void **) &buf, 4096, NR_BUFS * BUF_SIZE))
+ return T_EXIT_FAIL;
+
+ br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, 0, &ret);
+ if (!br) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "Buffer ring register failed %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ptr = buf;
+ for (i = 0; i < NR_BUFS; i++) {
+ io_uring_buf_ring_add(br, ptr, BUF_SIZE, i + 1, BR_MASK, i);
+ ptr += BUF_SIZE;
+ }
+ io_uring_buf_ring_advance(br, NR_BUFS);
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read_multishot(sqe, STDIN_FILENO, 0, 0, BUF_BGID);
+
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "submit: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ last_bid = -1;
+ do {
+ int bid;
+
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait cqe failed %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ if (cqe->res && !(cqe->flags & IORING_CQE_F_BUFFER)) {
+ fprintf(stderr, "BUF flag not set %x\n", cqe->flags);
+ return T_EXIT_FAIL;
+ }
+ bid = cqe->flags >> 16;
+ printf("CQE res %d, bid %d, flags %x\n", cqe->res, bid, cqe->flags);
+ if (cqe->res > 0 && last_bid != -1 && last_bid + 1 != bid) {
+ fprintf(stderr, "Got bid %d, wanted %d\n", bid, last_bid + 1);
+ return T_EXIT_FAIL;
+ }
+ if (!(cqe->flags & IORING_CQE_F_MORE)) {
+ io_uring_cqe_seen(&ring, cqe);
+ break;
+ }
+
+ last_bid = bid;
+ io_uring_cqe_seen(&ring, cqe);
+ }while (1);
+
+ io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
+ io_uring_queue_exit(&ring);
+ free(buf);
+ return T_EXIT_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc == 1)
+ return T_EXIT_SKIP;
+ else if (argc > 2)
+ return T_EXIT_SKIP;
+ if (!strcmp(argv[1], "stdin"))
+ return test_stdin();
+ return T_EXIT_SKIP;
+}
diff --git a/contrib/libs/liburing/test/read-mshot-stdin.t/ya.make b/contrib/libs/liburing/test/read-mshot-stdin.t/ya.make
new file mode 100644
index 0000000000..66267bf515
--- /dev/null
+++ b/contrib/libs/liburing/test/read-mshot-stdin.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ read-mshot-stdin.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/read-mshot.c b/contrib/libs/liburing/test/read-mshot.c
index 681a306ad4..fe063d03f3 100644
--- a/contrib/libs/liburing/test/read-mshot.c
+++ b/contrib/libs/liburing/test/read-mshot.c
@@ -24,7 +24,134 @@
#define NR_OVERFLOW (NR_BUFS / 4)
-static int no_buf_ring, no_read_mshot;
+static int no_buf_ring, no_read_mshot, no_buf_ring_inc;
+
+static void arm_read(struct io_uring *ring, int fd, int use_mshot)
+{
+ struct io_uring_sqe *sqe;
+
+ sqe = io_uring_get_sqe(ring);
+ if (use_mshot) {
+ io_uring_prep_read_multishot(sqe, fd, 0, 0, BUF_BGID);
+ } else {
+ io_uring_prep_read(sqe, fd, NULL, 0, 0);
+ sqe->flags = IOSQE_BUFFER_SELECT;
+ sqe->buf_group = BUF_BGID;
+ }
+
+ io_uring_submit(ring);
+}
+
+static int test_inc(int use_mshot, int flags)
+{
+ struct io_uring_buf_ring *br;
+ struct io_uring_params p = { };
+ struct io_uring_cqe *cqe;
+ struct io_uring ring;
+ int nbytes = 65536;
+ int ret, fds[2], i;
+ char tmp[31];
+ char *buf;
+ void *ptr;
+ int bid = -1;
+ int bid_bytes;
+
+ if (no_buf_ring)
+ return 0;
+
+ p.flags = flags;
+ ret = io_uring_queue_init_params(64, &ring, &p);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return 1;
+ }
+
+ if (pipe(fds) < 0) {
+ perror("pipe");
+ return 1;
+ }
+
+ if (posix_memalign((void **) &buf, 4096, 65536))
+ return 1;
+
+ br = io_uring_setup_buf_ring(&ring, 32, BUF_BGID, IOU_PBUF_RING_INC, &ret);
+ if (!br) {
+ if (ret == -EINVAL) {
+ no_buf_ring_inc = 1;
+ free(buf);
+ return 0;
+ }
+ fprintf(stderr, "Buffer ring register failed %d\n", ret);
+ return 1;
+ }
+
+ ptr = buf;
+ buf = ptr + 65536 - 2048;
+ for (i = 0; i < 32; i++) {
+ io_uring_buf_ring_add(br, buf, 2048, i, 31, i);
+ buf -= 2048;
+ }
+ io_uring_buf_ring_advance(br, 32);
+
+ memset(tmp, 0x5a, sizeof(tmp));
+
+ arm_read(&ring, fds[0], use_mshot);
+
+ bid_bytes = 0;
+ do {
+ int write_size = sizeof(tmp);
+
+ if (write_size > nbytes)
+ write_size = nbytes;
+
+ io_uring_get_events(&ring);
+ ret = io_uring_peek_cqe(&ring, &cqe);
+ if (!ret) {
+ int this_bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
+ if (bid == -1) {
+ bid = this_bid;
+ } else if (bid != this_bid) {
+ if (bid_bytes != 2048) {
+ fprintf(stderr, "unexpected bid bytes %d\n",
+ bid_bytes);
+ return 1;
+ }
+ bid = this_bid;
+ bid_bytes = 0;
+ }
+ bid_bytes += cqe->res;
+ nbytes -= cqe->res;
+ if (!(cqe->flags & IORING_CQE_F_MORE))
+ arm_read(&ring, fds[0], use_mshot);
+ io_uring_cqe_seen(&ring, cqe);
+ if (!nbytes)
+ break;
+ }
+ usleep(1000);
+ ret = write(fds[1], tmp, write_size);
+ if (ret < 0) {
+ perror("write");
+ return 1;
+ } else if (ret != write_size) {
+ printf("short write %d\n", ret);
+ return 1;
+ }
+ } while (nbytes);
+
+ if (bid_bytes) {
+ if (bid_bytes != 2048) {
+ fprintf(stderr, "unexpected bid bytes %d\n", bid_bytes);
+ return 1;
+ }
+ }
+
+ io_uring_free_buf_ring(&ring, br, 32, BUF_BGID);
+ io_uring_queue_exit(&ring);
+ free(ptr);
+ close(fds[0]);
+ close(fds[1]);
+ return 0;
+}
static int test_clamp(void)
{
@@ -130,21 +257,24 @@ static int test_clamp(void)
io_uring_cqe_seen(&ring, cqe);
}
+ io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
io_uring_queue_exit(&ring);
free(ptr);
return 0;
}
-static int test(int first_good, int async, int overflow)
+static int test(int first_good, int async, int overflow, int incremental)
{
struct io_uring_buf_ring *br;
struct io_uring_params p = { };
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
struct io_uring ring;
- int ret, fds[2], i;
+ int ret, fds[2], i, start_msg = 0;
+ int br_flags = 0;
char tmp[32];
void *ptr[NR_BUFS];
+ char *inc_index;
p.flags = IORING_SETUP_CQSIZE;
if (!overflow)
@@ -157,14 +287,19 @@ static int test(int first_good, int async, int overflow)
return 1;
}
- if (pipe(fds) < 0) {
- perror("pipe");
- return 1;
+ if (incremental) {
+ if (no_buf_ring_inc)
+ return 0;
+ br_flags |= IOU_PBUF_RING_INC;
}
- br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, 0, &ret);
+ br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, br_flags, &ret);
if (!br) {
if (ret == -EINVAL) {
+ if (incremental) {
+ no_buf_ring_inc = 1;
+ return 0;
+ }
no_buf_ring = 1;
return 0;
}
@@ -172,17 +307,30 @@ static int test(int first_good, int async, int overflow)
return 1;
}
- for (i = 0; i < NR_BUFS; i++) {
- unsigned size = i <= 1 ? BUF_SIZE_FIRST : BUF_SIZE;
- ptr[i] = malloc(size);
- if (!ptr[i])
- return 1;
- io_uring_buf_ring_add(br, ptr[i], size, i + 1, BR_MASK, i);
+ if (pipe(fds) < 0) {
+ perror("pipe");
+ return 1;
+ }
+
+ if (!incremental) {
+ for (i = 0; i < NR_BUFS; i++) {
+ unsigned size = i <= 1 ? BUF_SIZE_FIRST : BUF_SIZE;
+ ptr[i] = malloc(size);
+ if (!ptr[i])
+ return 1;
+ io_uring_buf_ring_add(br, ptr[i], size, i + 1, BR_MASK, i);
+ }
+ inc_index = NULL;
+ io_uring_buf_ring_advance(br, NR_BUFS);
+ } else {
+ inc_index = ptr[0] = malloc(NR_BUFS * BUF_SIZE);
+ memset(inc_index, 0, NR_BUFS * BUF_SIZE);
+ io_uring_buf_ring_add(br, ptr[0], NR_BUFS * BUF_SIZE, 1, BR_MASK, 0);
+ io_uring_buf_ring_advance(br, 1);
}
- io_uring_buf_ring_advance(br, NR_BUFS);
if (first_good) {
- sprintf(tmp, "this is buffer %d\n", 0);
+ sprintf(tmp, "this is buffer %d\n", start_msg++);
ret = write(fds[1], tmp, strlen(tmp));
}
@@ -202,7 +350,7 @@ static int test(int first_good, int async, int overflow)
for (i = 0; i < NR_BUFS + !first_good; i++) {
/* prevent pipe buffer merging */
usleep(1000);
- sprintf(tmp, "this is buffer %d\n", i + 1);
+ sprintf(tmp, "this is buffer %d\n", i + start_msg);
ret = write(fds[1], tmp, strlen(tmp));
if (ret != strlen(tmp)) {
fprintf(stderr, "write ret %d\n", ret);
@@ -211,6 +359,8 @@ static int test(int first_good, int async, int overflow)
}
for (i = 0; i < NR_BUFS + 1; i++) {
+ int bid;
+
ret = io_uring_wait_cqe(&ring, &cqe);
if (ret) {
fprintf(stderr, "wait cqe failed %d\n", ret);
@@ -235,6 +385,18 @@ static int test(int first_good, int async, int overflow)
fprintf(stderr, "no buffer selected\n");
return 1;
}
+ bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
+ if (incremental && bid != 1) {
+ fprintf(stderr, "bid %d for incremental\n", bid);
+ return 1;
+ }
+ if (incremental && !first_good) {
+ char out_buf[64];
+ sprintf(out_buf, "this is buffer %d\n", i + start_msg);
+ if (strncmp(inc_index, out_buf, strlen(out_buf)))
+ return 1;
+ inc_index += cqe->res;
+ }
if (!(cqe->flags & IORING_CQE_F_MORE)) {
/* we expect this on overflow */
if (overflow && i >= NR_OVERFLOW)
@@ -250,9 +412,15 @@ static int test(int first_good, int async, int overflow)
io_uring_cqe_seen(&ring, cqe);
}
+
+ io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
io_uring_queue_exit(&ring);
- for (i = 0; i < NR_BUFS; i++)
- free(ptr[i]);
+ if (incremental) {
+ free(ptr[0]);
+ } else {
+ for (i = 0; i < NR_BUFS; i++)
+ free(ptr[i]);
+ }
return 0;
}
@@ -321,6 +489,7 @@ static int test_invalid(int async)
}
io_uring_cqe_seen(&ring, cqe);
+ io_uring_free_buf_ring(&ring, br, 1, BUF_BGID);
io_uring_queue_exit(&ring);
free(buf);
return 0;
@@ -333,56 +502,106 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
- ret = test(0, 0, 0);
+ ret = test(0, 0, 0, 0);
if (ret) {
fprintf(stderr, "test 0 0 0 failed\n");
return T_EXIT_FAIL;
}
- if (no_buf_ring || no_read_mshot)
+ if (no_buf_ring || no_read_mshot) {
+ printf("skip\n");
return T_EXIT_SKIP;
+ }
- ret = test(0, 1, 0);
+ ret = test(0, 1, 0, 0);
if (ret) {
fprintf(stderr, "test 0 1 0, failed\n");
return T_EXIT_FAIL;
}
- ret = test(1, 0, 0);
+ ret = test(1, 0, 0, 0);
if (ret) {
fprintf(stderr, "test 1 0 0 failed\n");
return T_EXIT_FAIL;
}
- ret = test(0, 0, 1);
+ ret = test(0, 0, 1, 0);
if (ret) {
fprintf(stderr, "test 0 0 1 failed\n");
return T_EXIT_FAIL;
}
- ret = test(0, 1, 1);
+ ret = test(0, 1, 1, 0);
if (ret) {
fprintf(stderr, "test 0 1 1 failed\n");
return T_EXIT_FAIL;
}
- ret = test(1, 0, 1);
+ ret = test(1, 0, 1, 0);
if (ret) {
fprintf(stderr, "test 1 0 1, failed\n");
return T_EXIT_FAIL;
}
- ret = test(1, 0, 1);
+ ret = test(1, 0, 1, 0);
if (ret) {
fprintf(stderr, "test 1 0 1 failed\n");
return T_EXIT_FAIL;
}
- ret = test(1, 1, 1);
+ ret = test(1, 1, 1, 0);
if (ret) {
fprintf(stderr, "test 1 1 1 failed\n");
return T_EXIT_FAIL;
}
+ ret = test(0, 0, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test 0 0 0 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(0, 0, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test 0 0 1 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(0, 1, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test 0 1 0 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(0, 1, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test 0 1 1 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(1, 0, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test 1 0 0 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(1, 0, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test 1 0 1 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(1, 1, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test 1 1 0 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(1, 1, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test 1 1 1 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
ret = test_invalid(0);
if (ret) {
fprintf(stderr, "test_invalid 0 failed\n");
@@ -401,5 +620,41 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
+ ret = test_inc(0, 0);
+ if (ret) {
+ fprintf(stderr, "test_inc 0 0 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_inc(0, IORING_SETUP_SQPOLL);
+ if (ret) {
+ fprintf(stderr, "test_inc 0 sqpoll failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_inc(0, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
+ if (ret) {
+ fprintf(stderr, "test_inc 0 defer failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_inc(1, 0);
+ if (ret) {
+ fprintf(stderr, "test_inc 1 0 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_inc(1, IORING_SETUP_SQPOLL);
+ if (ret) {
+ fprintf(stderr, "test_inc 1 sqpoll failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_inc(1, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
+ if (ret) {
+ fprintf(stderr, "test_inc 1 defer failed\n");
+ return T_EXIT_FAIL;
+ }
+
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/read-mshot.t/ya.make b/contrib/libs/liburing/test/read-mshot.t/ya.make
index a760a7efbd..44f536e7bb 100644
--- a/contrib/libs/liburing/test/read-mshot.t/ya.make
+++ b/contrib/libs/liburing/test/read-mshot.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/read-write.c b/contrib/libs/liburing/test/read-write.c
index 2ca1fde1a4..dd4dddff34 100644
--- a/contrib/libs/liburing/test/read-write.c
+++ b/contrib/libs/liburing/test/read-write.c
@@ -16,6 +16,7 @@
#include "helpers.h"
#include "liburing.h"
+#include "../src/syscall.h"
#define FILE_SIZE (256 * 1024)
#define BS 8192
@@ -24,6 +25,7 @@
static struct iovec *vecs;
static int no_read;
static int no_buf_select;
+static int no_buf_copy;
static int warned;
static int create_nonaligned_buffers(void)
@@ -43,9 +45,9 @@ static int create_nonaligned_buffers(void)
return 0;
}
-static int __test_io(const char *file, struct io_uring *ring, int write,
- int buffered, int sqthread, int fixed, int nonvec,
- int buf_select, int seq, int exp_len)
+static int _test_io(const char *file, struct io_uring *ring, int write,
+ int buffered, int sqthread, int fixed, int nonvec,
+ int buf_select, int seq, int exp_len)
{
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
@@ -65,7 +67,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
if (!buffered)
open_flags |= O_DIRECT;
- if (fixed) {
+ if (fixed == 1) {
ret = t_register_buffers(ring, vecs, BUFFERS);
if (ret == T_SETUP_SKIP)
return 0;
@@ -77,7 +79,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
fd = open(file, open_flags);
if (fd < 0) {
- if (errno == EINVAL)
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
return 0;
perror("file open");
goto err;
@@ -202,13 +204,6 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
io_uring_cqe_seen(ring, cqe);
}
- if (fixed) {
- ret = io_uring_unregister_buffers(ring);
- if (ret) {
- fprintf(stderr, "buffer unreg failed: %d\n", ret);
- goto err;
- }
- }
if (sqthread) {
ret = io_uring_unregister_files(ring);
if (ret) {
@@ -230,6 +225,65 @@ err:
close(fd);
return 1;
}
+
+static int __test_io(const char *file, struct io_uring *ring, int write,
+ int buffered, int sqthread, int fixed, int nonvec,
+ int buf_select, int seq, int exp_len)
+{
+ int ret;
+
+ ret = _test_io(file, ring, write, buffered, sqthread, fixed, nonvec,
+ buf_select, seq, exp_len);
+ if (ret)
+ return ret;
+
+ if (fixed) {
+ struct io_uring ring2;
+ int ring_flags = 0;
+
+ if (no_buf_copy)
+ return 0;
+ if (sqthread)
+ ring_flags = IORING_SETUP_SQPOLL;
+ ret = t_create_ring(64, &ring2, ring_flags);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ ret = io_uring_clone_buffers(&ring2, ring);
+ if (ret) {
+ if (ret == -EINVAL) {
+ no_buf_copy = 1;
+ io_uring_queue_exit(&ring2);
+ return 0;
+ }
+ fprintf(stderr, "copy buffers: %d\n", ret);
+ return ret;
+ }
+ ret = _test_io(file, &ring2, write, buffered, sqthread, 2,
+ nonvec, buf_select, seq, exp_len);
+ if (ret)
+ return ret;
+
+ ret = io_uring_unregister_buffers(ring);
+ if (ret) {
+ fprintf(stderr, "buffer unreg failed: %d\n", ret);
+ return ret;
+ }
+ ret = io_uring_unregister_buffers(&ring2);
+ if (ret) {
+ fprintf(stderr, "buffer copy unreg failed: %d\n", ret);
+ return ret;
+ }
+ io_uring_queue_exit(&ring2);
+ }
+
+ return ret;
+}
+
static int test_io(const char *file, int write, int buffered, int sqthread,
int fixed, int nonvec, int exp_len)
{
@@ -267,6 +321,8 @@ static int read_poll_link(const char *file)
fd = open(file, O_WRONLY);
if (fd < 0) {
+ if (errno == EACCES || errno == EPERM)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -339,6 +395,7 @@ out:
if (!(p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED))
goto out;
io_uring_queue_exit(&ring);
+ free(p);
return 1;
}
@@ -697,6 +754,8 @@ static int test_io_link(const char *file)
fd = open(file, O_WRONLY);
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES)
+ return 0;
perror("file open");
goto err;
}
@@ -930,7 +989,7 @@ int main(int argc, char *argv[])
}
ret = read_poll_link(fname);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "read_poll_link failed\n");
goto err;
}
@@ -971,6 +1030,12 @@ int main(int argc, char *argv[])
goto err;
}
+ if(vecs != NULL) {
+ for (i = 0; i < BUFFERS; i++)
+ free(vecs[i].iov_base);
+ }
+ free(vecs);
+
srand((unsigned)time(NULL));
if (create_nonaligned_buffers()) {
fprintf(stderr, "file creation failed\n");
diff --git a/contrib/libs/liburing/test/read-write.t/ya.make b/contrib/libs/liburing/test/read-write.t/ya.make
index 25de751b18..7d887f6898 100644
--- a/contrib/libs/liburing/test/read-write.t/ya.make
+++ b/contrib/libs/liburing/test/read-write.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/recv-msgall-stream.c b/contrib/libs/liburing/test/recv-msgall-stream.c
index 355b1f5cfe..77eb45d86e 100644
--- a/contrib/libs/liburing/test/recv-msgall-stream.c
+++ b/contrib/libs/liburing/test/recv-msgall-stream.c
@@ -318,6 +318,7 @@ static int do_send(struct recv_data *rd)
if (cqe->res == -EINVAL) {
fprintf(stdout, "send not supported, skipping\n");
close(sockfd);
+ free(buf);
return 0;
}
if (cqe->res != iov.iov_len) {
@@ -329,10 +330,12 @@ static int do_send(struct recv_data *rd)
shutdown(sockfd, SHUT_RDWR);
close(sockfd);
+ free(buf);
return 0;
err:
shutdown(sockfd, SHUT_RDWR);
close(sockfd);
+ free(buf);
return 1;
}
diff --git a/contrib/libs/liburing/test/recv-msgall-stream.t/ya.make b/contrib/libs/liburing/test/recv-msgall-stream.t/ya.make
index 428cb35d61..414c410945 100644
--- a/contrib/libs/liburing/test/recv-msgall-stream.t/ya.make
+++ b/contrib/libs/liburing/test/recv-msgall-stream.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/recv-msgall.c b/contrib/libs/liburing/test/recv-msgall.c
index e0d94f33b1..c95ab7f914 100644
--- a/contrib/libs/liburing/test/recv-msgall.c
+++ b/contrib/libs/liburing/test/recv-msgall.c
@@ -172,12 +172,14 @@ static int do_send(void)
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
+ free(buf);
return 1;
}
ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret < 0) {
perror("connect");
+ free(buf);
return 1;
}
@@ -202,6 +204,7 @@ static int do_send(void)
if (cqe->res == -EINVAL) {
fprintf(stdout, "send not supported, skipping\n");
close(sockfd);
+ free(buf);
return 0;
}
if (cqe->res != iov.iov_len) {
@@ -212,9 +215,11 @@ static int do_send(void)
}
close(sockfd);
+ free(buf);
return 0;
err:
close(sockfd);
+ free(buf);
return 1;
}
diff --git a/contrib/libs/liburing/test/recv-msgall.t/ya.make b/contrib/libs/liburing/test/recv-msgall.t/ya.make
index 6a779b4378..f8c6f883aa 100644
--- a/contrib/libs/liburing/test/recv-msgall.t/ya.make
+++ b/contrib/libs/liburing/test/recv-msgall.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/recv-multishot.t/ya.make b/contrib/libs/liburing/test/recv-multishot.t/ya.make
index 4196930356..97c41c11e5 100644
--- a/contrib/libs/liburing/test/recv-multishot.t/ya.make
+++ b/contrib/libs/liburing/test/recv-multishot.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/recvsend_bundle-inc.c b/contrib/libs/liburing/test/recvsend_bundle-inc.c
new file mode 100644
index 0000000000..3e10ce4b64
--- /dev/null
+++ b/contrib/libs/liburing/test/recvsend_bundle-inc.c
@@ -0,0 +1,681 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Simple test case showing using send and recv bundles with incremental
+ * buffer ring usage
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+#define MSG_SIZE 128
+#define NR_MIN_MSGS 4
+#define NR_MAX_MSGS 32
+#define SEQ_SIZE (MSG_SIZE / sizeof(unsigned long))
+
+static int nr_msgs;
+
+#define RECV_BIDS 8192
+#define RECV_BID_MASK (RECV_BIDS - 1)
+
+#include <liburing.h>
+
+enum t_test_result {
+ T_EXIT_PASS = 0,
+ T_EXIT_FAIL = 1,
+ T_EXIT_SKIP = 77,
+};
+
+#define PORT 10202
+#define HOST "127.0.0.1"
+
+static int use_port = PORT;
+
+#define SEND_BGID 7
+#define RECV_BGID 8
+
+static int no_send_mshot;
+
+struct recv_data {
+ pthread_barrier_t connect;
+ pthread_barrier_t startup;
+ pthread_barrier_t barrier;
+ pthread_barrier_t finish;
+ unsigned long seq;
+ int recv_bytes;
+ int accept_fd;
+ int abort;
+ unsigned int max_sends;
+ int to_eagain;
+ void *recv_buf;
+
+ int send_bundle;
+ int recv_bundle;
+};
+
+static int arm_recv(struct io_uring *ring, struct recv_data *rd)
+{
+ struct io_uring_sqe *sqe;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_recv_multishot(sqe, rd->accept_fd, NULL, 0, 0);
+ if (rd->recv_bundle)
+ sqe->ioprio |= IORING_RECVSEND_BUNDLE;
+ sqe->buf_group = RECV_BGID;
+ sqe->flags |= IOSQE_BUFFER_SELECT;
+ sqe->user_data = 2;
+
+ ret = io_uring_submit(ring);
+ if (ret != 1) {
+ fprintf(stderr, "submit failed: %d\n", ret);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int recv_prep(struct io_uring *ring, struct recv_data *rd, int *sock)
+{
+ struct sockaddr_in saddr;
+ int sockfd, ret, val, use_fd;
+ socklen_t socklen;
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ saddr.sin_port = htons(use_port);
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0) {
+ perror("socket");
+ return 1;
+ }
+
+ val = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+
+ ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
+ if (ret < 0) {
+ perror("bind");
+ goto err;
+ }
+
+ ret = listen(sockfd, 1);
+ if (ret < 0) {
+ perror("listen");
+ goto err;
+ }
+
+ pthread_barrier_wait(&rd->connect);
+
+ socklen = sizeof(saddr);
+ use_fd = accept(sockfd, (struct sockaddr *)&saddr, &socklen);
+ if (use_fd < 0) {
+ perror("accept");
+ goto err;
+ }
+
+ rd->accept_fd = use_fd;
+ pthread_barrier_wait(&rd->startup);
+ pthread_barrier_wait(&rd->barrier);
+
+ if (arm_recv(ring, rd))
+ goto err;
+
+ *sock = sockfd;
+ return 0;
+err:
+ close(sockfd);
+ return 1;
+}
+
+static int verify_seq(struct recv_data *rd, void *verify_ptr, int verify_sz,
+ int start_bid)
+{
+ unsigned long *seqp;
+ int seq_size = verify_sz / sizeof(unsigned long);
+ int i;
+
+ seqp = verify_ptr;
+ for (i = 0; i < seq_size; i++) {
+ if (rd->seq != *seqp) {
+ fprintf(stderr, "bid=%d, got seq %lu, wanted %lu, offset %d\n", start_bid, *seqp, rd->seq, i);
+ return 0;
+ }
+ seqp++;
+ rd->seq++;
+ }
+
+ return 1;
+}
+
+static int recv_get_cqe(struct io_uring *ring, struct recv_data *rd,
+ struct io_uring_cqe **cqe)
+{
+ struct __kernel_timespec ts = { .tv_sec = 0, .tv_nsec = 100000000LL };
+ int ret;
+
+ do {
+ ret = io_uring_wait_cqe_timeout(ring, cqe, &ts);
+ if (!ret)
+ return 0;
+ if (ret == -ETIME) {
+ if (rd->abort)
+ break;
+ continue;
+ }
+ fprintf(stderr, "wait recv: %d\n", ret);
+ break;
+ } while (1);
+
+ return 1;
+}
+
+static int do_recv(struct io_uring *ring, struct recv_data *rd)
+{
+ struct io_uring_cqe *cqe;
+ void *verify_ptr;
+ int verify_sz = 0;
+ int verify_bid = 0;
+ int bid;
+
+ verify_ptr = malloc(rd->recv_bytes);
+
+ do {
+ if (recv_get_cqe(ring, rd, &cqe))
+ break;
+ if (cqe->res == -EINVAL) {
+ fprintf(stdout, "recv not supported, skipping\n");
+ return 0;
+ }
+ if (cqe->res < 0) {
+ fprintf(stderr, "failed recv cqe: %d\n", cqe->res);
+ goto err;
+ }
+ if (!(cqe->flags & IORING_CQE_F_BUFFER)) {
+ fprintf(stderr, "no buffer set in recv\n");
+ goto err;
+ }
+ if (!(cqe->flags & IORING_CQE_F_BUF_MORE)) {
+ fprintf(stderr, "CQE_F_BUF_MORE not set\n");
+ goto err;
+ }
+ bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
+ if (bid != 0) {
+ fprintf(stderr, "got bid %d\n", bid);
+ goto err;
+ }
+ if (!(verify_sz % MSG_SIZE)) {
+ if (!verify_seq(rd, verify_ptr, verify_sz, verify_bid))
+ goto err;
+ verify_bid += verify_sz / MSG_SIZE;
+ verify_bid &= RECV_BID_MASK;
+ verify_sz = 0;
+ } else {
+ memcpy(verify_ptr + verify_sz, rd->recv_buf + (bid * MSG_SIZE), cqe->res);
+ verify_sz += cqe->res;
+ }
+ rd->recv_bytes -= cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ if (!(cqe->flags & IORING_CQE_F_MORE) && rd->recv_bytes) {
+ if (arm_recv(ring, rd))
+ goto err;
+ }
+ } while (rd->recv_bytes);
+
+ if (verify_sz && !(verify_sz % MSG_SIZE) &&
+ !verify_seq(rd, verify_ptr, verify_sz, verify_bid))
+ goto err;
+
+ pthread_barrier_wait(&rd->finish);
+ return 0;
+err:
+ pthread_barrier_wait(&rd->finish);
+ return 1;
+}
+
+static void *recv_fn(void *data)
+{
+ struct recv_data *rd = data;
+ struct io_uring_params p = { };
+ struct io_uring ring;
+ struct io_uring_buf_ring *br;
+ void *buf, *ptr;
+ int ret, sock;
+
+ p.cq_entries = 4096;
+ p.flags = IORING_SETUP_CQSIZE;
+ io_uring_queue_init_params(16, &ring, &p);
+
+ ret = 0;
+ if (posix_memalign(&buf, 4096, MSG_SIZE * RECV_BIDS))
+ goto err;
+
+ br = io_uring_setup_buf_ring(&ring, RECV_BIDS, RECV_BGID, IOU_PBUF_RING_INC, &ret);
+ if (!br) {
+ fprintf(stderr, "failed setting up recv ring %d\n", ret);
+ goto err;
+ }
+
+ ptr = buf;
+ io_uring_buf_ring_add(br, ptr, MSG_SIZE * RECV_BIDS, 0, RECV_BID_MASK, 0);
+ io_uring_buf_ring_advance(br, 1);
+ rd->recv_buf = buf;
+
+ ret = recv_prep(&ring, rd, &sock);
+ if (ret) {
+ fprintf(stderr, "recv_prep failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = do_recv(&ring, rd);
+
+ close(sock);
+ close(rd->accept_fd);
+ free(buf);
+ io_uring_queue_exit(&ring);
+err:
+ return (void *)(intptr_t)ret;
+}
+
+static int __do_send_bundle(struct recv_data *rd, struct io_uring *ring, int sockfd)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int bytes_needed = MSG_SIZE * nr_msgs;
+ int i, ret;
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_send_bundle(sqe, sockfd, 0, 0);
+ sqe->flags |= IOSQE_BUFFER_SELECT;
+ sqe->buf_group = SEND_BGID;
+ sqe->user_data = 1;
+
+ ret = io_uring_submit(ring);
+ if (ret != 1)
+ return 1;
+
+ pthread_barrier_wait(&rd->barrier);
+
+ for (i = 0; i < nr_msgs; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait send: %d\n", ret);
+ return 1;
+ }
+ if (!i && cqe->res == -EINVAL) {
+ rd->abort = 1;
+ no_send_mshot = 1;
+ break;
+ }
+ if (cqe->res < 0) {
+ fprintf(stderr, "bad send cqe res: %d\n", cqe->res);
+ return 1;
+ }
+ bytes_needed -= cqe->res;
+ if (!bytes_needed) {
+ io_uring_cqe_seen(ring, cqe);
+ break;
+ }
+ if (!(cqe->flags & IORING_CQE_F_MORE)) {
+ fprintf(stderr, "expected more, but MORE not set\n");
+ return 1;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ return 0;
+}
+
+static int __do_send(struct recv_data *rd, struct io_uring *ring, int sockfd)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int bytes_needed = MSG_SIZE * nr_msgs;
+ int i, ret;
+
+ for (i = 0; i < nr_msgs; i++) {
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_send(sqe, sockfd, NULL, 0, 0);
+ sqe->user_data = 10 + i;
+ sqe->flags |= IOSQE_BUFFER_SELECT;
+ sqe->buf_group = SEND_BGID;
+
+ ret = io_uring_submit(ring);
+ if (ret != 1)
+ return 1;
+
+ if (!i)
+ pthread_barrier_wait(&rd->barrier);
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "send wait cqe %d\n", ret);
+ return 1;
+ }
+
+ if (!i && cqe->res == -EINVAL) {
+ rd->abort = 1;
+ no_send_mshot = 1;
+ break;
+ }
+ if (cqe->res != MSG_SIZE) {
+ fprintf(stderr, "send failed cqe: %d\n", cqe->res);
+ return 1;
+ }
+ if (cqe->res < 0) {
+ fprintf(stderr, "bad send cqe res: %d\n", cqe->res);
+ return 1;
+ }
+ bytes_needed -= cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ if (!bytes_needed)
+ break;
+ }
+
+ return 0;
+}
+
+static int do_send(struct recv_data *rd)
+{
+ struct sockaddr_in saddr;
+ struct io_uring ring;
+ unsigned long seq_buf[SEQ_SIZE], send_seq;
+ struct io_uring_params p = { };
+ struct io_uring_buf_ring *br;
+ int sockfd, ret, len, i;
+ socklen_t optlen;
+ void *buf, *ptr;
+
+ ret = io_uring_queue_init_params(16, &ring, &p);
+ if (ret) {
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ return 1;
+ }
+ if (!(p.features & IORING_FEAT_RECVSEND_BUNDLE)) {
+ no_send_mshot = 1;
+ return 0;
+ }
+
+ if (posix_memalign(&buf, 4096, MSG_SIZE * nr_msgs))
+ return 1;
+
+ br = io_uring_setup_buf_ring(&ring, nr_msgs, SEND_BGID, 0, &ret);
+ if (!br) {
+ if (ret == -EINVAL) {
+ fprintf(stderr, "einval on br setup\n");
+ return 0;
+ }
+ fprintf(stderr, "failed setting up send ring %d\n", ret);
+ return 1;
+ }
+
+ ptr = buf;
+ for (i = 0; i < nr_msgs; i++) {
+ io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, nr_msgs - 1, i);
+ ptr += MSG_SIZE;
+ }
+ io_uring_buf_ring_advance(br, nr_msgs);
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = htons(use_port);
+ inet_pton(AF_INET, HOST, &saddr.sin_addr);
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0) {
+ perror("socket");
+ goto err2;
+ }
+
+ pthread_barrier_wait(&rd->connect);
+
+ ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
+ if (ret < 0) {
+ perror("connect");
+ goto err;
+ }
+
+ pthread_barrier_wait(&rd->startup);
+
+ optlen = sizeof(len);
+ len = 1024 * MSG_SIZE;
+ setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &len, optlen);
+
+ /* almost fill queue, leave room for one message */
+ send_seq = 0;
+ rd->to_eagain = 0;
+ while (rd->max_sends && rd->max_sends--) {
+ for (i = 0; i < SEQ_SIZE; i++)
+ seq_buf[i] = send_seq++;
+
+ ret = send(sockfd, seq_buf, sizeof(seq_buf), MSG_DONTWAIT);
+ if (ret < 0) {
+ if (errno == EAGAIN) {
+ send_seq -= SEQ_SIZE;
+ break;
+ }
+ perror("send");
+ return 1;
+ } else if (ret != sizeof(seq_buf)) {
+ fprintf(stderr, "short %d send\n", ret);
+ return 1;
+ }
+
+ rd->to_eagain++;
+ rd->recv_bytes += sizeof(seq_buf);
+ }
+
+ ptr = buf;
+ for (i = 0; i < nr_msgs; i++) {
+ unsigned long *pseq = ptr;
+ int j;
+
+ for (j = 0; j < SEQ_SIZE; j++)
+ pseq[j] = send_seq++;
+ ptr += MSG_SIZE;
+ }
+
+ /* prepare more messages, sending with bundle */
+ rd->recv_bytes += (nr_msgs * MSG_SIZE);
+ if (rd->send_bundle)
+ ret = __do_send_bundle(rd, &ring, sockfd);
+ else
+ ret = __do_send(rd, &ring, sockfd);
+ if (ret)
+ goto err;
+
+ pthread_barrier_wait(&rd->finish);
+
+ close(sockfd);
+ free(buf);
+ io_uring_queue_exit(&ring);
+ return 0;
+
+err:
+ close(sockfd);
+err2:
+ io_uring_queue_exit(&ring);
+ pthread_barrier_wait(&rd->finish);
+ return 1;
+}
+
+static int test(int backlog, unsigned int max_sends, int *to_eagain,
+ int send_bundle, int recv_bundle)
+{
+ pthread_t recv_thread;
+ struct recv_data rd;
+ int ret;
+ void *retval;
+
+ memset(&rd, 0, sizeof(rd));
+ pthread_barrier_init(&rd.connect, NULL, 2);
+ pthread_barrier_init(&rd.startup, NULL, 2);
+ pthread_barrier_init(&rd.barrier, NULL, 2);
+ pthread_barrier_init(&rd.finish, NULL, 2);
+ rd.max_sends = max_sends;
+ if (to_eagain)
+ *to_eagain = 0;
+
+ rd.send_bundle = send_bundle;
+ rd.recv_bundle = recv_bundle;
+
+ ret = pthread_create(&recv_thread, NULL, recv_fn, &rd);
+ if (ret) {
+ fprintf(stderr, "Thread create failed: %d\n", ret);
+ return 1;
+ }
+
+ ret = do_send(&rd);
+ if (no_send_mshot)
+ return 0;
+
+ if (ret)
+ return ret;
+
+ pthread_join(recv_thread, &retval);
+ if (to_eagain)
+ *to_eagain = rd.to_eagain;
+ return (intptr_t)retval;
+}
+
+static int run_tests(void)
+{
+ int ret, eagain_hit;
+
+ nr_msgs = NR_MIN_MSGS;
+
+ /* test basic send bundle first */
+ ret = test(0, 0, NULL, 0, 0);
+ if (ret) {
+ fprintf(stderr, "test a failed\n");
+ return T_EXIT_FAIL;
+ }
+ if (no_send_mshot)
+ return T_EXIT_SKIP;
+
+ /* test recv bundle */
+ ret = test(0, 0, NULL, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test b failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test bundling recv and send */
+ ret = test(0, 0, NULL, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test c failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test bundling with full socket */
+ ret = test(1, 1000000, &eagain_hit, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test d failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test bundling with almost full socket */
+ ret = test(1, eagain_hit - (nr_msgs / 2), NULL, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test e failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test recv bundle with almost full socket */
+ ret = test(1, eagain_hit - (nr_msgs / 2), NULL, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test f failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test send bundle with almost full socket */
+ ret = test(1, eagain_hit - (nr_msgs / 2), &eagain_hit, 1, 0);
+ if (ret) {
+ fprintf(stderr, "test g failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* now repeat the last three tests, but with > FAST_UIOV segments */
+ nr_msgs = NR_MAX_MSGS;
+
+ /* test bundling with almost full socket */
+ ret = test(1, eagain_hit - (nr_msgs / 2), NULL, 1, 1);
+ if (ret) {
+ fprintf(stderr, "test h failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test recv bundle with almost full socket */
+ ret = test(1, eagain_hit - (nr_msgs / 2), NULL, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test i failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test send bundle with almost full socket */
+ ret = test(1, eagain_hit - (nr_msgs / 2), &eagain_hit, 1, 0);
+ if (ret) {
+ fprintf(stderr, "test j failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ return T_EXIT_PASS;
+}
+
+static int test_tcp(void)
+{
+ int ret;
+
+ ret = run_tests();
+ if (ret == T_EXIT_FAIL)
+ fprintf(stderr, "TCP test case failed\n");
+ return ret;
+}
+
+static bool has_pbuf_ring_inc(void)
+{
+ struct io_uring_buf_ring *br;
+ bool has_pbuf_inc = false;
+ struct io_uring ring;
+ void *buf;
+ int ret;
+
+ ret = io_uring_queue_init(1, &ring, 0);
+ if (ret)
+ return false;
+
+ if (posix_memalign(&buf, 4096, MSG_SIZE * RECV_BIDS))
+ return false;
+
+ br = io_uring_setup_buf_ring(&ring, RECV_BIDS, RECV_BGID, IOU_PBUF_RING_INC, &ret);
+ if (br) {
+ has_pbuf_inc = true;
+ io_uring_unregister_buf_ring(&ring, RECV_BGID);
+ }
+ io_uring_queue_exit(&ring);
+ free(buf);
+ return has_pbuf_inc;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+ if (!has_pbuf_ring_inc())
+ return T_EXIT_SKIP;
+
+ ret = test_tcp();
+ if (ret != T_EXIT_PASS)
+ return ret;
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/recvsend_bundle-inc.t/ya.make b/contrib/libs/liburing/test/recvsend_bundle-inc.t/ya.make
new file mode 100644
index 0000000000..35c4f17c72
--- /dev/null
+++ b/contrib/libs/liburing/test/recvsend_bundle-inc.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ recvsend_bundle-inc.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/recvsend_bundle.c b/contrib/libs/liburing/test/recvsend_bundle.c
index 8d4305e847..b1ed5b947a 100644
--- a/contrib/libs/liburing/test/recvsend_bundle.c
+++ b/contrib/libs/liburing/test/recvsend_bundle.c
@@ -20,6 +20,7 @@
static int nr_msgs;
static int use_tcp;
+static int classic_buffers;
#define RECV_BIDS 8192
#define RECV_BID_MASK (RECV_BIDS - 1)
@@ -114,6 +115,9 @@ static int recv_prep(struct io_uring *ring, struct recv_data *rd, int *sock)
pthread_barrier_wait(&rd->connect);
+ if (rd->abort)
+ goto err;
+
socklen = sizeof(saddr);
use_fd = accept(sockfd, (struct sockaddr *)&saddr, &socklen);
if (use_fd < 0) {
@@ -211,7 +215,7 @@ static int do_recv(struct io_uring *ring, struct recv_data *rd)
fprintf(stderr, "got bid %d, wanted %d\n", bid, next_bid);
goto err;
}
- if (!rd->recv_bundle && cqe->res != MSG_SIZE) {
+ if (!rd->recv_bundle && cqe->res > MSG_SIZE) {
fprintf(stderr, "recv got wrong length: %d\n", cqe->res);
goto err;
}
@@ -246,13 +250,36 @@ err:
return 1;
}
+static int provide_classic_buffers(struct io_uring *ring, void *buf, int nbufs, int bgid)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_provide_buffers(sqe, buf, MSG_SIZE, nbufs, bgid, 0);
+ io_uring_submit(ring);
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "provide buffer wait: %d\n", ret);
+ return 1;
+ }
+ if (cqe->res) {
+ fprintf(stderr, "provide buffers fail: %d\n", cqe->res);
+ return 1;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ return 0;
+}
+
static void *recv_fn(void *data)
{
struct recv_data *rd = data;
struct io_uring_params p = { };
struct io_uring ring;
struct io_uring_buf_ring *br;
- void *buf, *ptr;
+ void *buf = NULL, *ptr;
int ret, sock, i;
p.cq_entries = 4096;
@@ -268,19 +295,28 @@ static void *recv_fn(void *data)
if (posix_memalign(&buf, 4096, MSG_SIZE * RECV_BIDS))
goto err;
- br = io_uring_setup_buf_ring(&ring, RECV_BIDS, RECV_BGID, 0, &ret);
- if (!br) {
- fprintf(stderr, "failed setting up recv ring %d\n", ret);
- goto err;
- }
+ if (!classic_buffers) {
+ br = io_uring_setup_buf_ring(&ring, RECV_BIDS, RECV_BGID, 0, &ret);
+ if (!br) {
+ if (ret != -EINVAL)
+ fprintf(stderr, "failed setting up recv ring %d\n", ret);
+ goto err;
+ }
- ptr = buf;
- for (i = 0; i < RECV_BIDS; i++) {
- io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, RECV_BID_MASK, i);
- ptr += MSG_SIZE;
+ ptr = buf;
+ for (i = 0; i < RECV_BIDS; i++) {
+ io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, RECV_BID_MASK, i);
+ ptr += MSG_SIZE;
+ }
+ io_uring_buf_ring_advance(br, RECV_BIDS);
+ rd->recv_buf = buf;
+ } else {
+ ret = provide_classic_buffers(&ring, buf, RECV_BIDS, RECV_BGID);
+ if (ret) {
+ fprintf(stderr, "failed providing classic buffers\n");
+ goto err;
+ }
}
- io_uring_buf_ring_advance(br, RECV_BIDS);
- rd->recv_buf = buf;
ret = recv_prep(&ring, rd, &sock);
if (ret) {
@@ -294,6 +330,7 @@ static void *recv_fn(void *data)
close(rd->accept_fd);
io_uring_queue_exit(&ring);
err:
+ free(buf);
return (void *)(intptr_t)ret;
}
@@ -403,7 +440,7 @@ static int do_send(struct recv_data *rd)
struct io_uring_buf_ring *br;
int sockfd, ret, len, i;
socklen_t optlen;
- void *buf, *ptr;
+ void *buf = NULL, *ptr;
ret = io_uring_queue_init_params(16, &ring, &p);
if (ret) {
@@ -411,29 +448,39 @@ static int do_send(struct recv_data *rd)
return 1;
}
if (!(p.features & IORING_FEAT_RECVSEND_BUNDLE)) {
+ rd->abort = 1;
no_send_mshot = 1;
+ pthread_barrier_wait(&rd->connect);
return 0;
}
if (posix_memalign(&buf, 4096, MSG_SIZE * nr_msgs))
return 1;
- br = io_uring_setup_buf_ring(&ring, nr_msgs, SEND_BGID, 0, &ret);
- if (!br) {
- if (ret == -EINVAL) {
- fprintf(stderr, "einval on br setup\n");
- return 0;
+ if (!classic_buffers) {
+ br = io_uring_setup_buf_ring(&ring, nr_msgs, SEND_BGID, 0, &ret);
+ if (!br) {
+ if (ret == -EINVAL) {
+ fprintf(stderr, "einval on br setup\n");
+ return 0;
+ }
+ fprintf(stderr, "failed setting up send ring %d\n", ret);
+ return 1;
}
- fprintf(stderr, "failed setting up send ring %d\n", ret);
- return 1;
- }
- ptr = buf;
- for (i = 0; i < nr_msgs; i++) {
- io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, nr_msgs - 1, i);
- ptr += MSG_SIZE;
+ ptr = buf;
+ for (i = 0; i < nr_msgs; i++) {
+ io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, nr_msgs - 1, i);
+ ptr += MSG_SIZE;
+ }
+ io_uring_buf_ring_advance(br, nr_msgs);
+ } else {
+ ret = provide_classic_buffers(&ring, buf, nr_msgs, SEND_BGID);
+ if (ret) {
+ fprintf(stderr, "failed providing classic buffers\n");
+ return ret;
+ }
}
- io_uring_buf_ring_advance(br, nr_msgs);
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
@@ -510,6 +557,7 @@ static int do_send(struct recv_data *rd)
close(sockfd);
io_uring_queue_exit(&ring);
+ free(buf);
return 0;
err:
@@ -517,6 +565,7 @@ err:
err2:
io_uring_queue_exit(&ring);
pthread_barrier_wait(&rd->finish);
+ free(buf);
return 1;
}
@@ -551,8 +600,12 @@ static int test(int backlog, unsigned int max_sends, int *to_eagain,
}
ret = do_send(&rd);
- if (no_send_mshot)
+ if (no_send_mshot) {
+ fprintf(stderr, "no_send_mshot, aborting (ignore other errors)\n");
+ rd.abort = 1;
+ pthread_join(recv_thread, &retval);
return 0;
+ }
if (ret)
return ret;
@@ -657,7 +710,7 @@ static int test_tcp(void)
use_tcp = 1;
ret = run_tests(false);
if (ret == T_EXIT_FAIL)
- fprintf(stderr, "TCP test case failed\n");
+ fprintf(stderr, "TCP test case (classic=%d) failed\n", classic_buffers);
return ret;
}
@@ -669,7 +722,7 @@ static int test_udp(void)
use_port++;
ret = run_tests(true);
if (ret == T_EXIT_FAIL)
- fprintf(stderr, "UDP test case failed\n");
+ fprintf(stderr, "UDP test case (classic=%d) failed\n", classic_buffers);
return ret;
}
@@ -688,5 +741,15 @@ int main(int argc, char *argv[])
if (ret != T_EXIT_PASS)
return ret;
+ classic_buffers = 1;
+
+ ret = test_tcp();
+ if (ret != T_EXIT_PASS)
+ return ret;
+
+ ret = test_udp();
+ if (ret != T_EXIT_PASS)
+ return ret;
+
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/recvsend_bundle.t/ya.make b/contrib/libs/liburing/test/recvsend_bundle.t/ya.make
index d4928a810d..81dadbb159 100644
--- a/contrib/libs/liburing/test/recvsend_bundle.t/ya.make
+++ b/contrib/libs/liburing/test/recvsend_bundle.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/reg-fd-only.c b/contrib/libs/liburing/test/reg-fd-only.c
index 1ff6ea250e..1c795e316c 100644
--- a/contrib/libs/liburing/test/reg-fd-only.c
+++ b/contrib/libs/liburing/test/reg-fd-only.c
@@ -50,14 +50,15 @@ static int test_nops(struct io_uring *ring, int sq_size, int nr_nops)
return T_EXIT_PASS;
}
-static int test(int nentries)
+static int test(int nentries, int ring_flags)
{
struct io_uring ring;
unsigned values[2];
int ret;
ret = io_uring_queue_init(nentries, &ring,
- IORING_SETUP_REGISTERED_FD_ONLY | IORING_SETUP_NO_MMAP);
+ IORING_SETUP_REGISTERED_FD_ONLY | IORING_SETUP_NO_MMAP |
+ ring_flags);
if (ret == -EINVAL) {
no_mmap = 1;
return T_EXIT_SKIP;
@@ -65,7 +66,7 @@ static int test(int nentries)
fprintf(stdout, "Enable huge pages to test big rings\n");
return T_EXIT_SKIP;
} else if (ret) {
- fprintf(stderr, "ring setup failed\n");
+ fprintf(stderr, "ring setup failed: %d\n", ret);
return T_EXIT_FAIL;
}
@@ -111,7 +112,16 @@ int main(int argc, char *argv[])
return T_EXIT_SKIP;
/* test single normal page */
- ret = test(NORMAL_PAGE_ENTRIES);
+ ret = test(NORMAL_PAGE_ENTRIES, 0);
+ if (ret == T_EXIT_SKIP || no_mmap) {
+ return T_EXIT_SKIP;
+ } else if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "test 8 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ /* test single normal page */
+ ret = test(NORMAL_PAGE_ENTRIES, IORING_SETUP_SQPOLL);
if (ret == T_EXIT_SKIP || no_mmap) {
return T_EXIT_SKIP;
} else if (ret != T_EXIT_PASS) {
@@ -120,7 +130,7 @@ int main(int argc, char *argv[])
}
/* test with entries requiring a huge page */
- ret = test(HUGE_PAGE_ENTRIES);
+ ret = test(HUGE_PAGE_ENTRIES, 0);
if (ret == T_EXIT_SKIP) {
return T_EXIT_SKIP;
} else if (ret != T_EXIT_PASS) {
diff --git a/contrib/libs/liburing/test/reg-fd-only.t/ya.make b/contrib/libs/liburing/test/reg-fd-only.t/ya.make
index 373599e6c3..3d84cb51e0 100644
--- a/contrib/libs/liburing/test/reg-fd-only.t/ya.make
+++ b/contrib/libs/liburing/test/reg-fd-only.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/reg-hint.t/ya.make b/contrib/libs/liburing/test/reg-hint.t/ya.make
index 1aaaff7170..1c4788b6fd 100644
--- a/contrib/libs/liburing/test/reg-hint.t/ya.make
+++ b/contrib/libs/liburing/test/reg-hint.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/reg-reg-ring.t/ya.make b/contrib/libs/liburing/test/reg-reg-ring.t/ya.make
index 09fb918298..3eb7a743a1 100644
--- a/contrib/libs/liburing/test/reg-reg-ring.t/ya.make
+++ b/contrib/libs/liburing/test/reg-reg-ring.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/regbuf-clone.c b/contrib/libs/liburing/test/regbuf-clone.c
new file mode 100644
index 0000000000..9e49989554
--- /dev/null
+++ b/contrib/libs/liburing/test/regbuf-clone.c
@@ -0,0 +1,248 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test buffer cloning between rings
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/uio.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define NR_VECS 64
+#define BUF_SIZE 8192
+
+static int no_buf_clone;
+
+static int test(int reg_src, int reg_dst)
+{
+ struct iovec vecs[NR_VECS];
+ struct io_uring src, dst;
+ int ret, i;
+
+ ret = io_uring_queue_init(1, &src, 0);
+ if (ret) {
+ fprintf(stderr, "ring_init: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ ret = io_uring_queue_init(1, &dst, 0);
+ if (ret) {
+ fprintf(stderr, "ring_init: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ if (reg_src) {
+ ret = io_uring_register_ring_fd(&src);
+ if (ret < 0) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "register ring: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ }
+ if (reg_dst) {
+ ret = io_uring_register_ring_fd(&dst);
+ if (ret < 0) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "register ring: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ }
+
+ /* test fail with no buffers in src */
+ ret = io_uring_clone_buffers(&dst, &src);
+ if (ret == -EINVAL) {
+ /* no buffer copy support */
+ no_buf_clone = true;
+ return T_EXIT_SKIP;
+ } else if (ret != -ENXIO) {
+ fprintf(stderr, "empty copy: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ for (i = 0; i < NR_VECS; i++) {
+ if (posix_memalign(&vecs[i].iov_base, 4096, BUF_SIZE))
+ return T_EXIT_FAIL;
+ vecs[i].iov_len = BUF_SIZE;
+ }
+
+ ret = io_uring_register_buffers(&src, vecs, NR_VECS);
+ if (ret < 0) {
+ if (ret == -ENOMEM)
+ return T_EXIT_SKIP;
+ return T_EXIT_FAIL;
+ }
+
+ /* copy should work now */
+ ret = io_uring_clone_buffers(&dst, &src);
+ if (ret) {
+ fprintf(stderr, "buffer copy: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ /* try copy again, should get -EBUSY */
+ ret = io_uring_clone_buffers(&dst, &src);
+ if (ret != -EBUSY) {
+ fprintf(stderr, "busy copy: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&dst);
+ if (ret) {
+ fprintf(stderr, "dst unregister buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&dst);
+ if (ret != -ENXIO) {
+ fprintf(stderr, "dst unregister empty buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&src);
+ if (ret) {
+ fprintf(stderr, "src unregister buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_register_buffers(&dst, vecs, NR_VECS);
+ if (ret < 0) {
+ fprintf(stderr, "register buffers dst; %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_clone_buffers(&src, &dst);
+ if (ret) {
+ fprintf(stderr, "buffer copy reverse: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&dst);
+ if (ret) {
+ fprintf(stderr, "dst unregister buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&dst);
+ if (ret != -ENXIO) {
+ fprintf(stderr, "dst unregister empty buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&src);
+ if (ret) {
+ fprintf(stderr, "src unregister buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_queue_exit(&src);
+ io_uring_queue_exit(&dst);
+
+ for (i = 0; i < NR_VECS; i++)
+ free(vecs[i].iov_base);
+
+ return T_EXIT_PASS;
+}
+
+static int test_dummy(void)
+{
+ struct iovec vec = { };
+ struct io_uring src, dst;
+ int ret;
+
+ ret = io_uring_queue_init(1, &src, 0);
+ if (ret) {
+ fprintf(stderr, "ring_init: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ ret = io_uring_queue_init(1, &dst, 0);
+ if (ret) {
+ fprintf(stderr, "ring_init: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_register_buffers(&src, &vec, 1);
+ if (ret < 0) {
+ fprintf(stderr, "failed to register dummy buffer: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_clone_buffers(&dst, &src);
+ if (ret) {
+ fprintf(stderr, "clone dummy buf: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&src);
+ if (ret) {
+ fprintf(stderr, "rsc unregister buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_unregister_buffers(&dst);
+ if (ret) {
+ fprintf(stderr, "dst unregister buffers: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_queue_exit(&src);
+ io_uring_queue_exit(&dst);
+
+ return T_EXIT_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test(0, 0);
+ if (ret == T_EXIT_SKIP) {
+ return T_EXIT_SKIP;
+ } else if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "test 0 0 failed\n");
+ return T_EXIT_FAIL;
+ }
+ if (no_buf_clone)
+ return T_EXIT_SKIP;
+
+ ret = test(0, 1);
+ if (ret == T_EXIT_SKIP) {
+ return T_EXIT_SKIP;
+ } else if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "test 0 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(1, 0);
+ if (ret == T_EXIT_SKIP) {
+ return T_EXIT_SKIP;
+ } else if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "test 1 0 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(1, 1);
+ if (ret == T_EXIT_SKIP) {
+ return T_EXIT_SKIP;
+ } else if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "test 1 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_dummy();
+ if (ret == T_EXIT_SKIP) {
+ return T_EXIT_SKIP;
+ } else if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "test_dummy failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/regbuf-clone.t/ya.make b/contrib/libs/liburing/test/regbuf-clone.t/ya.make
new file mode 100644
index 0000000000..016640dcce
--- /dev/null
+++ b/contrib/libs/liburing/test/regbuf-clone.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ regbuf-clone.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/regbuf-merge.c b/contrib/libs/liburing/test/regbuf-merge.c
index bb2e1286cb..942d383a68 100644
--- a/contrib/libs/liburing/test/regbuf-merge.c
+++ b/contrib/libs/liburing/test/regbuf-merge.c
@@ -14,6 +14,7 @@
#include "helpers.h"
+#ifndef CONFIG_USE_SANITIZER
#ifndef __NR_io_uring_register
#define __NR_io_uring_register 427
#endif
@@ -90,3 +91,9 @@ int main(int argc, char *argv[])
syscall(__NR_io_uring_register, r[0], 0ul, 0x20002840ul, 2ul);
return T_EXIT_PASS;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/regbuf-merge.t/ya.make b/contrib/libs/liburing/test/regbuf-merge.t/ya.make
index 1a108c6c3e..ee4f314adc 100644
--- a/contrib/libs/liburing/test/regbuf-merge.t/ya.make
+++ b/contrib/libs/liburing/test/regbuf-merge.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/register-restrictions.c b/contrib/libs/liburing/test/register-restrictions.c
index af35db4b4a..974daa2961 100644
--- a/contrib/libs/liburing/test/register-restrictions.c
+++ b/contrib/libs/liburing/test/register-restrictions.c
@@ -14,12 +14,7 @@
#include <sys/eventfd.h>
#include "liburing.h"
-
-enum {
- TEST_OK,
- TEST_SKIPPED,
- TEST_FAILED
-};
+#include "helpers.h"
static int test_restrictions_sqe_op(void)
{
@@ -37,15 +32,15 @@ static int test_restrictions_sqe_op(void)
if (pipe(pipe1) != 0) {
perror("pipe");
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
if (ret) {
if (ret == -EINVAL)
- return TEST_SKIPPED;
+ return T_EXIT_SKIP;
fprintf(stderr, "ring setup failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
res[0].opcode = IORING_RESTRICTION_SQE_OP;
@@ -57,16 +52,16 @@ static int test_restrictions_sqe_op(void)
ret = io_uring_register_restrictions(&ring, res, 2);
if (ret) {
if (ret == -EINVAL)
- return TEST_SKIPPED;
+ return T_EXIT_SKIP;
fprintf(stderr, "failed to register restrictions: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_enable_rings(&ring);
if (ret) {
fprintf(stderr, "ring enabling failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -80,28 +75,28 @@ static int test_restrictions_sqe_op(void)
ret = io_uring_submit(&ring);
if (ret != 2) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
for (int i = 0; i < 2; i++) {
ret = io_uring_wait_cqe(&ring, &cqe);
if (ret) {
fprintf(stderr, "wait: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
switch (cqe->user_data) {
case 1: /* writev */
if (cqe->res != sizeof(ptr)) {
fprintf(stderr, "write res: %d\n", cqe->res);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
break;
case 2: /* readv should be denied */
if (cqe->res != -EACCES) {
fprintf(stderr, "read res: %d\n", cqe->res);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
break;
}
@@ -109,7 +104,7 @@ static int test_restrictions_sqe_op(void)
}
io_uring_queue_exit(&ring);
- return TEST_OK;
+ return T_EXIT_PASS;
}
static int test_restrictions_register_op(void)
@@ -126,13 +121,13 @@ static int test_restrictions_register_op(void)
if (pipe(pipe1) != 0) {
perror("pipe");
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
if (ret) {
fprintf(stderr, "ring setup failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
res[0].opcode = IORING_RESTRICTION_REGISTER_OP;
@@ -141,32 +136,32 @@ static int test_restrictions_register_op(void)
ret = io_uring_register_restrictions(&ring, res, 1);
if (ret) {
if (ret == -EINVAL)
- return TEST_SKIPPED;
+ return T_EXIT_SKIP;
fprintf(stderr, "failed to register restrictions: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_enable_rings(&ring);
if (ret) {
fprintf(stderr, "ring enabling failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_register_buffers(&ring, &vec, 1);
if (ret) {
fprintf(stderr, "io_uring_register_buffers failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_register_files(&ring, pipe1, 2);
if (ret != -EACCES) {
fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
io_uring_queue_exit(&ring);
- return TEST_OK;
+ return T_EXIT_PASS;
}
static int test_restrictions_fixed_file(void)
@@ -185,13 +180,13 @@ static int test_restrictions_fixed_file(void)
if (pipe(pipe1) != 0) {
perror("pipe");
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
if (ret) {
fprintf(stderr, "ring setup failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
res[0].opcode = IORING_RESTRICTION_SQE_OP;
@@ -209,22 +204,22 @@ static int test_restrictions_fixed_file(void)
ret = io_uring_register_restrictions(&ring, res, 4);
if (ret) {
if (ret == -EINVAL)
- return TEST_SKIPPED;
+ return T_EXIT_SKIP;
fprintf(stderr, "failed to register restrictions: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_enable_rings(&ring);
if (ret) {
fprintf(stderr, "ring enabling failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_register_files(&ring, pipe1, 2);
if (ret) {
fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -244,34 +239,34 @@ static int test_restrictions_fixed_file(void)
ret = io_uring_submit(&ring);
if (ret != 3) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
for (int i = 0; i < 3; i++) {
ret = io_uring_wait_cqe(&ring, &cqe);
if (ret) {
fprintf(stderr, "wait: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
switch (cqe->user_data) {
case 1: /* writev */
if (cqe->res != sizeof(ptr)) {
fprintf(stderr, "write res: %d\n", cqe->res);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
break;
case 2: /* readv */
if (cqe->res != sizeof(ptr)) {
fprintf(stderr, "read res: %d\n", cqe->res);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
break;
case 3: /* writev without fixed_file should be denied */
if (cqe->res != -EACCES) {
fprintf(stderr, "write res: %d\n", cqe->res);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
break;
}
@@ -279,7 +274,7 @@ static int test_restrictions_fixed_file(void)
}
io_uring_queue_exit(&ring);
- return TEST_OK;
+ return T_EXIT_PASS;
}
static int test_restrictions_flags(void)
@@ -298,13 +293,13 @@ static int test_restrictions_flags(void)
if (pipe(pipe1) != 0) {
perror("pipe");
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
if (ret) {
fprintf(stderr, "ring setup failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
res[0].opcode = IORING_RESTRICTION_SQE_OP;
@@ -319,22 +314,22 @@ static int test_restrictions_flags(void)
ret = io_uring_register_restrictions(&ring, res, 3);
if (ret) {
if (ret == -EINVAL)
- return TEST_SKIPPED;
+ return T_EXIT_SKIP;
fprintf(stderr, "failed to register restrictions: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_register_files(&ring, pipe1, 2);
if (ret) {
fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_enable_rings(&ring);
if (ret) {
fprintf(stderr, "ring enabling failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -355,7 +350,7 @@ static int test_restrictions_flags(void)
ret = io_uring_submit(&ring);
if (ret != 3) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -366,7 +361,7 @@ static int test_restrictions_flags(void)
ret = io_uring_submit(&ring);
if (ret != 1) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -377,7 +372,7 @@ static int test_restrictions_flags(void)
ret = io_uring_submit(&ring);
if (ret != 1) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -388,7 +383,7 @@ static int test_restrictions_flags(void)
ret = io_uring_submit(&ring);
if (ret != 1) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -398,14 +393,14 @@ static int test_restrictions_flags(void)
ret = io_uring_submit(&ring);
if (ret != 1) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
for (int i = 0; i < 7; i++) {
ret = io_uring_wait_cqe(&ring, &cqe);
if (ret) {
fprintf(stderr, "wait: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
switch (cqe->user_data) {
@@ -415,7 +410,7 @@ static int test_restrictions_flags(void)
if (cqe->res != sizeof(ptr)) {
fprintf(stderr, "write res: %d user_data %" PRIu64 "\n",
cqe->res, (uint64_t) cqe->user_data);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
break;
@@ -426,7 +421,7 @@ static int test_restrictions_flags(void)
if (cqe->res != -EACCES) {
fprintf(stderr, "write res: %d user_data %" PRIu64 "\n",
cqe->res, (uint64_t) cqe->user_data);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
break;
}
@@ -434,7 +429,7 @@ static int test_restrictions_flags(void)
}
io_uring_queue_exit(&ring);
- return TEST_OK;
+ return T_EXIT_PASS;
}
static int test_restrictions_empty(void)
@@ -453,40 +448,40 @@ static int test_restrictions_empty(void)
if (pipe(pipe1) != 0) {
perror("pipe");
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
if (ret) {
fprintf(stderr, "ring setup failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_register_restrictions(&ring, res, 0);
if (ret) {
if (ret == -EINVAL)
- return TEST_SKIPPED;
+ return T_EXIT_SKIP;
fprintf(stderr, "failed to register restrictions: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_enable_rings(&ring);
if (ret) {
fprintf(stderr, "ring enabling failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_register_buffers(&ring, &vec, 1);
if (ret != -EACCES) {
fprintf(stderr, "io_uring_register_buffers ret: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_register_files(&ring, pipe1, 2);
if (ret != -EACCES) {
fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -495,24 +490,24 @@ static int test_restrictions_empty(void)
ret = io_uring_submit(&ring);
if (ret != 1) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
ret = io_uring_wait_cqe(&ring, &cqe);
if (ret) {
fprintf(stderr, "wait: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
if (cqe->res != -EACCES) {
fprintf(stderr, "write res: %d\n", cqe->res);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
io_uring_cqe_seen(&ring, cqe);
io_uring_queue_exit(&ring);
- return TEST_OK;
+ return T_EXIT_PASS;
}
static int test_restrictions_rings_not_disabled(void)
@@ -524,7 +519,7 @@ static int test_restrictions_rings_not_disabled(void)
ret = io_uring_queue_init(8, &ring, 0);
if (ret) {
fprintf(stderr, "ring setup failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
res[0].opcode = IORING_RESTRICTION_SQE_OP;
@@ -534,11 +529,11 @@ static int test_restrictions_rings_not_disabled(void)
if (ret != -EBADFD) {
fprintf(stderr, "io_uring_register_restrictions ret: %d\n",
ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
io_uring_queue_exit(&ring);
- return TEST_OK;
+ return T_EXIT_PASS;
}
static int test_restrictions_rings_disabled(void)
@@ -550,7 +545,7 @@ static int test_restrictions_rings_disabled(void)
ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
if (ret) {
fprintf(stderr, "ring setup failed: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
sqe = io_uring_get_sqe(&ring);
@@ -559,11 +554,11 @@ static int test_restrictions_rings_disabled(void)
ret = io_uring_submit(&ring);
if (ret != -EBADFD) {
fprintf(stderr, "submit: %d\n", ret);
- return TEST_FAILED;
+ return T_EXIT_FAIL;
}
io_uring_queue_exit(&ring);
- return TEST_OK;
+ return T_EXIT_PASS;
}
int main(int argc, char *argv[])
@@ -574,61 +569,67 @@ int main(int argc, char *argv[])
return 0;
ret = test_restrictions_sqe_op();
- if (ret == TEST_SKIPPED) {
+ if (ret == T_EXIT_SKIP) {
printf("test_restrictions_sqe_op: skipped\n");
- return 0;
- } else if (ret == TEST_FAILED) {
+ return T_EXIT_SKIP;
+ } else if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_restrictions_sqe_op failed\n");
return ret;
}
ret = test_restrictions_register_op();
- if (ret == TEST_SKIPPED) {
+ if (ret == T_EXIT_SKIP) {
printf("test_restrictions_register_op: skipped\n");
- } else if (ret == TEST_FAILED) {
+ return T_EXIT_SKIP;
+ } else if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_restrictions_register_op failed\n");
return ret;
}
ret = test_restrictions_fixed_file();
- if (ret == TEST_SKIPPED) {
+ if (ret == T_EXIT_SKIP) {
printf("test_restrictions_fixed_file: skipped\n");
- } else if (ret == TEST_FAILED) {
+ return T_EXIT_SKIP;
+ } else if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_restrictions_fixed_file failed\n");
return ret;
}
ret = test_restrictions_flags();
- if (ret == TEST_SKIPPED) {
+ if (ret == T_EXIT_SKIP) {
printf("test_restrictions_flags: skipped\n");
- } else if (ret == TEST_FAILED) {
+ return T_EXIT_SKIP;
+ } else if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_restrictions_flags failed\n");
return ret;
}
ret = test_restrictions_empty();
- if (ret == TEST_SKIPPED) {
+ if (ret == T_EXIT_SKIP) {
printf("test_restrictions_empty: skipped\n");
- } else if (ret == TEST_FAILED) {
+ return T_EXIT_SKIP;
+ } else if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_restrictions_empty failed\n");
return ret;
}
ret = test_restrictions_rings_not_disabled();
- if (ret == TEST_SKIPPED) {
+ if (ret == T_EXIT_SKIP) {
printf("test_restrictions_rings_not_disabled: skipped\n");
- } else if (ret == TEST_FAILED) {
+ return T_EXIT_SKIP;
+ } else if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_restrictions_rings_not_disabled failed\n");
return ret;
}
ret = test_restrictions_rings_disabled();
- if (ret == TEST_SKIPPED) {
+ if (ret == T_EXIT_SKIP) {
printf("test_restrictions_rings_disabled: skipped\n");
- } else if (ret == TEST_FAILED) {
+ return T_EXIT_SKIP;
+ } else if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_restrictions_rings_disabled failed\n");
return ret;
}
- return 0;
+ return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/register-restrictions.t/ya.make b/contrib/libs/liburing/test/register-restrictions.t/ya.make
index 6e5e8b92ee..cb64fc0194 100644
--- a/contrib/libs/liburing/test/register-restrictions.t/ya.make
+++ b/contrib/libs/liburing/test/register-restrictions.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/rename.c b/contrib/libs/liburing/test/rename.c
index d11ad17b33..230eb466f5 100644
--- a/contrib/libs/liburing/test/rename.c
+++ b/contrib/libs/liburing/test/rename.c
@@ -14,6 +14,51 @@
#include "liburing.h"
+/* test using a bad address for either old or new path */
+static int test_rename_badaddr(struct io_uring *ring, bool bad_old)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ const char *path = ".foo.bar";
+ const char *old, *new;
+ int ret;
+
+ if (bad_old) {
+ old = (void *) (uintptr_t) 0x1234;
+ new = path;
+ } else {
+ old = path;
+ new = (void *) (uintptr_t) 0x1234;
+ }
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ goto err;
+ }
+
+ memset(sqe, 0, sizeof(*sqe));
+
+ io_uring_prep_rename(sqe, old, new);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ ret = cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ return ret;
+err:
+ return 1;
+}
+
static int test_rename(struct io_uring *ring, const char *old, const char *new)
{
struct io_uring_cqe *cqe;
@@ -29,7 +74,7 @@ static int test_rename(struct io_uring *ring, const char *old, const char *new)
memset(sqe, 0, sizeof(*sqe));
io_uring_prep_rename(sqe, old, new);
-
+
ret = io_uring_submit(ring);
if (ret <= 0) {
fprintf(stderr, "sqe submit failed: %d\n", ret);
@@ -123,6 +168,19 @@ int main(int argc, char *argv[])
fprintf(stderr, "test_rename invalid failed: %d\n", ret);
return ret;
}
+
+ ret = test_rename_badaddr(&ring, 0);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "test_badaddr 0 failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = test_rename_badaddr(&ring, 1);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "test_badaddr 1 failed: %d\n", ret);
+ return ret;
+ }
+
out:
unlink(dst);
return 0;
diff --git a/contrib/libs/liburing/test/rename.t/ya.make b/contrib/libs/liburing/test/rename.t/ya.make
index 2c782d7d0a..eea4a265ae 100644
--- a/contrib/libs/liburing/test/rename.t/ya.make
+++ b/contrib/libs/liburing/test/rename.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/ring-leak.t/ya.make b/contrib/libs/liburing/test/ring-leak.t/ya.make
index bb0c0ded49..c0230f3efa 100644
--- a/contrib/libs/liburing/test/ring-leak.t/ya.make
+++ b/contrib/libs/liburing/test/ring-leak.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/ring-leak2.t/ya.make b/contrib/libs/liburing/test/ring-leak2.t/ya.make
index 720bef28bc..e35f5e3c10 100644
--- a/contrib/libs/liburing/test/ring-leak2.t/ya.make
+++ b/contrib/libs/liburing/test/ring-leak2.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/ringbuf-read.c b/contrib/libs/liburing/test/ringbuf-read.c
index 5ff6738b04..7cec7b5a57 100644
--- a/contrib/libs/liburing/test/ringbuf-read.c
+++ b/contrib/libs/liburing/test/ringbuf-read.c
@@ -60,6 +60,8 @@ static int test(const char *filename, int dio, int async)
fd = open(filename, O_RDONLY);
}
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open");
return 1;
}
@@ -124,6 +126,7 @@ static int test(const char *filename, int dio, int async)
if (verify_buffer(buf + ((bid - 1) * BUF_SIZE), ud))
return 1;
}
+ free(buf);
return 0;
}
@@ -145,6 +148,8 @@ int main(int argc, char *argv[])
fd = open(fname, O_WRONLY);
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open");
goto err;
}
diff --git a/contrib/libs/liburing/test/ringbuf-read.t/ya.make b/contrib/libs/liburing/test/ringbuf-read.t/ya.make
index 894e741045..a04fed0d1a 100644
--- a/contrib/libs/liburing/test/ringbuf-read.t/ya.make
+++ b/contrib/libs/liburing/test/ringbuf-read.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/ringbuf-status.c b/contrib/libs/liburing/test/ringbuf-status.c
index d4a56c7473..88b6e8a47a 100644
--- a/contrib/libs/liburing/test/ringbuf-status.c
+++ b/contrib/libs/liburing/test/ringbuf-status.c
@@ -110,6 +110,7 @@ static int test(int invalid)
if (!br) {
if (ret == -EINVAL) {
no_buf_ring = 1;
+ free(buf);
return 0;
}
fprintf(stderr, "Buffer ring register failed %d\n", ret);
@@ -132,10 +133,13 @@ static int test(int invalid)
if (ret) {
if (ret == -EINVAL) {
no_buf_ring_status = 1;
+ free(buf);
return T_EXIT_SKIP;
}
- if (invalid && ret == -ENOENT)
+ if (invalid && ret == -ENOENT) {
+ free(buf);
return T_EXIT_PASS;
+ }
fprintf(stderr, "buf_ring_head: %d\n", ret);
return T_EXIT_FAIL;
}
diff --git a/contrib/libs/liburing/test/ringbuf-status.t/ya.make b/contrib/libs/liburing/test/ringbuf-status.t/ya.make
index 5c45952a94..854af2e2ae 100644
--- a/contrib/libs/liburing/test/ringbuf-status.t/ya.make
+++ b/contrib/libs/liburing/test/ringbuf-status.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/rsrc_tags.t/ya.make b/contrib/libs/liburing/test/rsrc_tags.t/ya.make
index 7ad3a073e8..58c661f865 100644
--- a/contrib/libs/liburing/test/rsrc_tags.t/ya.make
+++ b/contrib/libs/liburing/test/rsrc_tags.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/rw_merge_test.t/ya.make b/contrib/libs/liburing/test/rw_merge_test.t/ya.make
index 408f4de290..25088065c8 100644
--- a/contrib/libs/liburing/test/rw_merge_test.t/ya.make
+++ b/contrib/libs/liburing/test/rw_merge_test.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/self.t/ya.make b/contrib/libs/liburing/test/self.t/ya.make
index d5a5f0ddc6..fb2ee7c203 100644
--- a/contrib/libs/liburing/test/self.t/ya.make
+++ b/contrib/libs/liburing/test/self.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/send-zerocopy.c b/contrib/libs/liburing/test/send-zerocopy.c
index 75149d55d3..4cc7e813e6 100644
--- a/contrib/libs/liburing/test/send-zerocopy.c
+++ b/contrib/libs/liburing/test/send-zerocopy.c
@@ -647,7 +647,8 @@ static int test_inet_send(struct io_uring *ring)
if (!buffers_iov[buf_index].iov_base)
continue;
- if (!tcp && len > 4 * page_sz)
+ /* UDP IPv4 max datagram size is under 64K */
+ if (!tcp && len > (1U << 15))
continue;
conf.buf_index = buf_index;
@@ -739,6 +740,59 @@ static int test_async_addr(struct io_uring *ring)
return 0;
}
+static int test_sendzc_report(struct io_uring *ring)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct sockaddr_storage addr;
+ int sock_tx, sock_rx;
+ int ret;
+
+ ret = create_socketpair_ip(&addr, &sock_tx, &sock_rx, true, true, false, true);
+ if (ret) {
+ fprintf(stderr, "sock prep failed %d\n", ret);
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_send_zc(sqe, sock_tx, tx_buffer, 1, 0,
+ IORING_SEND_ZC_REPORT_USAGE);
+ ret = io_uring_submit(ring);
+ if (ret != 1) {
+ fprintf(stderr, "io_uring_submit failed %i\n", ret);
+ return 1;
+ }
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "io_uring_wait_cqe failed %i\n", ret);
+ return 1;
+ }
+ if (cqe->res != 1 && cqe->res != -EINVAL) {
+ fprintf(stderr, "sendzc report failed %u\n", cqe->res);
+ return 1;
+ }
+ if (!(cqe->flags & IORING_CQE_F_MORE)) {
+ fprintf(stderr, "expected notification %i\n", cqe->res);
+ return 1;
+ }
+ io_uring_cqe_seen(ring, cqe);
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "io_uring_wait_cqe failed %i\n", ret);
+ return 1;
+ }
+ if (cqe->flags & IORING_CQE_F_MORE) {
+ fprintf(stderr, "F_MORE after notification\n");
+ return 1;
+ }
+ io_uring_cqe_seen(ring, cqe);
+
+ close(sock_tx);
+ close(sock_rx);
+ return 0;
+}
+
/* see also send_recv.c:test_invalid */
static int test_invalid_zc(int fds[2])
{
@@ -833,6 +887,12 @@ static int run_basic_tests(void)
return T_EXIT_FAIL;
}
+ ret = test_sendzc_report(&ring);
+ if (ret) {
+ fprintf(stderr, "test_sendzc_report() failed\n");
+ return T_EXIT_FAIL;
+ }
+
io_uring_queue_exit(&ring);
}
diff --git a/contrib/libs/liburing/test/send-zerocopy.t/ya.make b/contrib/libs/liburing/test/send-zerocopy.t/ya.make
index 8488fd09ad..d6af232525 100644
--- a/contrib/libs/liburing/test/send-zerocopy.t/ya.make
+++ b/contrib/libs/liburing/test/send-zerocopy.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/send_recv.t/ya.make b/contrib/libs/liburing/test/send_recv.t/ya.make
index 9ebfd4beb7..45a35c05a2 100644
--- a/contrib/libs/liburing/test/send_recv.t/ya.make
+++ b/contrib/libs/liburing/test/send_recv.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/send_recvmsg.t/ya.make b/contrib/libs/liburing/test/send_recvmsg.t/ya.make
index 819cfe1e8f..91263afd59 100644
--- a/contrib/libs/liburing/test/send_recvmsg.t/ya.make
+++ b/contrib/libs/liburing/test/send_recvmsg.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/shared-wq.t/ya.make b/contrib/libs/liburing/test/shared-wq.t/ya.make
index 7d6ec12f79..f1d0979e8e 100644
--- a/contrib/libs/liburing/test/shared-wq.t/ya.make
+++ b/contrib/libs/liburing/test/shared-wq.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/short-read.c b/contrib/libs/liburing/test/short-read.c
index cd8c1644f8..e9b4b20827 100644
--- a/contrib/libs/liburing/test/short-read.c
+++ b/contrib/libs/liburing/test/short-read.c
@@ -72,5 +72,6 @@ int main(int argc, char *argv[])
}
io_uring_cqe_seen(&ring, cqe);
+ free(vec.iov_base);
return 0;
}
diff --git a/contrib/libs/liburing/test/short-read.t/ya.make b/contrib/libs/liburing/test/short-read.t/ya.make
index 20b7807f6a..254e93b6d3 100644
--- a/contrib/libs/liburing/test/short-read.t/ya.make
+++ b/contrib/libs/liburing/test/short-read.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/shutdown.t/ya.make b/contrib/libs/liburing/test/shutdown.t/ya.make
index 4f388e64a6..8ddc04ac60 100644
--- a/contrib/libs/liburing/test/shutdown.t/ya.make
+++ b/contrib/libs/liburing/test/shutdown.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sigfd-deadlock.t/ya.make b/contrib/libs/liburing/test/sigfd-deadlock.t/ya.make
index 923d05efa3..13f2a770f7 100644
--- a/contrib/libs/liburing/test/sigfd-deadlock.t/ya.make
+++ b/contrib/libs/liburing/test/sigfd-deadlock.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/single-issuer.t/ya.make b/contrib/libs/liburing/test/single-issuer.t/ya.make
index 22b9933c40..1e84c75510 100644
--- a/contrib/libs/liburing/test/single-issuer.t/ya.make
+++ b/contrib/libs/liburing/test/single-issuer.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/skip-cqe.t/ya.make b/contrib/libs/liburing/test/skip-cqe.t/ya.make
index b2d5c9ae5a..a4445c9e20 100644
--- a/contrib/libs/liburing/test/skip-cqe.t/ya.make
+++ b/contrib/libs/liburing/test/skip-cqe.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/socket-getsetsock-cmd.t/ya.make b/contrib/libs/liburing/test/socket-getsetsock-cmd.t/ya.make
index 17a58600d7..dc3b688a0b 100644
--- a/contrib/libs/liburing/test/socket-getsetsock-cmd.t/ya.make
+++ b/contrib/libs/liburing/test/socket-getsetsock-cmd.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/socket-io-cmd.t/ya.make b/contrib/libs/liburing/test/socket-io-cmd.t/ya.make
index 1bef521386..83a0249549 100644
--- a/contrib/libs/liburing/test/socket-io-cmd.t/ya.make
+++ b/contrib/libs/liburing/test/socket-io-cmd.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/socket-rw-eagain.t/ya.make b/contrib/libs/liburing/test/socket-rw-eagain.t/ya.make
index b8be4cd81a..420451f607 100644
--- a/contrib/libs/liburing/test/socket-rw-eagain.t/ya.make
+++ b/contrib/libs/liburing/test/socket-rw-eagain.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/socket-rw-offset.t/ya.make b/contrib/libs/liburing/test/socket-rw-offset.t/ya.make
index 58f6331b37..814cb935b0 100644
--- a/contrib/libs/liburing/test/socket-rw-offset.t/ya.make
+++ b/contrib/libs/liburing/test/socket-rw-offset.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/socket-rw.t/ya.make b/contrib/libs/liburing/test/socket-rw.t/ya.make
index df06bc4449..336701e98b 100644
--- a/contrib/libs/liburing/test/socket-rw.t/ya.make
+++ b/contrib/libs/liburing/test/socket-rw.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/socket.c b/contrib/libs/liburing/test/socket.c
index b4514e3154..d33fad4997 100644
--- a/contrib/libs/liburing/test/socket.c
+++ b/contrib/libs/liburing/test/socket.c
@@ -366,6 +366,43 @@ static int test(int use_sqthread, int regfiles, int socket_direct, int alloc)
return (intptr_t)retval;
}
+static int test_bad_socket(void)
+{
+ struct io_uring ring;
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int ret;
+
+ ret = io_uring_queue_init(1, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_socket(sqe, -1, SOCK_DGRAM, 0, 0);
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "socket submit: %d\n", ret);
+ goto err;
+ }
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe: %d\n", ret);
+ goto err;
+ }
+ if (cqe->res != -EAFNOSUPPORT) {
+ fprintf(stderr, "socket res: %d\n", cqe->res);
+ goto err;
+ }
+ io_uring_cqe_seen(&ring, cqe);
+ io_uring_queue_exit(&ring);
+ return 0;
+err:
+ io_uring_queue_exit(&ring);
+ return 1;
+}
+
int main(int argc, char *argv[])
{
int ret;
@@ -405,5 +442,11 @@ int main(int argc, char *argv[])
return ret;
}
+ ret = test_bad_socket();
+ if (ret) {
+ fprintf(stderr, "test bad socket failed\n");
+ return 1;
+ }
+
return 0;
}
diff --git a/contrib/libs/liburing/test/socket.t/ya.make b/contrib/libs/liburing/test/socket.t/ya.make
index 598bf99516..54d72000a2 100644
--- a/contrib/libs/liburing/test/socket.t/ya.make
+++ b/contrib/libs/liburing/test/socket.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/splice.c b/contrib/libs/liburing/test/splice.c
index d4042a8fdb..b614cbf25a 100644
--- a/contrib/libs/liburing/test/splice.c
+++ b/contrib/libs/liburing/test/splice.c
@@ -192,7 +192,7 @@ static int do_splice(struct io_uring *ring,
IORING_OP_SPLICE);
}
-static int do_tee(struct io_uring *ring, int fd_in, int fd_out,
+static int do_tee(struct io_uring *ring, int fd_in, int fd_out,
unsigned int len)
{
return do_splice_op(ring, fd_in, 0, fd_out, 0, len, IORING_OP_TEE);
@@ -505,6 +505,8 @@ int main(int argc, char *argv[])
splice_flags = SPLICE_F_FD_IN_FIXED;
sqe_flags = IOSQE_FIXED_FILE;
ret = test_splice(&ring, &ctx);
+ free(ctx.buf_in);
+ free(ctx.buf_out);
if (ret) {
fprintf(stderr, "registered fds splice tests failed\n");
return ret;
diff --git a/contrib/libs/liburing/test/splice.t/ya.make b/contrib/libs/liburing/test/splice.t/ya.make
index 2dc1ee706a..dad18f999b 100644
--- a/contrib/libs/liburing/test/splice.t/ya.make
+++ b/contrib/libs/liburing/test/splice.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sq-full-cpp.t/ya.make b/contrib/libs/liburing/test/sq-full-cpp.t/ya.make
index 5a4d26b61a..aa406abdee 100644
--- a/contrib/libs/liburing/test/sq-full-cpp.t/ya.make
+++ b/contrib/libs/liburing/test/sq-full-cpp.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sq-full.t/ya.make b/contrib/libs/liburing/test/sq-full.t/ya.make
index baa4eb0cf5..ecf9fa084b 100644
--- a/contrib/libs/liburing/test/sq-full.t/ya.make
+++ b/contrib/libs/liburing/test/sq-full.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sq-poll-dup.c b/contrib/libs/liburing/test/sq-poll-dup.c
index a821f21962..9a45f6a6bd 100644
--- a/contrib/libs/liburing/test/sq-poll-dup.c
+++ b/contrib/libs/liburing/test/sq-poll-dup.c
@@ -178,7 +178,7 @@ int main(int argc, char *argv[])
if (fname != argv[1])
unlink(fname);
- if (__e == EINVAL)
+ if (__e == EINVAL || __e == EPERM || __e == EACCES)
return T_EXIT_SKIP;
perror("open");
return -1;
diff --git a/contrib/libs/liburing/test/sq-poll-dup.t/ya.make b/contrib/libs/liburing/test/sq-poll-dup.t/ya.make
index 9e86468e20..1fcca15117 100644
--- a/contrib/libs/liburing/test/sq-poll-dup.t/ya.make
+++ b/contrib/libs/liburing/test/sq-poll-dup.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sq-poll-kthread.t/ya.make b/contrib/libs/liburing/test/sq-poll-kthread.t/ya.make
index 61be5885c7..858b6ea987 100644
--- a/contrib/libs/liburing/test/sq-poll-kthread.t/ya.make
+++ b/contrib/libs/liburing/test/sq-poll-kthread.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sq-poll-share.c b/contrib/libs/liburing/test/sq-poll-share.c
index c8a72107f9..59a85835ad 100644
--- a/contrib/libs/liburing/test/sq-poll-share.c
+++ b/contrib/libs/liburing/test/sq-poll-share.c
@@ -91,6 +91,8 @@ int main(int argc, char *argv[])
fd = open(fname, O_RDONLY | O_DIRECT);
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES || errno == EINVAL)
+ return T_EXIT_SKIP;
perror("open");
return -1;
}
diff --git a/contrib/libs/liburing/test/sq-poll-share.t/ya.make b/contrib/libs/liburing/test/sq-poll-share.t/ya.make
index 7b739bc0f6..8b7321b3f4 100644
--- a/contrib/libs/liburing/test/sq-poll-share.t/ya.make
+++ b/contrib/libs/liburing/test/sq-poll-share.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sq-space_left.t/ya.make b/contrib/libs/liburing/test/sq-space_left.t/ya.make
index f23eec434a..12f82d935b 100644
--- a/contrib/libs/liburing/test/sq-space_left.t/ya.make
+++ b/contrib/libs/liburing/test/sq-space_left.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sqpoll-disable-exit.c b/contrib/libs/liburing/test/sqpoll-disable-exit.c
index 6e5bfc6f47..b0b0938cfb 100644
--- a/contrib/libs/liburing/test/sqpoll-disable-exit.c
+++ b/contrib/libs/liburing/test/sqpoll-disable-exit.c
@@ -23,8 +23,10 @@
#include <unistd.h>
#include "liburing.h"
+#include "helpers.h"
#include "../src/syscall.h"
+#ifndef CONFIG_USE_SANITIZER
static void sleep_ms(uint64_t ms)
{
usleep(ms * 1000);
@@ -195,3 +197,9 @@ int main(void)
loop();
return 0;
}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/sqpoll-disable-exit.t/ya.make b/contrib/libs/liburing/test/sqpoll-disable-exit.t/ya.make
index 69163bf995..8e7341edbf 100644
--- a/contrib/libs/liburing/test/sqpoll-disable-exit.t/ya.make
+++ b/contrib/libs/liburing/test/sqpoll-disable-exit.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sqpoll-exec.t/ya.make b/contrib/libs/liburing/test/sqpoll-exec.t/ya.make
index 7c98e7a947..1ac9e2986e 100644
--- a/contrib/libs/liburing/test/sqpoll-exec.t/ya.make
+++ b/contrib/libs/liburing/test/sqpoll-exec.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sqpoll-exit-hang.c b/contrib/libs/liburing/test/sqpoll-exit-hang.c
index 7f5e539903..e009cbf1dc 100644
--- a/contrib/libs/liburing/test/sqpoll-exit-hang.c
+++ b/contrib/libs/liburing/test/sqpoll-exit-hang.c
@@ -11,31 +11,7 @@
#include <sys/time.h>
#include <poll.h>
#include "liburing.h"
-
-static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
-}
-
-static unsigned long long mtime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
-}
+#include "helpers.h"
int main(int argc, char *argv[])
{
diff --git a/contrib/libs/liburing/test/sqpoll-exit-hang.t/ya.make b/contrib/libs/liburing/test/sqpoll-exit-hang.t/ya.make
index c3fdac8493..cb4611bda5 100644
--- a/contrib/libs/liburing/test/sqpoll-exit-hang.t/ya.make
+++ b/contrib/libs/liburing/test/sqpoll-exit-hang.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sqpoll-sleep.c b/contrib/libs/liburing/test/sqpoll-sleep.c
index f98d733ea4..439a6fa148 100644
--- a/contrib/libs/liburing/test/sqpoll-sleep.c
+++ b/contrib/libs/liburing/test/sqpoll-sleep.c
@@ -10,31 +10,7 @@
#include <unistd.h>
#include <sys/time.h>
#include "liburing.h"
-
-static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
-}
-
-static unsigned long long mtime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
-}
+#include "helpers.h"
int main(int argc, char *argv[])
{
diff --git a/contrib/libs/liburing/test/sqpoll-sleep.t/ya.make b/contrib/libs/liburing/test/sqpoll-sleep.t/ya.make
index ccf2774f1d..6ae9ae9827 100644
--- a/contrib/libs/liburing/test/sqpoll-sleep.t/ya.make
+++ b/contrib/libs/liburing/test/sqpoll-sleep.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sqwait.c b/contrib/libs/liburing/test/sqwait.c
new file mode 100644
index 0000000000..135b50be3a
--- /dev/null
+++ b/contrib/libs/liburing/test/sqwait.c
@@ -0,0 +1,137 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test that the app can always get a new sqe after having
+ * called io_uring_sqring_wait().
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define NR_IOS 10000
+#define INFLIGHT 256
+#define FILE_SIZE (256 * 1024 * 1024)
+
+static int inflight;
+
+static int reap(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe;
+ int ret;
+
+ while (inflight >= INFLIGHT / 2) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait=%d\n", ret);
+ return 1;
+ }
+ if (cqe->res < 0) {
+ printf("cqe res %d\n", cqe->res);
+ return 1;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ inflight--;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ int fd = -1, i, iov_off, ret, fret;
+ struct iovec iovs[INFLIGHT];
+ const char *fname;
+ char buf[256];
+ loff_t off;
+
+ if (argc > 1) {
+ fname = argv[1];
+ } else {
+ srand((unsigned)time(NULL));
+ snprintf(buf, sizeof(buf), ".sqwait-%u-%u", (unsigned)rand(),
+ (unsigned)getpid());
+ fname = buf;
+ t_create_file(fname, FILE_SIZE);
+ }
+
+ fret = T_EXIT_SKIP;
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SQPOLL);
+ if (ret < 0) {
+ if (errno == EINVAL || errno == EPERM)
+ goto err;
+ fprintf(stderr, "queue init %d\n", ret);
+ fret = T_EXIT_FAIL;
+ goto err;
+ }
+
+ fd = open(fname, O_RDONLY | O_DIRECT);
+ if (fd < 0) {
+ if (errno == EACCES || errno == EPERM || errno == EINVAL)
+ return T_EXIT_SKIP;
+ perror("open");
+ fret = T_EXIT_FAIL;
+ goto err;
+ }
+
+ for (i = 0; i < INFLIGHT; i++) {
+ if (posix_memalign(&iovs[i].iov_base, 4096, 4096))
+ goto err;
+ iovs[i].iov_len = 4096;
+ }
+
+ iov_off = off = 0;
+ for (i = 0; i < NR_IOS; i++) {
+ struct iovec *iov = &iovs[iov_off];
+
+ sqe = io_uring_get_sqe(&ring);
+ if (!sqe) {
+ ret = io_uring_sqring_wait(&ring);
+ if (ret < 0) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "sqwait=%d\n", ret);
+ fret = T_EXIT_FAIL;
+ goto err;
+ }
+ sqe = io_uring_get_sqe(&ring);
+ if (!sqe) {
+ fprintf(stderr, "No sqe post wait\n");
+ fret = T_EXIT_FAIL;
+ goto err;
+ }
+ }
+ io_uring_prep_read(sqe, fd, iov->iov_base, iov->iov_len, 0);
+ io_uring_submit(&ring);
+ inflight++;
+
+ iov_off++;
+ if (iov_off == INFLIGHT)
+ iov_off = 0;
+ off += 8192;
+ if (off > FILE_SIZE - 8192)
+ off = 0;
+ if (reap(&ring)) {
+ fret = T_EXIT_FAIL;
+ goto err;
+ }
+ }
+
+ if (fd != -1)
+ close(fd);
+ if (fname != argv[1])
+ unlink(fname);
+ io_uring_queue_exit(&ring);
+ return T_EXIT_PASS;
+err:
+ if (fd != -1)
+ close(fd);
+ if (fname != argv[1])
+ unlink(fname);
+ return fret;
+}
diff --git a/contrib/libs/liburing/test/sqwait.t/ya.make b/contrib/libs/liburing/test/sqwait.t/ya.make
new file mode 100644
index 0000000000..303a16afd2
--- /dev/null
+++ b/contrib/libs/liburing/test/sqwait.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ sqwait.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/stdout.c b/contrib/libs/liburing/test/stdout.c
index 02b0456955..5044ccab15 100644
--- a/contrib/libs/liburing/test/stdout.c
+++ b/contrib/libs/liburing/test/stdout.c
@@ -90,6 +90,7 @@ static int test_pipe_io_fixed(struct io_uring *ring)
io_uring_cqe_seen(ring, cqe);
}
io_uring_unregister_buffers(ring);
+ free(vecs[0].iov_base);
return 0;
err:
return 1;
@@ -144,6 +145,7 @@ static int test_stdout_io_fixed(struct io_uring *ring)
}
io_uring_cqe_seen(ring, cqe);
io_uring_unregister_buffers(ring);
+ free(vecs.iov_base);
return 0;
err:
return 1;
diff --git a/contrib/libs/liburing/test/stdout.t/ya.make b/contrib/libs/liburing/test/stdout.t/ya.make
index 53a1c134cc..275a46da01 100644
--- a/contrib/libs/liburing/test/stdout.t/ya.make
+++ b/contrib/libs/liburing/test/stdout.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/submit-and-wait.c b/contrib/libs/liburing/test/submit-and-wait.c
index ab841ca6b1..166f63fb3d 100644
--- a/contrib/libs/liburing/test/submit-and-wait.c
+++ b/contrib/libs/liburing/test/submit-and-wait.c
@@ -14,33 +14,9 @@
#include <sys/time.h>
#include "liburing.h"
+#include "helpers.h"
#include "test.h"
-static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
-}
-
-static unsigned long long mtime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
-}
-
static int test(struct io_uring *ring)
{
struct io_uring_cqe *cqe;
diff --git a/contrib/libs/liburing/test/submit-and-wait.t/ya.make b/contrib/libs/liburing/test/submit-and-wait.t/ya.make
index 63234cd835..478d642e10 100644
--- a/contrib/libs/liburing/test/submit-and-wait.t/ya.make
+++ b/contrib/libs/liburing/test/submit-and-wait.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/submit-link-fail.t/ya.make b/contrib/libs/liburing/test/submit-link-fail.t/ya.make
index 342296fe78..b5c1118f59 100644
--- a/contrib/libs/liburing/test/submit-link-fail.t/ya.make
+++ b/contrib/libs/liburing/test/submit-link-fail.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/submit-reuse.c b/contrib/libs/liburing/test/submit-reuse.c
index 92f6b2f5d0..a57ab19997 100644
--- a/contrib/libs/liburing/test/submit-reuse.c
+++ b/contrib/libs/liburing/test/submit-reuse.c
@@ -103,31 +103,6 @@ static int wait_nr(int nr)
return 0;
}
-static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
-}
-
-static unsigned long long mtime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
-}
-
static int test_reuse(int argc, char *argv[], int split, int async)
{
struct thread_data data;
@@ -163,6 +138,8 @@ static int test_reuse(int argc, char *argv[], int split, int async)
if (do_unlink)
unlink(fname1);
if (fd1 < 0) {
+ if (errno == EPERM || errno == EACCES)
+ return T_EXIT_SKIP;
perror("open fname1");
goto err;
}
@@ -212,7 +189,6 @@ static int test_reuse(int argc, char *argv[], int split, int async)
err:
io_uring_queue_exit(&ring);
return 1;
-
}
int main(int argc, char *argv[])
@@ -226,6 +202,8 @@ int main(int argc, char *argv[])
async = (i & 2) != 0;
ret = test_reuse(argc, argv, split, async);
+ if (ret == T_EXIT_SKIP)
+ continue;
if (ret) {
fprintf(stderr, "test_reuse %d %d failed\n", split, async);
return ret;
diff --git a/contrib/libs/liburing/test/submit-reuse.t/ya.make b/contrib/libs/liburing/test/submit-reuse.t/ya.make
index 05b78c046d..43c5fe34fa 100644
--- a/contrib/libs/liburing/test/submit-reuse.t/ya.make
+++ b/contrib/libs/liburing/test/submit-reuse.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/symlink.c b/contrib/libs/liburing/test/symlink.c
index 1fc6b8e1db..3594f4c8b3 100644
--- a/contrib/libs/liburing/test/symlink.c
+++ b/contrib/libs/liburing/test/symlink.c
@@ -12,7 +12,6 @@
#include "liburing.h"
-
static int do_symlinkat(struct io_uring *ring, const char *oldname, const char *newname)
{
int ret;
@@ -106,6 +105,18 @@ int main(int argc, char *argv[])
goto err1;
}
+ ret = do_symlinkat(&ring, target, (const char *) (uintptr_t) 0x1234);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "test_symlinkat bad target failed: %d\n", ret);
+ goto err1;
+ }
+
+ ret = do_symlinkat(&ring, (const char *) (uintptr_t) 0x1234, target);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "test_symlinkat bad source failed: %d\n", ret);
+ goto err1;
+ }
+
out:
unlinkat(AT_FDCWD, linkname, 0);
io_uring_queue_exit(&ring);
diff --git a/contrib/libs/liburing/test/symlink.t/ya.make b/contrib/libs/liburing/test/symlink.t/ya.make
index 781a2bacff..e689152500 100644
--- a/contrib/libs/liburing/test/symlink.t/ya.make
+++ b/contrib/libs/liburing/test/symlink.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/sync-cancel.c b/contrib/libs/liburing/test/sync-cancel.c
index 096d210ffb..b3a38f4d56 100644
--- a/contrib/libs/liburing/test/sync-cancel.c
+++ b/contrib/libs/liburing/test/sync-cancel.c
@@ -14,9 +14,9 @@
#include "liburing.h"
#include "helpers.h"
-static int no_sync_cancel;
+static int no_sync_cancel, no_sync_cancel_op;
-static int test_sync_cancel_timeout(struct io_uring *ring, int async)
+static int test_sync_cancel_timeout(struct io_uring *ring, int async, int by_op)
{
struct io_uring_sync_cancel_reg reg = { };
struct io_uring_sqe *sqe;
@@ -44,9 +44,15 @@ static int test_sync_cancel_timeout(struct io_uring *ring, int async)
usleep(10000);
- reg.addr = 0x89;
+ reg.flags = IORING_ASYNC_CANCEL_OP;
+ reg.opcode = IORING_OP_READ;
reg.timeout.tv_nsec = 1;
ret = io_uring_register_sync_cancel(ring, &reg);
+ /* earlier kernels had sync cancel, but not per-op */
+ if (ret == -EINVAL) {
+ no_sync_cancel_op = 1;
+ return 0;
+ }
if (async) {
/* we expect -ETIME here, but can race and get 0 */
if (ret != -ETIME && ret != 0) {
@@ -81,7 +87,7 @@ static int test_sync_cancel_timeout(struct io_uring *ring, int async)
}
static int test_sync_cancel(struct io_uring *ring, int async, int nr_all,
- int use_fd)
+ int use_fd, int by_op)
{
struct io_uring_sync_cancel_reg reg = { };
struct io_uring_sqe *sqe;
@@ -169,7 +175,7 @@ int main(int argc, char *argv[])
else if (ret != T_SETUP_OK)
return ret;
- ret = test_sync_cancel(&ring, 0, 0, 0);
+ ret = test_sync_cancel(&ring, 0, 0, 0, 0);
if (ret) {
fprintf(stderr, "test_sync_cancel 0 0 0 failed\n");
return T_EXIT_FAIL;
@@ -177,56 +183,84 @@ int main(int argc, char *argv[])
if (no_sync_cancel)
return T_EXIT_SKIP;
- ret = test_sync_cancel(&ring, 1, 0, 0);
+ ret = test_sync_cancel(&ring, 0, 0, 0, 1);
if (ret) {
- fprintf(stderr, "test_sync_cancel 1 0 0 failed\n");
+ fprintf(stderr, "test_sync_cancel 0 0 1 failed\n");
return T_EXIT_FAIL;
}
- ret = test_sync_cancel(&ring, 0, 1, 0);
+ ret = test_sync_cancel(&ring, 1, 0, 0, 0);
if (ret) {
- fprintf(stderr, "test_sync_cancel 0 1 0 failed\n");
+ fprintf(stderr, "test_sync_cancel 1 0 0 0 failed\n");
return T_EXIT_FAIL;
}
- ret = test_sync_cancel(&ring, 1, 1, 0);
+ ret = test_sync_cancel(&ring, 1, 0, 0, 1);
if (ret) {
- fprintf(stderr, "test_sync_cancel 1 1 0 failed\n");
+ fprintf(stderr, "test_sync_cancel 1 0 0 1 failed\n");
return T_EXIT_FAIL;
}
- ret = test_sync_cancel(&ring, 0, 0, 1);
+
+ ret = test_sync_cancel(&ring, 0, 1, 0, 0);
if (ret) {
- fprintf(stderr, "test_sync_cancel 0 0 1 failed\n");
+ fprintf(stderr, "test_sync_cancel 0 1 0 0 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_sync_cancel(&ring, 0, 1, 0, 1);
+ if (ret) {
+ fprintf(stderr, "test_sync_cancel 0 1 0 1 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+
+ ret = test_sync_cancel(&ring, 1, 1, 0, 0);
+ if (ret) {
+ fprintf(stderr, "test_sync_cancel 1 1 0 0 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_sync_cancel(&ring, 0, 0, 1, 0);
+ if (ret) {
+ fprintf(stderr, "test_sync_cancel 0 0 1 0 failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_sync_cancel(&ring, 1, 0, 1, 0);
+ if (ret) {
+ fprintf(stderr, "test_sync_cancel 1 0 1 0 failed\n");
return T_EXIT_FAIL;
}
- ret = test_sync_cancel(&ring, 1, 0, 1);
+ ret = test_sync_cancel(&ring, 0, 1, 1, 0);
if (ret) {
- fprintf(stderr, "test_sync_cancel 1 0 1 failed\n");
+ fprintf(stderr, "test_sync_cancel 0 1 1 0 failed\n");
return T_EXIT_FAIL;
}
- ret = test_sync_cancel(&ring, 0, 1, 1);
+ ret = test_sync_cancel(&ring, 1, 1, 1, 0);
if (ret) {
- fprintf(stderr, "test_sync_cancel 0 1 1 failed\n");
+ fprintf(stderr, "test_sync_cancel 1 1 1 0 failed\n");
return T_EXIT_FAIL;
}
- ret = test_sync_cancel(&ring, 1, 1, 1);
+ ret = test_sync_cancel_timeout(&ring, 0, 0);
if (ret) {
- fprintf(stderr, "test_sync_cancel 1 1 1 failed\n");
+ fprintf(stderr, "test_sync_cancel_timeout 0 0\n");
return T_EXIT_FAIL;
}
+ if (no_sync_cancel_op)
+ return T_EXIT_PASS;
- ret = test_sync_cancel_timeout(&ring, 0);
+ ret = test_sync_cancel_timeout(&ring, 0, 1);
if (ret) {
- fprintf(stderr, "test_sync_cancel_timeout 0\n");
+ fprintf(stderr, "test_sync_cancel_timeout 0 1\n");
return T_EXIT_FAIL;
}
/* must be last, leaves request */
- ret = test_sync_cancel_timeout(&ring, 1);
+ ret = test_sync_cancel_timeout(&ring, 1, 0);
if (ret) {
fprintf(stderr, "test_sync_cancel_timeout 1\n");
return T_EXIT_FAIL;
diff --git a/contrib/libs/liburing/test/sync-cancel.t/ya.make b/contrib/libs/liburing/test/sync-cancel.t/ya.make
index d6a5a15318..253fe4f7a7 100644
--- a/contrib/libs/liburing/test/sync-cancel.t/ya.make
+++ b/contrib/libs/liburing/test/sync-cancel.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/teardowns.t/ya.make b/contrib/libs/liburing/test/teardowns.t/ya.make
index f227ee9f18..2899e8be17 100644
--- a/contrib/libs/liburing/test/teardowns.t/ya.make
+++ b/contrib/libs/liburing/test/teardowns.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/thread-exit.c b/contrib/libs/liburing/test/thread-exit.c
index 282b1e8461..7c83e4f549 100644
--- a/contrib/libs/liburing/test/thread-exit.c
+++ b/contrib/libs/liburing/test/thread-exit.c
@@ -103,6 +103,8 @@ int main(int argc, char *argv[])
if (do_unlink)
unlink(fname);
if (fd < 0) {
+ if (errno == EPERM || errno == EACCES)
+ goto skip;
perror("open");
return 1;
}
@@ -141,4 +143,7 @@ int main(int argc, char *argv[])
err:
free_g_buf();
return 1;
+skip:
+ free_g_buf();
+ return T_EXIT_SKIP;
}
diff --git a/contrib/libs/liburing/test/thread-exit.t/ya.make b/contrib/libs/liburing/test/thread-exit.t/ya.make
index eefdfcf3f1..5ce470b9e1 100644
--- a/contrib/libs/liburing/test/thread-exit.t/ya.make
+++ b/contrib/libs/liburing/test/thread-exit.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/timeout-new.c b/contrib/libs/liburing/test/timeout-new.c
index e0f2935e63..0608675e59 100644
--- a/contrib/libs/liburing/test/timeout-new.c
+++ b/contrib/libs/liburing/test/timeout-new.c
@@ -9,6 +9,7 @@
#include <unistd.h>
#include <pthread.h>
#include "liburing.h"
+#include "helpers.h"
#define TIMEOUT_MSEC 200
#define TIMEOUT_SEC 10
@@ -23,32 +24,6 @@ static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
ts->tv_nsec = (msec % 1000) * 1000000;
}
-static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
-}
-
-static unsigned long long mtime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
-}
-
-
static int test_return_before_timeout(struct io_uring *ring)
{
struct io_uring_cqe *cqe;
diff --git a/contrib/libs/liburing/test/timeout-new.t/ya.make b/contrib/libs/liburing/test/timeout-new.t/ya.make
index 1303f2cf15..9ee0e1870d 100644
--- a/contrib/libs/liburing/test/timeout-new.t/ya.make
+++ b/contrib/libs/liburing/test/timeout-new.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/timeout.c b/contrib/libs/liburing/test/timeout.c
index 8e3c7bdf7c..0eb67315ac 100644
--- a/contrib/libs/liburing/test/timeout.c
+++ b/contrib/libs/liburing/test/timeout.c
@@ -30,31 +30,6 @@ static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
ts->tv_nsec = (msec % 1000) * 1000000;
}
-static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
-{
- long long sec, usec;
-
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
-}
-
-static unsigned long long mtime_since_now(struct timeval *tv)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
-}
-
/*
* Test that we return to userspace if a timeout triggers, even if we
* don't satisfy the number of events asked for.
@@ -981,6 +956,7 @@ static int test_update_timeout(struct io_uring *ring, unsigned long ms,
struct io_uring_cqe *cqe;
struct __kernel_timespec ts, ts_upd;
unsigned long long exp_ms, base_ms = 10000;
+ bool update_ealready = false;
struct timeval tv;
int ret, i, nr = 2;
__u32 mode = abs ? IORING_TIMEOUT_ABS : 0;
@@ -1043,6 +1019,16 @@ static int test_update_timeout(struct io_uring *ring, unsigned long ms,
}
break;
case 2:
+ /*
+ * We should not be hitting this case, but for
+ * a kernel with PREEMPT_RT, even an instant attempt
+ * to remove a timer will return that the timer is
+ * already running... Deal with it.
+ */
+ if (cqe->res == -EALREADY) {
+ update_ealready = true;
+ break;
+ }
if (cqe->res != 0) {
fprintf(stderr, "%s: got %d, wanted %d\n",
__FUNCTION__, cqe->res,
@@ -1063,7 +1049,7 @@ static int test_update_timeout(struct io_uring *ring, unsigned long ms,
}
exp_ms = mtime_since_now(&tv);
- if (exp_ms >= base_ms / 2) {
+ if (!update_ealready && exp_ms >= base_ms / 2) {
fprintf(stderr, "too long, timeout wasn't updated\n");
goto err;
}
diff --git a/contrib/libs/liburing/test/timeout.t/ya.make b/contrib/libs/liburing/test/timeout.t/ya.make
index 3b26c010dd..a0d748a68e 100644
--- a/contrib/libs/liburing/test/timeout.t/ya.make
+++ b/contrib/libs/liburing/test/timeout.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/truncate.t/ya.make b/contrib/libs/liburing/test/truncate.t/ya.make
index 6a4e13ab41..4adbaa862e 100644
--- a/contrib/libs/liburing/test/truncate.t/ya.make
+++ b/contrib/libs/liburing/test/truncate.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/tty-write-dpoll.t/ya.make b/contrib/libs/liburing/test/tty-write-dpoll.t/ya.make
index f51141ac1e..4ddf4e4f1b 100644
--- a/contrib/libs/liburing/test/tty-write-dpoll.t/ya.make
+++ b/contrib/libs/liburing/test/tty-write-dpoll.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/unlink.c b/contrib/libs/liburing/test/unlink.c
index 95e613ae3f..b4161fff2a 100644
--- a/contrib/libs/liburing/test/unlink.c
+++ b/contrib/libs/liburing/test/unlink.c
@@ -14,6 +14,87 @@
#include "liburing.h"
+static int test_rmdir(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ char buf[32];
+ int ret;
+
+ sprintf(buf, ".tmp.dir.%d", getpid());
+ if (mkdir(buf, 0755) < 0) {
+ perror("mkdir");
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ goto err;
+ }
+ io_uring_prep_unlink(sqe, buf, AT_REMOVEDIR);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ ret = cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+
+ if (!ret) {
+ struct stat sb;
+
+ if (!stat(buf, &sb)) {
+ fprintf(stderr, "dir unlinked but still there\n");
+ goto err;
+ }
+ }
+ unlink(buf);
+ return ret;
+err:
+ unlink(buf);
+ return 1;
+}
+
+static int test_unlink_badaddr(struct io_uring *ring)
+{
+ const char *old = (const char *) (uintptr_t) 0x1234;
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ goto err;
+ }
+ io_uring_prep_unlink(sqe, old, 0);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ ret = cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ return ret;
+err:
+ return 1;
+}
+
static int test_unlink(struct io_uring *ring, const char *old)
{
struct io_uring_cqe *cqe;
@@ -26,7 +107,7 @@ static int test_unlink(struct io_uring *ring, const char *old)
goto err;
}
io_uring_prep_unlink(sqe, old, 0);
-
+
ret = io_uring_submit(ring);
if (ret <= 0) {
fprintf(stderr, "sqe submit failed: %d\n", ret);
@@ -106,6 +187,18 @@ int main(int argc, char *argv[])
return 1;
}
+ ret = test_unlink_badaddr(&ring);
+ if (ret != -EFAULT) {
+ fprintf(stderr, "badaddr unlink got %s\n", strerror(-ret));
+ return 1;
+ }
+
+ ret = test_rmdir(&ring);
+ if (ret) {
+ fprintf(stderr, "rmdir failed: %s\n", strerror(-ret));
+ return 1;
+ }
+
return 0;
err:
unlink(buf);
diff --git a/contrib/libs/liburing/test/unlink.t/ya.make b/contrib/libs/liburing/test/unlink.t/ya.make
index 8c6bf7cdc3..78082b4401 100644
--- a/contrib/libs/liburing/test/unlink.t/ya.make
+++ b/contrib/libs/liburing/test/unlink.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/uring_cmd_ublk.c b/contrib/libs/liburing/test/uring_cmd_ublk.c
new file mode 100644
index 0000000000..30012c7516
--- /dev/null
+++ b/contrib/libs/liburing/test/uring_cmd_ublk.c
@@ -0,0 +1,1253 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: uring_cmd based ublk
+ *
+ * Covers cancellable uring_cmd feature.
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <pthread.h>
+#include <limits.h>
+#include <poll.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/inotify.h>
+#include <sys/wait.h>
+
+#include "liburing.h"
+#include "helpers.h"
+#ifdef CONFIG_HAVE_UBLK_HEADER
+#include <linux/ublk_cmd.h>
+
+/****************** part 1: libublk ********************/
+
+#define CTRL_DEV "/dev/ublk-control"
+#define UBLKC_DEV "/dev/ublkc"
+#define UBLKB_DEV "/dev/ublkb"
+#define UBLK_CTRL_RING_DEPTH 32
+
+/* queue idle timeout */
+#define UBLKSRV_IO_IDLE_SECS 20
+
+#define UBLK_IO_MAX_BYTES 65536
+#define UBLK_MAX_QUEUES 4
+#define UBLK_QUEUE_DEPTH 128
+
+#define UBLK_DBG_DEV (1U << 0)
+#define UBLK_DBG_QUEUE (1U << 1)
+#define UBLK_DBG_IO_CMD (1U << 2)
+#define UBLK_DBG_IO (1U << 3)
+#define UBLK_DBG_CTRL_CMD (1U << 4)
+#define UBLK_LOG (1U << 5)
+
+struct ublk_dev;
+struct ublk_queue;
+
+struct ublk_ctrl_cmd_data {
+ __u32 cmd_op;
+#define CTRL_CMD_HAS_DATA 1
+#define CTRL_CMD_HAS_BUF 2
+ __u32 flags;
+
+ __u64 data[2];
+ __u64 addr;
+ __u32 len;
+};
+
+struct ublk_io {
+ char *buf_addr;
+
+#define UBLKSRV_NEED_FETCH_RQ (1UL << 0)
+#define UBLKSRV_NEED_COMMIT_RQ_COMP (1UL << 1)
+#define UBLKSRV_IO_FREE (1UL << 2)
+ unsigned int flags;
+
+ unsigned int result;
+};
+
+struct ublk_tgt_ops {
+ const char *name;
+ int (*init_tgt)(struct ublk_dev *);
+ void (*deinit_tgt)(struct ublk_dev *);
+
+ int (*queue_io)(struct ublk_queue *, int tag);
+ void (*tgt_io_done)(struct ublk_queue *,
+ int tag, const struct io_uring_cqe *);
+};
+
+struct ublk_tgt {
+ unsigned long dev_size;
+ const struct ublk_tgt_ops *ops;
+ struct ublk_params params;
+};
+
+struct ublk_queue {
+ int q_id;
+ int q_depth;
+ unsigned int cmd_inflight;
+ unsigned int io_inflight;
+ struct ublk_dev *dev;
+ const struct ublk_tgt_ops *tgt_ops;
+ char *io_cmd_buf;
+ struct io_uring ring;
+ struct ublk_io ios[UBLK_QUEUE_DEPTH];
+#define UBLKSRV_QUEUE_STOPPING (1U << 0)
+#define UBLKSRV_QUEUE_IDLE (1U << 1)
+ unsigned state;
+ pid_t tid;
+ pthread_t thread;
+};
+
+struct ublk_dev {
+ struct ublk_tgt tgt;
+ struct ublksrv_ctrl_dev_info dev_info;
+ struct ublk_queue q[UBLK_MAX_QUEUES];
+
+ int fds[2]; /* fds[0] points to /dev/ublkcN */
+ int nr_fds;
+ int ctrl_fd;
+ struct io_uring ring;
+};
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ unsigned long __mptr = (unsigned long)(ptr); \
+ ((type *)(__mptr - offsetof(type, member))); })
+#endif
+
+#define round_up(val, rnd) \
+ (((val) + ((rnd) - 1)) & ~((rnd) - 1))
+
+static unsigned int ublk_dbg_mask = 0;
+
+static const struct ublk_tgt_ops *ublk_find_tgt(const char *name);
+
+static inline int is_target_io(__u64 user_data)
+{
+ return (user_data & (1ULL << 63)) != 0;
+}
+
+static inline __u64 build_user_data(unsigned tag, unsigned op,
+ unsigned tgt_data, unsigned is_target_io)
+{
+ assert(!(tag >> 16) && !(op >> 8) && !(tgt_data >> 16));
+
+ return tag | (op << 16) | (tgt_data << 24) | (__u64)is_target_io << 63;
+}
+
+static inline unsigned int user_data_to_tag(__u64 user_data)
+{
+ return user_data & 0xffff;
+}
+
+static inline unsigned int user_data_to_op(__u64 user_data)
+{
+ return (user_data >> 16) & 0xff;
+}
+
+static void ublk_err(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+}
+
+static void ublk_dbg(int level, const char *fmt, ...)
+{
+ if (level & ublk_dbg_mask) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stdout, fmt, ap);
+ }
+}
+
+static inline void *ublk_get_sqe_cmd(const struct io_uring_sqe *sqe)
+{
+ return (void *)&sqe->cmd;
+}
+
+static inline void ublk_mark_io_done(struct ublk_io *io, int res)
+{
+ io->flags |= (UBLKSRV_NEED_COMMIT_RQ_COMP | UBLKSRV_IO_FREE);
+ io->result = res;
+}
+
+static inline const struct ublksrv_io_desc *ublk_get_iod(
+ const struct ublk_queue *q, int tag)
+{
+ return (struct ublksrv_io_desc *)
+ &(q->io_cmd_buf[tag * sizeof(struct ublksrv_io_desc)]);
+}
+
+static inline void ublk_set_sqe_cmd_op(struct io_uring_sqe *sqe,
+ __u32 cmd_op)
+{
+ __u32 *addr = (__u32 *)&sqe->off;
+
+ addr[0] = cmd_op;
+ addr[1] = 0;
+}
+
+static inline int ublk_setup_ring(struct io_uring *r, int depth,
+ int cq_depth, unsigned flags)
+{
+ struct io_uring_params p;
+
+ memset(&p, 0, sizeof(p));
+ p.flags = flags | IORING_SETUP_CQSIZE;
+ p.cq_entries = cq_depth;
+
+ return io_uring_queue_init_params(depth, r, &p);
+}
+
+static void ublk_ctrl_init_cmd(struct ublk_dev *dev,
+ struct io_uring_sqe *sqe,
+ struct ublk_ctrl_cmd_data *data)
+{
+ struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
+ struct ublksrv_ctrl_cmd *cmd = (struct ublksrv_ctrl_cmd *)ublk_get_sqe_cmd(sqe);
+
+ sqe->fd = dev->ctrl_fd;
+ sqe->opcode = IORING_OP_URING_CMD;
+ sqe->ioprio = 0;
+
+ if (data->flags & CTRL_CMD_HAS_BUF) {
+ cmd->addr = data->addr;
+ cmd->len = data->len;
+ }
+
+ if (data->flags & CTRL_CMD_HAS_DATA)
+ cmd->data[0] = data->data[0];
+
+ cmd->dev_id = info->dev_id;
+ cmd->queue_id = -1;
+
+ ublk_set_sqe_cmd_op(sqe, data->cmd_op);
+
+ io_uring_sqe_set_data(sqe, cmd);
+}
+
+static int __ublk_ctrl_cmd(struct ublk_dev *dev,
+ struct ublk_ctrl_cmd_data *data)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int ret = -EINVAL;
+
+ sqe = io_uring_get_sqe(&dev->ring);
+ if (!sqe) {
+ ublk_err("%s: can't get sqe ret %d\n", __func__, ret);
+ return ret;
+ }
+
+ ublk_ctrl_init_cmd(dev, sqe, data);
+
+ ret = io_uring_submit(&dev->ring);
+ if (ret < 0) {
+ ublk_err("uring submit ret %d\n", ret);
+ return ret;
+ }
+
+ ret = io_uring_wait_cqe(&dev->ring, &cqe);
+ if (ret < 0) {
+ ublk_err("wait cqe: %s\n", strerror(-ret));
+ return ret;
+ }
+ io_uring_cqe_seen(&dev->ring, cqe);
+
+ return cqe->res;
+}
+
+static int ublk_ctrl_start_dev(struct ublk_dev *dev,
+ int daemon_pid)
+{
+ struct ublk_ctrl_cmd_data data = {
+ .cmd_op = UBLK_U_CMD_START_DEV,
+ .flags = CTRL_CMD_HAS_DATA,
+ };
+
+ dev->dev_info.ublksrv_pid = data.data[0] = daemon_pid;
+
+ return __ublk_ctrl_cmd(dev, &data);
+}
+
+static int ublk_ctrl_add_dev(struct ublk_dev *dev)
+{
+ struct ublk_ctrl_cmd_data data = {
+ .cmd_op = UBLK_U_CMD_ADD_DEV,
+ .flags = CTRL_CMD_HAS_BUF,
+ .addr = (__u64) (uintptr_t) &dev->dev_info,
+ .len = sizeof(struct ublksrv_ctrl_dev_info),
+ };
+
+ return __ublk_ctrl_cmd(dev, &data);
+}
+
+static int ublk_ctrl_del_dev(struct ublk_dev *dev)
+{
+ struct ublk_ctrl_cmd_data data = {
+ .cmd_op = UBLK_U_CMD_DEL_DEV,
+ .flags = 0,
+ };
+
+ return __ublk_ctrl_cmd(dev, &data);
+}
+
+static int ublk_ctrl_get_info(struct ublk_dev *dev)
+{
+ struct ublk_ctrl_cmd_data data = {
+ .cmd_op = UBLK_U_CMD_GET_DEV_INFO,
+ .flags = CTRL_CMD_HAS_BUF,
+ .addr = (__u64) (uintptr_t) &dev->dev_info,
+ .len = sizeof(struct ublksrv_ctrl_dev_info),
+ };
+
+ return __ublk_ctrl_cmd(dev, &data);
+}
+
+static int ublk_ctrl_set_params(struct ublk_dev *dev,
+ struct ublk_params *params)
+{
+ struct ublk_ctrl_cmd_data data = {
+ .cmd_op = UBLK_U_CMD_SET_PARAMS,
+ .flags = CTRL_CMD_HAS_BUF,
+ .addr = (__u64) (uintptr_t) params,
+ .len = sizeof(*params),
+ };
+ params->len = sizeof(*params);
+ return __ublk_ctrl_cmd(dev, &data);
+}
+
+static int ublk_ctrl_get_features(struct ublk_dev *dev,
+ __u64 *features)
+{
+ struct ublk_ctrl_cmd_data data = {
+ .cmd_op = UBLK_U_CMD_GET_FEATURES,
+ .flags = CTRL_CMD_HAS_BUF,
+ .addr = (__u64) (uintptr_t) features,
+ .len = sizeof(*features),
+ };
+
+ return __ublk_ctrl_cmd(dev, &data);
+}
+
+static void ublk_ctrl_deinit(struct ublk_dev *dev)
+{
+ close(dev->ctrl_fd);
+ free(dev);
+}
+
+static struct ublk_dev *ublk_ctrl_init(void)
+{
+ struct ublk_dev *dev = (struct ublk_dev *)calloc(1, sizeof(*dev));
+ struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
+ int ret;
+
+ dev->ctrl_fd = open(CTRL_DEV, O_RDWR);
+ if (dev->ctrl_fd < 0) {
+ free(dev);
+ return NULL;
+ }
+
+ info->max_io_buf_bytes = UBLK_IO_MAX_BYTES;
+
+ ret = ublk_setup_ring(&dev->ring, UBLK_CTRL_RING_DEPTH,
+ UBLK_CTRL_RING_DEPTH, IORING_SETUP_SQE128);
+ if (ret < 0) {
+ ublk_err("queue_init: %s\n", strerror(-ret));
+ free(dev);
+ return NULL;
+ }
+ dev->nr_fds = 1;
+
+ return dev;
+}
+
+static int ublk_queue_cmd_buf_sz(struct ublk_queue *q)
+{
+ int size = q->q_depth * sizeof(struct ublksrv_io_desc);
+ unsigned int page_sz = getpagesize();
+
+ return round_up(size, page_sz);
+}
+
+static void ublk_queue_deinit(struct ublk_queue *q)
+{
+ int i;
+ int nr_ios = q->q_depth;
+
+ io_uring_unregister_ring_fd(&q->ring);
+
+ if (q->ring.ring_fd > 0) {
+ io_uring_unregister_files(&q->ring);
+ close(q->ring.ring_fd);
+ q->ring.ring_fd = -1;
+ }
+
+ if (q->io_cmd_buf)
+ munmap(q->io_cmd_buf, ublk_queue_cmd_buf_sz(q));
+
+ for (i = 0; i < nr_ios; i++)
+ free(q->ios[i].buf_addr);
+}
+
+static int ublk_queue_init(struct ublk_queue *q)
+{
+ struct ublk_dev *dev = q->dev;
+ int depth = dev->dev_info.queue_depth;
+ int i, ret = -1;
+ int cmd_buf_size, io_buf_size;
+ unsigned long off;
+ int ring_depth = depth, cq_depth = depth;
+
+ q->tgt_ops = dev->tgt.ops;
+ q->state = 0;
+ q->q_depth = depth;
+ q->cmd_inflight = 0;
+ q->tid = gettid();
+
+ cmd_buf_size = ublk_queue_cmd_buf_sz(q);
+ off = UBLKSRV_CMD_BUF_OFFSET +
+ q->q_id * (UBLK_MAX_QUEUE_DEPTH * sizeof(struct ublksrv_io_desc));
+ q->io_cmd_buf = (char *)mmap(0, cmd_buf_size, PROT_READ,
+ MAP_SHARED | MAP_POPULATE, dev->fds[0], off);
+ if (q->io_cmd_buf == MAP_FAILED) {
+ ublk_err("ublk dev %d queue %d map io_cmd_buf failed %m\n",
+ q->dev->dev_info.dev_id, q->q_id);
+ goto fail;
+ }
+
+ io_buf_size = dev->dev_info.max_io_buf_bytes;
+ for (i = 0; i < q->q_depth; i++) {
+ q->ios[i].buf_addr = NULL;
+
+ if (posix_memalign((void **)&q->ios[i].buf_addr,
+ getpagesize(), io_buf_size)) {
+ ublk_err("ublk dev %d queue %d io %d posix_memalign failed %m\n",
+ dev->dev_info.dev_id, q->q_id, i);
+ goto fail;
+ }
+ q->ios[i].flags = UBLKSRV_NEED_FETCH_RQ | UBLKSRV_IO_FREE;
+ }
+
+ ret = ublk_setup_ring(&q->ring, ring_depth, cq_depth,
+ IORING_SETUP_COOP_TASKRUN);
+ if (ret < 0) {
+ ublk_err("ublk dev %d queue %d setup io_uring failed %d\n",
+ q->dev->dev_info.dev_id, q->q_id, ret);
+ goto fail;
+ }
+
+ io_uring_register_ring_fd(&q->ring);
+
+ ret = io_uring_register_files(&q->ring, dev->fds, dev->nr_fds);
+ if (ret) {
+ ublk_err("ublk dev %d queue %d register files failed %d\n",
+ q->dev->dev_info.dev_id, q->q_id, ret);
+ goto fail;
+ }
+
+ return 0;
+ fail:
+ ublk_queue_deinit(q);
+ ublk_err("ublk dev %d queue %d failed\n",
+ dev->dev_info.dev_id, q->q_id);
+ return -ENOMEM;
+}
+
+static int ublk_dev_prep(struct ublk_dev *dev)
+{
+ int dev_id = dev->dev_info.dev_id;
+ char buf[64];
+ int ret = 0;
+
+ snprintf(buf, 64, "%s%d", UBLKC_DEV, dev_id);
+ dev->fds[0] = open(buf, O_RDWR);
+ if (dev->fds[0] < 0) {
+ ret = -EBADF;
+ ublk_err("can't open %s, ret %d\n", buf, dev->fds[0]);
+ goto fail;
+ }
+
+ if (dev->tgt.ops->init_tgt)
+ ret = dev->tgt.ops->init_tgt(dev);
+
+ return ret;
+fail:
+ close(dev->fds[0]);
+ return ret;
+}
+
+static void ublk_dev_unprep(struct ublk_dev *dev)
+{
+ if (dev->tgt.ops->deinit_tgt)
+ dev->tgt.ops->deinit_tgt(dev);
+ close(dev->fds[0]);
+}
+
+static int ublk_queue_io_cmd(struct ublk_queue *q,
+ struct ublk_io *io, unsigned tag)
+{
+ struct ublksrv_io_cmd *cmd;
+ struct io_uring_sqe *sqe;
+ unsigned int cmd_op = 0;
+ __u64 user_data;
+
+ /* only freed io can be issued */
+ if (!(io->flags & UBLKSRV_IO_FREE))
+ return 0;
+
+ /* we issue because we need either fetching or committing */
+ if (!(io->flags &
+ (UBLKSRV_NEED_FETCH_RQ | UBLKSRV_NEED_COMMIT_RQ_COMP)))
+ return 0;
+
+ if (io->flags & UBLKSRV_NEED_COMMIT_RQ_COMP)
+ cmd_op = UBLK_U_IO_COMMIT_AND_FETCH_REQ;
+ else if (io->flags & UBLKSRV_NEED_FETCH_RQ)
+ cmd_op = UBLK_U_IO_FETCH_REQ;
+
+ sqe = io_uring_get_sqe(&q->ring);
+ if (!sqe) {
+ ublk_err("%s: run out of sqe %d, tag %d\n",
+ __func__, q->q_id, tag);
+ return -1;
+ }
+
+ cmd = (struct ublksrv_io_cmd *)ublk_get_sqe_cmd(sqe);
+
+ if (cmd_op == UBLK_U_IO_COMMIT_AND_FETCH_REQ)
+ cmd->result = io->result;
+
+ /* These fields should be written once, never change */
+ ublk_set_sqe_cmd_op(sqe, cmd_op);
+ sqe->fd = 0; /* dev->fds[0] */
+ sqe->opcode = IORING_OP_URING_CMD;
+ sqe->flags = IOSQE_FIXED_FILE;
+ sqe->rw_flags = 0;
+ cmd->tag = tag;
+ cmd->addr = (__u64) (uintptr_t) io->buf_addr;
+ cmd->q_id = q->q_id;
+
+ user_data = build_user_data(tag, _IOC_NR(cmd_op), 0, 0);
+ io_uring_sqe_set_data64(sqe, user_data);
+
+ io->flags = 0;
+
+ q->cmd_inflight += 1;
+
+ ublk_dbg(UBLK_DBG_IO_CMD, "%s: (qid %d tag %u cmd_op %u) iof %x stopping %d\n",
+ __func__, q->q_id, tag, cmd_op,
+ io->flags, !!(q->state & UBLKSRV_QUEUE_STOPPING));
+ return 1;
+}
+
+static int ublk_complete_io(struct ublk_queue *q,
+ unsigned tag, int res)
+{
+ struct ublk_io *io = &q->ios[tag];
+
+ ublk_mark_io_done(io, res);
+
+ return ublk_queue_io_cmd(q, io, tag);
+}
+
+static void ublk_submit_fetch_commands(struct ublk_queue *q)
+{
+ int i = 0;
+
+ for (i = 0; i < q->q_depth; i++)
+ ublk_queue_io_cmd(q, &q->ios[i], i);
+}
+
+static int ublk_queue_is_idle(struct ublk_queue *q)
+{
+ return !io_uring_sq_ready(&q->ring) && !q->io_inflight;
+}
+
+static int ublk_queue_is_done(struct ublk_queue *q)
+{
+ return (q->state & UBLKSRV_QUEUE_STOPPING) && ublk_queue_is_idle(q);
+}
+
+static inline void ublksrv_handle_tgt_cqe(struct ublk_queue *q,
+ struct io_uring_cqe *cqe)
+{
+ unsigned tag = user_data_to_tag(cqe->user_data);
+
+ if (cqe->res < 0 && cqe->res != -EAGAIN)
+ ublk_err("%s: failed tgt io: res %d qid %u tag %u, cmd_op %u\n",
+ __func__, cqe->res, q->q_id,
+ user_data_to_tag(cqe->user_data),
+ user_data_to_op(cqe->user_data));
+
+ if (q->tgt_ops->tgt_io_done)
+ q->tgt_ops->tgt_io_done(q, tag, cqe);
+}
+
+static void ublk_handle_cqe(struct io_uring *r,
+ struct io_uring_cqe *cqe, void *data)
+{
+ struct ublk_queue *q = container_of(r, struct ublk_queue, ring);
+ unsigned tag = user_data_to_tag(cqe->user_data);
+ unsigned cmd_op = user_data_to_op(cqe->user_data);
+ int fetch = (cqe->res != UBLK_IO_RES_ABORT) &&
+ !(q->state & UBLKSRV_QUEUE_STOPPING);
+ struct ublk_io *io;
+
+ ublk_dbg(UBLK_DBG_IO_CMD, "%s: res %d (qid %d tag %u cmd_op %u target %d) stopping %d\n",
+ __func__, cqe->res, q->q_id, tag, cmd_op,
+ is_target_io(cqe->user_data),
+ (q->state & UBLKSRV_QUEUE_STOPPING));
+
+ /* Don't retrieve io in case of target io */
+ if (is_target_io(cqe->user_data)) {
+ ublksrv_handle_tgt_cqe(q, cqe);
+ return;
+ }
+
+ io = &q->ios[tag];
+ q->cmd_inflight--;
+
+ if (!fetch) {
+ q->state |= UBLKSRV_QUEUE_STOPPING;
+ io->flags &= ~UBLKSRV_NEED_FETCH_RQ;
+ }
+
+ if (cqe->res == UBLK_IO_RES_OK) {
+ assert(tag < q->q_depth);
+ q->tgt_ops->queue_io(q, tag);
+ } else {
+ /*
+ * COMMIT_REQ will be completed immediately since no fetching
+ * piggyback is required.
+ *
+ * Marking IO_FREE only, then this io won't be issued since
+ * we only issue io with (UBLKSRV_IO_FREE | UBLKSRV_NEED_*)
+ *
+ * */
+ io->flags = UBLKSRV_IO_FREE;
+ }
+}
+
+static int ublk_reap_events_uring(struct io_uring *r)
+{
+ struct io_uring_cqe *cqe;
+ unsigned head;
+ int count = 0;
+
+ io_uring_for_each_cqe(r, head, cqe) {
+ ublk_handle_cqe(r, cqe, NULL);
+ count += 1;
+ }
+ io_uring_cq_advance(r, count);
+
+ return count;
+}
+
+static int ublk_process_io(struct ublk_queue *q)
+{
+ int ret, reapped;
+
+ ublk_dbg(UBLK_DBG_QUEUE, "dev%d-q%d: to_submit %d inflight cmd %u stopping %d\n",
+ q->dev->dev_info.dev_id,
+ q->q_id, io_uring_sq_ready(&q->ring),
+ q->cmd_inflight,
+ (q->state & UBLKSRV_QUEUE_STOPPING));
+
+ if (ublk_queue_is_done(q))
+ return -ENODEV;
+
+ ret = io_uring_submit_and_wait(&q->ring, 1);
+ reapped = ublk_reap_events_uring(&q->ring);
+
+ ublk_dbg(UBLK_DBG_QUEUE, "submit result %d, reapped %d stop %d idle %d\n",
+ ret, reapped, (q->state & UBLKSRV_QUEUE_STOPPING),
+ (q->state & UBLKSRV_QUEUE_IDLE));
+
+ return reapped;
+}
+
+static void *ublk_io_handler_fn(void *data)
+{
+ struct ublk_queue *q = data;
+ int dev_id = q->dev->dev_info.dev_id;
+ int ret;
+
+ ret = ublk_queue_init(q);
+ if (ret) {
+ ublk_err("ublk dev %d queue %d init queue failed\n",
+ dev_id, q->q_id);
+ return NULL;
+ }
+ ublk_dbg(UBLK_DBG_QUEUE, "tid %d: ublk dev %d queue %d started\n",
+ q->tid, dev_id, q->q_id);
+
+ /* submit all io commands to ublk driver */
+ ublk_submit_fetch_commands(q);
+ do {
+ if (ublk_process_io(q) < 0)
+ break;
+ } while (1);
+
+ ublk_dbg(UBLK_DBG_QUEUE, "ublk dev %d queue %d exited\n", dev_id, q->q_id);
+ ublk_queue_deinit(q);
+ return NULL;
+}
+
+static void ublk_set_parameters(struct ublk_dev *dev)
+{
+ int ret;
+
+ ret = ublk_ctrl_set_params(dev, &dev->tgt.params);
+ if (ret)
+ ublk_err("dev %d set basic parameter failed %d\n",
+ dev->dev_info.dev_id, ret);
+}
+
+static int ublk_start_daemon(struct ublk_dev *dev)
+{
+ int ret, i;
+ void *thread_ret;
+ const struct ublksrv_ctrl_dev_info *dinfo = &dev->dev_info;
+
+ if (daemon(1, 1) < 0)
+ return -errno;
+
+ ublk_dbg(UBLK_DBG_DEV, "%s enter\n", __func__);
+
+ ret = ublk_dev_prep(dev);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < dinfo->nr_hw_queues; i++) {
+ dev->q[i].dev = dev;
+ dev->q[i].q_id = i;
+ pthread_create(&dev->q[i].thread, NULL,
+ ublk_io_handler_fn,
+ &dev->q[i]);
+ }
+
+ /* everything is fine now, start us */
+ ublk_set_parameters(dev);
+ ret = ublk_ctrl_start_dev(dev, getpid());
+ if (ret < 0) {
+ ublk_err("%s: ublk_ctrl_start_dev failed: %d\n", __func__, ret);
+ goto fail;
+ }
+
+ /* wait until we are terminated */
+ for (i = 0; i < dinfo->nr_hw_queues; i++)
+ pthread_join(dev->q[i].thread, &thread_ret);
+ fail:
+ ublk_dev_unprep(dev);
+ ublk_dbg(UBLK_DBG_DEV, "%s exit\n", __func__);
+
+ return ret;
+}
+
+static int wait_ublk_dev(char *dev_name, int evt_mask, unsigned timeout)
+{
+#define EV_SIZE (sizeof(struct inotify_event))
+#define EV_BUF_LEN (128 * (EV_SIZE + 16))
+ struct pollfd pfd;
+ int fd, wd;
+ int ret = -EINVAL;
+
+ fd = inotify_init();
+ if (fd < 0) {
+ ublk_dbg(UBLK_DBG_DEV, "%s: inotify init failed\n", __func__);
+ return fd;
+ }
+
+ wd = inotify_add_watch(fd, "/dev", evt_mask);
+ if (wd == -1) {
+ ublk_dbg(UBLK_DBG_DEV, "%s: add watch for /dev failed\n", __func__);
+ goto fail;
+ }
+
+ pfd.fd = fd;
+ pfd.events = POLL_IN;
+ while (1) {
+ int i = 0;
+ char buffer[EV_BUF_LEN];
+ ret = poll(&pfd, 1, 1000 * timeout);
+
+ if (ret == -1) {
+ ublk_err("%s: poll inotify failed: %d\n", __func__, ret);
+ goto rm_watch;
+ } else if (ret == 0) {
+ ublk_err("%s: poll inotify timeout\n", __func__);
+ ret = -ENOENT;
+ goto rm_watch;
+ }
+
+ ret = read(fd, buffer, EV_BUF_LEN);
+ if (ret < 0) {
+ ublk_err("%s: read inotify fd failed\n", __func__);
+ goto rm_watch;
+ }
+
+ while (i < ret) {
+ struct inotify_event *event = (struct inotify_event *)&buffer[i];
+
+ ublk_dbg(UBLK_DBG_DEV, "%s: inotify event %x %s\n",
+ __func__, event->mask, event->name);
+ if (event->mask & evt_mask) {
+ if (!strcmp(event->name, dev_name)) {
+ ret = 0;
+ goto rm_watch;
+ }
+ }
+ i += EV_SIZE + event->len;
+ }
+ }
+rm_watch:
+ inotify_rm_watch(fd, wd);
+fail:
+ close(fd);
+ return ret;
+}
+
+static int ublk_stop_io_daemon(const struct ublk_dev *dev)
+{
+ int daemon_pid = dev->dev_info.ublksrv_pid;
+ int dev_id = dev->dev_info.dev_id;
+ char ublkc[64];
+ int ret;
+
+ /*
+ * Wait until ublk char device is closed, when our daemon is shutdown
+ */
+ snprintf(ublkc, sizeof(ublkc), "%s%d", "ublkc", dev_id);
+ ret = wait_ublk_dev(ublkc, IN_CLOSE_WRITE, 10);
+ waitpid(dev->dev_info.ublksrv_pid, NULL, 0);
+ ublk_dbg(UBLK_DBG_DEV, "%s: pid %d dev_id %d ret %d\n",
+ __func__, daemon_pid, dev_id, ret);
+
+ return ret;
+}
+
+static int cmd_dev_add(char *tgt_type, int *exp_id, unsigned nr_queues,
+ unsigned depth)
+{
+ const struct ublk_tgt_ops *ops;
+ struct ublksrv_ctrl_dev_info *info;
+ struct ublk_dev *dev;
+ int dev_id = *exp_id;
+ char ublkb[64];
+ int ret;
+
+ ops = ublk_find_tgt(tgt_type);
+ if (!ops) {
+ ublk_err("%s: no such tgt type, type %s\n",
+ __func__, tgt_type);
+ return -ENODEV;
+ }
+
+ if (nr_queues > UBLK_MAX_QUEUES || depth > UBLK_QUEUE_DEPTH) {
+ ublk_err("%s: invalid nr_queues or depth queues %u depth %u\n",
+ __func__, nr_queues, depth);
+ return -EINVAL;
+ }
+
+ dev = ublk_ctrl_init();
+ if (!dev) {
+ ublk_err("%s: can't alloc dev id %d, type %s\n",
+ __func__, dev_id, tgt_type);
+ return -ENOMEM;
+ }
+
+ info = &dev->dev_info;
+ info->dev_id = dev_id;
+ info->nr_hw_queues = nr_queues;
+ info->queue_depth = depth;
+ dev->tgt.ops = ops;
+
+ ret = ublk_ctrl_add_dev(dev);
+ if (ret < 0) {
+ ublk_err("%s: can't add dev id %d, type %s ret %d\n",
+ __func__, dev_id, tgt_type, ret);
+ goto fail;
+ }
+
+ switch (fork()) {
+ case -1:
+ goto fail;
+ case 0:
+ ublk_start_daemon(dev);
+ return 0;
+ }
+
+ /*
+ * Wait until ublk disk is added, when our daemon is started
+ * successfully
+ */
+ snprintf(ublkb, sizeof(ublkb), "%s%u", "ublkb", dev->dev_info.dev_id);
+ ret = wait_ublk_dev(ublkb, IN_CREATE, 3);
+ if (ret < 0) {
+ ublk_err("%s: can't start daemon id %d, type %s\n",
+ __func__, dev_id, tgt_type);
+ ublk_ctrl_del_dev(dev);
+ } else {
+ *exp_id = dev->dev_info.dev_id;
+ }
+fail:
+ ublk_ctrl_deinit(dev);
+ return ret;
+}
+
+static int cmd_dev_del_by_kill(int number)
+{
+ struct ublk_dev *dev;
+ int ret;
+
+ dev = ublk_ctrl_init();
+ dev->dev_info.dev_id = number;
+
+ ret = ublk_ctrl_get_info(dev);
+ if (ret < 0)
+ goto fail;
+
+ /* simulate one ublk daemon panic */
+ kill(dev->dev_info.ublksrv_pid, 9);
+
+ ret = ublk_stop_io_daemon(dev);
+ if (ret < 0)
+ ublk_err("%s: can't stop daemon id %d\n", __func__, number);
+ ublk_ctrl_del_dev(dev);
+fail:
+ if (ret >= 0)
+ ret = ublk_ctrl_get_info(dev);
+ ublk_ctrl_deinit(dev);
+
+ return (ret != 0) ? 0 : -EIO;
+}
+
+/****************** part 2: target implementation ********************/
+
+static int ublk_null_tgt_init(struct ublk_dev *dev)
+{
+ const struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
+ unsigned long dev_size = 250UL << 30;
+
+ dev->tgt.dev_size = dev_size;
+ dev->tgt.params = (struct ublk_params) {
+ .types = UBLK_PARAM_TYPE_BASIC,
+ .basic = {
+ .logical_bs_shift = 9,
+ .physical_bs_shift = 12,
+ .io_opt_shift = 12,
+ .io_min_shift = 9,
+ .max_sectors = info->max_io_buf_bytes >> 9,
+ .dev_sectors = dev_size >> 9,
+ },
+ };
+
+ return 0;
+}
+
+static int ublk_null_queue_io(struct ublk_queue *q, int tag)
+{
+ const struct ublksrv_io_desc *iod = ublk_get_iod(q, tag);
+
+ ublk_complete_io(q, tag, iod->nr_sectors << 9);
+
+ return 0;
+}
+
+static const struct ublk_tgt_ops tgt_ops_list[] = {
+ {
+ .name = "null",
+ .init_tgt = ublk_null_tgt_init,
+ .queue_io = ublk_null_queue_io,
+ },
+};
+
+static const struct ublk_tgt_ops *ublk_find_tgt(const char *name)
+{
+ const struct ublk_tgt_ops *ops;
+ int i;
+
+ if (name == NULL)
+ return NULL;
+
+ for (i = 0; sizeof(tgt_ops_list) / sizeof(*ops); i++)
+ if (strcmp(tgt_ops_list[i].name, name) == 0)
+ return &tgt_ops_list[i];
+ return NULL;
+}
+
+
+/****************** part 3: IO test over ublk disk ********************/
+
+#include "helpers.h"
+#include "liburing.h"
+#define BS 4096
+#define BUFFERS 128
+
+struct io_ctx {
+ int dev_id;
+ int write;
+ int seq;
+
+ /* output */
+ int res;
+ pthread_t handle;
+};
+
+static int __test_io(struct io_uring *ring, int fd, int write,
+ int seq, struct iovec *vecs, int exp_len, off_t start)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int i, ret;
+ off_t offset;
+
+ offset = start;
+ for (i = 0; i < BUFFERS; i++) {
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "sqe get failed\n");
+ goto err;
+ }
+ if (!seq)
+ offset = start + BS * (rand() % BUFFERS);
+ if (write) {
+ io_uring_prep_write_fixed(sqe, fd, vecs[i].iov_base,
+ vecs[i].iov_len,
+ offset, i);
+ } else {
+ io_uring_prep_read_fixed(sqe, fd, vecs[i].iov_base,
+ vecs[i].iov_len,
+ offset, i);
+ }
+ sqe->user_data = i;
+ if (seq)
+ offset += BS;
+ }
+
+ ret = io_uring_submit(ring);
+ if (ret != BUFFERS) {
+ fprintf(stderr, "submit got %d, wanted %d\n", ret, BUFFERS);
+ goto err;
+ }
+
+ for (i = 0; i < BUFFERS; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe=%d\n", ret);
+ goto err;
+ }
+ if (exp_len == -1) {
+ int iov_len = vecs[cqe->user_data].iov_len;
+
+ if (cqe->res != iov_len) {
+ fprintf(stderr, "cqe res %d, wanted %d\n",
+ cqe->res, iov_len);
+ goto err;
+ }
+ } else if (cqe->res != exp_len) {
+ fprintf(stderr, "cqe res %d, wanted %d\n", cqe->res, exp_len);
+ goto err;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ return 0;
+err:
+ return 1;
+}
+
+/* Run IO over ublk block device */
+static int test_io(struct io_ctx *ctx)
+{
+ struct io_uring ring;
+ int ret, ring_flags = 0;
+ char buf[256];
+ int fd = -1;
+ off_t offset = 0;
+ unsigned long long bytes;
+ int open_flags = O_DIRECT;
+ struct iovec *vecs = t_create_buffers(BUFFERS, BS);
+
+ ret = t_create_ring(BUFFERS, &ring, ring_flags);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ snprintf(buf, sizeof(buf), "%s%d", UBLKB_DEV, ctx->dev_id);
+
+ if (ctx->write)
+ open_flags |= O_WRONLY;
+ else
+ open_flags |= O_RDONLY;
+ fd = open(buf, open_flags);
+ if (fd < 0) {
+ if (errno == EINVAL)
+ return 0;
+ return 1;
+ }
+
+ if (ioctl(fd, BLKGETSIZE64, &bytes) != 0)
+ return 1;
+
+ ret = t_register_buffers(&ring, vecs, BUFFERS);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "buffer reg failed: %d\n", ret);
+ return 1;
+ }
+
+ for (offset = 0; offset < bytes; offset += BS * BUFFERS) {
+ ret = __test_io(&ring, fd, ctx->write, ctx->seq, vecs, BS,
+ offset);
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "/dev/ublkb%d read failed: offset %lu ret %d\n",
+ ctx->dev_id, (unsigned long) offset, ret);
+ break;
+ }
+ }
+
+ close(fd);
+ io_uring_unregister_buffers(&ring);
+ io_uring_queue_exit(&ring);
+
+ return ret;
+}
+
+static void *test_io_fn(void *data)
+{
+ struct io_ctx *ctx = data;
+
+ ctx->res = test_io(ctx);
+
+ return data;
+}
+
+static void ignore_stderr(void)
+{
+ int devnull = open("/dev/null", O_WRONLY);
+
+ if (devnull >= 0) {
+ dup2(devnull, fileno(stderr));
+ close(devnull);
+ }
+}
+
+static int test_io_worker(int dev_id)
+{
+ const int nr_jobs = 4;
+ struct io_ctx ctx[nr_jobs];
+ int i, ret = 0;
+
+ for (i = 0; i < nr_jobs; i++) {
+ ctx[i].dev_id = dev_id;
+ ctx[i].write = (i & 0x1) ? 0 : 1;
+ ctx[i].seq = 1;
+
+ pthread_create(&ctx[i].handle, NULL, test_io_fn, &ctx[i]);
+ }
+
+ for (i = 0; i < nr_jobs; i++) {
+ pthread_join(ctx[i].handle, NULL);
+
+ if (!ret && ctx[i].res)
+ ret = ctx[i].res;
+ }
+
+ return ret;
+}
+
+/*
+ * Run IO over created ublk device, meantime delete this ublk device
+ *
+ * Cover cancellable uring_cmd
+ * */
+static int test_del_ublk_with_io(void)
+{
+ const unsigned wait_ms = 200;
+ char *tgt_type = "null";
+ int dev_id = -1;
+ int ret, pid;
+
+ ret = cmd_dev_add(tgt_type, &dev_id, 2, BUFFERS);
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "buffer reg failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ switch ((pid = fork())) {
+ case -1:
+ fprintf(stderr, "fork failed\n");
+ return T_EXIT_FAIL;
+ case 0:
+ /* io error is expected since the parent is killing ublk */
+ ignore_stderr();
+ test_io_worker(dev_id);
+ return 0;
+ default:
+ /*
+ * Wait a little while until ublk IO pipeline is warm up,
+ * then try to shutdown ublk device by `kill -9 $ublk_daemon_pid`.
+ *
+ * cancellable uring_cmd code path can be covered in this way.
+ */
+ usleep(wait_ms * 1000);
+ ret = cmd_dev_del_by_kill(dev_id);
+ waitpid(pid, NULL, 0);
+ return ret;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ const int nr_loop = 4;
+ struct ublk_dev *dev;
+ __u64 features;
+ int ret, i;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ dev = ublk_ctrl_init();
+ /* ublk isn't supported or the module isn't loaded */
+ if (!dev)
+ return T_EXIT_SKIP;
+
+ /* kernel doesn't support get_features */
+ ret = ublk_ctrl_get_features(dev, &features);
+ if (ret < 0)
+ return T_EXIT_SKIP;
+
+ if (!(features & UBLK_F_CMD_IOCTL_ENCODE))
+ return T_EXIT_SKIP;
+
+ for (i = 0; i < nr_loop; i++) {
+ if (test_del_ublk_with_io())
+ return T_EXIT_FAIL;
+ }
+ ublk_ctrl_deinit(dev);
+ return T_EXIT_PASS;
+}
+#else
+int main(int argc, char *argv[])
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/uring_cmd_ublk.t/ya.make b/contrib/libs/liburing/test/uring_cmd_ublk.t/ya.make
new file mode 100644
index 0000000000..edc9a36693
--- /dev/null
+++ b/contrib/libs/liburing/test/uring_cmd_ublk.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ uring_cmd_ublk.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/version.t/ya.make b/contrib/libs/liburing/test/version.t/ya.make
index 8f387e4ca4..aca2c8b392 100644
--- a/contrib/libs/liburing/test/version.t/ya.make
+++ b/contrib/libs/liburing/test/version.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/wait-timeout.c b/contrib/libs/liburing/test/wait-timeout.c
new file mode 100644
index 0000000000..3d05a8763e
--- /dev/null
+++ b/contrib/libs/liburing/test/wait-timeout.c
@@ -0,0 +1,288 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: run various timeout tests
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#include "helpers.h"
+#include "liburing.h"
+#include "../src/syscall.h"
+
+#define IO_NSEC_PER_SEC 1000000000ULL
+
+static bool support_abs = false;
+static bool support_clock = false;
+
+static unsigned long long timespec_to_ns(struct timespec *ts)
+{
+ return ts->tv_nsec + ts->tv_sec * IO_NSEC_PER_SEC;
+}
+static struct timespec ns_to_timespec(unsigned long long t)
+{
+ struct timespec ts;
+
+ ts.tv_sec = t / IO_NSEC_PER_SEC;
+ ts.tv_nsec = t - ts.tv_sec * IO_NSEC_PER_SEC;
+ return ts;
+}
+
+static long long ns_since(struct timespec *ts)
+{
+ struct timespec now;
+ int ret;
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &now);
+ if (ret) {
+ fprintf(stderr, "clock_gettime failed\n");
+ exit(T_EXIT_FAIL);
+ }
+
+ return timespec_to_ns(&now) - timespec_to_ns(ts);
+
+}
+
+static int t_io_uring_wait(struct io_uring *ring, int nr, unsigned enter_flags,
+ struct timespec *ts)
+{
+ struct __kernel_timespec kts = {
+ .tv_sec = ts->tv_sec,
+ .tv_nsec = ts->tv_nsec
+ };
+ struct io_uring_getevents_arg arg = {
+ .sigmask = 0,
+ .sigmask_sz = _NSIG / 8,
+ .ts = (unsigned long) &kts
+ };
+ int ret;
+
+ enter_flags |= IORING_ENTER_GETEVENTS | IORING_ENTER_EXT_ARG;
+ ret = io_uring_enter2(ring->ring_fd, 0, nr, enter_flags,
+ (void *)&arg, sizeof(arg));
+ return ret;
+}
+
+static int probe_timers(void)
+{
+ struct io_uring_clock_register cr = { .clockid = CLOCK_MONOTONIC, };
+ struct io_uring ring;
+ struct timespec ts;
+ int ret;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "probe ring setup failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (ret) {
+ fprintf(stderr, "clock_gettime failed\n");
+ return ret;
+ }
+
+ ret = t_io_uring_wait(&ring, 0, IORING_ENTER_ABS_TIMER, &ts);
+ if (!ret) {
+ support_abs = true;
+ } else if (ret != -EINVAL) {
+ fprintf(stderr, "wait failed %i\n", ret);
+ return ret;
+ }
+
+ ret = io_uring_register_clock(&ring, &cr);
+ if (!ret) {
+ support_clock = true;
+ } else if (ret != -EINVAL) {
+ fprintf(stderr, "io_uring_register_clock %i\n", ret);
+ return ret;
+ }
+
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
+static int test_timeout(bool abs, bool set_clock)
+{
+ unsigned enter_flags = abs ? IORING_ENTER_ABS_TIMER : 0;
+ struct io_uring ring;
+ struct timespec start, end, ts;
+ long long dt;
+ int ret;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return 1;
+ }
+
+ if (set_clock) {
+ struct io_uring_clock_register cr = {};
+
+ cr.clockid = CLOCK_BOOTTIME;
+ ret = io_uring_register_clock(&ring, &cr);
+ if (ret) {
+ fprintf(stderr, "io_uring_register_clock failed\n");
+ return 1;
+ }
+ }
+
+ /* pass current time */
+ ret = clock_gettime(CLOCK_MONOTONIC, &start);
+ assert(ret == 0);
+
+ ts = abs ? start : ns_to_timespec(0);
+ ret = t_io_uring_wait(&ring, 1, enter_flags, &ts);
+ if (ret != -ETIME) {
+ fprintf(stderr, "wait current time failed, %i\n", ret);
+ return 1;
+ }
+
+ if (ns_since(&start) >= IO_NSEC_PER_SEC) {
+ fprintf(stderr, "current time test failed\n");
+ return 1;
+ }
+
+ if (abs) {
+ /* expired time */
+ ret = clock_gettime(CLOCK_MONOTONIC, &start);
+ assert(ret == 0);
+ ts = ns_to_timespec(timespec_to_ns(&start) - IO_NSEC_PER_SEC);
+
+ ret = t_io_uring_wait(&ring, 1, enter_flags, &ts);
+ if (ret != -ETIME) {
+ fprintf(stderr, "expired timeout wait failed, %i\n", ret);
+ return 1;
+ }
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &end);
+ assert(ret == 0);
+
+ if (ns_since(&start) >= IO_NSEC_PER_SEC) {
+ fprintf(stderr, "expired timer test failed\n");
+ return 1;
+ }
+ }
+
+ /* 1s wait */
+ ret = clock_gettime(CLOCK_MONOTONIC, &start);
+ assert(ret == 0);
+
+ dt = 2 * IO_NSEC_PER_SEC + (abs ? timespec_to_ns(&start) : 0);
+ ts = ns_to_timespec(dt);
+ ret = t_io_uring_wait(&ring, 1, enter_flags, &ts);
+ if (ret != -ETIME) {
+ fprintf(stderr, "wait timeout failed, %i\n", ret);
+ return 1;
+ }
+
+ dt = ns_since(&start);
+ if (dt < IO_NSEC_PER_SEC || dt > 3 * IO_NSEC_PER_SEC) {
+ fprintf(stderr, "early wake up, %lld\n", dt);
+ return 1;
+ }
+ return 0;
+}
+
+static int test_clock_setup(void)
+{
+ struct io_uring ring;
+ struct io_uring_clock_register cr = {};
+ int ret;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, NULL, 0);
+ if (!ret) {
+ fprintf(stderr, "invalid null clock registration %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ cr.clockid = -1;
+ ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+ if (ret != -EINVAL) {
+ fprintf(stderr, "invalid clockid registration %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ cr.clockid = CLOCK_MONOTONIC;
+ ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+ if (ret) {
+ fprintf(stderr, "clock monotonic registration failed %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ cr.clockid = CLOCK_BOOTTIME;
+ ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+ if (ret) {
+ fprintf(stderr, "clock boottime registration failed %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ cr.clockid = CLOCK_MONOTONIC;
+ ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+ if (ret) {
+ fprintf(stderr, "2nd clock monotonic registration failed %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret, i;
+
+ if (argc > 1)
+ return 0;
+
+ ret = probe_timers();
+ if (ret) {
+ fprintf(stderr, "probe failed\n");
+ return T_EXIT_FAIL;
+ }
+ if (!support_abs && !support_clock)
+ return T_EXIT_SKIP;
+
+ if (support_clock) {
+ ret = test_clock_setup();
+ if (ret) {
+ fprintf(stderr, "test_clock_setup failed\n");
+ return T_EXIT_FAIL;
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ bool abs = i & 1;
+ bool clock = i & 2;
+
+ if (abs && !support_abs)
+ continue;
+ if (clock && !support_clock)
+ continue;
+
+ ret = test_timeout(abs, clock);
+ if (ret) {
+ fprintf(stderr, "test_timeout failed %i %i\n",
+ abs, clock);
+ return ret;
+ }
+ }
+
+ return 0;
+}
diff --git a/contrib/libs/liburing/test/wait-timeout.t/ya.make b/contrib/libs/liburing/test/wait-timeout.t/ya.make
new file mode 100644
index 0000000000..ac1b89877f
--- /dev/null
+++ b/contrib/libs/liburing/test/wait-timeout.t/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+VERSION(2.8)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ wait-timeout.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/waitid.c b/contrib/libs/liburing/test/waitid.c
index f7ebe55ac7..d66e483026 100644
--- a/contrib/libs/liburing/test/waitid.c
+++ b/contrib/libs/liburing/test/waitid.c
@@ -20,6 +20,39 @@ static void child(long usleep_time)
exit(0);
}
+static int test_invalid_infop(struct io_uring *ring)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ siginfo_t *si = (siginfo_t *) (uintptr_t) 0x1234;
+ int ret, w;
+ pid_t pid;
+
+ pid = fork();
+ if (!pid) {
+ child(200000);
+ exit(0);
+ }
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_waitid(sqe, P_PID, pid, si, WEXITED, 0);
+ sqe->user_data = 1;
+ io_uring_submit(ring);
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "cqe wait: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ if (cqe->res != -EFAULT) {
+ fprintf(stderr, "Bad return on invalid infop: %d\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ wait(&w);
+ return T_EXIT_PASS;
+}
+
/*
* Test linked timeout with child not exiting in time
*/
@@ -28,9 +61,9 @@ static int test_noexit(struct io_uring *ring)
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
struct __kernel_timespec ts;
+ int ret, i, w;
siginfo_t si;
pid_t pid;
- int ret, i;
pid = fork();
if (!pid) {
@@ -68,6 +101,7 @@ static int test_noexit(struct io_uring *ring)
io_uring_cqe_seen(ring, cqe);
}
+ wait(&w);
return T_EXIT_PASS;
}
@@ -80,7 +114,7 @@ static int test_double(struct io_uring *ring)
struct io_uring_cqe *cqe;
siginfo_t si;
pid_t p1, p2;
- int ret;
+ int ret, w;
/* p1 will exit shortly */
p1 = fork();
@@ -117,6 +151,7 @@ static int test_double(struct io_uring *ring)
}
io_uring_cqe_seen(ring, cqe);
+ wait(&w);
return T_EXIT_PASS;
}
@@ -168,7 +203,7 @@ static int test_cancel(struct io_uring *ring)
{
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
- int ret, i;
+ int ret, i, w;
pid_t pid;
pid = fork();
@@ -206,6 +241,7 @@ static int test_cancel(struct io_uring *ring)
io_uring_cqe_seen(ring, cqe);
}
+ wait(&w);
return T_EXIT_PASS;
}
@@ -217,10 +253,12 @@ static int test_cancel_race(struct io_uring *ring, int async)
{
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
- int ret, i;
+ int ret, i, to_wait, total_forks;
pid_t pid;
+ total_forks = 0;
for (i = 0; i < 10; i++) {
+ total_forks++;
pid = fork();
if (!pid) {
child(getpid() & 1);
@@ -244,16 +282,20 @@ static int test_cancel_race(struct io_uring *ring, int async)
io_uring_submit(ring);
+ to_wait = total_forks;
for (i = 0; i < 2; i++) {
ret = io_uring_wait_cqe(ring, &cqe);
if (ret) {
fprintf(stderr, "cqe wait: %d\n", ret);
return T_EXIT_FAIL;
}
- if (cqe->user_data == 1 && !(cqe->res == -ECANCELED ||
- cqe->res == 0)) {
- fprintf(stderr, "cqe1 res: %d\n", cqe->res);
- return T_EXIT_FAIL;
+ if (cqe->user_data == 1) {
+ if (!cqe->res)
+ to_wait--;
+ if (!(cqe->res == -ECANCELED || cqe->res == 0)) {
+ fprintf(stderr, "cqe1 res: %d\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
}
if (cqe->user_data == 2 &&
!(cqe->res == 1 || cqe->res == 0 || cqe->res == -ENOENT ||
@@ -264,6 +306,12 @@ static int test_cancel_race(struct io_uring *ring, int async)
io_uring_cqe_seen(ring, cqe);
}
+ for (i = 0; i < to_wait; i++) {
+ int w;
+
+ wait(&w);
+ }
+
return T_EXIT_PASS;
}
@@ -361,6 +409,12 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
+ ret = test_invalid_infop(&ring);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test_invalid_infop failed\n");
+ return T_EXIT_FAIL;
+ }
+
for (i = 0; i < 1000; i++) {
ret = test_cancel_race(&ring, i & 1);
if (ret == T_EXIT_FAIL) {
diff --git a/contrib/libs/liburing/test/waitid.t/ya.make b/contrib/libs/liburing/test/waitid.t/ya.make
index d1b66baa8b..e3b160a48b 100644
--- a/contrib/libs/liburing/test/waitid.t/ya.make
+++ b/contrib/libs/liburing/test/waitid.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/wakeup-hang.t/ya.make b/contrib/libs/liburing/test/wakeup-hang.t/ya.make
index 32f72dadef..0dbdefae8c 100644
--- a/contrib/libs/liburing/test/wakeup-hang.t/ya.make
+++ b/contrib/libs/liburing/test/wakeup-hang.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/wq-aff.c b/contrib/libs/liburing/test/wq-aff.c
index 0548d6a698..0d3c10d3ef 100644
--- a/contrib/libs/liburing/test/wq-aff.c
+++ b/contrib/libs/liburing/test/wq-aff.c
@@ -128,6 +128,33 @@ static int test(int sqpoll)
return ret;
}
+static int test_invalid_cpu(void)
+{
+ struct io_uring_params p = { };
+ struct io_uring ring;
+ int ret, nr_cpus;
+
+ nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ if (nr_cpus < 0) {
+ perror("sysconf(_SC_NPROCESSORS_ONLN");
+ return T_EXIT_SKIP;
+ }
+
+ p.flags = IORING_SETUP_SQPOLL | IORING_SETUP_SQ_AFF;
+ p.sq_thread_cpu = 16 * nr_cpus;
+
+ ret = io_uring_queue_init_params(8, &ring, &p);
+ if (ret == -EPERM) {
+ return T_EXIT_SKIP;
+ } else if (ret != -EINVAL) {
+ fprintf(stderr, "Queue init: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_queue_exit(&ring);
+ return T_EXIT_PASS;
+}
+
int main(int argc, char *argv[])
{
int ret;
@@ -135,6 +162,14 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
+ ret = test_invalid_cpu();
+ if (ret == T_EXIT_SKIP) {
+ return T_EXIT_SKIP;
+ } else if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "test sqpoll cpu failed\n");
+ return T_EXIT_FAIL;
+ }
+
ret = test(1);
if (ret == T_EXIT_SKIP) {
return T_EXIT_SKIP;
diff --git a/contrib/libs/liburing/test/wq-aff.t/ya.make b/contrib/libs/liburing/test/wq-aff.t/ya.make
index fc8c72502a..28c8e06301 100644
--- a/contrib/libs/liburing/test/wq-aff.t/ya.make
+++ b/contrib/libs/liburing/test/wq-aff.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/test/xattr.t/ya.make b/contrib/libs/liburing/test/xattr.t/ya.make
index 9a4d76006a..1ef224a2df 100644
--- a/contrib/libs/liburing/test/xattr.t/ya.make
+++ b/contrib/libs/liburing/test/xattr.t/ya.make
@@ -4,7 +4,7 @@ PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(2.7)
+VERSION(2.8)
LICENSE(MIT)
diff --git a/contrib/libs/liburing/ya.make b/contrib/libs/liburing/ya.make
index 9ee5aee27d..776c355623 100644
--- a/contrib/libs/liburing/ya.make
+++ b/contrib/libs/liburing/ya.make
@@ -2,9 +2,9 @@
LIBRARY()
-VERSION(2.7)
+VERSION(2.8)
-ORIGINAL_SOURCE(https://github.com/axboe/liburing/archive/liburing-2.7.tar.gz)
+ORIGINAL_SOURCE(https://github.com/axboe/liburing/archive/liburing-2.8.tar.gz)
LICENSE(
"(GPL-2.0-only WITH Linux-syscall-note OR MIT)" AND
@@ -60,6 +60,7 @@ RECURSE(
test/buf-ring.t
test/ce593a6c480a.t
test/close-opath.t
+ test/cmd-discard.t
test/connect-rep.t
test/connect.t
test/coredump.t
@@ -90,6 +91,8 @@ RECURSE(
test/fc2a85cb02ef.t
test/fd-install.t
test/fd-pass.t
+ test/fdinfo.t
+ test/fifo-nonblock-read.t
test/file-register.t
test/file-update.t
test/file-verify.t
@@ -114,18 +117,23 @@ RECURSE(
test/iopoll-leak.t
test/iopoll-overflow.t
test/iopoll.t
+ test/kallsyms.t
test/lfs-openat-write.t
test/lfs-openat.t
test/link-timeout.t
test/link.t
test/link_drain.t
+ test/linked-defer-close.t
test/madvise.t
+ test/min-timeout-wait.t
+ test/min-timeout.t
test/mkdir.t
test/msg-ring-fd.t
test/msg-ring-flags.t
test/msg-ring-overflow.t
test/msg-ring.t
test/multicqes_drain.t
+ test/napi-test.t
test/no-mmap-inval.t
test/nolibc.t
test/nop-all-sizes.t
@@ -151,18 +159,22 @@ RECURSE(
test/poll-ring.t
test/poll-v-poll.t
test/poll.t
+ test/pollfree.t
test/probe.t
test/read-before-exit.t
test/read-mshot-empty.t
+ test/read-mshot-stdin.t
test/read-mshot.t
test/read-write.t
test/recv-msgall-stream.t
test/recv-msgall.t
test/recv-multishot.t
+ test/recvsend_bundle-inc.t
test/recvsend_bundle.t
test/reg-fd-only.t
test/reg-hint.t
test/reg-reg-ring.t
+ test/regbuf-clone.t
test/regbuf-merge.t
test/register-restrictions.t
test/rename.t
@@ -199,6 +211,7 @@ RECURSE(
test/sqpoll-exec.t
test/sqpoll-exit-hang.t
test/sqpoll-sleep.t
+ test/sqwait.t
test/stdout.t
test/submit-and-wait.t
test/submit-link-fail.t
@@ -212,7 +225,9 @@ RECURSE(
test/truncate.t
test/tty-write-dpoll.t
test/unlink.t
+ test/uring_cmd_ublk.t
test/version.t
+ test/wait-timeout.t
test/waitid.t
test/wakeup-hang.t
test/wq-aff.t