I am trying to create an encrypted, growing-as-needed file system in with Linux. I am familiar with LUKS and cryptsetup.
I can create an empty file:
fallocate -l 512M /root/image
I can create a LUKS container on it:
cryptsetup -y luksFormat /root/image
And then "open" it:
cryptsetup luksOpen /root/image luksvolume
At this point, I can just make a file system on it:
mkfs.ext4 -j /dev/mapper/luksvolume
This is all fine and dandy. However, it doesn't address the "grow-on-demand" part of the question.
The idea is that copying a 2Gb file on the encrypted file system will "expand" the image so that it's big enough to contain the file.
Is it even possible to do?
Best Answer
Yes! It looks like it's possible. Let's check how it can be achieved. Note that this doesn't create a true grow-on-demand filesystem, as when the filesystem reaches the max size of the sparse file, it will report 'out of space' errors if more data still needs to be written.
Initially, I was investigating Thin Provisioning, a well-known technology to save storage space in virtualization scenarios. Unfortunately, in common Linux use-cases, it seems to be available only with LVM. As this seems a bit outside the scope of your question, I searched for something else.
The second concept I investigated is Sparse File. This is exactly suited to your question and... my initial doubt was: "OK. I can create a Sparse File. But what happens when I initialize it as a LUKS container? Will such initialization allocate all the available space? If not, what will happen when I will initialize the filesystem in such a container? Will an
mkfs.ext4
allocate all the available space?". As I had no answer, I decided to try. So, let's see what happened.Let's start from my current system, where I have only 3.3G of free space within the
/repository
filesystem:Let's create a 10G sparse-file within such a filesystem, with:
and let's verify that... it's really a sparse file:
OK. So we have a 10G file, in a filesystem that previously had 3.3G of free space. How much free space still I have?
Still 3.3G. Nice. Sparse-file are really... sparse-file ;-) Let's step ahead, by creating a LUKS container within such a 10G file and... let's see if we run out of space:
So now I have an opened
secrets
container defined on top of my 10G sparse-file stored in a filesystem having only 3.3G of free space.How much free space still I have?
Wonderful! Still 3.3GB. Our encrypted container required mostly no space!
Let's check if everything is OK or if there are something strange with our setup:
Everything seems OK so let's start using such a container to store something. Let's begin by creating an EXT4 filesystem inside it:
It looks like it worked, as there was no track of "out of space". Let's check:
Uhm.... so something happened. We lost something like 100M of space but.... it's an expected behaviour: the creation of the EXT4 filesystem DO require the writing of lots of metadata. So it's normal that some space have been used by the creation process.
Is it a "working" EXT4 filesystem?
Yes! It looks ok.
So now we have an EXT4 filesystem written inside an opened LUKS container defined on top of a 10G sparse-file stored within a 3.3G filesystem.
Let's see if everything works correctly, by allocating space "on-demand".
Let's start by writing 500M of dummy data to the encrypted FS
Have we been succesfull in creating the file?
It looks so.
What happened to our real filesystem?
Uau! We "lost" sligthly more than 500M. That's good, BTW, as the physical space is really allocated on demand!
Let's store another 2GB file:
What happened?
Really nice. What happens if we delete a file?
As expected, with sparse-file the behaviour is exactly like thin-provisioning: once allocated, storage-space cannot be claimed back when file are deleted. But this, in general, is OK. Don't you?
So at this point, the answer to your question should be complete. Right?
Addition:
Let's see what happens when the underlining storage gets full:
What? it looks like it succeded! How this have been possible? Let's check!
Uhm... It looks ok. Are we sure?
we have run out of space! Without any error!
Even if it would be nice to investigate what really happened... I'm going to leave this to your curiosity and/or troubleshooting skills of other ServerFault members ;-)
Have fun!
BTW: I've tested all of the above, here: