agent: Drop the Option for LinuxContainer.cgroup_manager

Cgroup manager for a container will always be created.
Thus, dropping the option for LinuxContainer.cgroup_manager
is feasible and could simplify the code.

Fixes: #5778

Signed-off-by: Yuan-Zhuo <yuanzhuo0118@outlook.com>
This commit is contained in:
Yuan-Zhuo 2022-12-07 13:40:38 +08:00
parent 326d589ff5
commit 7fdbbcda82
4 changed files with 41 additions and 93 deletions

View File

@ -109,7 +109,6 @@ impl Default for ContainerStatus {
} }
// We might want to change this to thiserror in the future // We might want to change this to thiserror in the future
const MissingCGroupManager: &str = "failed to get container's cgroup Manager";
const MissingLinux: &str = "no linux config"; const MissingLinux: &str = "no linux config";
const InvalidNamespace: &str = "invalid namespace type"; const InvalidNamespace: &str = "invalid namespace type";
@ -243,7 +242,7 @@ pub struct LinuxContainer {
pub id: String, pub id: String,
pub root: String, pub root: String,
pub config: Config, pub config: Config,
pub cgroup_manager: Option<Box<dyn Manager + Send + Sync>>, pub cgroup_manager: Box<dyn Manager + Send + Sync>,
pub init_process_pid: pid_t, pub init_process_pid: pid_t,
pub init_process_start_time: u64, pub init_process_start_time: u64,
pub uid_map_path: String, pub uid_map_path: String,
@ -292,16 +291,11 @@ impl Container for LinuxContainer {
)); ));
} }
if self.cgroup_manager.is_some() { self.cgroup_manager.as_ref().freeze(FreezerState::Frozen)?;
self.cgroup_manager
.as_ref()
.unwrap()
.freeze(FreezerState::Frozen)?;
self.status.transition(ContainerState::Paused); self.status.transition(ContainerState::Paused);
return Ok(());
} Ok(())
Err(anyhow!(MissingCGroupManager))
} }
fn resume(&mut self) -> Result<()> { fn resume(&mut self) -> Result<()> {
@ -310,16 +304,11 @@ impl Container for LinuxContainer {
return Err(anyhow!("container status is: {:?}, not paused", status)); return Err(anyhow!("container status is: {:?}, not paused", status));
} }
if self.cgroup_manager.is_some() { self.cgroup_manager.as_ref().freeze(FreezerState::Thawed)?;
self.cgroup_manager
.as_ref()
.unwrap()
.freeze(FreezerState::Thawed)?;
self.status.transition(ContainerState::Running); self.status.transition(ContainerState::Running);
return Ok(());
} Ok(())
Err(anyhow!(MissingCGroupManager))
} }
} }
@ -847,22 +836,17 @@ impl BaseContainer for LinuxContainer {
} }
fn stats(&self) -> Result<StatsContainerResponse> { fn stats(&self) -> Result<StatsContainerResponse> {
let mut r = StatsContainerResponse::default();
if self.cgroup_manager.is_some() {
r.cgroup_stats =
SingularPtrField::some(self.cgroup_manager.as_ref().unwrap().get_stats()?);
}
// what about network interface stats? // what about network interface stats?
Ok(r) Ok(StatsContainerResponse {
cgroup_stats: SingularPtrField::some(self.cgroup_manager.as_ref().get_stats()?),
..Default::default()
})
} }
fn set(&mut self, r: LinuxResources) -> Result<()> { fn set(&mut self, r: LinuxResources) -> Result<()> {
if self.cgroup_manager.is_some() { self.cgroup_manager.as_ref().set(&r, true)?;
self.cgroup_manager.as_ref().unwrap().set(&r, true)?;
}
self.config self.config
.spec .spec
.as_mut() .as_mut()
@ -1035,7 +1019,7 @@ impl BaseContainer for LinuxContainer {
&logger, &logger,
spec, spec,
&p, &p,
self.cgroup_manager.as_ref().unwrap().as_ref(), self.cgroup_manager.as_ref(),
self.config.use_systemd_cgroup, self.config.use_systemd_cgroup,
&st, &st,
&mut pipe_w, &mut pipe_w,
@ -1114,7 +1098,7 @@ impl BaseContainer for LinuxContainer {
)?; )?;
fs::remove_dir_all(&self.root)?; fs::remove_dir_all(&self.root)?;
if let Some(cgm) = self.cgroup_manager.as_mut() { let cgm = self.cgroup_manager.as_mut();
// Kill all of the processes created in this container to prevent // Kill all of the processes created in this container to prevent
// the leak of some daemon process when this container shared pidns // the leak of some daemon process when this container shared pidns
// with the sandbox. // with the sandbox.
@ -1126,7 +1110,7 @@ impl BaseContainer for LinuxContainer {
} }
cgm.destroy().context("destroy cgroups")?; cgm.destroy().context("destroy cgroups")?;
}
Ok(()) Ok(())
} }
@ -1514,7 +1498,7 @@ impl LinuxContainer {
Ok(LinuxContainer { Ok(LinuxContainer {
id: id.clone(), id: id.clone(),
root, root,
cgroup_manager: Some(cgroup_manager), cgroup_manager,
status: ContainerStatus::new(), status: ContainerStatus::new(),
uid_map_path: String::from(""), uid_map_path: String::from(""),
gid_map_path: "".to_string(), gid_map_path: "".to_string(),
@ -1980,24 +1964,12 @@ mod tests {
assert!(format!("{:?}", ret).contains("failed to pause container")) assert!(format!("{:?}", ret).contains("failed to pause container"))
} }
#[test]
fn test_linuxcontainer_pause_cgroupmgr_is_none() {
let ret = new_linux_container_and_then(|mut c: LinuxContainer| {
c.cgroup_manager = None;
c.pause().map_err(|e| anyhow!(e))
});
assert!(ret.is_err(), "Expecting error, Got {:?}", ret);
}
#[test] #[test]
fn test_linuxcontainer_pause() { fn test_linuxcontainer_pause() {
let ret = new_linux_container_and_then(|mut c: LinuxContainer| { let ret = new_linux_container_and_then(|mut c: LinuxContainer| {
let cgroup_manager: Box<dyn Manager + Send + Sync> = c.cgroup_manager = Box::new(FsManager::new("").map_err(|e| {
Box::new(FsManager::new("").map_err(|e| {
anyhow!(format!("fail to create cgroup manager with path: {:}", e)) anyhow!(format!("fail to create cgroup manager with path: {:}", e))
})?); })?);
c.cgroup_manager = Some(cgroup_manager);
c.pause().map_err(|e| anyhow!(e)) c.pause().map_err(|e| anyhow!(e))
}); });
@ -2016,25 +1988,12 @@ mod tests {
assert!(format!("{:?}", ret).contains("not paused")) assert!(format!("{:?}", ret).contains("not paused"))
} }
#[test]
fn test_linuxcontainer_resume_cgroupmgr_is_none() {
let ret = new_linux_container_and_then(|mut c: LinuxContainer| {
c.status.transition(ContainerState::Paused);
c.cgroup_manager = None;
c.resume().map_err(|e| anyhow!(e))
});
assert!(ret.is_err(), "Expecting error, Got {:?}", ret);
}
#[test] #[test]
fn test_linuxcontainer_resume() { fn test_linuxcontainer_resume() {
let ret = new_linux_container_and_then(|mut c: LinuxContainer| { let ret = new_linux_container_and_then(|mut c: LinuxContainer| {
let cgroup_manager: Box<dyn Manager + Send + Sync> = c.cgroup_manager = Box::new(FsManager::new("").map_err(|e| {
Box::new(FsManager::new("").map_err(|e| {
anyhow!(format!("fail to create cgroup manager with path: {:}", e)) anyhow!(format!("fail to create cgroup manager with path: {:}", e))
})?); })?);
c.cgroup_manager = Some(cgroup_manager);
// Change status to paused, this way we can resume it // Change status to paused, this way we can resume it
c.status.transition(ContainerState::Paused); c.status.transition(ContainerState::Paused);
c.resume().map_err(|e| anyhow!(e)) c.resume().map_err(|e| anyhow!(e))

View File

@ -271,15 +271,14 @@ impl AgentService {
} }
// start oom event loop // start oom event loop
if let Some(ref ctr) = ctr.cgroup_manager {
let cg_path = ctr.get_cgroup_path("memory"); let cg_path = ctr.cgroup_manager.as_ref().get_cgroup_path("memory");
if let Ok(cg_path) = cg_path { if let Ok(cg_path) = cg_path {
let rx = notifier::notify_oom(cid.as_str(), cg_path.to_string()).await?; let rx = notifier::notify_oom(cid.as_str(), cg_path.to_string()).await?;
s.run_oom_event_monitor(rx, cid.clone()).await; s.run_oom_event_monitor(rx, cid.clone()).await;
} }
}
Ok(()) Ok(())
} }
@ -465,11 +464,7 @@ impl AgentService {
let ctr = sandbox let ctr = sandbox
.get_container(cid) .get_container(cid)
.ok_or_else(|| anyhow!("Invalid container id {}", cid))?; .ok_or_else(|| anyhow!("Invalid container id {}", cid))?;
let cm = ctr ctr.cgroup_manager.as_ref().freeze(state)?;
.cgroup_manager
.as_ref()
.ok_or_else(|| anyhow!("cgroup manager not exist"))?;
cm.freeze(state)?;
Ok(()) Ok(())
} }
@ -479,11 +474,7 @@ impl AgentService {
let ctr = sandbox let ctr = sandbox
.get_container(cid) .get_container(cid)
.ok_or_else(|| anyhow!("Invalid container id {}", cid))?; .ok_or_else(|| anyhow!("Invalid container id {}", cid))?;
let cm = ctr let pids = ctr.cgroup_manager.as_ref().get_pids()?;
.cgroup_manager
.as_ref()
.ok_or_else(|| anyhow!("cgroup manager not exist"))?;
let pids = cm.get_pids()?;
Ok(pids) Ok(pids)
} }

View File

@ -296,7 +296,6 @@ impl Sandbox {
info!(self.logger, "updating {}", ctr.id.as_str()); info!(self.logger, "updating {}", ctr.id.as_str());
ctr.cgroup_manager ctr.cgroup_manager
.as_ref() .as_ref()
.unwrap()
.update_cpuset_path(guest_cpuset.as_str(), container_cpust)?; .update_cpuset_path(guest_cpuset.as_str(), container_cpust)?;
} }

View File

@ -337,7 +337,6 @@ impl ContainerLauncher {
self.runner self.runner
.cgroup_manager .cgroup_manager
.as_ref() .as_ref()
.unwrap()
.as_any()? .as_any()?
.downcast_ref::<CgroupManager>() .downcast_ref::<CgroupManager>()
.unwrap() .unwrap()