2007-04-17

init script generators

Posted in Computers, PlanetDebian at 20:34 CEST (+0200) by sven

Gunnar is following up on the init script blog posts by Erich and me. First a note to Gunnar: The idea of the init scrip snippets isn’t exactly my own idea, but rather taken from a comment to one of Erich’s posts (IIRC), I don’t know the original author anymore.

Anyway, I really think that some init script generator should work. It should even be possible to fetch variables from /etc/default/<daemon-name> if needed. I’m just doing a braindump of what I have in mind for the start and stop of a daemon. I would expect a configuration file (currently I think one for each operation might be best, but INI-lookalike files might also be OK). So for the start operation, I would expect these options:

  1. simple daemon, uses a default config with a hardcoded path and needs no options or only static options passed:
    [SIMPLE]
    /path/to/daemon
    option 1
    option 2
    option 3
    

    Where I chose to name one option per line so whitespace and controll characters can be part of the options without the need to quote anything.

  2. a bit more complicated, needs a few variables from /etc/default/daemon:
    [TEMPLATED]
    /path/to/daemon
    option 1
    %PARAMETER_FROM_ETC_DEFAULT%
    --parameter=%ANOTHER_ONE_FROM_ETC_DEFAULT%
    

    Where the script generator would have to make sure that the parameters from /etc/default are filled in at runtime. I would expect POSIX-Shell-Scripts in /etc/default for this.

  3. Really complex: A custom script snippet is needed which has to do some specificc tasks, like cleaning possible stable locks which had been left behind.
    [SCRIPT]
    rm /var/lock/daemon.lck
    /path/to/daemon --background --and --other --options
    

    Where the script generator would simply take this script and use it where it would otherwise generate its own code.

As for stopping, I generally see only three options for the sysv-like background processes: Either a script is needed (see above for how that would look like) or a process needs to be killed according to a PID-file or the process name (with the later being rather bad). So this would result in:

  1. [SCRIPT] like for starting the daemon
  2. killing by PID-file:
    [PIDFILE]
    /path/to/pid-file
    
  3. killing by process name/executable:
    [PROCESS]
    binary
    

    or

    [PROCESS]
    /path/to/binary
    

    where the generator would either only look at the name of the process (first version, no full pathname) or for a process with the given executable (from /proc/ /exec, I would expect).

Alright, this would leave the cases of running (instead of backgrounding) the server and stopping such a running server (the later should be fairly simple unless the stopping of the server requires additional actions other than simply killing it) as well as the reload/restart/status stuff. But these should also be relatively simple actually.

What would be interesting for me:
Does any init system require information that is not part of the following list? I would plan with supplying information how to:

  • start server in background
  • start server in foreground (without the need for a terminal)
  • determine wether a server runs (status)
  • determine wether a server is ready to serve requests (also part of status)
  • determine wether the server is installed (and able to be started)
  • stop a background server
  • stop a foreground server (unless specified, a simple SIGKILL to the process is assumed)
  • restart foreground server (unless specified, a simple stop-start cycle is assumed)
  • restart background server (unless specified, a simple stop-start cycle is assumed)
  • reload config (unless specified, it is assumed that reloading doesn’t work and a restart is needed)
  • reopen logs (unless specified, the “reload config” operation is assumed to do this)
  • some meta information: short description, needs writeable filesystem(s) mounted, needs a certain daemon to be running already (or even: able to serve requests), enhances other daemon X and should be started before it (don’t care if X isn’t installed/configured), is enhanced by daemon Y and should be started after it (don’t care if Y isn’t installed/configured), replaces daemon Z, should only run once at startup, …

Finally, even with all that information available inside a Debian package, this would still leave one question unanswered: Who triggers init script generation? If a daemon package does so in postinst: How do I switch to a different init system? If the init system does it in postinst: What happens to additional daemons installed later on? If they get regenerated during system start: How much penalty does that cause? Currently I think the route to go is to provide a command to daemon packages’ postinst that (re)generates only the needed scripts for that package and have a command used in an init system’s postinst which regenerates all of them. That should do. Regenerating during boot would most likely take too much time and has other problems, too, like the availability of a writeable filesystem to store the generated scripts.
Alright, if someone would like to see this post (or rather parts of it) on the Wiki page about an Init HackFest, please transfer it there yourself. I’m currently not able to log in, for whatever reason.

2007-04-13

Init HackFest / New init systems in Debian

Posted in Computers, PlanetDebian at 13:53 CEST (+0200) by sven

In his “Init followup” post, Erich posted a reference to his Debian-Wiki post about a proposed Debian HackFest after Etch was released (which would be about 5 days ago<smile />). Anyway, since that page at the wiki is protected, which means I can’t edit it, I’m posting my thoughts here.

I agree with Erich and some other commentors at Gunnar Wolf’s blog post that it doesn’t make sense to add X init-script-only-packages for any daemon to support X init systems. Instead, each package containing one or more daemons should contain the meta information needed to create all init scripts. Basically, this would probably include script snippets which do the following operations:

  • Pre-check: Check wether the package actually is installed rather than in removed/configured status.
  • start: Start the daemon in background mode.
  • run: Start a daemon in foreground mode (so that an exiting daemon can immediately be recognized by the init system).
  • stop: Stop a daemon running in background mode.
  • stop-running: Stop a daemon running in foreground mode. This should only be needed if the daemon doesn’t shut down nicely on a SIGTERM but instead needs some sort of message/semaphore to do so.
  • status: Return current running status.
  • reload: Reload configs, reopen logs (if supported by daemon).

Additionally, some control information would be needed including, but probably not limited to:

  • Dependencies: Should allow for alternatives, lists daemons which need to be running before this daemon is started.
  • Provides: Similar to package-provides, this should be used to allow things like replacing inetd with xinetd or something else providing similar functionality.
  • Short Description: For init systems that are capable of showing a short description next to the name of configured daemons
  • Run-Sets: Not strictly like sysvinit-runlevels, but similar, should allow the admin/user to configure different sets of daemons to start, selecting at boot by a kernel cmdline-parameter or at runtime through some command (”init 1″) which set should be running.

The script snippets listed above should allow basically any operation on a daemon, including the force-reload and try-restart commands not yet implemented by all current sysv-initscripts.