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
data/test/test_um.rb CHANGED
@@ -160,7 +160,9 @@ end
160
160
  class SleepTest < UMBaseTest
161
161
  def test_sleep
162
162
  t0 = monotonic_clock
163
+ assert_equal 0, machine.pending_count
163
164
  res = machine.sleep(0.1)
165
+ assert_equal 0, machine.pending_count
164
166
  t1 = monotonic_clock
165
167
  assert_in_range 0.09..0.13, t1 - t0
166
168
  assert_equal 0.1, res
@@ -173,7 +175,9 @@ class ReadTest < UMBaseTest
173
175
  w << 'foobar'
174
176
 
175
177
  buf = +''
178
+ assert_equal 0, machine.pending_count
176
179
  res = machine.read(r.fileno, buf, 3)
180
+ assert_equal 0, machine.pending_count
177
181
  assert_equal 3, res
178
182
  assert_equal 'foo', buf
179
183
 
@@ -339,7 +343,9 @@ class WriteTest < UMBaseTest
339
343
  def test_write
340
344
  r, w = IO.pipe
341
345
 
346
+ assert_equal 0, machine.pending_count
342
347
  machine.write(w.fileno, 'foo')
348
+ assert_equal 0, machine.pending_count
343
349
  assert_equal 'foo', r.readpartial(3)
344
350
 
345
351
  machine.write(w.fileno, 'bar', 2)
@@ -349,16 +355,33 @@ class WriteTest < UMBaseTest
349
355
  def test_write_bad_fd
350
356
  r, _w = IO.pipe
351
357
 
358
+ assert_equal 0, machine.pending_count
352
359
  assert_raises(Errno::EBADF) do
353
360
  machine.write(r.fileno, 'foo')
354
361
  end
362
+ assert_equal 0, machine.pending_count
363
+ end
364
+ end
365
+
366
+ class Closetest < UMBaseTest
367
+ def test_close
368
+ r, w = IO.pipe
369
+ machine.write(w.fileno, 'foo')
370
+ assert_equal 'foo', r.readpartial(3)
371
+
372
+ assert_equal 0, machine.pending_count
373
+ machine.close(w.fileno)
374
+ assert_equal 0, machine.pending_count
375
+ assert_equal '', r.read
376
+
377
+ assert_raises(Errno::EBADF) { machine.close(w.fileno) }
355
378
  end
356
379
  end
357
380
 
358
381
  class AcceptTest < UMBaseTest
359
382
  def setup
360
383
  super
361
- @port = 9000 + rand(1000)
384
+ @port = assign_port
362
385
  @server = TCPServer.open('127.0.0.1', @port)
363
386
  end
364
387
 
@@ -370,7 +393,9 @@ class AcceptTest < UMBaseTest
370
393
  def test_accept
371
394
  conn = TCPSocket.new('127.0.0.1', @port)
372
395
 
396
+ assert_equal 0, machine.pending_count
373
397
  fd = machine.accept(@server.fileno)
398
+ assert_equal 0, machine.pending_count
374
399
  assert_kind_of Integer, fd
375
400
  assert fd > 0
376
401
 
@@ -384,7 +409,7 @@ end
384
409
  class AcceptEachTest < UMBaseTest
385
410
  def setup
386
411
  super
387
- @port = 9000 + rand(1000)
412
+ @port = assign_port
388
413
  @server = TCPServer.open('127.0.0.1', @port)
389
414
  end
390
415
 
@@ -394,11 +419,15 @@ class AcceptEachTest < UMBaseTest
394
419
  end
395
420
 
396
421
  def test_accept_each
397
- conns = 3.times.map { TCPSocket.new('127.0.0.1', @port) }
422
+ conns = []
423
+ t = Thread.new do
424
+ sleep 0.1
425
+ 3.times { conns << TCPSocket.new('127.0.0.1', @port) }
426
+ end
398
427
 
399
428
  count = 0
400
429
  machine.accept_each(@server.fileno) do |fd|
401
- machine.write(fd, (count += 1).to_s)
430
+ count += 1
402
431
  break if count == 3
403
432
  end
404
433
 
@@ -406,9 +435,200 @@ class AcceptEachTest < UMBaseTest
406
435
  assert_equal 1, machine.pending_count
407
436
  machine.snooze
408
437
  assert_equal 0, machine.pending_count
438
+ ensure
439
+ t&.kill
440
+ end
441
+ end
442
+
443
+ class SocketTest < UMBaseTest
444
+ def test_socket
445
+ assert_equal 0, machine.pending_count
446
+ fd = machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0);
447
+ assert_equal 0, machine.pending_count
448
+ assert_kind_of Integer, fd
449
+ assert fd > 0
450
+
451
+ assert_raises(Errno::EDESTADDRREQ) { machine.write(fd, 'foo') }
452
+ end
453
+ end
454
+
455
+ class ConnectTest < UMBaseTest
456
+ def setup
457
+ super
458
+ @port = assign_port
459
+ @server = TCPServer.open('127.0.0.1', @port)
460
+ end
461
+
462
+ def teardown
463
+ @server&.close
464
+ super
465
+ end
466
+
467
+ def test_connect
468
+ t = Thread.new do
469
+ conn = @server.accept
470
+ conn.write('foobar')
471
+ sleep
472
+ end
473
+
474
+ fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0);
475
+ assert_equal 0, machine.pending_count
476
+ res = machine.connect(fd, '127.0.0.1', @port)
477
+ assert_equal 0, machine.pending_count
478
+ assert_equal 0, res
479
+
480
+ buf = +''
481
+ res = machine.read(fd, buf, 42)
482
+ assert_equal 6, res
483
+ assert_equal 'foobar', buf
484
+ ensure
485
+ t&.kill
486
+ end
409
487
 
410
- assert_equal '1', conns[0].readpartial(3)
411
- assert_equal '2', conns[1].readpartial(3)
412
- assert_equal '3', conns[2].readpartial(3)
488
+ def test_connect_with_bad_addr
489
+ fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0);
490
+ assert_equal 0, machine.pending_count
491
+ assert_raises(Errno::ENETUNREACH) { machine.connect(fd, 'a.b.c.d', @port) }
492
+ assert_equal 0, machine.pending_count
413
493
  end
414
494
  end
495
+
496
+ class SendTest < UMBaseTest
497
+ def setup
498
+ super
499
+ @port = assign_port
500
+ @server = TCPServer.open('127.0.0.1', @port)
501
+ end
502
+
503
+ def teardown
504
+ @server&.close
505
+ super
506
+ end
507
+
508
+ def test_send
509
+ t = Thread.new do
510
+ conn = @server.accept
511
+ str = conn.readpartial(42)
512
+ conn.write("You said: #{str}")
513
+ sleep
514
+ end
515
+
516
+ fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0);
517
+ res = machine.connect(fd, '127.0.0.1', @port)
518
+ assert_equal 0, res
519
+
520
+ res = machine.send(fd, 'foobar', 6, 0)
521
+ assert_equal 6, res
522
+
523
+ buf = +''
524
+ res = machine.read(fd, buf, 42)
525
+ assert_equal 16, res
526
+ assert_equal 'You said: foobar', buf
527
+ ensure
528
+ t&.kill
529
+ end
530
+ end
531
+
532
+ class RecvTest < UMBaseTest
533
+ def setup
534
+ super
535
+ @port = assign_port
536
+ @server = TCPServer.open('127.0.0.1', @port)
537
+ end
538
+
539
+ def teardown
540
+ @server&.close
541
+ super
542
+ end
543
+
544
+ def test_recv
545
+ t = Thread.new do
546
+ conn = @server.accept
547
+ conn.write('foobar')
548
+ sleep
549
+ end
550
+
551
+ fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0);
552
+ res = machine.connect(fd, '127.0.0.1', @port)
553
+ assert_equal 0, res
554
+
555
+ buf = +''
556
+ res = machine.recv(fd, buf, 42, 0)
557
+ assert_equal 6, res
558
+ assert_equal 'foobar', buf
559
+ ensure
560
+ t&.kill
561
+ end
562
+ end
563
+
564
+ class BindTest < UMBaseTest
565
+ def setup
566
+ super
567
+ @port = assign_port
568
+ end
569
+
570
+ def test_bind
571
+ assert_equal 0, machine.pending_count
572
+ fd = machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0);
573
+ res = machine.bind(fd, '127.0.0.1', @port)
574
+ assert_equal 0, res
575
+ assert_equal 0, machine.pending_count
576
+
577
+ peer = UDPSocket.new
578
+ peer.connect('127.0.0.1', @port)
579
+ peer.send 'foo', 0
580
+
581
+ buf = +''
582
+ res = machine.recv(fd, buf, 8192, 0)
583
+ assert_equal 3, res
584
+ assert_equal 'foo', buf
585
+ end
586
+
587
+ def test_bind_invalid_args
588
+ assert_equal 0, machine.pending_count
589
+
590
+ fd = machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0);
591
+ assert_raises(Errno::EACCES) { machine.bind(fd, 'foo.bar.baz', 3) }
592
+ assert_raises(Errno::EBADF) { machine.bind(-3, '127.0.01', 1234) }
593
+
594
+ assert_equal 0, machine.pending_count
595
+ end
596
+ end
597
+
598
+ class ListenTest < UMBaseTest
599
+ def setup
600
+ super
601
+ @port = assign_port
602
+ end
603
+
604
+ def test_listen
605
+ fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0);
606
+ machine.bind(fd, '127.0.0.1', @port)
607
+ res = machine.listen(fd, 5)
608
+ assert_equal 0, res
609
+ assert_equal 0, machine.pending_count
610
+
611
+ conn = nil
612
+ t = Thread.new do
613
+ sleep 0.01
614
+ conn = TCPSocket.new('127.0.0.1', @port)
615
+ end
616
+
617
+ conn_fd = machine.accept(fd)
618
+ t.join
619
+ assert_kind_of TCPSocket, conn
620
+
621
+ machine.send(conn_fd, 'foo', 3, 0)
622
+
623
+ buf = conn.readpartial(42)
624
+ assert_equal 'foo', buf
625
+ ensure
626
+ t&.kill
627
+ end
628
+ end
629
+
630
+ class ConstTest < UMBaseTest
631
+ def test_constants
632
+ assert_equal UM::SOCK_STREAM, UM::SOCK_STREAM
633
+ end
634
+ end
@@ -7,7 +7,7 @@ on:
7
7
 
8
8
  jobs:
9
9
  build:
10
- runs-on: ubuntu-22.04
10
+ runs-on: ubuntu-24.04
11
11
 
12
12
  strategy:
13
13
  fail-fast: false
@@ -19,6 +19,15 @@ jobs:
19
19
  cxx_pkg: g++-x86-64-linux-gnu
20
20
  cc: x86_64-linux-gnu-gcc
21
21
  cxx: x86_64-linux-gnu-g++
22
+ sanitize: 0
23
+
24
+ # x86-64 gcc asan
25
+ - arch: x86_64
26
+ cc_pkg: gcc-x86-64-linux-gnu
27
+ cxx_pkg: g++-x86-64-linux-gnu
28
+ cc: x86_64-linux-gnu-gcc
29
+ cxx: x86_64-linux-gnu-g++
30
+ sanitize: 1
22
31
 
23
32
  # x86-64 clang
24
33
  - arch: x86_64
@@ -28,6 +37,7 @@ jobs:
28
37
  cxx: clang++
29
38
  liburing_extra_flags: -Wshorten-64-to-32
30
39
  extra_flags: -Wmissing-prototypes -Wstrict-prototypes -Wunreachable-code-loop-increment -Wunreachable-code -Wmissing-variable-declarations -Wextra-semi-stmt
40
+ sanitize: 0
31
41
 
32
42
  # x86 (32-bit) gcc
33
43
  - arch: i686
@@ -35,6 +45,7 @@ jobs:
35
45
  cxx_pkg: g++-i686-linux-gnu
36
46
  cc: i686-linux-gnu-gcc
37
47
  cxx: i686-linux-gnu-g++
48
+ sanitize: 0
38
49
 
39
50
  # aarch64 gcc
40
51
  - arch: aarch64
@@ -42,6 +53,7 @@ jobs:
42
53
  cxx_pkg: g++-aarch64-linux-gnu
43
54
  cc: aarch64-linux-gnu-gcc
44
55
  cxx: aarch64-linux-gnu-g++
56
+ sanitize: 0
45
57
 
46
58
  # arm (32-bit) gcc
47
59
  - arch: arm
@@ -49,6 +61,7 @@ jobs:
49
61
  cxx_pkg: g++-arm-linux-gnueabi
50
62
  cc: arm-linux-gnueabi-gcc
51
63
  cxx: arm-linux-gnueabi-g++
64
+ sanitize: 0
52
65
 
53
66
  # riscv64
54
67
  - arch: riscv64
@@ -56,6 +69,7 @@ jobs:
56
69
  cxx_pkg: g++-riscv64-linux-gnu
57
70
  cc: riscv64-linux-gnu-gcc
58
71
  cxx: riscv64-linux-gnu-g++
72
+ sanitize: 0
59
73
 
60
74
  # powerpc64
61
75
  - arch: powerpc64
@@ -63,6 +77,7 @@ jobs:
63
77
  cxx_pkg: g++-powerpc64-linux-gnu
64
78
  cc: powerpc64-linux-gnu-gcc
65
79
  cxx: powerpc64-linux-gnu-g++
80
+ sanitize: 0
66
81
 
67
82
  # powerpc
68
83
  - arch: powerpc
@@ -70,6 +85,7 @@ jobs:
70
85
  cxx_pkg: g++-powerpc-linux-gnu
71
86
  cc: powerpc-linux-gnu-gcc
72
87
  cxx: powerpc-linux-gnu-g++
88
+ sanitize: 0
73
89
 
74
90
  # alpha
75
91
  - arch: alpha
@@ -77,6 +93,7 @@ jobs:
77
93
  cxx_pkg: g++-alpha-linux-gnu
78
94
  cc: alpha-linux-gnu-gcc
79
95
  cxx: alpha-linux-gnu-g++
96
+ sanitize: 0
80
97
 
81
98
  # mips64
82
99
  - arch: mips64
@@ -84,6 +101,7 @@ jobs:
84
101
  cxx_pkg: g++-mips64-linux-gnuabi64
85
102
  cc: mips64-linux-gnuabi64-gcc
86
103
  cxx: mips64-linux-gnuabi64-g++
104
+ sanitize: 0
87
105
 
88
106
  # mips
89
107
  - arch: mips
@@ -91,6 +109,7 @@ jobs:
91
109
  cxx_pkg: g++-mips-linux-gnu
92
110
  cc: mips-linux-gnu-gcc
93
111
  cxx: mips-linux-gnu-g++
112
+ sanitize: 0
94
113
 
95
114
  # hppa
96
115
  - arch: hppa
@@ -98,9 +117,11 @@ jobs:
98
117
  cxx_pkg: g++-hppa-linux-gnu
99
118
  cc: hppa-linux-gnu-gcc
100
119
  cxx: hppa-linux-gnu-g++
120
+ sanitize: 0
101
121
 
102
122
  env:
103
123
  FLAGS: -g -O3 -Wall -Wextra -Werror -Wno-sign-compare ${{matrix.extra_flags}}
124
+ SANITIZE: ${{matrix.sanitize}}
104
125
 
105
126
  # Flags for building sources in src/ dir only.
106
127
  LIBURING_CFLAGS: ${{matrix.liburing_extra_flags}}
@@ -128,10 +149,17 @@ jobs:
128
149
  ${{matrix.cxx}} --version;
129
150
 
130
151
  - name: Build
152
+ if: ${{matrix.sanitizer == '0'}}
131
153
  run: |
132
154
  ./configure --cc=${{matrix.cc}} --cxx=${{matrix.cxx}};
133
155
  make -j$(nproc) V=1 CPPFLAGS="-Werror" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS";
134
156
 
157
+ - name: Build
158
+ if: ${{matrix.sanitizer == '1'}}
159
+ run: |
160
+ ./configure --cc=${{matrix.cc}} --cxx=${{matrix.cxx}} --enable-sanitizer;
161
+ make -j$(nproc) V=1 CPPFLAGS="-Werror" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS";
162
+
135
163
  - name: Test install command
136
164
  run: |
137
165
  sudo make install;
@@ -26,6 +26,7 @@
26
26
  /examples/proxy
27
27
  /examples/send-zerocopy
28
28
  /examples/rsrc-update-bench
29
+ /examples/kdigest
29
30
 
30
31
  /test/*.t
31
32
  /test/*.dmesg
@@ -1,3 +1,18 @@
1
+ liburing-2.8 release
2
+ - Add support for incrementally/partially consumed provided buffers,
3
+ usable with the provided buffer ring support.
4
+ - Add support for foo_and_wait_min_timeout(), where it's possible to
5
+ define a minimum timeout for waiting to get batches of completions,
6
+ but if that fails, extend for a longer timeout without having any
7
+ extra context switches.
8
+ - Add support for using different clock sources for completion waiting.
9
+ - Great increase coverage of test cases, test case improvements and
10
+ fixes.
11
+ - Man page updates
12
+ - Don't leak _GNU_SOURCE via pkb-config --cflags
13
+ - Support for address sanitizer
14
+ - Add examples/kdigest sample program
15
+
1
16
  liburing-2.7 release
2
17
 
3
18
  - Man page updates
@@ -0,0 +1,165 @@
1
+ Introduction
2
+ ============
3
+
4
+ liburing welcomes contributions, whether they be bug fixes, features, or
5
+ documentation additions/updates. However, we do have some rules in place
6
+ to govern the sanity of the project, and all contributions should follow
7
+ the guidelines in this document. The main reasons for the rules are:
8
+
9
+ 1) Keep the code consistent
10
+ 2) Keep the git repository consistent
11
+ 3) Maintain bisectability
12
+
13
+ Coding style
14
+ ============
15
+
16
+ Generally, all the code in liburing should follow the same style. A few
17
+ known exceptions exist, like syzbot test cases that got committed rather
18
+ than re-writing them in a saner format. Any change you make, please
19
+ follow the style of the code around you.
20
+
21
+ Commit format
22
+ =============
23
+
24
+ Each commit should do one thing, and one thing only. If you find yourself,
25
+ in the commit message, adding phrases like "Also do [...]" or "While in
26
+ here [...]", then that's a sign that the change should have been split
27
+ into multiple commits. If your change includes some refactoring of code to
28
+ make your change possible, then that refactoring should be a separate
29
+ commit, done first. That means this preparatory commit won't have any
30
+ functional changes, and hence should be a no-op. It also means that your
31
+ main commit, with the change that you actually care about, will be smaller
32
+ and easier to review.
33
+
34
+ Each commit must stand on its own in terms of what it provides, and how it
35
+ works. Lots of changes are just a single commit, but for something a bit
36
+ more involved, it's not uncommon to have a pull request contain multiple
37
+ commits. Make each commit as simple as possible, and not any simpler. We'd
38
+ much rather see 10 simple commits than 2 more complicated ones. If you
39
+ stumble across something that needs fixing while making an unrelated
40
+ change, then please make that change as a separate commit, explaining why
41
+ it's being made.
42
+
43
+ Each commit in a series must be buildable, it's not enough that the end
44
+ result is buildable. See reason 3 in the introduction for why that's the
45
+ case.
46
+
47
+ No fixup commits! Sometimes people post a change and errors are pointed
48
+ out in the commit, and the author then does a followup fix for that
49
+ error. This isn't acceptable, please squash fixup commits into the
50
+ commit that introduced the problem in the first place. This is done by
51
+ amending the fix into the original commit that caused the issue. You can
52
+ do that with git rebase -i <sha> and arrange the commit order such that
53
+ the fixup is right after the original commit, and then use 's' (for
54
+ squash) to squash the fixup into the original commit. Don't forget to
55
+ edit the commit message while doing that, as git will combine the two
56
+ commit messages into one. Or you can do it manually. Once done, force
57
+ push your rewritten git history. See reasons 1-3 in the introduction
58
+ series for why that is.
59
+
60
+ Commit message
61
+ ==============
62
+
63
+ A good commit explains the WHY of a commit - explain the reason for this
64
+ commit to exist. Don't explain what the code in commit does, that should
65
+ be readily apparent from just reading the code. If that isn't the case,
66
+ then a comment in the code is going to be more useful than a lengthy
67
+ explanation in the commit message. liburing commits use the following
68
+ format:
69
+
70
+ Title
71
+
72
+ Body of commit
73
+
74
+ Signed-off-by: ```My Identity <my@email.com>```
75
+
76
+ That is, a descriptive title on the first line, then an empty line, then
77
+ the body of the commit message, then an empty line, and finally an SOB
78
+ tag. The signed-off-by exists to provide proof of origin, see the
79
+ [DCO](https://developercertificate.org/).
80
+
81
+ Example commit:
82
+
83
+ ```
84
+ commit 0fe5c09195c0918f89582dd6ff098a58a0bdf62a
85
+ Author: Jens Axboe <axboe@kernel.dk>
86
+ Date: Fri Sep 6 15:54:04 2024 -0600
87
+
88
+ configure: fix ublk_cmd header check
89
+
90
+ The previous commit is mixing private structures and defines with public
91
+ uapi ones. Testing for UBLK_U_CMD_START_DEV is fine, CTRL_CMD_HAS_DATA
92
+ is not. And struct ublk_ctrl_cmd_data is not a public struct.
93
+
94
+ Fixes: 83bc535a3118 ("configure: don't enable ublk if modern commands not available")
95
+ Signed-off-by: Jens Axboe <axboe@kernel.dk>
96
+ ```
97
+
98
+ Since this change is pretty trivial, a huge explanation need not be given
99
+ as to the reasonings for the change. However, for more complicated
100
+ changes, better reasonings should be given.
101
+
102
+ A Fixes line can be added if this commit fixes an issue in a previous
103
+ commit. That kind of meta data can be useful down the line for finding
104
+ dependencies between commits. Adding the following to your .gitconfig:
105
+
106
+ ```
107
+ [pretty]
108
+ fixes = Fixes: %h (\"%s\")
109
+ ```
110
+
111
+ and running ```git fixes <sha>``` will then generate the correctly
112
+ formatted Fixes line for the commit. Likewise, other meta data can be:
113
+
114
+ Link: https://somesite/somewhere
115
+
116
+ can be useful to link to a discussion around the issue that led to this
117
+ commit, perhaps a bug report. This can be a GitHub issue as well. If a
118
+ commit closes/solves a GitHub issue, than:
119
+
120
+ Closes: https://github.com/axboe/liburing/issues/XXXX
121
+
122
+ can also be used.
123
+
124
+ Each commit message should be formatted so each full line is 72-74 chars
125
+ wide. For many of us, GitHub is not the primary location, and git log is
126
+ often used in a terminal to browse the repo. Breaking lines at 72-74
127
+ characters retains readability in an xterm/terminal.
128
+
129
+ Pull Requests
130
+ =============
131
+
132
+ The git repository itself is the canonical location for information. It's
133
+ quite fine to provide a lengthy explanation for a pull request on GitHub,
134
+ however please ensure that this doesn't come at the expense of the commit
135
+ messages themselves being lacking. The commit messages should stand on
136
+ their own and contain everything that you'd otherwise put in the PR
137
+ message. If you've worked on projects that send patches before, consider
138
+ the PR message similar to the cover letter for a series of patches.
139
+
140
+ Most contributors seem to use GH for sending patches, which is fine. If
141
+ you prefer using email, then patches can also be sent to the io_uring
142
+ mailing list: io-uring@vger.kernel.org.
143
+
144
+ liburing doesn't squash/rebase-on-merge, or other heinous practices
145
+ sometimes seen elsewhere. Whatever sha your commit has in your tree is
146
+ what it'll have in the upstream tree. Patches are applied directly, and
147
+ pull requests are merged with a merge commit. If meta data needs to go
148
+ into the merge commit, then it will go into the merge commit message.
149
+ This means that you don't need to continually rebase your changes on top
150
+ of the master branch.
151
+
152
+ Testing changes
153
+ ===============
154
+
155
+ You should ALWAYS test your changes, no matter how trivial or obviously
156
+ correct they may seem. Nobody is infallible, and making mistakes is only
157
+ human.
158
+
159
+ liburing contains a wide variety of functional tests. If you make changes
160
+ to liburing, then you should run the test cases. This is done by building
161
+ the repo and running ```make runtests```. Note that some of the liburing
162
+ tests test for defects in older kernels, and hence it's possible that they
163
+ will crash on an outdated kernel that doesn't contain fixes from the
164
+ stable kernel tree. If in doubt, building and running the tests in a vm is
165
+ encouraged.
@@ -28,6 +28,8 @@ for opt do
28
28
  ;;
29
29
  --use-libc) use_libc=yes
30
30
  ;;
31
+ --enable-sanitizer) use_sanitizer=yes
32
+ ;;
31
33
  *)
32
34
  echo "ERROR: unknown option $opt"
33
35
  echo "Try '$0 --help' for more information"
@@ -76,6 +78,7 @@ Options: [defaults in brackets after descriptions]
76
78
  --cc=CMD use CMD as the C compiler
77
79
  --cxx=CMD use CMD as the C++ compiler
78
80
  --use-libc use libc for liburing (useful for hardening)
81
+ --enable-sanitizer compile liburing with the address and undefined behaviour sanitizers. (useful for debugging)
79
82
  EOF
80
83
  exit 0
81
84
  fi
@@ -471,6 +474,26 @@ fi
471
474
  print_config "has_fanotify" "$has_fanotify"
472
475
  ####################################################
473
476
 
477
+ ##########################################
478
+ # check for ublk headers
479
+ ublk_header="no"
480
+ cat > $TMPC << EOF
481
+ #include <string.h>
482
+ #include <sys/ioctl.h>
483
+ #include <linux/ublk_cmd.h>
484
+ int main(int argc, char **argv)
485
+ {
486
+ struct ublksrv_ctrl_cmd cmd = { };
487
+
488
+ cmd.addr = UBLK_U_CMD_START_DEV;
489
+ return cmd.queue_id;
490
+ }
491
+ EOF
492
+ if compile_prog "" "" "ublk_header"; then
493
+ ublk_header="yes"
494
+ fi
495
+ print_config "ublk_header" "$ublk_header"
496
+
474
497
  if test "$liburing_nolibc" = "yes"; then
475
498
  output_sym "CONFIG_NOLIBC"
476
499
  fi
@@ -510,6 +533,15 @@ fi
510
533
  if test "$futexv" = "yes"; then
511
534
  output_sym "CONFIG_HAVE_FUTEXV"
512
535
  fi
536
+ if test "$ublk_header" = "yes"; then
537
+ output_sym "CONFIG_HAVE_UBLK_HEADER"
538
+ fi
539
+ if test "$use_sanitizer" = "yes"; then
540
+ output_sym "CONFIG_USE_SANITIZER"
541
+ print_config "use sanitizer" "yes"
542
+ else
543
+ print_config "use sanitizer" "no"
544
+ fi
513
545
 
514
546
  echo "CC=$cc" >> $config_host_mak
515
547
  print_config "CC" "$cc"
@@ -13,6 +13,12 @@ endif
13
13
  LDFLAGS ?=
14
14
  override LDFLAGS += -L../src/ -luring -lpthread
15
15
 
16
+ ifeq ($(CONFIG_USE_SANITIZER),y)
17
+ override CFLAGS += -fsanitize=address,undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls
18
+ override CPPFLAGS += -fsanitize=address,undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls
19
+ override LDFLAGS += -fsanitize=address,undefined
20
+ endif
21
+
16
22
  example_srcs := \
17
23
  io_uring-close-test.c \
18
24
  io_uring-cp.c \
@@ -24,7 +30,8 @@ example_srcs := \
24
30
  poll-bench.c \
25
31
  send-zerocopy.c \
26
32
  rsrc-update-bench.c \
27
- proxy.c
33
+ proxy.c \
34
+ kdigest.c
28
35
 
29
36
  all_targets :=
30
37