Franks Raspberry Pi
Ein twitternder Raspberry Pi
aus Altlußheim am Rhein

Log-Dateien in eine Ramdisk!

Dieses Blog ist entstanden, weil nach einigen Monaten mein Raspberry Pi mal wieder ein Problem mit der SD-Karte hatte, das Schreiben auf die Karte funktionierte nicht mehr. Dummerweise sieht man das im laufenden Betrieb nicht, da sieht das Dateisystem so aus, wie es sollte, nur nach einem Reboot sind alle geänderten Daten auf einem alten Stand. Sehr schräg. Ich muss dazu sagen, dass mein Raspberry Pi morgens um sieben Uhr aufwacht (Zeitschaltuhr) und sich abends um zehn selbst herunterfährt (cron), fünf Minuten später schaltet die Zeitschaltuhr den Strom ab.
 
Nachdem dieses Problem nun schon mehrfach aufgetreten ist und ich den Eindruck hatte, dass es immer dann passiert, wenn Transmission viel zu tun hat, denn dann schreibt der Daemon wie wild ins Syslog, musste ich etwas tun... dieses ständige Schreiben ins Syslog ist - nun ja - überflüssig in dem Sinne, dass ich sowieso nicht hinschaue. Da ich allen meinen Raspberry Pis erst gerade Ramdisks verpasst hatte war schnell klar, dass auch diese Logs in eine Ramdisk müssen. Meine normale Ramdisk geht aber nicht, weil die während des Bootprozesses viel zu spät erstellt wird - der rsyslogd soll ja schon hineinschreiben.

/etc/fstab

Die Lösung scheint einfach: In der Datei /etc/fstab für die betreffenden Verzeichnisse eine Ramdisk mounten. Dann ist diese sehr früh im Bootprozess vorhanden und alles wird gut. Also in die /etc/fstab die folgenden Zeilen hinzugefügt:
# tmpfs for some dirs
tmpfs           /var/log        tmpfs   defaults,noatime,mode=0755 0       0
und weil /tmp sowieso beim Booten geleert wird auch noch
tmpfs           /tmp            tmpfs   defaults,noatime,mode=1777 0       0
Neu gebootet - und tatsächlich, das Syslog wird jetzt in eine Ramdisk geschrieben und nicht mehr auf die SD-Karte.

Manche Dienste brauchen ihr Verzeichnis

Dummerweise lief jetzt mein Webserver - lighttpd - nicht mehr. Er möchte beim Start sein Verzeichnis lighttpd in /var/log vorfinden, sonst beendet er sich sofort. Das ist aber in einer Ramdisk - ähem - nicht vorhanden, das Verzeichnis muss also vor dem Start von lighttpd schnell angelegt werden. Vielleicht gibt es ja auch noch andere Dienste, die ihr Verzeichnis in /var/log erwarten und jetzt nicht mehr starten ohne dass ich das bemerkt habe.

/etc/init.d

Wie die Ramdisk aus meinem letzten Blog können auch die Verzeichnisse mit einem init-Script angelegt werden. Nun weiß ich nicht, welche Dienste ihr spezielles Verzeichnis benötigen, deshalb lege ich einfach alle an... Dazu in /etc/fstab die Zeile mit /var/log wieder auskommentiert
# tmpfs           /var/log        tmpfs   defaults,noatime,mode=0755 0       0
und neu gebootet. Jetzt als root in das Verzeichnis gewechselt und alle Verzeichnisse und Unterverzeichnisse herausgeschrieben
root@rpi1:/var/log# ls -al | grep '^d'
drwxr-xr-x 13 root     root       540 Nov  3 14:55 .
drwxr-xr-x 12 root     root      4096 Jan 15  2013 ..
drwxr-xr-x  2 root     root        40 Nov  3 14:55 apt
drwxr-xr-x  2 root     root        60 Nov  3 14:56 ConsoleKit
drwxr-xr-x  2 root     root       100 Nov  3 14:55 cups
drwxr-xr-x  2 root     root        40 Nov  3 14:55 fsck
drwxr-xr-x  2 root     root        40 Nov  3 14:55 hp
drwxr-xr-x  2 www-data www-data    60 Nov  3 14:55 lighttpd
drwxr-xr-x  2 mysql    adm         40 Nov  3 14:55 mysql
drwxr-xr-x  2 root     root       100 Nov  3 14:55 news
drwxr-xr-x  2 ntp      ntp         40 Nov  3 14:55 ntpstats
drwxr-xr-x  3 root     root       200 Nov  3 15:03 samba
drwxr-xr-x  2 root     root        40 Nov  3 14:55 sysstat
Das Verzeichnis samba hat noch Unterverzeichnisse, die brauchen wir auch noch, das schreibe ich jetzt hier aber nicht alles hin. Dann das init-Script daraus gebastelt, interessant sind dabei besonders die Abhängigkeitserklärungen im Kopf, dazu brauchte ich erst einmal das Debian Wiki. Herausgekommen ist das folgende Script, das die Verzeichnisse anlegt, wenn sie noch nicht vorhanden sind (das sollte beim Booten so sein, falls jemand das Script aber später noch einmal aufruft, passiert nichts) und auch die Berechtigungen und Eigentümer setzt.
#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          ramlog
# Required-Start:    $local_fs
# Required-Stop:     $local_fs
# X-Start-Before:    lighttpd samba cups mysql rsyslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Create directories in /var/log
# Description:       Create directories in /var/log
### END INIT INFO

case "$1" in
start)
        cd /var/log
        DIR='apt';              [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='ConsoleKit';       [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='cups';             [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='fsck';             [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='hp';               [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='lighttpd';         [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR; chown www-data:www-data $DIR )
        DIR='mysql';            [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR; chown mysql:adm $DIR )
        DIR='news';             [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='ntpstats';         [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR; chown ntp:ntp $DIR )
        DIR='sysstat';          [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='samba';            [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='samba/cores';      [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='samba/cores/nmbd'; [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='samba/cores/smbd'; [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        DIR='samba/cores/winbindd';     [ -d $DIR ] || ( mkdir $DIR; chmod 755 $DIR )
        ;;

stop)
        ;;

*)
        echo "Usage: /etc/init.d/ramlog {start|stop}"
        exit 1
        ;;
esac

exit 0
Das Script wird unter dem Namen ramlog in /etc/init.d gespeichert. Die Zeile
# X-Start-Before:    lighttpd samba cups mysql rsyslog
definiert, dass das Script vor dem Start der aufgezählten Dienste gestartet werden soll, damit werden die Verzeichnisse angelegt, bevor einer der Dienste darauf zugreifen möchte. Wer andere Dienste verwendet, muss diese Zeile entsprechend anpassen! Jetzt noch
root@rpi1:/etc/init.d# update-rc.d ramlog defaults
aufrufen und das Script wird beim Boot passend gestartet. Nicht vergessen, das Kommentarzeichen in /etc/fstab wieder zu entfernen.
tmpfs           /var/log        tmpfs   defaults,noatime,mode=0755 0       0
Nach dem nächsten Reboot ist /var/log in einer Ramdisk und die benötigten Verzeichnisse sind auch vorhanden. Fertig.

Kommentare und Meinungen sind herzlich willkommen, bitte via Twitter.

Impressum & Datenschutzerklärung