Subject: | Locks on PID file not held on Solaris |
Date: | Fri, 1 Feb 2013 18:58:38 +1100 |
To: | bug-Daemon-Generic [...] rt.cpan.org |
From: | Clinton Mead <clintonmead [...] gmail.com> |
I’ve been using your Daemon::Generic module, which is pretty much exactly
what I’m looking for. However, I’ve found it has some issues on Solaris, in
particular the lock not being held on the PID file so ‘status’ always
returning that the daemon was down. I’ve worked around them by changing by
using “use IO::Handle;” and changing the last part of the “new” function to
the following:
my $daemonized = 0;
unless ($self->{gd_foreground} || $do eq 'debug') {
$self->gd_daemonize;
$daemonized = 1;
}
($locked and (not $daemonized)) or lock($pidfile, undef,
'nonblocking')
or die "Could not lock PID file $pidfile: $!";
open PIDFILE, ">$pidfile" or die "Unable to open PIDFILE: $pidfile\n";
PIDFILE->autoflush(1);
print PIDFILE "$$\n";
print STDERR "Starting up...\n";
$self->gd_postconfig(%newconfig);
$self->gd_setup_signals;
$self->gd_run;
close PIDFILE;
unlink($pidfile);
exit(0);
}
This works around a few issues on Solaris:
(1) Locks don’t seem to survive in the child of fork on Solaris. So
relock after daemonizing.
(2) It looks like locks are removed upon closing a file on Solaris, so
previously writing to the pidfile caused the lock to be lost (as the
PIDFILE was opened then closed). I’ve modified it so the PIDFILE isn’t
closed until after the run function completes.
However, this is a bit of a hack and I may have broken other things +
introduced race conditions, so I thought I’d send this to you so you can do
a better job than me at it.