This is the procedure for restoring (undeleting) accidentally deleted or modified files from a snapshot of a file system on ZFS.

What is ZFS?

ZFS is a pooled storage file system, that is robust, scalable and easy to administrate. ZFS stores data in file systems, known as datasets, in storage pools on physical storage devices. When new storage devices is added, the file systems within the pool can immediately use the additional disk space.

Data on ZFS can never become corrupted, because it is a transactional file system, that never overwrites data. This is also known as copy on write (CoW). Data is verified using a checksum algorithm. If a bad block is detected, then ZFS will fetch data from a redundant copy and repair it.

What is a ZFS snapshot?

ZFS has a built-in snapsnot feature, that ensures, that changes can be undone quick and easy. This includes accidentally deleted files, modified files or encrypted files from a ransom-ware attack or computer virus. A snapshot is a read-only copy of a file system as it was on the time of the snapshot creation.

Snapshots only consume the data, that makes up for the differences between other snapshots and the current file system. For that reason, daily snapshots of server file systems can be taken with a rolling snapshot cron script or manually taken as necessary.

In the following example, a recursive snapshot is taken of the user home directory on a FreeBSD operating system. It is named after todays date, which is a good naming convention for snapshots.

# zfs snapshot -r zroot/usr/home@2022-04-22

Find snapshot of accidentally deleted files in hidden ZFS snapshot directory.

Get a list of snapshots. In the following example, there are 3 different snapshots, that was taken on different days, of the dataset and its user home directores in /usr/home.

# zfs list -t snapshot
NAME                        USED  AVAIL     REFER  MOUNTPOINT
zroot/usr/home@2022-04-19  40.4G      -      830G  -
zroot/usr/home@2022-04-20  11.1G      -      871G  -
zroot/usr/home@2022-04-21   183K      -      871G  -

ZFS snapshots are stored in a hidden directory, that is named .zfs/snapshot, of the mountpoint. In the following example, the mountpoint is the user home directories /usr/home, so the ZFS snapshots are found in the hidden directory.

# cd /usr/home
# cd .zfs/snapshot
# ls
2022-04-19 2022-04-20 2022-04-21

Find the user homes, that are to be restored. In the following example, the default find utility is used to find, which snapshots, that contain a copy of the accidentally deleted user homes ann and bob. The command line can be read as “start searching recursively in current directory and find directories with the name ann or bob“.

# find . -type d -name 'ann' -or -name 'bob'
./2022-04-21/ann
./2022-04-21/bob

Change directory to the directory of the snapshot, that will be used for the restore. A list will confirm the copy of the user homes.

# cd 2022-04-21
# ls
ann bob cory david franklin

Restore (undelete) the accidentally deleted files from the ZFS snapshot.

The files can now be restored (undeleted) by copying them to the original directory from where they were accidentally deleted.

  • Make sure, that the directories, and their entire subtree, are copied. This is known as recursive copying.
  • Make sure, that symbolic links are copied rather than indirected through (followed).
  • Make sure, that existing good files, if any, are not overwritten by older versions.
  • Make sure, that file attributes, such as modification time, access time, flags, mode, user ID and group ID are preserved.
  • Make sure, that copying is done with verbose output, so any issues, there might be, can be addressed. Files, that are copied, will be listed, and files, that are not overwritten, will also be listed.
  • Storing the output can document, which files were restored and help resolve issues, there might be.

In the following example, the user homes of Ann and Bob, that originally was /usr/home/ann and /usr/home/bob, are restored (undeleted) in /usr/home/. The requirements above are meet. The tee command, that the output is piped to, writes the output to a text file as well as to the screen.

# cd
# ls /usr/home
cory david franklin
# cp -R -n -p -v /usr/home/.zfs/snapshot/2022-04-21/{ann,bob} /usr/home/ | tee output.txt
# ls /usr/home
ann bob cory david franklin

The restored user homes, and files within them, can now be accessed and used by the users as normal.

More about ZFS.

Chapter 20. The Z File System (ZFS) in FreeBSD Handbook. ZFS on WikiPedia.