Operations 46 min read

Accidental rm -rf in Production: Complete Linux Data Recovery Guide

This guide details step-by-step recovery strategies after accidental rm -rf deletion in Linux production environments, covering immediate write cessation, backup/snapshot verification, /proc file descriptor rescue, block-level imaging, filesystem-specific tools for ext4/XFS/Btrfs/ZFS, container/Kubernetes considerations, validation procedures, and prevention practices.

Raymond Ops
Raymond Ops
Raymond Ops
Accidental rm -rf in Production: Complete Linux Data Recovery Guide

The article opens with a clear conclusion: recovery after rm -rf is sometimes possible, but no single command guarantees full restoration. Success depends on whether the file is still held open by a process, the existence of backups or snapshots, filesystem type, post-deletion write activity, TRIM/discard status, and whether the data resides in a container writable layer, network storage, or object storage.

The first priority after accidental deletion is to stop further writes. Installing recovery tools, continuing logging, restarting services, recreating directories, running fsck or xfs_repair, writing recovered files back to the source filesystem, executing fstrim, or rebooting can all overwrite still-recoverable blocks and metadata. Controlled isolation — draining traffic from the affected instance — is preferred over a hard power-off, which may leave databases, filesystems, or RAID in an inconsistent state.

Immediate documentation is critical: record the exact time, user, command, and target path. Use date -Is, id, pwd, and findmnt -T /path/to/deleted to identify the underlying filesystem and device. Shell history ( history | tail -n 30) helps but may be incomplete; auditd, bastion logs, or centralized logging are more reliable. Do not install new auditing software on the affected filesystem.

Next, confirm the filesystem type (ext4, XFS, Btrfs, ZFS, or network/distributed FS), block device (local HDD/SSD/NVMe, cloud disk, hardware/software RAID, LVM), mount options (especially discard), scheduled fstrim, pre-deletion snapshots (LVM, storage array, cloud disk, Btrfs, ZFS), container volume types (overlay writable layer, bind mount, named volume, Kubernetes PersistentVolume), and encryption status with key availability. These factors dictate the recovery path; never apply ext4-specific tools to an unknown filesystem.

Recovery Priority Order

Recovery attempts should follow success probability and risk, not tool sophistication:

Application-level backups, version control, artifact repositories, object storage versions.

Pre-deletion filesystem, LVM, cloud disk, or storage array snapshots.

Still-open deleted files via /proc.

Replicas on other nodes, replicas, caches, container images, or release artifacts.

Filesystem-level or signature-based recovery on an offline image.

Backup and Snapshot Verification

Do not trust a "successful" backup job alone. Verify the backup timestamp precedes the deletion, covers the target path, and retention policy didn't purge it. For databases, use the database's own physical/logical restore procedure — never just copy data files. Restore to an isolated directory on a separate filesystem (e.g., mkdir -p /recovery/restore-test), then validate file manifests, sizes, hashes, permissions, ownership, timestamps, and application consistency before any production cutover.

Snapshots created after deletion cannot revert to a pre-deletion state; they only freeze the post-deletion state. If a pre-deletion snapshot exists, clone it to a new volume and mount read-only in isolation. Do not roll back the production volume directly, as that would lose all legitimate writes since the snapshot. Key safeguards: scope impact (full-volume rollback affects all files), pre-check snapshot ID/time/source/consistency, take a controlled snapshot of the current volume to preserve post-deletion increments, use a clone for gradual extraction, verify files/permissions/application consistency, and keep a rollback plan (unmount and discard clone on failure). Commands vary widely across LVM, cloud disks, and storage arrays — use vendor documentation and rehearsed runbooks.

Rescuing Still-Open Files via /proc

This is often the highest-value opportunity in production. Deleted log, config, temporary database, or memory-mapped files may remain open by processes. Use lsof +L1 to list files with link count zero (deleted) but still open. Example output shows

nginx 18472 www 5w REG 253,2 734003200 0 8123 /data/logs/access.log (deleted)

. The NLINK column is 0 and the name includes (deleted). Filter by filesystem ( lsof +L1 /data) or PID ( lsof -p 18472 +L1). Do not restart or signal the process until rescue completes; log rotation, service reload, or application reopen can close the descriptor.

Confirm the descriptor and file identity: readlink /proc/18472/fd/5 and stat /proc/18472/fd/5. Then copy to a different filesystem: install -d -m 700 /recovery/open-files followed by

cp --sparse=always /proc/18472/fd/5 /recovery/open-files/access.log.recovered

and sync /recovery/open-files/access.log.recovered. /recovery must be on independent storage with sufficient capacity. cp --sparse=always reduces sparse-hole allocation on the target but final size and content must be verified.

Limitations: if the process continuously appends, the copy captures a moving target; if the file was truncated before deletion, /proc shows only post-truncation content; special files, anonymous tmpfiles, memory mappings, or database data files may not yield application-consistent copies via simple cp; recovered files lack original directory entries, ownership, ACLs, extended attributes, SELinux contexts — these must be reconstructed from backups or adjacent files; the process may close the descriptor at any moment, so prioritize the most critical, smallest files first. After copying, record hashes and metadata: sha256sum /recovery/open-files/access.log.recovered and stat /recovery/open-files/access.log.recovered.

Block-Level Imaging Before Filesystem Recovery

If no backup, snapshot, or open file exists and data value justifies it, stop writes, unmount, and create a block-level image. Work only on the image thereafter. Unmounting interrupts all processes using the filesystem; forced unmount risks inconsistency. Pre-requisites: list affected mount points, services, containers, databases, users; confirm traffic drained, writes stopped, dependents notified; prepare target media with capacity ≥ source device; dry-run with fuser -vm /data and lsof +f -- /data to verify no holders; verify unmount with findmnt /data (no output = unmounted); rollback plan: if safe unmount impossible, escalate to storage/recovery team — do not force with umount -l or umount -f.

Use GNU ddrescue (pre-installed on rescue media, not the affected FS) for its mapfile and retry capability:

ddrescue -f -n /dev/mapper/vg-data /recovery/vg-data.img /recovery/vg-data.map

(first pass, skip retries), then

ddrescue -d -f -r3 /dev/mapper/vg-data /recovery/vg-data.img /recovery/vg-data.map

(retry up to 3 times). Source device must be confirmed via findmnt and lsblk; target must be on another device. After imaging, set source disk read-only and preserve; all further experiments run on the image copy.

ext4: Opportunities Exist, No Guarantees

On ext4, directory entries, inodes, and data blocks can be quickly reused. Journal mode, file size, fragmentation, post-deletion writes, kernel features, and tool support all affect outcome. SSDs/NVMe with online discard or subsequent fstrim may have already zeroed released blocks, drastically reducing recoverability.

On an offline image, try extundelete with caveats: limited support for newer ext4 features; source must stay unmounted (or read-only); output must go to another filesystem; recovered filenames, directories, permissions, or content may be incomplete; tool-reported "success" does not guarantee usable content. First verify the image: file /recovery/vg-data.img and blkid -p /recovery/vg-data.img. Then attempt: mkdir -p /recovery/extundelete-output and

extundelete /recovery/vg-data.img --restore-all --output-dir /recovery/extundelete-output

. Paths must be real and not on the source FS. Check extundelete --help for version-specific parameters. Targeted path restore is often more verifiable than --restore-all. Results must be checked file-by-file; never overwrite production directly. debugfs, fsck, e2fsck are not general undelete tools; e2fsck may modify metadata even with read-only checks. Any write repair must target a disposable image copy only.

XFS: No Official Undelete; xfs_repair Is Not Undelete

XFS lacks an officially supported, general-purpose undelete workflow. xfs_repair fixes metadata consistency, it does not reliably restore user-deleted files by original path; running it may alter the scene. Priority for XFS: pre-deletion snapshots/backups, open file descriptors, other business replicas, professional recovery or signature scanning on a block image. Tools like PhotoRec can identify common file formats from raw blocks but typically lose original names, directories, permissions, timestamps. Fragmented files, database files, archives, and custom formats may not recover fully. Signature scanning suits "recover some content", not "restore original directory tree".

Btrfs, ZFS, LVM, Cloud Disks: Snapshots Are Not Backup Substitutes

Btrfs and ZFS recovery hinges on pre-existing snapshots, not post-deletion magic commands. List snapshots, then expose or clone the relevant one read-only into isolation. Commands vary by version/deployment — follow local documentation. LVM snapshots are block-level point-in-time views; they must predate the deletion. Check snapshot status (space exhaustion invalidates them). Cloud disk and storage array snapshots may be crash-consistent or application-consistent; database recovery requires log replay or consistency checks per product mechanism.

Never roll back the production volume directly. Safer: create a clone volume, mount on an isolated host, extract target files, then merge legitimate post-deletion changes. Snapshots share fault domains, credentials, and delete permissions with the source — operator error or credential compromise can delete both. They are not off-site backups.

Container and Kubernetes Scenarios

After rm -rf inside a container, first determine where the directory lives:

Container image read-only layer: deletion creates an overlay whiteout; recreating a container from the same image may restore the original file.

Container writable layer: deletion may be permanent if the container is removed; recovery depends on runtime storage structure — do not manually edit overlay directories.

Bind mount or named volume: treat per the host's actual filesystem.

Kubernetes PersistentVolume: follow CSI driver, backend storage snapshot, and backup mechanisms.

ConfigMap or Secret mounts: re-project if source object exists, but verify version and secret handling.

Investigate Kubernetes resources with explicit namespace:

kubectl -n <namespace> get pod <pod-name> -o yaml

, kubectl -n <namespace> get pvc, kubectl -n <namespace> describe pvc <pvc-name>. Output may contain image, mount, node, label info — store per internal security policy.

Do not delete the Pod to "bring files back" — that closes open file descriptors and may destroy the container writable layer. Do not delete PVC/PV without understanding reclaim policy; StorageClass and PV reclaim policy may delete the backend volume. If the file originated from the image, spin up a temporary container in an isolated environment without production volumes:

docker create --name recover-image-copy registry.example.com/app:1.2.3

,

docker cp recover-image-copy:/opt/app/config /recovery/image-config

, docker rm recover-image-copy. Replace image address, tag, container name, source/target paths. Verify image digest matches pre-incident state; don't rely on mutable tags. docker rm only removes the temporary non-production container; confirm identity with docker inspect recover-image-copy before and after export. For containerd, CRI-O, or Kubernetes, adapt commands accordingly.

Post-Recovery Validation and Production Cutover

Recovered files ≠ recovered business. Verify at minimum: file count, directory depth, total size vs. backup manifest; hash match with artifact repo, backup manifest, or other trusted copy; ownership, group, permissions, ACLs, extended attributes, SELinux contexts; symlink and hardlink integrity; config files pass application syntax checks; data files recognized by the application in read-only/verification mode; legitimate post-recovery increments merged.

Check basic metadata:

find /recovery/restored -xdev -printf '%y %m %u %g %s %p
' > /recovery/restored-manifest.txt

and

find /recovery/restored -xdev -type f -print0 | sort -z | xargs -0 sha256sum > /recovery/restored-sha256.txt

. /recovery/restored is the isolated recovery directory. sha256sum reads entire files — assess I/O impact for large datasets. Filenames with newlines break text manifests; use NUL-delimited formats or dedicated tools for automated comparison.

Production restoration is a high-risk data change:

10.1 Impact Scope

Identify services reading the recovered data, whether they'll overwrite post-deletion new files, and whether caches, indexes, databases, or downstream replicas need synchronization.

10.2 Pre-Execution Checks and Backup

Freeze related writes, backup current directory, place recovery results in a new directory (not direct overwrite), preserve old directory name, permissions, mount info.

10.3 Canary / Dry-Run

Compare differences first: rsync -aHAXn --delete /recovery/restored/ /data/target/. Trailing slashes affect rsync semantics (here syncs contents of restored). -n is dry-run; --delete removes extra files on target during real run — high risk. Only remove -n after confirming diff list and business semantics; drop --delete if mirror sync isn't required.

10.4 Validation Method

Load recovered data on a single non-critical instance or isolated environment; run application self-checks, health checks, key read-only queries. Do not use write-capable requests for first validation.

10.5 Rollback Plan

Retain pre-cutover directory or volume; prefer directory rename, mount switch, or traffic shift for rollback. Trigger conditions: app fails to start, validation fails, data timestamp mismatch, error rate spike. Keep old copy until stability confirmed beyond retention window.

Data-Type-Specific Recovery Strategies

Filesystem tools see blocks, inodes, directory entries — not business transactions. Strategy must match data type, else "file opens but business is inconsistent".

11.1 Database Directories

MySQL, PostgreSQL, Redis AOF/RDB, Elasticsearch data directories cannot be treated as ordinary documents. Multiple data files, transaction logs, checkpoints, metadata must come from a consistent point in time. Copying a single open data file from /proc/<PID>/fd or stitching scanned fragments rarely guarantees consistency.

Correct sequence: preserve entire volume or block image, don't start DB on original disk; locate DB-native backups, archive logs, binlogs, WAL, replicas; execute restore in isolation per that DB's specific version procedure; restore to new instance, run DB's own consistency checks; compare recovery point, key table counts, business validation results; restore service via controlled migration or primary/secondary failover, preserving original scene. Commands and log semantics differ entirely across databases — no "universal DB restore command" exists. Primary/secondary switchover or data migration requires separate impact scope, current replication state, write freeze point, backup, canary, validation, and reverse switchover plan.

11.2 Config, Code, Release Artifacts

Config and code should not prioritize filesystem scanning. Check Git repos, config centers, CI build records, image digests, artifact repos, other same-version instances. Lock to commit ID, artifact digest, config version — don't accept "same filename" copies. Before copying config from another running node, diff environment differences (instance ID, IP, key paths, dynamic content). Sensitive config must come from secret management, not logs, shell history, or unknown recovered files. If rebuildable from artifacts, unpack in isolation and verify manifest: sha256sum /recovery/artifacts/app-package.tar.gz, tar -tzf /recovery/artifacts/app-package.tar.gz | less. Paths must be real. tar -t lists only; before actual unpack, check for absolute paths, .. traversal, symlinks, abnormal permissions — all in isolated directory.

11.3 Log Files

Logs often allow partial time-range recovery, but distinguish audit, transaction, and operational logs. Missing audit/compliance logs are security incidents — cannot substitute with similar content from other nodes. If deleted log is still open, copying from /proc may race with ongoing appends. Record copy start/end times and original FD info, then backfill from centralized log platform. Do not forge original mtime; keep "recovered copy" provenance note and hash. If only directory entry deleted but Nginx/Java still holds the space, don't restart to release then recover. Copy critical logs first, confirm centralized collection complete, then rebuild log file via application-supported reopen/reload.

11.4 Images, Videos, Archives, VM Images

Signature scanners like PhotoRec work better on files with clear headers/footers (images), but original names/directories are lost. Large videos, archives, VM disks are often fragmented — scans may yield only fragments. Must verify with format-native tools: archive integrity test, media decode check, virtual disk read-only check — not just size similarity. VM images and container layers may nest filesystems. Preserve outer block image first, then on a copy identify partitions, LVM, internal filesystems; mounting signature-scan results directly as production disks is high risk.

11.5 Directory Structure and Metadata

Even if content recovers, directory tree, ACLs, extended attributes, capabilities, SELinux contexts, hardlinks, sparse attributes may be lost. Missing capabilities on executables break port/network permissions; wrong ACLs on shared dirs cause privilege escalation; sparse images copied normally may balloon in actual usage. Inspect metadata on a trusted copy: getfacl -R /recovery/restored > /recovery/restored.acl.txt,

getfattr -R -d -m- /recovery/restored > /recovery/restored.xattr.txt

. Commands recurse — large datasets generate I/O and large output files; target must stay on independent recovery disk. Tools may need pre-install; don't write install packages to source FS post-incident. SELinux contexts must be restored per system policy and original path, not copied from unknown labels.

Preserve Scene and Recovery Records

High-value data deletion may involve compliance, security, liability. Every recovery action must log operator, time, source device, image hash, tool version, full parameters, output directory, result. Terminal screenshots alone are insufficient. Full SHA-256 of block images takes time and sequential read but enables repeatable forensics:

sha256sum /recovery/vg-data.img > /recovery/vg-data.img.sha256

. Assess target storage I/O and time window. Analysis should use working copies; original image set read-only with restricted access. If each tool run modifies the same image, you cannot compare methods or revert to initial state.

Recovery inventory must distinguish four outcomes: restored from trusted backup, rescued from open FDs, recovered from block scan, unverifiable. The latter two must not be conflated with trusted backups. Unverifiable configs, scripts, binaries must not run in production.

Common Misconceptions

13.1 "Reboot Immediately to Stop Disk Writes"

Reboot closes still-open deleted files; boot process itself writes logs, caches, filesystem metadata. Unless controlled shutdown is assessed and chosen, don't make reboot the first action.

13.2 "Running sync Restores Directory Entries"

sync

only flushes dirty cache to storage; it does not undo deletion. Extra writes to source disk after deletion have no recovery value.

13.3 "Run fsck and Files Reappear"

fsck

family repairs consistency, not general undelete. Write repairs may further alter metadata. Use only for actual filesystem corruption per FS-specific procedure, preferably on an image copy.

13.4 "SSD Behaves Like Mechanical Disk"

SSD/NVMe TRIM/discard tells the controller which logical blocks are unused; the controller may subsequently make those blocks unreadable. Whether immediate zeroing occurs depends on device and stack implementation — cannot promise recovery just because deletion was recent.

13.5 "Recovery Software Lists Filenames So Content Is Intact"

Metadata and data blocks may have been separately reused. Must verify file format, hash, application consistency. Text files can be sampled; archives tested with native tools; databases require DB-native checksum and restore flows.

13.6 "Overwrite Recovery Results Back to Original Path"

This overwrites potentially still-recoverable data and mixes recovered files with post-incident new files. All recovery writes go to independent storage and isolated directories first.

Reducing Impact of Future Accidental Deletions

14.1 Permissions and Directory Design

Application accounts get only necessary directory permissions; daily service accounts must not have whole-volume delete rights.

Separate data, logs, cache, release artifacts into distinct mounts and authorization domains.

Avoid shared high-privilege accounts in production; use sudo with per-person audit.

Protect critical data with application-level immutable backups, object versioning, or protected snapshots.

Place reproducible release files in artifact repos, rebuild via deployment system — don't rely on single local machine copies.

14.2 Write Safe Cleanup Scripts

Pre-delete validation: variable non-empty, target within allowed directory, filesystem matches expectation. Example shell snippet (review in test first):

set -euo pipefail

TARGET_DIR="${TARGET_DIR:?TARGET_DIR must be set}"
ALLOWED_ROOT="/data/app-cache"

case "$TARGET_DIR" in
  "$ALLOWED_ROOT"/*) ;;
  *) printf 'refuse to delete outside %s: %s
' "$ALLOWED_ROOT" "$TARGET_DIR" >&2; exit 1 ;;
esac

find "$TARGET_DIR" -xdev -mindepth 1 -maxdepth 1 -type f -mtime +7 -print
TARGET_DIR

is an env var — replace with actual subdirectory to clean. Script rejects empty var and paths outside allowed root. Final line uses -print only for dry-run. After reviewing the list, hand off to an approved cleanup pipeline; don't simply change -print to -delete and deploy. Handle concurrent creation, symlinks, special filenames, mount boundaries, retention rules. alias rm='rm -i' is not production protection — scripts and non-interactive shells may not load aliases, operators can bypass prompts. Real protection: least privilege, approval, verifiable dry-run, snapshots, recovery drills.

14.3 Backups Must Include Restore Drills

Define RPO and RTO explicitly: how much data loss is tolerable, how fast must recovery be. Backups must include manifests, checksums, encryption key management, off-site or cross-fault-domain copies, and regular isolated-environment restores. A backup never validated by restore is only a "potentially usable copy".

14.4 Monitor Deletions and Capacity Anomalies

Alert on critical directory file-count drops, capacity sudden decreases, backup deletions, snapshot deletions, high-risk command execution. inotify suits real-time event notification but event queues can overflow; it doesn't replace backups and centralized audit. Evaluate monitoring overhead for large directories.

Incident Response Checklist

After rm -rf mis-deletion, proceed in order:

Record exact time, host, user, command, target path.

Stop non-essential writes on affected FS; no installs, no reboots.

Use findmnt, lsblk to confirm real filesystem, device, container/network storage boundaries.

Check backups, pre-deletion snapshots, artifact repos, other nodes, object versions first.

Immediately run lsof +L1 for still-open deleted files; copy to another filesystem.

If data value high and no reliable copy: controlled drain, unmount, create block image.

All recovery experiments target image copies only; output to independent target disks.

Choose method per ext4, XFS, Btrfs, ZFS, or storage product — don't mix tools.

Validate recovered content, hashes, permissions, timestamps, application consistency.

Before production restore: dry-run, canary, backup current state, prepare explicit rollback.

Retrospective: permissions, cleanup scripts, snapshots, backups, audit, recovery drills.

Whether opportunity remains after rm -rf depends on whether the scene was protected and whether recoverable copies existed before the incident. The only truly reliable recovery strategy is validated backups and snapshots; filesystem scanning is a last resort, not a data protection strategy.

Before closing the incident, confirm two time targets: does recovery point meet RPO? Does recovery duration meet RTO? Even if the target directory reappears, if the last pre-deletion data segment is missing, permissions not restored, or downstream indexes not rebuilt, recovery is not complete. For unrecoverable data, explicitly document missing scope, affected business, re-entry method, and owner — "tool reported no errors" cannot substitute business acceptance.

Finally, preserve controlled scene, recovery inventory, hashes, approvals, validation records, and set a retention period for recovery copies. Recovery disks often contain full production data; long-term unmanaged storage becomes a new security risk. Expiry cleanup also requires target verification, approval, dry-run, validation, and auditable records — don't reuse unprotected recursive deletion just because it's a temporary directory.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

operationslinuxincident responseData RecoveryBackupSnapshotscontainersFile Systems
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.