Skip to content

Commit

Permalink
add schedule entity
Browse files Browse the repository at this point in the history
Signed-off-by: lengrongfu <1275177125@qq.com>
  • Loading branch information
lengrongfu committed Nov 1, 2023
1 parent a6735b1 commit 8c78feb
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 2 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/libcontainer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ regex = "1.10.2"
thiserror = "1.0.50"
tracing = { version = "0.1.40", features = ["attributes"] }
safe-path = "0.1.0"
nc = "0.8.18"

[dev-dependencies]
oci-spec = { version = "~0.6.4", features = ["proptests", "runtime"] }
Expand Down
50 changes: 49 additions & 1 deletion crates/libcontainer/src/container/tenant_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use nix::unistd::{self, close, pipe2, read, Pid};
use oci_spec::runtime::{
Capabilities as SpecCapabilities, Capability as SpecCapability, LinuxBuilder,
LinuxCapabilities, LinuxCapabilitiesBuilder, LinuxNamespace, LinuxNamespaceBuilder,
LinuxNamespaceType, Process, ProcessBuilder, Spec,
LinuxNamespaceType, LinuxSchedulerPolicy, Process, ProcessBuilder, Spec,
};
use procfs::process::Namespace;

Expand Down Expand Up @@ -222,6 +222,54 @@ impl TenantContainerBuilder {
}
}
}

if let Some(sc) = process.scheduler() {
let policy = sc.policy();
if let Some(nice) = sc.nice() {
if *nice < -20 && *nice > 19 {
tracing::error!(?nice, "invalid scheduler.nice: '{}'", nice);
Err(ErrInvalidSpec::Scheduler)?;
}
}
if let Some(priority) = sc.priority() {
if *priority != 0
&& (*policy != LinuxSchedulerPolicy::SchedFifo
&& *policy != LinuxSchedulerPolicy::SchedRr)
{
tracing::error!(?policy,"scheduler.priority can only be specified for SchedFIFO or SchedRR policy");
Err(ErrInvalidSpec::Scheduler)?;
}
}
if *policy != LinuxSchedulerPolicy::SchedDeadline {
if let Some(runtime) = sc.runtime() {
if *runtime != 0 {
tracing::error!(
?runtime,
"scheduler runtime can only be specified for SchedDeadline policy"
);
Err(ErrInvalidSpec::Scheduler)?;
}
}
if let Some(deadline) = sc.deadline() {
if *deadline != 0 {
tracing::error!(
?deadline,
"scheduler deadline can only be specified for SchedDeadline policy"
);
Err(ErrInvalidSpec::Scheduler)?;
}
}
if let Some(period) = sc.period() {
if *period != 0 {
tracing::error!(
?period,
"scheduler period can only be specified for SchedDeadline policy"
);
Err(ErrInvalidSpec::Scheduler)?;
}
}
}
}
}

utils::validate_spec_for_new_user_ns(spec)?;
Expand Down
2 changes: 2 additions & 0 deletions crates/libcontainer/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,6 @@ pub enum ErrInvalidSpec {
AppArmorNotEnabled,
#[error("invalid io priority or class.")]
IoPriority,
#[error("invalid scheduler config for process")]
Scheduler,
}
61 changes: 60 additions & 1 deletion crates/libcontainer/src/process/container_init_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ use crate::{
capabilities, hooks, namespaces::Namespaces, process::channel, rootfs::RootFS, tty,
user_ns::UserNamespaceConfig, utils,
};
use nc;
use nix::mount::MsFlags;
use nix::sched::CloneFlags;
use nix::sys::stat::Mode;
use nix::unistd::setsid;
use nix::unistd::{self, Gid, Uid};
use oci_spec::runtime::{IOPriorityClass, LinuxIOPriority, LinuxNamespaceType, Spec, User};
use oci_spec::runtime::{
IOPriorityClass, LinuxIOPriority, LinuxNamespaceType, LinuxSchedulerFlag, LinuxSchedulerPolicy,
Scheduler, Spec, User,
};
use std::collections::HashMap;
use std::mem;
use std::os::unix::io::AsRawFd;
use std::{
env, fs,
Expand Down Expand Up @@ -74,6 +79,8 @@ pub enum InitProcessError {
WorkloadValidation(#[from] workload::ExecutorValidationError),
#[error("invalid io priority class: {0}")]
IoPriorityClass(String),
#[error("call exec sched_setattr error: {0}")]
SchedSetattr(String),
}

type Result<T> = std::result::Result<T, InitProcessError>;
Expand Down Expand Up @@ -288,6 +295,8 @@ pub fn container_init_process(

set_io_priority(syscall.as_ref(), proc.io_priority())?;

setup_scheduler(proc.scheduler())?;

// set up tty if specified
if let Some(csocketfd) = args.console_socket {
tty::setup_console(&csocketfd).map_err(|err| {
Expand Down Expand Up @@ -741,6 +750,56 @@ fn set_io_priority(syscall: &dyn Syscall, io_priority_op: &Option<LinuxIOPriorit
Ok(())
}

/// Set the RT priority of a thread
fn setup_scheduler(sc_op: &Option<Scheduler>) -> Result<()> {
if let Some(sc) = sc_op {
let policy: u32 = match sc.policy() {
LinuxSchedulerPolicy::SchedOther => 0,
LinuxSchedulerPolicy::SchedFifo => 1,
LinuxSchedulerPolicy::SchedRr => 2,
LinuxSchedulerPolicy::SchedBatch => 3,
LinuxSchedulerPolicy::SchedIso => 4,
LinuxSchedulerPolicy::SchedIdle => 5,
LinuxSchedulerPolicy::SchedDeadline => 6,
};
let mut flags: u64 = 0;
for flag in sc.flags().as_ref().unwrap() {
match flag {
LinuxSchedulerFlag::SchedResetOnFork => flags |= 0x01,
LinuxSchedulerFlag::SchedFlagReclaim => flags |= 0x02,
LinuxSchedulerFlag::SchedFlagDLOverrun => flags |= 0x04,
LinuxSchedulerFlag::SchedFlagKeepPolicy => flags |= 0x08,
LinuxSchedulerFlag::SchedFlagKeepParams => flags |= 0x10,
LinuxSchedulerFlag::SchedFlagUtilClampMin => flags |= 0x20,
LinuxSchedulerFlag::SchedFlagUtilClampMax => flags |= 0x40,
}
}
let mut a = nc::sched_attr_t {
size: mem::size_of::<nc::sched_attr_t>().try_into().unwrap(),
sched_policy: policy,
sched_flags: flags,
sched_nice: sc.nice().unwrap(),
sched_priority: sc.priority().unwrap() as u32,
sched_runtime: sc.runtime().unwrap(),
sched_deadline: sc.deadline().unwrap(),
sched_period: sc.period().unwrap(),
sched_util_min: 0,
sched_util_max: 0,
};
unsafe {
let result = nc::sched_setattr(0, &mut a, 0);
match result {
Ok(_) => {}
Err(err) => {
tracing::error!(?err, "error setting scheduler");
Err(InitProcessError::SchedSetattr(err.to_string()))?;
}
}
};
}
Ok(())
}

#[cfg(feature = "libseccomp")]
fn sync_seccomp(
fd: Option<i32>,
Expand Down

0 comments on commit 8c78feb

Please sign in to comment.