uringmachine 0.3 → 0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +2 -1
- data/CHANGELOG.md +23 -0
- data/README.md +128 -0
- data/TODO.md +14 -0
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/echo_server.rb +18 -40
- data/examples/http_server.rb +42 -43
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +24 -23
- data/ext/um/um.c +524 -278
- data/ext/um/um.h +146 -44
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +217 -106
- data/ext/um/um_const.c +213 -0
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +86 -114
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +49 -4
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +28 -0
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +8 -0
- data/test/test_um.rb +685 -46
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +6 -0
- data/vendor/liburing/CHANGELOG +16 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +64 -0
- data/vendor/liburing/examples/Makefile +9 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +77 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +59 -6
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +16 -0
- data/vendor/liburing/src/liburing.map +10 -0
- data/vendor/liburing/src/queue.c +28 -16
- data/vendor/liburing/src/register.c +106 -1
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +47 -19
- data/vendor/liburing/src/setup.h +6 -0
- data/vendor/liburing/test/35fa71a030ca.c +7 -0
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
- data/vendor/liburing/test/917257daa0fe.c +7 -0
- data/vendor/liburing/test/Makefile +38 -4
- data/vendor/liburing/test/a0908ae19763.c +7 -0
- data/vendor/liburing/test/a4c0b3decb33.c +7 -0
- data/vendor/liburing/test/accept.c +14 -4
- data/vendor/liburing/test/b19062a56726.c +7 -0
- data/vendor/liburing/test/bind-listen.c +2 -2
- data/vendor/liburing/test/buf-ring-nommap.c +10 -3
- data/vendor/liburing/test/buf-ring.c +2 -0
- data/vendor/liburing/test/cmd-discard.c +427 -0
- data/vendor/liburing/test/coredump.c +7 -0
- data/vendor/liburing/test/cq-overflow.c +13 -1
- data/vendor/liburing/test/d4ae271dfaae.c +11 -3
- data/vendor/liburing/test/defer-taskrun.c +2 -2
- data/vendor/liburing/test/defer-tw-timeout.c +4 -1
- data/vendor/liburing/test/defer.c +2 -2
- data/vendor/liburing/test/double-poll-crash.c +1 -1
- data/vendor/liburing/test/eeed8b54e0df.c +2 -0
- data/vendor/liburing/test/eventfd.c +0 -1
- data/vendor/liburing/test/exit-no-cleanup.c +11 -0
- data/vendor/liburing/test/fadvise.c +9 -26
- data/vendor/liburing/test/fdinfo.c +9 -1
- data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- data/vendor/liburing/test/file-register.c +14 -2
- data/vendor/liburing/test/file-update.c +1 -1
- data/vendor/liburing/test/file-verify.c +27 -16
- data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
- data/vendor/liburing/test/fixed-buf-iter.c +3 -1
- data/vendor/liburing/test/fixed-hugepage.c +12 -1
- data/vendor/liburing/test/fsnotify.c +1 -0
- data/vendor/liburing/test/futex.c +16 -4
- data/vendor/liburing/test/helpers.c +47 -0
- data/vendor/liburing/test/helpers.h +6 -0
- data/vendor/liburing/test/init-mem.c +5 -3
- data/vendor/liburing/test/io-cancel.c +0 -24
- data/vendor/liburing/test/io_uring_passthrough.c +4 -0
- data/vendor/liburing/test/io_uring_register.c +38 -8
- data/vendor/liburing/test/iopoll-leak.c +4 -0
- data/vendor/liburing/test/iopoll-overflow.c +1 -1
- data/vendor/liburing/test/iopoll.c +3 -3
- data/vendor/liburing/test/kallsyms.c +203 -0
- data/vendor/liburing/test/link-timeout.c +159 -0
- data/vendor/liburing/test/linked-defer-close.c +224 -0
- data/vendor/liburing/test/madvise.c +12 -25
- data/vendor/liburing/test/min-timeout-wait.c +0 -25
- data/vendor/liburing/test/min-timeout.c +0 -25
- data/vendor/liburing/test/mkdir.c +6 -0
- data/vendor/liburing/test/msg-ring.c +8 -2
- data/vendor/liburing/test/napi-test.c +16 -3
- data/vendor/liburing/test/no-mmap-inval.c +3 -1
- data/vendor/liburing/test/nop.c +44 -0
- data/vendor/liburing/test/ooo-file-unreg.c +1 -1
- data/vendor/liburing/test/open-close.c +40 -0
- data/vendor/liburing/test/openat2.c +37 -14
- data/vendor/liburing/test/poll-many.c +13 -7
- data/vendor/liburing/test/poll-mshot-update.c +17 -10
- data/vendor/liburing/test/poll-v-poll.c +6 -3
- data/vendor/liburing/test/pollfree.c +148 -0
- data/vendor/liburing/test/read-mshot-empty.c +158 -153
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +282 -27
- data/vendor/liburing/test/read-write.c +78 -13
- data/vendor/liburing/test/recv-msgall-stream.c +3 -0
- data/vendor/liburing/test/recv-msgall.c +5 -0
- data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
- data/vendor/liburing/test/recvsend_bundle.c +94 -31
- data/vendor/liburing/test/reg-fd-only.c +15 -5
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +645 -0
- data/vendor/liburing/test/regbuf-merge.c +7 -0
- data/vendor/liburing/test/register-restrictions.c +86 -85
- data/vendor/liburing/test/rename.c +59 -1
- data/vendor/liburing/test/resize-rings.c +643 -0
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/rsrc_tags.c +1 -1
- data/vendor/liburing/test/runtests.sh +16 -1
- data/vendor/liburing/test/send-zerocopy.c +59 -0
- data/vendor/liburing/test/short-read.c +1 -0
- data/vendor/liburing/test/socket.c +43 -0
- data/vendor/liburing/test/splice.c +3 -1
- data/vendor/liburing/test/sq-poll-dup.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +2 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
- data/vendor/liburing/test/sqpoll-sleep.c +40 -33
- data/vendor/liburing/test/sqwait.c +136 -0
- data/vendor/liburing/test/statx.c +89 -0
- data/vendor/liburing/test/stdout.c +2 -0
- data/vendor/liburing/test/submit-and-wait.c +1 -25
- data/vendor/liburing/test/submit-reuse.c +4 -26
- data/vendor/liburing/test/symlink.c +12 -1
- data/vendor/liburing/test/sync-cancel.c +56 -22
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +25 -34
- data/vendor/liburing/test/unlink.c +94 -1
- data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
- data/vendor/liburing/test/waitid.c +62 -8
- data/vendor/liburing/test/wq-aff.c +35 -0
- data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
- data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
- metadata +37 -6
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
@@ -0,0 +1,427 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <assert.h>
|
5
|
+
#include <string.h>
|
6
|
+
#include <unistd.h>
|
7
|
+
#include <stdlib.h>
|
8
|
+
#include <sys/ioctl.h>
|
9
|
+
#include <linux/fs.h>
|
10
|
+
|
11
|
+
#include "liburing.h"
|
12
|
+
#include "helpers.h"
|
13
|
+
|
14
|
+
#define MAX_TEST_LBAS 1024
|
15
|
+
|
16
|
+
static const char *filename;
|
17
|
+
struct opcode {
|
18
|
+
int op;
|
19
|
+
bool test;
|
20
|
+
bool not_supported;
|
21
|
+
};
|
22
|
+
|
23
|
+
#define TEST_BLOCK_URING_CMD_MAX 3
|
24
|
+
|
25
|
+
static struct opcode opcodes[TEST_BLOCK_URING_CMD_MAX] = {
|
26
|
+
{ .op = BLOCK_URING_CMD_DISCARD, .test = true, },
|
27
|
+
{ .test = false, },
|
28
|
+
{ .test = false, },
|
29
|
+
};
|
30
|
+
|
31
|
+
static int lba_size;
|
32
|
+
static uint64_t bdev_size;
|
33
|
+
static uint64_t bdev_size_lbas;
|
34
|
+
static char *buffer;
|
35
|
+
|
36
|
+
static void prep_blk_cmd(struct io_uring_sqe *sqe, int fd,
|
37
|
+
uint64_t from, uint64_t len,
|
38
|
+
int cmd_op)
|
39
|
+
{
|
40
|
+
assert(cmd_op == BLOCK_URING_CMD_DISCARD);
|
41
|
+
|
42
|
+
io_uring_prep_cmd_discard(sqe, fd, from, len);
|
43
|
+
}
|
44
|
+
|
45
|
+
static int queue_cmd_range(struct io_uring *ring, int bdev_fd,
|
46
|
+
uint64_t from, uint64_t len, int cmd_op)
|
47
|
+
{
|
48
|
+
struct io_uring_sqe *sqe;
|
49
|
+
struct io_uring_cqe *cqe;
|
50
|
+
int err;
|
51
|
+
|
52
|
+
sqe = io_uring_get_sqe(ring);
|
53
|
+
assert(sqe != NULL);
|
54
|
+
prep_blk_cmd(sqe, bdev_fd, from, len, cmd_op);
|
55
|
+
|
56
|
+
err = io_uring_submit_and_wait(ring, 1);
|
57
|
+
if (err != 1) {
|
58
|
+
fprintf(stderr, "io_uring_submit_and_wait failed %d\n", err);
|
59
|
+
exit(1);
|
60
|
+
}
|
61
|
+
|
62
|
+
err = io_uring_wait_cqe(ring, &cqe);
|
63
|
+
if (err) {
|
64
|
+
fprintf(stderr, "io_uring_wait_cqe failed %d (op %i)\n",
|
65
|
+
err, cmd_op);
|
66
|
+
exit(1);
|
67
|
+
}
|
68
|
+
|
69
|
+
err = cqe->res;
|
70
|
+
io_uring_cqe_seen(ring, cqe);
|
71
|
+
return err;
|
72
|
+
}
|
73
|
+
|
74
|
+
static int queue_cmd_lba(struct io_uring *ring, int bdev_fd,
|
75
|
+
uint64_t from, uint64_t nr_lba, int cmd_op)
|
76
|
+
{
|
77
|
+
return queue_cmd_range(ring, bdev_fd, from * lba_size,
|
78
|
+
nr_lba * lba_size, cmd_op);
|
79
|
+
}
|
80
|
+
|
81
|
+
static int queue_discard_lba(struct io_uring *ring, int bdev_fd,
|
82
|
+
uint64_t from, uint64_t nr_lba)
|
83
|
+
{
|
84
|
+
return queue_cmd_lba(ring, bdev_fd, from, nr_lba,
|
85
|
+
BLOCK_URING_CMD_DISCARD);
|
86
|
+
}
|
87
|
+
|
88
|
+
static int test_parallel(struct io_uring *ring, int fd, int cmd_op)
|
89
|
+
{
|
90
|
+
struct io_uring_sqe *sqe;
|
91
|
+
struct io_uring_cqe *cqe;
|
92
|
+
int inflight = 0;
|
93
|
+
int max_inflight = 16;
|
94
|
+
int left = 1000;
|
95
|
+
int ret;
|
96
|
+
|
97
|
+
while (left || inflight) {
|
98
|
+
int queued = 0;
|
99
|
+
unsigned head, nr_cqes = 0;
|
100
|
+
int lba_len = 8;
|
101
|
+
|
102
|
+
while (inflight < max_inflight && left) {
|
103
|
+
int off = rand() % (MAX_TEST_LBAS - lba_len);
|
104
|
+
sqe = io_uring_get_sqe(ring);
|
105
|
+
assert(sqe != NULL);
|
106
|
+
|
107
|
+
prep_blk_cmd(sqe, fd, off * lba_size,
|
108
|
+
lba_len * lba_size, cmd_op);
|
109
|
+
if (rand() & 1)
|
110
|
+
sqe->flags |= IOSQE_ASYNC;
|
111
|
+
|
112
|
+
queued++;
|
113
|
+
left--;
|
114
|
+
inflight++;
|
115
|
+
}
|
116
|
+
if (queued) {
|
117
|
+
ret = io_uring_submit(ring);
|
118
|
+
if (ret != queued) {
|
119
|
+
fprintf(stderr, "io_uring_submit failed %d\n", ret);
|
120
|
+
return T_EXIT_FAIL;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
125
|
+
if (ret) {
|
126
|
+
fprintf(stderr, "io_uring_wait_cqe failed %d\n", ret);
|
127
|
+
exit(1);
|
128
|
+
}
|
129
|
+
|
130
|
+
io_uring_for_each_cqe(ring, head, cqe) {
|
131
|
+
nr_cqes++;
|
132
|
+
inflight--;
|
133
|
+
if (cqe->res != 0) {
|
134
|
+
fprintf(stderr, "cmd %i failed %i\n", cmd_op,
|
135
|
+
cqe->res);
|
136
|
+
return T_EXIT_FAIL;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
io_uring_cq_advance(ring, nr_cqes);
|
140
|
+
}
|
141
|
+
|
142
|
+
return 0;
|
143
|
+
}
|
144
|
+
|
145
|
+
static int cmd_issue_verify(struct io_uring *ring, int fd, int lba, int len,
|
146
|
+
int cmd_op)
|
147
|
+
{
|
148
|
+
int verify = (cmd_op != BLOCK_URING_CMD_DISCARD);
|
149
|
+
int ret, i;
|
150
|
+
ssize_t res;
|
151
|
+
|
152
|
+
if (verify) {
|
153
|
+
for (i = 0; i < len; i++) {
|
154
|
+
size_t off = (i + lba) * lba_size;
|
155
|
+
|
156
|
+
res = pwrite(fd, buffer, lba_size, off);
|
157
|
+
if (res == -1) {
|
158
|
+
fprintf(stderr, "pwrite failed\n");
|
159
|
+
return T_EXIT_FAIL;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
ret = queue_cmd_lba(ring, fd, lba, len, cmd_op);
|
165
|
+
if (ret) {
|
166
|
+
if (ret == -EINVAL || ret == -EOPNOTSUPP)
|
167
|
+
return T_EXIT_SKIP;
|
168
|
+
|
169
|
+
fprintf(stderr, "cmd_issue_verify %i fail lba %i len %i ret %i\n",
|
170
|
+
cmd_op, lba, len, ret);
|
171
|
+
return T_EXIT_FAIL;
|
172
|
+
}
|
173
|
+
|
174
|
+
if (verify) {
|
175
|
+
for (i = 0; i < len; i++) {
|
176
|
+
size_t off = (i + lba) * lba_size;
|
177
|
+
|
178
|
+
res = pread(fd, buffer, lba_size, off);
|
179
|
+
if (res == -1) {
|
180
|
+
fprintf(stderr, "pread failed\n");
|
181
|
+
return T_EXIT_FAIL;
|
182
|
+
}
|
183
|
+
if (!memchr(buffer, 0, lba_size)) {
|
184
|
+
fprintf(stderr, "mem cmp failed, lba %i\n", lba + i);
|
185
|
+
return T_EXIT_FAIL;
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
return 0;
|
190
|
+
}
|
191
|
+
|
192
|
+
static int basic_cmd_test(struct io_uring *ring, int op)
|
193
|
+
{
|
194
|
+
int cmd_op = opcodes[op].op;
|
195
|
+
int ret, fd;
|
196
|
+
|
197
|
+
if (!opcodes[op].test)
|
198
|
+
return T_EXIT_SKIP;
|
199
|
+
|
200
|
+
fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
|
201
|
+
if (fd < 0) {
|
202
|
+
if (errno == -EINVAL || errno == -EBUSY)
|
203
|
+
return T_EXIT_SKIP;
|
204
|
+
fprintf(stderr, "open failed %i\n", errno);
|
205
|
+
return T_EXIT_FAIL;
|
206
|
+
}
|
207
|
+
|
208
|
+
ret = cmd_issue_verify(ring, fd, 0, 1, cmd_op);
|
209
|
+
if (ret == T_EXIT_SKIP) {
|
210
|
+
printf("cmd %i not supported, skip\n", cmd_op);
|
211
|
+
opcodes[op].not_supported = 1;
|
212
|
+
close(fd);
|
213
|
+
return T_EXIT_SKIP;
|
214
|
+
} else if (ret) {
|
215
|
+
fprintf(stderr, "cmd %i fail 0 1\n", cmd_op);
|
216
|
+
return T_EXIT_FAIL;
|
217
|
+
}
|
218
|
+
|
219
|
+
ret = cmd_issue_verify(ring, fd, 7, 15, cmd_op);
|
220
|
+
if (ret) {
|
221
|
+
fprintf(stderr, "cmd %i fail 7 15 %i\n", cmd_op, ret);
|
222
|
+
return T_EXIT_FAIL;
|
223
|
+
}
|
224
|
+
|
225
|
+
ret = cmd_issue_verify(ring, fd, 1, MAX_TEST_LBAS - 1, cmd_op);
|
226
|
+
if (ret) {
|
227
|
+
fprintf(stderr, "large cmd %i failed %i\n", cmd_op, ret);
|
228
|
+
return T_EXIT_FAIL;
|
229
|
+
}
|
230
|
+
|
231
|
+
ret = test_parallel(ring, fd, cmd_op);
|
232
|
+
if (ret) {
|
233
|
+
fprintf(stderr, "test_parallel() %i failed %i\n", cmd_op, ret);
|
234
|
+
return T_EXIT_FAIL;
|
235
|
+
}
|
236
|
+
|
237
|
+
close(fd);
|
238
|
+
return 0;
|
239
|
+
}
|
240
|
+
|
241
|
+
static int test_fail_edge_cases(struct io_uring *ring, int op)
|
242
|
+
{
|
243
|
+
int cmd_op = opcodes[op].op;
|
244
|
+
int ret, fd;
|
245
|
+
|
246
|
+
if (!opcodes[op].test)
|
247
|
+
return T_EXIT_SKIP;
|
248
|
+
|
249
|
+
fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
|
250
|
+
if (fd < 0) {
|
251
|
+
fprintf(stderr, "open failed %i\n", errno);
|
252
|
+
return T_EXIT_FAIL;
|
253
|
+
}
|
254
|
+
|
255
|
+
ret = queue_cmd_lba(ring, fd, bdev_size_lbas, 1, cmd_op);
|
256
|
+
if (ret >= 0) {
|
257
|
+
fprintf(stderr, "cmd %i beyond capacity %i\n",
|
258
|
+
cmd_op, ret);
|
259
|
+
return 1;
|
260
|
+
}
|
261
|
+
|
262
|
+
ret = queue_cmd_lba(ring, fd, bdev_size_lbas - 1, 2, cmd_op);
|
263
|
+
if (ret >= 0) {
|
264
|
+
fprintf(stderr, "cmd %i beyond capacity with overlap %i\n",
|
265
|
+
cmd_op, ret);
|
266
|
+
return 1;
|
267
|
+
}
|
268
|
+
|
269
|
+
ret = queue_cmd_range(ring, fd, (uint64_t)-lba_size, lba_size + 2,
|
270
|
+
cmd_op);
|
271
|
+
if (ret >= 0) {
|
272
|
+
fprintf(stderr, "cmd %i range overflow %i\n",
|
273
|
+
cmd_op, ret);
|
274
|
+
return 1;
|
275
|
+
}
|
276
|
+
|
277
|
+
ret = queue_cmd_range(ring, fd, lba_size / 2, lba_size, cmd_op);
|
278
|
+
if (ret >= 0) {
|
279
|
+
fprintf(stderr, "cmd %i unaligned offset %i\n",
|
280
|
+
cmd_op, ret);
|
281
|
+
return 1;
|
282
|
+
}
|
283
|
+
|
284
|
+
ret = queue_cmd_range(ring, fd, 0, lba_size / 2, cmd_op);
|
285
|
+
if (ret >= 0) {
|
286
|
+
fprintf(stderr, "cmd %i unaligned size %i\n",
|
287
|
+
cmd_op, ret);
|
288
|
+
return 1;
|
289
|
+
}
|
290
|
+
|
291
|
+
close(fd);
|
292
|
+
return 0;
|
293
|
+
}
|
294
|
+
|
295
|
+
static int test_rdonly(struct io_uring *ring, int op)
|
296
|
+
{
|
297
|
+
int ret, fd;
|
298
|
+
int ro;
|
299
|
+
|
300
|
+
if (!opcodes[op].test)
|
301
|
+
return T_EXIT_SKIP;
|
302
|
+
|
303
|
+
fd = open(filename, O_DIRECT | O_RDONLY | O_EXCL);
|
304
|
+
if (fd < 0) {
|
305
|
+
fprintf(stderr, "open failed %i\n", errno);
|
306
|
+
return T_EXIT_FAIL;
|
307
|
+
}
|
308
|
+
|
309
|
+
ret = queue_discard_lba(ring, fd, 0, 1);
|
310
|
+
if (ret >= 0) {
|
311
|
+
fprintf(stderr, "discarded with O_RDONLY %i\n", ret);
|
312
|
+
return 1;
|
313
|
+
}
|
314
|
+
close(fd);
|
315
|
+
|
316
|
+
fd = open(filename, O_DIRECT | O_RDWR | O_EXCL);
|
317
|
+
if (fd < 0) {
|
318
|
+
fprintf(stderr, "open failed %i\n", errno);
|
319
|
+
return T_EXIT_FAIL;
|
320
|
+
}
|
321
|
+
|
322
|
+
ro = 1;
|
323
|
+
ret = ioctl(fd, BLKROSET, &ro);
|
324
|
+
if (ret) {
|
325
|
+
fprintf(stderr, "BLKROSET 1 failed %i\n", errno);
|
326
|
+
return T_EXIT_FAIL;
|
327
|
+
}
|
328
|
+
|
329
|
+
ret = queue_discard_lba(ring, fd, 0, 1);
|
330
|
+
if (ret >= 0) {
|
331
|
+
fprintf(stderr, "discarded with O_RDONLY %i\n", ret);
|
332
|
+
return 1;
|
333
|
+
}
|
334
|
+
|
335
|
+
ro = 0;
|
336
|
+
ret = ioctl(fd, BLKROSET, &ro);
|
337
|
+
if (ret) {
|
338
|
+
fprintf(stderr, "BLKROSET 0 failed %i\n", errno);
|
339
|
+
return T_EXIT_FAIL;
|
340
|
+
}
|
341
|
+
close(fd);
|
342
|
+
return 0;
|
343
|
+
}
|
344
|
+
|
345
|
+
int main(int argc, char *argv[])
|
346
|
+
{
|
347
|
+
struct io_uring ring;
|
348
|
+
int fd, ret, i, fret;
|
349
|
+
int cmd_op;
|
350
|
+
|
351
|
+
if (argc != 2)
|
352
|
+
return T_EXIT_SKIP;
|
353
|
+
filename = argv[1];
|
354
|
+
|
355
|
+
fd = open(filename, O_DIRECT | O_RDONLY | O_EXCL);
|
356
|
+
if (fd < 0) {
|
357
|
+
fprintf(stderr, "open failed %i\n", errno);
|
358
|
+
return T_EXIT_FAIL;
|
359
|
+
}
|
360
|
+
|
361
|
+
ret = ioctl(fd, BLKGETSIZE64, &bdev_size);
|
362
|
+
if (ret < 0) {
|
363
|
+
fprintf(stderr, "BLKGETSIZE64 failed %i\n", errno);
|
364
|
+
return T_EXIT_FAIL;
|
365
|
+
}
|
366
|
+
ret = ioctl(fd, BLKSSZGET, &lba_size);
|
367
|
+
if (ret < 0) {
|
368
|
+
fprintf(stderr, "BLKSSZGET failed %i\n", errno);
|
369
|
+
return T_EXIT_FAIL;
|
370
|
+
}
|
371
|
+
assert(bdev_size % lba_size == 0);
|
372
|
+
bdev_size_lbas = bdev_size / lba_size;
|
373
|
+
close(fd);
|
374
|
+
|
375
|
+
buffer = aligned_alloc(lba_size, lba_size);
|
376
|
+
if (!buffer) {
|
377
|
+
fprintf(stderr, "aligned_alloc failed\n");
|
378
|
+
return T_EXIT_FAIL;
|
379
|
+
}
|
380
|
+
for (i = 0; i < lba_size; i++)
|
381
|
+
buffer[i] = i ^ 0xA7;
|
382
|
+
|
383
|
+
if (bdev_size_lbas < MAX_TEST_LBAS) {
|
384
|
+
fprintf(stderr, "the device is too small, skip\n");
|
385
|
+
return T_EXIT_SKIP;
|
386
|
+
}
|
387
|
+
|
388
|
+
ret = io_uring_queue_init(16, &ring, 0);
|
389
|
+
if (ret) {
|
390
|
+
fprintf(stderr, "queue init failed: %d\n", ret);
|
391
|
+
return T_EXIT_FAIL;
|
392
|
+
}
|
393
|
+
|
394
|
+
fret = T_EXIT_SKIP;
|
395
|
+
for (cmd_op = 0; cmd_op < TEST_BLOCK_URING_CMD_MAX; cmd_op++) {
|
396
|
+
if (!opcodes[cmd_op].test)
|
397
|
+
continue;
|
398
|
+
ret = basic_cmd_test(&ring, cmd_op);
|
399
|
+
if (ret) {
|
400
|
+
if (ret == T_EXIT_SKIP)
|
401
|
+
continue;
|
402
|
+
|
403
|
+
fprintf(stderr, "basic_cmd_test() failed, cmd %i\n",
|
404
|
+
cmd_op);
|
405
|
+
return T_EXIT_FAIL;
|
406
|
+
}
|
407
|
+
|
408
|
+
ret = test_rdonly(&ring, cmd_op);
|
409
|
+
if (ret) {
|
410
|
+
fprintf(stderr, "test_rdonly() failed, cmd %i\n",
|
411
|
+
cmd_op);
|
412
|
+
return T_EXIT_FAIL;
|
413
|
+
}
|
414
|
+
|
415
|
+
ret = test_fail_edge_cases(&ring, cmd_op);
|
416
|
+
if (ret) {
|
417
|
+
fprintf(stderr, "test_fail_edge_cases() failed, cmd %i\n",
|
418
|
+
cmd_op);
|
419
|
+
return T_EXIT_FAIL;
|
420
|
+
}
|
421
|
+
fret = T_EXIT_PASS;
|
422
|
+
}
|
423
|
+
|
424
|
+
io_uring_queue_exit(&ring);
|
425
|
+
free(buffer);
|
426
|
+
return fret;
|
427
|
+
}
|
@@ -16,6 +16,7 @@
|
|
16
16
|
#include "liburing.h"
|
17
17
|
#include "helpers.h"
|
18
18
|
|
19
|
+
#ifndef CONFIG_USE_SANITIZER
|
19
20
|
static void test(void)
|
20
21
|
{
|
21
22
|
struct io_uring_sqe *sqe;
|
@@ -58,3 +59,9 @@ int main(int argc, char *argv[])
|
|
58
59
|
unlink("core");
|
59
60
|
return T_EXIT_PASS;
|
60
61
|
}
|
62
|
+
#else
|
63
|
+
int main(int argc, char *argv[])
|
64
|
+
{
|
65
|
+
return T_EXIT_SKIP;
|
66
|
+
}
|
67
|
+
#endif
|
@@ -88,8 +88,10 @@ static int test_io(const char *file, unsigned long usecs, unsigned *drops,
|
|
88
88
|
goto err;
|
89
89
|
}
|
90
90
|
offset = BS * (rand() % BUFFERS);
|
91
|
-
if (fault && i == ENTRIES + 4)
|
91
|
+
if (fault && i == ENTRIES + 4) {
|
92
|
+
free(vecs[i].iov_base);
|
92
93
|
vecs[i].iov_base = NULL;
|
94
|
+
}
|
93
95
|
io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
|
94
96
|
|
95
97
|
ret = io_uring_submit(&ring);
|
@@ -523,8 +525,18 @@ int main(int argc, char *argv[])
|
|
523
525
|
}
|
524
526
|
|
525
527
|
unlink(fname);
|
528
|
+
if(vecs != NULL) {
|
529
|
+
for (i = 0; i < BUFFERS; i++)
|
530
|
+
free(vecs[i].iov_base);
|
531
|
+
}
|
532
|
+
free(vecs);
|
526
533
|
return T_EXIT_PASS;
|
527
534
|
err:
|
528
535
|
unlink(fname);
|
536
|
+
if(vecs != NULL) {
|
537
|
+
for (i = 0; i < BUFFERS; i++)
|
538
|
+
free(vecs[i].iov_base);
|
539
|
+
}
|
540
|
+
free(vecs);
|
529
541
|
return T_EXIT_FAIL;
|
530
542
|
}
|
@@ -19,10 +19,10 @@
|
|
19
19
|
int main(int argc, char *argv[])
|
20
20
|
{
|
21
21
|
struct io_uring ring;
|
22
|
-
int i, fd, ret;
|
22
|
+
int i, fd, ret, __e;
|
23
23
|
struct io_uring_sqe *sqe;
|
24
24
|
struct io_uring_cqe *cqe;
|
25
|
-
struct iovec *iovecs;
|
25
|
+
struct iovec *iovecs = NULL;
|
26
26
|
struct io_uring_params p;
|
27
27
|
char *fname;
|
28
28
|
void *buf;
|
@@ -43,10 +43,13 @@ int main(int argc, char *argv[])
|
|
43
43
|
}
|
44
44
|
|
45
45
|
fd = open(fname, O_RDONLY | O_DIRECT);
|
46
|
+
__e = errno;
|
46
47
|
if (fname != argv[1])
|
47
48
|
unlink(fname);
|
48
49
|
if (fd < 0) {
|
49
|
-
|
50
|
+
if (__e == EINVAL || __e == EPERM || __e == EACCES)
|
51
|
+
return T_EXIT_SKIP;
|
52
|
+
fprintf(stderr, "open: %s\n", strerror(__e));
|
50
53
|
goto out;
|
51
54
|
}
|
52
55
|
|
@@ -92,5 +95,10 @@ int main(int argc, char *argv[])
|
|
92
95
|
close(fd);
|
93
96
|
out:
|
94
97
|
io_uring_queue_exit(&ring);
|
98
|
+
if (iovecs != NULL) { //
|
99
|
+
for (i = 0; i < 10; i++)
|
100
|
+
free(iovecs[i].iov_base);
|
101
|
+
free(iovecs);
|
102
|
+
}
|
95
103
|
return ret;
|
96
104
|
}
|
@@ -196,12 +196,12 @@ static int test_exec(const char *filename)
|
|
196
196
|
|
197
197
|
if (filename) {
|
198
198
|
fd = open(filename, O_RDONLY | O_DIRECT);
|
199
|
-
if (fd < 0 && errno == EINVAL)
|
199
|
+
if (fd < 0 && (errno == EINVAL || errno == EPERM || errno == EACCES))
|
200
200
|
return T_EXIT_SKIP;
|
201
201
|
} else {
|
202
202
|
t_create_file(EXEC_FILENAME, EXEC_FILESIZE);
|
203
203
|
fd = open(EXEC_FILENAME, O_RDONLY | O_DIRECT);
|
204
|
-
if (fd < 0 && errno == EINVAL) {
|
204
|
+
if (fd < 0 && (errno == EINVAL || errno == EPERM || errno == EACCES)) {
|
205
205
|
unlink(EXEC_FILENAME);
|
206
206
|
return T_EXIT_SKIP;
|
207
207
|
}
|
@@ -99,7 +99,7 @@ static int test_file(struct io_uring *ring, char *__fname)
|
|
99
99
|
|
100
100
|
fd = open(fname, O_RDONLY | O_DIRECT);
|
101
101
|
if (fd < 0) {
|
102
|
-
if (errno == EINVAL) {
|
102
|
+
if (errno == EINVAL || errno == EPERM || errno == EACCES) {
|
103
103
|
if (!__fname)
|
104
104
|
unlink(fname);
|
105
105
|
return T_EXIT_SKIP;
|
@@ -128,6 +128,7 @@ static int test_file(struct io_uring *ring, char *__fname)
|
|
128
128
|
if (ret != 1) {
|
129
129
|
fprintf(stderr, "unexpected wait ret %d\n", ret);
|
130
130
|
close(fd);
|
131
|
+
free(buf);
|
131
132
|
return T_EXIT_FAIL;
|
132
133
|
}
|
133
134
|
|
@@ -141,10 +142,12 @@ static int test_file(struct io_uring *ring, char *__fname)
|
|
141
142
|
if (i != 1) {
|
142
143
|
fprintf(stderr, "Got %d request, expected 1\n", i);
|
143
144
|
close(fd);
|
145
|
+
free(buf);
|
144
146
|
return T_EXIT_FAIL;
|
145
147
|
}
|
146
148
|
|
147
149
|
close(fd);
|
150
|
+
free(buf);
|
148
151
|
return T_EXIT_PASS;
|
149
152
|
}
|
150
153
|
|
@@ -96,7 +96,7 @@ static int test_canceled_userdata(struct io_uring *ring)
|
|
96
96
|
if (init_context(&ctx, ring, nr, OP_NOP))
|
97
97
|
return 1;
|
98
98
|
|
99
|
-
for (i = 0; i < nr; i++)
|
99
|
+
for (i = 0; i < nr - 1; i++)
|
100
100
|
ctx.sqes[i]->flags |= IOSQE_IO_LINK;
|
101
101
|
|
102
102
|
ret = io_uring_submit(ring);
|
@@ -130,7 +130,7 @@ static int test_thread_link_cancel(struct io_uring *ring)
|
|
130
130
|
if (init_context(&ctx, ring, nr, OP_REMOVE_BUFFERS))
|
131
131
|
return 1;
|
132
132
|
|
133
|
-
for (i = 0; i < nr; i++)
|
133
|
+
for (i = 0; i < nr - 1; i++)
|
134
134
|
ctx.sqes[i]->flags |= IOSQE_IO_LINK;
|
135
135
|
|
136
136
|
ret = io_uring_submit(ring);
|
@@ -114,7 +114,7 @@ static uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff};
|
|
114
114
|
int main(int argc, char *argv[])
|
115
115
|
{
|
116
116
|
void *mmap_ret;
|
117
|
-
#if !defined(__i386) && !defined(__x86_64__)
|
117
|
+
#if (!defined(__i386) && !defined(__x86_64__)) || defined(CONFIG_USE_SANITIZER)
|
118
118
|
return T_EXIT_SKIP;
|
119
119
|
#endif
|
120
120
|
|
@@ -19,6 +19,11 @@
|
|
19
19
|
#include "liburing.h"
|
20
20
|
#include "helpers.h"
|
21
21
|
|
22
|
+
// on fast enough machines with enough cores, the first few threads will post
|
23
|
+
// enough sem's to cause the main thread to exit while some threads are half way
|
24
|
+
// initialization. This causes a null deference somewhere in thread cleanup,
|
25
|
+
// which trips ASAN.
|
26
|
+
#ifndef CONFIG_USE_SANITIZER
|
22
27
|
#define IORING_ENTRIES 8
|
23
28
|
|
24
29
|
static pthread_t *threads;
|
@@ -115,3 +120,9 @@ int main(int argc, char *argv[])
|
|
115
120
|
// Exit without resource cleanup
|
116
121
|
exit(EXIT_SUCCESS);
|
117
122
|
}
|
123
|
+
#else
|
124
|
+
int main(int argc, char *argv[])
|
125
|
+
{
|
126
|
+
return T_EXIT_SKIP;
|
127
|
+
}
|
128
|
+
#endif
|
@@ -18,30 +18,6 @@
|
|
18
18
|
#define LOOPS 100
|
19
19
|
#define MIN_LOOPS 10
|
20
20
|
|
21
|
-
static unsigned long long utime_since(const struct timeval *s,
|
22
|
-
const struct timeval *e)
|
23
|
-
{
|
24
|
-
long long sec, usec;
|
25
|
-
|
26
|
-
sec = e->tv_sec - s->tv_sec;
|
27
|
-
usec = (e->tv_usec - s->tv_usec);
|
28
|
-
if (sec > 0 && usec < 0) {
|
29
|
-
sec--;
|
30
|
-
usec += 1000000;
|
31
|
-
}
|
32
|
-
|
33
|
-
sec *= 1000000;
|
34
|
-
return sec + usec;
|
35
|
-
}
|
36
|
-
|
37
|
-
static unsigned long long utime_since_now(struct timeval *tv)
|
38
|
-
{
|
39
|
-
struct timeval end;
|
40
|
-
|
41
|
-
gettimeofday(&end, NULL);
|
42
|
-
return utime_since(tv, &end);
|
43
|
-
}
|
44
|
-
|
45
21
|
static int do_fadvise(struct io_uring *ring, int fd, off_t offset, off_t len,
|
46
22
|
int advice)
|
47
23
|
{
|
@@ -92,7 +68,7 @@ static long do_read(int fd, char *buf)
|
|
92
68
|
perror("lseek");
|
93
69
|
return -1;
|
94
70
|
}
|
95
|
-
|
71
|
+
|
96
72
|
gettimeofday(&tv, NULL);
|
97
73
|
ret = read(fd, buf, FILE_SIZE);
|
98
74
|
t = utime_since_now(&tv);
|
@@ -115,6 +91,8 @@ static int test_fadvise(struct io_uring *ring, const char *filename)
|
|
115
91
|
|
116
92
|
fd = open(filename, O_RDONLY);
|
117
93
|
if (fd < 0) {
|
94
|
+
if (errno == EPERM || errno == EACCES)
|
95
|
+
return T_EXIT_SKIP;
|
118
96
|
perror("open");
|
119
97
|
return 1;
|
120
98
|
}
|
@@ -148,9 +126,12 @@ static int test_fadvise(struct io_uring *ring, const char *filename)
|
|
148
126
|
return 1;
|
149
127
|
|
150
128
|
if (cached_read < uncached_read &&
|
151
|
-
|
129
|
+
cached_read2 < uncached_read) {
|
130
|
+
free(buf);
|
152
131
|
return 0;
|
132
|
+
}
|
153
133
|
|
134
|
+
free(buf);
|
154
135
|
return 2;
|
155
136
|
}
|
156
137
|
|
@@ -174,6 +155,8 @@ int main(int argc, char *argv[])
|
|
174
155
|
good = bad = 0;
|
175
156
|
for (i = 0; i < LOOPS; i++) {
|
176
157
|
ret = test_fadvise(&ring, fname);
|
158
|
+
if (ret == T_EXIT_SKIP)
|
159
|
+
return T_EXIT_SKIP;
|
177
160
|
if (ret == 1) {
|
178
161
|
fprintf(stderr, "read_fadvise failed\n");
|
179
162
|
goto err;
|