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 17, 2023
1 parent 1faa881 commit d20660c
Show file tree
Hide file tree
Showing 8 changed files with 411 additions and 5 deletions.
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 @@ -21,7 +24,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 @@ -69,6 +72,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: bool = false;

if let Some(linux) = container_args.spec.linux() {
if let Some(seccomp) = linux.seccomp() {
Expand All @@ -90,6 +94,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 @@ -128,7 +140,7 @@ pub fn container_main_process(container_args: &ContainerArgs) -> Result<Pid> {
}
};

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

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

0 comments on commit d20660c

Please sign in to comment.