From a86bf52390e80c14a2a5f7e8158c79170fa23c62 Mon Sep 17 00:00:00 2001 From: Stefan Reiter Date: Wed, 7 Oct 2020 13:53:07 +0200 Subject: [PATCH] fuse_loop: wait for instance to close after killing On unmap, only report success if the instance we are killing actually terminates. This is especially important so that cleanup routines can be assured that /run files are actually cleaned up after calling cleanup_unused_run_files. Signed-off-by: Stefan Reiter --- src/tools/fuse_loop.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/tools/fuse_loop.rs b/src/tools/fuse_loop.rs index da186b4c..05d92525 100644 --- a/src/tools/fuse_loop.rs +++ b/src/tools/fuse_loop.rs @@ -16,6 +16,7 @@ use futures::stream::{StreamExt, TryStreamExt}; use futures::channel::mpsc::{Sender, Receiver}; use proxmox::const_regex; +use proxmox::tools::time; use proxmox_fuse::{*, requests::FuseRequest}; use super::loopdev; use super::fs; @@ -288,8 +289,28 @@ fn unmap_from_backing(backing_file: &Path) -> Result<(), Error> { let pid = pid_str.parse::().map_err(|err| format_err!("malformed PID ({}) in pidfile - {}", pid_str, err))?; + let pid = Pid::from_raw(pid); + // send SIGINT to trigger cleanup and exit in target process - signal::kill(Pid::from_raw(pid), Signal::SIGINT)?; + signal::kill(pid, Signal::SIGINT)?; + + // block until unmap is complete or timeout + let start = time::epoch_i64(); + loop { + match signal::kill(pid, None) { + Ok(_) => { + // 10 second timeout, then assume failure + if (time::epoch_i64() - start) > 10 { + return Err(format_err!("timed out waiting for PID '{}' to exit", &pid)); + } + std::thread::sleep(std::time::Duration::from_millis(100)); + }, + Err(nix::Error::Sys(nix::errno::Errno::ESRCH)) => { + break; + }, + Err(e) => return Err(e.into()), + } + } Ok(()) }