Here my rather lengthy post about what I did to use ZRAMs daily sync:
Motivation:
- After a power failure OpenHABs persistence is lost up to point in time when ZRAM did last syncronize the persistence folder to SD card.
- After a power failure ZRAM does not start - see: https://github.com/ecdye/zram-config/issues/142 but mentioned fix did not work for me.
- Current default ZRAM config for OpenHAB does not allow online ZRAM sync - Openhab service is stopped and after Zsync started again. I dont like that.
- When doing a “online” ZRAM sync OpenHAB RRD4j and MapDB persistance may fail - no system likes messing with files it wants to acces, results in loss of data.
- When doing a “online” ZRAM sync OpenHAB logging to openhab.log file will stop . (But it may be waken up by Karaf console e.g. by command log:tail).
My Setup:
Openhab 5.1.4 on a Raspi 4 with 2 GB of RAM.
This was set up by using OpenHABian v1.11.0. 32GB SD Card.
RaspiOS: Release = Debian GNU/Linux 12 (bookworm) , Kernel = Linux 6.6.62+rpt-rpi-v8
app. 800 Items, app. 500 items are persisted by RRD4j by every6sec and restoreOnStartup strategy. No other persistence service is running.
Workaround overview:
- Modify zram-config so OpenHAB service is not restated.
- ZRAM sync just the folder holding persistance database files.
- Pause RRD4j persistence logging to allow safe online Zram sync.
- Create a systemd timer and service to ZRAM sync once each day.
- Detect if Raspi was restarted right after a power fail and do a 2nd (clean) restart if so.
If you plan to implement the workaround it is time now to do some kind of backup - e.g. OpenHAB config backup using “sudo openhab-config” and menue pt. 50
Workaround steps in detail:
1) Modify zram-config so OpenHAB service is not restated running “zram-config sync”.
Default Openhabian setting for ZRAM sync will stop all related services to do a clean syncronisation to SD card.
For sure this is the safest/cleanest way to do a sync, but I really dont like that so many services are pulled down and started up again. Things can go wrong during service startups, clients may not be logging in,…
1.1) Change zram-config file to not shut down OpenHAB and related services:
I am using default zram-config from ZRAM-config github from here: zram-config/zram-config at main · ecdye/zram-config · GitHub
This can be done like this:
1.1.1) Log into host (openhabian) running OpenHAB.
1.1.2) Stop OpenHAB service: sudo systemctl stop openhab.service
1.1.3) Stop ZRAM service: sudo systemctl stop zram-config.service
Check if ZRAM stopped clean: zramctl … should not give any response, if yes delete listed “ghost” zram device e.g. sudo rm /dev/zram2
1.1.4) Remove zram-config file: sudo rm /usr/local/sbin/zram-config
1.1.5) Create a new one, copy the github zram-config to /usr/local/sbin/zram-config or use nano editor: sudo nano /usr/local/sbin/zram-config
1.1.6) paste all the content of zram-config/zram-config at main · ecdye/zram-config · GitHub and finish nano editor with “strg + X” and y to save
1.1.7) Make zram-config executable: sudo chmod 777 /usr/local/sbin/zram-config
2) Modify zram-sync to syncronize just the folder holding persistance database files.
ZRAM sync allows to add a target folder option for syncronisation - I just want to syncronize /var/lib/openhab/persistence
Also stop rrd4j persistence from writing to persistance rrd files during syncronisation (see also next pt. 3)
2.1) Create special zram-sync bash script: zram-oh-persistence-sync
This can be done like this using nano editor:
2.1.1) sudo nano /usr/local/sbin/zram-oh-persistence-sync
2.1.2) paste following text:
#!/usr/bin/env bash
cp /etc/openhab/persistence/rrd4j-empty.txt /etc/openhab/persistence/rrd4j.persist
echo "Persistence strategies emptied...now waiting 30 sec"
sleep 30
/usr/local/sbin/zram-config sync /var/lib/openhab/persistence
echo "Finished running: /usr/local/sbin/zram-config sync /var/lib/openhab/persistence ...now waiting 60 sec"
sleep 60
cp /etc/openhab/persistence/rrd4j-ok.txt /etc/openhab/persistence/rrd4j.persist
echo "Persistence strategies restored"
exit 0
2.1.3) A strg + X followed by y …saves the file
2.1.4) sudo chmod 777 /usr/local/sbin/zram-oh-persistence-sync … sets it executable
3) Pause RRD4j persistence logging to allow safe online Zram sync.
The idea is to temporerally persist no items during zram-sync and persist normally when zram-sync is done.
Persistence in OpenHAB can be defined via UI or via a setup file for rrd4j called: /etc/openhab/persistence/rrd4j.persist.
If the setup file exists it is used. Changes in persistence via UI is disabled. Changes in setup file are taken into account on the fly.
So 2 files must be created one for no persistance and one for your normal persistance strategies setup.
3.1) Create a file which will persists zero items - used during syncronisation
3.1.1) sudo nano /etc/openhab/persistence/rrd4j-empty.txt
3.1.2) paste following text:
Strategies {
every6sec : "0/6 * * * * ? *"
}
Items {
// File: /etc/openhab/persistence/rrd4j.persist
// Temporarily left empty to pause persistence
}
3.1.3) A strg + X followed by y …saves the file
3.2) Create a file which will persists all items/groups you want persisted. (Here my file, change to your needs !)
3.2.1) sudo nano /etc/openhab/persistence/rrd4j-ok.txt
3.2.2) paste following text (Thats the file I use, change to your needs):
Strategies {
every6sec : "0/6 * * * * ? *"
}
Items {
// File: /etc/openhab/persistence/rrd4j.persist
// Persist all Items from these Groups
Elektroheizung*, Energiemessung1*, GoeCharger*, Heizung*, PV_Wechselrichter*, RaspberryPi*, Raum1_Thermometer*, Raum2_Thermometer*, Raum3_Thermometer*, Shelly_Heizung*, Stadel_PV*, Stromzaehler*, Thermische_Solaranlage*, Warmwasser_Boiler*, Wasserpumpe* : strategy = every6sec, restoreOnStartup
}
3.2.3) A strg + X followed by y …saves the file
I had to switch from UI persistence setup to file based persistance setup.
First I created a correct /etc/openhab/persistence/rrd4j.persist file which reflected UI setup. Then restarted OpenHAB so persistence switched over to file based setup.
Now call up UI page for persistence and go to RRD4j configuration. If it looks like you still are able to do modifications via UI you should correct this:
Press red Remove persistence configuration link at the bottom of the config page and OK the popup and finally Save (upper right corner).
Calling up the RRD4j Config page again should show now: Note: This persistence configuration is not editable because it has been provisioned from a file.
Check OH documentation for persistence here: Persistence | openHAB
4) Create a systemd timer and service to ZRAM sync once each day.
The above created /usr/local/sbin/zram-oh-persistence-sync file has to be started once a day to do syncronisation.
So 2 systemd files are created one timer and one service file called by the timer
4.1) Create new zsync timer systemd file
4.1.1) sudo nano /etc/systemd/system/zsync-oh-persistence.timer
4.1.2) paste following text
[Unit]
Description=Perform nightly zram sync to persistent storage (only OpenHab Persistence)
[Timer]
Unit=zsync-oh-persistence.service
OnCalendar=*-*-* 23:15
RandomizedDelaySec=10m
Persistent=true
[Install]
WantedBy=timers.target
4.1.3) A strg + X followed by y …saves the file
So with this timer the sync takes place at around 23:15 , you may change this to your needs.
4.2) Create new zsync service systemd file
4.2.1) sudo nano /etc/systemd/system/zsync-oh-persistence.service
4.2.2) paste following text
[Unit]
Description=Perform nightly zram sync to persistent storage (only OpenHab Persistance)
After=zram-config.service
Wants=zsync-oh-persistence.timer
[Service]
Type=oneshot
Environment=SERVICE=1
ExecStart=/usr/local/sbin/zram-oh-persistence-sync
4.2.3) A strg + X followed by y …saves the file
4.3) Enable and start the new timer and service file
4.3.1) sudo systemctl start zsync-oh-persistence.timer
4.3.2) sudo systemctl enable zsync-oh-persistence.timer
4.3.3) sudo systemctl daemon-reload
5) Detect if Raspi was restarted right after a power fail and do a 2nd (clean) restart if so.
When a power fail occurs there is a high chance that ZRAM will not start up correctly.
This happenes on my system and is also described here: Zram is not loaded after a power outage · Issue #142 · ecdye/zram-config · GitHub
The mentioned fix did not work for me, so following my brutal fix…to detect power fail and restart a 2nd time if booting was after a power failure
At Raspi startup a file is checked for existance and gets created. At an orderly shutdown this file gets deleted.
So if this file exist at startup boot up was right after a power fail and a reboot command is fired up.
5.1) Create a bash script to do the “magic” decribed above.
5.1.1) sudo nano /bin/powercheck
5.1.2) paste following text
#!/bin/sh
FLAG1=/etc/poweroff-flag-file
FLAG2=/etc/bad-reboot-flag-file
if [ "$1" = "start" ]; then
if [ -f "$FLAG1" ]; then
echo "Detected impropert shutdown" >&2
(
echo 'Detected improper reboot'
rm -f $FLAG1
echo "Power fail detected" > $FLAG1
rm -f $FLAG2
echo "Power fail detected" > $FLAG2
echo "So reboot now again..." >> $FLAG2
date >> "$FLAG2"
reboot
)
fi
date >> "$FLAG1"
elif [ "$1" = "stop" ]; then
rm -f $FLAG1
fi
5.1.3) A strg + X followed by y …saves the file
5.1.4) sudo chmod 777 /bin/powercheck … sets it to executable
5.2) Create a systemd service to have the bash script run a boot and shutdown.
5.2.1) sudo nano /etc/systemd/system/powercheck.service
5.2.2) paste following text
[Unit]
Description=Detect if system was shut down cleanly
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/powercheck start
ExecStop=/bin/powercheck stop
[Install]
WantedBy=multi-user.target
5.2.3) A strg + X followed by y …saves the file
5.2.4) sudo systemctl start powercheck.service
5.2.5) sudo systemctl enable powercheck.service
5.2.6) sudo systemctl daemon-reload
Its also a good idea to finally reboot your OpenHAB host using : sudo reboot
Notes:
-
I did test 15 times a zram-sync followed by a power fail - all ok, no loss of data. And about 60 times a zram-sync which is done then automatically on a daily basis - all ok.
-
Actual zram-config included a “bind_dir” folder in /etc/ztab config file. This is now removed, automatically if old version of ztab is detected.
-
I deleted MapDB persistance and only use now RRD4j - also to restore items on startup (Strategy: restoreOnStartup). My tests where showing that MapDB stops working once it is “online” synced. Keep in mind that RRD4j just saves numbers and status of switches.
-
I changed also my ztab file (very optional - zram must be stopped during editing!), my /etc/ztab file looks like this:
# swap alg mem_limit disk_size swap_priority page-cluster swappiness
swap lzo-rle 200M 1G 75 0 150
# dir alg mem_limit disk_size target_dir
dir lzo-rle 800M 2G /var/lib/openhab/persistence
# log alg mem_limit disk_size target_dir oldlog_dir
log lzo-rle 400M 1G /var/log