Dear community,
I have OpenHABian / OH 4.3 with, well, a number of bindings and rules running on a Raspberry Pi 4 and therefore am very interested in the longevity of my SD card.
Over time (almost 18 months of operation and improvements) I found quite some tricks and hints of how to further and further reduce the number of write actions on the SD and would like to share these experiences with you.
First, there are some cool tools I found for analyzing what is going on:
inotifywait
this is part of the inotify-tools package (sudo apt install inotify-tools).
This sets up watches (even recursively) on directories and tells you which file or which file attributes were changed, causing writes onto the device itâs mounted on.
I used this command for finding when any file on the filesystem was changed:
sudo inotifywait -m -r -e modify,create,delete,attrib / | grep -v -E âtty|/dev/pts/|/var/lib/openhab/persistence|/opt/zram|/var/log/â
with the grep
part filtering out any directories mounted on a tempfs or zram. Let this run for a while, and if you find recurrent writes, you quickly get the candidates for files that could write the SD to death. This tool runs on the filesystem level, and potentially displays stuff which is in reality in a virtual buffer or cache, but is very detailed and file specific.
iotop
this is a standalone tool (sudo apt install iotop
).
you can run it standalone, and it will show you any I/O operations on the storage devices, but itâs a bit hard to watch what is going on because the entries change quickly and the commandlines are often too wide for the screen.
But with sudo iotop -o -b -n 100 | grep mmc
it runs for 100 seconds and geves you filtered operations to the SD card. The fundamental difference to inotifywait is that it does not run on filesystem level but almost on hardware level; if you see a write there, this really means that there was a data flow onto the SD card. Lower level operations like journaling can be seen here as well.
Now to my findings and solutions so far:
General jsondb
- org.openhab.core.config.discovery.DiscoveryResult.json
- StorageHandler.For.OAuthClientService.json
- thing_status_storage.json
- users.json
- the whole backup folder
are files I found quite dynamically modified (partially several times a minute, permanently).
As my impression was that potentially losing the most recent status of these files (autodiscovery results, user logins, online/offline status of Things, backups) would not kill the system, but they nevertheless should stay there, I thought the best solution would be moving these files into the persistence zram and to symlink them to their original location.
So far, for about one year of operation, I never had any negative side effects from this, but a huge reduction of SD writes!
Hue emulation
- hueEmulationUsers.json
I am using this service, and I found the file above updated on every access to the hue bridge - often multiply in one second (!!), and it was just a âlast access timestampâ.
I did the same as in General jsondb - move it into the persistence zram. Works fine!
Samba
I found
- /var/lib/samba/wins.dat
- /var/lib/samba/wins.tdb
modified frequently, about once or twice a minute. Checking out what wins is doing, I saw that this is a discovery service for Microsoft OSes from Windows XP downwards which is required in a network environment with many subnets. Well, I donât have any of them, and I guess most of as wonât have as well. So itâs easy to turn this off completely:
In /etc/samba/smb.conf,
set the following entries:
- wins support = no (itâs âyesâ by default)
- wins server = (just leave empty, itâs commented out by default and has âw.x.y.zâ example)
- disable the wins service:
sudo systemctl stop samba-ad-dc.service
sudo systemctl disable samba-ad-dc.service
- delete the wins files named above
The writes will disappear, the files wonât be recreated. My smb / cifs shares continued working perfectly on my linux machine.
EDIT / Add-on:
********
There also is a directory /var/cache/samba
which contains browse.dat
and smbprofile.tdb.
These files are used by nmbd, and also are frequenty written. Especially for stopping these writes, it is important to disable the samba-ad-dc.service
; only setting wins support = no
does not stop that! When this is done, browse.dat
is no longer written at all, and smbprofile.tdb
is only updated and written on any reboot, but no longer while the system is up and running.
********
Timesync service
In /var/lib/systemd/timesync
, i found a file timer
, which has no content, but has its creation timestamp updated every few seconds, causing masses of journaling writes to the SD card. To my knowledge, this file is used to keep an approximate time for reboot time when NTP sync is not yet up. This functionality is already covered by the fake-hwclock
service, which does the same, but with a 30 or 60 minute cronjob. Also writes, but orders of magnitude less per day.
Good thing is, this behavior of systemd-timesync can be switched off without disabling NTP:
-
create an override file for the service config:
sudo mkdir -p /etc/systemd/system/systemd-timesyncd.service.d
sudo nano /etc/systemd/system/systemd-timesyncd.service.d/override.conf
-
Insert the lines (yes, just empty):
[Service]
StateDirectory=
-
Reload the system config and check the override is working (StateDirectory should be empty and Runtime Directory should be somewhere in /run, which is a tmpfs):
sudo systemctl daemon-reload
systemctl show systemd-timesyncd --no-pager | grep -E âStateDirectory|RuntimeDirectory'
-
Delete the dir / file:
sudo rm -rf /var/lib/systemd/timesync
-
Restart the service:
sudo systemctl restart systemd-timesyncd
With this, the permanent writing is gone permanently, and NTP timesync as such stays fully functional.
Signal
If you use the Signal binding, you can find a folder /signal inside the JSONdb.
Here, the <uid>.d
file is updated whenever the Signal server is contacted, which also sums up to several times a minute even when the account is idle - and every transaction triggers that as well.
This file I found to be better symlinked like described in the âGeneral jsondbâ section.
I hope this helps anyone, and I would be curious for any of your ideas!