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
@@ -90,6 +90,8 @@ static int test_truncate(struct io_uring *ring, const char *fname, int buffered,
90
90
  else
91
91
  fd = open(fname, O_DIRECT | O_RDWR);
92
92
  if (fd < 0) {
93
+ if (!buffered && errno == EINVAL)
94
+ return T_EXIT_SKIP;
93
95
  perror("open");
94
96
  return 1;
95
97
  }
@@ -346,6 +348,8 @@ static int test(struct io_uring *ring, const char *fname, int buffered,
346
348
  flags |= O_DIRECT;
347
349
  fd = open(fname, flags);
348
350
  if (fd < 0) {
351
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
352
+ return T_EXIT_SKIP;
349
353
  perror("open");
350
354
  return 1;
351
355
  }
@@ -505,6 +509,8 @@ static int fill_pattern(const char *fname)
505
509
 
506
510
  fd = open(fname, O_WRONLY);
507
511
  if (fd < 0) {
512
+ if (errno == EPERM || errno == EACCES)
513
+ return T_EXIT_SKIP;
508
514
  perror("open");
509
515
  return 1;
510
516
  }
@@ -557,89 +563,94 @@ int main(int argc, char *argv[])
557
563
  goto err;
558
564
  }
559
565
 
560
- if (fill_pattern(fname))
566
+ ret = fill_pattern(fname);
567
+ if (ret == T_EXIT_SKIP)
568
+ return T_EXIT_SKIP;
569
+ else if (ret)
561
570
  goto err;
562
571
 
563
572
  ret = test(&ring, fname, 1, 0, 0, 0, 0);
573
+ if (ret == T_EXIT_SKIP)
574
+ return T_EXIT_SKIP;
564
575
  if (ret) {
565
576
  fprintf(stderr, "Buffered novec test failed\n");
566
577
  goto err;
567
578
  }
568
579
  ret = test(&ring, fname, 1, 0, 0, 1, 0);
569
- if (ret) {
580
+ if (ret == T_EXIT_FAIL) {
570
581
  fprintf(stderr, "Buffered novec reg test failed\n");
571
582
  goto err;
572
583
  }
573
584
  ret = test(&ring, fname, 1, 0, 0, 0, 1);
574
- if (ret) {
585
+ if (ret == T_EXIT_FAIL) {
575
586
  fprintf(stderr, "Buffered novec provide test failed\n");
576
587
  goto err;
577
588
  }
578
589
  ret = test(&ring, fname, 1, 1, 0, 0, 0);
579
- if (ret) {
590
+ if (ret == T_EXIT_FAIL) {
580
591
  fprintf(stderr, "Buffered vec test failed\n");
581
592
  goto err;
582
593
  }
583
594
  ret = test(&ring, fname, 1, 1, 1, 0, 0);
584
- if (ret) {
595
+ if (ret == T_EXIT_FAIL) {
585
596
  fprintf(stderr, "Buffered small vec test failed\n");
586
597
  goto err;
587
598
  }
588
599
 
589
600
  ret = test(&ring, fname, 0, 0, 0, 0, 0);
590
- if (ret) {
601
+ if (ret == T_EXIT_FAIL) {
591
602
  fprintf(stderr, "O_DIRECT novec test failed\n");
592
603
  goto err;
593
604
  }
594
605
  ret = test(&ring, fname, 0, 0, 0, 1, 0);
595
- if (ret) {
606
+ if (ret == T_EXIT_FAIL) {
596
607
  fprintf(stderr, "O_DIRECT novec reg test failed\n");
597
608
  goto err;
598
609
  }
599
610
  ret = test(&ring, fname, 0, 0, 0, 0, 1);
600
- if (ret) {
611
+ if (ret == T_EXIT_FAIL) {
601
612
  fprintf(stderr, "O_DIRECT novec provide test failed\n");
602
613
  goto err;
603
614
  }
604
615
  ret = test(&ring, fname, 0, 1, 0, 0, 0);
605
- if (ret) {
616
+ if (ret == T_EXIT_FAIL) {
606
617
  fprintf(stderr, "O_DIRECT vec test failed\n");
607
618
  goto err;
608
619
  }
609
620
  ret = test(&ring, fname, 0, 1, 1, 0, 0);
610
- if (ret) {
621
+ if (ret == T_EXIT_FAIL) {
611
622
  fprintf(stderr, "O_DIRECT small vec test failed\n");
612
623
  goto err;
613
624
  }
614
625
 
615
626
  ret = test_truncate(&ring, fname, 1, 0, 0);
616
- if (ret) {
627
+ if (ret == T_EXIT_FAIL) {
617
628
  fprintf(stderr, "Buffered end truncate read failed\n");
618
629
  goto err;
619
630
  }
620
631
  ret = test_truncate(&ring, fname, 1, 1, 0);
621
- if (ret) {
632
+ if (ret == T_EXIT_FAIL) {
622
633
  fprintf(stderr, "Buffered end truncate vec read failed\n");
623
634
  goto err;
624
635
  }
625
636
  ret = test_truncate(&ring, fname, 1, 0, 1);
626
- if (ret) {
637
+ if (ret == T_EXIT_FAIL) {
627
638
  fprintf(stderr, "Buffered end truncate pbuf read failed\n");
628
639
  goto err;
629
640
  }
630
641
 
631
642
  ret = test_truncate(&ring, fname, 0, 0, 0);
632
- if (ret) {
643
+ if (ret == T_EXIT_FAIL) {
633
644
  fprintf(stderr, "O_DIRECT end truncate read failed\n");
634
645
  goto err;
635
646
  }
636
647
  ret = test_truncate(&ring, fname, 0, 1, 0);
637
- if (ret) {
648
+ if (ret == T_EXIT_FAIL) {
638
649
  fprintf(stderr, "O_DIRECT end truncate vec read failed\n");
639
650
  goto err;
640
651
  }
641
652
  ret = test_truncate(&ring, fname, 0, 0, 1);
642
- if (ret) {
653
+ if (ret == T_EXIT_FAIL) {
643
654
  fprintf(stderr, "O_DIRECT end truncate pbuf read failed\n");
644
655
  goto err;
645
656
  }
@@ -43,13 +43,12 @@ static void add_accept(struct io_uring *ring, int fd)
43
43
 
44
44
  sqe = io_uring_get_sqe(ring);
45
45
  io_uring_prep_accept(sqe, fd, 0, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
46
- sqe->flags |= IOSQE_IO_LINK;
47
46
  }
48
47
 
49
48
  static int setup_io_uring(void)
50
49
  {
51
50
  int ret;
52
-
51
+
53
52
  ret = io_uring_queue_init(16, &ring, 0);
54
53
  if (ret) {
55
54
  fprintf(stderr, "Unable to setup io_uring: %s\n", strerror(-ret));
@@ -63,7 +63,7 @@ static int test(struct io_uring *ring)
63
63
  return 1;
64
64
  }
65
65
 
66
- if (cqe->res < 0) {
66
+ if (cqe->res < 0) {
67
67
  fprintf(stderr, "Error in async operation: %s\n", strerror(-cqe->res));
68
68
  return 1;
69
69
  }
@@ -87,6 +87,8 @@ static int test(struct io_uring *ring)
87
87
  return 1;
88
88
  }
89
89
  io_uring_cqe_seen(ring, cqe);
90
+ for (i = 0; i < BUFFERS; i++)
91
+ free(iov[i].iov_base);
90
92
  return 0;
91
93
  }
92
94
 
@@ -246,7 +246,8 @@ static int register_submit(struct io_uring *ring, struct iovec *iov,
246
246
 
247
247
  ret = io_uring_register_buffers(ring, iov, nr_bufs);
248
248
  if (ret) {
249
- fprintf(stderr, "Error registering buffers: %s\n", strerror(-ret));
249
+ if (ret != -ENOMEM)
250
+ fprintf(stderr, "Error registering buffers: %s\n", strerror(-ret));
250
251
  return ret;
251
252
  }
252
253
 
@@ -282,6 +283,8 @@ static int test_one_hugepage(struct io_uring *ring, int fd_in, int fd_out)
282
283
 
283
284
  ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
284
285
  unmap(iov, NR_BUFS, 0);
286
+ if (ret == -ENOMEM)
287
+ return T_EXIT_SKIP;
285
288
  return ret ? T_EXIT_FAIL : T_EXIT_PASS;
286
289
  }
287
290
 
@@ -296,6 +299,8 @@ static int test_multi_hugepages(struct io_uring *ring, int fd_in, int fd_out)
296
299
 
297
300
  ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
298
301
  unmap(iov, NR_BUFS, 0);
302
+ if (ret == -ENOMEM)
303
+ return T_EXIT_SKIP;
299
304
  return ret ? T_EXIT_FAIL : T_EXIT_PASS;
300
305
  }
301
306
 
@@ -311,6 +316,8 @@ static int test_unaligned_hugepage(struct io_uring *ring, int fd_in, int fd_out)
311
316
 
312
317
  ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
313
318
  unmap(iov, NR_BUFS, offset);
319
+ if (ret == -ENOMEM)
320
+ return T_EXIT_SKIP;
314
321
  return ret ? T_EXIT_FAIL : T_EXIT_PASS;
315
322
  }
316
323
 
@@ -326,6 +333,8 @@ static int test_multi_unaligned_mthps(struct io_uring *ring, int fd_in, int fd_o
326
333
 
327
334
  ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
328
335
  free_bufs(iov, NR_BUFS, offset);
336
+ if (ret == -ENOMEM)
337
+ return T_EXIT_SKIP;
329
338
  return ret ? T_EXIT_FAIL : T_EXIT_PASS;
330
339
  }
331
340
 
@@ -341,6 +350,8 @@ static int test_page_mixture(struct io_uring *ring, int fd_in, int fd_out, int h
341
350
 
342
351
  ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
343
352
  unmap(iov, NR_BUFS, 0);
353
+ if (ret == -ENOMEM)
354
+ return T_EXIT_SKIP;
344
355
  return ret ? T_EXIT_FAIL : T_EXIT_PASS;
345
356
  }
346
357
 
@@ -90,6 +90,7 @@ int main(int argc, char *argv[])
90
90
  wait(&wstat);
91
91
  if (!WEXITSTATUS(wstat))
92
92
  err = T_EXIT_PASS;
93
+ free(buf);
93
94
  } else {
94
95
  struct fanotify_event_metadata m;
95
96
  int fret;
@@ -120,6 +120,7 @@ static int __test(struct io_uring *ring, int vectored, int async,
120
120
 
121
121
  if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) {
122
122
  no_futex = 1;
123
+ free(futex);
123
124
  return 0;
124
125
  }
125
126
  io_uring_cqe_seen(ring, cqe);
@@ -134,6 +135,7 @@ static int __test(struct io_uring *ring, int vectored, int async,
134
135
  for (i = 0; i < nfutex; i++)
135
136
  pthread_join(threads[i], &tret);
136
137
 
138
+ free(futex);
137
139
  return 0;
138
140
  }
139
141
 
@@ -145,7 +147,7 @@ static int test(int flags, int vectored)
145
147
  ret = io_uring_queue_init(8, &ring, flags);
146
148
  if (ret)
147
149
  return ret;
148
-
150
+
149
151
  for (i = 0; i < LOOPS; i++) {
150
152
  int async_cancel = (!i % 2);
151
153
  int async_wait = !(i % 3);
@@ -166,7 +168,8 @@ static int test_order(int vectored, int async)
166
168
  {
167
169
  struct io_uring_sqe *sqe;
168
170
  struct io_uring_cqe *cqe;
169
- struct futex_waitv fw;
171
+ struct futex_waitv fw = { };
172
+ struct io_uring_sync_cancel_reg reg = { };
170
173
  struct io_uring ring;
171
174
  unsigned int *futex;
172
175
  int ret, i;
@@ -178,10 +181,8 @@ static int test_order(int vectored, int async)
178
181
  futex = malloc(sizeof(*futex));
179
182
  *futex = 0;
180
183
 
181
- fw.val = 0;
182
184
  fw.uaddr = (unsigned long) futex;
183
185
  fw.flags = FUTEX2_SIZE_U32;
184
- fw.__reserved = 0;
185
186
 
186
187
  /*
187
188
  * Submit two futex waits
@@ -241,7 +242,15 @@ static int test_order(int vectored, int async)
241
242
  return 1;
242
243
  }
243
244
 
245
+ reg.addr = 2;
246
+ ret = io_uring_register_sync_cancel(&ring, &reg);
247
+ if (ret != 1) {
248
+ fprintf(stderr, "Failed to cancel pending futex wait: %d\n", ret);
249
+ return 1;
250
+ }
251
+
244
252
  io_uring_queue_exit(&ring);
253
+ free(futex);
245
254
  return 0;
246
255
  }
247
256
 
@@ -322,6 +331,7 @@ static int test_multi_wake(int vectored)
322
331
  }
323
332
 
324
333
  io_uring_queue_exit(&ring);
334
+ free(futex);
325
335
  return 0;
326
336
  }
327
337
 
@@ -378,6 +388,7 @@ static int test_wake_zero(void)
378
388
  }
379
389
 
380
390
  io_uring_queue_exit(&ring);
391
+ free(futex);
381
392
  return 0;
382
393
  }
383
394
 
@@ -459,6 +470,7 @@ static int test_invalid(void)
459
470
  io_uring_cqe_seen(&ring, cqe);
460
471
 
461
472
  io_uring_queue_exit(&ring);
473
+ free(futex);
462
474
  return 0;
463
475
  }
464
476
 
@@ -316,3 +316,50 @@ void t_error(int status, int errnum, const char *format, ...)
316
316
  va_end(args);
317
317
  exit(status);
318
318
  }
319
+
320
+ unsigned long long mtime_since(const struct timeval *s, const struct timeval *e)
321
+ {
322
+ long long sec, usec;
323
+
324
+ sec = e->tv_sec - s->tv_sec;
325
+ usec = (e->tv_usec - s->tv_usec);
326
+ if (sec > 0 && usec < 0) {
327
+ sec--;
328
+ usec += 1000000;
329
+ }
330
+
331
+ sec *= 1000;
332
+ usec /= 1000;
333
+ return sec + usec;
334
+ }
335
+
336
+ unsigned long long mtime_since_now(struct timeval *tv)
337
+ {
338
+ struct timeval end;
339
+
340
+ gettimeofday(&end, NULL);
341
+ return mtime_since(tv, &end);
342
+ }
343
+
344
+ unsigned long long utime_since(const struct timeval *s, const struct timeval *e)
345
+ {
346
+ long long sec, usec;
347
+
348
+ sec = e->tv_sec - s->tv_sec;
349
+ usec = (e->tv_usec - s->tv_usec);
350
+ if (sec > 0 && usec < 0) {
351
+ sec--;
352
+ usec += 1000000;
353
+ }
354
+
355
+ sec *= 1000000;
356
+ return sec + usec;
357
+ }
358
+
359
+ unsigned long long utime_since_now(struct timeval *tv)
360
+ {
361
+ struct timeval end;
362
+
363
+ gettimeofday(&end, NULL);
364
+ return utime_since(tv, &end);
365
+ }
@@ -12,6 +12,7 @@ extern "C" {
12
12
  #include "liburing.h"
13
13
  #include "../src/setup.h"
14
14
  #include <arpa/inet.h>
15
+ #include <sys/time.h>
15
16
 
16
17
  enum t_setup_ret {
17
18
  T_SETUP_OK = 0,
@@ -101,6 +102,11 @@ static inline int t_io_uring_init_sqarray(unsigned entries, struct io_uring *rin
101
102
 
102
103
  void t_error(int status, int errnum, const char *format, ...);
103
104
 
105
+ unsigned long long mtime_since(const struct timeval *s, const struct timeval *e);
106
+ unsigned long long mtime_since_now(struct timeval *tv);
107
+ unsigned long long utime_since(const struct timeval *s, const struct timeval *e);
108
+ unsigned long long utime_since_now(struct timeval *tv);
109
+
104
110
  #ifdef __cplusplus
105
111
  }
106
112
  #endif
@@ -13,7 +13,6 @@
13
13
  #include <netinet/udp.h>
14
14
  #include <arpa/inet.h>
15
15
  #include <net/if.h>
16
- #include <error.h>
17
16
 
18
17
  #include "liburing.h"
19
18
  #include "helpers.h"
@@ -68,6 +67,7 @@ static int setup_ctx(struct ctx *ctx, struct q_entries *q)
68
67
  static void clean_ctx(struct ctx *ctx)
69
68
  {
70
69
  io_uring_queue_exit(&ctx->ring);
70
+ free(ctx->mem);
71
71
  }
72
72
 
73
73
  static int check_red(struct ctx *ctx, unsigned long i)
@@ -94,10 +94,12 @@ static int test(struct q_entries *q)
94
94
  int j, ret, batch;
95
95
 
96
96
  ret = setup_ctx(&ctx, q);
97
- if (ret == T_EXIT_SKIP)
97
+ if (ret == T_EXIT_SKIP) {
98
+ clean_ctx(&ctx);
98
99
  return T_EXIT_SKIP;
99
- else if (ret != T_EXIT_PASS)
100
+ } else if (ret != T_EXIT_PASS) {
100
101
  return ret;
102
+ }
101
103
 
102
104
  batch = 64;
103
105
  if (batch > q->sqes)
@@ -22,30 +22,6 @@
22
22
 
23
23
  static struct iovec *vecs;
24
24
 
25
- static unsigned long long utime_since(const struct timeval *s,
26
- const struct timeval *e)
27
- {
28
- long long sec, usec;
29
-
30
- sec = e->tv_sec - s->tv_sec;
31
- usec = (e->tv_usec - s->tv_usec);
32
- if (sec > 0 && usec < 0) {
33
- sec--;
34
- usec += 1000000;
35
- }
36
-
37
- sec *= 1000000;
38
- return sec + usec;
39
- }
40
-
41
- static unsigned long long utime_since_now(struct timeval *tv)
42
- {
43
- struct timeval end;
44
-
45
- gettimeofday(&end, NULL);
46
- return utime_since(tv, &end);
47
- }
48
-
49
25
  static int start_io(struct io_uring *ring, int fd, int do_write)
50
26
  {
51
27
  struct io_uring_sqe *sqe;
@@ -95,6 +95,8 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
95
95
 
96
96
  fd = open(file, open_flags);
97
97
  if (fd < 0) {
98
+ if (errno == EACCES || errno == EPERM)
99
+ return T_EXIT_SKIP;
98
100
  perror("file open");
99
101
  goto err;
100
102
  }
@@ -21,6 +21,7 @@
21
21
  #include <linux/mman.h>
22
22
  #include <sys/time.h>
23
23
  #include <sys/resource.h>
24
+ #include <sys/vfs.h>
24
25
  #include <limits.h>
25
26
 
26
27
  #include "helpers.h"
@@ -76,8 +77,13 @@ static int new_io_uring(int entries, struct io_uring_params *p)
76
77
 
77
78
  #define MAXFDS (UINT_MAX * sizeof(int))
78
79
 
80
+ #define OFS_MAGIC 0x794c7630
81
+ #define TMPFS_MAGIC 0x01021994
82
+ #define RAMFS_MAGIC 0x858458f6
83
+
79
84
  static void *map_filebacked(size_t size)
80
85
  {
86
+ struct statfs buf;
81
87
  int fd, ret;
82
88
  void *addr;
83
89
  char template[32] = "io_uring_register-test-XXXXXXXX";
@@ -87,8 +93,21 @@ static void *map_filebacked(size_t size)
87
93
  perror("mkstemp");
88
94
  return NULL;
89
95
  }
96
+ if (statfs(template, &buf) < 0) {
97
+ perror("statfs");
98
+ unlink(template);
99
+ close(fd);
100
+ return NULL;
101
+ }
90
102
  unlink(template);
91
103
 
104
+ /* virtual file systems may not present as file mapped */
105
+ if (buf.f_type == OFS_MAGIC || buf.f_type == RAMFS_MAGIC ||
106
+ buf.f_type == TMPFS_MAGIC) {
107
+ close(fd);
108
+ return NULL;
109
+ }
110
+
92
111
  ret = ftruncate(fd, size);
93
112
  if (ret < 0) {
94
113
  perror("ftruncate");
@@ -365,12 +384,12 @@ static int test_iovec_size(int fd)
365
384
 
366
385
  /* file-backed buffers -- not supported */
367
386
  buf = map_filebacked(2*1024*1024);
368
- if (!buf)
369
- status = 1;
370
- iov.iov_base = buf;
371
- iov.iov_len = 2*1024*1024;
372
- status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, -EOPNOTSUPP);
373
- munmap(buf, 2*1024*1024);
387
+ if (buf) {
388
+ iov.iov_base = buf;
389
+ iov.iov_len = 2*1024*1024;
390
+ status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, -EOPNOTSUPP);
391
+ munmap(buf, 2*1024*1024);
392
+ }
374
393
 
375
394
  /* bump up against the soft limit and make sure we get EFAULT
376
395
  * or whatever we're supposed to get. NOTE: this requires
@@ -26,6 +26,8 @@ static int do_iopoll(const char *fname)
26
26
 
27
27
  fd = open(fname, O_RDONLY | O_DIRECT);
28
28
  if (fd < 0) {
29
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
30
+ return T_EXIT_SKIP;
29
31
  perror("open");
30
32
  return T_EXIT_SKIP;
31
33
  }
@@ -39,6 +41,8 @@ static int do_iopoll(const char *fname)
39
41
  io_uring_submit(&ring);
40
42
 
41
43
  close(fd);
44
+ free(iov->iov_base);
45
+ free(iov);
42
46
  return T_EXIT_PASS;
43
47
  }
44
48
 
@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
95
95
 
96
96
  fd = open(fname, O_RDONLY | O_DIRECT);
97
97
  if (fd < 0) {
98
- if (errno == EINVAL) {
98
+ if (errno == EINVAL || errno == EACCES || errno == EPERM) {
99
99
  if (fname != argv[1])
100
100
  unlink(fname);
101
101
  return T_EXIT_SKIP;
@@ -87,7 +87,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write, int sqt
87
87
  }
88
88
  fd = open(file, open_flags);
89
89
  if (fd < 0) {
90
- if (errno == EINVAL)
90
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
91
91
  return 0;
92
92
  perror("file open");
93
93
  goto err;
@@ -230,7 +230,7 @@ static int test_io_uring_cqe_peek(const char *file)
230
230
 
231
231
  fd = open(file, O_RDONLY | O_DIRECT);
232
232
  if (fd < 0) {
233
- if (errno == EINVAL) {
233
+ if (errno == EINVAL || errno == EPERM || errno == EACCES) {
234
234
  io_uring_queue_exit(&ring);
235
235
  return T_EXIT_SKIP;
236
236
  }
@@ -302,7 +302,7 @@ static int test_io_uring_submit_enters(const char *file)
302
302
  open_flags = O_WRONLY | O_DIRECT;
303
303
  fd = open(file, open_flags);
304
304
  if (fd < 0) {
305
- if (errno == EINVAL)
305
+ if (errno == EINVAL || errno == EPERM || errno == EACCES)
306
306
  return T_EXIT_SKIP;
307
307
  perror("file open");
308
308
  goto err;