summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init/src/host/mod.rs1
-rw-r--r--init/src/host/sethn.rs37
-rw-r--r--init/src/log.rs12
-rw-r--r--init/src/main.rs56
-rw-r--r--init/src/mounts/fstab.rs48
-rw-r--r--init/src/mounts/rescue.rs3
6 files changed, 128 insertions, 29 deletions
diff --git a/init/src/host/mod.rs b/init/src/host/mod.rs
new file mode 100644
index 0000000..4a3de53
--- /dev/null
+++ b/init/src/host/mod.rs
@@ -0,0 +1 @@
+pub mod sethn; \ No newline at end of file
diff --git a/init/src/host/sethn.rs b/init/src/host/sethn.rs
new file mode 100644
index 0000000..1857297
--- /dev/null
+++ b/init/src/host/sethn.rs
@@ -0,0 +1,37 @@
+use std::{ffi::CString, fs, io};
+use libc::{sethostname, c_char, size_t};
+use crate::log::{log_warning};
+
+pub fn try_set_hostname() {
+ let content = fs::read_to_string("/etc/hostname")
+ .map(|s| s.trim().to_string())
+ .unwrap_or_else(|_| "localhost".to_string());
+
+ if let Err(e) = perform_set_hostname(&content) {
+ log_warning(&format!("Failed to set hostname to '{}': {}. Falling back to localhost.", content, e));
+ let _ = perform_set_hostname("localhost");
+ }
+}
+
+fn perform_set_hostname(name: &str) -> io::Result<()> {
+ if name.len() > 64 {
+ return Err(io::Error::new(io::ErrorKind::InvalidInput, "Hostname too long"));
+ }
+
+ let c_str = CString::new(name).map_err(|_| {
+ io::Error::new(io::ErrorKind::InvalidInput, "Hostname contains null byte")
+ })?;
+
+ let res = unsafe {
+ sethostname(
+ c_str.as_ptr() as *const c_char,
+ name.len() as size_t,
+ )
+ };
+
+ if res != 0 {
+ return Err(io::Error::last_os_error());
+ }
+
+ Ok(())
+} \ No newline at end of file
diff --git a/init/src/log.rs b/init/src/log.rs
new file mode 100644
index 0000000..23f644f
--- /dev/null
+++ b/init/src/log.rs
@@ -0,0 +1,12 @@
+pub fn log_critical_error(message: &str) {
+ println!("\x1b[31m * \x1b[0m {}", message);
+}
+
+pub fn log_warning(message: &str) {
+ println!("\x1b[33m * \x1b[0m {}", message);
+}
+
+pub fn log_success(message: &str) {
+ println!("\x1b[32m * \x1b[0m {}", message);
+}
+
diff --git a/init/src/main.rs b/init/src/main.rs
index e944424..feea052 100644
--- a/init/src/main.rs
+++ b/init/src/main.rs
@@ -1,36 +1,78 @@
+mod log;
mod mounts;
mod pid_one;
+mod host;
+use crate::log::{log_critical_error, log_warning, log_success};
use crate::mounts::fstab::FstabEntry;
use crate::mounts::rescue;
use crate::pid_one::check_pid;
+use crate::host::sethn::try_set_hostname;
+
+use std::process::Command;
// RULE: I will not use .expect() and .unwrap() in this project. This causes panic,
// which will affect stability.
+fn spawn_udev() -> Result<(), Box<dyn std::error::Error>> {
+ log_success("Spawning udev daemon.");
+
+ let udevd_paths = [
+ "/sbin/udevd",
+ "/usr/sbin/udevd",
+ "/bin/udevd",
+ "/usr/bin/udevd",
+ ];
+ let udevd_path = udevd_paths
+ .iter()
+ .find(|path| std::path::Path::new(path).exists())
+ .ok_or("udevd not found in standard locations")?;
+
+ let child = Command::new(udevd_path)
+ .arg("--daemon")
+ .spawn()
+ .map_err(|e| format!("Failed to spawn udevd: {}", e))?;
+
+ log_success(&format!("udevd started with PID: {}", child.id()));
+ Command::new(udevd_path)
+ .arg("--trigger")
+ .output()
+ .map_err(|e| format!("Failed to trigger udev: {}", e))?;
+
+ Ok(())
+}
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Initializing your system.");
- check_pid().expect("\x1b[31m * \x1b[0m Runned not as first process. init/src/pid_one.rs:8:8");
-
+ if let Err(e) = check_pid() {
+ log_critical_error(&format!("Runned not as first process. init/src/pid_one.rs:8:8 - {}", e));
+ return Err(e);
+ }
+
match FstabEntry::parse_fstab("/etc/fstab") {
Ok(entries) => {
- println!("\x1b[32m * \x1b[0m Sucessfully parsed /etc/fstab.");
+ log_success("Sucessfully parsed /etc/fstab.");
for entry in &entries {
let _ = entry.mount();
}
- },
+ }
Err(error) => {
- println!("\x1b[33m * \x1b[0m Looks like fstab broken. Mounting all without reading /etc/fstab.");
- println!("\x1b[33m * \x1b[0m Error:\n {}", error);
+ log_warning("Looks like fstab broken. Mounting all without reading /etc/fstab.");
+ log_warning(&format!("Error:\n {}", error));
let _ = rescue::mount_system();
-
+
// Minimal mounts without fstab, because /etc/fstab needs fixes :)
// Btw it should be used if fstab broken or has syntax-errors
// TODO: If fstab contains syntax errors, mount everything else that does not contain them through it anyway.
}
}
+ let _ = try_set_hostname();
+ match spawn_udev() {
+ Ok(_) => log_success("Successfully started udev daemon."),
+ Err(e) => log_critical_error(&format!("Failed to start udev daemon: {}", e)),
+ }
Ok(())
}
diff --git a/init/src/mounts/fstab.rs b/init/src/mounts/fstab.rs
index 3ea62e5..c0cfd58 100644
--- a/init/src/mounts/fstab.rs
+++ b/init/src/mounts/fstab.rs
@@ -1,6 +1,7 @@
-use libc::{self};
+use crate::log::{log_critical_error, log_warning, log_success};
use std::ffi::CString;
-use std::{fs, fmt};
+use std::{fmt, fs};
+use libc::syscall;
#[derive(Debug)]
pub struct FstabEntry {
@@ -16,7 +17,7 @@ impl fmt::Display for FstabEntry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
- "{} {} {} {} {} {}",
+ "Source: {}\n Mountpoint: {}\n FSType: {}\n Options: {}\n Dump: {}\n Pass: {}\n",
self.source, self.mountpoint, self.fstype, self.options, self.dump, self.pass
)
}
@@ -41,13 +42,13 @@ impl FstabEntry {
let fstype = parts[2].to_string();
let options = parts[3].to_string();
- let dump = parts[4].parse::<u32>().map_err(|e| {
- format!("Failed to parse dump field '{}': {}", parts[4], e)
- })?;
+ let dump = parts[4]
+ .parse::<u32>()
+ .map_err(|e| format!("Failed to parse dump field '{}': {}", parts[4], e))?;
- let pass = parts[5].parse::<u32>().map_err(|e| {
- format!("Failed to parse pass field '{}': {}", parts[5], e)
- })?;
+ let pass = parts[5]
+ .parse::<u32>()
+ .map_err(|e| format!("Failed to parse pass field '{}': {}", parts[5], e))?;
Ok(FstabEntry {
source,
@@ -67,7 +68,7 @@ impl FstabEntry {
match Self::parse_line(line) {
Ok(entry) => entries.push(entry),
Err(_) => {
- println!("\x1b[32m * \x1b[0m Warning: Skipping invalid fstab line: {}", line);
+ log_warning(&format!("Skipping invalid fstab line: {}", line));
continue;
}
}
@@ -113,11 +114,17 @@ impl FstabEntry {
Ok((flags, data))
}
+
pub fn mount(&self) -> Result<(), Box<dyn std::error::Error>> {
- println!("\x1b[32m * \x1b[0m Started mounting {} from {}", self.mountpoint, self.source);
-
+ log_success(&format!("Started mounting {} from {}", self.mountpoint, self.source));
+
if self.fstype == "swap" {
- println!("\x1b[30m * \x1b[0m Skipping swap: {}", self.source);
+ log_success(&format!("Filesystem type contains swap, upping it: {}", self.source));
+
+ unsafe {
+ syscall(libc::SYS_swapon, &self.source, 0);
+ }
+
return Ok(());
}
@@ -134,14 +141,14 @@ impl FstabEntry {
let source_c = CString::new(&*self.source)?;
let target_c = CString::new(&*self.mountpoint)?;
let fstype_c = CString::new(&*self.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_c = data.map(|s| CString::new(s)).transpose()?;
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(
+ syscall(
libc::SYS_mount,
source_c.as_ptr(),
target_c.as_ptr(),
@@ -152,15 +159,14 @@ impl FstabEntry {
};
if ret != 0 {
- eprintln!(
- "\x1b[31m * \x1b[0m Failed to mount {}: {}",
+ log_critical_error(&format!(
+ "Failed to mount {}: {}",
self.mountpoint,
std::io::Error::last_os_error()
- );
+ ));
} else {
- println!("\x1b[32m * \x1b[0m Mounted {}", self.mountpoint);
+ log_success(&format!("Mounted {}", self.mountpoint));
}
Ok(())
}
-
-} \ No newline at end of file
+}
diff --git a/init/src/mounts/rescue.rs b/init/src/mounts/rescue.rs
index 84517ed..ad80a84 100644
--- a/init/src/mounts/rescue.rs
+++ b/init/src/mounts/rescue.rs
@@ -1,3 +1,4 @@
+use crate::log::log_success;
use std::ffi::CString;
use std::fs::create_dir;
@@ -38,7 +39,7 @@ pub fn mount_system() -> Result<(), Box<dyn std::error::Error>> {
)
.into());
}
- println!("\x1b[32m * \x1b[0m Mounting {}...", target);
+ log_success(&format!("Mounting {}...", target));
}
}