Como verificar se o TRIM está funcionando para um volume criptografado?

5

Você pode verificar facilmente se o TRIM funciona para uma partição ext4 "normal": link .

Como fazer isso para um criptografado pelo LUKS? Vamos supor que a configuração LUKS padrão feita por 12.04 instalador alternativo (ou seja, aquele com LVM envolvido).

Atualizar

O que estou perguntando aqui é como eu posso verificar se o bloco no disco está realmente cheio de zeros depois de remover o arquivo, se o arquivo estiver armazenado em um volume criptografado.

    
por Tomasz Zieliński 11.07.2012 / 19:37

4 respostas

1

Existe uma maneira de testá-lo respondido em unix. stackexchange.com por frostschutz (esta resposta é o seu mérito, portanto, obrigado), copiada abaixo:

"Crie um arquivo de teste: (não aleatório de propósito)

# yes | dd iflag=fullblock bs=1M count=1 of=trim.test 

Obtenha o endereço: (o comando exato pode ter que diferir dependendo do filefrag version)

# 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

Obtenha o dispositivo:

# df trim.test
/dev/mapper/something  32896880 11722824  20838512   37% /

Com essa configuração, você tem um arquivo trim.test filles com yes -pattern em /dev/mapper/something no endereço 34048 com comprimento de 256 blocos de 4096 bytes.

A leitura direta do dispositivo deve produzir o 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

Se o TRIM estiver ativado, esse padrão deverá mudar quando você excluir o arquivo. Observe que os caches também precisam ser descartados, caso contrário, dd não relerá os dados do disco.

# 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

Na maioria dos SSD, isso resultaria em um padrão zero:

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000

Se a criptografia estiver envolvida, você verá um padrão aleatório:

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..&... ~"..!|.,|

Isso porque, fisicamente aparado, a camada criptográfica lê zeros e descriptografa esses zeros para dados "aleatórios".

Se o yes -pattern persistir, muito provavelmente nenhum recorte foi feito. "

Este é o meu script automatizado:

#!/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
    
por desgua 29.04.2014 / 13:51
2

Eu ainda não tenho o dm-crypt com a configuração TRIM, mas também estou interessado em verificar isso. Primeiro, deve-se dizer que isso pode não ser possível, dependendo do seu SSD (consulte: link ).

Supondo que você tenha o tipo certo de SSD, vejo algumas opções diferentes:

  1. Teste isso em um dispositivo de bloco muito pequeno. Crie uma partição criptografada de 20Mb, assim como faria para todo o seu sistema. Certifique-se primeiro de preencher a partição com bytes aleatórios. Em seguida, crie, grave, elimine e exclua um arquivo de 10 Mb no fs criptografado. Execute fstrim nos fs montados. Se tudo estiver funcionando, você verá cerca de metade da partição de 20Mb preenchida com zero bytes.

  2. Como alternativa, você pode verificar se o comando UNMAP ou WRITE SAME scsi está sendo emitido por meio do subsistema scsi. A única maneira que encontrei de ver os pacotes scsi sem usar um dispositivo de hardware ou hackear o kernel foi ativar registro de pacotes scsi :

    % bl0ck_qu0te%

    Usando o 9216 como o BITMASK foi o suficiente para eu ver os cdbs do WRITE SAME sendo enviados após um fstrim de um ext4 fs residindo diretamente no disco (sem criptografia).

    Você pode usar fstrim no nível fs ou sg_unmap / sg_write_same no nível do dispositivo para acionar um TRIM. Depois de encontrar UNMAP ou WRITE SAME, use os documentos scsi em t10.org para decodificar o pacote e descobrir a que bloco de disco se refere. Em seguida, verifique se o disco tem todos os zeros nesse (s) setor (es).

A última abordagem é mais árdua, mas tem a vantagem de trabalhar em instalações pré-existentes e é muito mais fácil quando se trabalha com sistemas de arquivos de tamanho não trivial. Você pode achar suficiente ver o comando UNMAP ou WRITE SAME sendo enviado (você realmente se importa se há zeros ou não?) Observe que a última abordagem provavelmente não funcionará se o TRIM for feito através do comando ata DATA SET MANAGEMENT, ele não deve aparecer no log scsi e não vejo como obter os cdbs dos ata. Mas aposto que é menos que 0,01% dos casos.

A última solução poderia ser um pouco automatizada, assim não teríamos que decodificar o pacote manualmente. Algum tomador?

E tanto quanto eu agora não há como obter um mapeamento do endereço de bloco criptografado para o endereço do bloco do dispositivo sem hackear dm-crypt.c Então, se você está olhando para ver que os blocos de um arquivo excluído em um fs aparado no mapa do dispositivo de bloco criptografado para zero setores no dispositivo, você está em um mundo de dor.

    
por crass 09.08.2012 / 09:50
1

Isso foi respondido na pergunta que você vinculou.

Se você estiver usando o LVM, precisará adicionar discard às opções em /etc/fstab

Abra /etc/fstab com qualquer editor

# Command line
sudo -e /etc/fstab

# Graphical
gksu gedit /etc/fstab

Adicione "descartar" às opções da quarta coluna.

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

Você adiciona a mesma opção (descartar) a /etc/crypttab

Assumindo que sua partição LUKS é /dev/sda1 (ajuste de acordo)

# Command line
sudo -e /etc/crypttab

# Graphical
gksu gedit /etc/crypttab

Novamente, adicione em descartar:

sda1_crypt UUID=[... series of numbers ...] none luks,discard

Atualize seu initramfs

sudo update-initramfs -c -k all

Reinicie

Confirme se o TRIM está funcionando ...

sudo dmsetup table /dev/mapper/sda1_crypt --showkeys

Você deve ver "allow_discards" na saída

Para obter informações adicionais, consulte: link

    
por Panther 11.07.2012 / 19:51
0

Não vejo como o TRIM pode funcionar para um volume criptografado; o volume é, por definição, cheio de dados de aparência aleatória (ou seja, não zero). TRIM zera os blocos quando o sistema de arquivos não possui mais dados ativos armazenados neles. Em um volume criptografado, o que está armazenado no dispositivo de bloco de hardware não é um sistema de arquivos, mas um dispositivo de bloco virtual.

    
por Adrian 11.07.2012 / 19:47