mount an atproto PDS repository as a FUSE filesystem

Clean up stale mounts automatically #13

merged opened by danabra.mov targeting main

I often can't get it running because a failure screws up the mount. This is what Claude wrote that seems to fix it.

Labels

None yet.

Participants 2
AT URI
at://did:plc:fpruhuo22xkm5o7ttr2ktxdo/sh.tangled.repo.pull/3mckedrho6m22
+64
Diff #0
+64
src/main.rs
··· 15 15 use std::{ 16 16 io::{Cursor, Write}, 17 17 path::PathBuf, 18 + process::Command, 18 19 sync::Arc, 19 20 }; 20 21 ··· 44 45 .get_one::<PathBuf>("mountpoint") 45 46 .map(ToOwned::to_owned) 46 47 .unwrap_or(PathBuf::from("mnt")); 48 + 49 + // Clean up any stale mount before proceeding 50 + cleanup_stale_mount(&mountpoint); 47 51 let _ = std::fs::create_dir_all(&mountpoint); 48 52 49 53 let resolver = Arc::new(resolver::id_resolver()); ··· 186 190 let repo = Repository::open(store, root).await?; 187 191 Ok(repo) 188 192 } 193 + 194 + /// Clean up any stale FUSE mount at the given path. 195 + /// This handles the case where a previous run crashed or was killed without unmounting. 196 + fn cleanup_stale_mount(mountpoint: &PathBuf) { 197 + // Check if the path exists and might be a stale mount 198 + if !mountpoint.exists() { 199 + return; 200 + } 201 + 202 + // Try to detect if it's a stale mount by attempting to read the directory 203 + // A stale FUSE mount will typically fail with "Device not configured" or similar 204 + if std::fs::read_dir(mountpoint).is_ok() { 205 + // Directory is readable, not a stale mount 206 + return; 207 + } 208 + 209 + eprintln!("Detected stale mount at {:?}, attempting cleanup...", mountpoint); 210 + 211 + // Try platform-specific unmount commands 212 + #[cfg(target_os = "macos")] 213 + { 214 + // Try diskutil first (more reliable on macOS) 215 + let _ = Command::new("diskutil") 216 + .args(["unmount", "force"]) 217 + .arg(mountpoint) 218 + .output(); 219 + 220 + // Fall back to umount if diskutil didn't work 221 + if std::fs::read_dir(mountpoint).is_err() { 222 + let _ = Command::new("umount") 223 + .arg("-f") 224 + .arg(mountpoint) 225 + .output(); 226 + } 227 + } 228 + 229 + #[cfg(target_os = "linux")] 230 + { 231 + // Try fusermount first 232 + let _ = Command::new("fusermount") 233 + .args(["-uz"]) 234 + .arg(mountpoint) 235 + .output(); 236 + 237 + // Fall back to umount 238 + if std::fs::read_dir(mountpoint).is_err() { 239 + let _ = Command::new("umount") 240 + .arg("-l") 241 + .arg(mountpoint) 242 + .output(); 243 + } 244 + } 245 + 246 + // If still broken, try removing and recreating the directory 247 + if std::fs::read_dir(mountpoint).is_err() { 248 + let _ = std::fs::remove_dir(mountpoint); 249 + } 250 + 251 + eprintln!("Cleanup complete"); 252 + }

Submissions

sign up or login to add to the discussion
danabra.mov submitted #0
oppi.li

seems harmless enough, thanks for the addition!

pull request successfully merged