mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-28 19:54:35 +00:00
agent: do some rollback works if case of do_create_container failed
In some cases do_create_container may return an error, mostly due to `container.start(process)` call. This commit will do some rollback works if this function failed. Fixes: #4749 Signed-off-by: Bin Liu <bin@hyper.sh>
This commit is contained in:
parent
a238d8c6bd
commit
09672eb2da
@ -249,7 +249,20 @@ impl AgentService {
|
||||
info!(sl!(), "no process configurations!");
|
||||
return Err(anyhow!(nix::Error::EINVAL));
|
||||
};
|
||||
ctr.start(p).await?;
|
||||
|
||||
// if starting container failed, we will do some rollback work
|
||||
// to ensure no resources are leaked.
|
||||
if let Err(err) = ctr.start(p).await {
|
||||
error!(sl!(), "failed to start container: {:?}", err);
|
||||
if let Err(e) = ctr.destroy().await {
|
||||
error!(sl!(), "failed to destroy container: {:?}", e);
|
||||
}
|
||||
if let Err(e) = remove_container_resources(&mut s, &cid) {
|
||||
error!(sl!(), "failed to remove container resources: {:?}", e);
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
s.update_shared_pidns(&ctr)?;
|
||||
s.add_container(ctr);
|
||||
info!(sl!(), "created container!");
|
||||
@ -295,27 +308,6 @@ impl AgentService {
|
||||
req: protocols::agent::RemoveContainerRequest,
|
||||
) -> Result<()> {
|
||||
let cid = req.container_id.clone();
|
||||
let mut cmounts: Vec<String> = vec![];
|
||||
|
||||
let mut remove_container_resources = |sandbox: &mut Sandbox| -> Result<()> {
|
||||
// Find the sandbox storage used by this container
|
||||
let mounts = sandbox.container_mounts.get(&cid);
|
||||
if let Some(mounts) = mounts {
|
||||
for m in mounts.iter() {
|
||||
if sandbox.storages.get(m).is_some() {
|
||||
cmounts.push(m.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for m in cmounts.iter() {
|
||||
sandbox.unset_and_remove_sandbox_storage(m)?;
|
||||
}
|
||||
|
||||
sandbox.container_mounts.remove(cid.as_str());
|
||||
sandbox.containers.remove(cid.as_str());
|
||||
Ok(())
|
||||
};
|
||||
|
||||
if req.timeout == 0 {
|
||||
let s = Arc::clone(&self.sandbox);
|
||||
@ -329,7 +321,7 @@ impl AgentService {
|
||||
.destroy()
|
||||
.await?;
|
||||
|
||||
remove_container_resources(&mut sandbox)?;
|
||||
remove_container_resources(&mut sandbox, &cid)?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
@ -361,8 +353,7 @@ impl AgentService {
|
||||
|
||||
let s = self.sandbox.clone();
|
||||
let mut sandbox = s.lock().await;
|
||||
|
||||
remove_container_resources(&mut sandbox)?;
|
||||
remove_container_resources(&mut sandbox, &cid)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1752,6 +1743,35 @@ fn update_container_namespaces(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn remove_container_resources(sandbox: &mut Sandbox, cid: &str) -> Result<()> {
|
||||
let mut cmounts: Vec<String> = vec![];
|
||||
|
||||
// Find the sandbox storage used by this container
|
||||
let mounts = sandbox.container_mounts.get(cid);
|
||||
if let Some(mounts) = mounts {
|
||||
for m in mounts.iter() {
|
||||
if sandbox.storages.get(m).is_some() {
|
||||
cmounts.push(m.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for m in cmounts.iter() {
|
||||
if let Err(err) = sandbox.unset_and_remove_sandbox_storage(m) {
|
||||
error!(
|
||||
sl!(),
|
||||
"failed to unset_and_remove_sandbox_storage for container {}, error: {:?}",
|
||||
cid,
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sandbox.container_mounts.remove(cid);
|
||||
sandbox.containers.remove(cid);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn append_guest_hooks(s: &Sandbox, oci: &mut Spec) -> Result<()> {
|
||||
if let Some(ref guest_hooks) = s.hooks {
|
||||
let mut hooks = oci.hooks.take().unwrap_or_default();
|
||||
|
Loading…
Reference in New Issue
Block a user