mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-01-16 04:44:21 +01:00
CCv0: Merge from main -- August 1st
Conflicts: src/runtime/pkg/katautils/config.go src/runtime/virtcontainers/container.go src/runtime/virtcontainers/hypervisor.go src/runtime/virtcontainers/qemu_arch_base.go src/runtime/virtcontainers/sandbox.go tests/integration/kubernetes/gha-run.sh tests/integration/kubernetes/setup.sh tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml tools/packaging/kata-deploy/local-build/kata-deploy-binaries.sh tools/packaging/kata-deploy/scripts/kata-deploy.sh tools/packaging/kernel/kata_config_version versions.yaml Fixes: #7433 Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
This commit is contained in:
2
src/agent/Cargo.lock
generated
2
src/agent/Cargo.lock
generated
@@ -2081,6 +2081,7 @@ dependencies = [
|
||||
"slog",
|
||||
"slog-scope",
|
||||
"slog-stdlog",
|
||||
"slog-term",
|
||||
"tempfile",
|
||||
"test-utils",
|
||||
"thiserror",
|
||||
@@ -2100,6 +2101,7 @@ dependencies = [
|
||||
name = "kata-sys-util"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
"cgroups-rs",
|
||||
"chrono",
|
||||
|
||||
@@ -44,6 +44,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"
|
||||
|
||||
@@ -26,7 +26,7 @@ export VERSION_COMMIT := $(if $(COMMIT),$(VERSION)-$(COMMIT),$(VERSION))
|
||||
EXTRA_RUSTFEATURES :=
|
||||
|
||||
##VAR SECCOMP=yes|no define if agent enables seccomp feature
|
||||
SECCOMP := yes
|
||||
SECCOMP ?= yes
|
||||
|
||||
# Enable seccomp feature of rust build
|
||||
ifeq ($(SECCOMP),yes)
|
||||
|
||||
@@ -1118,6 +1118,7 @@ mod tests {
|
||||
use std::fs::create_dir;
|
||||
use std::fs::create_dir_all;
|
||||
use std::fs::remove_dir_all;
|
||||
use std::fs::remove_file;
|
||||
use std::io;
|
||||
use std::os::unix::fs;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
@@ -1333,14 +1334,9 @@ mod tests {
|
||||
fn test_mknod_dev() {
|
||||
skip_if_not_root!();
|
||||
|
||||
let tempdir = tempdir().unwrap();
|
||||
|
||||
let olddir = unistd::getcwd().unwrap();
|
||||
defer!(let _ = unistd::chdir(&olddir););
|
||||
let _ = unistd::chdir(tempdir.path());
|
||||
|
||||
let path = "/dev/fifo-test";
|
||||
let dev = oci::LinuxDevice {
|
||||
path: "/fifo".to_string(),
|
||||
path: path.to_string(),
|
||||
r#type: "c".to_string(),
|
||||
major: 0,
|
||||
minor: 0,
|
||||
@@ -1348,13 +1344,16 @@ mod tests {
|
||||
uid: Some(unistd::getuid().as_raw()),
|
||||
gid: Some(unistd::getgid().as_raw()),
|
||||
};
|
||||
let path = Path::new("fifo");
|
||||
|
||||
let ret = mknod_dev(&dev, path);
|
||||
let ret = mknod_dev(&dev, Path::new(path));
|
||||
assert!(ret.is_ok(), "Should pass. Got: {:?}", ret);
|
||||
|
||||
let ret = stat::stat(path);
|
||||
assert!(ret.is_ok(), "Should pass. Got: {:?}", ret);
|
||||
|
||||
// clear test device node
|
||||
let ret = remove_file(path);
|
||||
assert!(ret.is_ok(), "Should pass, Got: {:?}", ret);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -161,7 +161,7 @@ impl Process {
|
||||
|
||||
pub fn notify_term_close(&mut self) {
|
||||
let notify = self.term_exit_notifier.clone();
|
||||
notify.notify_one();
|
||||
notify.notify_waiters();
|
||||
}
|
||||
|
||||
pub fn close_stdin(&mut self) {
|
||||
|
||||
@@ -33,7 +33,7 @@ pub fn create_pci_root_bus_path() -> String {
|
||||
|
||||
// check if there is pci bus path for acpi
|
||||
acpi_sysfs_dir.push_str(&acpi_root_bus_path);
|
||||
if let Ok(_) = fs::metadata(&acpi_sysfs_dir) {
|
||||
if fs::metadata(&acpi_sysfs_dir).is_ok() {
|
||||
return acpi_root_bus_path;
|
||||
}
|
||||
|
||||
|
||||
@@ -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={:?}",
|
||||
@@ -725,6 +756,14 @@ pub fn recursive_ownership_change(
|
||||
mask |= EXEC_MASK;
|
||||
mask |= MODE_SETGID;
|
||||
}
|
||||
|
||||
// We do not want to change the permission of the underlying file
|
||||
// using symlink. Hence we skip symlinks from recursive ownership
|
||||
// and permission changes.
|
||||
if path.is_symlink() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
nix::unistd::chown(path, uid, gid)?;
|
||||
|
||||
if gid.is_some() {
|
||||
@@ -1102,6 +1141,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 +1152,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)]
|
||||
|
||||
@@ -665,15 +665,16 @@ impl AgentService {
|
||||
let cid = req.container_id;
|
||||
let eid = req.exec_id;
|
||||
|
||||
let mut term_exit_notifier = Arc::new(tokio::sync::Notify::new());
|
||||
let term_exit_notifier;
|
||||
let reader = {
|
||||
let s = self.sandbox.clone();
|
||||
let mut sandbox = s.lock().await;
|
||||
|
||||
let p = sandbox.find_container_process(cid.as_str(), eid.as_str())?;
|
||||
|
||||
term_exit_notifier = p.term_exit_notifier.clone();
|
||||
|
||||
if p.term_master.is_some() {
|
||||
term_exit_notifier = p.term_exit_notifier.clone();
|
||||
p.get_reader(StreamType::TermMaster)
|
||||
} else if stdout {
|
||||
if p.parent_stdout.is_some() {
|
||||
@@ -693,9 +694,12 @@ impl AgentService {
|
||||
let reader = reader.ok_or_else(|| anyhow!("cannot get stream reader"))?;
|
||||
|
||||
tokio::select! {
|
||||
_ = term_exit_notifier.notified() => {
|
||||
Err(anyhow!("eof"))
|
||||
}
|
||||
// Poll the futures in the order they appear from top to bottom
|
||||
// it is very important to avoid data loss. If there is still
|
||||
// data in the buffer and read_stream branch will return
|
||||
// Poll::Ready so that the term_exit_notifier will never polled
|
||||
// before all data were read.
|
||||
biased;
|
||||
v = read_stream(reader, req.len as usize) => {
|
||||
let vector = v?;
|
||||
let mut resp = ReadStreamResponse::new();
|
||||
@@ -703,6 +707,9 @@ impl AgentService {
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
_ = term_exit_notifier.notified() => {
|
||||
Err(anyhow!("eof"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ fn online_resources(logger: &Logger, path: &str, pattern: &str, num: i32) -> Res
|
||||
}
|
||||
|
||||
// max wait for all CPUs to online will use 50 * 100 = 5 seconds.
|
||||
const ONLINE_CPUMEM_WATI_MILLIS: u64 = 50;
|
||||
const ONLINE_CPUMEM_WAIT_MILLIS: u64 = 50;
|
||||
const ONLINE_CPUMEM_MAX_RETRIES: i32 = 100;
|
||||
|
||||
#[instrument]
|
||||
@@ -465,7 +465,7 @@ fn online_cpus(logger: &Logger, num: i32) -> Result<i32> {
|
||||
);
|
||||
return Ok(num);
|
||||
}
|
||||
thread::sleep(time::Duration::from_millis(ONLINE_CPUMEM_WATI_MILLIS));
|
||||
thread::sleep(time::Duration::from_millis(ONLINE_CPUMEM_WAIT_MILLIS));
|
||||
}
|
||||
|
||||
Err(anyhow!(
|
||||
|
||||
@@ -57,7 +57,7 @@ async fn handle_sigchild(logger: Logger, sandbox: Arc<Mutex<Sandbox>>) -> Result
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut p = process.unwrap();
|
||||
let p = process.unwrap();
|
||||
|
||||
let ret: i32 = match wait_status {
|
||||
WaitStatus::Exited(_, c) => c,
|
||||
|
||||
Reference in New Issue
Block a user