diff --git a/pageserver/src/walredo.rs b/pageserver/src/walredo.rs index 8bac8ed42d..bc250166ce 100644 --- a/pageserver/src/walredo.rs +++ b/pageserver/src/walredo.rs @@ -685,7 +685,7 @@ impl PostgresRedoManager { // as close-on-exec by default, but that's not enough, since we use // libraries that directly call libc open without setting that flag. .close_fds() - .spawn_no_leak_child() + .spawn_no_leak_child(self.tenant_id) .map_err(|e| { Error::new( e.kind(), @@ -989,6 +989,7 @@ impl PostgresRedoManager { /// Wrapper type around `std::process::Child` which guarantees that the child /// will be killed and waited-for by this process before being dropped. struct NoLeakChild { + tenant_id: TenantId, child: Option, } @@ -1007,9 +1008,12 @@ impl DerefMut for NoLeakChild { } impl NoLeakChild { - fn spawn(command: &mut Command) -> io::Result { + fn spawn(tenant_id: TenantId, command: &mut Command) -> io::Result { let child = command.spawn()?; - Ok(NoLeakChild { child: Some(child) }) + Ok(NoLeakChild { + tenant_id, + child: Some(child), + }) } fn kill_and_wait(mut self) { @@ -1056,11 +1060,16 @@ impl Drop for NoLeakChild { Some(child) => child, None => return, }; + let tenant_id = self.tenant_id; // Offload the kill+wait of the child process into the background. // If someone stops the runtime, we'll leak the child process. // We can ignore that case because we only stop the runtime on pageserver exit. BACKGROUND_RUNTIME.spawn(async move { tokio::task::spawn_blocking(move || { + // Intentionally don't inherit the tracing context from whoever is dropping us. + // This thread here is going to outlive of our dropper. + let span = tracing::info_span!("walredo", %tenant_id); + let _entered = span.enter(); Self::kill_and_wait_impl(child); }) .await @@ -1069,12 +1078,12 @@ impl Drop for NoLeakChild { } trait NoLeakChildCommandExt { - fn spawn_no_leak_child(&mut self) -> io::Result; + fn spawn_no_leak_child(&mut self, tenant_id: TenantId) -> io::Result; } impl NoLeakChildCommandExt for Command { - fn spawn_no_leak_child(&mut self) -> io::Result { - NoLeakChild::spawn(self) + fn spawn_no_leak_child(&mut self, tenant_id: TenantId) -> io::Result { + NoLeakChild::spawn(tenant_id, self) } }