Re: Daemon that starts other Daemons

2004-09-24 Thread Bob Showalter
Errin Larsen wrote:
 Ok ... so with some research and playi^H^H^H^H^Htesting I've found the
 answer to what's really been bothering me.

If you *really* want to understand the nuts and bolts of all this, Stevens'
_Advanced Programming in the UNIX Environment_ is a must.

http://www.amazon.com/exec/obidos/ASIN/0201563177


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Daemon that starts other Daemons

2004-09-24 Thread John W. Krahn
Bob Showalter wrote:
Errin Larsen wrote:
Ok ... so with some research and playi^H^H^H^H^Htesting I've found the
answer to what's really been bothering me.
If you *really* want to understand the nuts and bolts of all this, Stevens'
_Advanced Programming in the UNIX Environment_ is a must.
http://www.amazon.com/exec/obidos/ASIN/0201563177
Since the OP mentioned that he is using Solaris he may want to get this book 
instead:

http://www.rite-group.com/rich/ssp/index.html
John
--
use Perl;
program
fulfillment
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response



Daemon that starts other Daemons

2004-09-23 Thread Errin Larsen
Hi perl-people,

I'm not sure if this is beginners stuff, but I'll post here 'cause
it's the only list I'm subscribed to at the moment.

I'm writing a script that will daemonize itself, and then watch some
processes.  If one of those processes die, it will start it again. 
So, I've been reading the perlipc docs and I found this handy code on
proper daemonization:

use POSIX 'setsid';

sub daemonize {
#it's polite for daemons to chdir to root so that they 
#don't prevent a filesystem from being unmounted
chdir '/' or die Can't chdir to /: $!;

#it's also polite for daemons to redirect all output to
#/dev/null so users don't get random output
open STDIN, '/dev/null' or die Can't read /dev/null: $!;
open STDOUT, '/dev/null' or die Can't write to /dev/null:$!;

#the parent get's the new child's pid back, the child gets '0' back
defined( my $pid = fork ) or die Can't fork: $!;

#here's where I start having problem.  This code assumes that
#the parent will be exiting, thus leaving the child able
#to run setsid
exit if $pid;
setsid or die Can't start a new session: $!;

open STDERR, 'STDOUT' or die Can't dup STDOUT: $!;
}

perlipc goes on to explain:
  The fork() has to come before the setsid() to ensure that you
aren't a process leader (the setsid() will fail if you are).

So, my question is, how do I implement this code WITHOUT the parent
process dieing?

--Errin

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Daemon that starts other Daemons

2004-09-23 Thread Errin Larsen
On Thu, 23 Sep 2004 11:23:16 -0500, Errin Larsen [EMAIL PROTECTED] wrote:
 Hi perl-people,

SNIP

 So, my question is, how do I implement this code WITHOUT the parent
 process dieing?
 
 --Errin
 

I found that (at least on the Solaris OS that I'm working on) that the
setsid function will setup a new session UNLESS:
The calling process is already a process group leader,
   or  the  process group  ID of a process other than the
   calling process matches the process  ID of the calling
   process. 

So, I think that's saying that as long as the process (the child) does
not have any children of it's own, then I'll be ok with the above
code!  Is that what the blurb above is saying?  (Why are UNIX docs
always so darn hard to read!!?)

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Daemon that starts other Daemons

2004-09-23 Thread Wiggins d Anconia
 Hi perl-people,
 
 I'm not sure if this is beginners stuff, but I'll post here 'cause
 it's the only list I'm subscribed to at the moment.
 

A stretch, but there have been more complex topics discussed. This is
pretty much a catch all and some of the experts will probably appreciate
not answering the same how do I delete an element of an array question :-).

 I'm writing a script that will daemonize itself, and then watch some
 processes.  If one of those processes die, it will start it again. 
 So, I've been reading the perlipc docs and I found this handy code on
 proper daemonization:
 

Great docs... however...

 use POSIX 'setsid';
 
 sub daemonize {
 #it's polite for daemons to chdir to root so that they 
 #don't prevent a filesystem from being unmounted
 chdir '/' or die Can't chdir to /: $!;
 
 #it's also polite for daemons to redirect all output to
 #/dev/null so users don't get random output
 open STDIN, '/dev/null' or die Can't read /dev/null: $!;
 open STDOUT, '/dev/null' or die Can't write to /dev/null:$!;
 
 #the parent get's the new child's pid back, the child gets '0' back
 defined( my $pid = fork ) or die Can't fork: $!;
 
 #here's where I start having problem.  This code assumes that
 #the parent will be exiting, thus leaving the child able
 #to run setsid
 exit if $pid;
 setsid or die Can't start a new session: $!;
 
 open STDERR, 'STDOUT' or die Can't dup STDOUT: $!;
 }
 
 perlipc goes on to explain:
   The fork() has to come before the setsid() to ensure that you
 aren't a process leader (the setsid() will fail if you are).
 
 So, my question is, how do I implement this code WITHOUT the parent
 process dieing?
 
 --Errin
 

Actually you want the parent process to die... or at least exit, then
your child process is the session leader and will do everything else you
need, aka fork more children in your case. Essentially you want to make
it so that the tty/shell (whatever) no longer thinks it has absentee
children so that it can exit cleanly, by daemonizing your process
essentially becomes a child of the kernel, which will always be running
(until shutdown that is).

However, the best advice NOT given by perldoc perlipc is to use the
Proc::Daemon::Init module, it is incredibly easy and takes care of all
of the code you mention above by itself, in a neat package that you
don't have to worry about the internals of.  It is available through
CPAN as usual, and despite its incredibly low release number (if you
are into that hole thing) I have never had problems with it.

Two additional comments, that you are likely to stumble across:

1. How do I get back to my process after it has daemonized, how do I
stop it, etc?  

This is where you will likely want to get into writing a pid file to
the disk so that your process can be looked up and signaled, and/or to
prevent two copies of your daemon running, or at least trying to work on
teh same resources.

2. How do I do logging, etc.?  

Check out the very, very excellent Log::Log4perl suite, it is incredible
and can accomplish just about all of your logging needs.

Of course I have already mentioned POE but I will plug it again.

http://danconia.org

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Daemon that starts other Daemons

2004-09-23 Thread Wiggins d Anconia
 On Thu, 23 Sep 2004 11:23:16 -0500, Errin Larsen
[EMAIL PROTECTED] wrote:
  Hi perl-people,
 
 SNIP
 
  So, my question is, how do I implement this code WITHOUT the parent
  process dieing?
  
  --Errin
  
 
 I found that (at least on the Solaris OS that I'm working on) that the
 setsid function will setup a new session UNLESS:
 The calling process is already a process group leader,
or  the  process group  ID of a process other than the
calling process matches the process  ID of the calling
process. 
 
 So, I think that's saying that as long as the process (the child) does
 not have any children of it's own, then I'll be ok with the above
 code!  Is that what the blurb above is saying?  (Why are UNIX docs
 always so darn hard to read!!?)
 

That is the way I read it, though see the suggestion in my other post...

http://danconia.org

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Daemon that starts other Daemons

2004-09-23 Thread Errin Larsen
-- Forwarded message --
From: Errin Larsen [EMAIL PROTECTED]
Date: Thu, 23 Sep 2004 16:30:21 -0500
Subject: Re: Daemon that starts other Daemons
To: Wiggins d Anconia [EMAIL PROTECTED]

Hi again,

Ok ... so with some research and playi^H^H^H^H^Htesting I've found the
answer to what's really been bothering me.  If I fork(), I get the PID
of the resulting child.  However, if THAT child runs and external
command, how do I get the (now grand)child's PID.  The answer I was
looking for was a deeper understanding of exec().

by fork()ing a child and having that child run exec(), the exec()ed
command will have the SAME process ID as the original child.  In
actuality, the exec()ed command is NOT a grandchild, but has taken
over the original child's process and all it's environment (STDIN,
STDOUT, %ENV, etc.).  That's what I needed to know!  Now, if I just
collect and keep the child's PID, when I run the exec() I'll have the
PID of whatever command was exec()ed.

Also, with some experimenting, the setsid() doesn't NEED the original
parent to die to work, it just needs the child to be forked before it
runs setsid().  In other words, if you try to run setsid() BEFORE you
fork the child (in an attempt to give both the child and the parent
the same session and group ID, perhaps) it will fail.  If you instead
have the child run setsid() after it is fork()ed, it will run fine,
whether the parent is dead or not!  YAY!!


On Thu, 23 Sep 2004 13:30:08 -0600, Wiggins d Anconia
[EMAIL PROTECTED] wrote:


  On Thu, 23 Sep 2004 11:23:16 -0500, Errin Larsen
 [EMAIL PROTECTED] wrote:
   Hi perl-people,
 
  SNIP
 
   So, my question is, how do I implement this code WITHOUT the parent
   process dieing?
  
   --Errin
  
 

SNIP

Thanks for the help, Wiggins.  I agree this would all be easier if I
just went a grabbed a module, but for (probably strange) reasons I'd
rather not go into, I want to do this from scratch.  Also, this has
been extremely helpful in teaching me what's going on with the
backticks, system(), fork() and exec() functions.  This process has
really helped me along with my Perl education.

Also, I realized that the ORIGINAL parent needs to die (So as to
disassociate the daemons from the calling terminal/process), but I was
looking for a daemon that would run, start other servers, and that
hang around monitoring them.  I think we're talking about the same
thing here, just I didn't explain it will originally.

Now, I just need to implement some code to dump a file with PIDs into
/var/run!  Thanks for the suggestions/help and I'll get working on it
now!

--Errin

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Daemon that starts other Daemons

2004-09-23 Thread Wiggins d Anconia
 Hi again,
 
 Ok ... so with some research and playi^H^H^H^H^Htesting I've found the
 answer to what's really been bothering me.  If I fork(), I get the PID
 of the resulting child.  However, if THAT child runs and external
 command, how do I get the (now grand)child's PID.  The answer I was
 looking for was a deeper understanding of exec().


Yep. Playing is the best way to go.
 
 by fork()ing a child and having that child run exec(), the exec()ed
 command will have the SAME process ID as the original child.  In
 actuality, the exec()ed command is NOT a grandchild, but has taken
 over the original child's process and all it's environment (STDIN,
 STDOUT, %ENV, etc.).  That's what I needed to know!  Now, if I just
 collect and keep the child's PID, when I run the exec() I'll have the
 PID of whatever command was exec()ed.
 

Correct.

 Also, with some experimenting, the setsid() doesn't NEED the original
 parent to die to work, it just needs the child to be forked before it
 runs setsid().  In other words, if you try to run setsid() BEFORE you
 fork the child (in an attempt to give both the child and the parent
 the same session and group ID, perhaps) it will fail.  If you instead
 have the child run setsid() after it is fork()ed, it will run fine,
 whether the parent is dead or not!  YAY!!
 

Yep again, making the child a session leader doesn't mean that the
parent must go away, more that if it wants to it can.  Which is a subtle
but important distinction.

 
 On Thu, 23 Sep 2004 13:30:08 -0600, Wiggins d Anconia
 [EMAIL PROTECTED] wrote:
 
 
   On Thu, 23 Sep 2004 11:23:16 -0500, Errin Larsen
  [EMAIL PROTECTED] wrote:
Hi perl-people,
  
   SNIP
  
So, my question is, how do I implement this code WITHOUT the parent
process dieing?
   
--Errin
   
  
 
 SNIP
 
 Thanks for the help, Wiggins.  I agree this would all be easier if I
 just went a grabbed a module, but for (probably strange) reasons I'd
 rather not go into, I want to do this from scratch.  Also, this has
 been extremely helpful in teaching me what's going on with the
 backticks, system(), fork() and exec() functions.  This process has
 really helped me along with my Perl education.
 

Definitely. You are essentially taking the same path through the madness
that I did 2 years ago or so, first attempting to understand the reasons
and lowlevels, reading lots of docs and making lots of mistakes. Once I
figured it out I was very glad because of the amount I learned, but then
opted for the module mostly to prevent code maintenance, hassles, etc.
We already had roughly 40 other dependencies, and considering it was
probably the easiest to install I wasn't concerned about Just Another
Module (hmph, JAM, that works pretty well in the glue analogy ;-)).

 Also, I realized that the ORIGINAL parent needs to die (So as to
 disassociate the daemons from the calling terminal/process), but I was
 looking for a daemon that would run, start other servers, and that
 hang around monitoring them.  I think we're talking about the same
 thing here, just I didn't explain it will originally.
 
 Now, I just need to implement some code to dump a file with PIDs into
 /var/run!  Thanks for the suggestions/help and I'll get working on it
 now!


Agreed and yep.
 
 --Errin
 

http://danconia.org

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Daemon that starts other Daemons

2004-09-23 Thread Chris Devers
On Thu, 23 Sep 2004, Errin Larsen wrote:

 [] I was looking for a daemon that would run, start other servers, 
 and that hang around monitoring them.

In other words, you want something that works like Apache [1.x].

  * To launch Apache, you run apachectl, a shell script.

  * apachectl launches a parent httpd process, which in turns spawns 
a pool of listener httpd child processes.

  * apachectl goes away then, and the parent httpd supervises the 
operation of the server from then on.

Granted, the interesting bits are all done in C or something, so that 
may not help you here, but it's the model you're looking for.



-- 
Chris Devers

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Daemon that starts other Daemons

2004-09-23 Thread Wiggins d Anconia
 On Thu, 23 Sep 2004, Errin Larsen wrote:
 
  [] I was looking for a daemon that would run, start other servers, 
  and that hang around monitoring them.
 
 In other words, you want something that works like Apache [1.x].
 
   * To launch Apache, you run apachectl, a shell script.
 
   * apachectl launches a parent httpd process, which in turns spawns 
 a pool of listener httpd child processes.
 
   * apachectl goes away then, and the parent httpd supervises the 
 operation of the server from then on.
 
 Granted, the interesting bits are all done in C or something, so that 
 may not help you here, but it's the model you're looking for.
 
 
 
 -- 
 Chris Devers
 

If you really want to get into it, Network Programming with Perl has
excellent coverage of various common types of daemons and how to write
them in Perl.  Don't know if you have the resources or time but it is
worth a look if the interest is there. My very unprofessional and
non-expert review of it is here:

http://danconia.org/cgi-bin/request?handler=Content;content=Site_Bookshelf_Book;id=26

http://danconia.org


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response