hypha: build init with musl, trace logging, and now map console optionally

This commit is contained in:
Alex Zenla 2024-02-01 11:50:33 +00:00
parent c17aacb6c8
commit 7eda5ea185
No known key found for this signature in database
GPG Key ID: 067B238899B51269
4 changed files with 34 additions and 34 deletions

View File

@ -5,7 +5,7 @@ use std::env;
fn main() -> Result<()> {
env::set_var("RUST_BACKTRACE", "1");
env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init();
env_logger::Builder::from_env(Env::default().default_filter_or("trace")).init();
if env::var("HYPHA_UNSAFE_ALWAYS_ALLOW_INIT").unwrap_or("0".to_string()) != "1" {
let pid = std::process::id();
if pid > 3 {

View File

@ -1,6 +1,6 @@
use crate::shared::LaunchInfo;
use anyhow::{anyhow, Result};
use log::trace;
use log::{trace, warn};
use nix::libc::{c_int, dup2, wait};
use nix::unistd::{execve, fork, ForkResult, Pid};
use oci_spec::image::{Config, ImageConfiguration};
@ -57,10 +57,14 @@ impl ContainerInit {
self.early_init()?;
trace!("opening console descriptor");
let console = OpenOptions::new()
match OpenOptions::new()
.read(true)
.write(true)
.open("/dev/console")?;
.open("/dev/console")
{
Ok(console) => self.map_console(console)?,
Err(error) => warn!("failed to open console: {}", error),
}
self.mount_squashfs_images()?;
let config = self.parse_image_config()?;
@ -69,7 +73,7 @@ impl ContainerInit {
self.nuke_initrd()?;
self.bind_new_root()?;
if let Some(cfg) = config.config() {
self.run(console, cfg, &launch)?;
self.run(cfg, &launch)?;
} else {
return Err(anyhow!(
"unable to determine what to execute, image config doesn't tell us"
@ -85,9 +89,9 @@ impl ContainerInit {
self.create_dir("/sys", None)?;
self.create_dir("/root", Some(0o0700))?;
self.create_dir("/tmp", None)?;
self.mount_kernel_fs("devtmpfs", "/dev")?;
self.mount_kernel_fs("proc", "/proc")?;
self.mount_kernel_fs("sysfs", "/sys")?;
self.mount_kernel_fs("devtmpfs", "/dev", "mode=0755")?;
self.mount_kernel_fs("proc", "/proc", "")?;
self.mount_kernel_fs("sysfs", "/sys", "")?;
Ok(())
}
@ -105,18 +109,30 @@ impl ContainerInit {
Ok(())
}
fn mount_kernel_fs(&mut self, fstype: &str, path: &str) -> Result<()> {
fn mount_kernel_fs(&mut self, fstype: &str, path: &str, data: &str) -> Result<()> {
let metadata = fs::metadata(path)?;
if metadata.st_dev() == fs::metadata("/")?.st_dev() {
trace!("mounting kernel fs {} to {}", fstype, path);
Mount::builder()
.fstype(FilesystemType::Manual(fstype))
.flags(MountFlags::NODEV | MountFlags::NOEXEC | MountFlags::NOSUID)
.data(data)
.mount(fstype, path)?;
}
Ok(())
}
fn map_console(&mut self, console: File) -> Result<()> {
trace!("mapping console");
unsafe {
dup2(console.as_raw_fd(), 0);
dup2(console.as_raw_fd(), 1);
dup2(console.as_raw_fd(), 2);
}
drop(console);
Ok(())
}
fn mount_squashfs_images(&mut self) -> Result<()> {
trace!("mounting squashfs images");
let image_mount_path = Path::new(IMAGE_MOUNT_PATH);
@ -255,18 +271,7 @@ impl ContainerInit {
Ok(())
}
fn map_console(&mut self, console: File) -> Result<()> {
trace!("mapping console");
unsafe {
dup2(console.as_raw_fd(), 0);
dup2(console.as_raw_fd(), 1);
dup2(console.as_raw_fd(), 2);
}
drop(console);
Ok(())
}
fn run(&mut self, console: File, config: &Config, launch: &LaunchInfo) -> Result<()> {
fn run(&mut self, config: &Config, launch: &LaunchInfo) -> Result<()> {
let mut cmd = match config.cmd() {
None => vec![],
Some(value) => value.clone(),
@ -306,7 +311,7 @@ impl ContainerInit {
}
std::env::set_current_dir(&working_dir)?;
self.fork_and_exec(console, &path_cstr, cmd_cstr, env_cstr)?;
self.fork_and_exec(&path_cstr, cmd_cstr, env_cstr)?;
Ok(())
}
@ -318,17 +323,10 @@ impl ContainerInit {
Ok(results)
}
fn fork_and_exec(
&mut self,
console: File,
path: &CStr,
cmd: Vec<CString>,
env: Vec<CString>,
) -> Result<()> {
fn fork_and_exec(&mut self, path: &CStr, cmd: Vec<CString>, env: Vec<CString>) -> Result<()> {
match unsafe { fork()? } {
ForkResult::Parent { child } => self.background(child),
ForkResult::Child => {
self.map_console(console)?;
execve(path, &cmd, &env)?;
Ok(())
}

View File

@ -1,12 +1,14 @@
#!/usr/bin/env bash
set -e
TARGET="x86_64-unknown-linux-musl"
export RUSTFLAGS="-Ctarget-feature=+crt-static"
cd "$(dirname "${0}")/.."
HYPHA_DIR="${PWD}"
cargo build --bin hyphactr --release --target x86_64-unknown-linux-gnu
cargo build --bin hyphactr --release --target "${TARGET}"
INITRD_DIR="$(mktemp -d /tmp/hypha-initrd.XXXXXXXXXXXXX)"
cp "target/x86_64-unknown-linux-gnu/release/hyphactr" "${INITRD_DIR}/init"
cp "target/${TARGET}/release/hyphactr" "${INITRD_DIR}/init"
chmod +x "${INITRD_DIR}/init"
cd "${INITRD_DIR}"
mkdir -p "${HYPHA_DIR}/target/initrd"

View File

@ -44,7 +44,7 @@ use crate::bindings::{
LOOP_SET_STATUS64, LO_FLAGS_AUTOCLEAR, LO_FLAGS_PARTSCAN, LO_FLAGS_READ_ONLY,
};
use libc::ioctl;
use std::ffi::{c_int, c_ulong};
use std::ffi::c_int;
use std::{
default::Default,
fs::{File, OpenOptions},
@ -54,7 +54,7 @@ use std::{
};
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
type IoctlRequest = c_ulong;
type IoctlRequest = std::ffi::c_ulong;
#[cfg(any(target_os = "android", target_env = "musl"))]
type IoctlRequest = c_int;