Ramdisks for the Raspberry

If you use your Raspberry Pi as a standalone (headless) device, e.g. to measure and log the room temperature, there is no need to write all log files etc. to the SD card. Instead you can mount ramdisks into the relevant directories. This reduces the number of write accesses to the memory card and does not wear out its flash memory.

Raspberry Pi used as a standalone temperature sensor and logger.

Raspberry Pi used as a standalone temperature sensor and logger.

A standalone raspberry might be powered off without shutting down linux by calling halt or shutdown -h now. If there is a write access to the sd card during power off, it might damage the internal filesystem structure and if you are really unlucky (as has happened to me…), the filesystem is damaged in a way that the raspberry cannot boot anymore. Keep in mind to regulary create backups of your sd card!

At least the following directories are written to by the linux system, so they should be mounted to ramdisks:

  • /var/log – System logfiles
  • /var/lock – Lock files for active processes
  • /tmp – Temporary files

You can do this by adding lines to the file /etc/fstab:

The lines starting with tmpfs are the important ones that mount ramdisks to the specified directories. The tmpfs filesystem implements a ramdisk that adapts its memory usage to the space needed in the ramdisk. So you do not need to specify its size in the options of /etc/fstab and consume only as much ram as is needed by the files in the ramdisk.

If you use a webserver like apache or nginx on the raspberry, you need to take care of the directory where the server stores its logfiles. This is /var/log/apache or /var/log/nginx. Both webservers do not create this directory if it is missing and do not start. So you need a solution to create this log directory, before the webserver process is started.

Therefore I have written an init script named prepare-dirs that creates this directory, in my case for the nginx webserver.

The script should be put into /etc/init.d and enabled in the boot process by calling

This creates links in the /etc/rcX.d directories and makes sure that the script is called with the start or stop parameter when entering or leaving the corresponding runlevels. If you want to know more about the boot procedure on raspbian, see the Upstart Website or the Upstart Wikipedia entry.

The numbers 01 and 99 tell update-rc.d to place the execution of the script at the beginning of the boot process and and the end of the shutdown process. The nginx webserver e.g. has the boot priority 02 by default, so it is started after the prepare-dirs script has been executed.

After editing /etc/fstab and setting up the init script, you should reboot the raspberry, so the ramdisks get mounted. You can check if everything works correctly by calling mount. It should print out a list with all mounted filesystems as specified in /etc/fstab.

With this setup you can prevent most of the write accesses to the sd card. To guarantee that the root filesystem (the one containing the data on the sd card) is never modified, it should be to mounted read-only, so that it cannot be damaged in any way. I hope to have enough time in the next days to try that out.

Update (2015-03-17)

Here the improved script of Tom from the comment below, so there are no problems with copy and pasting and the quotation marks modified by wordpress:

17 thoughts on “Ramdisks for the Raspberry

  1. you can also disable sound:
    mv /lib/modules/$(uname -r)/kernel/sound /lib/modules/$(uname -r)/kernel/sound.disable
    that make more free RAM for your applications

  2. This will not work unless you change the rights on the script, before running update-rc.d:

    chmod 0755 /etc/init.d/prepare-dirs

  3. Einige der mounts kann man sich schenken, wenn man /etc/default/tmpfs richtig konfiguriert:

    RAMLOCK=yes
    RAMSHM=yes
    RAMTMP=yes

    TMPFS_SIZE=10%VM
    RUN_SIZE=10M
    LOCK_SIZE=5M
    SHM_SIZE=10M
    TMP_SIZE=25M

    In meinem Fall würde dann in /etc/fstab nur noch folgendes stehen:

    tmpfs /var/log tmpfs size=20M,defaults,noatime,mode=0755 0 0
    tmpfs /var/cache/apt/archives tmpfs size=100M,defaults,noexec,nosuid,nodev,mode=0755 0 0
    tmpfs /var/spool/cups tmpfs size=100M,defaults,noatime,mode=0755 0 0
    tmpfs /var/spool/cups/tmp tmpfs defaults,noatime,mode=0755 0 0

    Die CUPS-Einträge sind nur bei einem Printserver notwendig.

  4. Eine verbesserte Version des Scripts für mehrere Verzeichnisse würde übrigens wie folgt aussehen:

    #!/bin/bash
    #
    ### BEGIN INIT INFO
    # Provides: prepare-dirs
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Required-Start:
    # Required-Stop:
    # Short-Description: Create needed directories on /var/log/ for tmpfs at startup
    # Description: Create needed directories on /var/log/ for tmpfs at startup
    ### END INIT INFO

    # needed Dirs
    DIR[0]=/var/log/nginx
    DIR[1]=/var/log/apache2
    DIR[2]=/var/log/apt
    DIR[3]=/var/log/ConsoleKit
    DIR[4]=/var/log/fsck
    DIR[5]=/var/log/news
    DIR[6]=/var/log/ntpstats
    DIR[7]=/var/log/samba
    DIR[8]=/var/log/lastlog
    DIR[9]=/var/log/trafficserver

    case “${1:-”}” in
    start)
    typeset -i i=0 max=${#DIR[*]}
    while (( i < max ))
    do
    mkdir ${DIR[$i]}
    chmod 755 ${DIR[$i]}
    i=i+1
    done
    # set rights
    chown trafficserver ${DIR[9]}
    ;;
    stop)
    ;;
    restart)
    ;;
    reload|force-reload)
    ;;
    status)
    ;;
    *)
    echo "Usage: $SELF start"
    exit 1
    ;;
    esac

    Danke an http://grenzdebiel.dyndns.org/wordpress/?p=98 für das Script.

  5. Here is an extended version of Gunther’s script where custom permissions can be configured in the PRM array. Plus, the script can handle missing index numbers for the DIR and PRM arrays. Thus, it is not necessary to renumber array elements when adding or removing entries and to define PRM array values for all DIR array elements. Of course all array indexes must be unique.

    #!/bin/bash
    #
    ### BEGIN INIT INFO
    # Provides: prepare-dirs
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Required-Start:
    # Required-Stop:
    # Short-Description: Create needed directories on /var/log/ for tmpfs at startup
    # Description: Create needed directories on /var/log/ for tmpfs at startup
    ### END INIT INFO

    # needed Dirs
    DIR[0]=/var/log/apt
    DIR[1]=/var/log/fsck
    DIR[2]=/var/log/lighttpd
    PRM[2]=”www-data.www-data”
    DIR[3]=/var/log/stunnel4
    PRM[3]=”stunnel4.stunnel4″

    case “${1:-”}” in
    start)
    typeset -i i=0 max=$(echo “${!DIR[*]}” | tr ” ” “\n” | sort -nr | head -n1)
    while (( i <= max ));do
    if [ -n "${DIR[$i]}" ];then
    mkdir -p ${DIR[$i]}
    chmod 755 ${DIR[$i]}
    fi
    i=i+1
    done
    # set rights
    typeset -i i=0 max=$(echo "${!PRM[*]}" | tr " " "\n" | sort -nr | head -n1)
    while (( i <= max ));do
    if [ -n "${PRM[$i]}" ];then
    chown -R ${PRM[$i]} ${DIR[$i]}
    fi
    i=i+1
    done
    ;;
    stop)
    ;;
    restart)
    ;;
    reload|force-reload)
    ;;
    status)
    ;;
    *)
    echo "Usage: $SELF start"
    exit 1
    ;;
    esac

  6. An addition to the script above: Please check all single and double quotes when copy&pasting this script, as wordpress replaces them in comments.

  7. @Tom:
    Can you please explan what you mean by:

    “Please check all single and double quotes when copy&pasting this script, as wordpress replaces them in comments.”

    Can’t I just copy&paste the last script?
    Or could the blog admin please post the correct last script with the code editor feature above, so that copy&paste is possible?

  8. @Andreas:
    Thank you very much for the addition of the copy&paste area for the extended script by Tom.

  9. In the copy&paste area of Tom’s script, I have found a typo.
    Right after the array of DIRs and PRMs,

    case “${1:-“}” in
    has to be replaced by
    case “${1:-}” in

    After that change, the copy&paste-area-code works!

    Greetings,
    Heiko

  10. Thank you for this, and your other post about ramdisks. Just one thing – I could be mistaken but has /var/lock been replaced by /run/lock since you wrote this post? If so, the current Raspbian build appears to mount it as a ramdisk by default.

  11. Hi Gavin, I just had a short look into this. I think you’re right. There now is a directory /run/lock mounted as a ramdisk in the current Raspbian version.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.