You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Igor Shevchenko <ig...@carcass.ath.cx> on 2005/02/19 00:25:55 UTC

exec and detach a subprocess

Hi all,

How can I launch a subprocess and have it completely detached from the 
mod_perl2/apache2 environment ? All file descriptors closed, not in a process 
group, etc.

I was trying to do it like this:

sub safe_exec {
    return if fork() > 0;
    
    # close all descriptors
    foreach my $fd ( 0, 3..1023 ) { close $fd }
    
    exec ( @_ );
    CORE::exit;
}

Unfortunately this doesn't close sockets which are listening on ports 80 and 
443. Tried it like this:

* start apache
* run bg process from web page / script
* stop apache
* "ps auxww|grep httpd" doesn't show any httpd process running,
"netstat -lp|grep http" shows ports 80 and 443, listening in a perl process 
(my background script)

Because of this, apache fails to restart when any of background processes are 
running. How do I close all file descriptors and sockets ?

(this is linux 2.6)

-- 
Best Regards,
Igor Shevchenko

Re: exec and detach a subprocess

Posted by Stas Bekman <st...@stason.org>.
Igor Shevchenko wrote:
> A small followup to this case.
> 
> Looks like mp2 or apache2 are killing background process, by PID; Probably in 
> a cleanup handler for the request. I had to add additional "return if fork() 
>>0;" to the exec_helper.pl script to make bg processes survice.

what do you mean by background proc?

so you do an additional fork? where do you return() to? it's probably 
exit(), no? show us the whole code snippet?



-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: exec and detach a subprocess

Posted by Igor Shevchenko <ig...@carcass.ath.cx>.
A small followup to this case.

Looks like mp2 or apache2 are killing background process, by PID; Probably in 
a cleanup handler for the request. I had to add additional "return if fork() 
> 0;" to the exec_helper.pl script to make bg processes survice.

-- 
Best Regards,
Igor Shevchenko

Re: exec and detach a subprocess

Posted by Stas Bekman <st...@stason.org>.
Igor Shevchenko wrote:
> On Saturday 19 February 2005 18:51, you wrote:
> 
>>please check one more thing where is your cwd in the spawned script, it
>>should be '/'. in mp1 one had to manually chdir '/' in the script, but I
>>believe the Apache C API called from spawn_proc_prog does it for you. Is
>>that right?
> 
> 
> Checked, it was not doing chdir.

so it's a good idea to do that to avoid potential mount(1) problems.

>> > CORE::exit(0);
>>
>>and you don't need this either, especiall if you call exec()
> 
> 
> Right, it was there to avoid any perl warnings for "exec-not-followed-by-{die 
> || warn || exit}". From "man perlfunc":

right. but it is a better solution to:

   exec or die '...';

since you really want to verify that exec didn't fail.

In anycase, the docs are updated:
http://perl.apache.org/docs/2.0/api/Apache/SubProcess.html#C_spawn_proc_prog_

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: exec and detach a subprocess

Posted by Igor Shevchenko <ig...@carcass.ath.cx>.
On Saturday 19 February 2005 18:51, you wrote:
> please check one more thing where is your cwd in the spawned script, it
> should be '/'. in mp1 one had to manually chdir '/' in the script, but I
> believe the Apache C API called from spawn_proc_prog does it for you. Is
> that right?

Checked, it was not doing chdir.

>  > CORE::exit(0);
>
> and you don't need this either, especiall if you call exec()

Right, it was there to avoid any perl warnings for "exec-not-followed-by-{die 
|| warn || exit}". From "man perlfunc":

>Since it's a common mistake to use "exec" instead of "system",
>Perl warns you if there is a following statement which isn't
>"die", "warn", or "exit" (if "-w" is set  -  but you always do
>that).

-- 
Best Regards,
Igor Shevchenko

Re: exec and detach a subprocess

Posted by Stas Bekman <st...@stason.org>.
Igor Shevchenko wrote:
[...]
>>>exec ( @ARGV );
>>
>>why do you need to call exec() here? It doesn't detach if you don't call
>>it? I think it should make no difference at all.
> 
> 
> I need to run the real script somehow, hence the call to "exec".

yes, of course, so this was just a wrapper. But you end up with yet 
another perl restart. If that script is only executed via this wrapper, 
you should merge the two and save some more cycles. exec() would be most 
useful for some C binary....

in any case this thread and code samples will documented at:
http://perl.apache.org/docs/2.0/api/Apache/SubProcess.html#C_spawn_proc_prog_
soonish.

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: exec and detach a subprocess

Posted by Igor Shevchenko <ig...@carcass.ath.cx>.
On Saturday 19 February 2005 18:44, you wrote:
> Igor Shevchenko wrote:
> > On Saturday 19 February 2005 03:06, Stas Bekman wrote:
> >>What about?
> >>$r->spawn_proc_prog
> >>http://perl.apache.org/docs/2.0/api/Apache/SubProcess.html#C_spawn_proc_p
> >>ro g_
> >
> > Thanks for those links, Stas! I had to find them by myself as they are in
> > docs...
> >
> > The following worked for me:
> >
> > A helper subroutine:
> >
> > sub safe_exec {
> >     my $out_fh = $apr->spawn_proc_prog ( '/path/to/exec_helper.pl', \@_
> > ); close $out_fh;
> > }
>
> I've just committed a change which does this for you if you call that
> method in a void context, so the above can be changed into:
>
>    $apr->spawn_proc_prog ( '/path/to/exec_helper.pl', \@_ );

Thanks!

> > And a helper script:
> >
> > #!/usr/bin/perl -w
> > use strict;
> > use warnings;
> > use POSIX;
>
> performance-wise this is silly :)
> See 13.5.2 in http://modperlbook.org/html/ch13_05.html for details.

Oops, thanks for the tip. I knew about the memory/runtime bloat, I was just 
not realizing that bare "use POSIX" would load all vs none with "use 
POSIX()". exec_helper.pl is rarely-used script, but I'll run thru my 
ModPerl::Registry scripts and modules to fix this... again, thanks!

> > POSIX::setsid;
> >
> > close STDIN;
> > open STDOUT, '+>>', '/path/to/apache/error_log';
> > open STDERR, '>&STDOUT';
> >
> > exec ( @ARGV );
>
> why do you need to call exec() here? It doesn't detach if you don't call
> it? I think it should make no difference at all.

I need to run the real script somehow, hence the call to "exec".

-- 
Best Regards,
Igor Shevchenko

Re: exec and detach a subprocess

Posted by Stas Bekman <st...@stason.org>.
Igor Shevchenko wrote:
> On Saturday 19 February 2005 03:06, Stas Bekman wrote:
> 
>>What about?
>>$r->spawn_proc_prog
>>http://perl.apache.org/docs/2.0/api/Apache/SubProcess.html#C_spawn_proc_pro
>>g_
> 
> 
> Thanks for those links, Stas! I had to find them by myself as they are in 
> docs...
> 
> The following worked for me:
> 
> A helper subroutine:
> 
> sub safe_exec {
>     my $out_fh = $apr->spawn_proc_prog ( '/path/to/exec_helper.pl', \@_ );
>     close $out_fh;
> }

I've just committed a change which does this for you if you call that 
method in a void context, so the above can be changed into:

   $apr->spawn_proc_prog ( '/path/to/exec_helper.pl', \@_ );

> And a helper script:
> 
> #!/usr/bin/perl -w
> use strict;
> use warnings;
> use POSIX;

performance-wise this is silly :)
See 13.5.2 in http://modperlbook.org/html/ch13_05.html for details.

> POSIX::setsid;
> 
> close STDIN;
> open STDOUT, '+>>', '/path/to/apache/error_log';
> open STDERR, '>&STDOUT';
> 
> exec ( @ARGV );

why do you need to call exec() here? It doesn't detach if you don't call 
it? I think it should make no difference at all.

> CORE::exit(0);


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: exec and detach a subprocess

Posted by Stas Bekman <st...@stason.org>.
please check one more thing where is your cwd in the spawned script, it 
should be '/'. in mp1 one had to manually chdir '/' in the script, but I 
believe the Apache C API called from spawn_proc_prog does it for you. Is 
that right?

 > CORE::exit(0);

and you don't need this either, especiall if you call exec()

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: exec and detach a subprocess

Posted by Igor Shevchenko <ig...@carcass.ath.cx>.
On Saturday 19 February 2005 03:06, Stas Bekman wrote:
> What about?
> $r->spawn_proc_prog
> http://perl.apache.org/docs/2.0/api/Apache/SubProcess.html#C_spawn_proc_pro
>g_

Thanks for those links, Stas! I had to find them by myself as they are in 
docs...

The following worked for me:

A helper subroutine:

sub safe_exec {
    my $out_fh = $apr->spawn_proc_prog ( '/path/to/exec_helper.pl', \@_ );
    close $out_fh;
}


And a helper script:

#!/usr/bin/perl -w
use strict;
use warnings;
use POSIX;

POSIX::setsid;

close STDIN;
open STDOUT, '+>>', '/path/to/apache/error_log';
open STDERR, '>&STDOUT';

exec ( @ARGV );
CORE::exit(0);

1;


-- 
Best Regards,
Igor Shevchenko

Re: exec and detach a subprocess

Posted by Stas Bekman <st...@stason.org>.
Igor Shevchenko wrote:
> Hi all,
> 
> How can I launch a subprocess and have it completely detached from the 
> mod_perl2/apache2 environment ? All file descriptors closed, not in a process 
> group, etc.
> 
> I was trying to do it like this:
> 
> sub safe_exec {
>     return if fork() > 0;
>     
>     # close all descriptors
>     foreach my $fd ( 0, 3..1023 ) { close $fd }
>     
>     exec ( @_ );
>     CORE::exit;
> }
> 
> Unfortunately this doesn't close sockets which are listening on ports 80 and 
> 443. Tried it like this:
> 
> * start apache
> * run bg process from web page / script
> * stop apache
> * "ps auxww|grep httpd" doesn't show any httpd process running,
> "netstat -lp|grep http" shows ports 80 and 443, listening in a perl process 
> (my background script)
> 
> Because of this, apache fails to restart when any of background processes are 
> running. How do I close all file descriptors and sockets ?
> 
> (this is linux 2.6)


Igor, the techniques explained here don't work?
http://perl.apache.org/docs/1.0/guide/performance.html#Forking_and_Executing_Subprocesses_from_mod_perl

What about?
$r->spawn_proc_prog
http://perl.apache.org/docs/2.0/api/Apache/SubProcess.html#C_spawn_proc_prog_

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com