Merge pull request #6993 from zvonkok/kata-agent-init-mount

agent: Ignore already mounted dev/fs/pseudo-fs
This commit is contained in:
Fabiano Fidêncio 2023-07-18 14:11:44 +02:00 committed by GitHub
commit 25d80fcec2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 0 deletions

1
src/agent/Cargo.lock generated
View File

@ -842,6 +842,7 @@ dependencies = [
"slog",
"slog-scope",
"slog-stdlog",
"slog-term",
"tempfile",
"test-utils",
"thiserror",

View File

@ -43,6 +43,7 @@ ipnetwork = "0.17.0"
logging = { path = "../libs/logging" }
slog = "2.5.2"
slog-scope = "4.1.2"
slog-term = "2.9.0"
# Redirect ttrpc log calls
slog-stdlog = "4.0.0"

View File

@ -36,6 +36,7 @@ use crate::Sandbox;
use crate::{ccw, device::get_virtio_blk_ccw_device_name};
use anyhow::{anyhow, Context, Result};
use slog::Logger;
use tracing::instrument;
pub const TYPE_ROOTFS: &str = "rootfs";
@ -145,6 +146,11 @@ pub const STORAGE_HANDLER_LIST: &[&str] = &[
DRIVER_WATCHABLE_BIND_TYPE,
];
#[instrument]
pub fn get_mounts() -> Result<String, std::io::Error> {
fs::read_to_string("/proc/mounts")
}
#[instrument]
pub fn baremount(
source: &Path,
@ -168,6 +174,31 @@ pub fn baremount(
return Err(anyhow!("need mount FS type"));
}
let destination_str = destination.to_string_lossy();
let mounts = get_mounts().unwrap_or_else(|_| String::new());
let already_mounted = mounts
.lines()
.map(|line| line.split_whitespace().collect::<Vec<&str>>())
.filter(|parts| parts.len() >= 3) // ensure we have at least [source}, destination, and fs_type
.any(|parts| {
// Check if source, destination and fs_type match any entry in /proc/mounts
// minimal check is for destination an fstype since source can have different names like:
// udev /dev devtmpfs
// dev /dev devtmpfs
// depending on which entity is mounting the dev/fs/pseudo-fs
parts[1] == destination_str && parts[2] == fs_type
});
if already_mounted {
slog_info!(
logger,
"{:?} is already mounted at {:?}",
source,
destination
);
return Ok(());
}
info!(
logger,
"baremount source={:?}, dest={:?}, fs_type={:?}, options={:?}, flags={:?}",
@ -1102,6 +1133,7 @@ fn parse_options(option_list: Vec<String>) -> HashMap<String, String> {
mod tests {
use super::*;
use protocols::agent::FSGroup;
use slog::Drain;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::Write;
@ -1112,6 +1144,31 @@ mod tests {
skip_if_not_root, skip_loop_by_user, skip_loop_if_not_root, skip_loop_if_root,
};
#[test]
fn test_already_baremounted() {
let plain = slog_term::PlainSyncDecorator::new(std::io::stdout());
let logger = Logger::root(slog_term::FullFormat::new(plain).build().fuse(), o!());
let test_cases = [
("dev", "/dev", "devtmpfs"),
("udev", "/dev", "devtmpfs"),
("proc", "/proc", "proc"),
("sysfs", "/sys", "sysfs"),
];
for &(source, destination, fs_type) in &test_cases {
let source = Path::new(source);
let destination = Path::new(destination);
let flags = MsFlags::MS_RDONLY;
let options = "mode=755";
println!(
"testing if already mounted baremount({:?} {:?} {:?})",
source, destination, fs_type
);
assert!(baremount(source, destination, fs_type, flags, options, &logger).is_ok());
}
}
#[test]
fn test_mount() {
#[derive(Debug)]