Taglia con LVM e dm-crypt


21

Ho provato a configurare TRIM con LVM e dm-crypt su Ubuntu 13.04 seguendo questo tutorial:

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

Vedi le note sulla mia configurazione e la mia procedura di test di seguito.

Domande

  1. Esiste un test affidabile se TRIM funziona correttamente?

  2. La mia routine di test è sbagliata o il mio TRIM non funziona?

  3. Se non funziona: cosa c'è di sbagliato nella mia configurazione?

  4. Come posso eseguire il debug di TRIM per la mia configurazione e far funzionare TRIM?

Configurazione

Ecco la mia configurazione:

cat /etc/crypttab

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

e

cat /etc/lvm/lvm.conf

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

L'SSD è un Samsung 840 Pro.

Ecco la mia procedura di test

Per testare la configurazione ho appena fatto il sudo fstrim -v /risultato

/: [...] bytes were trimmed

In questo modo si è verificato di nuovo /: 0 bytes were trimmedche sembra avere senso e ha indicato che TRIM sembra funzionare.

Tuttavia, ho fatto questo test:

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

Questo sembra indicare che TRIM non funziona. Da

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

modificare

Ecco l'output di 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

Ecco il mio /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 

Modificare:

Alla fine l'ho segnalato come bug in https://bugs.launchpad.net/ubuntu/+source/lvm2/+bug/1213631

Spero che qualcuno trovi una soluzione lì o almeno testare l'installazione e verificare il bug.

Aggiornare

Ora funziona, vedi risposta accettata.


LVM sembra mancare rigetti in mare, dovrebbe essere issue_discardsnon issue discardsse non fosse un errore di battitura. allow_discardsdovrebbe apparire nella tabella dmsetup per le partizioni LVM.
frostschutz,

Scusa, questo era un errore di battitura. Ho issue_discards = 1nel mio file di configurazione.
studente

Se fossi in te, proverei a utilizzare un target iSCSI e testarlo tramite tcpdump / WireShark per vedere se l'installazione funziona, anche se non so se il target iSCSI Linux supporta il trim o meno. Credo che dm-crypt non dovrebbe svuotare i blocchi sul disco fisico perché ciò rende più semplice ignorare lo spazio libero sul dispositivo quando si cerca di forzarlo (non so se lo fa o no, comunque ). Inoltre, gli SSD non sono tenuti a restituire zeri dopo il blanking, poiché il livellamento dell'usura può reindirizzare la lettura su un blocco diverso rispetto a quello cancellato.
Didi Kohen,

1
Secondo bugzilla.redhat.com/show_bug.cgi?id=958096 Ho frainteso il issue_discards = 1.
frostschutz,

Risposte:


23

Suggerisco di utilizzare un metodo di prova diverso. hdparmè un po 'strano in quanto fornisce gli indirizzi dei dispositivi piuttosto che gli indirizzi del filesystem e non dice a quale dispositivo si riferiscono quegli indirizzi (ad es. risolve partizioni, ma non target di devicemapper, ecc.). Molto più facile da usare qualcosa che si attacca agli indirizzi dei filesystem, in questo modo è coerente (forse tranne per i filesystem non tradizionali come zfs / btrfs).

Creare un file di prova: (non casuale apposta)

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

Ottieni indirizzo, lunghezza e dimensione del blocco: (il comando esatto dipende dalla filefragversione)

# 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

Ottieni il dispositivo e il mountpoint:

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

Con questa configurazione, hai un file trim.testriempito con yes-pattern acceso /dev/mapper/somethingall'indirizzo 34048con lunghezza di 256blocchi di 4096byte.

La lettura diretta dal dispositivo dovrebbe produrre il yesmodello:

# 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 TRIM è abilitato, questo modello dovrebbe cambiare quando si elimina il file. Si noti che è necessario eliminare anche le cache, altrimenti ddnon rileggere i dati dal 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

Sulla maggior parte degli SSD ciò comporterebbe uno schema zero:

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

Se è coinvolta la crittografia, vedrai invece un modello casuale:

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

Questo perché tagliato fisicamente, il livello di crittografia legge zero e decodifica tali zero in dati "casuali".

Se il yesmodello persiste, molto probabilmente non è stato eseguito alcun taglio.


1
@student: mi sento male per non averlo notato prima, ho modificato la risposta per eliminare la cache prima hexdump.
frostschutz,

1
Grazie, quello era il punto mancante. Ora sembra funzionare!
studente

2
Non sono ancora sicuro che il kernel non debba far cadere le cache da solo ogni volta che ritaglia qualcosa su un SSD. Le cache non dovrebbero restituire dati errati. È anche uno spreco di memoria cache se occupato da qualcosa che non c'è più ... vabbè.
frostschutz,

1
@frostschutz Grazie per questa ottima soluzione. Ho realizzato una sceneggiatura per automatizzare il processo se qualcuno pigro viene qui.
desgua,

1
I nuovi arrivati , si noti che il comando TRIM non sempre "riempie zero" i blocchi immediatamente. Vedi qui , qui e qui . Anche se dovrebbe, nel caso di OP, dal momento che il suo hdparm -Irisultato indica "Lettura ZERO deterministica dopo TRIM".
Marc.2377,

3

La tua routine di test è sbagliata - stai ottenendo i numeri di settore relativi al dispositivo a blocchi su cui si trova il filesystem - che in questo caso è un volume logico. Il volume logico, ovviamente, non inizia nel primo settore del volume fisico (e potrebbe anche non essere contiguo).

Anche se il volume logico è iniziato nel settore 0 del volume fisico (cosa che non lo fa), il volume fisico è in realtà un altro target di mappatura del dispositivo, questo per la crittografia. E probabilmente c'è un'intestazione LUKS di fronte, quindi anche i numeri di settore non corrispondono lì.

Se vuoi lavorare mappando il numero di settore sul disco sottostante, dmsetup tablesti forniranno le informazioni di cui hai bisogno. Se lo incolli qui, assicurati che la tua sia una versione che non mostra la chiave nell'output (dovrebbe invece mostrare tutti gli 0)! (Non è possibile recuperare la divulgazione della chiave - non può essere modificata - è molto peggio della divulgazione della password).

Suggerisco di eseguire il debug (una volta elaborata la mappatura settoriale) a partire dal livello più basso e confermare che funzioni lì. TRIM un file system direttamente su / dev / sdaX e assicurati che funzioni (è del tutto possibile che il dispositivo si trovi e che il trim non rilevi zero). Quindi dm-crypt sopra a quello, e taglia un filesystem su quello, e assicurati che funzioni. Infine, metti LVM in cima e controlla che funzioni.


@student OK, allora è il settore sbagliato (i primi due paragrafi della mia risposta). Modificherò la mia risposta per rimuovere quella frase relativa al settore 6575104, poiché non è più pertinente.
derobert,

Non sono sicuro di quale dispositivo dovrei prendere dmsetup. Ho appena fatto: il sudo dmsetup table /dev/mapper/lubuntu--vg-rootche dà0 465903616 linear 252:0 2048
studente

@student Ciò significa che il settore 0 è al settore 2048 sul dispositivo 252: 0. Dovrai capire cosa è 252: 0, immagino sia il tuo dispositivo crittografico dm (che è il numero maggiore e minore, apparirà in / dev per esempio). E dovrai guardare la tabella per quel dispositivo, per continuare a inseguirlo fino a un blocco su un dispositivo sottostante.
derobert,

3

Questa è solo una sceneggiatura che vorrei condividere se qualcuno pigro venisse qui. È stato creato dalla risposta accettata da frostschutz .

#! / Bin / bash
#
# Questo script viene fornito "così com'è" senza garanzie di alcun tipo, espresse o implicite, incluse, a titolo esemplificativo, le garanzie implicite di commerciabilità, idoneità per uno scopo particolare o non violazione.
#
# Licenza GPL2
#
# di desgua 2014/04/29

funzione CLEAN {
cd "$ pasta"
[-f test-trim-by-desgua] && rm test-trim-by-desgua && echo "File temporaneo rimosso"
echo "Arrivederci"
uscita 0
}

trap 'echo; echo "Interrotto". ; PULITO; eco ; esci 0 'INT HUP

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

leggi -n 1 -p 'Diventa root? [S / n] 'a
    se [[$ a == "Y" || $ a == "y" || $ a == ""]]; poi
        sudo $ 0 $ 1
        uscita 0
    altro
        eco "
        Questo script necessita del privilegio di root.
        "
        uscita 1

    fi

fi


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

eco "
Utilizzo: $ name / cartella / to / test /

"
uscita 1
fi

la pasta = $ 1

leggi -n 1 -p 'Usa fstrim? [y / N] 'a
se [[$ a == "Y" || $ a == "y"]]; poi
    fs = 1
fi

metodo =
while [["$ method"! = "1" && "$ method"! = "2"]]; fare
leggi -n 1 -s -p 'Scegli un metodo:
[1] hdparm (fallirà in LUKS su LVM)
[2] filefrag (avviso: potrebbe essere necessario forzare la chiusura - chiudere il terminale - in alcuni casi di esito positivo se vedi un output che non finisce mai) 
' metodo
fatto

funzione SDATEST {
disk = $ (fdisk -l | grep / dev / sda)
if ["$ disk" == ""]; poi
eco "
fdisk non ha trovato / dev / sda 
"
uscita 1
fi
}

test di funzionalita {
echo "Entrando /"; eco
cd $ pasta
echo "Creazione del file test-trim-by-desgua a $ pasta"; eco
dd if = / dev / urandom of = test-trim-by-desgua count = 10 bs = 512k
echo "Sincronizzazione e sospensione 2 secondi." ; eco
sync
dormire 2

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

echo "Come puoi vedere, il file è stato creato e il suo LBA inizia a $ lbab"; eco

echo "Sincronizzazione e sospensione 2 secondi." ; eco
sync
dormire 2

echo "Rimozione del file test-trim-by-desgua"; eco
rm test-trim-by-desgua

trap 'echo; eco ; echo "Interrotto". ; eco ; uscita 0 'INT
echo "Sincronizzazione e sospensione 2 secondi." ; eco
sync
dormire 2

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

echo "Questo è letto dal settore $ lbab:"
hdparm --read-sector $ lbab / dev / sda

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

if [[$ pass == ""]]; poi
    eco "
Trim fallito ... 
Dovresti vedere solo 0000 0000 0000 0000 ...
"
altro
    echo "Successo !!!"
fi
uscita 0

}

funzione LUKSTEST {
# Riferimento: /unix/85865/trim-with-lvm-and-dm-crypt#
echo 1> / proc / sys / vm / drop_caches
cd $ pasta
echo "Creazione di un file \" yes \ ".
si | 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 "Impossibile trovare la posizione del file. Sei su un LUKS su LVM?" && PULITO;

device = `df test-trim-by-desgua | grep "dev /" | awk '{print $ 1}' '

yes = `dd bs = 4096 skip = $ position count = 256 if = $ device | hexdump -C`

echo "Nella riga successiva dovresti vedere uno schema come: 
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | aaaaaaaa |
$ sì
"

if [["` echo "$ yes" | grep "yyy" `" == ""]]; poi
    echo "Impossibile verificare il modello. Qualcosa è andato storto. Uscita."
    PULITO;
altro
    echo "Pattern confermato."
fi

echo "Rimozione del file temporaneo." 
rm test-trim-by-desgua

echo "Sincronizzazione".
sync
dormire 1

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

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

echo "Nella riga successiva dovresti ** NON ** vedere un modello yes come: 
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | aaaaaaaa | 
Se vedi, il trim non funziona:
`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" `"! = ""]]; poi
    echo "TRIM non funziona."
altro
    echo "TRIM funziona!"
fi
PULITO;
}

if [["$ method" == "1"]]; poi
    SDATEST;
    TEST;
elif [["$ method" == "2"]]; poi
    LUKSTEST;
fi
uscita 0

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.