使用LVM和dm-crypt进行修剪


21

我尝试按照本教程在ubuntu 13.04上使用LVM和dm-crypt设置TRIM:

http://blog.neutrino.es/2013/howto-properly-activate-trim-for-your-ssd-on-linux-fstrim-lvm-and-dmcrypt/

请参阅下面有关我的配置和测试过程的说明。

问题

  1. TRIM是否正常工作,是否有可靠的测试?

  2. 我的测试程序是否错误或TRIM无法正常工作?

  3. 如果它不起作用:我的设置有什么问题?

  4. 如何调试设置的TRIM并使TRIM工作?

组态

这是我的配置:

cat /etc/crypttab

sda3_crypt UUID=[...] none luks,discard

cat /etc/lvm/lvm.conf

# [...]
devices  {
      # [ ... ]
      issue_discards = 1
      # [ ... ]
   }
# [...]

SSD是Samsung 840 Pro。

这是我的测试程序

为了测试我刚刚做的设置sudo fstrim -v /,结果

/: [...] bytes were trimmed

再次执行此操作/: 0 bytes were trimmed似乎很有意义,并表明TRIM似乎有效。

但是后来我做了这个测试:

dd if=/dev/urandom of=tempfile count=100 bs=512k oflag=direct

sudo hdparm --fibmap tempfile                                 

tempfile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0    5520384    5521407       1024
      524288    5528576    5529599       1024
     1048576    5523456    5525503       2048
     2097152    5607424    5619711      12288
     8388608    5570560    5603327      32768
    25165824    5963776    5980159      16384
    33554432    6012928    6029311      16384
    41943040    6275072    6291455      16384
    50331648    6635520    6639615       4096

sync

sudo hdparm --read-sector 5520384 /dev/sda                    

/dev/sda:
reading sector 5520384: succeeded
7746 4e11 bf42 0c93 25d3 2825 19fd 8eda
bd93 8ec6 9942 bb98 ed55 87eb 53e1 01d5
c61a 3f52 19a1 0ae5 0798 c6e2 39d9 771a
b89f 3fc5 e786 9b1d 3452 d5d7 9479 a80d
114a 7528 a79f f475 57dc aeaf 25f4 998c
3dd5 b44d 23bf 77f3 0ad9 8688 6518 28ee
81db 1473 08b5 befe 8f2e 5b86 c84e c7d2
1bdd 1065 6a23 fd0f 2951 d879 e823 021b
fa84 b9c1 eadd 9154 c9f4 2ebe cd70 64ec
75a8 4d93 c8fa 3174 7277 1ffb e858 5eca
7586 8b2e 9dbc ab12 40ab eb17 8187 e67d
5e0d 0005 5867 b924 5cfd 6723 9e4a 6f5f
99a4 a3b0 eeac 454a 83b6 c528 1106 6682
ca77 4edf 2180 bf0c b175 fabb 3d4b 37e2
b834 9e3e 82f2 2fdd 2c6a c6ca 873f e71e
f979 160f 5778 356f 2aea 6176 46b6 72b9
f76e ee51 979c 326b 1436 7cfe f677 bfcd
4c3c 9e11 4747 45c1 4bb2 4137 03a1 e4c8
e9dd 43b4 a3b4 ce1b d218 4161 bf64 727b
75d8 dcc2 e14c ebec 2126 25da 0300 12bd
6b1a 28b3 824f 3911 c960 527d 97cd de1b
9f08 9a8e dcdc e65f 1875 58ca be65 82bf
e844 50b8 cc1b 7466 58b8 e708 bd3d c01f
64fb 9317 a77a e43b 671f e1fb e328 93a9
c9c7 291c 56e0 c6c1 f011 b94d 9dc7 71e6
c8b1 5720 b8c9 b1a6 14f1 7299 9122 912b
312a 0f2f a31a 8bf9 9f8c 54e6 96f3 60b8
04a7 7dc9 3caa db0a a837 e5d7 2752 b477
c22d 7598 44e1 84e9 25d4 5db5 9f19 f73b
85a0 c656 373a ec34 55fb e1fc 124e 4674
1ba8 1a84 6aa4 7cb5 455e f416 adc6 a125
c4d4 8323 4eee 2493 2920 4e38 524c 1981

sudo rm tempfile

sync

sudo fstrim /

sync

sudo hdparm --read-sector 5520384 /dev/sda

/dev/sda:
reading sector 5520384: succeeded
7746 4e11 bf42 0c93 25d3 2825 19fd 8eda
bd93 8ec6 9942 bb98 ed55 87eb 53e1 01d5
c61a 3f52 19a1 0ae5 0798 c6e2 39d9 771a
b89f 3fc5 e786 9b1d 3452 d5d7 9479 a80d
114a 7528 a79f f475 57dc aeaf 25f4 998c
3dd5 b44d 23bf 77f3 0ad9 8688 6518 28ee
81db 1473 08b5 befe 8f2e 5b86 c84e c7d2
1bdd 1065 6a23 fd0f 2951 d879 e823 021b
fa84 b9c1 eadd 9154 c9f4 2ebe cd70 64ec
75a8 4d93 c8fa 3174 7277 1ffb e858 5eca
7586 8b2e 9dbc ab12 40ab eb17 8187 e67d
5e0d 0005 5867 b924 5cfd 6723 9e4a 6f5f
99a4 a3b0 eeac 454a 83b6 c528 1106 6682
ca77 4edf 2180 bf0c b175 fabb 3d4b 37e2
b834 9e3e 82f2 2fdd 2c6a c6ca 873f e71e
f979 160f 5778 356f 2aea 6176 46b6 72b9
f76e ee51 979c 326b 1436 7cfe f677 bfcd
4c3c 9e11 4747 45c1 4bb2 4137 03a1 e4c8
e9dd 43b4 a3b4 ce1b d218 4161 bf64 727b
75d8 dcc2 e14c ebec 2126 25da 0300 12bd
6b1a 28b3 824f 3911 c960 527d 97cd de1b
9f08 9a8e dcdc e65f 1875 58ca be65 82bf
e844 50b8 cc1b 7466 58b8 e708 bd3d c01f
64fb 9317 a77a e43b 671f e1fb e328 93a9
c9c7 291c 56e0 c6c1 f011 b94d 9dc7 71e6
c8b1 5720 b8c9 b1a6 14f1 7299 9122 912b
312a 0f2f a31a 8bf9 9f8c 54e6 96f3 60b8
04a7 7dc9 3caa db0a a837 e5d7 2752 b477
c22d 7598 44e1 84e9 25d4 5db5 9f19 f73b
85a0 c656 373a ec34 55fb e1fc 124e 4674
1ba8 1a84 6aa4 7cb5 455e f416 adc6 a125
c4d4 8323 4eee 2493 2920 4e38 524c 1981

这似乎表明TRIM不起作用。以来

sudo hdparm -I /dev/sda | grep -i TRIM                        
       *    Data Set Management TRIM supported (limit 8 blocks)
       *    Deterministic read ZEROs after TRIM

编辑

这是输出 sudo dmsetup table

lubuntu--vg-root: 0 465903616 linear 252:0 2048
lubuntu--vg-swap_1: 0 33308672 linear 252:0 465905664
sda3_crypt: 0 499222528 crypt aes-xts-plain64 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 8:3 4096 1 allow_discards

这是我的/etc/fstab

# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/mapper/lubuntu--vg-root /               ext4    errors=remount-ro 0       1
# /boot was on /dev/sda2 during installation
UUID=f700d855-96d0-495e-a480-81f52b965bda /boot           ext2    defaults        0       2
# /boot/efi was on /dev/sda1 during installation
UUID=2296-2E49  /boot/efi       vfat    defaults        0       1
/dev/mapper/lubuntu--vg-swap_1 none            swap    sw              0       0
# tmp
tmpfs /tmp tmpfs nodev,nosuid,noexec,mode=1777          0       0 

编辑:

我终于在https://bugs.launchpad.net/ubuntu/+source/lvm2/+bug/1213631中将其报告为错误

希望有人能在那里找到解决方案,或者至少测试设置并验证错误。

更新资料

现在可以使用了,请参见已接受的答案。


LVM似乎缺少丢弃,应该是issue_discards没有issue discards,如果这是不是一个错字。allow_discards应该在dmsetup表中显示LVM分区。
frostschutz

抱歉,这是一个错字。我issue_discards = 1在配置文件中。
学生

如果我是您,我将尝试使用iSCSI目标并通过tcpdump / wireshark进行测试以查看设置是否有效,尽管我不知道Linux iSCSI目标是否支持修整。我确实相信dm-crypt不应清空物理磁盘上的块,因为这样做会使尝试暴力破解设备时更容易忽略设备上的可用空间(尽管我不知道它是否这样做) )。此外,SSD不需要在消隐后返回零,因为损耗平均可以将读取重定向到与消隐的块不同的块。
Didi Kohen

1
根据bugzilla.redhat.com/show_bug.cgi?id=958096,我误解了issue_discards = 1
frostschutz 2013年

Answers:


23

我建议使用其他测试方法。hdparm有点奇怪,因为它提供了设备地址而不是文件系统地址,并且没有说明这些地址与哪个设备有关(例如,它解析分区,但不解析设备映射器目标,等等)。使用坚持文件系统地址的东西要容易得多,那样就可以保持一致(也许除了zfs / btrfs这样的非传统文件系统之外)。

创建一个测试文件:(不是随机的)

# 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% /mount/point

通过此设置,您将在地址为-pattern 的文件中trim.test充满字节块的长度。yes/dev/mapper/something340482564096

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

如果启用了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-pattern仍然存在,则很可能没有修剪。


1
@student:我很早就没有注意到这个问题,因此编辑了删除缓存的答案hexdump
frostschutz

1
谢谢,那是缺少的地方。现在看来有效!
2013年

2
我仍然不确定内核在调整SSD上的内容时是否不应该自行丢弃缓存。缓存不应该返回错误的数据。如果它已被不再存在的东西占用,那么这也会浪费高速缓存。
frostschutz 2013年

1
@frostschutz感谢您提供的出色解决方案。如果有些懒惰的人来到这里,我制作了一个脚本来自动执行该过程。
desgua 2014年

1
新手请注意,TRIM命令不会总是立即将块“零填充”。看到这里这里这里。尽管应该,在OP的情况下,因为他的hdparm -I结果表明“ TRIM之后确定性读取零”。
Marc.2377

3

您的测试例程是错误的-获得相对于文件系统所在的块设备的扇区号-在这种情况下,这是一个逻辑卷。当然,逻辑卷不是从物理卷的第一个扇区开始的(甚至可能不是连续的)。

即使逻辑卷从物理卷的扇区0开始(不是),但物理卷实际上是另一个设备映射器目标,该目标用于加密。可能在前面有一个LUKS标头,因此扇区号也不在那里。

如果您想通过将扇区号映射到基础磁盘来工作,dmsetup tables将为您提供所需的信息。如果将其粘贴到此处,请确保您的版本是未在输出中显示键的版本(它应显示全0)!(公开密钥无法恢复 - 无法更改 -与公开密码相比要差得多)。

我建议您从最低级别开始调试(一旦完成扇区映射工作),然后确认它在那里工作。在/ dev / sdaX上直接修剪文件系统,并确保其正常工作(设备很可能位于,并且trim不会读回零)。然后在其上进行dm-crypt,并在其上修剪一个文件系统,并确保它可以工作。最后,将LVM放在最上面,并检查其是否有效。


@学生好,那么那是错误的领域(我的回答的前两段)。我将编辑答案以删除有关扇区6575104的句子,因为它不再相关。
derobert

我不确定应该购买哪种设备dmsetup。我刚刚做过:sudo dmsetup table /dev/mapper/lubuntu--vg-root这给0 465903616 linear 252:0 2048
学生

@student这意味着扇区0在设备252:0上的扇区2048处。您必须弄清楚252:0是什么,我想它是您的dm加密设备(这是主要和次要数字,例如将显示在/ dev中)。而且,您需要查看该设备的表,才能继续将其追踪到基础设备上的某个块。
derobert

3

如果有些懒惰的人来到这里,这只是我想分享的脚本。它是根据弗罗斯特舒兹公认答案做出的

#!/ bin / bash
#
#此脚本按“原样”提供,没有任何形式的明示或暗示保证,包括但不限于对适销性,针对特定目的的适用性或不侵权的暗示保证。
#
#许可证GPL2
#
#由desgua 2014/04/29

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

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

如果[[“ $(echo $ USER)” =“ root”]]; 然后

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

    科幻

科幻


name = $(回显$ 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 {
disk = $(fdisk -l | grep / dev / sda)
如果[“ $ disk” ==“”]; 然后
回声“
找不到fdisk / dev / sda 
”
1号出口
科幻
}

功能测试 {
回声“输入/”;回声
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

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

陷阱回声; 回声; 回声“中止”。; 回声; 退出0'INT
回显“正在同步并休眠2秒”。; 回声
同步
睡2

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

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

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

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

}

函数LUKSTEST {
#参考:/unix/85865/trim-with-lvm-and-dm-crypt#
回声1> / proc / sys / vm / drop_caches
cd $ pasta
回显“创建\“是\”文件。
是的 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的| || g; s |。* 255:|| ; s | \。\ .. * ||'`
[[“” $ position“ ==”“]] && echo”找不到文件的位置。您在LVM上的LUKS上吗?“ &&清洁;

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 |
是
”

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

回显“删除临时文件。” 
rm test-tris by desgua

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

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

#删除缓存
回声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`”

yes =`dd bs = 4096 skip = $ position count = 256 if = $ device | hexdump -C`
如果[[“ echo” $ yes“ | grep” yyy“`”!=“”]]; 然后
    回显“ TRIM无法正常工作。”
其他
    回声“ TRIM正在工作!”
科幻
清洁;
}

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.