uringmachine 0.2 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -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 +340 -53
  10. data/ext/um/um.h +33 -11
  11. data/ext/um/um_class.c +101 -119
  12. data/ext/um/um_const.c +184 -0
  13. data/ext/um/um_op.c +39 -18
  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 +13 -12
  18. data/test/test_um.rb +301 -3
  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
@@ -120,16 +120,21 @@ static int test_grow(struct io_uring *ring)
120
120
  fds = open_files(1, 0, off);
121
121
  ret = io_uring_register_files_update(ring, off, fds, 1);
122
122
  if (ret != 1) {
123
- if (off == 300 && ret == -EINVAL)
123
+ if (off == 300 && ret == -EINVAL) {
124
+ free(fds);
124
125
  break;
126
+ }
125
127
  fprintf(stderr, "%s: update ret=%d\n", __FUNCTION__, ret);
128
+ free(fds);
126
129
  break;
127
130
  }
128
131
  if (off >= 300) {
129
132
  fprintf(stderr, "%s: Succeeded beyond end-of-list?\n", __FUNCTION__);
133
+ free(fds);
130
134
  goto err;
131
135
  }
132
136
  off++;
137
+ free(fds);
133
138
  } while (1);
134
139
 
135
140
  ret = io_uring_unregister_files(ring);
@@ -363,8 +368,10 @@ static int test_basic(struct io_uring *ring, int fail)
363
368
  ret = io_uring_register_files(ring, files, 100);
364
369
  if (ret) {
365
370
  if (fail) {
366
- if (ret == -EBADF || ret == -EFAULT)
371
+ if (ret == -EBADF || ret == -EFAULT) {
372
+ close_files(files, nr_files, 0);
367
373
  return 0;
374
+ }
368
375
  }
369
376
  fprintf(stderr, "%s: register %d\n", __FUNCTION__, ret);
370
377
  goto err;
@@ -631,6 +638,7 @@ static int test_sparse_updates(void)
631
638
  ret = io_uring_register_files(&ring, fds, 256);
632
639
  if (ret) {
633
640
  fprintf(stderr, "file_register: %d\n", ret);
641
+ free(fds);
634
642
  return ret;
635
643
  }
636
644
 
@@ -639,6 +647,7 @@ static int test_sparse_updates(void)
639
647
  ret = io_uring_register_files_update(&ring, i, &newfd, 1);
640
648
  if (ret != 1) {
641
649
  fprintf(stderr, "file_update: %d\n", ret);
650
+ free(fds);
642
651
  return ret;
643
652
  }
644
653
  }
@@ -650,6 +659,7 @@ static int test_sparse_updates(void)
650
659
  ret = io_uring_register_files(&ring, fds, 256);
651
660
  if (ret) {
652
661
  fprintf(stderr, "file_register: %d\n", ret);
662
+ free(fds);
653
663
  return ret;
654
664
  }
655
665
 
@@ -658,12 +668,14 @@ static int test_sparse_updates(void)
658
668
  ret = io_uring_register_files_update(&ring, i, &newfd, 1);
659
669
  if (ret != 1) {
660
670
  fprintf(stderr, "file_update: %d\n", ret);
671
+ free(fds);
661
672
  return ret;
662
673
  }
663
674
  }
664
675
  io_uring_unregister_files(&ring);
665
676
 
666
677
  io_uring_queue_exit(&ring);
678
+ free(fds);
667
679
  return 0;
668
680
  }
669
681
 
@@ -174,7 +174,7 @@ static int test_update_no_table(void)
174
174
  ret = cqe->res;
175
175
  io_uring_cqe_seen(&ring, cqe);
176
176
  if (ret != -EMFILE && ret != -EINVAL && ret != -EOVERFLOW &&
177
- ret != -ENXIO) {
177
+ ret != -ENXIO && ret != -EBADF) {
178
178
  fprintf(stderr, "Bad cqe res: %d\n", ret);
179
179
  goto fail;
180
180
  }
@@ -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;