0

I am attempting to write a cross-platform sysvinit service that works on as many sysvinit systems as possible.

Things I need:

  • The process needs to daemonize (it does not automatically daemonize itself when run)

  • The process needs to be restarted when it crashes

I achieved daemonization by using the start-stop-daemon command - but i have learned that this might not always exist. Is there a more standard way of achieving the functionality of start-stop-daemon in a cross-platform way?

I also need to ensure the process gets auto-restarted when it crashes...what is the best and most cross-platform way to achieve this as well?

Is it also possible the update-rc.d command doesn't always exist? if so, what should i be using instead?

Here is my sysvinit script so far: https://gist.github.com/banister/40775de6a3778e1439d2f776d290073d

Thanks!

horseyguy
  • 123
  • Seems to me you'd write variations of it for the various init daemons for the distributions that you plan on supporting and use the appropriate one at installation time (or point the sysadmin to your stock copies for them to install). – Jeff Schaller Apr 25 '19 at 10:57
  • If you try to do it yourself, there's https://unix.stackexchange.com/q/18209/117549 and https://unix.stackexchange.com/q/196166/117549 – Jeff Schaller Apr 25 '19 at 10:59
  • @JeffSchaller well if the system is systemd then we only need to write one script -- however, i want to write an equivalent sysvinit script that at least works on a large chunk of sysvinit systems without having to tune them for each distro...is this possible? – horseyguy Apr 25 '19 at 11:02

1 Answers1

1

One can write van Smoorenburg rc scripts that do this. They end up as a caseesac construct for every individual step in the script. It's unmaintainable.

This is one of the known problems with this mechanism.

To it, add the fact that van Smoorenburg rc scripts haven't been the way to do things in Ubuntu and Fedora for years. In both cases, before they had systemd they had Upstart. Then there's the fact that van Smoorenburg rc compatibility in systemd is switched off in Arch Linux. Thinking that a van Smoorenburg rc script is some kind of universal minimum that everyone can run even ignoring the helper command variations is an outright mistake. You are aiming at the wrong goal.

To get just an inkling of the wide differences that you have to cater for in writing a single script for all flavours, consider that since 2014 the Debian way of writing van Smoorenburg rc scripts is now documented to be this:

#!/lib/init/init-d-script

## BEGIN INIT INFO
# Provides:          myvpn
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: MY VPN service
# Description: This script starts the MY VPN Daemon
### END INIT INFO

DAEMON=/opt/myvpn/bin/myvpn-daemon
NAME=myvpn
export LD_LIBRARY_PATH=/opt/myvpn/lib

This being a lot shorter than your script, there's room for bonus content here. Taking a rough systemd service unit …

% cat myvpn.service
[Unit]
Description=My VPN service

[Service]
ExecStart=/opt/myvpn/bin/myvpn-daemon
Environment=LD_LIBRARY_PATH=/opt/myvpn/lib
Restart=always

[Install]
WantedBy=multi-user.target
%

… and converting it …

% system-control convert-systemd-units --no-generation-comment ./myvpn.service
%

… shows what a daemontools-family service definition (in this case using the nosh toolset) would also look like:

% system-control print-service-scripts ./myvpn
start:#!/bin/nosh
start:true
stop:#!/bin/nosh
stop:true
run:#!/bin/nosh
run:#My VPN service
run:move-to-control-group ../myvpn.service
run:getuidgid
run:userenv-fromenv
run:setenv LD_LIBRARY_PATH /opt/myvpn/lib
run:chdir /
run:/opt/myvpn/bin/myvpn-daemon
restart:#!/bin/sh
restart:sleep 0.1
restart:exec true       # ignore script arguments
%

Daemontools-family service managers can run on non-Linux operating systems, and automatic restart is even the default in this world.

Further reading

JdeBP
  • 68,745