lxmd and rnsd service
Started by Anonymous ·
Hi,
can you share how your rnsd+lxmd setup looks like? I currently have both running as systemd service files, but on bootup lxmd does not boot properly for some reason. I have to stop it and then start it again so it works.
Here are my service files:
lxmd:
# /etc/systemd/system/lxmd.service
[Unit]
Description=LFXC daemon propagation node
Requires=rnsd.service
After=rnsd.service
[Service]
Type=simple
Restart=always
RestartSec=3
User=rns
ExecStart=/home/rns/.local/bin/lxmd --propagation-node --service
[Install]
WantedBy=multi-user.target
and rnsd:
# /etc/systemd/system/rnsd.service
[Unit]
Description=Reticulum Network Stack Daemon
After=multi-user.target
[Service]
# If you run Reticulum on WiFi devices,
# or other devices that need some extra
# time to initialise, you might want to
# add a short delay before Reticulum is
# started by systemd:
# ExecStartPre=/bin/sleep 10
Type=simple
Restart=always
RestartSec=3
User=rns
ExecStart=/home/rns/.local/bin/rnsd --service
[Install]
WantedBy=multi-user.target
To troubleshoot, it's worth running:
systemctl status lxmd.service
I recommend just starting NomadNet with systemd and letting it handle the rest. To start nomadnet in daemon mode, use:
nomadnet --daemon
I am a bit confused how the daemons work with each other, maybe because the documentation is very bare on this side. You mean by starting nomadnet it would also start rnsd and a propagation node?
Aha, I see. lxmd seems to start up rnsd automatically. I removed the rnsd service file and instead start now only lxmd. seems to work.
hi!!, for rnsd, i use [Unit] Description=Reticulum Network Stack Daemon After=network.target
[Service] ExecStart=<folderwherernsislocatedin>/rnsd Restart=always User=<yourusername>
[Install] WantedBy=multi-user.target
test
None of these are reliable options. You need to watch the logs to know when RNS is fully started and it's ok to start lxmd and NomadNet. To do that you need wrapper scripts that fork off the rnsd process and don't end themselves until the logs indicate that RNS is fully started. This allows you to use the systemd functionality for making sure the different services start in sequence, without having to rely on timers which will get flaky when RNS has to load a lot of path table entries on startup.
/etc/systemd/system/rnsd.service:
[Unit]
Description=Reticulum rnsd Service
After=network-online.target
Requires=network-online.target
StartLimitIntervalSec=60
StartLimitBurst=4
[Service]
Type=forking
ExecStart="/path/to/start_rnsd.sh"
ExecStop="/path/to/stop_rnsd.sh"
Restart=always
RestartSec=3
Nice=-10
Environment="PYTHONPATH='/home/rns/Reticulum':'/home/rns/LXMF':'/home/rns/NomadNet'"
WorkingDirectory=~
User=rns
Group=reticulum
[Install]
WantedBy=multi-user.target
start_rnsd.sh:
#!/bin/bash
set -e
LOG="/path/to/reticulum/logfile"
LOGLINES=0
if [ -f $LOG ]; then
LOGLINES=$(wc -l < $LOG)
fi
echo "Starting rnsd service"
export PYTHONPATH='/home/rns/Reticulum':'/home/rns/LXMF':'/home/rns/NomadNet'
python3 -m "RNS.Utilities.rnsd" --service --config "/home/rns/config/reticulum" &
echo "Waiting for rnsd service to fully start"
while true; do
NEWLOGLINES=$(wc -l < $LOG)
if [ "$NEWLOGLINES" -lt "$LOGLINES" ] ; then
# The log must have rotated since the start of the script
TAILCMD="cat $LOG"
else
TAILCMD="tail -n +$LOGLINES $LOG"
fi
if $($TAILCMD | grep -q -E "Started rnsd"); then
break
else
sleep 1
fi
done
echo "Started rnsd service"
stop_rnsd.sh
#!/bin/bash
set -e
LOG="/path/to/reticulum/logfile"
LOGLINES=0
if [ -f $LOG ]; then
LOGLINES=$(wc -l < $LOG)
fi
echo "Stopping rnsd service"
kill $MAINPID
echo "Waiting for rnsd service to fully shut down"
while true; do
NEWLOGLINES=$(wc -l < $LOG)
if [ "$NEWLOGLINES" -lt "$LOGLINES" ] ; then
# The log must have rotated since the start of the script
TAILCMD="cat $LOG"
else
TAILCMD="tail -n +$LOGLINES $LOG"
fi
if $($TAILCMD | grep -q -E "Saved known destinations to storage"); then
break
else
sleep 1
fi
done
echo "Stopped rnsd service"
Note that I run my node from source for easier development, so you'll have to change the command to run rnsd to whatever you need for your environment, and you can also remove the Environment=... line from the service file.
The lxmd service definition will look similar, but depending on the rnsd service:
After=rnsd.service
Requires=rnsd.service
And the start and stop scripts should grep for "Started lxmd" and "All interfaces detached", respectively (and naturally should be changed to run the right command).
For NomadNet, grep for "ready for incoming connections" and "Persisting LXMF state data to storage".
I have all of this abstracted in an Ansible playbook that I use to deploy my public node. I will release it at some point, once I get things cleaned up and documented a bit.
Thank you for sharing! This is more complicated then I hoped ^^ but makes sense that it will work that way.
I just check for port 4242 being open before starting lxmd. In lxmd.service:
ExecStartPre=/usr/bin/bash -c '(while ! ss -lnt sport = :4242 | grep 4242 2>/dev/null; do echo "Waiting for port 4242 to open..."; sleep 3; done); sleep 3'
K8's solution is more thorough though, and I would think more reliable. The port being open doesn't necessarily mean that rnsd is ready, so YMMV, but it has worked well for me so far.
Anonymous wrote:
I am a bit confused how the daemons work with each other, maybe because the documentation is very bare on this side. You mean by starting nomadnet it would also start rnsd and a propagation node?
It's explained here: https://reticulum.miraheze.org/wiki/RNS#Shared_instance
Running (only) lxmd sounds like the right choice for you. nomadnet seems to have memory leaks, so I'd not run that as a daemon unless I also needed to serve pages/files.
Running rnsd first makes sense in some situations. From the manual:
If you are running Reticulum on a system with several different programs that use RNS starting and terminating at different times, it will be advantageous to run a master RNS instance as a daemon for other programs to use on demand.
And the start and stop scripts should grep for "Started lxmd" and "All interfaces detached", respectively (and naturally should be changed to run the right command).
For NomadNet, grep for "ready for incoming connections" and "Persisting LXMF state data to storage".
You got NomadNet and lxmd mixed up there, but otherwise, nice!
I encountered a very similar problem when trying to run an rnsd.service and a rnsh.service, basically the same setup you're describing here but with rnsh instead of lxmd. After hours of debugging, I finally figured out that it seemed to be some kind of systemd dependency loop that blocked the second service (lxmd or rnsh) from being started automatically. The solution that worked for me was to remove the line After=multi-user.target from the rnsd.service file and then everything worked as I wanted it to. It is also possible that the version of this problem I encountered is different than it would be elsewhere because it was with the resource constraints of a little RPi Zero 2w.
Another tip is that the debugging step that was most helpful for me to figure out what was going on was to enable LogLevel=debug in /etc/systemd/system.conf which gave more traces in journalctl -b of the interactions between the two services during boot.
Hopefully this is helpful to you and others with similar problems. It makes me wonder if there could be reason to remove or modify (or at least add a comment note) to the manual's template for an rnsd.service file that includes After=multi-user.target: https://github.com/markqvist/Reticulum/blob/master/docs/manual/using.html#L1234 but maybe there are other reasons for it to be there that I'm less aware of and would make the decision to change or remove it more complicated.
Cleeyv wrote:
I encountered a very similar problem when trying to run an rnsd.service and a rnsh.service, basically the same setup you're describing here but with rnsh instead of lxmd. After hours of debugging, I finally figured out that it seemed to be some kind of systemd dependency loop that blocked the second service (lxmd or rnsh) from being started automatically. The solution that worked for me was to remove the line
After=multi-user.targetfrom the rnsd.service file and then everything worked as I wanted it to. It is also possible that the version of this problem I encountered is different than it would be elsewhere because it was with the resource constraints of a little RPi Zero 2w.Another tip is that the debugging step that was most helpful for me to figure out what was going on was to enable
LogLevel=debugin /etc/systemd/system.conf which gave more traces injournalctl -bof the interactions between the two services during boot.Hopefully this is helpful to you and others with similar problems. It makes me wonder if there could be reason to remove or modify (or at least add a comment note) to the manual's template for an rnsd.service file that includes
After=multi-user.target: https://github.com/markqvist/Reticulum/blob/master/docs/manual/using.html#L1234 but maybe there are other reasons for it to be there that I'm less aware of and would make the decision to change or remove it more complicated.
You could message mark about it. Or maybe even better, we could create a page on the community wiki about running rnsd etc as a service?
@Anonymous#11 I think that part is correct. The different services all have inconsistent log output and those messages are the closest I was able to get the the real start and end (even though for NomadNet the last log message is talking about LXMF).
Anonymous wrote:
Hi,
can you share how your rnsd+lxmd setup looks like? I currently have both running as systemd service files, but on bootup lxmd does not boot properly for some reason. I have to stop it and then start it again so it works.
Here are my service files:
lxmd:
# /etc/systemd/system/lxmd.service [Unit] Description=LFXC daemon propagation node Requires=rnsd.service After=rnsd.service [Service] Type=simple Restart=always RestartSec=3 User=rns ExecStart=/home/rns/.local/bin/lxmd --propagation-node --service [Install] WantedBy=multi-user.targetand rnsd:
# /etc/systemd/system/rnsd.service [Unit] Description=Reticulum Network Stack Daemon After=multi-user.target [Service] # If you run Reticulum on WiFi devices, # or other devices that need some extra # time to initialise, you might want to # add a short delay before Reticulum is # started by systemd: # ExecStartPre=/bin/sleep 10 Type=simple Restart=always RestartSec=3 User=rns ExecStart=/home/rns/.local/bin/rnsd --service [Install] WantedBy=multi-user.target
Just run a simple lxmd startup script and that will bring up rnsd automatically. This is what I use:
[Unit] Description=Lightweight Extensible Message Daemon After=multi-user.target
[Service]
If you run Reticulum on WiFi devices,
or other devices that need some extra
time to initialise, you might want to
add a short delay before Reticulum is
started by systemd:
ExecStartPre=/bin/sleep 10
Type=simple Restart=always RestartSec=3 User=liberty ExecStart=lxmd --service
[Install] WantedBy=multi-user.target