Skip to content

Commit 3fa3b70

Browse files
committed
passthrough.rs fails with cannot find type statx in crate libc
musl 1.2.5 added support for the statx system call rust ships unknown-linux-musl with musl 1.2.3 milage on other libs may varay Enable portability by repling libc::statx with rustix::statx Fixes: #431 Signed-off-by: Pepper Gray <[email protected]>
1 parent 246b3f7 commit 3fa3b70

File tree

3 files changed

+67
-40
lines changed

3 files changed

+67
-40
lines changed

Cargo.lock

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/devices/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ utils = { path = "../utils" }
3737
polly = { path = "../polly" }
3838
rutabaga_gfx = { path = "../rutabaga_gfx", features = ["virgl_renderer", "virgl_renderer_next"], optional = true }
3939
imago = { version = "0.1.4", features = ["sync-wrappers", "vm-memory"] }
40+
rustix = { version = "1.1.2", features = ["fs"] }
4041

4142
[target.'cfg(target_os = "macos")'.dependencies]
4243
hvf = { path = "../hvf" }

src/devices/src/virtio/fs/linux/passthrough.rs

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -147,52 +147,48 @@ fn stat(f: &File) -> io::Result<libc::stat64> {
147147
}
148148

149149
fn statx(f: &File) -> io::Result<(libc::stat64, u64)> {
150-
let mut stx = MaybeUninit::<libc::statx>::zeroed();
150+
use rustix::fd::BorrowedFd;
151+
use rustix::fs::{statx, AtFlags, StatxFlags};
151152

152153
// Safe because this is a constant value and a valid C string.
153154
let pathname = unsafe { CStr::from_bytes_with_nul_unchecked(EMPTY_CSTR) };
155+
let dirfd = unsafe { BorrowedFd::borrow_raw(f.as_raw_fd()) };
154156

155157
// Safe because the kernel will only write data in `st` and we check the return
156158
// value.
157-
let res = unsafe {
158-
libc::statx(
159-
f.as_raw_fd(),
160-
pathname.as_ptr(),
161-
libc::AT_EMPTY_PATH | libc::AT_SYMLINK_NOFOLLOW,
162-
libc::STATX_BASIC_STATS | libc::STATX_MNT_ID,
163-
stx.as_mut_ptr(),
164-
)
165-
};
166-
if res >= 0 {
167-
// Safe because the kernel guarantees that the struct is now fully initialized.
168-
let stx = unsafe { stx.assume_init() };
169-
170-
// Unfortunately, we cannot use an initializer to create the stat64 object,
171-
// because it may contain padding and reserved fields (depending on the
172-
// architecture), and it does not implement the Default trait.
173-
// So we take a zeroed struct and set what we can. (Zero in all fields is
174-
// wrong, but safe.)
175-
let mut st = unsafe { MaybeUninit::<libc::stat64>::zeroed().assume_init() };
176-
177-
st.st_dev = libc::makedev(stx.stx_dev_major, stx.stx_dev_minor);
178-
st.st_ino = stx.stx_ino;
179-
st.st_mode = stx.stx_mode as _;
180-
st.st_nlink = stx.stx_nlink as _;
181-
st.st_uid = stx.stx_uid;
182-
st.st_gid = stx.stx_gid;
183-
st.st_rdev = libc::makedev(stx.stx_rdev_major, stx.stx_rdev_minor);
184-
st.st_size = stx.stx_size as _;
185-
st.st_blksize = stx.stx_blksize as _;
186-
st.st_blocks = stx.stx_blocks as _;
187-
st.st_atime = stx.stx_atime.tv_sec;
188-
st.st_atime_nsec = stx.stx_atime.tv_nsec as _;
189-
st.st_mtime = stx.stx_mtime.tv_sec;
190-
st.st_mtime_nsec = stx.stx_mtime.tv_nsec as _;
191-
st.st_ctime = stx.stx_ctime.tv_sec;
192-
st.st_ctime_nsec = stx.stx_ctime.tv_nsec as _;
193-
Ok((st, stx.stx_mnt_id))
194-
} else {
195-
Err(io::Error::last_os_error())
159+
match statx(
160+
dirfd,
161+
pathname,
162+
AtFlags::EMPTY_PATH | AtFlags::SYMLINK_NOFOLLOW,
163+
StatxFlags::BASIC_STATS | StatxFlags::MNT_ID,
164+
) {
165+
Ok(stx) => {
166+
// Unfortunately, we cannot use an initializer to create the stat64 object,
167+
// because it may contain padding and reserved fields (depending on the
168+
// architecture), and it does not implement the Default trait.
169+
// So we take a zeroed struct and set what we can. (Zero in all fields is
170+
// wrong, but safe.)
171+
let mut st = unsafe { MaybeUninit::<libc::stat64>::zeroed().assume_init() };
172+
173+
st.st_dev = libc::makedev(stx.stx_dev_major, stx.stx_dev_minor);
174+
st.st_ino = stx.stx_ino;
175+
st.st_mode = stx.stx_mode as _;
176+
st.st_nlink = stx.stx_nlink as _;
177+
st.st_uid = stx.stx_uid;
178+
st.st_gid = stx.stx_gid;
179+
st.st_rdev = libc::makedev(stx.stx_rdev_major, stx.stx_rdev_minor);
180+
st.st_size = stx.stx_size as _;
181+
st.st_blksize = stx.stx_blksize as _;
182+
st.st_blocks = stx.stx_blocks as _;
183+
st.st_atime = stx.stx_atime.tv_sec;
184+
st.st_atime_nsec = stx.stx_atime.tv_nsec as _;
185+
st.st_mtime = stx.stx_mtime.tv_sec;
186+
st.st_mtime_nsec = stx.stx_mtime.tv_nsec as _;
187+
st.st_ctime = stx.stx_ctime.tv_sec;
188+
st.st_ctime_nsec = stx.stx_ctime.tv_nsec as _;
189+
Ok((st, stx.stx_mnt_id))
190+
}
191+
Err(e) => Err(e.into()),
196192
}
197193
}
198194

0 commit comments

Comments
 (0)