summaryrefslogtreecommitdiff
path: root/init/src
diff options
context:
space:
mode:
Diffstat (limited to 'init/src')
-rw-r--r--init/src/main.rs10
-rw-r--r--init/src/mounts/fstab.rs97
-rw-r--r--init/src/mounts/mod.rs2
-rw-r--r--init/src/mounts/rescue.rs50
-rw-r--r--init/src/pid_one.rs10
5 files changed, 169 insertions, 0 deletions
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()),
+ }
+}