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.confdo 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.

11 myśli nt. „Raspberry Pi – Na ratunek karcie pamięci

  1. pm7

    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ń.

    Odpowiedz
    1. Kamil Autor wpisu

      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 :)

      Odpowiedz
  2. km

    Czy znikanie crontaba po każdym rebootcie maliny to jest ofekt uboczny powyższej procedury, czy też należy szukać przczyny gdzieś indziej ?

    Odpowiedz
    1. Kamil Autor wpisu

      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ł :)

      Odpowiedz
  3. KM

    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.

    Odpowiedz
    1. Kamil Autor wpisu

      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.

      Odpowiedz
  4. KM

    To musi mieć związek z uprawnieniami do któregoś z katalogów na ramdysku – po przywróceniu fizycznych katalogów problem zniknął.

    Odpowiedz
  5. Heniek

    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

    Odpowiedz
    1. Kamil Autor wpisu

      Dziwne. A sprawdzałeś przed rebootem czy te dowiązania się utworzyły poprawnie?

      Odpowiedz
      1. Heniek

        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. :)

        Odpowiedz
        1. Kamil Autor wpisu

          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? ;)

          Odpowiedz

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *