Skip to content

Commit

Permalink
acond: mount rootfs from /etc/fstab (#111)
Browse files Browse the repository at this point in the history
* acond: mount rootfs from /etc/fstab
* Fix review comments

---------

Signed-off-by: Xiangquan Liu <[email protected]>
  • Loading branch information
xiangquanliu authored Jun 28, 2024
1 parent 2305b50 commit 8fdbca2
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 17 deletions.
5 changes: 3 additions & 2 deletions acond/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions acond/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions acond/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,14 @@ fn start_service() -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
// 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()?;
Expand Down
107 changes: 96 additions & 11 deletions acond/src/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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![
Expand Down Expand Up @@ -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<String>) {
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)?;
}
}

Expand Down
2 changes: 1 addition & 1 deletion acond/src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
};
Expand Down
21 changes: 21 additions & 0 deletions acond/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 8fdbca2

Please sign in to comment.