Как проверить, работает ли TRIM для зашифрованного тома?

Вы можете легко проверить, работает ли TRIM для "нормального" раздела ext4: /questions/53129/kak-vklyuchit-trim/53143#53143.

Как это сделать для LUKS-зашифрованного? Давайте предположим, что установка LUKS по умолчанию выполнена альтернативным установщиком 12.04 (т.е. с включенным LVM).

Обновить

Здесь я спрашиваю, как я могу проверить, действительно ли блок на диске заполнен нулями после удаления файла, если файл хранится в зашифрованном томе.

4 ответа

Решение

Есть способ проверить ответ на unix.stackexchange.com от SHIBENYONG (этот ответ - его заслуга, так что спасибо ему), скопированный ниже:

"Создать тестовый файл: (не случайно)

# 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 -шаблон на /dev/mapper/something по адресу 34048 с длиной 256 блоки 4096 байт.

Чтение этого с устройства напрямую должно привести к 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/ Баш
#
# Этот сценарий предоставляется "как есть" без каких-либо явных или подразумеваемых гарантий, включая, помимо прочего, подразумеваемые гарантии товарной пригодности, пригодности для конкретной цели или отсутствия нарушений.
#
# Лицензия GPL2
#
# by desgua 2014/04/29

функция CLEAN {
cd "$pasta"
[ -f test-trim-by-desgua ] && rm test-trim-by-desgua && echo "Удален временный файл"
эхо "До свидания"
выход 0
}

ловушка эхо; эхо "Прервано".; ОЧИСТКА; эхо; выход 0 'INT HUP

if [["$ (echo $ USER)"! = "root"]]; затем

read -n 1 -p 'Стать пользователем root? [Да / Нет]'а
    если [[ $a == "Y" || $a == "y" || $a == "" ]]; затем
        sudo $0 $1
        выход 0
    еще
        эхо "
        Этот скрипт нуждается в привилегии суперпользователя.
        "
        выход 1

    фи

фи


name=$(echo $0 | sed 's/.*\///')
if [ $# -ne 1 ]; затем

эхо "
Использование: $ name / folder / to / test /

"
выход 1
фи

макаронные изделия =$1

читать -n 1 -p 'Использовать fstrim? [y/N]' a
если [[ $a == "Y" || $a == "y" ]]; затем
    фс =1
фи

метод =
while [[ "$method"!= "1" && "$method"!= "2" ]]; делать
read -n 1 -s -p 'Выберите метод:
[1] hdparm (потерпит неудачу в LUKS на LVM)
[2] filefrag (предупреждение: вам может потребоваться принудительно завершить работу - закрыть терминал - в некоторых случаях обрезки при успехе, если вы видите вывод, который никогда не заканчивается) 
метод
сделанный

function SDATEST {
диск =$(fdisk -l | grep /dev/sda)
if [ "$disk" == "" ]; затем
эхо "
fdisk не найден /dev/sda 
"
выход 1
фи
}

function TEST {
эхо "Вступление /"; эхо
паста cd $
echo "Создание файла test-trim-by-desgua в $pasta"; эхо
дд если =/dev/urandom of= тест-обрезка по счетчику =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
фи

echo "Это прочитано из сектора $lbab: "
hdparm - начальный сектор $ lbab / dev / sda

pass = $ (hdparm - начальный сектор $ 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 $
echo "Создание файла" да "."
да | dd iflag= полный блок 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| || г; s| *255:. ||; S |\ \..*||''.
[[ "$position" == "" ]] && echo "Не удалось найти позицию файла. Вы в LUKS на 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 "В следующей строке вы должны увидеть такой шаблон: 
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  | гггггггг |
$ да
"

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

echo "В следующей строке вы ** ** не должны видеть шаблон" да ", например: 
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  | гггггггг | 
Если вы видите, то обрезка не работает:
`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 не работает".
еще
    эхо "ТРИМ работает!"
фи
ОЧИСТКА;
}

if [["$ method" == "1"]]; затем
    SDATEST;
    ТЕСТОВОЕ ЗАДАНИЕ;
elif [[ "$method" == "2" ]]; затем
    LUKSTEST;
фи
выход 0

У меня еще нет dm-crypt с настройкой TRIM, но я также заинтересован в проверке этого. Во-первых, следует сказать, что это может быть невозможно в зависимости от вашего SSD (см. https://serverfault.com/a/401506/60525).

Предполагая, что у вас правильный тип SSD, я вижу несколько разных вариантов:

  1. Проверьте это на очень маленьком блочном устройстве. Создайте зашифрованный раздел размером 20 МБ, как для всей системы. Обязательно сначала заполните раздел случайными байтами. Затем создайте, запишите, очистите и удалите файл размером 10 МБ на зашифрованном фс. Запустите fstrim на смонтированном fs. Если все работает, вы должны увидеть около половины раздела размером 20 МБ, заполненного нулевыми байтами.

  2. В качестве альтернативы вы можете убедиться, что команда scmsi UNMAP или WRITE SAME запускается через подсистему scsi. Единственный способ увидеть scsi-пакеты без использования аппаратного устройства или взлома ядра - включить ведение журнала scsi-пакетов:

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

    Использование 9216 в качестве BITMASK было достаточно для того, чтобы я увидел WRITE SAME cdbs, отправляемые после fstrim ext4 fs, находящегося непосредственно на диске (без шифрования).

    Вы можете использовать либо fstrim на уровне fs, либо sg_unmap/sg_write_same на уровне устройства для запуска TRIM. Как только вы найдете UNMAP или WRITE SAME, используйте scsi docs на t10.org, чтобы декодировать пакет и выяснить, на какой блок диска он ссылается. Затем убедитесь, что на диске есть все нули в этом секторе.

Последний подход является более трудным, но он имеет преимущество работы с уже существующими установками и намного проще при работе с файловыми системами нестандартного размера. Вам может показаться достаточным увидеть отправку команды UNMAP или WRITE SAME (действительно ли вам важно, есть ли нули или нет?) Обратите внимание, что последний подход, скорее всего, не будет работать, если TRIM выполняется с помощью команды ata DATA SET MANAGEMENT, это не должно отображаться в журнале SCSI, и я не вижу способа получить ATA CDB. Но держу пари, что это меньше, чем 0,01% случаев.

Последнее решение может быть автоматизированным, так что нам не придется декодировать пакет вручную. Любой берущий?

И, насколько я знаю, нет способа получить отображение адреса зашифрованного блока на адрес блока устройства без взлома dm-crypt.c Так что, если вы хотите увидеть, что блоки удаленного файла на обрезанном fs на зашифрованном заблокируйте карту устройства на ноль секторов на устройстве, вы в мире боли.

На это был дан ответ в вопросе, который вы связали.

Если вы используете 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

Я не понимаю, как TRIM вообще может работать для зашифрованного тома; объем, по определению, полон случайно выглядящих (т. е. ненулевых) данных. TRIM обнуляет блоки, когда в файловой системе больше не хранятся активные данные. В зашифрованном томе на аппаратном блочном устройстве хранится не файловая система, а виртуальное блочное устройство.

Другие вопросы по тегам