Volt VMM (Neutron Stardust): source-available under AGPSL v5.0
KVM-based microVMM for the Volt platform: - Sub-second VM boot times - Minimal memory footprint - Landlock LSM + seccomp security - Virtio device support - Custom kernel management Copyright (c) Armored Gates LLC. All rights reserved. Licensed under AGPSL v5.0
This commit is contained in:
109
rootfs/volt-init/src/sys.rs
Normal file
109
rootfs/volt-init/src/sys.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
// System utilities: signal handling, hostname, kernel cmdline, console
|
||||
|
||||
use std::ffi::CString;
|
||||
|
||||
/// Set up console I/O by ensuring fd 0/1/2 point to /dev/console or /dev/ttyS0
|
||||
pub fn setup_console() {
|
||||
// Try /dev/console first, then /dev/ttyS0
|
||||
let consoles = ["/dev/console", "/dev/ttyS0"];
|
||||
|
||||
for console in &consoles {
|
||||
let c_path = CString::new(*console).unwrap();
|
||||
let fd = unsafe { libc::open(c_path.as_ptr(), libc::O_RDWR | libc::O_NOCTTY | libc::O_NONBLOCK) };
|
||||
if fd >= 0 {
|
||||
// Clear O_NONBLOCK now that the open succeeded
|
||||
unsafe {
|
||||
let flags = libc::fcntl(fd, libc::F_GETFL);
|
||||
if flags >= 0 {
|
||||
libc::fcntl(fd, libc::F_SETFL, flags & !libc::O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
// Close existing fds and dup console to 0, 1, 2
|
||||
if fd != 0 {
|
||||
unsafe {
|
||||
libc::close(0);
|
||||
libc::dup2(fd, 0);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
libc::close(1);
|
||||
libc::dup2(fd, 1);
|
||||
libc::close(2);
|
||||
libc::dup2(fd, 2);
|
||||
}
|
||||
if fd > 2 {
|
||||
unsafe {
|
||||
libc::close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
// Make this our controlling terminal
|
||||
unsafe {
|
||||
libc::ioctl(0, libc::TIOCSCTTY as libc::Ioctl, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If we get here, no console device available — output will be lost
|
||||
}
|
||||
|
||||
/// Install signal handlers for PID 1
|
||||
pub fn install_signal_handlers() {
|
||||
unsafe {
|
||||
// SIGCHLD: reap zombies
|
||||
libc::signal(
|
||||
libc::SIGCHLD,
|
||||
sigchld_handler as *const () as libc::sighandler_t,
|
||||
);
|
||||
|
||||
// SIGTERM: ignore (PID 1 handles shutdown via shell)
|
||||
libc::signal(libc::SIGTERM, libc::SIG_IGN);
|
||||
|
||||
// SIGINT: ignore (Ctrl+C shouldn't kill init)
|
||||
libc::signal(libc::SIGINT, libc::SIG_IGN);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn sigchld_handler(_sig: libc::c_int) {
|
||||
// Reap all zombie children
|
||||
unsafe {
|
||||
loop {
|
||||
let ret = libc::waitpid(-1, std::ptr::null_mut(), libc::WNOHANG);
|
||||
if ret <= 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read kernel command line
|
||||
pub fn read_kernel_cmdline() -> String {
|
||||
std::fs::read_to_string("/proc/cmdline")
|
||||
.unwrap_or_default()
|
||||
.trim()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Parse a key=value from kernel cmdline
|
||||
pub fn parse_cmdline_value(cmdline: &str, key: &str) -> Option<String> {
|
||||
let prefix = format!("{}=", key);
|
||||
for param in cmdline.split_whitespace() {
|
||||
if let Some(value) = param.strip_prefix(&prefix) {
|
||||
return Some(value.to_string());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Set system hostname
|
||||
pub fn set_hostname(name: &str) {
|
||||
let c_name = CString::new(name).unwrap();
|
||||
let ret = unsafe { libc::sethostname(c_name.as_ptr(), name.len()) };
|
||||
if ret != 0 {
|
||||
eprintln!(
|
||||
"[volt-init] Failed to set hostname: {}",
|
||||
std::io::Error::last_os_error()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user