My home directories are encrypted via dm-crypt / cryptsetup using a loopback device and formatted with the reiserfs filesystem. See Disk cryptography with dm-crypt and SECURITY dmcrypt - Gentoo Linux Wiki.
For the user 'bn', the image is a 5G file called /home/bn.img. It is set up as loopback device /dev/loop1 then mapped to crypt-bn and mounted as /home/bn.
The problem is that the image file does not automatically resize when it runs out of space.
Resizing reiserfs crypt mounted with dm-crypt
This assumes that the device is in use. If not, just ignore the first 3 steps.
- Unmount the file system with umount.
- Remove the crypt device mapping with cryptsetup.
- Detach the loop device with losetup.
- Back up the image file!
- Add data to the end of the image file with dd.
- Reattach the loop device with losetup.
- Recreate the crypt device mapping with cryptsetup.
- Resize the reiserfs filesystem with resize_reiserfs.
- Remount the file system with mount.
- Verify new size with df.
Detail
To begin, I restarted my computer and entered the incorrect password for crypt-bn. Once logged in to the system (as a different user) I backed up image bn.img to a seperate computer. Then I did the steps outlined above, with a few tests in between to make sure everything was going to plan...
root@localhost home # umount /home/bn umount: /home/bn: not mounted root@localhost home # dmsetup ls crypt-steph (254, 3) crypt-swap (254, 0) crypt-bn (254, 2) crypt-tmp (254, 1) root@localhost home # cryptsetup remove crypt-bn root@localhost home # dmsetup ls crypt-steph (254, 3) crypt-swap (254, 0) crypt-tmp (254, 1) root@localhost home # losetup -a /dev/loop0: [0808]:942290 (/tmp.img) /dev/loop1: [0808]:946234 (/home/bn.img) /dev/loop2: [0808]:344097 (/home/steph.img) /dev/loop/0: [0808]:942290 (/tmp.img) /dev/loop/1: [0808]:946234 (/home/bn.img) /dev/loop/2: [0808]:344097 (/home/steph.img) root@localhost home # losetup -d /dev/loop1 root@localhost home # losetup -a /dev/loop0: [0808]:942290 (/tmp.img) /dev/loop2: [0808]:344097 (/home/steph.img) /dev/loop/0: [0808]:942290 (/tmp.img) /dev/loop/2: [0808]:344097 (/home/steph.img) root@localhost home # dd if=/dev/urandom bs=1M count=3072 >> bn.img
I forgot to make note of the exact output here, but suffice to say the data was written to bn.img.
root@localhost home # losetup -f /dev/loop1 root@localhost home # losetup /dev/loop1 /home/bn.img root@localhost home # cryptsetup -y -c serpent -s 256 create crypt-bn /dev/loop1 Enter passphrase: Verify passphrase: root@localhost home # resize_reiserfs /dev/mapper/crypt-bn resize_reiserfs 3.6.19 (2003 www.namesys.com) ReiserFS report: blocksize 4096 block count 2066432 (1280000) free blocks 803801 (17393) bitmap block count 64 (40) Syncing..done resize_reiserfs: Resizing finished successfully. root@localhost home # mount /dev/mapper/crypt-bn /home/bn root@localhost home # df -lh /home/bn Filesystem Size Used Avail Use% Mounted on /dev/mapper/crypt-bn 7.9G 4.9G 3.1G 62% /home/bn
Success! The new size is 7.9G, with 3.1G unused.
References
- SECURITY dmcrypt - Gentoo Linux Wiki
- Gentoo Forums :: View Topic - Automatically mount dm-crypt encrypted home with pam_mount
- Gentoo Forums :: View topic - HOWTO: enlarge an encrypted LVM partition
Unused related links
- Gentoo Forums :: View topic - Resize a luks encrypted lvm volume (short guide)
- Encrypting a user home folder on a laptop
- Quick simple encrypted loopback filesystem
Tests
Some tests I did before resizing my important data.
Here I play with an image file called crypttest, which is set as loopback /dev/loop3, mapped to /dev/mapper/mycrypt and mounted as cryptmount.
Create crypt
root@localhost steph # dd if=/dev/urandom bs=1M count=2 > crypttest 2+0 records in 2+0 records out 2097152 bytes (2.1 MB) copied, 0.673763 s, 3.1 MB/s root@localhost steph # ls -l crypttest -rw-r--r-- 1 steph users 2097152 May 30 14:13 crypttest root@localhost steph # losetup -f /dev/loop3 root@localhost steph # losetup /dev/loop3 crypttest root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: Verify passphrase: root@localhost steph # dmsetup ls mycrypt (254, 4) crypt-steph (254, 3) crypt-swap (254, 0) crypt-bn (254, 2) crypt-tmp (254, 1) root@localhost steph # mkreiserfs /dev/mapper/mycrypt mkreiserfs 3.6.19 (2003 www.namesys.com) A pair of credits: Yury Umanets (aka Umka) developed libreiser4, userspace plugins, and all userspace tools (reiser4progs) except of fsck. Vladimir Saveliev started as the most junior programmer on the team, and became the lead programmer. He is now an experienced highly productive programmer. He wrote the extent handling code for Reiser4, plus parts of the balancing code and file write and file read. Guessing about desired format.. Kernel 2.6.18-gentoo-r6 is running. reiserfs_create_journal: cannot create a journal of 8193 blocks with 18 offset on 512 blocks
Too small! Recreate at over 32M (521/2 = 256. 8193/256 ~= 32). I'll do 100M
root@localhost steph # cryptsetup remove mycrypt root@localhost steph # dmsetup ls crypt-steph (254, 3) crypt-swap (254, 0) crypt-bn (254, 2) crypt-tmp (254, 1) root@localhost steph # losetup -d /dev/loop3 root@localhost steph # losetup -f /dev/loop3 root@localhost steph # dd if=/dev/urandom bs=1M count=100 > crypttest 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 34.2838 s, 3.1 MB/s root@localhost steph # ls -l crypttest -rw-r--r-- 1 steph users 104857600 May 30 14:38 crypttest root@localhost steph # losetup /dev/loop3 crypttest root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: Verify passphrase: root@localhost steph # dmsetup ls mycrypt (254, 4) crypt-steph (254, 3) crypt-swap (254, 0) crypt-bn (254, 2) crypt-tmp (254, 1) root@localhost steph # mkreiserfs /dev/mapper/mycrypt mkreiserfs 3.6.19 (2003 www.namesys.com) A pair of credits: Oleg Drokin was the debugger for V3 during most of the time that V4 was under development, and was quite skilled and fast at it. He wrote the large write optimization of V3. Jeremy Fitzhardinge wrote the teahash.c code for V3. Colin Plumb also contributed to that. Guessing about desired format.. Kernel 2.6.18-gentoo-r6 is running. Format 3.6 with standard journal Count of blocks on the device: 25600 Number of blocks consumed by mkreiserfs formatting process: 8212 Blocksize: 4096 Hash function used to sort names: "r5" Journal Size 8193 blocks (first block 18) Journal Max transaction length 1024 inode generation number: 0 UUID: da6a44e2-f7f8-4e69-a5d3-7c9c70b8adaf ATTENTION: YOU SHOULD REBOOT AFTER FDISK! ALL DATA WILL BE LOST ON '/dev/mapper/mycrypt'! Continue (y/n):y Initializing journal - 0%....20%....40%....60%....80%....100% Syncing..ok Tell your friends to use a kernel based on 2.4.18 or later, and especially not a kernel based on 2.4.9, when you use reiserFS. Have fun. ReiserFS is successfully created on /dev/mapper/mycrypt. root@localhost steph # mount /dev/mapper/mycrypt cryptmount
Create test files
root@localhost steph # echo "testing testing 123" > cryptmount/test1.txt root@localhost steph # mkdir cryptmount/testdir root@localhost steph # echo "testing testing 234" > cryptmount/testdir/test2.txt root@localhost steph # echo "testing testing 345" > cryptmount/testdir/test3.txt root@localhost steph # cat cryptmount/test1.txt testing testing 123 root@localhost steph # cat cryptmount/testdir/test2.txt testing testing 234 root@localhost steph # cat cryptmount/testdir/test3.txt testing testing 345
Test unmount
root@localhost steph # umount cryptmount root@localhost steph # cryptsetup remove mycrypt root@localhost steph # losetup -d /dev/loop3 root@localhost steph # losetup -f /dev/loop3 root@localhost steph # dmsetup ls crypt-steph (254, 3) crypt-swap (254, 0) crypt-bn (254, 2) crypt-tmp (254, 1)
Test remount
root@localhost steph # losetup /dev/loop3 crypttest root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: Verify passphrase: root@localhost steph # mount /dev/mapper/mycrypt cryptmount root@localhost steph # ls cryptmount/ test1.txt testdir root@localhost steph # cat cryptmount/test1.txt testing testing 123 root@localhost steph # cat cryptmount/testdir/test2.txt testing testing 234 root@localhost steph # cat cryptmount/testdir/test3.txt testing testing 345
Test resize
root@localhost steph # umount cryptmount root@localhost steph # cryptsetup remove mycrypt root@localhost steph # losetup -d /dev/loop3 root@localhost steph # losetup -f /dev/loop3 root@localhost steph # dmsetup ls crypt-steph (254, 3) crypt-swap (254, 0) crypt-bn (254, 2) crypt-tmp (254, 1) root@localhost steph # dd if=/dev/urandom bs=1M count=50 >> crypttest 50+0 records in 50+0 records out 52428800 bytes (52 MB) copied, 15.263 s, 3.4 MB/s root@localhost steph # ls -l crypttest -rw-r--r-- 1 steph users 157286400 May 30 14:56 crypttest root@localhost steph # losetup /dev/loop3 crypttest root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: Verify passphrase: root@localhost steph # resize_reiserfs /dev/mapper/mycrypt resize_reiserfs 3.6.19 (2003 www.namesys.com) ReiserFS report: blocksize 4096 block count 38400 (25600) free blocks 30187 (17388) bitmap block count 2 (1) Syncing..done resize_reiserfs: Resizing finished successfully. root@localhost steph # mount /dev/mapper/mycrypt cryptmount root@localhost steph # ls cryptmount/ test1.txt testdir root@localhost steph # df cryptmount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/mycrypt 153588 32840 120748 22% /home/steph/cryptmount root@localhost steph # df -h cryptmount Filesystem Size Used Avail Use% Mounted on /dev/mapper/mycrypt 150M 33M 118M 22% /home/steph/cryptmount root@localhost steph # cat cryptmount/test1.txt testing testing 123 root@localhost steph # cat cryptmount/testdir/test2.txt testing testing 234 root@localhost steph # cat cryptmount/testdir/test3.txt testing testing 345
Test password
root@localhost steph # losetup /dev/loop3 crypttest root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: (incorrect password entered) root@localhost steph # mount /dev/mapper/mycrypt cryptmount/ mount: you must specify the filesystem type
Good, so an incorrect password results in a crypt that can't be accessed.
Test 'cryptsetup resize'
One thing was left unanswered... What is 'cryptsetup resize' for?
Perhaps for resizing a block device that has changed size whilst mapped. See Re: how to use cryptsetup resize?.
Time for some tests (spoiler: couldn't find any discernible changes made by 'cryptsetup resize')...
Clean start
root@localhost steph # cryptsetup remove mycrypt root@localhost steph # losetup -d /dev/loop3 root@localhost steph # dd if=/dev/urandom bs=1M count=100 > crypttest 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 33.7287 s, 3.1 MB/s root@localhost steph # losetup /dev/loop3 crypttest root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: Verify passphrase: root@localhost steph # mkreiserfs /dev/mapper/mycrypt mkreiserfs 3.6.19 (2003 www.namesys.com) A pair of credits: The Defense Advanced Research Projects Agency (DARPA, www.darpa.mil) is the primary sponsor of Reiser4. DARPA does not endorse this project; it merely sponsors it. Vitaly Fertman wrote fsck for V3 and maintains the reiserfsprogs package now. He wrote librepair, userspace plugins repair code, fsck for V4, and worked on developing libreiser4 and userspace plugins with Umka. Guessing about desired format.. Kernel 2.6.18-gentoo-r6 is running. Format 3.6 with standard journal Count of blocks on the device: 25600 Number of blocks consumed by mkreiserfs formatting process: 8212 Blocksize: 4096 Hash function used to sort names: "r5" Journal Size 8193 blocks (first block 18) Journal Max transaction length 1024 inode generation number: 0 UUID: 2e1b01ea-8376-4f07-8e95-7470abb4bc6d ATTENTION: YOU SHOULD REBOOT AFTER FDISK! ALL DATA WILL BE LOST ON '/dev/mapper/mycrypt'! Continue (y/n):y Initializing journal - 0%....20%....40%....60%....80%....100% Syncing..ok Tell your friends to use a kernel based on 2.4.18 or later, and especially not a kernel based on 2.4.9, when you use reiserFS. Have fun. ReiserFS is successfully created on /dev/mapper/mycrypt. root@localhost steph # mount /dev/mapper/mycrypt cryptmount root@localhost steph # dd if=/dev/zero > cryptmount/zeroes dd: writing to `standard output': No space left on device 138961+0 records in 138960+0 records out 71147520 bytes (71 MB) copied, 2.78217 s, 25.6 MB/s root@localhost steph # ls -l cryptmount/zeroes -rw-r--r-- 1 root root 71147520 Jun 2 00:19 cryptmount/zeroes root@localhost steph # df cryptmount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/mycrypt 102392 102392 0 100% /home/steph/cryptmount
Resize crypttest
root@localhost steph # dd if=/dev/urandom bs=1M count=100 >> crypttest 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 30.4674 s, 3.4 MB/s root@localhost steph # cryptsetup resize mycrypt root@localhost steph # resize_reiserfs /dev/mapper/mycrypt resize_reiserfs 3.6.19 (2003 www.namesys.com) /dev/mapper/mycrypt already is of the needed size. Nothing to be done
Reiserfs doesn't think crypt size has changed. Perhaps 'cryptsetup resize' already resized the reiserfs filesystem...
root@localhost steph # umount cryptmount root@localhost steph # mount /dev/mapper/mycrypt cryptmount root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes dd: writing to `standard output': No space left on device 1+0 records in 0+0 records out 0 bytes (0 B) copied, 0.0295515 s, 0.0 kB/s root@localhost steph # ls -l cryptmount/zeroes -rw-r--r-- 1 root root 71147520 Jun 2 00:22 cryptmount/zeroes root@localhost steph # df cryptmount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/mycrypt 102392 102392 0 100% /home/steph/cryptmount
It didn't. Recreate crypt and try again...
root@localhost steph # umount cryptmount root@localhost steph # cryptsetup remove mycrypt root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: root@localhost steph # mount /dev/mapper/mycrypt cryptmount root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes dd: writing to `standard output': No space left on device 1+0 records in 0+0 records out 0 bytes (0 B) copied, 0.0294059 s, 0.0 kB/s root@localhost steph # ls -l cryptmount/zeroes -rw-r--r-- 1 root root 71147520 Jun 2 00:24 cryptmount/zeroes root@localhost steph # resize_reiserfs /dev/mapper/mycrypt resize_reiserfs 3.6.19 (2003 www.namesys.com) /dev/mapper/mycrypt already is of the needed size. Nothing to be done
Reiserfs still doesn't think crypt size has changed. Need to reset loop?...
root@localhost steph # umount cryptmount root@localhost steph # cryptsetup remove mycrypt root@localhost steph # losetup -d /dev/loop3 root@localhost steph # losetup /dev/loop3 crypttest root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: root@localhost steph # mount /dev/mapper/mycrypt cryptmount root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes dd: writing to `standard output': No space left on device 1+0 records in 0+0 records out 0 bytes (0 B) copied, 0.00282065 s, 0.0 kB/s root@localhost steph # ls -l cryptmount/zeroes -rw-r--r-- 1 root root 71147520 Jun 2 00:27 cryptmount/zeroes root@localhost steph # umount cryptmount root@localhost steph # resize_reiserfs /dev/mapper/mycrypt resize_reiserfs 3.6.19 (2003 www.namesys.com) ReiserFS report: blocksize 4096 block count 51200 (25600) free blocks 25599 (0) bitmap block count 2 (1) Syncing..done resize_reiserfs: Resizing finished successfully. root@localhost steph # mount /dev/mapper/mycrypt cryptmounts root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes dd: writing to `standard output': No space left on device 204593+0 records in 204592+0 records out 104751104 bytes (105 MB) copied, 4.85683 s, 21.6 MB/s root@localhost steph # ls -l cryptmount/zeroes -rw-r--r-- 1 root root 175898624 Jun 2 00:27 cryptmount/zeroes root@localhost steph # df cryptmount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/mycrypt 204788 204788 0 100% /home/steph/cryptmount
Resetting loop works, as expected - no new information discovered.
Resize /dev/loop3
root@localhost steph # umount cryptmount root@localhost steph # dd if=/dev/urandom bs=1M count=100 >> /dev/loop3 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 28.5788 s, 3.7 MB/s root@localhost steph # cryptsetup resize mycrypt root@localhost steph # resize_reiserfs /dev/mapper/mycrypt resize_reiserfs 3.6.19 (2003 www.namesys.com) reiserfs_open: the reiserfs superblock cannot be found on /dev/mapper/mycrypt.
Reiserfs can't find filesystem. Recreate crypt and try again...
root@localhost steph # cryptsetup remove mycrypt root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3 Enter passphrase: root@localhost steph # mount /dev/mapper/mycrypt cryptmount mount: you must specify the filesystem type root@localhost steph # resize_reiserfs /dev/mapper/mycrypt resize_reiserfs 3.6.19 (2003 www.namesys.com) reiserfs_open: the reiserfs superblock cannot be found on /dev/mapper/mycrypt.
Filesystem lost. Resizing /dev/loop3 while active is a desctructive action.
Conclusion
Can't find any discernible changes made by 'cryptsetup resize'. Can't find way of resizing block device without recreateing loop hence recreating crypt (and we already know that resizing via this method already works). Must assume that 'cryptsetup resize' applies to block devices that can change size whilst being mapped. Perhaps partitions rather than files?