uringmachine 0.3 → 0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +85 -0
  4. data/TODO.md +5 -0
  5. data/examples/echo_server.rb +18 -40
  6. data/examples/inout.rb +19 -0
  7. data/examples/nc.rb +36 -0
  8. data/ext/um/extconf.rb +6 -15
  9. data/ext/um/um.c +245 -53
  10. data/ext/um/um.h +21 -9
  11. data/ext/um/um_class.c +74 -87
  12. data/ext/um/um_const.c +184 -0
  13. data/ext/um/um_op.c +10 -13
  14. data/ext/um/um_utils.c +48 -3
  15. data/lib/uringmachine/version.rb +1 -1
  16. data/lib/uringmachine.rb +12 -0
  17. data/test/helper.rb +8 -0
  18. data/test/test_um.rb +227 -7
  19. data/vendor/liburing/.github/workflows/build.yml +29 -1
  20. data/vendor/liburing/.gitignore +1 -0
  21. data/vendor/liburing/CHANGELOG +15 -0
  22. data/vendor/liburing/CONTRIBUTING.md +165 -0
  23. data/vendor/liburing/configure +32 -0
  24. data/vendor/liburing/examples/Makefile +8 -1
  25. data/vendor/liburing/examples/kdigest.c +405 -0
  26. data/vendor/liburing/examples/proxy.c +75 -8
  27. data/vendor/liburing/liburing.pc.in +1 -1
  28. data/vendor/liburing/src/Makefile +16 -2
  29. data/vendor/liburing/src/include/liburing/io_uring.h +31 -0
  30. data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
  31. data/vendor/liburing/src/include/liburing.h +31 -4
  32. data/vendor/liburing/src/liburing-ffi.map +5 -0
  33. data/vendor/liburing/src/liburing.map +1 -0
  34. data/vendor/liburing/src/queue.c +3 -0
  35. data/vendor/liburing/src/register.c +36 -0
  36. data/vendor/liburing/src/sanitize.c +176 -0
  37. data/vendor/liburing/src/setup.c +1 -1
  38. data/vendor/liburing/test/35fa71a030ca.c +7 -0
  39. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  40. data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
  41. data/vendor/liburing/test/917257daa0fe.c +7 -0
  42. data/vendor/liburing/test/Makefile +31 -4
  43. data/vendor/liburing/test/a0908ae19763.c +7 -0
  44. data/vendor/liburing/test/a4c0b3decb33.c +7 -0
  45. data/vendor/liburing/test/accept.c +14 -4
  46. data/vendor/liburing/test/b19062a56726.c +7 -0
  47. data/vendor/liburing/test/bind-listen.c +2 -2
  48. data/vendor/liburing/test/buf-ring-nommap.c +10 -3
  49. data/vendor/liburing/test/buf-ring.c +2 -0
  50. data/vendor/liburing/test/coredump.c +7 -0
  51. data/vendor/liburing/test/cq-overflow.c +13 -1
  52. data/vendor/liburing/test/d4ae271dfaae.c +11 -3
  53. data/vendor/liburing/test/defer-taskrun.c +2 -2
  54. data/vendor/liburing/test/defer-tw-timeout.c +4 -1
  55. data/vendor/liburing/test/defer.c +2 -2
  56. data/vendor/liburing/test/double-poll-crash.c +1 -1
  57. data/vendor/liburing/test/eeed8b54e0df.c +2 -0
  58. data/vendor/liburing/test/eventfd.c +0 -1
  59. data/vendor/liburing/test/exit-no-cleanup.c +11 -0
  60. data/vendor/liburing/test/fadvise.c +9 -26
  61. data/vendor/liburing/test/fdinfo.c +9 -1
  62. data/vendor/liburing/test/file-register.c +14 -2
  63. data/vendor/liburing/test/file-update.c +1 -1
  64. data/vendor/liburing/test/file-verify.c +27 -16
  65. data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
  66. data/vendor/liburing/test/fixed-buf-iter.c +3 -1
  67. data/vendor/liburing/test/fixed-hugepage.c +12 -1
  68. data/vendor/liburing/test/fsnotify.c +1 -0
  69. data/vendor/liburing/test/futex.c +16 -4
  70. data/vendor/liburing/test/helpers.c +47 -0
  71. data/vendor/liburing/test/helpers.h +6 -0
  72. data/vendor/liburing/test/init-mem.c +5 -3
  73. data/vendor/liburing/test/io-cancel.c +0 -24
  74. data/vendor/liburing/test/io_uring_passthrough.c +2 -0
  75. data/vendor/liburing/test/io_uring_register.c +25 -6
  76. data/vendor/liburing/test/iopoll-leak.c +4 -0
  77. data/vendor/liburing/test/iopoll-overflow.c +1 -1
  78. data/vendor/liburing/test/iopoll.c +3 -3
  79. data/vendor/liburing/test/kallsyms.c +203 -0
  80. data/vendor/liburing/test/link-timeout.c +159 -0
  81. data/vendor/liburing/test/linked-defer-close.c +224 -0
  82. data/vendor/liburing/test/madvise.c +12 -25
  83. data/vendor/liburing/test/min-timeout-wait.c +0 -25
  84. data/vendor/liburing/test/min-timeout.c +0 -25
  85. data/vendor/liburing/test/mkdir.c +6 -0
  86. data/vendor/liburing/test/msg-ring.c +8 -2
  87. data/vendor/liburing/test/napi-test.c +15 -2
  88. data/vendor/liburing/test/no-mmap-inval.c +2 -0
  89. data/vendor/liburing/test/nop.c +44 -0
  90. data/vendor/liburing/test/ooo-file-unreg.c +1 -1
  91. data/vendor/liburing/test/open-close.c +40 -0
  92. data/vendor/liburing/test/openat2.c +37 -14
  93. data/vendor/liburing/test/poll-many.c +13 -7
  94. data/vendor/liburing/test/poll-mshot-update.c +17 -10
  95. data/vendor/liburing/test/poll-v-poll.c +6 -3
  96. data/vendor/liburing/test/pollfree.c +148 -0
  97. data/vendor/liburing/test/read-mshot-empty.c +156 -153
  98. data/vendor/liburing/test/read-mshot.c +276 -27
  99. data/vendor/liburing/test/read-write.c +78 -13
  100. data/vendor/liburing/test/recv-msgall-stream.c +3 -0
  101. data/vendor/liburing/test/recv-msgall.c +5 -0
  102. data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
  103. data/vendor/liburing/test/recvsend_bundle.c +92 -29
  104. data/vendor/liburing/test/reg-fd-only.c +14 -4
  105. data/vendor/liburing/test/regbuf-clone.c +187 -0
  106. data/vendor/liburing/test/regbuf-merge.c +7 -0
  107. data/vendor/liburing/test/register-restrictions.c +86 -85
  108. data/vendor/liburing/test/rename.c +59 -1
  109. data/vendor/liburing/test/ringbuf-read.c +5 -0
  110. data/vendor/liburing/test/ringbuf-status.c +5 -1
  111. data/vendor/liburing/test/runtests.sh +16 -1
  112. data/vendor/liburing/test/send-zerocopy.c +59 -0
  113. data/vendor/liburing/test/short-read.c +1 -0
  114. data/vendor/liburing/test/socket.c +43 -0
  115. data/vendor/liburing/test/splice.c +3 -1
  116. data/vendor/liburing/test/sq-poll-dup.c +1 -1
  117. data/vendor/liburing/test/sq-poll-share.c +2 -0
  118. data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
  119. data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
  120. data/vendor/liburing/test/sqpoll-sleep.c +1 -25
  121. data/vendor/liburing/test/statx.c +89 -0
  122. data/vendor/liburing/test/stdout.c +2 -0
  123. data/vendor/liburing/test/submit-and-wait.c +1 -25
  124. data/vendor/liburing/test/submit-reuse.c +4 -26
  125. data/vendor/liburing/test/symlink.c +12 -1
  126. data/vendor/liburing/test/sync-cancel.c +48 -21
  127. data/vendor/liburing/test/thread-exit.c +5 -0
  128. data/vendor/liburing/test/timeout-new.c +1 -26
  129. data/vendor/liburing/test/timeout.c +12 -26
  130. data/vendor/liburing/test/unlink.c +94 -1
  131. data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
  132. data/vendor/liburing/test/waitid.c +62 -8
  133. data/vendor/liburing/test/wq-aff.c +35 -0
  134. data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
  135. data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
  136. metadata +17 -4
  137. data/examples/event_loop.rb +0 -69
  138. data/examples/fibers.rb +0 -105
@@ -61,31 +61,6 @@ static int within_range(unsigned int target, unsigned int msec)
61
61
  return (msec >= low && msec <= high);
62
62
  }
63
63
 
64
- static unsigned long long mtime_since(const struct timeval *s,
65
- const struct timeval *e)
66
- {
67
- long long sec, usec;
68
-
69
- sec = e->tv_sec - s->tv_sec;
70
- usec = (e->tv_usec - s->tv_usec);
71
- if (sec > 0 && usec < 0) {
72
- sec--;
73
- usec += 1000000;
74
- }
75
-
76
- sec *= 1000;
77
- usec /= 1000;
78
- return sec + usec;
79
- }
80
-
81
- static unsigned long long mtime_since_now(struct timeval *tv)
82
- {
83
- struct timeval end;
84
-
85
- gettimeofday(&end, NULL);
86
- return mtime_since(tv, &end);
87
- }
88
-
89
64
  static int test(int flags, int expected_ctx, int min_wait, int write_delay,
90
65
  int nr_cqes, int msec_target)
91
66
  {
@@ -97,6 +97,12 @@ int main(int argc, char *argv[])
97
97
  goto err1;
98
98
  }
99
99
 
100
+ ret = do_mkdirat(&ring, (const char *) (uintptr_t) 0x1234);
101
+ if (ret != -EFAULT) {
102
+ fprintf(stderr, "do_mkdirat bad address: %d\n", ret);
103
+ goto err1;
104
+ }
105
+
100
106
  unlinkat(AT_FDCWD, fn, AT_REMOVEDIR);
101
107
  io_uring_queue_exit(&ring);
102
108
  return T_EXIT_PASS;
@@ -309,6 +309,8 @@ static int test_disabled_ring(struct io_uring *ring, int flags)
309
309
  flags |= IORING_SETUP_R_DISABLED;
310
310
  ret = io_uring_queue_init(8, &disabled_ring, flags);
311
311
  if (ret) {
312
+ if (ret == -EINVAL)
313
+ return T_EXIT_SKIP;
312
314
  fprintf(stderr, "ring setup failed: %d\n", ret);
313
315
  return 1;
314
316
  }
@@ -349,6 +351,8 @@ static int test(int ring_flags)
349
351
 
350
352
  ret = io_uring_queue_init(8, &ring, ring_flags);
351
353
  if (ret) {
354
+ if (ret == -EINVAL)
355
+ return T_EXIT_SKIP;
352
356
  fprintf(stderr, "ring setup failed: %d\n", ret);
353
357
  return T_EXIT_FAIL;
354
358
  }
@@ -452,13 +456,15 @@ int main(int argc, char *argv[])
452
456
  return T_EXIT_SKIP;
453
457
 
454
458
  ret = test(0);
455
- if (ret != T_EXIT_PASS) {
459
+ if (ret == T_EXIT_FAIL) {
456
460
  fprintf(stderr, "ring flags 0 failed\n");
457
461
  return ret;
462
+ } else if (ret == T_EXIT_SKIP) {
463
+ return T_EXIT_SKIP;
458
464
  }
459
465
 
460
466
  ret = test(IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN);
461
- if (ret != T_EXIT_PASS) {
467
+ if (ret == T_EXIT_FAIL) {
462
468
  fprintf(stderr, "ring flags defer failed\n");
463
469
  return ret;
464
470
  }
@@ -37,12 +37,23 @@ static void do_setsockopt(int fd, int level, int optname, int val)
37
37
  assert(ret == 0);
38
38
  }
39
39
 
40
- static int sender(void)
40
+ static int sender(int queue_flags)
41
41
  {
42
42
  unsigned long long written = 0;
43
43
  struct sockaddr_in addr;
44
+ struct io_uring ring;
44
45
  int i, ret, fd;
45
46
 
47
+ /*
48
+ * Sender doesn't use the ring, but try and set one up with the same
49
+ * flags that the receiver will use. If that fails, we know the
50
+ * receiver will have failed too - just skip the test in that case.
51
+ */
52
+ ret = io_uring_queue_init(1, &ring, queue_flags);
53
+ if (ret)
54
+ return T_EXIT_SKIP;
55
+ io_uring_queue_exit(&ring);
56
+
46
57
  memset(&addr, 0, sizeof(addr));
47
58
  addr.sin_family = AF_INET;
48
59
  addr.sin_port = htons(port);
@@ -100,6 +111,8 @@ static int receiver(int queue_flags)
100
111
 
101
112
  ret = io_uring_queue_init(8, &ring, queue_flags);
102
113
  if (ret < 0) {
114
+ if (ret == -EINVAL)
115
+ return T_EXIT_SKIP;
103
116
  fprintf(stderr, "queue_init: %s\n", strerror(-ret));
104
117
  return 1;
105
118
  }
@@ -211,5 +224,5 @@ int main(int argc, char **argv)
211
224
  if (is_rx)
212
225
  return receiver(queue_flags);
213
226
 
214
- return sender();
227
+ return sender(queue_flags);
215
228
  }
@@ -32,11 +32,13 @@ int main(int argc, char *argv[])
32
32
  ret = io_uring_queue_init_params(2, &ring, &p);
33
33
  if (ret == -EINVAL) {
34
34
  /* kernel doesn't support SETUP_NO_MMAP */
35
+ free(addr);
35
36
  return T_EXIT_SKIP;
36
37
  } else if (ret && (ret != -EFAULT && ret != -ENOMEM)) {
37
38
  fprintf(stderr, "Got %d, wanted -EFAULT\n", ret);
38
39
  return T_EXIT_FAIL;
39
40
  }
40
41
 
42
+ free(addr);
41
43
  return T_EXIT_PASS;
42
44
  }
@@ -15,6 +15,45 @@
15
15
 
16
16
  static int seq;
17
17
 
18
+ static int test_nop_inject(struct io_uring *ring, unsigned req_flags)
19
+ {
20
+ struct io_uring_cqe *cqe;
21
+ struct io_uring_sqe *sqe;
22
+ int ret;
23
+
24
+ sqe = io_uring_get_sqe(ring);
25
+ if (!sqe) {
26
+ fprintf(stderr, "get sqe failed\n");
27
+ goto err;
28
+ }
29
+
30
+ io_uring_prep_nop(sqe);
31
+ sqe->user_data = ++seq;
32
+ sqe->nop_flags = IORING_NOP_INJECT_RESULT;
33
+ sqe->flags |= req_flags;
34
+ sqe->len = -EFAULT;
35
+
36
+ ret = io_uring_submit(ring);
37
+ if (ret <= 0) {
38
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
39
+ goto err;
40
+ }
41
+
42
+ ret = io_uring_wait_cqe(ring, &cqe);
43
+ if (ret < 0) {
44
+ fprintf(stderr, "wait completion %d\n", ret);
45
+ goto err;
46
+ }
47
+ if (cqe->res != -EINVAL && cqe->res != -EFAULT) {
48
+ fprintf(stderr, "expected injected result, got %d\n", cqe->res);
49
+ goto err;
50
+ }
51
+ io_uring_cqe_seen(ring, cqe);
52
+ return 0;
53
+ err:
54
+ return 1;
55
+ }
56
+
18
57
  static int test_single_nop(struct io_uring *ring, unsigned req_flags)
19
58
  {
20
59
  struct io_uring_cqe *cqe;
@@ -151,6 +190,11 @@ static int test_ring(unsigned flags)
151
190
  fprintf(stderr, "test_barrier_nop failed\n");
152
191
  goto err;
153
192
  }
193
+ ret = test_nop_inject(&ring, req_flags);
194
+ if (ret) {
195
+ fprintf(stderr, "test_nop_inject failed\n");
196
+ goto err;
197
+ }
154
198
  }
155
199
  err:
156
200
  io_uring_queue_exit(&ring);
@@ -9,7 +9,7 @@
9
9
  #include <sys/socket.h>
10
10
  #include <unistd.h>
11
11
  #include <stdlib.h>
12
- #include <sys/poll.h>
12
+ #include <poll.h>
13
13
 
14
14
  #include "liburing.h"
15
15
  #include "helpers.h"
@@ -35,6 +35,36 @@ static int submit_wait(struct io_uring *ring)
35
35
  return ret;
36
36
  }
37
37
 
38
+ static int test_close_flush(void)
39
+ {
40
+ struct io_uring ring;
41
+ struct io_uring_sqe *sqe;
42
+ char buf[128];
43
+ int ret, fd;
44
+
45
+ sprintf(buf, "/sys/kernel/debug/tracing/per_cpu/cpu0/trace_pipe_raw");
46
+ fd = open(buf, O_RDONLY);
47
+ if (fd < 0)
48
+ return 0;
49
+
50
+ ret = io_uring_queue_init(8, &ring, 0);
51
+ if (ret) {
52
+ fprintf(stderr, "ring setup failed\n");
53
+ return -1;
54
+ }
55
+
56
+ sqe = io_uring_get_sqe(&ring);
57
+ io_uring_prep_close(sqe, fd);
58
+ ret = submit_wait(&ring);
59
+ if (ret) {
60
+ fprintf(stderr, "closefailed %i\n", ret);
61
+ return -1;
62
+ }
63
+
64
+ io_uring_queue_exit(&ring);
65
+ return 0;
66
+ }
67
+
38
68
  static inline int try_close(struct io_uring *ring, int fd, int slot)
39
69
  {
40
70
  struct io_uring_sqe *sqe;
@@ -220,12 +250,16 @@ int main(int argc, char *argv[])
220
250
  fprintf(stdout, "Open not supported, skipping\n");
221
251
  goto done;
222
252
  }
253
+ if (ret == -EPERM || ret == -EACCES)
254
+ return T_EXIT_SKIP;
223
255
  fprintf(stderr, "test_openat absolute failed: %d\n", ret);
224
256
  goto err;
225
257
  }
226
258
 
227
259
  ret = test_openat(&ring, path_rel, AT_FDCWD);
228
260
  if (ret < 0) {
261
+ if (ret == -EPERM || ret == -EACCES)
262
+ return T_EXIT_SKIP;
229
263
  fprintf(stderr, "test_openat relative failed: %d\n", ret);
230
264
  goto err;
231
265
  }
@@ -248,6 +282,12 @@ int main(int argc, char *argv[])
248
282
  goto err;
249
283
  }
250
284
 
285
+ ret = test_close_flush();
286
+ if (ret) {
287
+ fprintf(stderr, "test_close_flush failed\n");
288
+ goto err;
289
+ }
290
+
251
291
  done:
252
292
  unlink(path);
253
293
  if (do_unlink)
@@ -15,25 +15,32 @@
15
15
  #include "liburing.h"
16
16
 
17
17
  static int test_openat2(struct io_uring *ring, const char *path, int dfd,
18
- bool direct, int fixed_index)
18
+ bool direct, int fixed_index, int bad_how)
19
19
  {
20
20
  struct io_uring_cqe *cqe;
21
21
  struct io_uring_sqe *sqe;
22
- struct open_how how;
22
+ struct open_how __how, *how;
23
23
  int ret;
24
24
 
25
+ if (bad_how)
26
+ how = (struct open_how *) (uintptr_t) 0x1234;
27
+ else
28
+ how = &__how;
29
+
25
30
  sqe = io_uring_get_sqe(ring);
26
31
  if (!sqe) {
27
32
  fprintf(stderr, "get sqe failed\n");
28
33
  return -1;
29
34
  }
30
- memset(&how, 0, sizeof(how));
31
- how.flags = O_RDWR;
35
+ if (!bad_how) {
36
+ memset(how, 0, sizeof(*how));
37
+ how->flags = O_RDWR;
38
+ }
32
39
 
33
40
  if (!direct)
34
- io_uring_prep_openat2(sqe, dfd, path, &how);
41
+ io_uring_prep_openat2(sqe, dfd, path, how);
35
42
  else
36
- io_uring_prep_openat2_direct(sqe, dfd, path, &how, fixed_index);
43
+ io_uring_prep_openat2_direct(sqe, dfd, path, how, fixed_index);
37
44
 
38
45
  ret = io_uring_submit(ring);
39
46
  if (ret <= 0) {
@@ -78,7 +85,7 @@ static int test_open_fixed(const char *path, int dfd)
78
85
  return -1;
79
86
  }
80
87
 
81
- ret = test_openat2(&ring, path, dfd, true, 0);
88
+ ret = test_openat2(&ring, path, dfd, true, 0, 0);
82
89
  if (ret == -EINVAL) {
83
90
  printf("fixed open isn't supported\n");
84
91
  return 1;
@@ -135,7 +142,7 @@ static int test_open_fixed_fail(const char *path, int dfd)
135
142
  return -1;
136
143
  }
137
144
 
138
- ret = test_openat2(&ring, path, dfd, true, 0);
145
+ ret = test_openat2(&ring, path, dfd, true, 0, 0);
139
146
  if (ret != -ENXIO) {
140
147
  fprintf(stderr, "install into not existing table, %i\n", ret);
141
148
  return 1;
@@ -149,19 +156,19 @@ static int test_open_fixed_fail(const char *path, int dfd)
149
156
  return -1;
150
157
  }
151
158
 
152
- ret = test_openat2(&ring, path, dfd, true, 1);
159
+ ret = test_openat2(&ring, path, dfd, true, 1, 0);
153
160
  if (ret != -EINVAL) {
154
161
  fprintf(stderr, "install out of bounds, %i\n", ret);
155
162
  return -1;
156
163
  }
157
164
 
158
- ret = test_openat2(&ring, path, dfd, true, (1u << 16));
165
+ ret = test_openat2(&ring, path, dfd, true, (1u << 16), 0);
159
166
  if (ret != -EINVAL) {
160
167
  fprintf(stderr, "install out of bounds or u16 overflow, %i\n", ret);
161
168
  return -1;
162
169
  }
163
170
 
164
- ret = test_openat2(&ring, path, dfd, true, (1u << 16) + 1);
171
+ ret = test_openat2(&ring, path, dfd, true, (1u << 16) + 1, 0);
165
172
  if (ret != -EINVAL) {
166
173
  fprintf(stderr, "install out of bounds or u16 overflow, %i\n", ret);
167
174
  return -1;
@@ -196,7 +203,7 @@ static int test_direct_reinstall(const char *path, int dfd)
196
203
  }
197
204
 
198
205
  /* reinstall into the second slot */
199
- ret = test_openat2(&ring, path, dfd, true, 1);
206
+ ret = test_openat2(&ring, path, dfd, true, 1, 0);
200
207
  if (ret != 0) {
201
208
  fprintf(stderr, "reinstall failed, %i\n", ret);
202
209
  return -1;
@@ -264,18 +271,22 @@ int main(int argc, char *argv[])
264
271
  if (do_unlink)
265
272
  t_create_file(path_rel, 4096);
266
273
 
267
- ret = test_openat2(&ring, path, -1, false, 0);
274
+ ret = test_openat2(&ring, path, -1, false, 0, 0);
268
275
  if (ret < 0) {
269
276
  if (ret == -EINVAL) {
270
277
  fprintf(stdout, "openat2 not supported, skipping\n");
271
278
  goto done;
272
279
  }
280
+ if (ret == -EPERM || ret == -EACCES)
281
+ return T_EXIT_SKIP;
273
282
  fprintf(stderr, "test_openat2 absolute failed: %d\n", ret);
274
283
  goto err;
275
284
  }
276
285
 
277
- ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0);
286
+ ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0, 0);
278
287
  if (ret < 0) {
288
+ if (ret == -EPERM || ret == -EACCES)
289
+ return T_EXIT_SKIP;
279
290
  fprintf(stderr, "test_openat2 relative failed: %d\n", ret);
280
291
  goto err;
281
292
  }
@@ -299,6 +310,18 @@ int main(int argc, char *argv[])
299
310
  goto err;
300
311
  }
301
312
 
313
+ ret = test_openat2(&ring, (const char *) (uintptr_t) 0x1234, AT_FDCWD, false, 0, 0);
314
+ if (ret != -EFAULT) {
315
+ fprintf(stderr, "test_openat2 bad address failed: %d\n", ret);
316
+ goto err;
317
+ }
318
+
319
+ ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0, 1);
320
+ if (ret != -EFAULT) {
321
+ fprintf(stderr, "test_openat2 bad how failed: %d\n", ret);
322
+ goto err;
323
+ }
324
+
302
325
  done:
303
326
  unlink(path);
304
327
  if (do_unlink)
@@ -22,6 +22,8 @@
22
22
 
23
23
  #define RING_SIZE 512
24
24
 
25
+ static int nfiles = NFILES;
26
+
25
27
  struct p {
26
28
  int fd[2];
27
29
  int triggered;
@@ -91,7 +93,7 @@ static int trigger_polls(void)
91
93
  int off;
92
94
 
93
95
  do {
94
- off = rand() % NFILES;
96
+ off = rand() % nfiles;
95
97
  if (!p[off].triggered)
96
98
  break;
97
99
  } while (1);
@@ -109,7 +111,7 @@ static int trigger_polls(void)
109
111
 
110
112
  static int arm_polls(struct io_uring *ring)
111
113
  {
112
- int ret, to_arm = NFILES, i, off;
114
+ int ret, to_arm = nfiles, i, off;
113
115
 
114
116
  off = 0;
115
117
  while (to_arm) {
@@ -161,7 +163,7 @@ int main(int argc, char *argv[])
161
163
  int i, ret;
162
164
 
163
165
  if (argc > 1)
164
- return 0;
166
+ return T_EXIT_SKIP;
165
167
 
166
168
  if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
167
169
  perror("getrlimit");
@@ -169,8 +171,12 @@ int main(int argc, char *argv[])
169
171
  }
170
172
 
171
173
  if (rlim.rlim_cur < (2 * NFILES + 5)) {
172
- rlim.rlim_cur = (2 * NFILES + 5);
173
- rlim.rlim_max = rlim.rlim_cur;
174
+ rlim.rlim_cur = rlim.rlim_max;
175
+ nfiles = (rlim.rlim_cur / 2) - 5;
176
+ if (nfiles > NFILES)
177
+ nfiles = NFILES;
178
+ if (nfiles <= 0)
179
+ goto err_nofail;
174
180
  if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
175
181
  if (errno == EPERM)
176
182
  goto err_nofail;
@@ -179,7 +185,7 @@ int main(int argc, char *argv[])
179
185
  }
180
186
  }
181
187
 
182
- for (i = 0; i < NFILES; i++) {
188
+ for (i = 0; i < nfiles; i++) {
183
189
  if (pipe(p[i].fd) < 0) {
184
190
  perror("pipe");
185
191
  return T_EXIT_FAIL;
@@ -226,5 +232,5 @@ int main(int argc, char *argv[])
226
232
  err_nofail:
227
233
  fprintf(stderr, "poll-many: not enough files available (and not root), "
228
234
  "skipped\n");
229
- return 0;
235
+ return T_EXIT_SKIP;
230
236
  }
@@ -15,11 +15,14 @@
15
15
  #include <pthread.h>
16
16
 
17
17
  #include "liburing.h"
18
+ #include "helpers.h"
18
19
 
19
20
  #define NFILES 5000
20
21
  #define BATCH 500
21
22
  #define NLOOPS 1000
22
23
 
24
+ static int nfiles = NFILES;
25
+
23
26
  #define RING_SIZE 512
24
27
 
25
28
  struct p {
@@ -160,7 +163,7 @@ static int trigger_polls(void)
160
163
  int off;
161
164
 
162
165
  do {
163
- off = rand() % NFILES;
166
+ off = rand() % nfiles;
164
167
  if (!p[off].triggered)
165
168
  break;
166
169
  } while (1);
@@ -184,7 +187,7 @@ static void *trigger_polls_fn(void *data)
184
187
 
185
188
  static int arm_polls(struct io_uring *ring)
186
189
  {
187
- int ret, to_arm = NFILES, i, off;
190
+ int ret, to_arm = nfiles, i, off;
188
191
 
189
192
  off = 0;
190
193
  while (to_arm) {
@@ -220,7 +223,7 @@ static int run(int cqe)
220
223
  pthread_t thread;
221
224
  int i, j, ret;
222
225
 
223
- for (i = 0; i < NFILES; i++) {
226
+ for (i = 0; i < nfiles; i++) {
224
227
  if (pipe(p[i].fd) < 0) {
225
228
  perror("pipe");
226
229
  return 1;
@@ -252,12 +255,12 @@ static int run(int cqe)
252
255
  goto err;
253
256
  pthread_join(thread, NULL);
254
257
 
255
- for (j = 0; j < NFILES; j++)
258
+ for (j = 0; j < nfiles; j++)
256
259
  p[j].triggered = 0;
257
260
  }
258
261
 
259
262
  io_uring_queue_exit(&ring);
260
- for (i = 0; i < NFILES; i++) {
263
+ for (i = 0; i < nfiles; i++) {
261
264
  close(p[i].fd[0]);
262
265
  close(p[i].fd[1]);
263
266
  }
@@ -273,7 +276,7 @@ int main(int argc, char *argv[])
273
276
  int ret;
274
277
 
275
278
  if (argc > 1)
276
- return 0;
279
+ return T_EXIT_SKIP;
277
280
 
278
281
  ret = has_poll_update();
279
282
  if (ret < 0) {
@@ -290,13 +293,17 @@ int main(int argc, char *argv[])
290
293
  }
291
294
 
292
295
  if (rlim.rlim_cur < (2 * NFILES + 5)) {
293
- rlim.rlim_cur = (2 * NFILES + 5);
294
- rlim.rlim_max = rlim.rlim_cur;
296
+ rlim.rlim_cur = rlim.rlim_max;
297
+ nfiles = (rlim.rlim_cur / 2) - 5;
298
+ if (nfiles > NFILES)
299
+ nfiles = NFILES;
300
+ if (nfiles <= 0)
301
+ goto err_nofail;
295
302
  if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
296
303
  if (errno == EPERM)
297
304
  goto err_nofail;
298
305
  perror("setrlimit");
299
- goto err;
306
+ return T_EXIT_FAIL;
300
307
  }
301
308
  }
302
309
 
@@ -319,5 +326,5 @@ err:
319
326
  err_nofail:
320
327
  fprintf(stderr, "poll-many: not enough files available (and not root), "
321
328
  "skipped\n");
322
- return 0;
329
+ return T_EXIT_SKIP;
323
330
  }
@@ -17,6 +17,7 @@
17
17
  #include <sys/epoll.h>
18
18
 
19
19
  #include "liburing.h"
20
+ #include "helpers.h"
20
21
 
21
22
  struct thread_data {
22
23
  struct io_uring *ring;
@@ -174,6 +175,8 @@ static int do_fd_test(struct io_uring *ring, const char *fname, int events)
174
175
 
175
176
  fd = open(fname, O_RDONLY);
176
177
  if (fd < 0) {
178
+ if (errno == EPERM || errno == EACCES)
179
+ return T_EXIT_SKIP;
177
180
  perror("open");
178
181
  return 1;
179
182
  }
@@ -331,19 +334,19 @@ int main(int argc, char *argv[])
331
334
  fname = argv[0];
332
335
 
333
336
  ret = do_fd_test(&ring, fname, POLLIN);
334
- if (ret) {
337
+ if (ret == T_EXIT_FAIL) {
335
338
  fprintf(stderr, "fd test IN failed\n");
336
339
  return ret;
337
340
  }
338
341
 
339
342
  ret = do_fd_test(&ring, fname, POLLOUT);
340
- if (ret) {
343
+ if (ret == T_EXIT_FAIL) {
341
344
  fprintf(stderr, "fd test OUT failed\n");
342
345
  return ret;
343
346
  }
344
347
 
345
348
  ret = do_fd_test(&ring, fname, POLLOUT | POLLIN);
346
- if (ret) {
349
+ if (ret == T_EXIT_FAIL) {
347
350
  fprintf(stderr, "fd test IN|OUT failed\n");
348
351
  return ret;
349
352
  }