diff --git a/src/main.rs b/src/main.rs index f54faf9..f8bec88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use std::{ io::{Cursor, Write}, path::PathBuf, + process::Command, sync::Arc, }; @@ -44,6 +45,9 @@ fn main() { .get_one::("mountpoint") .map(ToOwned::to_owned) .unwrap_or(PathBuf::from("mnt")); + + // Clean up any stale mount before proceeding + cleanup_stale_mount(&mountpoint); let _ = std::fs::create_dir_all(&mountpoint); let resolver = Arc::new(resolver::id_resolver()); @@ -186,3 +190,63 @@ async fn build_repo(bytes: Vec) -> Result let repo = Repository::open(store, root).await?; Ok(repo) } + +/// Clean up any stale FUSE mount at the given path. +/// This handles the case where a previous run crashed or was killed without unmounting. +fn cleanup_stale_mount(mountpoint: &PathBuf) { + // Check if the path exists and might be a stale mount + if !mountpoint.exists() { + return; + } + + // Try to detect if it's a stale mount by attempting to read the directory + // A stale FUSE mount will typically fail with "Device not configured" or similar + if std::fs::read_dir(mountpoint).is_ok() { + // Directory is readable, not a stale mount + return; + } + + eprintln!("Detected stale mount at {:?}, attempting cleanup...", mountpoint); + + // Try platform-specific unmount commands + #[cfg(target_os = "macos")] + { + // Try diskutil first (more reliable on macOS) + let _ = Command::new("diskutil") + .args(["unmount", "force"]) + .arg(mountpoint) + .output(); + + // Fall back to umount if diskutil didn't work + if std::fs::read_dir(mountpoint).is_err() { + let _ = Command::new("umount") + .arg("-f") + .arg(mountpoint) + .output(); + } + } + + #[cfg(target_os = "linux")] + { + // Try fusermount first + let _ = Command::new("fusermount") + .args(["-uz"]) + .arg(mountpoint) + .output(); + + // Fall back to umount + if std::fs::read_dir(mountpoint).is_err() { + let _ = Command::new("umount") + .arg("-l") + .arg(mountpoint) + .output(); + } + } + + // If still broken, try removing and recreating the directory + if std::fs::read_dir(mountpoint).is_err() { + let _ = std::fs::remove_dir(mountpoint); + } + + eprintln!("Cleanup complete"); +}