Czy rozmiar ma znaczenie?

W tym przypadku prawo nagłówków Betteridge’a nie ma zastosowania, odpowiedź będzie twierdząca, a wszystko za sprawą Androida.

Logo Androida
Źródło: https://en.wikipedia.org/wiki/Android_(operating_system)

Od roku korzystam z Yanosika. Jakiś czas temu zauważyłem, że niemal skończyło mi się miejsce na karcie SD. Szybkie śledztwo ujawniło, że głównym winowajcą nie są – jak przypuszczałem – zdjęcia, tylko katalog yanosik-new, który zajmował ponad 700 MB z dostępnych 2 GB na karcie (wiem, mała, taka zaszłość). Ponarzekałem na FB, usłyszałem, że zawartość katalogu można bezpiecznie usunąć – odbuduje sobie co potrzebne. Znaczy się klasyczny cache. OK, rok używany, karta mała, nie robię afery. Usunąłem.

Ostatnimi dniami coś Yanosik zaczął zgłaszać błędy w stylu aplikacja nie odpowiada – czekaj/zgłoś/zamknij. Coś mnie tknęło, żeby znowu sprawdzić zajętość karty i… bingo. Znowu brak wolnego miejsca. Co prawda zrobiłem na urlopie parę zdjęć, ale zdecydowanie nie kilkaset MB. Oczywiście znowu yanosik-new ma rozmiar ponad 700 MB… Zacząłem szukać większej karty i rozglądać się za instrukcją zmiany karty w telefonie na większą. Przy okazji obmyślając, jakich ciepłych słów użyć pod adresem autorów Yanosika, bo zużycie 700 MB w rok to jeszcze jestem jakoś w stanie zrozumieć, ale w 3 tygodnie?

Znalazłem jakąś kartę 4 GB, ale okazało się, że muszę sprawdzić, czy jest sprawna. Wymiana karty SD w urządzeniach z Androidem jest prosta – wystarczy zgrać całą zawartość na komputer, sformatować nową kartę, przegrać wszystkie dane na nową. I powinno działać. Wygląda prosto, ale stwierdziłem, że zrobię backup, poza tym i tak wygodniej wrzucić całość na chwilę na komputer, niż kopiować między czytnikami.

I tu niespodzianka. Po usunięciu miniaturek zdjęć (jakieś 200 czy 300 MB) i skopiowaniu wszystkich danych na dysku katalog zajął… 880 MB.  Czyli jakąś połowę tego, co na karcie. W tym momencie zapaliła mi się lampka ostrzegawcza. Czyżby rozmiar bloku? Katalog Yanosika ma dużo małych kilkusetbajtowych plików, więc może o to chodzi. Sprawdziłem jego rozmiar w komputerze. 130 MB, więc bez dramatu. Czyżby autorzy zrobili taki bezsensowny i niedostosowany do Androida cache?

Zacząłem drążyć temat i okazało się, że cfdisk pokazuje jako system plików FAT16. No ale jak to? I jaki jest rozmiar bloku dla FAT 16? I czy w ogóle pojemności rzędu 2 GB są obsługiwane przez taki zabytek? Szybka wyprawa do muzeum i okazało się, że owszem, FAT16 obsługuje pojemności dysku do 2 GB. A rozmiar bloku to wówczas… 32 kB. Zamiast wymieniać kartę, postanowiłem zrobić mały eksperyment: zmienić system plików na FAT32.

Zmieniłem typ partycji w cfdisk (raczej bez znaczenia) i sformatowałem kartę przy pomocy mkfs.vfat -F 32, czyli wymuszając FAT32. Skopiowałem dane z komputera, włączyłem telefon, odbudowałem cache zdjęć. Po tym zabiegu jest 930 GB wolnego, bez kasowania jakichkolwiek danych! Czyli rozmiar bloku ma w przypadku urządzeń z Androidem duże znaczenie.

Zastanawiam się tylko, jak to możliwe. Kto w XXI w. używa FAT16? Nie kojarzę gdzie była formatowana karta. Wiele wskazuje na to, że w samym telefonie. Czyżby Android był tak słabo zaprojektowany, że domyślnie formatuje karty o rozmiarze 2 GB i mniejsze na FAT16? Jeśli tak, to jak widać zupełnie bez sensu. Ciekawe też, jaki system plików jest w na wbudowanej pamięci flash. Bo o ile karty microSD są tanie (8 GB class 4 od 12 zł widzę, za mniej niż 20 zł można nawet 16 GB class 10 w sklepie kupić), więc rozważania o rozmiarze 2 GB są czysto teoretyczne, o tyle w przypadku wbudowanej pamięci nie ma możliwości zmiany jej rozmiaru – trzeba zmienić urządzenie. Gra w tym przypadku (Yanosik i jego cache plus jakieś inne dane typu zdjęcia, ale przypuszczam, że nie on jeden tak robi…) toczy się w praktyce o podwojenie miejsca…

Pewnego rodzaju obejściem problemu może być w tym przypadku opisane kiedyś przeniesienie aplikacji z pamięci wbudowanej na kartę. Oczywiście najlepiej sformatowaną na FAT32, ale to powinno już stać się automatycznie w przypadku pojemności większych niż 2 GB.

EncFS – kolejne narzędzie do szyfrowania upada

Dawno temu zachwycałem się EncFS[1]. Obsługiwało AES, pozwalało szyfrować pliki, nie partycje i pozwalało trzymać je na zwykłym systemie plików. Tak naprawdę szyfrowany był katalog. Jakiś czas temu upadł Truecrypt, który – zdaniem twórców – okazał się nie tak bezpieczny, jak postrzegali go ludzie. Teraz kolej na EncFS.

Wczoraj, podczas aktualizacji systemu[2], dostałem w twarz dialogboksem o następującej treści:

Encfs security informationAccording to a security audit by Taylor Hornby (Defuse Security), the current implementation of Encfs is vulnerable or potentially vulnerable to multiple types of attacks. For example,an attacker with read/write access to encrypted data might lower the decryption complexity for subsequently encrypted data without this being noticed by a legitimate user, or might usetiming analysis to deduce information.Until these issues are resolved, encfs should not be considered a safe home for sensitive data in scenarios where such attacks are possible.

Pięknie, prawda? Szczególnie, że EncFS byłby świetnym rozwiązaniem do szyfrowania plików w chmurze – EncFS dla WebDAV czy Dropbox były proste w założeniu i wygodne w użytkowaniu[3]

Wygląda, że pomału można żegnać się z EncFS. A podobnych alternatyw jakoś nie widać na horyzoncie.

[1] Strona projektu zwraca 404. Przypadek? W każdym razie nie linkuję, łatwe do wyszukania…

[2] Debian unstable. Akurat tam nie używam encfs, ale instaluję wszędzie. Planowałem do chmury.

[3] Ładne ilustrowane howto dla EncFS w chmurze.

Raspberry Pi, Raspbian i problemy z kartami microSD

Jakieś siedem tygodni temu pisałem, że padła mi karta microSD (Kingston) w Raspberry Pi. Wymieniłem na nową (Goodram). Zamontowana oszczędnie, tj. bez journala i z symlinkiem /var/lib/transmission-daemon/info kierującym na dysk twardy. Wczoraj robię aktualizację systemu, a tu nagle:

Preparing to replace libssl1.0.0:armhf 1.0.1e-2+rvt+deb7u7 (using .../libssl1.0.0_1.0.1e-2+rvt+deb7u10_armhf.deb) ...
Unpacking replacement libssl1.0.0:armhf ... dpkg: error processing /var/cache/apt/archives/libssl1.0.0_1.0.1e-2+rvt+deb7u10_armhf.deb (--unpack):
error creating directory `./usr/share/doc/libssl1.0.0': Input/output error
Segmentation fault Segmentation fault -bash: mbrtowc.c:92: __mbrtowc: Assertion `status == __GCONV_OK || status == __GCONV_EMPTY_INPUT || status == __GCONV_ILLEGAL_INPUT || status == __GCONV_INCOMPLETE_INPUT || status == __GCONV_FULL_OUTPUT' failed.

Piękne, prawda? Oczywiście kluczowy jest input/output error. Fsck, są błędy, naprawiony filesystem. Coś mnie tknęło i sprawdziłem badblocks (badblocks -sv). Tak jest, błędy w okolicy 90% karty (dead link). Sztuk prawie 30. Wygląda, że karta Goodram wytrzymała w komfortowych warunkach raptem 7 tygodni. Masakra.

Z tego wszystkiego zacząłem sprawdzać, co pisze na dysk (iotop -ao). Wyniki (sortowane po ilości zapisów, czas działania kilka godzin) są ciekawe:

3192 be/4 root 8.00 K 4.03 M 0.00 % 0.00 % rsyslogd -c5
2184 be/4 root 240.00 K 880.00 K 0.00 % 0.00 % nmbd -D
3341 be/4 ntp 248.00 K 188.00 K 0.00 % 0.00 % ntpd -p /var/run/ntpd.pid -g -u 102:104
5256 be/4 root 0.00 B 160.00 K 0.00 % 0.00 % [kworker/u2:2]
2911 be/4 root 208.00 K 88.00 K 0.00 % 0.00 % -bash

Jak widać, głównie rsyslog. I raczej nie ma tego wiele.

I tu zaczyna się część najciekawsza. Pamiętacie uszkodzoną kartę Kingstona? Przygotowałem się do pozbycia się jej, poleciał shred. Stwierdziłem, że uruchomię badblocks na niej. I… niespodzianka. Teraz nie zgłasza błędów. Ani w teście odczytu (domyślny), ani w niedestrukcyjnym teście zapisu (badblocks -nvs). Naprawiło się?

Zaczynam podejrzewać jakiegoś buga z przejściówką microSD -> SD (ale są dwie różne, bo każda karta miała swoją), gniazdem w rpi (ale działało OK, poza tym i badblocks, i fsck robię w laptopie). Zagadka.

Ostatecznie zmniejszyłem rozmiar partycji ext4 na karcie Kingstona i działa do tej pory bez problemu. Czyli jakieś 3 tygodnie bezproblemowego działania, bo wpis zacząłem tworzyć 12 czerwca.

UPDATE: Zwariowałem. Goodram, który ewidentnie miał błędy, bo nie tylko badblocks je wykazywał, ale nawet shred puszczony przed wyrzuceniem powodował błędy IO i nie mógł dobrnąć do końca (a próbowałem nie raz), teraz działa. Nagrałem Raspbiana dla Banana Pi, test badblockiem i… czysto. WTF?

Pamięci flash, czyli pendrive, microSD itd.

Czasem człowiekowi wydaje się, że coś wie i… no właśnie, wydaje się. Że są różne pendrive’y (czy tam ogólnie pamięci flash), to wiedziałem. Wiedziałem też, że mają klasy i poszczególne klasy odpowiadają różnym prędkościom zapisu. I tyle.

Niedawno od hrw dowiedziałem się, że to nie do końca tak, że parametrów jest znacznie więcej i że w praktyce mają one spore znaczenie przy stosowaniu karty jako nośnika dla systemu Linux. Bo jednak czym innym jest zapis filmu na FAT, a czym innym realne operacje na jakichś linuksowych systemach plików.

Ostatnio uruchomiłem grzejnik na starym pendrive, użyłem ext2 i zdarzyło mi się trochę ponarzekać na μblogu, że wolno działa i w ogóle. Dostałem odpowiedź, że minimalny cluster size dla nośnika flash powinien być 4k. Co przypomniało mi wcześniejszą rozmowę i skłoniło do zadania pytania jak sprawdzić cluster size? Co dość szybko przywiodło mnie do wpisu nt. optymalizacji systemu plików dla pamięci flash.

Zauważyłem, że blog do którego powyżej linkuję ma raptem trzy wpisy i to sprzed roku, więc ryzyko zniknięcia jest spore. Pozwolę sobie zacytować dla pamięci część dotyczącą analizy:

  1. Interesting parts of this result are the diff changes drastically at two places:
    1. from  8388608 (8Mb) to 4194304 (4MB): Based in example readme in flashbench, this indicates that there was no performance overhead reading two blocks over the 4mb boundary, but there was for 8mb boundary. The guess is then that the erasure block is 8mb large on my sd-card
    2. before 8192 and after. I would really like to know why there is a bump at 8k, but times after that are so much lower, so 8k is obviously some sort of boundary point.
  2. From this, I deduce two things,
    1. Ext4 should have a block size of 4k, and the “stride” value should be 2. This will cause ext4 to think that units of 2 blocks (8k) can and should be treated as one.
    2. Ext4 should have the stripe-size set to 1024. This value was calculated by taking 8M (guessed erasure block size) dividing by 8K (size of a stride, 2 times block size (4K)). This will (hopefully) cause Ext4 to try to align writes so that while erasure blocks are written continuously and make it avoid sub-block updates.

Część dotyczącą ustawiania początku partycji w fdisk:

First sector (2048-15759359, default 2048): 16384

Wraz z wyjaśnieniem, skąd to się wzięło:

Fdisk uses blocks of 512 bytes, so that means that we want to start at 8*1024^2/512 = 16384.

No i na koniec część dotycząca tworzenia samego filesystemu ext4:

Reformat the filesystem, this time with Ext4 with block size of 4k, without journaling, but with additional parameters to encourage Ext4 to do the right thing with respect to the erasure block:

mkfs.ext4 -O ^has_journal -E stride=2,stripe-width=1024 -b 4096 -L Fedora14Arm  /dev/mmcblk0p1

Na koniec dwa linki, które autor wpisu podaje jako źródła:

Zachęcam do lektury całego wpisu z którego pochodzą powyższe cytaty, bo powyżej są jedynie najważniejsze wyjątki, które bez kontekstu nie do końca w czymkolwiek pomogą.

Inny, prostszy (ale starszy) wpis o podobnej tematyce: http://linux-howto-guide.blogspot.com/2009/10/increase-usb-flash-drive-write-speed.html

No i dowiedziałem się, że pożyteczne narzędzie to flashbench (pakiet jest w Debianie unstable), że żaden ext2 dla nośników flash, tylko ext4 bez journala, za to z dodatkowymi opcjami, zależnymi od parametrów karty. I że nie tylko w przypadku SSD warto stosować alignment. Różnica prędkości między ext2 a ext4 po tuningu? Wg autora wpisu 8 razy szybciej dla małych plików i dwa szybciej dla dużych. Trochę mi wszystko opadło, ale za to wiem, co będę robić w weekend.

UPDATE: Trochę się pobawiłem i wyszło mi, że metoda pomiaru jest średnio dokładna. Albo pendrive zwalnia w miarę używania (w sensie „wykonana ilość zapisów”), albo reboot/hibernacja drastycznie zmieniają wyniki, albo nie wiem co jest grane. Bo zrobiłem test na FAT, potem na ext4 po dopasowaniu partycji (brak zauważalnych różnic), potem zabawa z ustawieniami ext4 i… między pierwszym testem na ext4, a końcowym, na identycznych parametrach ext4 były 4 sekundy różnicy. Przy podstawie 22 sekundy, więc prawie 20% wolniej. Zagadka. A ponieważ nie widzę zysku między FAT a ext4, to chęć do migracji ext2 -> ext4 gwałtownie spadła. Może kiedyś.

UPDATE2: Dodane cytaty z bloga. Bawiłem się trochę w optymalizacje/benchmarki na czterech różnych pendrive’ach. Tylko jeden zareagował pozytywnie na zmianę alignmentu (OK, bez wyliczeń było, po prostu początek partycji na sektorze 16384) i zmianę systemu na ext4. Przy okazji wyszło na jaw, że pendrive, który uznałem za wolny jest ok. 3 razy wolniejszy od pozostałych, niezależnie od ustawień.

Praca na desktopie z małą ilością RAM po raz drugi.

Jakiś czas temu pisałem o pierwszym podejściu do małej ilości RAM na desktopie, więc pora na część drugą. Przejrzałem podrzucone linki nt. optymalizacji działania dekstopu. Dysk był już ustawiony optymalnie, niepotrzebne usługi powyłączane, więc tak naprawdę tylko zmniejszyłem ilość uruchamianych konsol w inittabie. Nie zauważyłem zmiany w ilości zużywanego RAM, ale i tak ich nie potrzebuję – dwie wystarczają z naddatkiem. Swappiness nadal jest ustawione na 0 i IMO działa OK.

Zauważyłem, że spowalnianie występuje głównie na jednym desktopie (tym w pracy, starszy, bardziej zapchany dysk), przy pracy z pakietami (aktualizacja listy, instalacja), co skłania mnie do wniosku, że głównym winowajcą jest fragmentacja filesystemu. W obu przypadkach jest to ReiserFS (zaszłość, kiedyś był najlepszym wyborem, teraz chętnie widziałbym ext4 w tym miejscu), ale w domu z pewnością fragmentacja jest mniejsza – pół dysku zawsze było wolne.

Tak czy inaczej, wydaje mi się, że wypracowałem sposób na drastyczne ograniczenie spowalniania komputera przy pracy z pakietami. Korzystam z niego mniej więcej raz na tydzień. Cudów nie ma, czyli najpierw zamykam programy, które zużywają najwięcej RAM: Iceweasel, czyli Firefox, Icedove, czyli Thunderbird i PSI. Trwa to chwilę, a zwalnia znaczne obszary RAM.

Następnie uruchamiam prosty skrypt, który robi sync na dyskach, opróżnia bufory dyskowe, a następnie wyłącza i ponownie włącza swap.

#!/bin/bash

echo Syncing hard discs
sync
sleep 5
sync

echo Flushing disc buffers
echo 3 > /proc/sys/vm/drop_caches

echo Turning swap off
swapoff -a

echo Turning swap on
swapon -a

Celem jest najpierw zwolnienie jak największego obszaru pamięci, a następnie wymuszenie przerzucenia danych ze swap do RAM. Szybsze od restartu, działa w tle, więc można pracować w tym czasie. Po wykonaniu skryptu można swobodnie uruchomić przeglądarkę, pocztę, komunikator i aktualizować system. Najgorsze co może się wydarzyć, to niewyłączenie swapa, jeśli nie będzie wystarczającej ilości dostępnej pamięci, ale nie jest to krytyczne i zdarza się rzadko (zwł. po wyłączeniu przeglądarki). Wydaje mi się, że po takim zabiegu system działa znacznie lepiej.