You are not logged in.
Pages: 1
Hi.
I went on IRC #devuan today, as I had issues with the cursed udevd daemon starting outside of runit's supervision, which was new and I suspected it caused me some issues. There, along the discussion, I got asked to shared my old scripts with a person named Lorenzo, so here I am.
I do not which ones of my runit scripts could be of use, since let's be honest, most of them are a dead simple. The process is dead simple: read the daemon's manual, search for the word: "PID", "fork", "background", "syslog"... this kind of stuff. Note the option that allows to disable those "features". Usually, it means running in what the author call "debug mode", and write your one-liner...
There are few exceptions, though, the most notable one being the cursed udevd. This is technically NOT my script, at least the ugly trick is something I've found like 10 years ago on some random blog post. I do not want to claim I did it, but this really helped me back then and I am unable to find anew the original author. I have integrated it along my system, as well, so I modified it a tiny bit.
DISCLAIMER: my computers are a mess, and I have several variants of some of those scripts, for random and idiotic reasons. Some are cleaner than others... I've been carrying those things since a decade, after all.
Here is the /etc/sv/udev cursed script, adapted to devuan (because debian ofc can't refrain shuffling files randomly every major version they do, and devuan fixed that toward the sane way... /complains):
#!/bin/sh
. /etc/runit/common
need()
{
i=0
while ! test -e "$1"
do
sleep "0.$i"
test "$i" = 9 || i=$((i+1))
done
}
mkdir -p /run/udev
rm -f /run/udev/control #just in case
rm -f /run/udevd_ready #just in case
(
need /run/udev/control # not sure we really need to wait for it
echo "Trigger+settle:"
udevadm --debug trigger --type=subsystems --action=add
udevadm --debug trigger --type=devices --action=add
udevadm --debug settle
>/run/udevd_ready
echo "Done: trigger+settle"
) &
echo "Starting $SVNAME"
exec env - PATH="$PATH" /usr/sbin/udevd -N lateIt starts, like all my runit scripts, by sourcing a single, trivial script I name /etc/runit/common:
#!/bin/sh
#this file provides some automatic features for runit daemons
#notably it:
#* provides the variable SVNAME, which is the name of the daemon dir
#* provides the die() function
#* sources an existing ./conf file
#* automatically rotates logs on startup if there are logs and AUTO_ROTATE=yes
#* redirects stderr to stdout
#* enables some shell verbosity and safeties (-xe)
die()
{
printf "%s\n" "$@" | tee ./down
exit 1
}
SVNAME="$(basename $(pwd))"
HAS_LOG="$(test -d "$(pwd)/log" && printf "yes")"
exec 0<&-
exec 2>&1
set -xe
test -f conf && . ./conf
if test "$0" = "run"
then
if test "$SVNAME" = "log"
then
SVLOG="$(basename $(dirname $(pwd)))"
SVNAME="${SVLOG}/${SVNAME}"
AUTO_ROTATE="${AUTO_ROTATE:="no"}"
fi
test "yes" = "${AUTO_ROTATE}" -a "yes" = "$HAS_LOG" && \
sv alarm "$(pwd)/log"
fiI also have a generic logger, so when I create a new service, I only create the log dir, and symlink it as "run", so it's named /etc/runit/log.run:
#!/bin/sh
SVLOG="$(basename $(dirname $(pwd)))"
LOG_PATH="/var/log/$SVLOG"
test -e "$LOG_PATH" || install -d -m 0750 -o root -g adm "$LOG_PATH"
exec svlogd -tt "$LOG_PATH"I also have /etc/runit/global.finish which does not do much:
#!/bin/sh
. /etc/runit/common
echo "Stopped $SVNAME"Maybe my networking stuff may be of interest, as I do not use ifupdown, networkd or whatever...
#!/bin/sh
. /etc/runit/common
ip l set $IFACE up
if test -e /sbin/ethtool
then
while $(/sbin/ethtool $IFACE | grep -q 'Link detected: no')
do
test "$VERBOSE" = "yes" && echo "$IFACE unplugged, sleep ${SLEEP:=60}"
sleep ${SLEEP:=60}
done
fi
echo "Starting $SVNAME on $IFACE"
exec udhcpc -i $IFACE -f -R -nThis stuff is not worth much, but apparently nothing does that kind of things in devuan? Or I could not find it, which seems more likely. I've been using those (or slight modifications, I do that for my own user, too, and similarly adjust the stuff on my toy server, and used to have a 250+ fleet of street equipments at work) since more than 10 years, as said, and this requires zero maintenance. I'm a lazy person, and thus runit have kept me happy for long. I'm expecting this happiness to last, because it's a sane program, which can handle whatever I want with just few lines of shell.
The logic behind the finish and even the starting is that it makes it dead simple, when reading your logs, to know when the daemon actually started and ended. Which I have found to be extremely useful, but YMMV. I would never remove those from system, clearly, but it's not really orthodox, I suppose.
That's it. I have a lot more runit stuff, on my systems, the only stuff which are not migrated are the services which do not spawn a daemon, mostly out of lazyness.
Offline
Hello freem,
thanks for sharing!
I suspect we copied similar ideas around the web ![]()
for comparison
It starts, like all my runit scripts, by sourcing a single, trivial script I name /etc/runit/common:
see man invoke-run(8) and /lib/runit/invoke-run script (instead of sourcing, it's an interpreter that exec into the run file)
I also have a generic logger, so when I create a new service, I only create the log dir, and symlink it as "run", so it's named /etc/runit/log.run:
in the runit Devuan/Debian package we ship /etc/sv/svlogd/run, same concept as yours (to be symlinked in each service's log dir)
I also have /etc/runit/global.finish which does not do much:
and /lib/runit/finish-exec ;
usage examples for the above 3 are in services in the runit-services package.
The logic behind the finish and even the starting is that it makes it dead simple, when reading your logs, to know when the daemon actually started and ended. Which I have found to be extremely useful
Again I agree: in fact invoke-run and finish-exec supports printing start/stop messages, but you need to touch a flag file in /etc (/etc/runit/verbose)
Maybe my networking stuff may be of interest, as I do not use ifupdown, networkd or whatever...
Yes it's of interest
I'll see if this can be included in runit-services; getting network right for distribution is not that easy because you
have to account for different setups (sometimes in conflict/not compatible with each other); in case, is it ok if I
credit you as 'freem' (do you want ot add an address - beware the spam- or a full name?) ?
Now about udev/eudev: the main problem is that it has to be started early at boot (as a oneshot, when the supervision tree is not active yet).
So, in order to supervise it in a run script we need to stop it and restart it inside the runit service; I saw this done in Void, not sure if ther are races during startup.
Do you start udevd early during boot , then stop it and restart it in the runscript? If yes, are there any issues such as races due to udev not being up when the supervision tree starts all services? Do you have any runit service that depends on udevd?
Also, there is the same problem at shutdown; usually udevd is stoped very late during shutdown (later than other services); I'm not sure this is actually necessary, because, in theory, I think, we don't need to react on devices event at shutdown. But I'm not sure if it creates problems to shutdown without udevd running; again do you observe any issues, such as an unclean shutdown?
Issues with filesystem at next boot?
Best, Lorenzo
Offline
Pages: 1