go ahead... be a heretic | |
PerlMonks |
Re^3: Daemon::Control pid-filesby afoken (Chancellor) |
on Apr 17, 2016 at 16:58 UTC ( [id://1160733]=note: print w/replies, xml ) | Need Help?? |
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):
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:
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:
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 Section
Seekers of Perl Wisdom
|
|