Setting up a Corruption-Resistant Drive for Data Storage

This post demonstrates my setup for a Btrfs hard drive for storing data with duplications, making it highly resistant to random data corruption.

Btrfs intro

From Btrfs Wiki:

Btrfs is a modern copy on write (CoW) filesystem for Linux aimed at implementing advanced features while also focusing on fault tolerance, repair and easy administration. Jointly developed at multiple companies, Btrfs is licensed under the GPL and open for contribution from anyone.

Btrfs is supported natively by Linux kernel. For user space utilities, Arch users can install the btrfs-progs package.

There are two ways to achieve the goal of setting up Btrfs on a single drive with data redundancy:

  1. Set up two partitions in RAID1 and configure the Btrfs on top of that.
  2. Use Btrfs’s mix mode.

Neither approach is perfect, and performance is going to be not as fast as usingĀ  multiple drives. But we can get away with the gaining in portability. The idea to to have an airtight backup drive that can be carried on travels. I this post I will only focus on the second approach, though it is not the intended use case as pointed out in Btrfs documentation.

Drive preparation

Before setting up the filesystem, we setup an encrypted container using dm-crypt. The first step is to rewrite the whole drive with random data to prevent cryptographic attacks or unwanted file recovery.

The best way to wipe the drive is by first creating a container

$ cryptsetup open --type plain -d /dev/urandom /dev/<block-device> to_be_wiped

and then wiping the container with zeros.

A use of if=/dev/urandom is not required as the encryption cipher is used for randomness.

(I actually skipped this step, since for a 4T drive it will take days to wipe, instead I did a quick and dirty wipefs only.)

Then create a partition using fdisk

$ sudo fdisk /dev/sdb

Now we can setup encryption on the partition sdb1 which we just created

$ sudo cryptsetup --verbose --verify-passphrase --cipher=aes-xts-plain64 --key-size=512 --hash=sha512 --iter-time=5000 --use-random luksFormat /dev/sdb1

Check if everything is setup as desired

$ sudo cryptsetup luksDump /dev/sdb1

It is highly advised that the header be backed up, since is the header of a LUKS volume gets damaged, all data is permanently lost unless you have a header-backup.

$ sudo cryptsetup luksHeaderBackup --header-backup-file /path/to/file.img /dev/sdb1

Lastly, open the container

$ sudo cryptsetup luksOpen /dev/sdb1 luksvol01

This will prompt for the password and mount the device at /dev/mapper/luksvol01.

Setup Btrfs

Create the Btrfs filesystem

$ sudo mkfs.btrfs --data dup --metadata dup /dev/mapper/luksvol01

Mount the filesystem

$ sudo mkdir -p /mnt/luksdrive01
$ sudo mount /dev/mapper/luksvol01 /mnt/luksdrive01

Unmount and close the container

$ sudo umount /mnt/luksdrive01
$ sudo cryptsetup luksClose /dev/mapper/luksvol01

Using Btrfs

Since all the data is duplicated, the available is space is only 50% of the whole capacity. To check and auto fix data corruption, use the scrub command

$ sudo btrfs scrub start -B /mnt/luksdrive01

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.