Skip to main content

Crate liburing_rs

Crate liburing_rs 

Source
Expand description

Rust bindings for io_uring via a transliteration of Jens Axboe’s liburing.

Crates.io lib.rs Documentation

Building this crate successfully may require the following in your .cargo/config.toml:

[env]
CLANG_PATH = "/usr/bin/clang-20"
LIBCLANG_PATH = "/usr/lib/llvm-20/lib"

in order for bindgen to successfully generate the required struct definitions.


This crate implements an almost pure Rust version of Jens Axboe’s liburing. All the good names were taken so the package’s name is axboe-liburing but the imported crate is liburing_rs.

liburing has tremendous value in that it’s a low-level unopinionated set of helpers that form a complete vocabulary for using io_uring. Originally designed as a set of test helpers, liburing is used to setup and teardown rings, register buffer groups, and create and manage SQEs and CQEs. liburing’s API offers users a comprehensive way of using io_uring in a simple manner.

axboe-liburing implements the entire header liburing.h in native Rust so that everything is as equally inlined as if you were using the library from C or C++. This covers around 142 public functions.

Add the crate with:

cargo add axboe-liburing

axboe-liburing ships with the liburing source and builds liburing.a, statically linking it in via the build.rs. This means that axboe-liburing requires a C toolchain be present on the system in order to build. Typical conventions are followed, the environment variables CC, CXX are used to set the C and C++ compilers.

CC=clang-19 CXX=clang++-19 cargo build

Read the docs for each module in Modules for a high-level overview of io_uring and each feature.

§Building Tests

axboe-liburing includes a few Rust-specific tests to verify the basic flow works but the lion’s share of the testing is in recycling what already exists in liburing proper. To this end, we need objcopy in order to weaken the io_uring_get_sqe() symbol present in liburing.a. When cross-compiling, it can be important to specify the objcopy being used. The objcopy binary can be set via the OBJCOPY environment variable. objcopy ships with gcc toolchains.

Example building liburing tests with liburing-rs:

export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export OBJCOPY=aarch64-linux-gnu-objcopy
export CARGO_TOOLCHAIN=aarch64-unknown-linux-gnu
make -C test liburing_rs_tests -j$(nproc)

axboe-liburing is also tested using sanitizers as well. To build the tests with sanitization enabled, one needs to enable the sanitizers feature. This causes the crate to build liburing.a with sanitization enabled.

RUSTFLAGS='-Zsanitizer=address' cargo +nightly test --features sanitizers --target x86_64-unknown-linux-gnu -Zbuild-std

For building the liburing_rs_tests target in test/Makefile, one needs to first configure the project to use sanitization.

# for liburing_rs_test.a, needed for the C test files to link against
./configure --enable-sanitizer

# builds everything, including C the default tests which are relied upon to exist by other tests
make all -j$(nproc)

# build a static library that exports everything from the Rust crate and use a shim header in the
# test files so that they link against the Rust-derived staticlib
make -C test liburing_rs_tests -j$(nproc)

§Example

Examples can be found in the main repo: https://github.com/axboe/liburing/tree/master/examples

extern crate liburing_rs;

use std::{mem::zeroed, ptr, time::Duration};

use liburing_rs::*;

pub fn queue_init() {
    // Setup the ring.
    //
    // We create a stack-local instance of `struct io_uring` and use
    // the `io_uring_queue_init` function to initialize all of its
    // fields, using a submission queue size of 64. liburing sets
    // the size of the CQ to twice the SQ size by default.
    //
    let mut ring = unsafe { zeroed::<io_uring>() };
    let ring = &raw mut ring;
    let r = unsafe { io_uring_queue_init(64, ring, 0) };
    assert_eq!(r, 0);

    // Grab a pointer to an unused SQE from the SQ
    let sqe = unsafe { io_uring_get_sqe(ring) };
    assert!(!sqe.is_null());

    // We're going to create an SQE that completes after a specified
    // amount of time, in this case 250ms. We introduce a cast for `ts`
    // because liburing expects a pointer to `__kernel_timespec` which
    // is layout compatible.
    //
    let dur = Duration::from_millis(250);
    let mut ts: timespec = dur.into();
    let ts = (&raw mut ts).cast();

    unsafe { io_uring_prep_timeout(sqe, ts, 0, 0) };
    unsafe { io_uring_sqe_set_data64(sqe, 1234) };

    // Submit the SQ to the kernel for processing. `io_uring_submit` returns
    // the number of submitted entries that are going to be processed. In this case,
    // we only have 1 work item.
    //
    let n = unsafe { io_uring_submit(ring) };
    assert_eq!(n, 1);

    // Grab the first CQE off the queue and make sure it has the same `user_data`
    // field that we originally set.
    //
    let mut cqe = ptr::null_mut::<io_uring_cqe>();
    unsafe { io_uring_wait_cqe(ring, &raw mut cqe) };

    assert!(!cqe.is_null());
    assert_eq!(unsafe { (*cqe).user_data }, 1234);

    // Mark the CQE as seen so that its spot can be reused as more
    // completions arrive.
    //
    unsafe { io_uring_cqe_seen(ring, cqe) };

    // Teardown the ring.
    //
    unsafe { io_uring_queue_exit(ring) };
}

Modules§

io_uring_cancelation
io_uring request cancelation overview
io_uring_linked_requests
io_uring linked requests overview
io_uring_multishot
io_uring multishot requests overview
io_uring_overview
Asynchronous I/O facility
io_uring_provided_buffers
io_uring provided buffer rings overview
io_uring_registered_buffers
io_uring registered buffers overview
io_uring_registered_files
io_uring registered files overview
io_uring_setup_flags
io_uring ring setup flags overview
io_uring_sqpoll
io_uring submission queue polling overview

Structs§

io_uring
io_uring_clone_buffers
Clones registered buffers between rings
io_uring_cq
io_uring_cqe
io_uring_sq
io_uring_sqe

Constants§

IOSQE_ASYNC
IOSQE_BUFFER_SELECT
IOSQE_CQE_SKIP_SUCCESS
IOSQE_FIXED_FILE
IOSQE_IO_DRAIN
IOSQE_IO_HARDLINK
IOSQE_IO_LINK

Functions§

__io_uring_buf_ring_cq_advance
Advance index of provided buffer and CQ ring
__io_uring_clone_buffers
Clones registered buffers between rings
__io_uring_clone_buffers_offset
Clones registered buffers between rings
io_uring_buf_ring_add
Add buffers to a shared buffer ring
io_uring_buf_ring_advance
Advance index of provided buffer in buffer ring
io_uring_buf_ring_available
Return number of unconsumed provided ring buffer entries
io_uring_buf_ring_cq_advance
Advance index of provided buffer and CQ ring
io_uring_buf_ring_init
Initialise a buffer ring
io_uring_buf_ring_mask
Calculate buffer ring mask size
io_uring_check_version
Functions and macros to check the liburing version
io_uring_clone_buffers
Clones registered buffers between rings
io_uring_clone_buffers_offset
Clones registered buffers between rings
io_uring_close_ring_fd
Close a ring file descriptor and use it only via registered index
io_uring_cq_advance
Mark one or more io_uring completion events as consumed
io_uring_cq_eventfd_enabled
Check if eventfd notifications are enabled
io_uring_cq_eventfd_toggle
Toggle eventfd notifications on or off
io_uring_cq_has_overflow
Returns if there are overflow entries waiting to move to the CQ ring
io_uring_cq_ready
Returns number of unconsumed ready entries in the CQ ring
io_uring_cqe_get_data
Get user data for completion event
io_uring_cqe_get_data64
Get user data for completion event
io_uring_cqe_nr
Return the number of CQ ring slots consumed by a CQE
io_uring_cqe_seen
Mark io_uring completion event as consumed
io_uring_enable_rings
Enable a disabled ring
io_uring_enter
Initiate and/or complete asynchronous I/O
io_uring_enter2
Initiate and/or complete asynchronous I/O
io_uring_for_each_cqe
Iterate pending completion events
io_uring_free_buf_ring
Register and free a buffer ring for provided buffers
io_uring_free_probe
Free probe instance
io_uring_get_events
Flush outstanding requests to CQE ring
io_uring_get_probe
Get probe instance
io_uring_get_probe_ring
Get probe information from an existing ring
io_uring_get_sqe
Get the next available submission queue entry from the submission queue
io_uring_get_sqe128
Get the next available 128-byte submission queue entry from the submission queue
io_uring_major_version
Functions and macros to check the liburing version
io_uring_minor_version
Functions and macros to check the liburing version
io_uring_opcode_supported
Is op code supported?
io_uring_peek_batch_cqe
Check if an io_uring completion event is available
io_uring_peek_cqe
Check if an io_uring completion event is available
io_uring_prep_accept
Prepare an accept request
io_uring_prep_accept_direct
Prepare an accept request
io_uring_prep_bind
Prepare a bind request
io_uring_prep_cancel
Prepare a cancelation request
io_uring_prep_cancel64
Prepare a cancelation request
io_uring_prep_cancel_fd
Prepare a cancelation request
io_uring_prep_close
Prepare a file descriptor close request
io_uring_prep_close_direct
Prepare a file descriptor close request
io_uring_prep_cmd_discard
Prepare a discard command
io_uring_prep_cmd_getsockname
Prepare a getsockname or getpeername request
io_uring_prep_cmd_sock
Prepare a command request for a socket
io_uring_prep_connect
Prepare a connect request
io_uring_prep_epoll_ctl
Prepare an epoll_ctl request
io_uring_prep_epoll_wait
Prepare an epoll wait request
io_uring_prep_fadvise
Prepare a fadvise request
io_uring_prep_fadvise64
Prepare a fadvise request
io_uring_prep_fallocate
Prepare a fallocate request
io_uring_prep_fgetxattr
Prepare a request to get an extended attribute value
io_uring_prep_files_update
Prepare a registered file update request
io_uring_prep_fixed_fd_install
Prepare fixed file fd installation request
io_uring_prep_fsetxattr
Prepare a request to set an extended attribute value
io_uring_prep_fsync
Prepare an fsync request
io_uring_prep_ftruncate
Prepare an ftruncate request
io_uring_prep_futex_wait
Prepare a futex wait request
io_uring_prep_futex_waitv
Prepare a futex waitv request
io_uring_prep_futex_wake
Prepare a futex wake request
io_uring_prep_getxattr
Prepare a request to get an extended attribute value
io_uring_prep_link
Prepare a linkat request
io_uring_prep_link_timeout
A timeout request for linked sqes
io_uring_prep_linkat
Prepare a linkat request
io_uring_prep_listen
Prepare a listen request
io_uring_prep_madvise
Prepare a madvise request
io_uring_prep_madvise64
Prepare a madvise request
io_uring_prep_mkdir
Prepare an mkdirat request
io_uring_prep_mkdirat
Prepare an mkdirat request
io_uring_prep_msg_ring
Send a message to another ring
io_uring_prep_msg_ring_cqe_flags
Send a message to another ring
io_uring_prep_msg_ring_fd
Send a direct descriptor to another ring
io_uring_prep_msg_ring_fd_alloc
Send a direct descriptor to another ring
io_uring_prep_multishot_accept
Prepare an accept request
io_uring_prep_multishot_accept_direct
Prepare an accept request
io_uring_prep_nop
Prepare a nop request
io_uring_prep_nop128
Prepare a nop request
io_uring_prep_open
Prepare an openat request
io_uring_prep_open_direct
Prepare an openat request
io_uring_prep_openat
Prepare an openat request
io_uring_prep_openat2
Prepare an openat2 request
io_uring_prep_openat2_direct
Prepare an openat2 request
io_uring_prep_openat_direct
Prepare an openat request
io_uring_prep_pipe
Prepare a pipe creation request
io_uring_prep_pipe_direct
Prepare a pipe creation request
io_uring_prep_poll_add
Prepare a poll request
io_uring_prep_poll_multishot
Prepare a poll request
io_uring_prep_poll_remove
Prepare a poll deletion request
io_uring_prep_poll_update
Update an existing poll request
io_uring_prep_provide_buffers
Prepare a provide buffers request
io_uring_prep_read
Prepare I/O read request
io_uring_prep_read_fixed
Prepare I/O read request with registered buffer
io_uring_prep_read_multishot
Prepare I/O read multishot request
io_uring_prep_readv
Prepare vector I/O read request
io_uring_prep_readv2
Prepare vector I/O read request with flags
io_uring_prep_readv_fixed
Prepare a vectored read using fixed buffers
io_uring_prep_recv
Prepare a recv request
io_uring_prep_recv_multishot
Prepare a recv request
io_uring_prep_recvmsg
Prepare a recvmsg request
io_uring_prep_recvmsg_multishot
Prepare a recvmsg request
io_uring_prep_remove_buffers
Prepare a remove buffers request
io_uring_prep_rename
Prepare a renameat request
io_uring_prep_renameat
Prepare a renameat request
io_uring_prep_send
Prepare a send request
io_uring_prep_send_bundle
Prepare a send request
io_uring_prep_send_set_addr
Set address details for send requests
io_uring_prep_send_zc
Prepare a zerocopy send request
io_uring_prep_send_zc_fixed
Prepare a zerocopy send request
io_uring_prep_sendmsg
Prepare a sendmsg request
io_uring_prep_sendmsg_zc
Prepare a sendmsg request
io_uring_prep_sendmsg_zc_fixed
Prepare a zero-copy sendmsg using fixed buffers
io_uring_prep_sendto
Prepare a send request
io_uring_prep_setxattr
Prepare a request to set an extended attribute value
io_uring_prep_shutdown
Prepare a shutdown request
io_uring_prep_socket
Prepare a socket creation request
io_uring_prep_socket_direct
Prepare a socket creation request
io_uring_prep_socket_direct_alloc
Prepare a socket creation request
io_uring_prep_splice
Prepare an splice request
io_uring_prep_statx
Prepare a statx request
io_uring_prep_symlink
Prepare a symlinkat request
io_uring_prep_symlinkat
Prepare a symlinkat request
io_uring_prep_sync_file_range
Prepare a sync_file_range request
io_uring_prep_tee
Prepare a tee request
io_uring_prep_timeout
Prepare a timeout request
io_uring_prep_timeout_remove
Prepare a request to update an existing timeout
io_uring_prep_timeout_update
Prepare a request to update an existing timeout
io_uring_prep_unlink
Prepare an unlinkat request
io_uring_prep_unlinkat
Prepare an unlinkat request
io_uring_prep_uring_cmd
Prepare a uring_cmd request
io_uring_prep_uring_cmd128
Prepare a uring_cmd request
io_uring_prep_waitid
Prepare a waitid request
io_uring_prep_write
Prepare I/O write request
io_uring_prep_write_fixed
Prepare I/O write request with registered buffer
io_uring_prep_writev
Prepare vector I/O write request
io_uring_prep_writev2
Prepare vector I/O write request with flags
io_uring_prep_writev_fixed
Prepare a vectored write using fixed buffers
io_uring_queue_exit
Tear down io_uring submission and completion queues
io_uring_queue_init
Setup io_uring submission and completion queues
io_uring_queue_init_mem
Setup io_uring submission and completion queues
io_uring_queue_init_params
Setup io_uring submission and completion queues
io_uring_queue_mmap
Mmap io_uring ring after setup
io_uring_recvmsg_cmsg_firsthdr
Access data from multishot recvmsg
io_uring_recvmsg_cmsg_nexthdr
Access data from multishot recvmsg
io_uring_recvmsg_name
Access data from multishot recvmsg
io_uring_recvmsg_payload
Access data from multishot recvmsg
io_uring_recvmsg_payload_length
Access data from multishot recvmsg
io_uring_recvmsg_validate
Access data from multishot recvmsg
io_uring_register
Register files or user buffers for asynchronous I/O
io_uring_register_bpf_filter
Register classic BPF filters for io_uring operations
io_uring_register_bpf_filter_task
Register classic BPF filters for io_uring operations
io_uring_register_buf_ring
Register buffer ring for provided buffers
io_uring_register_buffers
Register buffers for fixed buffer operations
io_uring_register_buffers_sparse
Register buffers for fixed buffer operations
io_uring_register_buffers_tags
Register buffers for fixed buffer operations
io_uring_register_buffers_update_tag
Register buffers for fixed buffer operations
io_uring_register_clock
Set clock source for event waiting
io_uring_register_eventfd
Register an eventfd with a ring
io_uring_register_eventfd_async
Register an eventfd with a ring
io_uring_register_file_alloc_range
Set range for fixed file allocations
io_uring_register_files
Register file descriptors
io_uring_register_files_sparse
Register file descriptors
io_uring_register_files_tags
Register file descriptors
io_uring_register_files_update
Register file descriptors
io_uring_register_files_update_tag
Register file descriptors
io_uring_register_ifq
Register a zero-copy receive interface queue
io_uring_register_iowq_affgnu
Register async worker CPU affinities
io_uring_register_iowq_max_workers
Modify the maximum allowed async workers
io_uring_register_napi
Register NAPI busy poll settings
io_uring_register_personality
Register credentials with io_uring
io_uring_register_probe
Register probe with io_uring
io_uring_register_query
Query io_uring capabilities and feature support
io_uring_register_region
Register a memory region
io_uring_register_restrictions
Register restrictions with io_uring
io_uring_register_ring_fd
Register a ring file descriptor
io_uring_register_sync_cancel
Issue a synchronous cancelation request
io_uring_register_sync_msg
Send a synchronous message to another ring
io_uring_register_wait_reg
Register wait regions with io_uring
io_uring_register_zcrx_ctrl
Perform control operations on a zero-copy receive context
io_uring_resize_rings
Resize the SQ and CQ rings
io_uring_ring_dontfork
Prevent ring memory from being shared after fork
io_uring_setup
Setup a context for performing asynchronous I/O
io_uring_setup_buf_ring
Setup and register buffer ring for provided buffers
io_uring_sq_ready
Number of unconsumed or unsubmitted entries in the SQ ring
io_uring_sq_space_left
Free space in the SQ ring
io_uring_sqe_set_buf_group
Set buf group for submission queue event
io_uring_sqe_set_data
Set user data for submission queue event
io_uring_sqe_set_data64
Set user data for submission queue event
io_uring_sqe_set_flags
Set flags for submission queue entry
io_uring_sqring_wait
Wait for free space in the SQ ring
io_uring_submit
Submit requests to the submission queue
io_uring_submit_and_get_events
Submit requests to the submission queue and flush completions
io_uring_submit_and_wait
Submit requests to the submission queue and wait for completion
io_uring_submit_and_wait_min_timeout
Submit requests to the submission queue and wait for the completion with both batch and normal timeout
io_uring_submit_and_wait_reg
Sets up and registers fixed wait regions
io_uring_submit_and_wait_timeout
Submit requests to the submission queue and wait for the completion with timeout
io_uring_unregister_buf_ring
Unregister a previously registered buffer ring
io_uring_unregister_buffers
Unregister buffers for fixed buffer operations
io_uring_unregister_eventfd
Register an eventfd with a ring
io_uring_unregister_files
Unregister file descriptors
io_uring_unregister_iowq_aff
Register async worker CPU affinities
io_uring_unregister_napi
Unregister NAPI busy poll settings
io_uring_unregister_personality
Unregister a personality from io_uring
io_uring_unregister_ring_fd
Unregister a ring file descriptor
io_uring_wait_cqe
Wait for one io_uring completion event
io_uring_wait_cqe_nr
Wait for one or more io_uring completion events
io_uring_wait_cqe_timeout
Wait for one io_uring completion event with timeout
io_uring_wait_cqes
Wait for one or more io_uring completion events
io_uring_wait_cqes_min_timeout
Wait for completions with both batch and normal timeout