diff options
Diffstat (limited to 'init')
| -rw-r--r-- | init/Cargo.toml | 9 | ||||
| -rw-r--r-- | init/src/main.rs | 10 | ||||
| -rw-r--r-- | init/src/mounts/fstab.rs | 97 | ||||
| -rw-r--r-- | init/src/mounts/mod.rs | 2 | ||||
| -rw-r--r-- | init/src/mounts/rescue.rs | 50 | ||||
| -rw-r--r-- | init/src/pid_one.rs | 10 |
6 files changed, 178 insertions, 0 deletions
diff --git a/init/Cargo.toml b/init/Cargo.toml new file mode 100644 index 0000000..a63ffb7 --- /dev/null +++ b/init/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "init" +version = "0.1.0" +edition = "2024" +description = "Lightweight and stable init system for Anthrill distro based on unix-phylosophy." + +[dependencies] +errno = "0.3.14" +libc = "0.2.178" diff --git a/init/src/main.rs b/init/src/main.rs new file mode 100644 index 0000000..bfcef87 --- /dev/null +++ b/init/src/main.rs @@ -0,0 +1,10 @@ +mod mounts; +mod pid_one; + +use crate::pid_one::check_pid; + +fn main() -> Result<(), Box<dyn std::error::Error>> { + println!("Initializing your system."); + check_pid().expect("Runned not as PID 1."); + Ok(()) +} diff --git a/init/src/mounts/fstab.rs b/init/src/mounts/fstab.rs new file mode 100644 index 0000000..4c43eac --- /dev/null +++ b/init/src/mounts/fstab.rs @@ -0,0 +1,97 @@ +use libc::{self}; +use std::ffi::CString; + +#[derive(Debug)] +pub struct FstabEntry { + pub source: String, + pub mountpoint: String, + pub fstype: String, + pub options: String, + pub dump: u32, + pub pass: u32, +} + +fn parse_mount_options( + options: &str, +) -> Result<(libc::c_ulong, Option<String>), Box<dyn std::error::Error>> { + let mut flags = 0; + let mut data_parts = Vec::new(); + + for opt in options.split(',') { + match opt { + "defaults" => { /* handled by not setting any restrictive flags */ } + "ro" => flags |= libc::MS_RDONLY, + "rw" => flags &= !libc::MS_RDONLY, + "noexec" => flags |= libc::MS_NOEXEC, + "nosuid" => flags |= libc::MS_NOSUID, + "nodev" => flags |= libc::MS_NODEV, + "sync" => flags |= libc::MS_SYNCHRONOUS, + "dirsync" => flags |= libc::MS_DIRSYNC, + "bind" => flags |= libc::MS_BIND, + "rbind" => flags |= libc::MS_BIND | libc::MS_REC, + "remount" => flags |= libc::MS_REMOUNT, + _ => { + if !opt.is_empty() { + data_parts.push(opt); + } + } + } + } + + let data = if data_parts.is_empty() { + None + } else { + Some(data_parts.join(",")) + }; + + Ok((flags, data)) +} + + + + +pub fn mount_from_fstab(entries: &[FstabEntry]) -> Result<(), Box<dyn std::error::Error>> { + for entry in entries { + if entry.fstype == "swap" { + println!("Skipping swap: {}", entry.source); + continue; + } + + if entry.mountpoint == "none" { + continue; + } + + if entry.options.contains("noauto") { + continue; + } + + let (flags, data) = parse_mount_options(&entry.options)?; + + let source_c = CString::new(&*entry.source)?; + let target_c = CString::new(&*entry.mountpoint)?; + let fstype_c = CString::new(&*entry.fstype)?; + let data_c = data.map(|s| CString::new(s).expect("\x1b[31m * \x1b[0m Something went wrong while mounting partitions. You are going to rescue mode...")); + + let data_ptr = data_c + .as_ref() + .map_or(std::ptr::null(), |s| s.as_ptr() as *const libc::c_void); + + let ret = unsafe { + libc::syscall( + libc::SYS_mount, + source_c.as_ptr(), + target_c.as_ptr(), + fstype_c.as_ptr(), + flags, + data_ptr, + ) + }; + + if ret != 0 { + eprintln!("Failed to mount {}: {}", entry.mountpoint, std::io::Error::last_os_error()); + } else { + println!("Mounted {}", entry.mountpoint); + } + } + Ok(()) +}
\ No newline at end of file diff --git a/init/src/mounts/mod.rs b/init/src/mounts/mod.rs new file mode 100644 index 0000000..bdaab24 --- /dev/null +++ b/init/src/mounts/mod.rs @@ -0,0 +1,2 @@ +pub mod fstab; +pub mod rescue;
\ No newline at end of file diff --git a/init/src/mounts/rescue.rs b/init/src/mounts/rescue.rs new file mode 100644 index 0000000..ba058f4 --- /dev/null +++ b/init/src/mounts/rescue.rs @@ -0,0 +1,50 @@ +use libc::{self}; +use std::ffi::CString; +use std::fs::create_dir; + + + + +pub fn mount_system() -> Result<(), Box<dyn std::error::Error>> { + let mounts: &[(&str, &str, Option<&str>)] = &[ + ("/proc", "proc", None), + ("/sys", "sysfs", None), + ("/dev", "devtmpfs", Some("devtmpfs")), + ("/tmp", "tmpfs", None), + ("/run", "tmpfs", None), + ]; + + unsafe { + for &(target, fstype, source) in mounts { + let target_c = CString::new(target)?; + let fstype_c = CString::new(fstype)?; + let source_c = source.map(|s| CString::new(s).unwrap()); + + let _ = create_dir(target); + + let source_ptr = source_c.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()); + + let ret = libc::syscall( + libc::SYS_mount, + source_ptr, + target_c.as_ptr(), + fstype_c.as_ptr(), + 0 as libc::c_ulong, + std::ptr::null::<libc::c_void>(), + ); + + if ret != 0 { + let errno = errno::errno().0; + return Err(format!( + "Failed to mount {}: {}", + target, + std::io::Error::from_raw_os_error(errno) + ) + .into()); + } + println!("\x1b[32m * \x1b[0m Mounting {}...", target ); + } + } + + Ok(()) +} diff --git a/init/src/pid_one.rs b/init/src/pid_one.rs new file mode 100644 index 0000000..84cca47 --- /dev/null +++ b/init/src/pid_one.rs @@ -0,0 +1,10 @@ +use std::process::id; + +pub fn check_pid() -> Result<(), Box<dyn std::error::Error>> { + let pid = id(); + + match pid { + 1 => Ok(()), + _ => Err("Runned not as first process.".into()), + } +} |
