container: add pause/resume container functions

add pause/resume container functions.

Fixes:#302

Signed-off-by: fupan.lfp <fupan.lfp@antfin.com>
This commit is contained in:
fupan.lfp 2020-06-09 17:58:32 +08:00
parent fe4166342a
commit e6c0a0bfca
2 changed files with 102 additions and 3 deletions

View File

@ -281,12 +281,58 @@ pub struct SyncPC {
pub trait Container: BaseContainer {
// fn checkpoint(&self, opts: &CriuOpts) -> Result<()>;
// fn restore(&self, p: &Process, opts: &CriuOpts) -> Result<()>;
fn pause(&self) -> Result<()>;
fn resume(&self) -> Result<()>;
fn pause(&mut self) -> Result<()>;
fn resume(&mut self) -> Result<()>;
// fn notify_oom(&self) -> Result<(Sender, Receiver)>;
// fn notify_memory_pressure(&self, lvl: PressureLevel) -> Result<(Sender, Receiver)>;
}
impl Container for LinuxContainer {
fn pause(&mut self) -> Result<()> {
let status = self.status();
if status != Status::RUNNING && status != Status::CREATED {
return Err(ErrorKind::ErrorCode(format!(
"failed to pause container: current status is: {:?}",
status
))
.into());
}
if self.cgroup_manager.is_some() {
self.cgroup_manager
.as_ref()
.unwrap()
.freeze(fscgroup::FROZEN)?;
self.status.transition(Status::PAUSED);
return Ok(());
}
Err(ErrorKind::ErrorCode(String::from("failed to get container's cgroup manager")).into())
}
fn resume(&mut self) -> Result<()> {
let status = self.status();
if status != Status::PAUSED {
return Err(ErrorKind::ErrorCode(format!(
"container status is: {:?}, not paused",
status
))
.into());
}
if self.cgroup_manager.is_some() {
self.cgroup_manager
.as_ref()
.unwrap()
.freeze(fscgroup::THAWED)?;
self.status.transition(Status::RUNNING);
return Ok(());
}
Err(ErrorKind::ErrorCode(String::from("failed to get container's cgroup manager")).into())
}
}
pub fn init_child() {
let cwfd = std::env::var(CWFD_FD).unwrap().parse::<i32>().unwrap();
let cfd_log = std::env::var(CLOG_FD).unwrap().parse::<i32>().unwrap();

View File

@ -18,7 +18,7 @@ use protocols::health::{
};
use protocols::types::Interface;
use rustjail;
use rustjail::container::{BaseContainer, LinuxContainer};
use rustjail::container::{BaseContainer, Container, LinuxContainer};
use rustjail::errors::*;
use rustjail::process::Process;
use rustjail::specconv::CreateOpts;
@ -754,6 +754,59 @@ impl protocols::agent_ttrpc::AgentService for agentService {
Ok(resp) => Ok(resp),
}
}
fn pause_container(
&self,
ctx: &ttrpc::TtrpcContext,
req: protocols::agent::PauseContainerRequest,
) -> ttrpc::Result<protocols::empty::Empty> {
let cid = req.get_container_id();
let s = Arc::clone(&self.sandbox);
let mut sandbox = s.lock().unwrap();
if let Some(ctr) = sandbox.get_container(cid) {
match ctr.pause() {
Err(e) => {
return Err(ttrpc::Error::RpcStatus(ttrpc::get_status(
ttrpc::Code::INTERNAL,
e.to_string(),
)))
}
Ok(_) => return Ok(Empty::new()),
}
};
Err(ttrpc::Error::RpcStatus(ttrpc::get_status(
ttrpc::Code::INVALID_ARGUMENT,
"invalid argument".to_string(),
)))
}
fn resume_container(
&self,
ctx: &ttrpc::TtrpcContext,
req: protocols::agent::ResumeContainerRequest,
) -> ttrpc::Result<protocols::empty::Empty> {
let cid = req.get_container_id();
let s = Arc::clone(&self.sandbox);
let mut sandbox = s.lock().unwrap();
if let Some(ctr) = sandbox.get_container(cid) {
match ctr.resume() {
Err(e) => {
return Err(ttrpc::Error::RpcStatus(ttrpc::get_status(
ttrpc::Code::INTERNAL,
e.to_string(),
)))
}
Ok(_) => return Ok(Empty::new()),
}
};
Err(ttrpc::Error::RpcStatus(ttrpc::get_status(
ttrpc::Code::INVALID_ARGUMENT,
"invalid argument: ".to_string(),
)))
}
fn write_stdin(
&self,
_ctx: &ttrpc::TtrpcContext,