Skip to content

Commit

Permalink
Intel RDT OCI support.
Browse files Browse the repository at this point in the history
Signed-off-by: Ismo Puustinen <[email protected]>
  • Loading branch information
ipuustin committed Apr 24, 2023
1 parent 59a888b commit 6d9bd12
Show file tree
Hide file tree
Showing 10 changed files with 581 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions crates/libcontainer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ mio = { version = "0.8.6", features = ["os-ext", "os-poll"] }
nix = "0.26.2"
path-clean = "1.0.1"
oci-spec = { version = "^0.6.0", features = ["runtime"] }
once_cell = "1.17.1"
procfs = "0.15.1"
prctl = "1.0.0"
libcgroups = { version = "0.0.5", path = "../libcgroups", default-features = false }
Expand All @@ -42,6 +43,7 @@ serde_json = "1.0"
syscalls = "0.6.10"
rust-criu = "0.4.0"
clone3 = "0.2.3"
regex = "1.7.3"

[dev-dependencies]
oci-spec = { version = "^0.6.0", features = ["proptests", "runtime"] }
Expand Down
17 changes: 16 additions & 1 deletion crates/libcontainer/src/container/builder_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
process::{
self,
args::{ContainerArgs, ContainerType},
intel_rdt::delete_resctrl_subdirectory,
},
rootless::Rootless,
syscall::Syscall,
Expand Down Expand Up @@ -137,7 +138,8 @@ impl<'a> ContainerBuilderImpl<'a> {
executor_manager: &self.executor_manager,
};

let init_pid = process::container_main_process::container_main_process(&container_args)?;
let (init_pid, need_to_clean_up_intel_rdt_dir) =
process::container_main_process::container_main_process(&container_args)?;

// if file to write the pid to is specified, write pid of the child
if let Some(pid_file) = &self.pid_file {
Expand All @@ -150,6 +152,7 @@ impl<'a> ContainerBuilderImpl<'a> {
.set_status(ContainerStatus::Created)
.set_creator(nix::unistd::geteuid().as_raw())
.set_pid(init_pid.as_raw())
.set_clean_up_intel_rdt_directory(need_to_clean_up_intel_rdt_dir)
.save()
.context("Failed to save container state")?;
}
Expand All @@ -171,11 +174,23 @@ impl<'a> ContainerBuilderImpl<'a> {
)?;

let mut errors = Vec::new();

if let Err(e) = cmanager.remove().context("failed to remove cgroup") {
errors.push(e.to_string());
}

if let Some(container) = &self.container {
if let Some(true) = container.clean_up_intel_rdt_subdirectory() {
if let Err(e) = delete_resctrl_subdirectory(container.id()).with_context(|| {
format!(
"failed to delete resctrl subdirectory: {:?}",
container.id()
)
}) {
errors.push(e.to_string());
}
}

if container.root.exists() {
if let Err(e) = fs::remove_dir_all(&container.root)
.with_context(|| format!("could not delete {:?}", container.root))
Expand Down
9 changes: 9 additions & 0 deletions crates/libcontainer/src/container/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@ impl Container {
self
}

pub fn set_clean_up_intel_rdt_directory(&mut self, clean_up: bool) -> &mut Self {
self.state.clean_up_intel_rdt_subdirectory = Some(clean_up);
self
}

pub fn clean_up_intel_rdt_subdirectory(&self) -> Option<bool> {
self.state.clean_up_intel_rdt_subdirectory
}

pub fn status(&self) -> ContainerStatus {
self.state.status
}
Expand Down
9 changes: 9 additions & 0 deletions crates/libcontainer/src/container/container_delete.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{Container, ContainerStatus};
use crate::config::YoukiConfig;
use crate::hooks;
use crate::process::intel_rdt::delete_resctrl_subdirectory;
use anyhow::{bail, Context, Result};
use libcgroups;
use nix::sys::signal;
Expand Down Expand Up @@ -66,6 +67,14 @@ impl Container {
// Once reached here, the container is verified that it can be deleted.
debug_assert!(self.status().can_delete());

if let Some(true) = &self.clean_up_intel_rdt_subdirectory() {
if let Err(err) = delete_resctrl_subdirectory(self.id()) {
log::warn!(
"failed to delete resctrl subdirectory due to: {err:?}, continue to delete"
);
}
}

if self.root.exists() {
match YoukiConfig::load(&self.root) {
Ok(config) => {
Expand Down
3 changes: 3 additions & 0 deletions crates/libcontainer/src/container/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ pub struct State {
pub creator: Option<u32>,
// Specifies if systemd should be used to manage cgroups
pub use_systemd: Option<bool>,
// Specifies if the Intel RDT subdirectory needs be cleaned up.
pub clean_up_intel_rdt_subdirectory: Option<bool>,
}

impl State {
Expand All @@ -119,6 +121,7 @@ impl State {
created: None,
creator: None,
use_systemd: None,
clean_up_intel_rdt_subdirectory: None,
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/libcontainer/src/process/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct ContainerArgs<'a> {
pub console_socket: Option<RawFd>,
/// The Unix Domain Socket to communicate container start
pub notify_socket: NotifyListener,
/// File descriptos preserved/passed to the container init process.
/// File descriptors preserved/passed to the container init process.
pub preserve_fds: i32,
/// Container state
pub container: &'a Option<Container>,
Expand Down
18 changes: 15 additions & 3 deletions crates/libcontainer/src/process/container_main_process.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
container::ContainerProcessState,
process::{args::ContainerArgs, channel, container_intermediate_process, fork},
process::{
args::ContainerArgs, channel, container_intermediate_process, fork,
intel_rdt::setup_intel_rdt,
},
rootless::Rootless,
utils,
};
Expand All @@ -20,7 +23,7 @@ use oci_spec::runtime;
#[cfg(feature = "libseccomp")]
use std::{io::IoSlice, path::Path};

pub fn container_main_process(container_args: &ContainerArgs) -> Result<Pid> {
pub fn container_main_process(container_args: &ContainerArgs) -> Result<(Pid, bool)> {
// We use a set of channels to communicate between parent and child process.
// Each channel is uni-directional. Because we will pass these channel to
// cloned process, we have to be deligent about closing any unused channel.
Expand Down Expand Up @@ -68,6 +71,7 @@ pub fn container_main_process(container_args: &ContainerArgs) -> Result<Pid> {
// The intermediate process will send the init pid once it forks the init
// process. The intermediate process should exit after this point.
let init_pid = main_receiver.wait_for_intermediate_ready()?;
let mut need_to_clean_up_intel_rdt_subdirectory = false;

if let Some(linux) = container_args.spec.linux() {
if let Some(seccomp) = linux.seccomp() {
Expand All @@ -89,6 +93,14 @@ pub fn container_main_process(container_args: &ContainerArgs) -> Result<Pid> {
sync_seccomp(seccomp, &state, init_sender, main_receiver)
.context("failed to sync seccomp with init")?;
}
if let Some(intel_rdt) = linux.intel_rdt() {
let container_id = container_args
.container
.as_ref()
.map(|container| container.id());
need_to_clean_up_intel_rdt_subdirectory =
setup_intel_rdt(container_id, &init_pid, intel_rdt)?;
}
}

// We don't need to send anything to the init process after this point, so
Expand Down Expand Up @@ -124,7 +136,7 @@ pub fn container_main_process(container_args: &ContainerArgs) -> Result<Pid> {
Err(err) => bail!("failed to wait for intermediate process: {err}"),
};

Ok(init_pid)
Ok((init_pid, need_to_clean_up_intel_rdt_subdirectory))
}

#[cfg(feature = "libseccomp")]
Expand Down
Loading

0 comments on commit 6d9bd12

Please sign in to comment.