Skip to content

Instantly share code, notes, and snippets.

@awilkins
Created May 8, 2015 15:39
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awilkins/20e421edee35504ca35f to your computer and use it in GitHub Desktop.
Save awilkins/20e421edee35504ca35f to your computer and use it in GitHub Desktop.
Script to add an encrypted SSD cache to Ubuntu install using dm-cache and LUKS
#!/bin/bash
# Add an LVM cache pool on and attach it to the root volume
# Including LUKS encryption
# Assumes you are using an "all on root" setup
# If you are not, adapt it if you like
#
# Script licensed GPL3 or later
# © Adrian Wilkins May 2015
# Pass the name of the disk device you are using as a cache
# This should ideally be totally blank, so run
#
# dd if=/dev/zero of=/dev/${DISK}
#
# over it for a short while to nuke the partition table
CACHE_DISK=$1
META_SIZE=$2
DATA_SIZE=$3
DISK_NAME=$(basename $CACHE_DISK)
# Define the sizes of the metadata and data sections
# These should add up to nearly the full size of your physical disk
CRYPT_VOLUME=${DISK_NAME}_crypt
CACHE_PV=/dev/mapper/${CRYPT_VOLUME}
cryptsetup luksFormat $CACHE_DISK
cryptsetup open --type luks $CACHE_DISK $CRYPT_VOLUME
# Started to try and work out disk size stuff but it's complex
# DISK_SIZE=$(fdisk -l | grep "Disk ${CACHE_DISK}" | awk ' { print $5 } ')
#
# META_SIZE=$(( DISK_SIZE / 1000 ))
# META_SIZE=$(( META_SIZE + 512 ))
# MOD=$(( META_SIZE % 512 ))
# MOD_OFFSET=$((512 - MOD))
# META_SIZE=$((META_SIZE + 512))
# META_SIZE=$((META_SIZE + MOD_OFFSET))
#
# DATA_SIZE=$(( DISK_SIZE - META_SIZE))
#
pvcreate $CACHE_PV
vgextend ubuntu-vg $CACHE_PV
lvcreate -L ${META_SIZE} -n cachemeta ubuntu-vg $CACHE_PV
lvcreate -L ${DATA_SIZE} -n cachedata ubuntu-vg $CACHE_PV
lvconvert --type cache-pool --poolmetadata ubuntu-vg/cachemeta --cachemode writethrough ubuntu-vg/cachedata --yes
lvconvert --type cache --cachepool ubuntu-vg/cachedata ubuntu-vg/root
# Now add the UUID of the cache pool PHYSICAL DRIVE (/dev/sdb) to /etc/crypttab
# so it can be mounted
DISK_UUID=$(ls -al /dev/disk/by-uuid/ | grep $DISK_NAME | awk '{ print $9 }')
echo "${CRYPT_VOLUME} UUID=${DISK_UUID} none luks,discard" >> /etc/crypttab
apt-get install --yes thin-provisioning-tools
HOOK=$(tempfile)
# Insert a hook so that initramfs correctly includes the right tools for dm-cache
echo "#!/bin/sh" > $HOOK
echo "PREREQ="lvm2"" >> $HOOK
echo "prereqs()" >> $HOOK
echo "{" >> $HOOK
echo " echo \"$PREREQ\"" >> $HOOK
echo "}" >> $HOOK
echo "case $1 in" >> $HOOK
echo "prereqs)" >> $HOOK
echo " prereqs" >> $HOOK
echo " exit 0" >> $HOOK
echo " ;;" >> $HOOK
echo "esac" >> $HOOK
echo "if [ ! -x /usr/sbin/cache_check ]; then" >> $HOOK
echo " exit 0" >> $HOOK
echo "fi" >> $HOOK
echo ". /usr/share/initramfs-tools/hook-functions" >> $HOOK
echo "copy_exec /usr/sbin/cache_check" >> $HOOK
echo "manual_add_modules dm_cache dm_cache_mq dm_persistent_data dm_bufio" >> $HOOK
cp $HOOK /etc/initramfs-tools/hooks/lvmcache
chmod +x /etc/initramfs-tools/hooks/lvmcache
echo "dm_cache" >> /etc/initramfs-tools/modules
echo "dm_cache_mq" >> /etc/initramfs-tools/modules
echo "dm_persistent_data" >> /etc/initramfs-tools/modules
echo "dm_bufio" >> /etc/initramfs-tools/modules
update-initramfs -u
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment