更新

更新

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

如何对 LUKS 加密的文件进行上述操作?我们假设 12.04 Alternate 安装程序 (即涉及 LVM 的安装程序) 进行了默认的 LUKS 设置。

更新

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

答案1

有一种方法可以测试它回答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填充了yes-pattern ,长度为字节块。/dev/mapper/something340482564096

直接从设备读取应该会产生以下yes模式:

# 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

如果启用了 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}....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..&... ~"..!|.,|

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

如果这种yes模式仍然存在,则很可能没有进行过修剪。”


这是我的自动脚本:

/bin/bash #!/bin/bash
#
# 此脚本按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定用途或不侵权的暗示保证。
#
# 许可证 GPL2
#
# 来自 desgua 2014/04/29

功能清洁{
cd“$pasta”
[ -f test-trim-by-desgua ] && rm test-trim-by-desgua && echo "临时文件已删除"
回声“再见”
出口 0
}

陷阱‘回显;回显“中止。”;CLEAN;回显;退出 0’INT HUP

如果 [[ "$(echo $USER)" != "root" ]]; 然后

read -n 1 -p ‘成为 root?[Y/n]’
    如果 [[ $a == "Y" || $a == "y" || $a == "" ]]; 然后
        sudo $0 $1
        出口 0
    别的
        回显
        此脚本需要root权限。
        出口 1




名称=$(echo $0 | sed's/.*\///')
如果 [ $# -ne 1 ]; 那么

回显
用法:$name /folder/to/test/

出口 1

意大利面=$1

读取 -n 1 -p'使用 fstrim?[y/N]'a
如果 [[ $a == "Y" || $a == "y" ]]; 然后
    fs=1

方法=
当 [[ "$method" != "1" && "$method" != "2" ]]; 执行
read -n 1 -s -p '选择方法:
[1] hdparm(在 LVM 上的 LUKS 中会失败)
[2] filefrag(警告:如果您看到永无止境的输出,您可能必须强制退出 - 关闭终端 - 在某些情况下成功修剪)
' 方法
完毕

函数 SDATEST {
磁盘=$(fdisk -l | grep /dev/sda)
如果 [ "$disk" == "" ]; 然后
回显
fdisk 没有找到 /dev/sda
出口 1
}

功能测试 {
echo "输入/" ; echo
$意大利面
echo "在 $pasta 创建文件 test-trim-by-desgua" ; echo
dd if=/dev/urandom of=test-trim-by-desgua count=10 bs=512k
echo "同步并休眠 2 秒。" ; echo
同步
睡眠2

hdparm --fibmap 测试按 desgua 修剪
lbab = $(hdparm --fibmap test-trim-by-desgua | tail -n1 | awk'{打印$ 2}')

echo "如您所见,该文件已创建并且其 LBA 从 $lbab 开始" ; echo

echo "同步并休眠 2 秒。" ; echo
同步
睡眠2

echo "删除文件 test-trim-by-desgua" ; echo
rm 测试-修剪-按-desgua

陷阱‘回显;回显;回显“中止。”;回显;退出 0’ INT
echo "同步并休眠 2 秒。" ; echo
同步
睡眠2

如果 [[ “$fs” == “1” ]]; 然后
    回显“fstrim $pasta && sleep 2”;回显
    fstrim $pasta
    睡眠2

echo "这是从扇区 $lbab 读取的:"
hdparm --读取扇区$lbab /dev/sda

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

如果 [[ $pass == "" ]]; 那么
    回显
修剪失败...
您应该只会看到 0000 0000 0000 0000 ...
别的
    echo "成功!!!"
出口 0

}

函数 LUKSTEST {
# 参考:https://unix.stackexchange.com/questions/85865/trim-with-lvm-and-dm-crypt#
echo 1 > /proc/sys/vm/drop_caches
$意大利面
echo "创建一个\“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 }'`
位置 =`filefrag -s -v test-trim-by-desgua | grep “eof” | sed 's| ||g ; s|.*255:|| ; s|\.\..*||'`
[[ "$position" == "" ]] && echo "无法找到文件的位置。您在 LVM 上使用 LUKS 吗?" && CLEAN;

设备 =`df test-trim-by-desgua | grep“ dev /”| awk'{打印$ 1}'`

是=`dd bs=4096 跳过=$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|
$是

如果 [[ “`echo “$yes” | grep “yyy”`” == “” ]]; 然后
    echo "无法检查模式。出现错误。退出。"
    干净的;
别的
    echo“模式已确认。”

echo“删除临时文件。”
rm 测试-修剪-按-desgua

回显“正在同步。”
同步
睡眠 1

如果 [[ “$fs” == “1” ]]; 然后
    回显“fstrim -v $pasta && sleep 2”;回显
    fstrim-v$pasta
    睡眠2

# 删除缓存
echo 1 > /proc/sys/vm/drop_caches

echo "在下一行中你不应该看到类似这样的“是”模式:
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`"

是=`dd bs=4096 跳过=$position count=256 if=$device | hexdump -C`
如果 [[ “`echo “$yes” | grep “yyy”`” != “” ]]; 然后
    回显“TRIM 不起作用。”
别的
    回显“TRIM正在运行!”
干净的;
}

如果 [[ "$method" == "1" ]]; 然后
    日期;
    测试;
elif [[ “$method” == “2” ]]; 然后
    卢克斯特;
出口 0

答案2

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

如果你使用 LVM,则需要discard添加/etc/fstab

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

# Command line
sudo -e /etc/fstab

# Graphical
gksu gedit /etc/fstab

在第4列的选项中添加“放弃”。

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

然后你添加相同的选项(丢弃)到/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

答案3

我还没有安装带有 TRIM 的 dm-crypt,但我也想验证一下。首先应该说,这可能是不可能的,这取决于你的 SSD(见:https://serverfault.com/a/401506/60525)。

假设您拥有正确类型的 SSD,我会看到几个不同的选项:

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

  2. 或者,您可以验证 UNMAP 或 WRITE SAME scsi 命令是否通过 scsi 子系统发出。我发现,不使用硬件设备或破解内核就能看到 scsi 数据包的唯一方法是打开scsi 数据包记录

    回显 $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 命令被发送就足够了(您真的关心是否有零吗?)请注意,如果 TRIM 是通过 ata DATA SET MANAGEMENT 命令完成的,后一种方法可能不起作用,它不应该出现在 scsi 日志中,而且我看不出获取 ata cdbs 的方法。但我敢打赌,这种情况不到 0.01%。

后一种解决方案可以实现某种程度的自动化,这样我们就不必手动解码数据包了。有人愿意接受吗?

据我所知,现在如果不破解 dm-crypt.c,就没有办法获得加密块地址到设备块地址的映射。因此,如果您希望看到加密块设备上修剪 fs 上已删除文件的块映射到设备上的零扇区,那么您将陷入痛苦之中。

答案4

我完全不明白 TRIM 如何对加密卷起作用;根据定义,该卷充满了随机(即非零)数据。当文件系统上不再存储活动数据时,TRIM 会将块清零。在加密卷中,存储在硬件块设备上的不是文件系统,而是虚拟块设备。

相关内容