Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Detecting stale pid file under *nix

by Dallaylaen (Chaplain)
on Oct 24, 2016 at 21:36 UTC ( [id://1174627]=perlquestion: print w/replies, xml ) Need Help??

Dallaylaen has asked for the wisdom of the Perl Monks concerning the following question:

This is more of a Unix question rather than a Perl one, but still...

I'm looking for a way to stop my daemon, but I don't want to terminate an innocent bystander process. I came up with idea that PID file is created after the process has been spawned. Therefore, it's not older then the process, so the following code was written which seems to work correctly on my Ubuntu:

open (my $fd, "<", $conf->{pidfile}) or die "Failed to read pidfile $conf->{pidfile}: $!"; my $pid = <$fd>; chomp $pid; die "Broken pid file $conf->{pidfile}" unless $pid =~ /^\d+$/; # detect stale pid if ([stat $fd]->[9] >= ([stat "/proc/$pid"]->[9] || 9**9**9)) { print "Killing pid $pid...\n"; kill INT => $pid; };

Of course, it can still be tricked by touching the pid file, but then it's also possible to write rubbish into the pid file anyway.

Now I would like to ask what is the proper way of avoiding sending signal to a wrong process? CPAN has a multitude of modules for PID file handling, I was unable to choose one.

Thank you!

Replies are listed 'Best First'.
Re: Detecting stale pid file under *nix
by andal (Hermit) on Oct 25, 2016 at 07:20 UTC

    If you are already checking the /proc/$pid, then why don't you check /proc/$pid/cmdline to see, if it contains name of your daemon? Or you can read destination of the symbolic link /proc/$pid/exe to see if it points to the executable of the daemon

    If the daemon is your own application, then you may want to change it so that it listens for termination (or other commands) on some hidden unix socket. Then you can terminate it by writing to that socket.

      Daemon is really a PSGI application, so the exe is doing to point to Perl interpreter and modification of daemon itself is possible, but undesired. I'd rather complicate my init script...

        Then check command line. Even if it is perl, the command line still contains name of the script and parameters.

Re: Detecting stale pid file under *nix
by perlancar (Hermit) on Oct 25, 2016 at 07:26 UTC
    IIRC, Proc::PID::File has a verify option to do stale PID checking. My old module (now removed from CPAN, due to Proc::PID::File already existing) also did stale PID checking.

      Thanks! And it does so by calling ps via shell. At least that is portable.

      I wonder if there is a standardized /proc layout or maybe a Perl module for fetching process properties...

      UPDATE I've found Proc::ProcessTable, but it does a full table scan, not just one process.

Re: Detecting stale pid file under *nix
by Monk::Thomas (Friar) on Oct 25, 2016 at 09:02 UTC
    By the way:
    if ( ... >= 9**9**9) {
    If you mean 'infinity', then you can use the string 'Inf' instead. (or 'inf', or 'INF' - Perl recognizes all of these as 'infinity'.)
    if ( ... >= "Inf") {
    Please note: I advise against using this to improve the original code. Please use the suggested module instead.
      The handling of Inf depends on the underlying standard library. I know it's not me who should be talking about portability here, but still.
Re: Detecting stale pid file under *nix
by afoken (Chancellor) on Oct 25, 2016 at 19:42 UTC

    If you would use daemontools or similar, you would never have any stale PID files. Simply because you don't need any PID files. (To be honest, PID files are a stupid idea, as you will see when you understand how clean deamontools work.)

    See Re: Daemon::Control pid-files and the postings linked from there for details. See Re: How to get the process Id for why PID files are stupid.

    Alexander

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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1174627]
Approved by davies
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2024-03-28 10:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found