Resizing Encrypted Filesystems

Posted by dkg on Tue 26 Jun 2007 at 14:13

Yes! You can grow an encrypted partition, as long as the size of the underlying block device grows first. If you have an ext3 filesystem on the encrypted partition, you can even grow the (encrypted) filesystem without unmounting it. This article gives a brief overview of how it is done.

I recommend reading the man pages for the commands used here. They are all quite good.

Below is a full transcript of creating and resizing an encrypted filesystem with a test setup. I don't include any RAID (mdadm) here, because that would all happen way before you even get to this step, since RAID devices are usually used as physical volumes to feed into an LVM Volume Group. The process below is basically two phases:

Phase 0 (Setup)

  1. Create a logical volume (just a block device, no filesystem yet)
  2. Overlay it with strong encryption (using LUKS)
  3. Create a filesystem on top of the encrypted device
  4. Mount the filesystem, and put some data into its tree

(and no, that's not my real passphrase; this is an experiment!)

[0 root@monkey ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree 
  monkey0   1   9   0 wz--n- 54.49G 20.49G
[0 root@monkey ~]# lvcreate --name=testy --size=50M monkey0
  Rounding up size to full physical extent 52.00 MB
  Logical volume "testy" created
[0 root@monkey ~]# cryptsetup luksFormat /dev/mapper/monkey0-testy

WARNING!
========
This will overwrite data on /dev/mapper/monkey0-testy irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: abc123
Verify passphrase: abc123
Command successful.
[0 root@monkey ~]# cryptsetup luksOpen /dev/mapper/monkey0-testy testy_crypt
Enter LUKS passphrase: abc123

key slot 0 unlocked.
Command successful.
[0 root@monkey ~]# mkfs -t ext3 -q /dev/mapper/testy_crypt
[0 root@monkey ~]# mount /dev/mapper/testy_crypt /mnt
[0 root@monkey ~]# dd if=/dev/zero of=/mnt/zeroes bs=1k count=1k
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.0200926 seconds, 52.2 MB/s
[0 root@monkey ~]# df -h /mnt
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/testy_crypt
                       50M  5.9M   42M  13% /mnt
[0 root@monkey ~]# 

Phase 1 (Resizing)

  1. Grow the logical volume with lvresize
  2. Ask the cryptsetup subsystem to acknowledge the new size
  3. Grow the filesystem on top of the newly bigger encrypted device
  4. Look to see how much more space you've got!

In the transcript below, it's interesting to watch how the kernel's representation of the underlying block devices change in size. You can see this by grepping the content of /proc/partitions, which i've done during these steps to demonstrate:

[0 root@monkey ~]# lvs | grep testy
  testy        monkey0 -wi-ao 52.00M                              
[0 root@monkey ~]# ls -la /dev/mapper/monkey0-testy /dev/mapper/testy_crypt
brw-rw---- 1 root disk 253, 14 2007-06-06 00:10 /dev/mapper/monkey0-testy
brw-rw---- 1 root disk 253, 15 2007-06-06 00:10 /dev/mapper/testy_crypt
[0 root@monkey ~]# grep '^\s*253\s*1[45]\s' /proc/partitions
 253    14      53248 dm-14
 253    15      52732 dm-15

[0 root@monkey ~]# lvresize --size=150M monkey0/testy
  Rounding up size to full physical extent 152.00 MB
  Extending logical volume testy to 152.00 MB
  Logical volume testy successfully resized
[0 root@monkey ~]# grep '^\s*253\s*1[45]\s' /proc/partitions
 253    14     155648 dm-14
 253    15      52732 dm-15
[0 root@monkey ~]# cryptsetup resize testy_crypt
[0 root@monkey ~]# grep '^\s*253\s*1[45]\s' /proc/partitions
 253    14     155648 dm-14
 253    15     155132 dm-15

[0 root@monkey ~]# df -h /mnt
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/testy_crypt
                       50M  5.9M   42M  13% /mnt
[0 root@monkey ~]# resize2fs /dev/mapper/testy_crypt
resize2fs 1.40-WIP (14-Nov-2006)
Filesystem at /dev/mapper/testy_crypt is mounted on /mnt; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/mapper/testy_crypt to 155132 (1k) blocks.
The filesystem on /dev/mapper/testy_crypt is now 155132 blocks long.

[0 root@monkey ~]# df -h /mnt
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/testy_crypt
                      148M  6.3M  134M   5% /mnt
[0 root@monkey ~]# ls -la /mnt/
total 1046
drwxr-xr-x  3 root root    1024 2007-06-06 00:12 .
drwxr-xr-x 21 root root    4096 2007-02-27 20:08 ..
drwx------  2 root root   12288 2007-06-06 00:10 lost+found
-rw-r--r--  1 root root 1048576 2007-06-06 00:12 zeroes
[0 root@monkey ~]# 

Software versions

Here are the versions of the software used on monkey at the time i made this test, fwiw:

[0 dkg@monkey ~]$ uname -a
Linux monkey 2.6.18-4-686 #1 SMP Mon Mar 26 17:17:36 UTC 2007 i686 GNU/Linux
[0 dkg@monkey ~]$ dpkg -l e2fsprogs lvm2 cryptsetup

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name        Version                           Description
+++-===========-=================================-=========================================
ii  cryptsetup  1.0.4+svn26-1                     configures encrypted block devices
ii  e2fsprogs   1.39+1.40-WIP-2006.11.14+dfsg-2   ext2 file system utilities and libraries
ii  lvm2        2.02.06-4                         The Linux Logical Volume Manager
[0 dkg@monkey ~]$ 

Cleanup the experiment

And since no example is responsibly complete without the cleanup phase, here it is (note that this cleanup makes it nearly impossible to recover data from the filesystem so removed, particularly if you've forgotten the LUKS passphrase):

[0 root@monkey ~]# umount /mnt
[0 root@monkey ~]# cryptsetup luksClose testy_crypt

[0 root@monkey ~]# lvremove monkey0/testy
Do you really want to remove active logical volume "testy"? [y/n]: y
  Logical volume "testy" successfully removed
[0 root@monkey ~]# 

I hope this is useful!

 

 


Posted by Anonymous (194.51.xx.xx) on Tue 16 Oct 2007 at 16:32
Thx for the article, it will be really useful as soon as I will buy my new laptop ;)

[ Parent | Reply to this comment ]

Posted by Anonymous (213.129.xx.xx) on Thu 1 Nov 2007 at 09:00
Very useful!

[ Parent | Reply to this comment ]

Posted by Anonymous (24.203.xx.xx) on Sun 11 Nov 2007 at 22:58
Before reading this tutorial, I already resized an encrypted filesystem (over mdadm instead of LVM). I was using JFS and cryptsetup-luks. All the steps were basically the same, but I didn't explicitely told dm-crypt to resize the device. I didn't do the "cryptsetup resize <name-of-device>". All I did was :

# grow raid array (raid1 with sda1 sdb1)
mdadm /dev/md0 --grow --size=max
# JFS resize
mount -o remount,resize /mnt/my_jfs_filesystem

It worked great nonetheless :
~# cat /proc/partitions
major minor #blocks name

8 1 488384001 sda1
8 17 488384001 sdb1
9 0 488383936 md0
253 0 488383420 dm-0

[ Parent | Reply to this comment ]

Posted by jamiemcc (166.84.xx.xx) on Mon 7 Jan 2008 at 00:29
[ Send Message ]
This was great - worked like a charm!

[ Parent | Reply to this comment ]

Posted by Anonymous (85.126.xx.xx) on Mon 24 Mar 2008 at 15:16
Thanks a lot!
I might have figured it out myself, but that saved me some time. Also it's nice to *know* that it'll work beforehand.

[ Parent | Reply to this comment ]

Posted by Anonymous (91.122.xx.xx) on Fri 2 May 2008 at 10:14
Clear and to the point, thanks.

[ Parent | Reply to this comment ]

Posted by Anonymous (84.119.xx.xx) on Sat 19 Jul 2008 at 17:30
can you shrink it too?

[ Parent | Reply to this comment ]

Posted by dkg (216.254.xx.xx) on Mon 21 Jul 2008 at 02:38
[ Send Message | View dkg's Scratchpad | View Weblogs ]
I haven't tried, but i don't think that resize2fs actually supports shrinking online (i.e. mounted) filesystems. But i think you could do it cleanly if you were able to unmount the filesystem first.

[ Parent | Reply to this comment ]

Posted by diegobelotti (151.38.xx.xx) on Mon 11 Aug 2008 at 11:07
[ Send Message ]
I've tryed shrinking without success (not yet on Debian to be sincere, but the versions of the packages are the same): I confirm you must unmount before resize, but the filesystem check always fail.
[root@localhost ~]# cryptsetup resize testy_crypt 
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/mapper/testy_crypt is mounted on /mnt; on-line resizing required
On-line shrinking from 212863 to 139135 not supported.
[root@localhost ~]# umount /dev/mapper/testy_crypt 
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 
resize2fs 1.39 (29-May-2006)
Please run 'e2fsck -f /dev/mapper/testy_crypt' first.

[root@localhost ~]# e2fsck -f /dev/mapper/testy_crypt
e2fsck 1.39 (29-May-2006)
The filesystem size (according to the superblock) is 212863 blocks
The physical size of the device is 139135 blocks
Either the superblock or the partition table is likely to be corrupt!
Abort? no

Pass 1: Checking inodes, blocks, and sizes
Error reading block 163877 (Invalid argument) while doing inode scan.  Ignore error? no

Error while scanning inodes (69600): Can't read next inode
e2fsck: aborted
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 
resize2fs 1.39 (29-May-2006)
Please run 'e2fsck -f /dev/mapper/testy_crypt' first.

[root@localhost ~]# e2fsck -f /dev/mapper/testy_crypt
e2fsck 1.39 (29-May-2006)
The filesystem size (according to the superblock) is 212863 blocks
The physical size of the device is 139135 blocks
Either the superblock or the partition table is likely to be corrupt!
Abort? no

Pass 1: Checking inodes, blocks, and sizes
Error reading block 163877 (Invalid argument) while doing inode scan.  Ignore error? no

Error while scanning inodes (69600): Can't read next inode
e2fsck: aborted
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 
resize2fs 1.39 (29-May-2006)
Please run 'e2fsck -f /dev/mapper/testy_crypt' first.
Any ideas?

[ Parent | Reply to this comment ]

Posted by dkg (216.254.xx.xx) on Mon 11 Aug 2008 at 15:07
[ Send Message | View dkg's Scratchpad | View Weblogs ]
For shrinking, i think you want to take the steps in the opposite order from growing.

That is, for shrinking a filesystem, you'll want to:

  1. resize2fs
  2. cryptsetup resize
  3. lvresize
The reason for this is because if you truncate the block device first, then the data at the end of the filesystem is already lost (which is why yer fsck is failing).

If you try it that way, does it work for you?

[ Parent | Reply to this comment ]

Posted by diegobelotti (151.38.xx.xx) on Mon 11 Aug 2008 at 16:02
[ Send Message ]
Thanks Daniel! It work this way. To avoid mistakes with the rounding of the dimension made by the different tools, I've
  • resized the fs from 1Gb to 100Mb
  • resized the crypted fs accordingly
  • resized the partition from 1Gb to 150Mb (so a bigger value than the fs)
  • resized the crypted fs
  • resized the fs automatically up to the new partition size
and everything seems to be ok... This is the copy paste from terminal:
[root@localhost ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-rt
                      4.8G  2.7G  1.9G  60% /
/dev/md0               99M   25M   70M  27% /boot
tmpfs                 187M     0  187M   0% /dev/shm
/dev/mapper/testy_crypt
                     1010M   17M  954M   2% /mnt
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 100M
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/mapper/testy_crypt is mounted on /mnt; on-line resizing required
On-line shrinking from 262015 to 25600 not supported.
[root@localhost ~]# umount /dev/mapper/testy_crypt
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 100M
resize2fs 1.39 (29-May-2006)
Please run 'e2fsck -f /dev/mapper/testy_crypt' first.

[root@localhost ~]# e2fsck -f /dev/mapper/testy_crypt
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/testy_crypt: 17/111360 files (5.9% non-contiguous), 7800/262015 blocks
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 100M
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/mapper/testy_crypt to 25600 (4k) blocks.
The filesystem on /dev/mapper/testy_crypt is now 25600 blocks long.

[root@localhost ~]# cryptsetup resize testy_crypt
[root@localhost ~]# lvresize /dev/VolGroup00/crypt -L 150M
  Rounding up size to full physical extent 160.00 MB
  WARNING: Reducing active and open logical volume to 160.00 MB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce testy? [y/n]: y
  Reducing logical volume testy to 160.00 MB
  Logical volume testy successfully resized
[root@localhost ~]# cryptsetup resize testy_crypt
[root@localhost ~]# resize2fs /dev/mapper/testy_crypt 
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/mapper/testy_crypt to 40831 (4k) blocks.
The filesystem on /dev/mapper/testy_crypt is now 40831 blocks long.

[root@localhost ~]# lvs
  LV    VG         Attr   LSize   Origin Snap%  Move Log Copy%  Convert
  testy VolGroup00 -wi-ao 160.00M                                      
  rt    VolGroup00 -wi-ao   4.88G                                      
  swp   VolGroup00 -wi-ao 992.00M                                      
[root@localhost ~]# mount /dev/mapper/testy_crypt /mnt
[root@localhost ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-rt
                      4.8G  2.7G  1.9G  60% /
/dev/md0               99M   25M   70M  27% /boot
tmpfs                 187M     0  187M   0% /dev/shm
/dev/mapper/testy_crypt
                      157M   17M  135M  11% /mnt
[root@localhost ~]# ls -l /mnt
total 100
-rwxr-xr-x 1 root root  1310 Aug 11 20:25 anaconda-ks.cfg
-rw-r--r-- 1 root root 14157 Aug 11 20:25 asdasdasdasd.txt
-rwxr-xr-x 1 root root 22287 Aug 11 20:25 install.log
-rwxr-xr-x 1 root root  4037 Aug 11 20:25 install.log.syslog
drwx------ 2 root root 16384 Aug 11 16:28 lost+found
-rw-r--r-- 1 root root 14157 Aug 11 20:25 test.txt

[ Parent | Reply to this comment ]

Posted by Anonymous (87.89.xx.xx) on Thu 26 Nov 2009 at 23:59
(this is a warning to readers to come, as the parent message is more than 1 year old)
Be careful with the units you use, when you specify "100M", it does not always have the same meaning across tools, it can either refer to "megabytes" (1000 kilobytes) or "mebibytes" (1024 kibibytes) (read wikipedia about this).
I urge you to check which meaning has each tool by reading the manpages (for LVM tools, it's in the pvs(1) manpage, and it's all about the case of the character)

[ Parent | Reply to this comment ]

Posted by Anonymous (132.252.xx.xx) on Wed 13 Jan 2010 at 21:08
I don't think
# cryptsetup resize testy_crypt
will shrink the the luks device. I think it will enlarge it to the maximum possible size. You have to use the "--size" option and specify the new number of sectors. Doing it as you did will leave the luks device larger than the logical volume under it.

[ Parent | Reply to this comment ]

Posted by Anonymous (2001:0xx:0xx:0xxx:0xxx:0xxx:xx) on Mon 10 May 2010 at 22:46
First of, from the manpage, "If --size (in sectors) is not specified, the size of the underlying block device is used." 'underlying' is a big ambiguous. So do, or don't you need --size when shrinking the device? How do you know how much sectors are being used by the resized filesystem?

Also, do you need to take metadata overhead into account? In other words, if I use resize2fs to resize a 1T partition to 500 gigabytes, can I simply type "cryptsetup resize --size <500G of sectors> <diskname>", or do I need to take overhead into account?

[ Parent | Reply to this comment ]

Posted by voidzero (2001:0xx:0xx:0xxx:0xxx:0xxx:xx) on Mon 10 May 2010 at 22:50
[ Send Message ]
(subscribing for reactions)

[ Parent | Reply to this comment ]

Posted by voidzero (2001:0xx:0xx:0xxx:0xxx:0xxx:xx) on Mon 10 May 2010 at 22:55
[ Send Message ]
Oh. to quote another site (http://osdir.com/ml/linux.kernel.device-mapper.dm-crypt/2004-05/m sg00003.html)

I don't think you have to resize, unless you cannot remove. 'resize' is for devices that are actively mapped. For others 'create' will just create larger/smaller, if the size of the device has changed.

If I am correct, for a block-device that has changed its size while being mapped, just call

cryptsetup resize $device

[ Parent | Reply to this comment ]

Posted by dkg (216.254.xx.xx) on Mon 19 Jul 2010 at 19:58
[ Send Message | View dkg's Scratchpad | View Weblogs ]
I don't think "underlying" is ambiguous in this context, actually.

cryptsetup takes an existing block device, and produces (via the device-mapper) a new block device. The "underlying block device" is the input to this process (even if it was itself created by the device mapper and has yet another underlying block device beneath it in the stack).

As for the metadata, are you talking about filesystem metadata or LVM or LUKS metadata? If you're talking about LVM or LUKS metadata, that's all metadata that eventually gets fed in one form or another to the device mapper. Each dm-exported block device has a size that does not reflect any metadata. That is, when the device-mapper offers a block device, nothing you write into that block device should be directly possible to screw up the metadata that defines that block device.

[ Parent | Reply to this comment ]

Posted by Anonymous (76.103.xx.xx) on Sun 24 Aug 2008 at 23:35
Very good! I was experimenting with LUKS over LVM setup and needed to extend an JFS partition. Obviously, standard LVM practice didn't work and I had no clue how to proceed further.

Your article about cryptsetup resize was a day saver. Thanks!

[ Parent | Reply to this comment ]

Posted by Anonymous (98.110.xx.xx) on Mon 4 Jul 2011 at 01:29
Thanks. This worked perfectly.

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

Which init system are you using in Debian?






( 1626 votes ~ 7 comments )