Wie im ersten Teil angekündigt werde ich in diesem Beitrag beschreiben wie man das Raspberry Dateisystem in einen “read-only” Modus versetzt. Der Grund hierfür: Durch das Schreiben von Logdateien etc. “verschleißt” die SD-Karte, denn Flash-Speicherzellen haben eine endliche Anzahl von Schreibzyklen bei der sie zuverlässig arbeiten. Danach kann es zu defekten Dateien bis hin zu einem nicht mehr funktionierendem Dateisystem kommen.
Um dem entgegenzuwirken, wird das komplette Dateisystem schreibgeschützt, da wir in der Regel während des Betriebs keine Dateien persistent auf der Speicherkarte ablegen wollen. Alle Dateien die zur Laufzeit beschrieben werden müssen, werden in eine sogenannte Ramdisk gelegt, also in ein Dateisystem das im Arbeitsspeicher lebt.
Dies bedeutet aber auch, dass all diese Dateien bei einem Neustart verloren sind.
Will man solche Dateien (z.B. Logdateien) für den Fall eines unvorhergesehenen Events (Absturz, Stromausfall) sichern, muss man sich selber darum kümmern diese Datei von Zeit zu Zeit entweder lokal oder remote zu sichern.
Ich habe mich für das Einrichten des read-only Dateisystems recht nah an diesem Blogbeitrag auf Hamspirit.de orientiert. Hier aber nochmal in meinen Worten bzw. mit meinen Kommentaren:
Entfernen von nicht mehr benötigten Diensten
Zuerst entfernen wir Dienstprogramme, die wir in einem read-only Dateisystem nicht mehr benötigen, bzw. die in einem read-only Dateisystem nicht mehr funktionieren.
Für unsere Anwendung sind diese allerdings auch nicht notwendig.
sudo apt-get remove --purge logrotate triggerhappy dphys-swapfile fake-hwclock samba-common sudo apt-get autoremove --purge
Ummappen von Systemverzeichnissen nach /tmp
Einige Programme wollen zur Laufzeit in Dateien schreiben. Diese leiten wir nun nach /tmp um, damit diese auch im read-only Dateisystem einen beschreibbaren Ort haben.
sudo rm -rf /var/lib/dhcp/ /var/spool /var/lock sudo ln -s /tmp /var/lib/dhcp sudo ln -s /tmp /var/spool sudo ln -s /tmp /var/lock sudo mv /etc/resolv.conf /tmp/ sudo ln -s /tmp/resolv.conf /etc/resolv.conf
Einstellungen in der Partitionstabelle
Nun bearbeiten wir /etc/fstab und setzen die boot und root Partitionen auf read-only (“ro”) und erzeugen drei tmpfs Partitionen.
Die hervorgehobenen Anteile müsst ihr in die Datei eintragen, der Rest sollte schon vorhanden sein (die PARTUUID unterscheidet sich auf jedem System)
proc /proc proc defaults 0 0 PARTUUID=d8cc668c-01 /boot vfat ro,defaults 0 2 PARTUUID=d8cc668c-02 / ext4 ro,defaults,noatime 0 1 # a swapfile is not a swap partition, no line here # use dphys-swapfile swap[on|off] for that tmpfs /var/log tmpfs nodev,nosuid 0 0 tmpfs /var/tmp tmpfs nodev,nosuid 0 0 tmpfs /tmp tmpfs nodev,nosuid 0 0
Nun aktivieren wir noch fastboot (wir haben kein beschreibbares Dateisystem und sparen uns somit fsck) und noswap (wir haben kein beschreibbares Dateisystem wo man hinswappen könnte) in der Datei /boot/cmdline.txt.
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fastboot noswap
Alias für rw und ro
Nach einem Neustart würde man nun in einem read-only Dateisystem landen. Um das Dateisystem beschreibbar zu machen, kann man den Befehl sudo mount -o remount,rw / ; sudo mount -o remount,rw /boot nutzen.
Das kann man mit einem bash alias etwas eleganter machen (wie man es eventuell von Pi-Star kennt).
Wir fügen folgendes an die Datei /etc/bash.bashrc an:
set_bash_prompt(){ fs_mode=$(mount | sed -n -e "s/^\/dev\/.* on \/ .*(\(r[w|o]\).*/\1/p") PS1='\[\033[01;32m\]\u@\h${fs_mode:+($fs_mode)}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' } alias ro='sudo mount -o remount,ro / ; sudo mount -o remount,ro /boot' alias rw='sudo mount -o remount,rw / ; sudo mount -o remount,rw /boot' PROMPT_COMMAND=set_bash_prompt
Nachdem man sich neu eingeloggt hat, wird nun in der Kommandozeile angezeigt, ob das Dateisystem aktuell schreibbar ist oder nicht (rw / ro). Mit den Befehlen rw und ro kann nun zwischen den beiden Zuständen gewechselt werden.
Will man nun z.B. die svxlink.conf bearbeiten, muss man vorher in den rw Modus wechseln und danach auch wieder in ro.
Besonderheiten
Zeitsynchronisation
Die der Standarddienst zur Zeitsynchronisation über Netzwerk systemd-timesyncd ist ebenfalls auf beschreibbare Dateien angewiesen, deren Zielorte wir mit obigen Kommandos allerdings nicht nicht abgedeckt haben. Es sind folgende Änderungen notwendig um den Service weiterhin nutzen zu können.
In /lib/systemd/system/systemd-timesyncd.service müssen folgende Zeilen auskommentiert bzw. geändert werden:
#CapabilityBoundingSet=CAP_SYS_TIME #PrivateTmp=yes StateDirectory=
Nach dem Ändern der Datei muss sie mit sudo systemctl daemon-reload neu eingelesen werden. Nach einem Neustart sollte der Dienst seinen Dienst aufnehmen.
Cronjobs
Was wir nun vermissen werden, ist das Dienstprogramm cron. cron legt Dateien werden in /var/spool/crontab abgelegt, was nun auf /tmp gemappt ist und somit beim Reboot verloren geht.
Lösung: Wir können unsere Cronjobs auch einfach in /etc/crontab ablegen.
Dort habe ich nun die Cron calls für die Telemetrie (Temperatur- und Lüftersensor) abgelegt – weitere Infos dazu in einem der nächsten Artikel!
Im nächsten Beitrag werde ich beschreiben welche Anpassungen ich noch an der Konfiguration von svxlink vorgenommen habe, die über die reine Anpassung der Konfigurationsdatei hinausgehen.
Danke Chris für die hervorragende Doku. Ich feue mich schon auf den nächsten Teil.