Przytnij z LVM i dm-crypt


21

Próbowałem skonfigurować TRIM z LVM i dm-crypt na Ubuntu 13.04, wykonując ten samouczek:

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

Zobacz uwagi dotyczące mojej konfiguracji i mojej procedury testowania poniżej.

pytania

  1. Czy istnieje wiarygodny test, jeśli TRIM działa poprawnie?

  2. Czy moja procedura testowa jest nieprawidłowa lub czy TRIM nie działa?

  3. Jeśli to nie działa: co jest nie tak z moją konfiguracją?

  4. Jak mogę debugować TRIM dla mojej konfiguracji i sprawić, by TRIM działał?

Konfiguracja

Oto moja konfiguracja:

cat /etc/crypttab

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

i

cat /etc/lvm/lvm.conf

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

SSD to Samsung 840 Pro.

Oto moja procedura testowa

Aby przetestować konfigurację, którą właśnie wykonałem, sudo fstrim -v /co spowodowało

/: [...] bytes were trimmed

Ponowne wykonanie tej czynności spowodowało, /: 0 bytes were trimmedże wydaje się to mieć sens i wskazało, że TRIM wydaje się działać.

Jednak wtedy zrobiłem ten 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

To wydaje się wskazywać, że TRIM nie działa. Od

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

Edytować

Oto wynik działania 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

Oto moje /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 

Edytować:

W końcu zgłosiłem to jako błąd w https://bugs.launchpad.net/ubuntu/+source/lvm2/+bug/1213631

Mam nadzieję, że ktoś znajdzie tam rozwiązanie lub przynajmniej przetestuje konfigurację i zweryfikuje błąd.

Aktualizacja

Teraz to działa, patrz zaakceptowana odpowiedź.


LVM wydaje się, że brakuje odrzutów, powinna być issue_discardsnie issue discardsjeśli to nie była literówka. allow_discardspowinien pojawić się w tabeli dmsetup dla partycji LVM.
frostschutz

Przepraszam, to była literówka. Mam issue_discards = 1w moim pliku konfiguracyjnym.
student

Gdybym był tobą, spróbowałbym użyć celu iSCSI i przetestować to za pomocą tcpdump / wireshark, aby sprawdzić, czy konfiguracja działa, chociaż nie wiem, czy cel iSCSI dla systemu Linux obsługuje trymowanie, czy nie. Uważam, że dm-crypt nie powinien puste bloki na dysku fizycznym, ponieważ ułatwia to zignorowanie wolnego miejsca na urządzeniu podczas próby użycia siły (jednak nie wiem, czy to robi, czy nie) ). Ponadto dyski SSD nie muszą zwracać zer po wygaszeniu, ponieważ wyrównanie zużycia może przekierować odczyt do innego bloku niż ten pusty.
Didi Kohen,

1
Według bugzilla.redhat.com/show_bug.cgi?id=958096 Źle zrozumiałem problem_discards = 1.
frostschutz 28.09.2013

Odpowiedzi:


23

Sugeruję użycie innej metody testowania. hdparmjest nieco dziwny, ponieważ podaje adresy urządzeń, a nie adresy systemów plików, i nie określa, z jakim urządzeniem te adresy się odnoszą (np. rozwiązuje partycje, ale nie cele devicemapper itp.). Znacznie łatwiej jest użyć czegoś, co przylega do adresów systemu plików, w ten sposób jest spójny (być może z wyjątkiem nietradycyjnych systemów plików, takich jak zfs / btrfs).

Utwórz plik testowy: (nie losowo celowo)

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

Uzyskaj adres, długość i rozmiar bloku: (dokładne polecenie zależy od filefragwersji)

# 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

Pobierz urządzenie i punkt instalacji:

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

Przy takiej konfiguracji masz plik trim.testwypełniony yesopcją -pattern /dev/mapper/somethingpod adresem 34048o długości 256bloków 4096bajtów.

Czytanie tego bezpośrednio z urządzenia powinno dać 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

Jeśli TRIM jest włączony, wzorzec ten powinien ulec zmianie po usunięciu pliku. Pamiętaj, że pamięci podręczne również muszą zostać usunięte, w przeciwnym razie dddane nie zostaną ponownie odczytane z dysku.

# 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

W przypadku większości dysków SSD miałoby to zerowy wzór:

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

Jeśli szyfrowanie jest włączone, zamiast tego zobaczysz losowy wzorzec:

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

Dzieje się tak, ponieważ fizycznie przycięta warstwa kryptograficzna odczytuje zera i odszyfrowuje te zera do „losowych” danych.

Jeśli yeswzorzec się utrzymuje, najprawdopodobniej nie zostało przycięte.


1
@student: Szkoda mi, że nie zauważyłem tego wcześniej, zredagowałem wcześniej odpowiedź na zrzuty pamięci podręcznej hexdump.
frostschutz

1
Dzięki, to był brakujący punkt. Teraz wydaje się, że działa!
student

2
Nadal nie jestem pewien, czy jądro nie powinno samodzielnie upuszczać pamięci podręcznej, ilekroć przycina coś na dysku SSD. Pamięci podręczne nie powinny zwracać złych danych. To także marnowanie pamięci podręcznej, jeśli jest zajęte przez coś, czego już nie ma ... no cóż.
frostschutz

1
@frostschutz Dziękujemy za to świetne rozwiązanie. Stworzyłem skrypt, aby zautomatyzować ten proces, jeśli przyjdzie tu jakaś leniwa osoba.
desgua

1
Nowicjusze , zauważcie , że polecenie TRIM nie zawsze od razu „zeruje” bloki. Zobacz tutaj , tutaj i tutaj . Chociaż powinno, w przypadku OP, ponieważ jego hdparm -Iwynik wskazuje na „Deterministyczne czytanie ZERO po TRIM”.
Marc.2377

3

Procedura testowa jest nieprawidłowa - otrzymujesz numery sektorów w stosunku do urządzenia blokowego, na którym znajduje się system plików - który w tym przypadku jest woluminem logicznym. Wolumin logiczny oczywiście nie rozpoczyna się w pierwszym sektorze woluminu fizycznego (i może nawet nie być ciągły).

Nawet jeśli wolumin logiczny rozpoczął się w sektorze 0 woluminu fizycznego (a tak nie jest), to wolumin fizyczny jest w rzeczywistości kolejnym celem mapowania urządzenia, tym razem do szyfrowania. Prawdopodobnie z przodu znajduje się nagłówek LUKS, więc numery sektorów również tam nie pasują.

Jeśli chcesz przepracować mapowanie numeru sektora na dysk podstawowy, dmsetup tablesotrzymasz potrzebne informacje. Jeśli wkleisz go tutaj, upewnij się, że twoja jest wersją, która nie pokazuje klucza w danych wyjściowych (zamiast tego powinny pokazywać wszystkie zera)! (Nie ma możliwości odzyskania po ujawnieniu klucza - nie można go zmienić - jest to o wiele gorsze niż ujawnienie hasła).

Sugeruję, aby w celu debugowania (po opracowaniu mapowania sektora) rozpocząć od najniższego poziomu i potwierdzić, że tam działa. PRZYCINUJ system plików bezpośrednio na / dev / sdaX i upewnij się, że działa (jest całkiem możliwe, że urządzenie leży, a przycinanie nie odczytuje zer). Następnie dodaj dm-crypt i przycinaj na nim system plików i upewnij się, że działa. Na koniec umieść LVM na górze i sprawdź, czy działa.


@ studenckie OK, to jest zły sektor (pierwsze dwa akapity mojej odpowiedzi). Zmienię swoją odpowiedź, aby usunąć to zdanie dotyczące sektora 6575104, ponieważ nie ma ono już znaczenia.
derobert

Nie jestem pewien, które urządzenie powinienem wziąć dmsetup. Właśnie to zrobiłem: sudo dmsetup table /dev/mapper/lubuntu--vg-rootco daje0 465903616 linear 252:0 2048
studentowi

@ student Oznacza to, że sektor 0 znajduje się w sektorze 2048 na urządzeniu 252: 0. Będziesz musiał dowiedzieć się, co to jest 252: 0, domyślam się, że to twoje urządzenie kryptograficzne dm (to główna i mniejsza liczba, pojawi się na przykład w / dev). I musisz spojrzeć na tabelę tego urządzenia, aby kontynuować ściganie go do bloku na podstawowym urządzeniu.
derobert

3

To tylko skrypt, którym chciałbym się podzielić, jeśli przyjedzie tu jakaś leniwa osoba. Zostało wykonane z zaakceptowanej odpowiedzi od frostschutz .

#! / bin / bash
#
# Ten skrypt jest dostarczany „w stanie, w jakim się znajduje”, bez jakiejkolwiek gwarancji, wyraźnej lub dorozumianej, w tym, między innymi, dorozumianych gwarancji przydatności handlowej, przydatności do określonego celu lub nienaruszalności.
#
# Licencja GPL2
#
# autor: desgua 2014/04/29

funkcja CLEAN {
cd „$ pasta”
[-f test-trim-by-desgua] && rm test-trim-by-desgua && echo „Plik tymczasowy usunięty”
echo „Do widzenia”
wyjście 0
}

echo pułapki; echo „Przerwane”. ; CZYSTY; Echo ; wyjście 0 'INT HUP

if [["$ (echo $ USER)"! = "root"]]; następnie

czytaj -n 1 -p 'Zostań rootem? [T / n] „a
    jeśli [[$ a == "Y" || $ a == "y" || $ a == ""]]; następnie
        sudo 0 USD 1 USD
        wyjście 0
    jeszcze
        Echo "
        Ten skrypt wymaga uprawnień roota.
        „
        wyjście 1

    fi

fi


name = $ (echo $ 0 | sed 's /.*\///')
jeśli [$ # -ne 1]; następnie

Echo "
Użycie: $ name / folder / to / test /

„
wyjście 1
fi

makaron = 1 USD

czytaj -n 1 -p 'Używasz fstrim? [t / n] „a
jeśli [[$ a == "Y" || $ a == "y"]]; następnie
    fs = 1
fi

metoda =
while [["$ method"! = "1" && "$ method"! = "2"]]; robić
czytaj -n 1 -s -p 'Wybierz metodę:
[1] hdparm (zawiedzie w LUKS na LVM)
[2] filefrag (ostrzeżenie: być może będziesz musiał wymusić zamknięcie - zamknij terminal - w niektórych przypadkach sukces przycinania, jeśli zobaczysz wyjście, które nigdy się nie kończy) 
' metoda
gotowy

funkcja SDATEST {
disk = $ (fdisk -l | grep / dev / sda)
if ["$ disk" == ""]; następnie
Echo "
fdisk nie znalazł / dev / sda 
„
wyjście 1
fi
}

funkcja TEST {
echo „Entrying /”; Echo
cd $ makaron
echo "Tworzenie pliku test-trim-by-desgua w $ pasta"; Echo
dd if = / dev / urandom of = test-trim-by-desgua count = 10 bs = 512k
echo „Synchronizowanie i spanie 2 sekundy”. ; Echo
synchronizacja
spać 2

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

echo "Jak widać, plik został utworzony, a jego LBA zaczyna się od $ lbab"; Echo

echo „Synchronizowanie i spanie 2 sekundy”. ; Echo
synchronizacja
spać 2

echo "Usuwanie pliku test-trim-by-desgua"; Echo
rm test-trim-by-desgua

echo pułapki; Echo ; echo „Przerwane”. ; Echo ; zjazd 0 'INT
echo „Synchronizowanie i spanie 2 sekundy”. ; Echo
synchronizacja
spać 2

if [[„$ fs” == „1”]]; następnie
    echo „fstrim $ pasta && sleep 2”; Echo
    fstrim $ pasta
    spać 2
fi

echo „Czyta się to z sektora $ lbab:”
hdparm --read-sektor $ lbab / dev / sda

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

if [[$ pass == ""]]; następnie
    Echo "
Przycinanie nie powiodło się ... 
Powinieneś zobaczyć tylko 0000 0000 0000 0000 ...
„
jeszcze
    echo „Sukces !!!”
fi
wyjście 0

}

funkcja LUKSTEST {
# Odniesienie: /unix/85865/trim-with-lvm-and-dm-crypt#
echo 1> / proc / sys / vm / drop_caches
cd $ makaron
echo „Tworzenie pliku„ tak ”.”
tak | 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 „Nie możesz znaleźć pozycji pliku. Czy korzystasz z LUKS na LVM?” && CLEAN;

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

tak = `dd bs = 4096 pomiń = $ liczba pozycji = 256 if = $ urządzenie | hexdump -C`

echo "W następnym wierszu powinieneś zobaczyć wzór w stylu: 
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | rrrrrrr |
$ tak
„

if [["" echo "$ yes" | grep "yyy" `" == ""]]; następnie
    echo „Nie można sprawdzić wzoru. Coś poszło nie tak. Wyjście.”
    CZYSTY;
jeszcze
    echo „Wzór potwierdzony”.
fi

echo „Usuwanie pliku tymczasowego.” 
rm test-trim-by-desgua

echo „Synchronizowanie”.
synchronizacja
spać 1

if [[„$ fs” == „1”]]; następnie
    echo "fstrim -v $ pasta && sleep 2"; Echo
    fstrim -v $ makaron
    spać 2
fi

# Upuść pamięć podręczną
echo 1> / proc / sys / vm / drop_caches

echo "W następnym wierszu ** NIE ** powinieneś zobaczyć wzoru tak, jak: 
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | rrrrrrr | 
Jeśli widzisz, przycinanie nie działa:
`dd bs = 4096 pomiń = $ liczba pozycji = 256 jeśli = $ urządzenie | hexdump -C` "

tak = `dd bs = 4096 pomiń = $ liczba pozycji = 256 if = $ urządzenie | hexdump -C`
if [["` echo "$ yes" | grep "yyy" `"! = ""]]; następnie
    echo „TRIM nie działa”.
jeszcze
    echo „TRIM działa!”
fi
CZYSTY;
}

if [[„$ method” == „1”]]; następnie
    SDATEST;
    TEST;
elif [[„$ method” == „2”]]; następnie
    LUKSTEST;
fi
wyjście 0

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.