Raspberry Pi – Na ratunek karcie pamięci
W dzisiejszym wpisie poświęconym mini komputerkowi Raspberry Pi dowiemy się jak uchronić kartę pamięci na której zainstalowany jest system operacyjny od przedwczesnej śmierci. Jak wiadomo każda pamięć typu flash (a do tego grona zaliczają się właśnie karty pamięci używane w RPi) ma ograniczoną ilość cykli zapisów. Po ich wyczerpaniu komórki pamięci nie mogą być nadpisane i tym samym karta zaczyna umierać. Dziś zaprezentuję Wam kilka trików jak ograniczyć ilość zapisów które Raspbian wykonuje pod maską.
Wszystkie kroki wykonałem na moim Raspberry Pi 2 model B z zainstalowanym systemem Raspbian Stretch Lite przez SSH. Należy pamiętać, że wszystkie polecenia trzeba poprzedzić komendą sudo, gdyż będziemy potrzebowali do ich wykonania uprawnień administratora.
Wskazówka: Jeżeli zapomnimy poprzedzić komendy słówkiem sudo, przez co wyświetli nam się informacja o braku uprawnień możemy wpisać sudo !!
dzięki czemu ostatnia komenda którą wpisaliśmy wykona się z uprawnieniami administratora :)
Krok 1: Upewniamy się, że mamy aktualne paczki
Wpisujemy w konsoli następujące polecenia:
apt-get update
apt-get upgrade
Krok 2: Zmieniamy domyślny systemowy logger na busybox
BusyBox to zestaw narzędzi przeznaczony dla systemó wbudowanych opartych na linuxie. Znajduję się w nim między innymi logger, który zapisuje dane do bufora kołowego zamiast zajmować coraz to więcej miejsca na dysku przez zwykłe logowanie wszystkeigo po kolei.
Aby zainstalować nowy logger wpisujemy w konsoli
apt-get install busybox-syslogd
a po pomyślnym zainstalowaniu usuwamy kompletnie stary logger:
dpkg --purge rsyslog
Teraz możemy sprawdzić ostatnie logi komendą logread
Krok 3: Wyłączamy plik wymiany
Systemy z rodziny *nix używają specjalnej partycji nazwanej swap (ang. wymiana) w celu przechowywania danych, które normalnie powinny być w RAMie jednak nie ma tam już miejsca lub system uznał, że lepiej będzie zapisać je na dysku.
Raspbian zamiast partycji swap ma do tego specjalny folder. Możemy wyłączyć używanie tego mechanizmu edytując plik /boot/cmdline.txt
W tym celu należy wpisać w konsoli nano /boot/cmdline.txt
po czym na końcu pierwszej linijki dopisać noswap
. U mnie po edycji ten plik wyglądał w następujący sposób:
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=2b099403-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait noswap
Możemy także całkowicie usunąć pliki wymiany (zauważyłem, że na nowszych raspbianach powyższy trick nie do końca działa tak jakbyśmy tego oczekiwali) wykonując polecenia:
sudo chmod -x /etc/init.d/dphys-swapfile sudo swapoff -a sudo rm /var/swap
Krok 4: Przerzucamy tymczasowe pliki systemowe do pamięci RAM
Aby to zrobić najpierw musimy je usunąć, a następnie zrobić w ich miejscu dowiązania symboliczne do folderu /tmp/
W tym celu wpisujemy komendę
UWAGA! Jeżeli skasujemy folder /var/spool przestaną działać nam crontaby użytkownika (będziemy mogli edytować tylko globalne). Jeżeli chcecie pozostawić sobie możliwość modyfikacji crontaba poleceniem crontab -e usuńcie z poniższego polecenia fragment /var/spool!
rm -rf /var/lib/dhcp/ /var/run /var/spool /var/lock /etc/resolv.conf
a następnie po kolei tworzymy dowiązania:
ln -s /tmp /var/lib/dhcp ln -s /tmp /var/run ln -s /tmp /var/spool ln -s /tmp /var/lock
Z racji tego, że dowiązanie musi wskazywać na istniejący już plik/folder w momencie jego utworzenia dla pliku /etc/resolv.conf musimy najpierw utworzyć resolv.conf w katalogu /tmp
W tym celu wpisujemy do konsoli touch /tmp/dhcpcd.resolv.conf
A następnie tworzymy dowiązanie analogicznie do powyższych ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf
Użytkownik pm7 w komentarzu zasugerował, że warto również tworzyć plik /tmp/dhcpd.resolv.conf przy każdym reboocie systemu (czyli np. dodając linijkę @reboot touch /tmp/dhcpcd.resolv.conf
do crontaba (crontab możemy edytować poleceniem nano crontab -e
)). U mnie ten plik był edytowalny i zapisywalny przez system nawet po restarcie, ale na pewno utworzenie go przy każdym rozruchu systemu nie zaszkodzi :)
Krok 5: Montujemy partycję główną z parametrem noatime
Kiedy utworzymy lub zapiszemy jakiś plik jasne jest, że w jego metadanych pojawi się informacja o czasie zapisu. Jednak systemy *nix poza tymi informacjami zapisują w metadanych także czas ostatniego dostępu do pliku przez co nasza karta pamięci może dość szybko się zużyć nawet jeżeli nie wykonujemy na niej żadnych zapisów. Aby wyłączyć tę opcję musimy dopisać parametr noatime w pliku /etc/fstab
w linijce odpowiadającej partycji zamontowanej w /.
W tym celu wpisuejmy
nano /etc/fstab
A następnie dopisujemy noatime po przecinku zaraz za defaults. U mnie wygląda to tak:
W Raspbianie prawdopodobnie będziecie mieli ten parametr wpisany domyślnie, jednak użytkownicy innych dystrybucji powinni to sprawdzić :)
Krok 6: Restartujemy Raspberry
Aby wykonać restart systemu wpisujemy komendę
shutdown -r now
Krok 7: Weryfikacja
Po restarcie systemu warto sprawdzić, czy wszystkie ważniejsze zmiany się zachowały.
W tym celu wpisujemy w konsoli polecenie ls -la /var
, które wyświetli nam listę plików i dowiązań. Dowiązania powinny być oznaczone specjalnym podświetleniem. Jeżeli tam są to znaczy, że jest ok :)
Poleceniem swapon -s
możemy sprawdzić czy plik wymiany jest używany.
U mnie wynik tego polecenia wygląda następująco:
krupson@raspberrypi:~ $ swapon -s Filename Type Size Used Priority /var/swap file 102396 0 -1
W kolumnie Used widnieje 0, więc swap nie jest używany.
Inną metodą sprawdzenia pliku wymiany jest wpisanie polecenia cat /proc/meminfo
oraz odszukanie linijki podpisanej SwapTotal. U mnie wygląda ona następująco:
SwapTotal: 0 kB SwapFree: 0 kB
Nasza karta jest już bezpieczna
Po wykonaniu wszystkich powyższych kroków możemy być z siebie dumni, gdyż przedłużyliśmy życie naszej karty pamięci przynajmniej kilkukrotnie :) Na koniec warto zrobić sobie obraz takiego systemu i zapisać na dysku, abyśmy w przyszłości mogli go łatwo przywrócić gdy przypadkiem coś uszkodzimy.
2. Od tego jest logrotate, zwykle zainstalowany domyślnie.
3. Wyłączenie sprawdzania systemu plików? Dlaczego? To jest dość ważny element…
4. A może by tak mv zamiast rm? Co po restarcie systemu? „/tmp/dhcpcd.resolv.conf” nie będzie istniało, nie? Trzeba ręcznie tworzyć co restart, albo dodać odpowiedni automat (np. crontab „@reboot”).
5. Rada ok, choć ja tam wolę „relatime” :)
Warto też sprawdzić opcję w nowych kernelach „lazytime”.
6. Albo prościej „poweroff”.
7. Nie mam co do tego pewności, ale jeżeli swap jest zamontowany w systemie, to znaczy, że ta opcja „noswap” raczej nie zadziałała. Rozmiar dostępnego swap powinien być równy zero. Możesz ewentualnie przetestować zajmując dużo pamięci RAM i sprawdzając wtedy, czy coś zostanie przerzucone do swap.
„Nasza karta jest już bezpieczna”
Bezpieczna byłaby, jakbyśmy jej używali w trybie read-only :)
No, ale rozumiem, że to jest zbyt skomplikowane do typowych zastosowań.
Dzięki za cenne uwagi :) Co do logrotate to u mnie w systemie nie mam go domyślnie zainstalwoanego,a znałem wcześniej busyboxa stąd poleciłem go w artykule. Jeśli chodzi o podpunkt 3 i 4 to już poprawione w artykule :) W podpunkcie 7 też dodałem conieco. Po sprawdzeniu cat /proc/meminfo mam w SwapTotal 0kB stąd wnioskuję, że jednak ten swap nie jest używany :)
6. raczej „reboot”
Czy znikanie crontaba po każdym rebootcie maliny to jest ofekt uboczny powyższej procedury, czy też należy szukać przczyny gdzieś indziej ?
Nie zwróciłem na to wcześniej uwagi, ale rzeczywiście za każdym rebootem kasuje to crontaba użytkownika. Analizujac sprawę doszedłem do tego, że crontab usera jest trzymany w /var/spool/cron/crontabs, które przez /var/spool znajduje się za każdm razem w RAMie. Istnieją 2 sposoby na naprawienie tego:
1. Używanie globalnego crontaba poprzez edycję pliku /etc/crontab
2. Przywrócenie folderu /var/spool wpisując najpierw rm -rf /var/spool, a następnie mkdir /var/spool
Dzięki za komentarz, już poprawiam artykuł :)
Dziękuję za odp. To mam jeszcze jeden „efekt uboczny”: otóż od momentu przejścia powyżej procedury nie mogę zalogować sie za pomocą interfejsu graficznego do Pi na innego użytkownika niż root. Natmiast przez PuTTy nie ma problemu.
Tu niestety na chwilę obecną nie jestem w stanie pomóc, bo korzystam z raspberry tylko przez SSH, a nie mam wolnej karty żeby zflashować pełnego graficznego raspbiana.
To musi mieć związek z uprawnieniami do któregoś z katalogów na ramdysku – po przywróceniu fizycznych katalogów problem zniknął.
Nie wiem co robię źle ale po wykonaniu punktu czwartego malina umiera, muszę ją przywracać z backupa. Zainstalowałem system na testy na innej karcie, wykonałem sam punkt czwarty i malina robi kaputt
Dziwne. A sprawdzałeś przed rebootem czy te dowiązania się utworzyły poprawnie?
Tak, sprawdziłem wszystko było poprawnie. Ale za drugim razem wykonałem wszystko oprócz operacji na pliku resolv.conf. i po reboocie wstał. Później zrobiłem dowiązanie i kaputt. wiec gdzieś tu siedzi błąd w mojej malince. W wolnej chwili przeanalizuję to dokładniej a narazie pomijam punkt czwarty. :)
No powiem że ciekawa sprawa. Ja robiłem wszystko na czystym Raspbianie Stretch i nie miałem żadnych problemów. Kilka miesięcy przed pisaniem artykułu robiłem na Jessie i tez bez problemów. Aczkolwiek ja zawsze ściągam obrazy minimalne bez środowiska graficznego, może w tym lezy haczyk? ;)