16.3.2014
Vyrobit jednoduchý počítač pro sběr dat je dneska poměrně jednoduché - najdete si jednodeskový ARM počítač (třeba Raspberry PI, ale já mám raději BeagleBone - mnohem snáze se pro ni vyrábějí rozšiřující desky) zaměstnáte hardwarového vývojáře a necháte si navrhnout rozšiřující desku. Nakonfigurujete dodaný linux, nainstalujete databázi, webový server, svoji aplikaci pro sběr dat a je to:
První nečitelnou SD kartu svedete na vadný kus. Kdyby byla karta v pořádku, nebyla by přece nabouraná už po čtrnácti dnech! Jenže další karta umřela už druhý den. Že by dva vadné kusy? Třetí karta zničená během měsíce vás začne nahlodávat - že by ty karty byly v pořádku a špatně je něco jiného?
Jeden můj známý mi ukázal velkou kulatou krabici od paklu cédeček plnou zničených SD karet. Během vývoje zničil stovky různých karet, od nejlacinějších noname, přes značkové karty až po průmyslové SD karty s cenou v tisícikorunách za kus, které měly údajně hrubé zacházení vydržet. Odešly stejně rychle, jako kterákoli jiná SD karta v jeho sbírce.
SD karta není dělaná na časté přepisy. Při použití ve foťáku nebo v mobilu se na kartu zapíše třeba 10 MB najednou, při další operaci se zapíše dalších 10 MB najednou a tak dál. O data na kartě ve foťáku se obvykle staráte až po zaplnění karty nebo až když chcete fotky stáhnout. Databáze pracuje s kartou výrazně jinak - při sběru dat se na kartu zapisuje s malým intervalem poměrně zanedbatelné množství dat. Jakmile zapíšete do databáze, připojí se na konec nějakého souboru pár bajtů dat, databáze si navíc vynutí sync.
Do algoritmu pro wear leveling na SD kartě vidí pouze výrobce, takže je dosti pravděpodobné, že postupným připisováním pár bajtů na konec souboru přepisujete vždy stejné místo na kartě. Je div, že karta vydrží takové zacházení celých čtrnáct dní!
Základem je omezit veškeré zápisy na SD kartu. Typicky se při práci linuxového stroje zapisují na disk tyto informace:
Začnu od toho nejjednoduššího: swap. Vaše zařízení musí mít dostatek paměti pro běh celého prostředí, aby se nesnažilo používat swap. Stejně - nejlepší je swap úplně vypnout. Když začne počítač odkládat paměťové stránky na SD kartu, neuvěřitelně zpomalí. Nejjednodušším únikem z takové situace je tvrdý reset.
Linux normálně při každém čtení zapisuje do informací o souboru datum posledního čtení. Každé čtení tedy představuje automaticky i zápis do struktury filesystému, vždy na přibližně stejné místo. Tuto vlastnost zakážete v /etc/fstab:
/dev/sda / ext4 data=writeback,nodiratime,noatime,norelatime 0 1
Databázová data přestěhujte na ramdisk. Ten můžete snadno vytvořit v souboru /etc/fstab řádkem:
shm /dev/shm tmpfs nodev,nosuid,noexec 0 0
Ramdisk vytvořený tímto řádkem najdete v adresáři /dev/shm. Nevýhodou ramdisku je, že po restartu systému se data ztratí. Vaše aplikace s tím proto musí počítat a musí být schopná získat šablonu databáze z odjinud. Ztracená data? Smůla - ale pořád je to lepší, než jet vyměňovat zničenou SD kartu do zařízení vzdáleného několik stovek kilometrů.
Poznámka k databázi: používám databázi Sqlite. Údajně je tato databáze vhodná právě pro použití na SD kartách, protože nepřepisuje staré záznamy, ale zapisuje vždy nové verze dat na konec souboru. V praxi likviduje Sqlite SD kartu stejně, jako kterákoliv jiná databáze. Navíc doba pro zotavení po havárii je při větší databázi (řádově jednotky GB) i na normálním disku nechutně dlouhá. Snažte se proto svou databázi udržet co nejmenší.
U logů je problém, že obvykle každá aplikace zapisuje své logy do nějakého jiného souboru a u některých aplikací - typicky třeba u webového serveru - je nastavení logů specifické právě pro tuto aplikaci. Nejjednodušší je vůbec nenastartovat syslog démona (ať už používáte jakýkoliv). Pokud logy přece jen potřebujete, syslog se dá u rozumných aplikací pro logování (používám syslog-ng) poslat přes síť do jiného počítače.
Zakázat wtmp je nesmírně obtížné. Do souboru /var/log/wtmp zapisuje proces init. Google vám příliš neporadí - dotazů "Jak zakázat zápisy do wtmp?" najdete sice dost, ale odpovědí je pravidelně podezíravá, vyhýbavá otázka: "A proč to chcete? Zakazovat zápisy do wtmp může chtít jen zlý člověk, který nechce nechávat v systému své stopy". Naštěstí existuje jedno primitivní řešení - po startu proceru init wtmp jednoduše smažte:
rm -f /var/log/wtmp
Než se vám podaří v init skriptech tento soubor smazat, proces init sice stačí soubor vytvořit a možná do něj i něco zapsat, a po smazání bude mít nějaké připomínky, ale fakt, že si soubor wtmp nepřejete, dokáže akceptovat, a už jej znovu nevytvoří. Pokud byste chtěli zakázat vytvoření wtmp souboru kompletně, asi budete muset hrábnout do zdrojových tvarů - do toho se mi nikdy nechtělo.
Po prostudování různých zdrojů na internetu jsem dospěl k názoru, že nejvhodnějším filesystémem pro SD kartu je ext4. Pro SD kartu je ale vhodné zakázat žurnál a upravit některé další parametry:
mkfs.ext4 -O ^has_journal -E stride=2,stripe-width=1024 -b 4096 /dev/sda1
V souvislosti s montováním nekorektně odmontovaného filesystému po havárii systému nebo po vypnutí napájení bych ještě doporučil upravit startovací skripty tak, aby se zakázalo manuální kontrolování disků. Donuťte startovací skript, aby zkontroloval disk vždy, když je potřeba, a aby to dokázal udělat i bez vaší asistence. Já si přepsal startovací skript /etc/init.d/fsck (distribuce gentoo). Do míst, kde se původně systém dovolával mojí pomoci, jsem vložil řádek
fsck -y /
V jiné distribuci bude startovací skript vypadat jinak, takže žádné podrobnosti neuvádím. Poraďte si.
A ještě jednu připomínku na konec: u podobných zařízení není důležité, aby fungovala stoprocentně spolehlivě. Důležité je, aby se zařízení dokázalo vzpamatovat po havárii samo a pokud možno co nejrychleji.