Read Only Root - implimentation of OctoPrint

Hello,
I use an RPI as my print server, RPI's are notorious for corrupting SD cards after just a single power failure.

I run all of my RPI's read-only, and recently I've configured a service, to manage octoprint serve on a RO root file system.

Assumes:
You already have a ReadOnly root file system setup on RPI SD card. If not you'll have to google how to get here, as I'm not going over that process.

3 files are created / edited,

New files:

  • /etc/systemd/system/octoprinter.service
  • /usr/bin/octoprint

Edited file

  • /etc/fstab

New directory to save your last configuration before a safe shutdown
mkdir /home/pi/octoprint-lastshutdown

Create the script file
nano /usr/bin/octoprint

#!/bin/bash

ro() {
sudo mount -o remount,ro / ; sudo mount -o remount,ro /boot
}

rw() {
sudo mount -o remount,rw / ; sudo mount -o remount,rw /boot
}

start() {
  rw
  rsync -r /home/pi/octoprint-lastshutdown/ /home/pi/.octoprint
  ro
  octoprint daemon start
}

stop() {
  # copies current runing file to backup.
  octoprint daemon stop
  rw
  rsync -r /home/pi/.octoprint/ /home/pi/octoprint-lastshutdown
  ro
}

case $1 in
  start|stop) "$1" ;;
esac

Create the service
nano /etc/systemd/system/octoprinter.service

octoprinter.service file content

[Unit]
Description=Create RAM disk for octoprint service to run in

[Service]
ExecStart=/usr/bin/octoprint start
ExecStop=/usr/bin/octoprint stop
RemainAfterExit=yes
User=pi

[Install]
WantedBy=multi-user.target

Edit - Create RAM drive to run while in RO root
nano /etc/fstab

tmpfs /home/pi/.octoprint tmpfs nosuid,nodev,size=25120k 0 0

Last you just need to include your new service in systemctrl
systemctl enable octoprinter.service

1 Like

So what I'm reading here is that the script /usr/bin/octoprint manages getting a session ready and finishing it when you're done. It's got a pair of functions ro() and rw() which hide some of the details. Upon startup, you allow writes to the partition, push the last known image over into place (in the working folder) and then prevent writes. Similarly on shutdown, the existing image is saved.

So, additionally you're creating a 25MB RAM disk which represents /home/pi/.octoprint, the working folder.

I'd be interested to know if this plays well with the standard upgrade activities of OctoPrint itself (probably). I'm sure there are times, though, when an individual plugin may want to step outside of the /home/pi/.octoprint folder area there and edit things.

It's possible that a collection of timelapse videos could eat up that 25MB, btw.

1 Like

Yup, you got it.
I wouldn't store images to RAM, if you want to do some time-lapse work I would mount a 2nd UB disk. My experience with RPI, is you never want to do constant read/writes to the sd-card, unless you're running the pi on a battery back up

1 Like

Just a thought, why not use NFS or if it has to be a M$ environment a SMB mount for Octoprint/user stuff ? Have not tried myself, just a quick thought.

Regards
Jan

I had a look some time ago how to do a RO setup, just found that link again which I thought had very good information and may be a good starting point for some people.

http://hallard.me/raspberry-pi-read-only/

Apart from log files and the obvious stuff ppl seem to forget "run" files for processes.....

Jan

Can I assume that the swapfile is still being written to?

I would imagine yes, but I don't think its residing on a physical drive.... can Linux run without swap at all ? Never tried TBH....

JP

The swapfile concept is a part of Debian/Linux and Raspbian in this case. It is of course located on the microSD and works basically like the Windows swapfile concept: when there's too much going on for RAM, things get paged to swap to make room.

I'm pretty sure that swappiness has been changed in Stretch to use it less. And yet, it's probably still active. If your setup marks the swapfile as read-only too then it will behave badly later on if it needs that.

You can turn off swap entirely, it has no negative consequences as long as your RAM is not running full. If RAM is running full and you have no swap, the Linux kernel will start to kill processes. If you have swap and RAM + swap is continually running full, the swap space will only prolong the time until this happens. If RAM is full and swap is nearly full and the system has to swap memory in and out all the time, the system will get very slow, so you should probably get more RAM rather than make swap bigger in that situation.

In short: If your system is very short on RAM in a normal usage situation, you should probably not turn off swap. If you normally have plenty of RAM free in normal operation, then turning swap off entirely should be ok.

If you can add some RAM to my Raspberry, I'll give you a cookie.

1 Like

Touché! :grinning:
I was thinking of people who maybe use a kind of Raspi with less memory like an A+ (like me) or Zero or older models who might think of "upgrading" to a 3B+.

At the moment, I do not have problems with my A+ regarding memory, but I have my cams running on an additional Pi Zero and using the A+ headless, so it only runs OctoPrint and nothing else (besides a bunch of plugins, of course).

I just bought a 3B+, a 3A+ and two more Zeroes for testing and whatever. And I just did a write-up on here regarding the 3A+. I found that if you drop the gpu_mem in config.txt down to 64 or so it will help you out (since you're running headless).

Yes, I have read your other thread. Never had that problems though - I am running OctoPrint 1.3.10 on OctoPi 0.15.1 actually. I have commented the gpu_mem line in config.txt on my 3A+, so default should be 64 already. Memory used running OctoPrint is 120MB.

When I look to my Pi ZeroW running solely the mjpg-streamer processes for my 2 cams (1 PiCam and 1 USB cam), this one takes only about 36MB memory total, although gpu_mem is set to 128 on that machine. So, seems to me that this parameter is not relevant for memory usage if the system is running headless?

No swapfile, If you wanted one, I would suggest a USB disk for swap, vs OS SDcard

Yeah, headless = why bother on the GPU shared memory. It's critical for things like Kivy apps on TFT, for example. Anything that's running OpenGL rendering would need it.

Querying mjpg_streamer's code, though, it does look like GPU is involved for acceleration. What's weird is that I see nowhere where this function is called so I have no idea what the minimum is.

void raspicamcontrol_check_configuration(int min_gpu_mem)
{
   int gpu_mem = raspicamcontrol_get_mem_gpu();
   int supported = 0, detected = 0;
   raspicamcontrol_get_camera(&supported, &detected);
   if (!supported)
      fprintf(stderr,"Camera is not enabled in this build. Try running \"sudo raspi-config\" and ensure that \"camera\" has been enabled\n");
   else if (gpu_mem < min_gpu_mem)
      fprintf(stderr,"Only %dM of gpu_mem is configured. Try running \"sudo raspi-config\" and ensure that \"memory_split\" has a value of %d or greater\n", gpu_mem, min_gpu_mem);
   else if (!detected)
      fprintf(stderr,"Camera is not detected. Please check carefully the camera module is installed correctly\n");
   else
      fprintf(stderr,"Failed to run camera app. Please check for firmware updates\n");
}

Maybe it is just checking for the minimum 16GB like it is mentioned here:

Remember the intent here is an un-foulable RPI system.

Mounting remote file systems and performance improvements are after the fact. Stability is king.

Subscribing, this should be part of the default system.

Now that the Raspberry Pi 4B (with 4GB RAM) is out, I think it's a good time to revisit this topic. With that much RAM, having even a 1GB RAM drive isn't outside of the realm of possibilities.

I'm definitely going to make a stab at this and see what the performance turns out to be.

I hadn't earlier thought much about gcode file uploads but they'll land in this space as well. So the size of the RAM drive needs to hold the entire collection of gcode files and timelapse videos, etc.