summaryrefslogtreecommitdiffstats
path: root/src/runner/runc/init.rs
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2021-02-06 23:24:05 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2021-02-06 23:24:05 +0100
commit6f446ffc9dd49cac07e6c0096cc512e379a7f3ed (patch)
tree987240e7137a9332dab957899533ffcbe04689c7 /src/runner/runc/init.rs
parentad74dfb5520414b21d2e8b057f846661e671fc2e (diff)
downloadrebel-6f446ffc9dd49cac07e6c0096cc512e379a7f3ed.tar
rebel-6f446ffc9dd49cac07e6c0096cc512e379a7f3ed.zip
Unpack rootfs into tmpfs in runc namespace
Diffstat (limited to 'src/runner/runc/init.rs')
-rw-r--r--src/runner/runc/init.rs80
1 files changed, 71 insertions, 9 deletions
diff --git a/src/runner/runc/init.rs b/src/runner/runc/init.rs
index 02b89e4..1786719 100644
--- a/src/runner/runc/init.rs
+++ b/src/runner/runc/init.rs
@@ -1,4 +1,10 @@
-use std::io;
+use std::{
+ ffi::CString,
+ fs::{DirBuilder, File},
+ io,
+ os::unix::ffi::OsStrExt,
+ path::Path,
+};
use nix::{
mount::{self, MsFlags},
@@ -6,7 +12,9 @@ use nix::{
};
use serde::{Deserialize, Serialize};
-fn mount_buildtmp() -> nix::Result<()> {
+use crate::util::ToIOResult;
+
+fn prepare_buildtmp() -> io::Result<()> {
mount::mount::<_, _, _, str>(
Some("buildtmp"),
"build/tmp",
@@ -14,6 +22,56 @@ fn mount_buildtmp() -> nix::Result<()> {
MsFlags::empty(),
None,
)
+ .to_io_result()?;
+
+ DirBuilder::new().create("build/tmp/rootfs")?;
+
+ {
+ let file = File::open("build/rootfs.tar")?;
+ let mut archive = tar::Archive::new(file);
+ archive.set_preserve_permissions(true);
+ archive.set_preserve_mtime(true);
+ archive.set_unpack_xattrs(true);
+
+ let dst = Path::new("build/tmp/rootfs");
+
+ for entry_r in archive.entries()? {
+ let mut entry = entry_r?;
+ if entry.unpack_in(dst)? {
+ let header = entry.header();
+ let uid = header.uid()? as libc::uid_t;
+ let gid = header.gid()? as libc::gid_t;
+
+ let path = CString::new(dst.join(entry.path()?).as_os_str().as_bytes())
+ .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+ if unsafe { libc::lchown(path.as_ptr(), uid, gid) } < 0 {
+ return Err(io::Error::last_os_error());
+ }
+ }
+ }
+ }
+
+ DirBuilder::new().create("build/tmp/runc")?;
+ DirBuilder::new().create("build/tmp/runc/rootfs")?;
+
+ mount::mount::<_, _, str, str>(
+ Some("build/tmp/rootfs"),
+ "build/tmp/runc/rootfs",
+ None,
+ MsFlags::MS_BIND,
+ None,
+ )
+ .to_io_result()?;
+ mount::mount::<str, _, str, str>(
+ None,
+ "build/tmp/runc/rootfs",
+ None,
+ MsFlags::MS_BIND | MsFlags::MS_REMOUNT | MsFlags::MS_RDONLY,
+ None,
+ )
+ .to_io_result()?;
+
+ Ok(())
}
#[derive(Debug, Deserialize, Serialize)]
@@ -22,11 +80,11 @@ pub enum Error {
String(String),
}
-impl From<nix::Error> for Error {
- fn from(error: nix::Error) -> Self {
- match error {
- nix::Error::Sys(code) => Error::Code(code as i32),
- _ => Error::String(error.to_string()),
+impl From<io::Error> for Error {
+ fn from(error: io::Error) -> Self {
+ match error.raw_os_error() {
+ Some(code) => Error::Code(code),
+ None => Error::String(error.to_string()),
}
}
}
@@ -40,8 +98,12 @@ impl From<Error> for io::Error {
}
}
+pub fn runc_unshare() -> Result<(), Error> {
+ sched::unshare(CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_NEWNS).to_io_result()?;
+ Ok(())
+}
+
pub fn runc_initialize() -> Result<(), Error> {
- sched::unshare(CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_NEWNS)?;
- mount_buildtmp()?;
+ prepare_buildtmp()?;
Ok(())
}