niedziela, 21 października 2018

FSTRIM w Linuxie, KVM i gościach

W czym rzecz?

Mam dwa hosty KVMowe, na których pędzam rożne maszyny wirualne. Jeden z tych hostów to laptop, który z przyczyn oczywistych, jest poszyfrowany LUKSem. 
I od niego się wysztko zaczęło - używam go już od około 3 lat, no i ma dysk SSD. Ostatnio zaczęły mu się ostre zacięcia przy zapisach trwające nawet po kilka sekund. Po odrobinie googlania doszedłem do wniosku, że to pewnie trimowanie SSD. No i zacząłem borować temat, kikla razy się nawet od tego odbiłem - niby wszystko miałem a nie działało. Aż w końcu trafiłem na wyczerpujący artykuł. Nie będę tu przepisywał cudzej treści tylko ją zacytuję/zalinkuję.

Drugi problem jaki zauważyłem, to zajętość miejsca w obrazach dysków (używam cienkich, ale nie "sparse" qcow2). Otóż po jakimś czasie te obrazy wcale nie są takie cienkie wystarczy, że zrobię "dnf system-upgrade" na wirtualnej fedorze i już jest nadmuchana o dodatkowe 10 GiB. Windows Update robi podobne fiki-miki. 

Czyli, żeby trimować od maszyny wirtualnej, po dysk SSD hosta, trzeba przejść przez klika pięter stosu IO:



A konkretnie?

LUKS

Konkretnie, to trzeba zacząć od końca, czyli od crypttab'a na hoscie. Oczywiście jeżeli dysk hosta jest poszyfrowany, co gorąco polecam zwłaszcza dla laptopów. LUKS na Intelach pokazujących w /proc/cpuinfo flagę AES nie boli: i tak będzie sprzętowy.
U mnie zaszyfrowany jest cały dysk i wygląda to tak (lsblk):

NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                                             8:0    0   477G  0 disk 
├─sda1                                          8:1    0   500M  0 part  /boot
└─sda2                                          8:2    0 476,5G  0 part 
  └─luks-157fae7b-545b-4348-a02c-1b8a38110e33 253:0    0 476,5G  0 crypt
    ├─turing-root                             253:1    0    50G  0 lvm   /
    ├─turing-swap                             253:2    0   7,7G  0 lvm   [SWAP]
    └─turing-home                             253:3    0 418,8G  0 lvm   /home
sr0                                            11:0    1  1024M  0 rom  


Wystarczy zatem do /etc/crypttab dopisać to co poniżej zaznaczyłem na czerwono:

luks-157fae7b-545b-4348-a02c-1b8a38110e33 UUID=157fae7b-545b-4348-a02c-1b8a38110e33 none discard


LVM

Po LUKSie, pora na LVM (dziś chyba każdy go używa). Tu też sprawa jest prosta, wystarczy zmienić w /etc/lvm/lvm.conf w sekcji devices linijkę issue_discards:

devices {
[ ... ]
   issue_discards = 1

A potem to już tylko odświeżenie initrd:

sudo dracut -f 

I ostrzegawczy strzał w tyl głowy:

shutdown -r now

Co jeszcze po stronie hosta?

Jakoś trzeba zdecydować jak będziemy obcinać dane. Można dodać opcję do /etc/fstab albo uzyć mechnizmu obcinania cyklicznego. Ja wolę to drugie:

sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer

Maszyny wirtualne

Fajny i kompletny artykuł jest tu. Ja tylko podsumuję, żeby wszystko było w jednym miejscu. 
Żeby działało, trzeba mieć:
  • W miarę nowego KVMa i QEMu. W Fedorze 28 na której to teraz robię jest. 
  • Maszyny wirtualne muszą używać sterownika Virtio SCSI.
  • Definicja dysków takiej maszyny musi zawierać opcję discard.


Kontroler można zmienić np za pomocą VirtManager'a - linuxy (jako gość) zwykle dobrze znoszą taką zmianę. Z łindołs bywa gorzej, bo przed zmianą np z IDE, albo VirtIO na VirtIO SCSI, pewnie trzeba będzie dograć sterowniki. Nie wiem jak z desktopowymi windami, ale miałem ten problem z 20012R2. Zmiana sterownika wirtualnego dysku bootowalnego z IDE na SCSI powodowała, że WinDOS wyciągał kopyta.
Dla istniejącego dysku IDE albo VirtIO, po zmianie typu na SCSI, w urządzeniach pojawi się kontroler VirtIO SCSI:




Potem trzeba grzebnąć niestety w XMLu, można to zrobić np komendą sudo virsh edit Nazwa_Maszyny_Wirtualnej. W sekcji odpowiedzialnej za dysk, który ma być trimowany trzeba dopisać to, co zaznaczyłem na czerwono:

<domain type='kvm'>
  <name>Fredzia</name>
  <uuid>7b0ea399-36e0-4ec1-aa12-bbbdc2c46f8d</uuid>
  <title>Fredzia - Najnowsza Fedorka</title>
  <description>Experymentalna Fedora 25, a nawet 29</description>
[...]
  <devices>
  [...]
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writeback' discard='unmap'/>
      <source file='/home/marcinek/vm/fredzia.qcow2'/>
      <target dev='sda' bus='scsi'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>



No i start maszynki. Tak, jak wspominałem, Linuxy przeżywają taką zmianę bezboleśnie. Można od tego momentu używać fstrim w gościu, dokładnie tak jak napisałem o hoscie.

A co z (win)DOS

Po odtańczeniu Tańca Deszczu, czyli zaklinaniu systemu, żeby łaskawie wstał z dysku który kiedyś widział jako IDE, a teraz jest SCSI, trimowanie dysków robi się tak. Ponieważ moje maszynki nie kręcą się non-stop, więc zadowalam się możliwością wywołania optymalizacji z palca (OptimizeVolume -reTrim) oraz ustawieniami domyślnymi, ale o tym później.

Efekty

Na windows wygląda to mniej więcej tak:

Definicja dysku maszyny wirtualnej:



Tyle widzi gość:

I w sumie nie dziwota. Dostał plik 128 GiB to tyle widzi i będziewidział. Ciekawsze rzeczy dzieją się na hoscie. Łindołs jako to łindołs sciąga sobie poprawki...

du -sm /var/lib/libvirt/images/WinDOS2012r2.qcow2
17954    /var/lib/libvirt/images/WinDOS2012r2.qcow2

Powtórzyłem tę komendę parę razy za każdym razem dostąjąc rożne, czasem większe, czasem mniejsze!!! wartości. Jak to się dzieje?  Otóż od wersji 2012 ten "system" wysyła discardy automatycznie. Komenda PowerShell która to pokazuje:



Nie będę wnikał czy warto to robić czy nie - odpowiednikiem tej opcji w Linuxie jest dostanie odpowiednich wpisów przy fielsystemach w fstabie. 

Godzinę (i półtora gigabajta poprawek) później, zajętość dysku na hoście:

du -sm /var/lib/libvirt/images/WinDOS2012r2.qcow2
19059    /var/lib/libvirt/images/WinDOS2012r2.qcow2

Pytanie otwarte: Czy jeśli gość wykona discard, plik obrazu dysku się obetnie z punktu widzenia hosta, to ten discard póədzie dalej? Do LVMa, LUKSa aż do SSD hosta, czy trzeba robić to oddzielnie ?

Jak rozkminię jak to sprawdzić, to pewnie dopiszę :-)

Póki co, polegam na cyklicznym zwalnianiu miejsca przy pomocy fstrim.timer na moim linuxowym hoscie i gościach, oraz na automacie w gościach Windowsowych.

Aha, na Linuxie (innym niż mój laptop opisany powyżej) pierwsze zastosowanie fstrim na filesystemie /var (w którym działa pokazany łindołs) obcięło....

sudo fstrim -v /var
/var: obcięto 64 GiB (bajtów: 68709412864)


Nmon pokazywał przez około 15-20s ciągły zapis do dysku SSD na poziomie 350MB/s. Ale to jest nie miarodajne, bo ten filesystem został strimowany pierwszy raz. W każdym razie teraz. mogę tam swobodnie zapisać kolejne 64GiB bez ryzyka, że będę musiał czekać na wyzerowanie jakichś komórek ;-)

Aktualizacja,czyli jak to jest z plikami sparse:

Akurat wyszła Fedora 29. Nawet ja nie jestem tak szalony, żeby od razu aktualizować hosty do najnowszej wersji, ale oczywiście korci. dlatego mam maszynkę wirtualną którą sobie aktualizuję najpierw, i jak trochę poużywam, to decyduję co dalej
Maszynka o wdzięcznej nazwie "Fredzia" jest obecnie jakąś niezbyt świeżą betą 29 i od strony hosta jest rzadkim plikiem (sparse) o takich parametrach:

ls -la fredzia.qcow2
-rw-rw-r--. 1 root root 32217432064 10-23 19:37 fredzia.qcow2

 
W rzeczywistości zajmuje tyle:

du -sm fredzia.qcow2 
19586    fredzia.qcow2 
Komenda dnf update zeznała, ze do ściągnięcia jest około 120MB (po ściągnięciu 70MB indeksów). Czyli spodziewam się wzrostu zajętości o co najmniej 200MB. 

Po aktualizacji zajętość wygąda tak:

du -sm fredzia.qcow2
19922    fredzia.qcow2

Czyli zeżarło jakieś 300 MB. A po zawołaniu fstrim w gosciu:

19448    fredzia.qcow2

Czyli działa :-) Oczywiśćie ls -l cały czas opkazuje, że plik ma 30 GiB, ale od tego są pliki sparse, nie?



Brak komentarzy:

Prześlij komentarz