summaryrefslogtreecommitdiff
path: root/init/src/mounts/fstab.rs
diff options
context:
space:
mode:
authornamilsk <namilsk@namilsk.tech>2025-12-31 17:31:34 +0300
committernamilsk <namilsk@namilsk.tech>2025-12-31 17:31:34 +0300
commitafe6b0d5d59c90b3765914eb771ad8237d40a90f (patch)
treea965cdff3536cca2d3ef775980e398ff1a34b41e /init/src/mounts/fstab.rs
Started work on vigil init system
Diffstat (limited to 'init/src/mounts/fstab.rs')
-rw-r--r--init/src/mounts/fstab.rs97
1 files changed, 97 insertions, 0 deletions
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