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:
Fabiano Fidêncio
2023-08-01 17:14:17 +02:00
426 changed files with 64309 additions and 2456 deletions

2
src/agent/Cargo.lock generated
View File

@@ -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",

View File

@@ -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"

View File

@@ -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)

View File

@@ -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]

View File

@@ -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) {

View File

@@ -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;
}

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={:?}",
@@ -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)]

View File

@@ -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"))
}
}
}

View File

@@ -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!(

View File

@@ -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,