mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 12:44:39 +00:00
agent: Ignore already mounted dev/fs/pseudo-fs
Using an initrd and setting KATA_INIT=yes meaning we're using the kata-agent as the init process we need to make sure that the agent is not segfaulting if mounts are already happened. Some workloads need to configure several things in the initrd before the kata-agent starts which involves having /proc or /sys already mounted. Fixes: #6992 Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
This commit is contained in:
parent
58e921eace
commit
07810bf71f
@ -145,6 +145,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 +173,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={:?}",
|
||||
@ -1112,6 +1142,42 @@ mod tests {
|
||||
skip_if_not_root, skip_loop_by_user, skip_loop_if_not_root, skip_loop_if_root,
|
||||
};
|
||||
|
||||
// Shadow get_mounts during tests since this is only used in the test
|
||||
// context, compiler will warn about dead-code.
|
||||
#[allow(dead_code)]
|
||||
fn get_mounts() -> Result<String, std::io::Error> {
|
||||
Ok(String::from(
|
||||
"
|
||||
rootfs / rootfs rw,size=1694984k,nr_inodes=423746 0 0
|
||||
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
|
||||
sys /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
|
||||
dev /dev devtmpfs rw,nosuid,relatime,size=1695000k,nr_inodes=423750,mode=755 0 0
|
||||
run /run tmpfs rw,nosuid,nodev,relatime,mode=755 0 0
|
||||
",
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_already_baremounted() {
|
||||
let drain = slog::Discard;
|
||||
let logger = slog::Logger::root(drain, 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!("baremount({:?} {:?} {:?}", source, destination, fs_type);
|
||||
assert!(baremount(source, destination, fs_type, flags, options, &logger).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mount() {
|
||||
#[derive(Debug)]
|
||||
|
Loading…
Reference in New Issue
Block a user