@@ -181,14 +181,6 @@ pub fn partitions_of(dev: &Utf8Path) -> Result<PartitionTable> {
181181
182182pub struct LoopbackDevice {
183183 pub dev : Option < Utf8PathBuf > ,
184- // Handle to the cleanup helper process
185- cleanup_handle : Option < LoopbackCleanupHandle > ,
186- }
187-
188- /// Handle to manage the cleanup helper process for loopback devices
189- struct LoopbackCleanupHandle {
190- /// Child process handle
191- child : std:: process:: Child ,
192184}
193185
194186impl LoopbackDevice {
@@ -216,15 +208,7 @@ impl LoopbackDevice {
216208 . run_get_string ( ) ?;
217209 let dev = Utf8PathBuf :: from ( dev. trim ( ) ) ;
218210 tracing:: debug!( "Allocated loopback {dev}" ) ;
219-
220- // Try to spawn cleanup helper process - if it fails, make it fatal
221- let cleanup_handle = Self :: spawn_cleanup_helper ( dev. as_str ( ) )
222- . context ( "Failed to spawn loopback cleanup helper" ) ?;
223-
224- Ok ( Self {
225- dev : Some ( dev) ,
226- cleanup_handle : Some ( cleanup_handle) ,
227- } )
211+ Ok ( Self { dev : Some ( dev) } )
228212 }
229213
230214 // Access the path to the loopback block device.
@@ -233,49 +217,13 @@ impl LoopbackDevice {
233217 self . dev . as_deref ( ) . unwrap ( )
234218 }
235219
236- /// Spawn a cleanup helper process that will clean up the loopback device
237- /// if the parent process dies unexpectedly
238- fn spawn_cleanup_helper ( device_path : & str ) -> Result < LoopbackCleanupHandle > {
239- use std:: process:: { Command , Stdio } ;
240-
241- // Get the path to our own executable
242- let self_exe =
243- std:: fs:: read_link ( "/proc/self/exe" ) . context ( "Failed to read /proc/self/exe" ) ?;
244-
245- // Create the helper process
246- let mut cmd = Command :: new ( self_exe) ;
247- cmd. args ( [ "loopback-cleanup-helper" , "--device" , device_path] ) ;
248-
249- // Set environment variable to indicate this is a cleanup helper
250- cmd. env ( "BOOTC_LOOPBACK_CLEANUP_HELPER" , "1" ) ;
251-
252- // Set up stdio to redirect to /dev/null
253- cmd. stdin ( Stdio :: null ( ) ) ;
254- cmd. stdout ( Stdio :: null ( ) ) ;
255- cmd. stderr ( Stdio :: null ( ) ) ;
256-
257- // Spawn the process
258- let child = cmd
259- . spawn ( )
260- . context ( "Failed to spawn loopback cleanup helper" ) ?;
261-
262- Ok ( LoopbackCleanupHandle { child } )
263- }
264-
265220 // Shared backend for our `close` and `drop` implementations.
266221 fn impl_close ( & mut self ) -> Result < ( ) > {
267222 // SAFETY: This is the only place we take the option
268223 let Some ( dev) = self . dev . take ( ) else {
269224 tracing:: trace!( "loopback device already deallocated" ) ;
270225 return Ok ( ( ) ) ;
271226 } ;
272-
273- // Kill the cleanup helper since we're cleaning up normally
274- if let Some ( mut cleanup_handle) = self . cleanup_handle . take ( ) {
275- // Send SIGTERM to the child process
276- let _ = cleanup_handle. child . kill ( ) ;
277- }
278-
279227 Command :: new ( "losetup" ) . args ( [ "-d" , dev. as_str ( ) ] ) . run ( )
280228 }
281229
@@ -292,46 +240,6 @@ impl Drop for LoopbackDevice {
292240 }
293241}
294242
295- /// Main function for the loopback cleanup helper process
296- /// This function does not return - it either exits normally or via signal
297- pub async fn run_loopback_cleanup_helper ( device_path : & str ) -> Result < ( ) > {
298- // Check if we're running as a cleanup helper
299- if std:: env:: var ( "BOOTC_LOOPBACK_CLEANUP_HELPER" ) . is_err ( ) {
300- anyhow:: bail!( "This function should only be called as a cleanup helper" ) ;
301- }
302-
303- // Set up death signal notification - we want to be notified when parent dies
304- rustix:: process:: set_parent_process_death_signal ( Some ( rustix:: process:: Signal :: TERM ) )
305- . context ( "Failed to set parent death signal" ) ?;
306-
307- // Wait for SIGTERM (either from parent death or normal cleanup)
308- tokio:: signal:: unix:: signal ( tokio:: signal:: unix:: SignalKind :: terminate ( ) )
309- . expect ( "Failed to create signal stream" )
310- . recv ( )
311- . await ;
312-
313- // Clean up the loopback device
314- let status = std:: process:: Command :: new ( "losetup" )
315- . args ( [ "-d" , device_path] )
316- . status ( ) ;
317-
318- match status {
319- Ok ( exit_status) if exit_status. success ( ) => {
320- // Log to systemd journal instead of stderr
321- tracing:: info!( "Cleaned up leaked loopback device {}" , device_path) ;
322- std:: process:: exit ( 0 ) ;
323- }
324- Ok ( _) => {
325- tracing:: error!( "Failed to clean up loopback device {}" , device_path) ;
326- std:: process:: exit ( 1 ) ;
327- }
328- Err ( e) => {
329- tracing:: error!( "Error cleaning up loopback device {}: {}" , device_path, e) ;
330- std:: process:: exit ( 1 ) ;
331- }
332- }
333- }
334-
335243/// Parse key-value pairs from lsblk --pairs.
336244/// Newer versions of lsblk support JSON but the one in CentOS 7 doesn't.
337245fn split_lsblk_line ( line : & str ) -> HashMap < String , String > {
0 commit comments