如何检查TRIM是否适用于加密卷?

您可以轻松检查TRIM是否适用于“正常”ext4分区: https : //askubuntu.com/a/19480/5920 。

如何为LUKS加密的那个做? 假设由12.04备用安装程序(即涉及LVM的安装程序)进行默认的LUKS设置。

更新

我在这里要问的是,如果文件存储在加密卷中,我可以在删除文件后检查磁盘上的块实际上是否填充了零。

有一种方法可以通过frostschutz在unix.stackexchange.com上测试它的答案(这个答案是他的优点,所以感谢他),复制如下:

“创建一个测试文件:(不是故意的)

# yes | dd iflag=fullblock bs=1M count=1 of=trim.test 

获取地址:(确切的命令可能必须根据filefrag版本而有所不同)

 # 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 

获取设备:

 # df trim.test /dev/mapper/something 32896880 11722824 20838512 37% / 

通过这个设置,你有一个文件trim.test filles,在/dev/mapper/something ,地址为34048 ,长度为2564096字节。

直接从设备读取它应该产生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 |yyyyyyyy| * 00100000 

如果启用了TRIM,则删除文件时此模式应该会更改。 请注意,还需要删除缓存,否则dd将不会从磁盘重新读取数据。

 # 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 

在大多数SSD上会导致零模式:

 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00100000 

如果涉及加密,您将看到一个随机模式:

 00000000 1f c9 55 7d 07 15 00 d1 4a 1c 41 1a 43 84 15 c0 |..U}....JAC..| 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..&... ~"..!|.,| 

这是因为物理修剪,加密层读取零并将这些零解密为“随机”数据。

如果yes模式仍然存在,很可能没有完成修剪。“


这是我的自动脚本:

 #!/斌/庆典
 #
 #此脚本“按原样”提供,不附带任何明示或暗示的担保,包括但不限于适销性,适用于特定用途或不侵权的默示担保。
 #
 #License GPL2
 #
 #desgua 2014/04/29

functionCLEAN {
 cd“$ pasta”
 [-f test-trim-by-desgua] && rm test-trim-by-desgua && echo“Temp file removed removed”
回声“再见”
退出0
 }

陷阱'回声; 回声“中止。”  ; 清洁; 回声; 退出0'INT HUP

 if [[“$(echo $ USER)”!=“root”]]; 然后

读-n 1 -p'成为root?  [是/否]'a
    如果[[$ a ==“Y”||  $ a ==“y”||  $ a ==“”]]; 然后
         sudo $ 0 $ 1
        退出0
    其他
        回声“
        此脚本需要root权限。
         “
         1号出口

    科幻

科幻


 name = $(echo $ 0 | sed's /.*\///')
如果[$#-ne 1]; 然后

回声“
用法:$ name / folder / to / test /

 “
 1号出口
科幻

面食= $ 1

读-n 1 -p'使用fstrim?  [是/否]'a
如果[[$ a ==“Y”||  $ a ==“y”]]; 然后
     FS = 1
科幻

方法=
而[[“$ method”!=“1”&&“$ method”!=“2”]]; 做
 read -n 1 -s -p'选择一种方法:
 [1] hdparm(将在LVM上的LUKS中失败)
 [2] filefrag(警告:您可能必须强制退出 - 关闭终端 - 在某些情况下成功修剪,如果您看到输出永远不会结束) 
 ' 方法
 DONE

函数SDATEST {
 disk = $(fdisk -l | grep / dev / sda)
 if [“$ disk”==“”]; 然后
回声“
 fdisk没找到/ dev / sda 
 “
 1号出口
科幻
 }

function测试 {
 echo“Entrying /”; 回声
 cd $ pasta
 echo“在$ pasta创建文件test-trim-by-desgua”; 回声
 dd if = / dev / urandom of = test-trim-by-desgua count = 10 bs = 512k
回声“同步和睡眠2秒。”  ; 回声
同步
睡觉2

 hdparm --fibmap test-trim-by-desgua
 lbab = $(hdparm --fibmap test-trim-by-desgua | tail -n1 | awk'{print $ 2}')

 echo“正如你所看到的,文件已经创建,其LBA从$ lbab开始”; 回声

回声“同步和睡眠2秒。”  ; 回声
同步
睡觉2

 echo“删除文件test-trim-by-desgua”; 回声 
 rm test-trim-by-desgua

陷阱'回声; 回声; 回声“中止。”  ; 回声; 退出0'INT
回声“同步和睡眠2秒。”  ; 回声
同步
睡觉2

 if [[“$ fs”==“1”]]; 然后 
     echo“fstrim $ pasta && sleep 2”; 回声
     fstrim $ pasta
    睡觉2
科幻

回声“这是来自行业$ lbab:”
 hdparm --read-sector $ lbab / dev / sda

 pass = $(hdparm --read-sector $ lbab / dev / sda | grep“0000 0000 0000 0000”)

 if [[$ pass ==“”]]; 然后
    回声“
修剪失败了...... 
你应该只看到0000 0000 0000 0000 ......
 “
其他
    回声“成功!!!”
科幻
退出0

 }

函数LUKSTEST {
 #参考:https://unix.stackexchange.com/questions/85865/trim-with-lvm-and-dm-crypt#
 echo 1> / proc / sys / vm / drop_caches
 cd $ pasta
 echo“创建一个”是的“文件”。
是的|  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“无法找到文件的位置。你在LVM上的LUKS吗?”  && 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“在下一行你应该看到如下模式: 
 00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | yyyyyyyy |
 $是
 “

 if [[“`echo”$ yes“| grep”yyy“`”==“”]]; 然后 
     echo“无法检查模式。出了点问题。退出。”
    清洁;
其他
    回声“模式确认。”
科幻

 echo“删除临时文件”。 
 rm test-trim-by-desgua

回声“同步”。
同步
睡1

 if [[“$ fs”==“1”]]; 然后 
     echo“fstrim -v $ pasta && sleep 2”; 回声
     fstrim -v $ pasta
    睡觉2
科幻

 #Drop cache
 echo 1> / proc / sys / vm / drop_caches

回声“在下一行你应该**不**看到是这样的模式: 
 00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | yyyyyyyy | 
如果你看到,那么修剪不起作用:
 `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”yyy“`”!=“”]]; 然后 
    回应“TRIM不工作”。
其他
    回声“TRIM正在发挥作用!”
科幻
清洁;
 }

 if [[“$ method”==“1”]]; 然后
     SDATEST;
    测试;
 elif [[“$ method”==“2”]]; 然后
     LUKSTEST;
科幻
退出0

我还没有使用TRIM设置的dm-crypt,但我也有兴趣validation这一点。 首先应该说这可能是不可能的,这取决于你的SSD(参见: https : //serverfault.com/a/401506/60525 )。

假设您拥有合适的SSD,我会看到几种不同的选择:

  1. 在非常小的块设备上进行测试。 创建一个20Mb加密分区,就像整个系统一样。 确保首先使用随机字节填充分区。 然后在加密的fs上创建,写入,刷新和删除10Mb文件。 在已安装的fs上运行fstrim。 如果一切正常,你应该看到大约一半的20Mb分区填充零字节。

  2. 或者,您可以validation是否通过scsi子系统发出UNMAP或WRITE SAME scsi命令。 我发现在不使用硬件设备或黑客内核的情况下查看scsi数据包的唯一方法是打开scsi数据包的日志记录 :

    echo $ BITMASK> / sys / module / scsi_mod / parameters / scsi_logging_level

    使用9216作为BITMASK就足以让我看到在直接驻留在磁盘上的ext4 fs的fstrim(无加密)之后发送WRITE SAME cdbs。

    您可以在fs级别使用fstrim或在设备级别使用sg_unmap / sg_write_same来触发TRIM。 一旦找到UNMAP或WRITE SAME,请使用t10.org上的scsi文档对数据包进行解码并找出其引用的磁盘块。 然后检查磁盘在该扇区是否全部为零。

后一种方法更加艰巨,但它具有处理预先存在的安装的优点,并且在处理非平凡大小的文件系统时更容易。 你可能会发现发送UNMAP或WRITE SAME命令就足够了(你真的关心是否有零?)注意如果通过ata DATA SET MANAGEMENT命令完成TRIM,后一种方法可能不起作用,它不应该出现在scsi日志中,我看不到获取ata cdbs的方法。 但我敢打赌,这个案例不到0.01%。

后一种解决方案可能是一些自动化的方式,这样我们就不必手动解码数据包了。 任何接受者?

而就我而言,现在无法获取加密块地址到设备块地址的映射,而无需破解dm-crypt.c因此,如果您希望在加密的修剪fs上看到已删除文件的块阻止设备映射到设备上的零扇区,您将陷​​入痛苦的世界。

您在链接的问题中回答了这个问题。

如果您使用的是LVM,则需要将discard添加到/etc/fstab的选项

使用任何编辑器打开/etc/fstab

 # Command line sudo -e /etc/fstab # Graphical gksu gedit /etc/fstab 

将“discard”添加到第4列中的选项。

 /dev/mapper/volumegroup-root / ext4 discard,noatime,nodiratime,errors=remount-ro 0 1 

然后,您将相同的选项(discard)添加到/etc/crypttab

假设您的LUKS分区是/dev/sda1 (相应地调整)

 # Command line sudo -e /etc/crypttab # Graphical gksu gedit /etc/crypttab 

再次,添加丢弃:

 sda1_crypt UUID=[... series of numbers ...] none luks,discard 

更新您的initramfs

 sudo update-initramfs -c -k all 

重启

确认TRIM正在运行……

 sudo dmsetup table /dev/mapper/sda1_crypt --showkeys 

您应该在输出中看到“allow_discards”

有关其他信息,请参阅: http : //worldsmostsecret.blogspot.com/2012/04/how-to-activate-trim-on-luks-encrypted.html

我不知道TRIM如何为加密卷工作; 根据定义,该卷充满了随机(即非零)数据。 当文件系统不再存储有效数据时,TRIM会将块清零。 在加密卷中,存储在硬件块设备上的不是文件系统,而是虚拟块设备。