Linux clone encrypted drive to smaller drive

Solution 1:

I'm going to answer the question myself, but a general note: Maybe its fastest just to start from scratch, the steps are complicated and timeconsuming!

  • Make Backup using your favourite disk cloning/backup tool
  • Follow the Ubuntu Wiki Article about ResizeEncryptedPartions
  • Make sure the partitions matches exactly the size of your smaller disk (so the free space after the last partition is unallocated)
  • clone your disk using dd until that exact size

Detailed

  • /dev/sda is my current disk I want to shrink
  • /dev/sdb is my new disk
  • Use your exact values for your disk sizes, block sizes and so on, my calculations are only a little clue how I did it.
  • be careful with the options parameter (e.g. b sometimes means bytes, sometimes means blocks and so on). Always check man-page first.
  • Check the linked article above for some additional informations about sensible steps

Boot livecd, load modules, decrypt your disk, discover partitions:

sudo modprobe dm-crypt
sudo cryptsetup luksOpen /dev/sda5 crypt1
sudo vgscan --mknodes
sudo vgchange -ay

print out your current partition layout with sizes in bytes:

ubuntu@ubuntu:~$ lsblk -b

NAME                               MAJ:MIN RM         SIZE RO TYPE  MOUNTPOINT
sda                                  8:0    0 250059350016  0 disk 
├─sda1                               8:1    0    254803968  0 part 
├─sda2                               8:2    0         1024  0 part 
└─sda5                               8:5    0 249802260480  0 part 
  └─crypt1 (dm-0)                  252:0    0 249800163328  0 crypt
    ├─elementary--vg-root (dm-1)   252:1    0 247757537280  0 lvm  
    └─elementary--vg-swap_1 (dm-2) 252:2    0   2038431744  0 lvm  
sdb                                  8:16   0 120034123776  0 disk 
└─sdb1                               8:17   0 120034091520  0 part  /media/ubuntu/ff08402

We need to know, which size the new root partition should have, we do some calculation:

find how much space is used without root:
  250059350016
- 247757537280
=   2301812736

calculate new wished size from the new disk:
  120034123776
-   2301812736
= 117732311040

Since we can specify it only in kibibytes, we divide it by 1024
  117732311040
/         1024
=    114972960

Resize your partition using resize2fs (I'm having ext4):

sudo resize2fs -p /dev/mapper/elementary--vg-root 114972960k

Set the logical volume to the calculated size:

sudo lvreduce -L 114972960k /dev/mapper/elementary--vg-root

Print the new partition setup, we need some values from there:

ubuntu@ubuntu:~$ lsblk -b
NAME                               MAJ:MIN RM         SIZE RO TYPE  MOUNTPOINT
sda                                  8:0    0 250059350016  0 disk 
├─sda1                               8:1    0    254803968  0 part 
├─sda2                               8:2    0         1024  0 part 
└─sda5                               8:5    0 249802260480  0 part 
  └─crypt1 (dm-0)                  252:0    0 249800163328  0 crypt
    ├─elementary--vg-root (dm-1)   252:1    0 117734113280  0 lvm  
    └─elementary--vg-swap_1 (dm-2) 252:2    0   2038431744  0 lvm  
sdb                                  8:16   0 120034123776  0 disk 
└─sdb1                               8:17   0 120034091520  0 part  /media/ubuntu/ff08402

We need to know, which size the new crypt1 partition should have, we do some calculation:

Calculate difference between logical volume sizes and crypt1 (from before we made any changes):
    2038431744
+ 247757537280
= 249795969024

  249800163328
- 249795969024
=      4194304

calculate the new crypt1 size (with the new changes):
    2038431744
+ 117734113280
+      4194304
= 119776739328

later we need the crypt1 size in blocks:
  119776739328
/          512
=    233938944

Before we can reduce the crypt volume, check if volumes are in order:

ubuntu@ubuntu:~$ sudo pvs -v --segments /dev/mapper/crypt1
    Using physical volume(s) on command line
  PV                 VG            Fmt  Attr PSize   PFree   Start SSize LV     Start Type   PE Ranges                    
  /dev/mapper/crypt1 elementary-vg lvm2 a--  232.64g 121.09g     0 28070 root       0 linear /dev/mapper/crypt1:0-28069   
  /dev/mapper/crypt1 elementary-vg lvm2 a--  232.64g 121.09g 28070 31000            0 free                                
  /dev/mapper/crypt1 elementary-vg lvm2 a--  232.64g 121.09g 59070   486 swap_1     0 linear /dev/mapper/crypt1:59070-59555

No, they're not, so I needed to move swap to best free space (actually means to block 28070):

sudo pvmove --alloc anywhere /dev/mapper/crypt1:59070-59555

And recheck your allocation so the free space is in the end:

sudo pvs -v --segments /dev/mapper/crypt1

set the new volume size for crypt1

sudo pvresize --setphysicalvolumesize 119776739328b /dev/mapper/crypt1
sudo cryptsetup -b 233938944 resize crypt1

Continue with the partition table, for that unload the encrypted partition:

sudo vgchange -an
sudo cryptsetup luksClose crypt1

Print out and note somewhere your current partition table layout:

ubuntu@ubuntu:~$ sudo fdisk -l

Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders, total 488397168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00082d72

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      499711      248832   83  Linux
/dev/sda2          501758   488396799   243947521    5  Extended
/dev/sda5          501760   488396799   243947520   83  Linux

We need to know, which size the new partition table should have, we do some calculations again:

reverse engineering blocks setup from current /dev/sda:
     243947521
*         1024
-         1024
= 249802260480

size of other uses:
  250059350016
- 249802260480
=    257089536

size for the new disk:
  120034123776
-    257089536
= 119777034240

blocks for new disk:
  119777034240
+         1024
/         1024
=    116969761

calculating end sector with new size:
     488396799
+            1
-       501758
/            2
=    243947521

     116969761
*            2
+       501758
-            1
=    234441279

Now we can redefine the partition table with the new sizes:

ubuntu@ubuntu:~$ sudo fdisk /dev/sda

Command (m for help): d
Partition number (1-5): 5

Command (m for help): d
Partition number (1-5): 2

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): e
Partition number (1-4, default 2):
Using default value 2
First sector (499712-488397167, default 499712):
Using default value 499712
Last sector, +sectors or +size{K,M,G} (499712-488397167, default 488397167): 234441279

Command (m for help): n
Partition type:
   p   primary (1 primary, 1 extended, 2 free)
   l   logical (numbered from 5)
Select (default p): l
Adding logical partition 5
First sector (501760-234441279, default 501760):
Using default value 501760
Last sector, +sectors or +size{K,M,G} (501760-234441279, default 234441279):
Using default value 234441279

Command (m for help): p

Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders, total 488397168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00082d72

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      499711      248832   83  Linux
/dev/sda2          499712   234441279   116970784    5  Extended
/dev/sda5          501760   234441279   116969760   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Small Test: try to load the new encrypted volume (or reboot without livecd) and check if you can access data (If you cant, you made an error somewhere and need to restart using your backup):

sudo cryptsetup luksOpen /dev/sda5 crypt1
sudo vgscan --mknodes
sudo vgchange -ay

Check if your calculations were correct by comparing the end block with the block size of your smaller disk:

ubuntu@ubuntu:~$ sudo fdisk /dev/sda

Command (m for help): p

Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders, total 488397168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00082d72

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      499711      248832   83  Linux
/dev/sda2          499712   234441279   116970784    5  Extended
/dev/sda5          501760   234441279   116969760   83  Linux


ubuntu@ubuntu:~$ sudo fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders, total 234441648 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000f335e

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1              63   234441647   117220792+  83  Linux

recheck your calculations with the new partition table:

/dev/sda total - sda5 end-block (in the beginning):
  488397168
- 488396799
=       369

/dev/sdb total - sda5 end-block (after shrink):
  234441648
- 234441279
=       369

were good to go, exactly the size we want. so next step is to dd from 0 to 234441648 (= total size of /dev/sdb)

sudo dd if=/dev/sda of=/dev/sdb bs=1b count=234441648

And you're ready, shrink complete. This dd command will take some time and you don't see any output. In my case it ran around 6 hours.