3 stable releases
Uses new Rust 2024
| new 1.1.0 | Apr 14, 2026 |
|---|---|
| 1.0.1 | Apr 12, 2026 |
#975 in Filesystem
34KB
546 lines
๐ฅ Obliterate - Force Removal on Linux
Force-remove Files and Directories on Linux Including Paths with 000 Permissions.
๐ Overview
obliterate is a Linux-only Rust crate designed to aggressively and safely
remove files and directories โ even in scenarios where traditional tools fail.
It handles edge cases like 000 permissions, nested mount points, and deeply
recursive trees without stack overflows.
Unlike traditional approaches, this crate:
- Fixes permissions automatically before deletion;
- Detects and lazily unmounts nested mount points;
- Avoids dangerous path patterns like
..; - Uses controlled recursion with stack growth protection;
๐ Features
-
๐ Handles
000permissions
removes trees thatstd::fs::remove_dir_allcannot. -
๐งฉ Mount-point aware
lazily unmounts nested filesystems before deleting. -
๐งฑ Stack-safe recursion
usesstackerto safely handle deeply nested trees. -
๐ก๏ธ Basic safety guards
prevents invalid paths like... -
๐ฆ Structured errors
clear error types for invalid targets, I/O failures, and unmount issues. -
๐ง Linux-only
relies on/proc/self/mountinfoandumount2.
๐ Usage
This section demonstrates how to integrate and use obliterate in your Rust
project. The crate provides two main entry points:
removeโ strict removal (fails if the path does not exist)ensure_removedโ forgiving removal (behaves likerm -rf)
Add the dependency to your Cargo.toml:
[dependencies]
obliterate = "1.0"
Then use it in your code:
use obliterate::{remove, ensure_removed, Error};
// Strict removal (fails if not found)
remove("target")?;
// Idempotent removal (like rm -rf)
ensure_removed("build")?;
match remove("some/path") {
Ok(()) => {}
Err(Error::NotFound) => eprintln!("already gone"),
Err(Error::UnmountFailed { path, fstype, reason }) => {
eprintln!("failed to unmount {} ({}): {}", path.display(), fstype, reason)
}
Err(e) => return Err(e.into()),
}
๐ก When to use each function
- Use
removewhen you expect the path to exist and want strict error handling. - Use
ensure_removedwhen you want idempotent cleanup, especially in build scripts, CI pipelines, or temporary directory management.
Both functions guarantee safe, race-resistant removal using file-descriptor-based operations under the hood.
โ๏ธ How it works
๐ Permission handling
Before deletion, the crate ensures the current process has sufficient
permissions by setting mode 0o700 when necessary. std::fs::remove_dir_all fails
on directories with 000 permissions because the kernel checks execute permission
on the directory before allowing iteration.
๐งท Mount-point handling
Before touching any directory, obliterate reads /proc/self/mountinfo and
collects every mount-point nested inside the target tree. They are unmounted
deepest-first using a three-tier strategy:
umount2(MNT_DETACH)via libcfusermount3 -u -zfusermount -u -z
Mounts are processed deepest-first to avoid dependency issues. If unmounting fails, an error is returned and deletion is aborted.
๐งต Recursive removal
The crate recursively deletes files and directories while:
- Fixing permissions
- Avoiding stack overflow via
stacker - Handling both files and directories correctly
โ Error variants
pub enum Error {
/// Path does not exist (only from `remove`, not `ensure_removed`).
NotFound,
/// The Path ends in ".." or is otherwise invalid.
InvalidTarget(String),
/// OS-level I/O failure, with the path that triggered it.
IoError(std::io::Error),
/// A nested mount-point could not be unmounted.
UnmountFailed {
path: PathBuf,
fstype: String,
reason: String,
},
}
๐งช Notes
Some unmount operations may require elevated privileges (CAP_SYS_ADMIN).
๐ MIT License
This repository has scripts created to be free software.
Therefore, they can be distributed and/or modified within the terms of the MIT License.
See the MIT License file for details.
๐ฌ Contact
Dependencies
~0.2โ10MB
~61K SLoC