#[cfg(target_os = "linux")]
mod platform {
use std::fs;
use std::os::unix::fs as unix_fs;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use nix::mount::{MsFlags, mount};
pub fn init_system() {
mount_tmpfs("/tmp");
mount_tmpfs("/run");
mount_tmpfs("/var");
mount_tmpfs("/etc");
write_etc_resolv_conf();
write_etc_hosts();
write_etc_passwd();
write_etc_group();
mkdir_p("/etc/ssl/certs");
symlink_if_source_exists(
"/cacerts/ca-certificates.crt",
"/etc/ssl/certs/ca-certificates.crt",
);
mkdir_p("/var/lib/docker");
mkdir_p("/var/run/docker");
mkdir_p("/run/containerd");
mount_cgroup2();
mount_devpts();
mount_shm();
setup_networking();
mount_virtiofs_optional("users", "/Users");
tracing::info!("PID 1 system initialization complete");
}
fn mount_tmpfs(target: &str) {
if crate::mount::is_mounted(target) {
return;
}
mkdir_p(target);
if let Err(e) = mount(
Some("tmpfs"),
target,
Some("tmpfs"),
MsFlags::MS_NODEV | MsFlags::MS_NOSUID,
None::<&str>,
) {
tracing::warn!(target, error = %e, "failed to mount tmpfs");
}
}
fn mount_cgroup2() {
if Path::new("/sys/fs/cgroup/cgroup.controllers").exists() {
return;
}
mkdir_p("/sys/fs/cgroup");
if let Err(e) = mount(
Some("cgroup2"),
"/sys/fs/cgroup",
Some("cgroup2"),
MsFlags::empty(),
None::<&str>,
) {
tracing::warn!(error = %e, "failed to mount cgroup2");
}
}
fn mount_devpts() {
if Path::new("/dev/pts/ptmx").exists() {
return;
}
mkdir_p("/dev/pts");
if let Err(e) = mount(
Some("devpts"),
"/dev/pts",
Some("devpts"),
MsFlags::MS_NOEXEC | MsFlags::MS_NOSUID,
Some("gid=5,mode=0620"),
) {
tracing::warn!(error = %e, "failed to mount devpts");
}
}
fn mount_shm() {
if crate::mount::is_mounted("/dev/shm") {
return;
}
mkdir_p("/dev/shm");
if let Err(e) = mount(
Some("shm"),
"/dev/shm",
Some("tmpfs"),
MsFlags::MS_NODEV | MsFlags::MS_NOSUID | MsFlags::MS_NOEXEC,
None::<&str>,
) {
tracing::warn!(error = %e, "failed to mount /dev/shm");
}
}
fn mount_virtiofs_optional(tag: &str, mountpoint: &str) {
if crate::mount::is_mounted(mountpoint) {
return;
}
mkdir_p(mountpoint);
if let Err(e) = mount(
Some(tag),
mountpoint,
Some("virtiofs"),
MsFlags::empty(),
None::<&str>,
) {
tracing::debug!(tag, mountpoint, error = %e, "virtiofs share not available");
}
}
fn setup_networking() {
if let Err(e) = std::fs::write("/proc/sys/net/ipv4/ip_forward", b"1\n") {
tracing::warn!(error = %e, "failed to enable ip_forward");
}
match std::process::Command::new("/bin/busybox")
.args(["ip", "link", "set", "lo", "up"])
.status()
{
Ok(s) if s.success() => {}
Ok(s) => tracing::warn!(
exit_code = s.code().unwrap_or(-1),
"loopback 'ip link set lo up' exited non-zero"
),
Err(e) => tracing::warn!(error = %e, "failed to bring up loopback"),
}
configure_primary_interface_dhcp();
}
fn configure_primary_interface_dhcp() {
let Some(interface) = detect_primary_interface() else {
tracing::warn!("no non-loopback network interface found for DHCP");
return;
};
match std::process::Command::new("/bin/busybox")
.args(["ip", "link", "set", interface.as_str(), "up"])
.status()
{
Ok(s) if s.success() => {}
Ok(s) => {
tracing::warn!(
interface,
exit_code = s.code().unwrap_or(-1),
"failed to bring interface up before DHCP"
);
}
Err(e) => {
tracing::warn!(interface, error = %e, "failed to execute 'ip link set up'");
}
}
let udhcpc_script = "/run/udhcpc.script";
let script = r#"#!/bin/sh
set -e
case "$1" in
deconfig)
/bin/busybox ifconfig "$interface" 0.0.0.0 || true
;;
renew|bound)
/bin/busybox ifconfig "$interface" "$ip" netmask "${subnet:-255.255.255.0}" broadcast "${broadcast:-+}" up
if [ -n "${router:-}" ]; then
while /bin/busybox route del default gw 0.0.0.0 dev "$interface" 2>/dev/null; do :; done
for r in $router; do
/bin/busybox route add default gw "$r" dev "$interface" && break
done
fi
;;
esac
exit 0
"#;
if let Err(e) = fs::write(udhcpc_script, script) {
tracing::warn!(error = %e, "failed to write udhcpc script");
return;
}
if let Err(e) = fs::set_permissions(udhcpc_script, fs::Permissions::from_mode(0o755)) {
tracing::warn!(error = %e, "failed to chmod udhcpc script");
return;
}
match std::process::Command::new("/bin/busybox")
.args([
"udhcpc",
"-i",
interface.as_str(),
"-n",
"-q",
"-t",
"3",
"-T",
"2",
"-s",
udhcpc_script,
])
.status()
{
Ok(s) if s.success() => {
tracing::info!(interface, "DHCP lease acquired");
}
Ok(s) => {
tracing::warn!(
interface,
exit_code = s.code().unwrap_or(-1),
"DHCP request failed"
);
}
Err(e) => {
tracing::warn!(interface, error = %e, "failed to run udhcpc");
}
}
}
fn detect_primary_interface() -> Option<String> {
let entries = fs::read_dir("/sys/class/net").ok()?;
let mut candidates = Vec::new();
for entry in entries.flatten() {
let Ok(name) = entry.file_name().into_string() else {
continue;
};
if name == "lo"
|| name.starts_with("dummy")
|| name.starts_with("veth")
|| name.starts_with("br-")
|| name.starts_with("docker")
{
continue;
}
candidates.push(name);
}
candidates.sort();
candidates.into_iter().next()
}
fn write_etc_resolv_conf() {
let content = "nameserver 192.168.64.1\n";
if let Err(e) = std::fs::write("/etc/resolv.conf", content) {
tracing::warn!(error = %e, "failed to write /etc/resolv.conf");
}
}
fn write_etc_hosts() {
let hostname = hostname::get()
.ok()
.and_then(|h| h.into_string().ok())
.unwrap_or_else(|| "arcbox".to_string());
let content = format!("127.0.0.1\tlocalhost\n::1\t\tlocalhost\n127.0.1.1\t{hostname}\n");
if let Err(e) = std::fs::write("/etc/hosts", content) {
tracing::warn!(error = %e, "failed to write /etc/hosts");
}
}
fn write_etc_passwd() {
let content =
"root:x:0:0:root:/root:/bin/sh\nnobody:x:65534:65534:nobody:/:/sbin/nologin\n";
if let Err(e) = std::fs::write("/etc/passwd", content) {
tracing::warn!(error = %e, "failed to write /etc/passwd");
}
}
fn write_etc_group() {
let content = "root:x:0:\ntty:x:5:\nnobody:x:65534:\n";
if let Err(e) = std::fs::write("/etc/group", content) {
tracing::warn!(error = %e, "failed to write /etc/group");
}
}
fn mkdir_p(path: &str) {
if let Err(e) = std::fs::create_dir_all(path) {
tracing::warn!(path, error = %e, "failed to create directory");
}
}
fn symlink_if_source_exists(source: &str, link: &str) {
if !Path::new(source).exists() {
tracing::debug!(source, "symlink source does not exist, skipping");
return;
}
match unix_fs::symlink(source, link) {
Ok(()) => {}
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {
}
Err(e) => {
tracing::warn!(source, link, error = %e, "failed to create symlink");
}
}
}
}
#[cfg(target_os = "linux")]
pub use platform::init_system;
#[cfg(not(target_os = "linux"))]
pub fn init_system() {
tracing::warn!("init_system is only functional on Linux");
}