Skip to content

Commit

Permalink
Switch from io_uring to rustix_uring for broad compatibility
Browse files Browse the repository at this point in the history
rustix wraps syscalls without the libc crate, which does not expose a
bunch of io-uring related APIs such as statx on musl targets.

With these changes, tokio-uring compiles fine when built for musl
targets.

Signed-off-by: Jens Reidel <[email protected]>
  • Loading branch information
Gelbpunkt committed Dec 14, 2024
1 parent 7761222 commit 37625e8
Show file tree
Hide file tree
Showing 41 changed files with 165 additions and 143 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ keywords = ["async", "fs", "io-uring"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio = { version = "1.2", features = ["net", "rt", "sync"] }
slab = "0.4.2"
tokio = { version = "1.12", features = ["net", "rt", "sync"] }
slab = "0.4.4"
libc = "0.2.80"
io-uring = "0.6.0"
rustix = { version = "0.38.42", features = ["net", "io_uring"] }
rustix-uring = "0.2.0"
socket2 = { version = "0.4.4", features = ["all"] }
bytes = { version = "1.0", optional = true }
futures-util = { version = "0.3.26", default-features = false, features = ["std"] }
Expand Down
3 changes: 2 additions & 1 deletion examples/test_create_dir_all.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustix::fs::StatxFlags;
use std::io;
use std::path::Path;
use tokio_uring::fs;
Expand Down Expand Up @@ -200,7 +201,7 @@ async fn statx_builder2<P: AsRef<Path>>(dir_path: P, rel_path: P) -> io::Result<

async fn matches_mode<P: AsRef<Path>>(path: P, want_mode: u16) -> io::Result<()> {
let statx = tokio_uring::fs::StatxBuilder::new()
.mask(libc::STATX_MODE)
.mask(StatxFlags::MODE)
.pathname(path)?
.statx()
.await?;
Expand Down
2 changes: 1 addition & 1 deletion src/buf/fixed/buffers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use libc::iovec;
use rustix::io_uring::iovec;

// Abstracts management of fixed buffers in a buffer registry.
pub(crate) trait FixedBuffers {
Expand Down
2 changes: 1 addition & 1 deletion src/buf/fixed/handle.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::FixedBuffers;
use crate::buf::{IoBuf, IoBufMut};

use libc::iovec;
use rustix::io_uring::iovec;
use std::cell::RefCell;
use std::fmt::{self, Debug};
use std::ops::{Deref, DerefMut};
Expand Down
3 changes: 2 additions & 1 deletion src/buf/fixed/plumbing/pool.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::buf::fixed::{handle::CheckedOutBuf, FixedBuffers};
use crate::buf::IoBufMut;

use libc::{iovec, UIO_MAXIOV};
use libc::UIO_MAXIOV;
use rustix::io_uring::iovec;
use tokio::sync::Notify;

use std::cmp;
Expand Down
3 changes: 2 additions & 1 deletion src/buf/fixed/plumbing/registry.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::buf::fixed::{handle::CheckedOutBuf, FixedBuffers};
use crate::buf::IoBufMut;

use libc::{iovec, UIO_MAXIOV};
use libc::UIO_MAXIOV;
use rustix::io_uring::iovec;
use std::cmp;
use std::mem;
use std::ptr;
Expand Down
11 changes: 6 additions & 5 deletions src/fs/create_dir_all.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use futures_util::future::LocalBoxFuture;
use rustix::fs::StatxFlags;
use std::io;
use std::path::Path;

Expand Down Expand Up @@ -165,25 +166,25 @@ impl DirBuilder {

mod fs_imp {
use crate::runtime::driver::op::Op;
use libc::mode_t;
use rustix::fs::Mode;
use std::path::Path;

#[derive(Debug)]
pub struct DirBuilder {
mode: mode_t,
mode: Mode,
}

impl DirBuilder {
pub fn new() -> DirBuilder {
DirBuilder { mode: 0o777 }
DirBuilder { mode: 0o777.into() }
}

pub async fn mkdir(&self, p: &Path) -> std::io::Result<()> {
Op::make_dir(p, self.mode)?.await
}

pub fn set_mode(&mut self, mode: u32) {
self.mode = mode as mode_t;
self.mode = mode.into();
}
}
}
Expand All @@ -193,7 +194,7 @@ mod fs_imp {
// Uses one asynchronous uring call to determine this.
async fn is_dir<P: AsRef<Path>>(path: P) -> bool {
let mut builder = crate::fs::StatxBuilder::new();
if builder.mask(libc::STATX_TYPE).pathname(path).is_err() {
if builder.mask(StatxFlags::TYPE).pathname(path).is_err() {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/fs/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use std::path::Path;
/// }
/// ```
pub async fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
Op::make_dir(path.as_ref(), 0o777)?.await
Op::make_dir(path.as_ref(), 0o777.into())?.await
}

/// Removes a directory on the local filesystem.
Expand Down
4 changes: 3 additions & 1 deletion src/fs/file.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rustix_uring::types;

use crate::buf::fixed::FixedBuf;
use crate::buf::{BoundedBuf, BoundedBufMut, IoBuf, IoBufMut, Slice};
use crate::fs::OpenOptions;
Expand Down Expand Up @@ -960,5 +962,5 @@ pub async fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// }
/// ```
pub async fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
Op::rename_at(from.as_ref(), to.as_ref(), 0)?.await
Op::rename_at(from.as_ref(), to.as_ref(), types::RenameFlags::empty())?.await
}
39 changes: 21 additions & 18 deletions src/fs/open_options.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use rustix::fs::Mode;
use rustix_uring::types;

use crate::fs::File;

use crate::runtime::driver::op::Op;
Expand Down Expand Up @@ -62,8 +65,8 @@ pub struct OpenOptions {
truncate: bool,
create: bool,
create_new: bool,
pub(crate) mode: libc::mode_t,
pub(crate) custom_flags: libc::c_int,
pub(crate) mode: Mode,
pub(crate) custom_flags: types::OFlags,
}

impl OpenOptions {
Expand Down Expand Up @@ -95,8 +98,8 @@ impl OpenOptions {
truncate: false,
create: false,
create_new: false,
mode: 0o666,
custom_flags: 0,
mode: 0o666.into(),
custom_flags: types::OFlags::empty(),
}
}

Expand Down Expand Up @@ -336,18 +339,18 @@ impl OpenOptions {
Op::open(path.as_ref(), self)?.await
}

pub(crate) fn access_mode(&self) -> io::Result<libc::c_int> {
pub(crate) fn access_mode(&self) -> io::Result<types::OFlags> {
match (self.read, self.write, self.append) {
(true, false, false) => Ok(libc::O_RDONLY),
(false, true, false) => Ok(libc::O_WRONLY),
(true, true, false) => Ok(libc::O_RDWR),
(false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND),
(true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND),
(true, false, false) => Ok(types::OFlags::RDONLY),
(false, true, false) => Ok(types::OFlags::WRONLY),
(true, true, false) => Ok(types::OFlags::RDWR),
(false, _, true) => Ok(types::OFlags::WRONLY | types::OFlags::APPEND),
(true, _, true) => Ok(types::OFlags::RDWR | types::OFlags::APPEND),
(false, false, false) => Err(io::Error::from_raw_os_error(libc::EINVAL)),
}
}

pub(crate) fn creation_mode(&self) -> io::Result<libc::c_int> {
pub(crate) fn creation_mode(&self) -> io::Result<types::OFlags> {
match (self.write, self.append) {
(true, false) => {}
(false, false) => {
Expand All @@ -363,11 +366,11 @@ impl OpenOptions {
}

Ok(match (self.create, self.truncate, self.create_new) {
(false, false, false) => 0,
(true, false, false) => libc::O_CREAT,
(false, true, false) => libc::O_TRUNC,
(true, true, false) => libc::O_CREAT | libc::O_TRUNC,
(_, _, true) => libc::O_CREAT | libc::O_EXCL,
(false, false, false) => types::OFlags::empty(),
(true, false, false) => types::OFlags::CREATE,
(false, true, false) => types::OFlags::TRUNC,
(true, true, false) => types::OFlags::CREATE | types::OFlags::TRUNC,
(_, _, true) => types::OFlags::CREATE | types::OFlags::EXCL,
})
}
}
Expand All @@ -380,12 +383,12 @@ impl Default for OpenOptions {

impl OpenOptionsExt for OpenOptions {
fn mode(&mut self, mode: u32) -> &mut OpenOptions {
self.mode = mode;
self.mode = mode.into();
self
}

fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
self.custom_flags = flags;
self.custom_flags = types::OFlags::from_bits_truncate(flags as u32);
self
}
}
33 changes: 18 additions & 15 deletions src/fs/statx.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use rustix::fs::StatxFlags;
use rustix_uring::types;

use super::File;
use crate::io::{cstr, SharedFd};
use crate::runtime::driver::op::Op;
Expand Down Expand Up @@ -28,9 +31,9 @@ impl File {
/// f.close().await.unwrap();
/// })
/// ```
pub async fn statx(&self) -> io::Result<libc::statx> {
let flags = libc::AT_EMPTY_PATH;
let mask = libc::STATX_ALL;
pub async fn statx(&self) -> io::Result<types::Statx> {
let flags = types::AtFlags::EMPTY_PATH;
let mask = StatxFlags::ALL;
Op::statx(Some(self.fd.clone()), None, flags, mask)?.await
}

Expand Down Expand Up @@ -72,8 +75,8 @@ impl File {
StatxBuilder {
file: Some(self.fd.clone()),
path: None,
flags: libc::AT_EMPTY_PATH,
mask: libc::STATX_ALL,
flags: types::AtFlags::EMPTY_PATH,
mask: StatxFlags::ALL,
}
}
}
Expand Down Expand Up @@ -102,7 +105,7 @@ impl File {
/// let statx = tokio_uring::fs::statx("foo.txt").await.unwrap();
/// })
/// ```
pub async fn statx<P: AsRef<Path>>(path: P) -> io::Result<libc::statx> {
pub async fn statx<P: AsRef<Path>>(path: P) -> io::Result<rustix::fs::Statx> {
StatxBuilder::new().pathname(path).unwrap().statx().await
}

Expand All @@ -115,8 +118,8 @@ pub async fn statx<P: AsRef<Path>>(path: P) -> io::Result<libc::statx> {
pub struct StatxBuilder {
file: Option<SharedFd>,
path: Option<CString>,
flags: i32,
mask: u32,
flags: types::AtFlags,
mask: StatxFlags,
}

impl Default for StatxBuilder {
Expand Down Expand Up @@ -161,8 +164,8 @@ impl StatxBuilder {
StatxBuilder {
file: None,
path: None,
flags: libc::AT_EMPTY_PATH,
mask: libc::STATX_ALL,
flags: types::AtFlags::EMPTY_PATH,
mask: StatxFlags::ALL,
}
}

Expand Down Expand Up @@ -241,7 +244,7 @@ impl StatxBuilder {
/// })
/// ```
#[must_use]
pub fn flags(&mut self, flags: i32) -> &mut Self {
pub fn flags(&mut self, flags: types::AtFlags) -> &mut Self {
self.flags = flags;
self
}
Expand All @@ -254,13 +257,13 @@ impl StatxBuilder {
/// tokio_uring::start(async {
/// // Fetch file metadata
/// let statx = tokio_uring::fs::StatxBuilder::new()
/// .mask(libc::STATX_BASIC_STATS)
/// .mask(rustix::fs::StatxFlags::ALL)
/// .pathname("foo.txt").unwrap()
/// .statx().await.unwrap();
/// })
/// ```
#[must_use]
pub fn mask(&mut self, mask: u32) -> &mut Self {
pub fn mask(&mut self, mask: StatxFlags) -> &mut Self {
self.mask = mask;
self
}
Expand Down Expand Up @@ -288,7 +291,7 @@ impl StatxBuilder {
/// dir.close().await.unwrap();
/// })
/// ```
pub async fn statx(&mut self) -> io::Result<libc::statx> {
pub async fn statx(&mut self) -> io::Result<types::Statx> {
// TODO should the statx() terminator be renamed to something like submit()?
let fd = self.file.take();
let path = self.path.take();
Expand All @@ -303,7 +306,7 @@ impl StatxBuilder {
#[allow(dead_code)]
pub async fn is_dir_regfile<P: AsRef<Path>>(path: P) -> (bool, bool) {
let mut builder = crate::fs::StatxBuilder::new();
if builder.mask(libc::STATX_TYPE).pathname(path).is_err() {
if builder.mask(StatxFlags::TYPE).pathname(path).is_err() {
return (false, false);
}

Expand Down
6 changes: 4 additions & 2 deletions src/io/accept.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rustix::net::SocketFlags;

use crate::io::{SharedFd, Socket};
use crate::runtime::driver::op;
use crate::runtime::driver::op::{Completable, Op};
Expand All @@ -12,7 +14,7 @@ pub(crate) struct Accept {

impl Op<Accept> {
pub(crate) fn accept(fd: &SharedFd) -> io::Result<Op<Accept>> {
use io_uring::{opcode, types};
use rustix_uring::{opcode, types};

let socketaddr = Box::new((
unsafe { std::mem::zeroed() },
Expand All @@ -30,7 +32,7 @@ impl Op<Accept> {
&mut accept.socketaddr.0 as *mut _ as *mut _,
&mut accept.socketaddr.1,
)
.flags(libc::O_CLOEXEC)
.flags(SocketFlags::CLOEXEC)
.build()
},
)
Expand Down
2 changes: 1 addition & 1 deletion src/io/close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub(crate) struct Close {

impl Op<Close> {
pub(crate) fn close(fd: RawFd) -> io::Result<Op<Close>> {
use io_uring::{opcode, types};
use rustix_uring::{opcode, types};

CONTEXT.with(|x| {
x.handle()
Expand Down
4 changes: 2 additions & 2 deletions src/io/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub(crate) struct Connect {
impl Op<Connect> {
/// Submit a request to connect.
pub(crate) fn connect(fd: &SharedFd, socket_addr: SockAddr) -> io::Result<Op<Connect>> {
use io_uring::{opcode, types};
use rustix_uring::{opcode, types};

CONTEXT.with(|x| {
x.handle().expect("Not in a runtime context").submit_op(
Expand All @@ -26,7 +26,7 @@ impl Op<Connect> {
|connect| {
opcode::Connect::new(
types::Fd(connect.fd.raw_fd()),
connect.socket_addr.as_ptr(),
connect.socket_addr.as_ptr() as *const _,
connect.socket_addr.len(),
)
.build()
Expand Down
2 changes: 1 addition & 1 deletion src/io/fallocate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::io;

use io_uring::{opcode, types};
use rustix_uring::{opcode, types};

use crate::{
io::SharedFd,
Expand Down
2 changes: 1 addition & 1 deletion src/io/fsync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io;
use crate::io::SharedFd;
use crate::runtime::driver::op::{Completable, CqeResult, Op};
use crate::runtime::CONTEXT;
use io_uring::{opcode, types};
use rustix_uring::{opcode, types};

pub(crate) struct Fsync {
fd: SharedFd,
Expand Down
Loading

0 comments on commit 37625e8

Please sign in to comment.