runtime-rs: force shutdown shim process in it can't exit

In some case the call of cleanup from shim to service manager will fail,
and the shim process will continue to running, that will make process leak.

This commit will force shutdown the shim process in case of any errors in
service crate.

Fixes: #5087

Signed-off-by: Bin Liu <bin@hyper.sh>
This commit is contained in:
Bin Liu 2022-09-02 17:36:28 +08:00
parent b5786361e9
commit 86ad832e37
3 changed files with 31 additions and 6 deletions

View File

@ -67,7 +67,10 @@ impl ShareVirtioFsStandalone {
fn virtiofsd_args(&self, sock_path: &str) -> Result<Vec<String>> {
let source_path = get_host_ro_shared_path(&self.config.id);
if !source_path.exists() {
return Err(anyhow!("The virtiofs shared path didn't exist"));
return Err(anyhow!(
"The virtiofs shared path({:?}) didn't exist",
source_path
));
}
let mut args: Vec<String> = vec![

View File

@ -155,7 +155,7 @@ impl ServiceManager {
let handler = RuntimeHandlerManager::new(sid, sender)
.await
.context("new runtime handler")?;
handler.cleanup().await?;
handler.cleanup().await.context("runtime handler cleanup")?;
let temp_dir = [KATA_PATH, sid].join("/");
if std::fs::metadata(temp_dir.as_str()).is_ok() {
// try to remove dir and skip the result

View File

@ -6,6 +6,9 @@
use anyhow::{Context, Result};
use containerd_shim_protos::api;
use kata_sys_util::spec::{get_bundle_path, get_contaier_type, load_oci_spec};
use kata_types::container::ContainerType;
use nix::{sys::signal::kill, sys::signal::SIGKILL, unistd::Pid};
use protobuf::Message;
use std::{fs, path::Path};
@ -14,7 +17,7 @@ use crate::{shim::ShimExecutor, Error};
impl ShimExecutor {
pub async fn delete(&mut self) -> Result<()> {
self.args.validate(true).context("validate")?;
let rsp = self.do_cleanup().await.context("do cleanup")?;
let rsp = self.do_cleanup().await.context("shim do cleanup")?;
rsp.write_to_writer(&mut std::io::stdout())
.context(Error::FileWrite(format!("write {:?} to stdout", rsp)))?;
Ok(())
@ -41,9 +44,28 @@ impl ShimExecutor {
info!(sl!(), "remote socket path: {:?}", &file_path);
fs::remove_file(file_path).ok();
}
service::ServiceManager::cleanup(&self.args.id)
.await
.context("cleanup")?;
if let Err(e) = service::ServiceManager::cleanup(&self.args.id).await {
error!(
sl!(),
"failed to cleanup in service manager: {:?}. force shutdown shim process", e
);
let bundle_path = get_bundle_path().context("get bundle path")?;
if let Ok(spec) = load_oci_spec() {
if let Ok(ContainerType::PodSandbox) = get_contaier_type(&spec) {
// only force shutdown for sandbox container
if let Ok(shim_pid) = self.read_pid_file(&bundle_path) {
info!(sl!(), "force to shutdown shim process {}", shim_pid);
let pid = Pid::from_raw(shim_pid as i32);
if let Err(_e) = kill(pid, SIGKILL) {
// ignore kill errors
}
}
}
}
}
Ok(rsp)
}
}