How to check if TRIM is working for an encrypted volume?
Solution 1
There is a way to test it answered at unix.stackexchange.com by frostschutz (this answer is his merit so thanks him), copied below:
"Create a test file: (not random on purpose)
# yes | dd iflag=fullblock bs=1M count=1 of=trim.test
Get the address: (exact command may have to differ depending on filefrag
version)
# filefrag -s -v trim.test
File size of trim.test is 1048576 (256 blocks, blocksize 4096)
ext logical physical expected length flags
0 0 34048 256 eof
trim.test: 1 extent found
Get the device:
# df trim.test
/dev/mapper/something 32896880 11722824 20838512 37% /
With this set up, you have a file trim.test
filles with yes
-pattern on /dev/mapper/something
at address 34048
with length of 256
blocks of 4096
bytes.
Reading that from the device directly should produce the yes
-pattern:
# dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.|
*
00100000
If TRIM is enabled, this pattern should change when you delete the file. Note that caches need to be dropped also, otherwise dd
will not re-read the data from disk.
# rm trim.test
# sync
# fstrim -v /mount/point/ # when not using 'discard' mount option
# echo 1 > /proc/sys/vm/drop_caches
# dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C
On most SSD that would result in a zero pattern:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00100000
If encryption is involved, you will see a random pattern instead:
00000000 1f c9 55 7d 07 15 00 d1 4a 1c 41 1a 43 84 15 c0 |..U}....J.A.C...|
00000010 24 35 37 fe 05 f7 43 93 1e f4 3c cc d8 83 44 ad |$57...C...<...D.|
00000020 46 80 c2 26 13 06 dc 20 7e 22 e4 94 21 7c 8b 2c |F..&... ~"..!|.,|
That's because physically trimmed, the crypto layer reads zeroes and decrypts those zeroes to "random" data.
If the yes
-pattern persists, most likely no trimming has been done."
This is my automated script:
#!/bin/bash # # This script is provided "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement. # # License GPL2 # # by desgua 2014/04/29 function CLEAN { cd "$pasta" [ -f test-trim-by-desgua ] && rm test-trim-by-desgua && echo "Temp file removed" echo "Goodbye" exit 0 } trap 'echo ; echo "Aborted." ; CLEAN; echo ; exit 0' INT HUP if [[ "$(echo $USER)" != "root" ]]; then read -n 1 -p 'Become root? [Y/n]' a if [[ $a == "Y" || $a == "y" || $a == "" ]]; then sudo $0 $1 exit 0 else echo " This script needs root privilege. " exit 1 fi fi name=$(echo $0 | sed 's/.*\///') if [ $# -ne 1 ]; then echo " Usage: $name /folder/to/test/ " exit 1 fi pasta=$1 read -n 1 -p 'Use fstrim? [y/N]' a if [[ $a == "Y" || $a == "y" ]]; then fs=1 fi method= while [[ "$method" != "1" && "$method" != "2" ]]; do read -n 1 -s -p 'Choose a method: [1] hdparm (will fail in LUKS on LVM) [2] filefrag (warning: you may have to force quit - close the terminal - in some cases of success trim if you see an output that never ends) ' method done function SDATEST { disk=$(fdisk -l | grep /dev/sda) if [ "$disk" == "" ]; then echo " fdisk did not found /dev/sda " exit 1 fi } function TEST { echo "Entrying /" ; echo cd $pasta echo "Creating the file test-trim-by-desgua at $pasta" ; echo dd if=/dev/urandom of=test-trim-by-desgua count=10 bs=512k echo "Syncing and sleeping 2 seconds." ; echo sync sleep 2 hdparm --fibmap test-trim-by-desgua lbab=$(hdparm --fibmap test-trim-by-desgua | tail -n1 | awk '{ print $2 }') echo "As you can see, the file was created and its LBA begins at $lbab" ; echo echo "Syncing and sleeping 2 seconds." ; echo sync sleep 2 echo "Removing file test-trim-by-desgua" ; echo rm test-trim-by-desgua trap 'echo ; echo ; echo "Aborted." ; echo ; exit 0' INT echo "Syncing and sleeping 2 seconds." ; echo sync sleep 2 if [[ "$fs" == "1" ]]; then echo "fstrim $pasta && sleep 2" ; echo fstrim $pasta sleep 2 fi echo "This is readed from sector $lbab: " hdparm --read-sector $lbab /dev/sda pass=$(hdparm --read-sector $lbab /dev/sda | grep "0000 0000 0000 0000") if [[ $pass == "" ]]; then echo " Trim failed... You should see only 0000 0000 0000 0000 ... " else echo "Success!!!" fi exit 0 } function LUKSTEST { # Reference: https://unix.stackexchange.com/questions/85865/trim-with-lvm-and-dm-crypt# echo 1 > /proc/sys/vm/drop_caches cd $pasta echo "Creating a \"yes\" file." yes | dd iflag=fullblock bs=1M count=1 of=test-trim-by-desgua #position=`filefrag -s -v test-trim-by-desgua | grep "eof" | awk '{ print $3 }'` position=`filefrag -s -v test-trim-by-desgua | grep "eof" | sed 's| ||g ; s|.*255:|| ; s|\.\..*||'` [[ "$position" == "" ]] && echo "Could not find the position of the file. Are you on a LUKS on LVM?" && CLEAN; device=`df test-trim-by-desgua | grep "dev/" | awk '{ print $1 }'` yes=`dd bs=4096 skip=$position count=256 if=$device | hexdump -C` echo "In the next line you should see a pattern like: 00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.| $yes " if [[ "`echo "$yes" | grep "y.y.y"`" == "" ]]; then echo "The pattern could not be checked. Something went wrong. Exiting." CLEAN; else echo "Pattern confirmed." fi echo "Removing the temp file." rm test-trim-by-desgua echo "Syncing." sync sleep 1 if [[ "$fs" == "1" ]]; then echo "fstrim -v $pasta && sleep 2" ; echo fstrim -v $pasta sleep 2 fi # Drop cache echo 1 > /proc/sys/vm/drop_caches echo "In the next line you should **NOT** see a yes pattern like: 00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.| If you see, then trim is not working: `dd bs=4096 skip=$position count=256 if=$device | hexdump -C`" yes=`dd bs=4096 skip=$position count=256 if=$device | hexdump -C` if [[ "`echo "$yes" | grep "y.y.y"`" != "" ]]; then echo "TRIM not working." else echo "TRIM is working!" fi CLEAN; } if [[ "$method" == "1" ]]; then SDATEST; TEST; elif [[ "$method" == "2" ]]; then LUKSTEST; fi exit 0
Solution 2
I don't have dm-crypt with TRIM setup yet, but I'm also interested in verifying this. First it should be said that this might not be possible, depending on your SSD (see: https://serverfault.com/a/401506/60525).
Assuming you have the right kind of SSD, I see a couple different options:
Test this on a very small block device. Create a 20Mb encrypted partition just as you would for your whole system. Make sure to first fill the partition with random bytes. Then create, write, flush, and delete a 10Mb file on the encrypted fs. Run fstrim on the mounted fs. If everything is working, you should see about half the 20Mb partition filled with zero bytes.
-
Alternatively you could verify that either the UNMAP or WRITE SAME scsi command is being issued through the scsi subsystem. The only way that I found to see the scsi packets without using a hardware device or hacking the kernel was to turn on logging of scsi packets:
echo $BITMASK > /sys/module/scsi_mod/parameters/scsi_logging_level
Using 9216 as the BITMASK was enough for me to see WRITE SAME cdbs being send after an fstrim of an ext4 fs residing directly on disk (no encryption).
You could use either fstrim at the fs level or sg_unmap/sg_write_same at the device level to trigger a TRIM. Once you find either UNMAP or WRITE SAME, use the scsi docs at t10.org to decode the packet and figure out what disk block its referring to. Then check that the disk has all zeroes at that sector(s).
The latter approach is more arduous, but it has the advantage of working on pre-existing installs and is much easier when working with non-trivially sized filesystems. You may find it sufficient to see the UNMAP or WRITE SAME command being sent (do you really care if there are zeros or not?) Note that the latter approach will likely not work if the TRIM is done via the ata DATA SET MANAGEMENT command, it shouldn't show up in the scsi log and I see not way to get ata cdbs. But I'd bet that's less than .01% of the cases.
The latter solution could be some what automated, that way we wouldn't have to decode the packet by hand. Any takers?
And as far as I now there's no way to get a mapping of encrypted block address to device block address without hacking dm-crypt.c So if you're looking to see that the blocks of a deleted file on a trimmed fs on the encrypted block device map to zero sectors on the device, you're in for a world of pain.
Solution 3
This was answered in the question you linked.
If you are using LVM, you need to add discard
to the options in /etc/fstab
Open /etc/fstab
with any editor
# Command line
sudo -e /etc/fstab
# Graphical
gksu gedit /etc/fstab
Add in "discard" to the options in the 4th column.
/dev/mapper/volumegroup-root / ext4 discard,noatime,nodiratime,errors=remount-ro 0 1
You then add in the same option (discard) to /etc/crypttab
Assuming your LUKS partition is /dev/sda1
(adjust accordingly)
# Command line
sudo -e /etc/crypttab
# Graphical
gksu gedit /etc/crypttab
Again, add in discard:
sda1_crypt UUID=[... series of numbers ...] none luks,discard
Update your initramfs
sudo update-initramfs -c -k all
Reboot
Confirm TRIM is working ...
sudo dmsetup table /dev/mapper/sda1_crypt --showkeys
You should see "allow_discards" in the output
For additional information, see : http://worldsmostsecret.blogspot.com/2012/04/how-to-activate-trim-on-luks-encrypted.html
Related videos on Youtube
Pawel K
Updated on September 18, 2022Comments
-
Pawel K over 1 year
You can easily check if TRIM works for a "normal" ext4 partition: https://askubuntu.com/a/19480/5920.
How to do that for a LUKS-encrypted one? Let's assume the default LUKS setup made by 12.04 Alternate installer (i.e. the one with LVM involved).
Update
What I'm asking here is how I can check that the block on the disk is actually filled with zeros after removing the file, if the file is stored in an encrypted volume.
-
Pawel K almost 12 yearsThanks for the answers, but I meant a different thing in my question, sorry for the lack of clarification. Check my updated question. FYI
sudo dmsetup table /dev/mapper/sda1_crypt --showkeys
returnsallow_discards
, but I'd like to check if the disk is actually TRIM-ed. -
Pawel K almost 12 yearsWell, it works. But I'd like to see those zeros myself :)
-
Pawel K over 11 yearsInteresting ideas! I'll try them when I have some time to spend :)