Suggestions on simpler ways to make a perl-script run at boot time are welcome.

Well, click on any but the first link in the posting you replied to. I suggest to start with the djb way. Yes, that text does not mention perl at all, the example is a stupid daemon written as a shell script, in just 12 lines of code.

But that does not matter at all. You write your "daemon" not to fork to background, and to write warnings and errors to STDERR (just use warn and die). STDIN and STDOUT may be used for other purposes, or you ignore STDIN and don't write to STDOUT. You may also write debug messages to STDOUT, and decide in the starting script (the run script) if you want to merge STDOUT and STDERR (during debugging) or if you want to discard STDOUT (i.e. redirect to /dev/null, for production use).

Daemontools take care of reliable logging and automatic log rotation (via svscan, supervise, multilog; just copy and paste log/run from "the djb way"), restarting (implicit in supervise), sending signals to your program (svc via supervise), starting and stopping your program (svc via supervise, down flag file).

Daemontools have a little learning curve, in that they chain several programs together in an unusual way. Each program does only one thing, removes its arguments from the command line, and execs the next program on the command line. Don't worry, it looks a little bit strange, but it works very nice.


This is a working example from my server to start the fetchmail service (file /service/fetchmail/run):

#!/bin/sh exec 2>&1 echo "*** Starting fetchmail service ...***" if [ "$(pidof exim)" = "" ] ; then echo "exim not running, exiting" exit 1 fi exec \ env FETCHMAILHOME="./pid" \ setuidgid fetchmail \ fetchmail -f ./fetchmail.conf --nodetach

STDOUT and STDERR are merged, a log line is written, if exim (my mail server) is not running, the run script just exits. supervise will restart it after a second, at that time, exim is hopefully running.

Now the chaining part. Note that everything after exec is essentially one long command line:

The shell interpreting the run script sees this: exec env FETCHMAILHOME="./pid" setuidgid fetchmail fetchmail -f ./fetchmail.conf --nodetach
Tell the shell to replace this script with the env(1) program, passing everything after env as parameters.
env sees this: FETCHMAILHOME="./pid" setuidgid fetchmail fetchmail -f ./fetchmail.conf --nodetach
Set the environment variable FETCHMAILHOME to ./pid, then exec setuidgid with all arguments following it.
setuidgid sees this: fetchmail fetchmail -f ./fetchmail.conf --nodetach
Set user id to uid of user "fetchmail", group id to main group of that user, then exec fetchmail with all arguments following it.
fetchmail sees this: -f ./fetchmail.conf --nodetach
Read configuration from ./fetchmail.conf, don't fork to background

In short: set $ENV{FETCHMAILHOME}, become the fetchmail user, run the fetchmail program as that user. All using the same process ID, and always under control of supervise.

The logging script /service/fetchmail/log/run is even shorter:

#!/bin/sh exec \ setuidgid nobody \ multilog t s1000000 /var/multilog/fetchmail

Yes, just four lines that could be stuffed into two lines. Become "nobody", then run the multilog program. Multilog creates logfiles in /var/multilog/fetchmail, prefixes timestamps to the log lines (t), rotates the logfiles after 1_000_000 bytes.


Now, how to you send signals to your daemon if there is no PID file?

supervise always knows the current PID of your daemon, and it will send the signal for you. It will also start or stop your daemon on command.

So, how do you talk to supervise? There are many supervise processes around when you use daemontools. Which one is the right one?

supervise uses a pipe below the service directory. There is exactly one pipe per running process, and it's always the one below the service directory. You don't have to know which supervise you want to talk to, you just use the pipe below the service directory.

What's the name of the pipe? What to write there?

You don't have to know that. There is a tool named svc that talks to supervise. Just tell svc which signal to send, and it will take care of everything. Note that svc and supervise from djb do not send the signals QUIT, USR1, and USR2, but if you follow the djb way, you will find a patch that adds support for those three signals.

So, to send a USR1 signal to your service, just execute svc -1 /service/yourservice. That's all. No PID files needed, as I promised.

The options for the other signals are -p for STOP, -C for CONT, -h for HUP, -a for ALRM, -i for INT, -t for TERM, -k for KILL. With the patch, -1 sends USR1, -2 sends USR2, -q sends QUIT.

Other commands are sent like signals: To start your service, and to restart it when it exits, execute svc -u /service/yourservice. To stop it, execute svc -d /service/yourservice. To run your service only once, execute svc -o /service/yourservice. To prevent your service from automatically starting during boot, create a file named /service/yourservice/down. To make your service start during boot, delete /service/yourservice/down. To completely remove a service, execute svc -dx /service/yourservice /service/yourservice/log, then remove the /service/yourservice directory.

Is your service running?

svstat and svok answer that question, for humans and scripts. (You might notice that my /service/fetchmail/run script does not use svok, neiter does it use svstat. It uses pidof. It's an old script, from a time when exim was not under control of daemontools, that's why. It should really use svok /service/exim instead.)

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to Re^3: Daemon::Control pid-files by afoken
in thread Daemon::Control pid-files by morgon

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.