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

Вы можете легко проверить, работает ли TRIM для «нормального» раздела ext4: https://askubuntu.com/a/19480/5920 .

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

Обновление

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

6
задан 13 April 2017 в 15:25

4 ответа

Существует способ протестировать его, ответил по unix.stackexchange.com frostschutz (этот ответ является его заслугой так благодарит его), скопированный ниже:

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

# 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

Если ОБРЕЗКА включена, этот шаблон должен измениться при удалении файла. Обратите внимание, что кэши должны быть отброшены также, иначе 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..&... ~"..!|.,|

Поэтому физически обрезанный, crypto чтения слоя обнуляют и дешифруют, они обнуляют к "случайным" данным.

Если yes- шаблон сохраняется, скорее всего, никакая обрезка не была сделана."


Это - мой автоматизированный сценарий:

#!/bin/bash
#
# This script is provided "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.
#
# License GPL2
#
# by desgua 2014/04/29

function CLEAN {
cd "$pasta"
[ -f test-trim-by-desgua ] && rm test-trim-by-desgua && echo "Temp file removed"
echo "Goodbye"
exit 0
}

trap 'echo ; echo "Aborted." ; CLEAN; echo ; exit 0' INT HUP

if [[ "$(echo $USER)" != "root" ]]; then

read -n 1 -p 'Become root? [Y/n]' a
    if [[ $a == "Y" || $a == "y" || $a == "" ]]; then
        sudo $0 $1
        exit 0
    else
        echo "
        This script needs root privilege.
        "
        exit 1

    fi

fi


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

echo "
Usage: $name /folder/to/test/

"
exit 1
fi

pasta=$1

read -n 1 -p 'Use fstrim? [y/N]' a
if [[ $a == "Y" || $a == "y" ]]; then
    fs=1
fi

method=
while [[ "$method" != "1" && "$method" != "2" ]]; do
read -n 1 -s -p 'Choose a method:
[1] hdparm (will fail in LUKS on LVM)
[2] filefrag (warning: you may have to force quit - close the terminal - in some cases of success trim if you see an output that never ends) 
' method
done

function SDATEST {
disk=$(fdisk -l | grep /dev/sda)
if [ "$disk" == "" ]; then
echo "
fdisk did not found /dev/sda 
"
exit 1
fi
}

function TEST {
echo "Entrying /" ; echo
cd $pasta
echo "Creating the file test-trim-by-desgua at $pasta" ; echo
dd if=/dev/urandom of=test-trim-by-desgua count=10 bs=512k
echo "Syncing and sleeping 2 seconds." ; echo
sync
sleep 2

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

echo "As you can see, the file was created and its LBA begins at $lbab" ; echo

echo "Syncing and sleeping 2 seconds." ; echo
sync
sleep 2

echo "Removing file test-trim-by-desgua" ; echo 
rm test-trim-by-desgua

trap 'echo ; echo ; echo "Aborted." ; echo ; exit 0' INT
echo "Syncing and sleeping 2 seconds." ; echo
sync
sleep 2

if [[ "$fs" == "1" ]]; then 
    echo "fstrim $pasta && sleep 2" ; echo
    fstrim $pasta
    sleep 2
fi

echo "This is readed from sector $lbab: "
hdparm --read-sector $lbab /dev/sda

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

if [[ $pass == "" ]]; then
    echo "
Trim failed... 
You should see only 0000 0000 0000 0000 ...
"
else
    echo "Success!!!"
fi
exit 0

}

function LUKSTEST {
# Reference: https://unix.stackexchange.com/questions/85865/trim-with-lvm-and-dm-crypt#
echo 1 > /proc/sys/vm/drop_caches
cd $pasta
echo "Creating a \"yes\" file."
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 "Could not find the position of the file. Are you on a LUKS on 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 "In the next line you should see a pattern like: 
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.|
$yes
"

if [[ "`echo "$yes" | grep "y.y.y"`" == "" ]]; then 
    echo "The pattern could not be checked. Something went wrong. Exiting."
    CLEAN;
else
    echo "Pattern confirmed."
fi

echo "Removing the temp file." 
rm test-trim-by-desgua

echo "Syncing."
sync
sleep 1

if [[ "$fs" == "1" ]]; then 
    echo "fstrim -v $pasta && sleep 2" ; echo
    fstrim -v $pasta
    sleep 2
fi

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

echo "In the next line you should **NOT** see a yes pattern like: 
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.| 
If you see, then trim is not working:
`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 "y.y.y"`" != "" ]]; then 
    echo "TRIM not working."
else
    echo "TRIM is working!"
fi
CLEAN;
}

if [[ "$method" == "1" ]]; then
    SDATEST;
    TEST;
elif [[ "$method" == "2" ]]; then
    LUKSTEST;
fi
exit 0
4
ответ дан 13 April 2017 в 15:25

У меня пока нет 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, находящегося непосредственно на диске (без шифрования).

    Вы можете использовать либо 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 на карте зашифрованного блочного устройства с нулевыми секторами на устройстве, вы в мире боли.

0
ответ дан 13 April 2017 в 15:25

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

0
ответ дан 13 April 2017 в 15:25

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

Если вы используете 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- подрезать-на-Luks-encrypted.html

0
ответ дан 13 April 2017 в 15:25

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

Похожие вопросы: