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_discardsLVMパーティションのdmsetupテーブルに表示されるはずです。
frostschutz

申し訳ありませんが、これはタイプミスでした。構成issue_discards = 1ファイルにあります。
学生

私があなたなら、iSCSIターゲットを使用して、tcpdump / wiresharkでこれをテストしてセットアップが機能するかどうかを確認しますが、Linux iSCSIターゲットがトリムをサポートしているかどうかはわかりません。dm-cryptは物理ディスク上のブロックをブランクにすべきではないと信じています。これにより、ブルートフォースしようとするときにデバイスの空き領域を無視しやすくなります(そうするかどうかはわかりませんが、 )。さらに、SSDはブランキング後にゼロを返す必要がありません。これは、ウェアレベリングが、ブランキングされたブロックとは異なるブロックに読み取りをリダイレクトできるためです。
ディディコーヘン

1
よるとbugzilla.redhat.com/show_bug.cgi?id=958096私は誤解issue_discards = 1
frostschutz

回答:


23

別のテスト方法を使用することをお勧めします。hdparmファイルシステムのアドレスではなくデバイスのアドレスを提供するため、少し奇妙です。また、それらのアドレスがどのデバイスに関係するかはわかりません(たとえば、パーティションを解決しますが、devicemapperターゲットは解決しません)。ファイルシステムのアドレスに固執するものを使用する方がずっと簡単で、一貫性があります(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 on でtrim.test満たされたファイルがyes作成さ/dev/mapper/somethingれます。340482564096

デバイスから直接読み取ると、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
おかげで、それが欠けていた点でした。今ではうまくいくようです!
学生

2
SSDで何かをトリムするたびに、カーネルがそれ自体でキャッシュをドロップすべきでないかどうかはまだわかりません。キャッシュが間違ったデータを返すことは想定されていません。キャッシュメモリがもう存在しないもので占められている場合、それはキャッシュメモリの浪費でもあります。
frostschutz

1
@frostschutzこの素晴らしいソリューションをありがとう。怠け者がここに来た場合にプロセスを自動化するスクリプトを作成しました。
デスグア14

1
新人は、TRIMコマンドがすぐにブロック常に「ゼロ・フィル」ではないことに注意してくださいを実行します。参照してください。ここでここここ。OPの場合、hdparm -I結果は「TRIM後の決定論的読み取りZEROs」を示しているため、そうする必要があります。
-Marc.2377

3

テストルーチンが間違っています。ファイルシステムが置かれているブロックデバイスに関連するセクター番号を取得しています。この場合は論理ボリュームです。論理ボリュームは、もちろん、物理ボリュームの最初のセクターからは開始しません(連続していなくてもかまいません)。

論理ボリュームが物理ボリュームのセクター0で開始した場合(開始していない場合)、物理ボリュームは実際には別のデバイスマッパーターゲットであり、これは暗号化用です。そして、おそらく前にLUKSヘッダーがあるので、セクター番号もそこに一致しません。

セクター番号を基礎となるディスクにマッピングして作業するdmsetup tables場合、必要な情報が提供されます。ここに貼り付ける場合は、出力にキーが表示されないバージョンであることを確認してください(代わりにすべて0が表示されます)。(キーの公開からの回復はありません—変更できません—パスワードを公開するよりもはるかに悪いです)。

デバッグするには(セクタマッピングが完了したら)最下位レベルから開始し、そこで動作することを確認することをお勧めします。/ dev / sdaXでファイルシステムを直接TRIMし、それが機能することを確認します(デバイスが存在し、trimがゼロを読み戻さない可能性があります)。次に、その上でdm-cryptを実行し、その上でファイルシステムをトリミングして、動作することを確認します。最後に、LVMを上に置き、それが機能することを確認します。


@student OK、それは間違ったセクターです(私の答えの最初の2つの段落)。私は回答を編集して、セクター6575104についての文章を削除します。これは関連性がなくなったためです。
デロバート

どのデバイスを使うべきかわかりませんdmsetup。私はちょうどやった:sudo dmsetup table /dev/mapper/lubuntu--vg-rootそれは与える0 465903616 linear 252:0 2048
学生

@studentつまり、セクター0はデバイス252:0のセクター2048にあります。252:0が何であるかを理解する必要があります。そのdm暗号化デバイス(メジャー番号とマイナー番号です。たとえば、/ devに表示されます)。そして、そのデバイスのテーブルを調べて、基盤となるデバイスのブロックまで追跡し続ける必要があります。
デロバート

3

これは、怠け者がここに来た場合に共有したいスクリプトです。それはfrostschutzから受け入れられた答えから作られました

#!/ bin / bash
#
#このスクリプトは、商品性、特定の目的への適合性、または非侵害の黙示の保証を含むがこれらに限定されない、明示または黙示のいかなる種類の保証なしに「現状のまま」提供されます。
#
#ライセンスGPL2
#
#デスグア2014/04/29

関数CLEAN {
cd "$ pasta"
[-f test-trim-by-desgua] && rm test-trim-by-desgua && echo "Tempファイルが削除されました"
エコー「さようなら」
出口0
}

トラップエコー; エコー「中止」。; クリーン; エコー ; exit 0 'INT HUP

if [["$(echo $ USER)"!= "root"]]; それから

read -n 1 -p 'ルートになりますか?[Y / n] '
    if [[$ a == "Y" || $ a == "y" || $ a == ""]]; それから
        sudo $ 0 $ 1
        出口0
    他に
        エコー "
        このスクリプトにはルート権限が必要です。
        」
        1番出口

    fi

fi


name = $(echo $ 0 | sed 's /.*\///')
if [$#-ne 1]; それから

エコー "
使用法:$ name / folder / to / test /

」
1番出口
fi

パスタ= $ 1

read -n 1 -p 'fstrimを使用しますか?[y / N] '
if [[$ a == "Y" || $ a == "y"]]; それから
    fs = 1
fi

method =
while [["$ method"!= "1" && "$ method"!= "2"]]; 行う
read -n 1 -s -p 'メソッドを選択:
[1] hdparm(LVM上のLUKSでは失敗します)
[2] filefrag(警告:強制終了する必要がある場合があります-ターミナルを閉じます-終了しない出力が表示された場合、成功した場合のトリム) 
' 方法
やった

関数SDATEST {
disk = $(fdisk -l | grep / dev / sda)
if ["$ disk" == ""]; それから
エコー "
fdiskは/ dev / sdaを見つけられませんでした 
」
1番出口
fi
}

機能テスト {
echo "Entrying /"; エコー
cd $ pasta
echo "$ pastaでファイルtest-trim-by-desguaを作成"; エコー
dd if = / dev / urandom of = test-trim-by-desgua count = 10 bs = 512k
echo "2秒間同期してスリープします。" ; エコー
同期する
寝る2

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

echo "ご覧のとおり、ファイルが作成され、そのLBAは$ lbabから始まります"; エコー

echo "2秒間同期してスリープします。" ; エコー
同期する
寝る2

echo "ファイルtest-trim-by-desguaの削除"; エコー
rm test-trim-by-desgua

トラップエコー; エコー ; エコー「中止」。; エコー ; 終了0 'INT
echo "2秒間同期してスリープします。" ; エコー
同期する
寝る2

if [["$ fs" == "1"]]; それから
    echo "fstrim $ pasta && sleep 2"; エコー
    fstrim $ pasta
    寝る2
fi

echo "これはセクター$ 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のみが表示されるはずです...
」
他に
    エコー「成功!!!」
fi
出口0

}

関数LUKSTEST {
#リファレンス:/unix/85865/trim-with-lvm-and-dm-crypt#
エコー1> / proc / sys / vm / drop_caches
cd $ pasta
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}' `
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「パターンが確認されました。」
fi

echo "一時ファイルを削除しています。" 
rm test-trim-by-desgua

echo "同期中。"
同期する
寝る1

if [["$ fs" == "1"]]; それから
    echo "fstrim -v $ pasta && sleep 2"; エコー
    fstrim -v $ pasta
    寝る2
fi

#キャッシュをドロップ
エコー1> / proc / sys / vm / drop_caches

echo "次の行では、次のようなyesパターンが** NOT **表示されるはずです。 
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" `"!= ""]]; それから
    echo "TRIMが機能していません。"
他に
    echo "TRIMは機能しています!"
fi
クリーン;
}

if [["$ method" == "1"]]; それから
    SDATEST;
    テスト;
elif [["$ method" == "2"]]; それから
    LUKSTEST;
fi
出口0

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.