You are not logged in.
Pages: 1
Runit is designed to work with daemons that stay in the foreground, so that the daemon may be supervised easily. Many daemons do try and run in the background but there is often an option that can be given to tell it to run in the foreground. Thus ntpd can use the -n (--nofork) option to run in the foreground.
Occasionally, there is a daemon which only runs in the background. I have found noip2 which updates my dynamic IP address. I have not found a way to tell it to run in the foreground. There are one or two things which you can do to handle this.
Runit comes with a program to change the process status (chpst).
This has a number of things it can do, such as changing the user or group it runs as.
The options which are useful here are -l & -L which can open a lock file for writing and obtain an exclusive lock on it, creating the file if necessary. -l will wait for the file to become available, while -L will fail immediately if it is not available.
The file /etc/sv/noip2/run looks like this :-
#!/bin/sh -eu
exec 2>&1echo "executing /etc/sv/noip2/run"
chpst -L supervise/runlock /usr/local/bin/noip2 || exit 1
exec chpst -l supervise/runlock true
The echo message is logged if logging has been set up.
The daemon noip2 is run by chpst with an exclusive lock on the file /etc/sv/noip2/supervise/runlock
The second instance of chpst is ready to run the command true and waits for the lock file to become available, i.e. when noip2 stops running. When the lock file becomes available the command true will be run, which returns immediately and runit becomes aware that noip2 is no longer running and can take the appropriate actions.
But what happens if we want to stop the daemon? If
sv down noip2
is run then runit will stop the waiting chpst process, but not noip2.
After it has stopped chpst it will then look for the file finish and run it if it exists.
As we know the name of the lock file, we can find the PID of the process which has it open, using lsof, which may need installing.
apt install lsof
We can find the processes which have the lock file open :-
lsof /run/runit/supervise/noip2/runlock
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
chpst 2006 root 3w REG 0,23 0 1738 /run/runit/supervise/noip2/runlock
noip2 2051 nobody 3w REG 0,23 0 1738 /run/runit/supervise/noip2/runlock
We could find the PID of the daemon by looking through the output for the process run by nobody
and then printing the second field :-
PID=`lsof /run/runit/supervise/noip2/runlock | grep nobody | awk '{ print $2 }' -`
although awk can do the search as well :-
PID=`lsof /run/runit/supervise/noip2/runlock | awk '/nobody/ { print $2 }' -`
However, a study of the lsof man page shows that there are lots of options available and the -t option just prints out the PIDs
lsof -t /run/runit/supervise/noip2/runlock
2006
2051
Also, there is the -c option which can select the process of a particular command or filter out processes of certain commands with the negation ^. In this case we don't want the chpst process.
lsof -t -c ^chpst /run/runit/supervise/noip2/runlock
2051
which can be incorporated into the file /etc/sv/noip2/finish :-
#!/bin/sh
exec 2&>1# use lsof to find the process with a lock on our file.
PID=`lsof -t -c ^chpst /run/runit/supervise/noip2/runlock`
echo "executing /etc/sv/noip2/finish. PID = $PID"
[ -z $PID ] && exit 1
# We could do something like "kill -TERM $PID", but in this case "noip2 -K $PID" works.
/usr/local/bin/noip2 -K $PID
This seems to work nicely. With run and finish set up the daemon can be started, supervised and stopped.
Offline
Pages: 1