Skip to content

Commit

Permalink
bin: add composefs-pivot-sysroot
Browse files Browse the repository at this point in the history
  • Loading branch information
allisonkarlitskaya committed Oct 28, 2024
1 parent 12186ff commit 1e76d68
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 8 deletions.
29 changes: 29 additions & 0 deletions src/bin/composefs-pivot-sysroot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::io::Read;
use std::path::Path;

use anyhow::{bail, Result};

use composefs_experiments::{fsverity::Sha256HashValue, repository::Repository};

fn parse_composefs_cmdline() -> Result<Sha256HashValue> {
let mut cmdline = vec![];
let mut proc_cmdline = std::fs::File::open("/proc/cmdline")?;
proc_cmdline.read_to_end(&mut cmdline)?;
// TODO?: officially we need to understand quoting with double-quotes...
for part in cmdline.split(|c| *c == b' ') {
if let Some(digest) = part.strip_prefix(b"composefs=") {
let mut value = [0; 32];
hex::decode_to_slice(digest, &mut value)?;
return Ok(value);
}
}
bail!("Unable to find composefs= cmdline parameter");
}

fn main() -> Result<()> {
let repo = Repository::open_system()?;
let image = parse_composefs_cmdline()?;
repo.pivot_sysroot(&hex::encode(image), Path::new("/sysroot"))?;

Ok(())
}
50 changes: 43 additions & 7 deletions src/mount.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use std::{
fs::canonicalize,
os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd},
path::Path,
};

use anyhow::Result;
use rustix::mount::{
fsconfig_create, fsconfig_set_string, fsmount, fsopen, move_mount, unmount, FsMountFlags,
FsOpenFlags, MountAttrFlags, MoveMountFlags, UnmountFlags,
use rustix::{
fs::CWD,
io::Errno,
mount::{
fsconfig_create, fsconfig_set_string, fsmount, fsopen, move_mount, open_tree, unmount,
FsMountFlags, FsOpenFlags, MountAttrFlags, MoveMountFlags, OpenTreeFlags, UnmountFlags,
},
};

use crate::fsverity;
Expand Down Expand Up @@ -71,7 +76,7 @@ fn proc_self_fd<A: AsFd>(fd: A) -> String {
format!("/proc/self/fd/{}", fd.as_fd().as_raw_fd())
}

pub fn mount_fd<F: AsFd>(image: F, basedir: &Path, mountpoint: &str) -> Result<()> {
pub fn composefs_fsmount(image: impl AsFd, basedir: &Path) -> Result<OwnedFd> {
let erofs = FsHandle::open("erofs")?;
fsconfig_set_string(erofs.as_fd(), "source", proc_self_fd(&image))?;
fsconfig_create(erofs.as_fd())?;
Expand All @@ -87,22 +92,53 @@ pub fn mount_fd<F: AsFd>(image: F, basedir: &Path, mountpoint: &str) -> Result<(
fsconfig_set_string(overlayfs.as_fd(), "datadir+", basedir)?;
fsconfig_create(overlayfs.as_fd())?;

let mnt = fsmount(
Ok(fsmount(
overlayfs.as_fd(),
FsMountFlags::FSMOUNT_CLOEXEC,
MountAttrFlags::empty(),
)?;
)?)
}

pub fn mount_fd<F: AsFd>(image: F, basedir: &Path, mountpoint: &str) -> Result<()> {
let mnt = composefs_fsmount(image, basedir)?;

move_mount(
mnt.as_fd(),
"",
rustix::fs::CWD,
mountpoint,
canonicalize(mountpoint)?,
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
)?;

Ok(())
}

pub fn pivot_sysroot(image: impl AsFd, basedir: &Path, sysroot: &Path) -> Result<()> {
let mnt = composefs_fsmount(image, basedir)?;

let prev = open_tree(CWD, sysroot, OpenTreeFlags::OPEN_TREE_CLONE)?;
unmount(sysroot, UnmountFlags::DETACH)?;

move_mount(
mnt.as_fd(),
"",
rustix::fs::CWD,
sysroot,
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
)?;

match move_mount(
prev.as_fd(),
"",
rustix::fs::CWD,
sysroot.join("sysroot"),
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
) {
Ok(()) | Err(Errno::NOENT) => Ok(()),
Err(err) => Err(err)?,
}
}

pub struct MountOptions<'a> {
image: &'a str,
basedir: &'a Path,
Expand Down
9 changes: 8 additions & 1 deletion src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
ioctl::{fs_ioc_enable_verity, fs_ioc_measure_verity},
FsVerityHashValue, Sha256HashValue,
},
mount::mount_fd,
mount::{mount_fd, pivot_sysroot},
splitstream::{DigestMap, SplitStreamReader, SplitStreamWriter},
util::{parse_sha256, proc_self_fd},
};
Expand Down Expand Up @@ -376,6 +376,13 @@ impl Repository {
mount_fd(image, &object_path, mountpoint)
}

pub fn pivot_sysroot(&self, name: &str, mountpoint: &Path) -> Result<()> {
let filename = format!("images/{}", name);
let object_path = self.path.join("objects");
let image = self.open_with_verity(&filename, &parse_sha256(name)?)?;
pivot_sysroot(image, &object_path, mountpoint)
}

pub fn symlink(&self, name: impl AsRef<Path>, target: impl AsRef<Path>) -> ErrnoResult<()> {
let name = name.as_ref();

Expand Down

0 comments on commit 1e76d68

Please sign in to comment.