diff --git a/acond/Cargo.lock b/acond/Cargo.lock index 076d09d..28e636a 100644 --- a/acond/Cargo.lock +++ b/acond/Cargo.lock @@ -17,6 +17,7 @@ dependencies = [ "futures", "lazy_static", "libc", + "log", "nix 0.26.4", "openidconnect", "openssl", @@ -376,9 +377,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] diff --git a/acond/Cargo.toml b/acond/Cargo.toml index 55387fd..9f5bd07 100644 --- a/acond/Cargo.toml +++ b/acond/Cargo.toml @@ -35,6 +35,7 @@ tokio-send-fd = "0.9.3" openidconnect = "3.5.0" chrono = "0.4.38" env_logger = "0.11.3" +log = "0.4.21" [dev-dependencies] # unit test diff --git a/acond/src/main.rs b/acond/src/main.rs index ee61170..261ce1e 100644 --- a/acond/src/main.rs +++ b/acond/src/main.rs @@ -65,15 +65,14 @@ fn start_service() -> Result<(), Box> { Ok(()) } Err(errno) => { - eprintln!("Start service error, errno = {errno}."); + log::error!("Start service error, errno = {errno}."); Err("Start service error, errno = {errno}.".into()) } } } fn main() -> Result<(), Box> { - // Uncomment this line to show debug information. - // env_logger::init_from_env(env_logger::Env::default().default_filter_or("debug")); + env_logger::init(); mount::mount_rootfs()?; start_service()?; diff --git a/acond/src/mount.rs b/acond/src/mount.rs index fc9dd1a..1a0ff13 100644 --- a/acond/src/mount.rs +++ b/acond/src/mount.rs @@ -4,10 +4,12 @@ use crate::utils; use anyhow::Result; use nix::mount::{self, MsFlags}; -use std::fs; -use std::io::ErrorKind; -use std::os::unix::fs as unixfs; -use std::path::Path; +use std::{ + fs::{self, File}, + io::{BufRead, BufReader, ErrorKind}, + os::unix::fs as unixfs, + path::Path, +}; lazy_static! { pub static ref SOFT_LINKS: Vec<(&'static str, &'static str)> = vec![ @@ -71,15 +73,98 @@ pub struct RootMount { pub option: Option<&'static str>, } +fn mount( + source: Option<&str>, + target: &str, + fstype: Option<&str>, + flags: MsFlags, + option: Option<&str>, +) -> Result<()> { + if !utils::is_mounted(target) { + let path = Path::new(target); + if !path.exists() { + fs::create_dir(path)?; + } + + mount::mount(source, target, fstype, flags, option)?; + } + + Ok(()) +} + +fn parse_mount_options(options_str: &str) -> (MsFlags, Vec) { + let mut flags = MsFlags::empty(); + let mut options = Vec::new(); + + for option in options_str.split(',') { + match option { + "defaults" => (), + "ro" => flags |= MsFlags::MS_RDONLY, + "nosuid" => flags |= MsFlags::MS_NOSUID, + "nodev" => flags |= MsFlags::MS_NODEV, + "noexec" => flags |= MsFlags::MS_NOEXEC, + "sync" => flags |= MsFlags::MS_SYNCHRONOUS, + "remount" => flags |= MsFlags::MS_REMOUNT, + "dirsync" => flags |= MsFlags::MS_DIRSYNC, + "diratime" => flags |= MsFlags::MS_NOATIME, + "nodiratime" => flags |= MsFlags::MS_NODIRATIME, + "silent" => flags |= MsFlags::MS_SILENT, + "relatime" => flags |= MsFlags::MS_RELATIME, + "strictatime" => flags |= MsFlags::MS_STRICTATIME, + "lazytime" => flags |= MsFlags::MS_LAZYTIME, + _ if option.contains('=') => options.push(option.into()), + _ => log::error!("Mount option '{option}' is not supported."), + } + } + + (flags, options) +} + +fn mount_fstab() -> Result<()> { + let fstab_file = File::open("/etc/fstab")?; + let reader = BufReader::new(fstab_file); + + for line in reader.lines() { + let line = line?; + if line.trim().starts_with('#') || line.trim().is_empty() { + continue; + } + + let fields: Vec<&str> = line.split_whitespace().collect(); + if fields.len() < 4 { + continue; + } + + let source = Path::new(fields[0]); + if source.is_absolute() && !source.exists() { + continue; + } + + let (flags, options) = parse_mount_options(fields[3]); + if let Err(e) = mount( + Some(fields[0]).filter(|s| *s != "none"), + fields[1], + Some(fields[2]).filter(|s| *s != "none"), + flags, + Some(options.join(",").as_str()).filter(|s| !s.is_empty()), + ) { + log::error!( + "[/etc/fstab]: failed to mount {} to {} , error is {}.", + fields[0], + fields[1], + e + ); + return Err(e.into()); + } + } + + Ok(()) +} + pub fn mount_rootfs() -> Result<()> { - if !utils::is_rootfs_mounted() { + if !utils::is_rootfs_mounted() && mount_fstab().is_err() { for m in ROOTFS_MOUNTS.iter() { - let target = Path::new(m.target); - if !target.exists() { - fs::create_dir(target)?; - } - - mount::mount(m.source, m.target, m.fstype, m.flags, m.option)?; + mount(m.source, m.target, m.fstype, m.flags, m.option)?; } } diff --git a/acond/src/report.rs b/acond/src/report.rs index 0e7987e..e0c4760 100644 --- a/acond/src/report.rs +++ b/acond/src/report.rs @@ -64,7 +64,7 @@ pub fn extend_rtmr(contents: &str) -> Result<()> { let devf = match File::options().write(true).open(TDX_GUEST) { Ok(f) => Some(f), Err(_) => { - eprintln!("Failed to open {}", TDX_GUEST); + log::error!("Failed to open {}", TDX_GUEST); None } }; diff --git a/acond/src/utils.rs b/acond/src/utils.rs index d998444..b1997e9 100644 --- a/acond/src/utils.rs +++ b/acond/src/utils.rs @@ -596,6 +596,27 @@ pub fn is_rootfs_mounted() -> bool { Path::new("/proc/mounts").exists() } +pub fn is_mounted(path: &str) -> bool { + let file = match File::open("/proc/mounts") { + Ok(f) => f, + _ => return false, + }; + let reader = BufReader::new(file); + + for line in reader.lines() { + let line = match line { + Ok(l) => l, + Err(_) => return false, + }; + let fields: Vec<&str> = line.split_whitespace().collect(); + if fields.len() > 1 && fields[1] == path { + return true; + } + } + + false +} + pub fn start_with_uppercase(command: &str) -> bool { command .chars()