use std::{
io::Result,
os::fd::{AsFd, BorrowedFd, OwnedFd},
};
#[cfg(not(feature = "pre-6.15"))]
pub fn overlayfs_set_fd(fs_fd: BorrowedFd, key: &str, fd: BorrowedFd) -> rustix::io::Result<()> {
rustix::mount::fsconfig_set_fd(fs_fd, key, fd)
}
#[cfg(not(feature = "pre-6.15"))]
pub fn overlayfs_set_lower_and_data_fds(
fs_fd: impl AsFd,
lower: impl AsFd,
data: Option<impl AsFd>,
) -> rustix::io::Result<()> {
overlayfs_set_fd(fs_fd.as_fd(), "lowerdir+", lower.as_fd())?;
if let Some(data) = data {
overlayfs_set_fd(fs_fd.as_fd(), "datadir+", data.as_fd())?;
}
Ok(())
}
#[cfg(not(feature = "rhel9"))]
pub fn make_erofs_mountable(image: OwnedFd) -> Result<OwnedFd> {
Ok(image)
}
#[cfg(not(feature = "pre-6.15"))]
pub fn prepare_mount(mnt_fd: OwnedFd) -> Result<impl AsFd> {
Ok(mnt_fd)
}
#[cfg(feature = "pre-6.15")]
pub fn overlayfs_set_fd(fs_fd: BorrowedFd, key: &str, fd: BorrowedFd) -> rustix::io::Result<()> {
rustix::mount::fsconfig_set_string(fs_fd, key, crate::util::proc_self_fd(fd))
}
#[cfg(feature = "pre-6.15")]
pub fn overlayfs_set_lower_and_data_fds(
fs_fd: impl AsFd,
lower: impl AsFd,
data: Option<impl AsFd>,
) -> rustix::io::Result<()> {
use std::os::fd::AsRawFd;
let lower_fd = lower.as_fd().as_raw_fd().to_string();
let arg = if let Some(data) = data {
let data_fd = data.as_fd().as_raw_fd().to_string();
format!("/proc/self/fd/{lower_fd}::/proc/self/fd/{data_fd}")
} else {
format!("/proc/self/fd/{lower_fd}")
};
rustix::mount::fsconfig_set_string(fs_fd.as_fd(), "lowerdir", arg)
}
#[cfg(feature = "pre-6.15")]
pub fn prepare_mount(mnt_fd: OwnedFd) -> Result<impl AsFd> {
tmpmount::TmpMount::mount(mnt_fd)
}
#[cfg(feature = "rhel9")]
pub fn make_erofs_mountable(image: OwnedFd) -> Result<OwnedFd> {
loopify(image)
}
#[cfg(feature = "pre-6.15")]
mod tmpmount {
use std::{
io::Result,
os::fd::{AsFd, BorrowedFd, OwnedFd},
};
use rustix::fs::{Mode, OFlags, open};
use rustix::mount::{MoveMountFlags, UnmountFlags, move_mount, unmount};
pub(super) struct TmpMount {
dir: tempfile::TempDir,
fd: OwnedFd,
}
impl TmpMount {
pub(super) fn mount(mnt_fd: OwnedFd) -> Result<impl AsFd> {
let tmp = tempfile::TempDir::new()?;
move_mount(
mnt_fd.as_fd(),
"",
rustix::fs::CWD,
tmp.path(),
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
)?;
let fd = open(
tmp.path(),
OFlags::PATH | OFlags::DIRECTORY | OFlags::CLOEXEC,
Mode::empty(),
)?;
Ok(TmpMount { dir: tmp, fd })
}
}
impl AsFd for TmpMount {
fn as_fd(&self) -> BorrowedFd<'_> {
self.fd.as_fd()
}
}
impl Drop for TmpMount {
fn drop(&mut self) {
let _ = unmount(self.dir.path(), UnmountFlags::DETACH);
}
}
}
#[cfg(feature = "rhel9")]
fn loopify(image: OwnedFd) -> Result<OwnedFd> {
composefs_ioctls::loop_device::loopify(image)
}