You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by An...@Bertelsmann.de on 2005/05/24 09:39:09 UTC

Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Hi  folks,
 
recently I deployed Apache::SizeLimit on a mod_perl 1.29 machine running SLES 9, since we had - ehm - runaway processes....
 
After a while I stumbled across messages like this:
 
/var/web/logs/error_log_modperl.3:[Tue May 17 20:45:04 2005] (21886) Apache::SizeLimit main process too big, SIZE=2003764 KB  SHARE=21208 KB
/var/web/logs/error_log_modperl.3:[Tue May 17 20:56:49 2005] (21886) Apache::SizeLimit main process too big, SIZE=2003764 KB  SHARE=21208 KB
/var/web/logs/error_log_modperl.3:[Tue May 17 21:02:42 2005] (21886) Apache::SizeLimit main process too big, SIZE=2003764 KB  SHARE=21208 KB
/var/web/logs/error_log_modperl.3:[Tue May 17 21:07:02 2005] (21886) Apache::SizeLimit main process too big, SIZE=2003764 KB  SHARE=21208 KB

and eventually read them in a way that actually hit my brain and I though: why does the main process grow and why is it serving requests ? I registered Apache::SizeLimit as a PerlCleanupHandler, so it should only be called for requests, right ? So I looked at the code and saw this:
 
  # wake up! time to die.
            if ($WIN32 || (getppid > 1)) {      # this is a child httpd
                my $e = time - $START_TIME;
                my $msg = "httpd process too big, exiting at SIZE=$size KB ";
                $msg .= " SHARE=$share KB " if ($share);
                $msg .= " REQUESTS=$REQUEST_COUNT  LIFETIME=$e seconds";
                error_log($msg);
 
                if ($WIN32) {
                    CORE::exit(-2); # child_terminate() is disabled in win32 Apache
                } else {
                    $r->child_terminate();
                }
 
            } else {    # this is the main httpd, whose parent is init?
                my $msg = "main process too big, SIZE=$size KB ";
                $msg .= " SHARE=$share KB" if ($share);
                error_log($msg);
            }
 
I claim, the "main process " detection does never work and does not make sense. Why? Not even when the apache is started on boot through init, the PPID will be 1, but some shell / rc pid.  You can only find the PPID in the PID file that apache writes. But still: this should never be the case - right ?
 
I checked Apache::SizeLimit for mod_perl 2 and found it mostly unchanged, so maybe this should be updated as:
 
- if I am wrong and the main process goes through the cleanup phase, then we should read the PID file once at startup and test $$ against that PID
- if I am right, then the whole getppid stuff can just go away
 
What do you think ?
 
For my problem: I think that somehow the getppid does not work correctly with my perl 5.8.3 SLES9 / mp 1.29 / apache 1.3.29 combination -> I`ll try to scrap the getppid test and see, if the server will ever get killed...


cheers

Andreas Nolte
Leitung IT
-----------------------------------------------------------
arvato direct services
Olympiastraße 1
26419 Schortens
Germany
 <http://www.arvato.com/> http://www.arvato.com/

andreas.nolte@bertelsmann.de
Phone   +49 (0) 4421 - 76- 84002
Fax     +49 (0) 4421 - 76- 84111
  

 
 

Andreas Nolte
Leitung IT
-----------------------------------------------------------
arvato direct services
Olympiastraße 1
26419 Schortens
Germany
http://www.arvato.com/

andreas.nolte@bertelsmann.de
Phone   +49 (0) 4421 - 76- 84002
Fax     +49 (0) 4421 - 76- 84111
  

 

Re: Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Posted by "Philip M. Gollucci" <pg...@p6m7g8.com>.
Perrin Harkins wrote:

>On Tuesday 24 May 2005 2:36 pm, Philip M. Gollucci wrote:
>  
>
>>httpd -X
>>    
>>
>
>What would be appropriate behavior in that case?  Report the size but not kill 
>the process?
>  
>
That sounds good to me.  I wasn't really following this thread.  I just 
saw something I could answer :)

-- 
END 
---------------------------------------------------------
    What doesn't kill us, can only make us stronger.
               Nothing is impossible.
				
Philip M. Gollucci (pgollucci@p6m7g8.com) 301.254.5198
Consultant / http://p6m7g8.net/Resume/resume.shtml
Senior Developer / Liquidity Services, Inc.
     http://www.liquidityservicesinc.com


Re: Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Posted by Perrin Harkins <pe...@elem.com>.
On Tuesday 24 May 2005 2:36 pm, Philip M. Gollucci wrote:
> httpd -X

What would be appropriate behavior in that case?  Report the size but not kill 
the process?

- Perrin

Re: Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Posted by "Philip M. Gollucci" <pg...@p6m7g8.com>.
Perrin Harkins wrote:

>On Tuesday 24 May 2005 3:39 am, Andreas.Nolte@Bertelsmann.de wrote:
>  
>
>>I claim, the "main process " detection does never work and does not make
>>sense.
>>    
>>
>
>As other have pointed out, it does work, but apparently has issues on some 
>platforms for some people.  However, I can't see any reason why the main 
>process would serve a request, so maybe the whole thing is pointless and 
>should be removed rather than fixed.
>
>Can anyone think of a reason why the main process would server a request?  I 
>suppose you could misconfigure this to run the size check during a phase that 
>is in the main process, but it's easier to check for the current phase than 
>to fix the pid stuff.
>
>- Perrin
>  
>
httpd -X


-- 
END 
---------------------------------------------------------
    What doesn't kill us, can only make us stronger.
               Nothing is impossible.
				
Philip M. Gollucci (pgollucci@p6m7g8.com) 301.254.5198
Consultant / http://p6m7g8.net/Resume/resume.shtml
Senior Developer / Liquidity Services, Inc.
     http://www.liquidityservicesinc.com


Re: Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Posted by Perrin Harkins <pe...@elem.com>.
On Tuesday 24 May 2005 3:39 am, Andreas.Nolte@Bertelsmann.de wrote:
> I claim, the "main process " detection does never work and does not make
> sense.

As other have pointed out, it does work, but apparently has issues on some 
platforms for some people.  However, I can't see any reason why the main 
process would serve a request, so maybe the whole thing is pointless and 
should be removed rather than fixed.

Can anyone think of a reason why the main process would server a request?  I 
suppose you could misconfigure this to run the size check during a phase that 
is in the main process, but it's easier to check for the current phase than 
to fix the pid stuff.

- Perrin

Re: Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Posted by Torsten Foertsch <to...@gmx.net>.
On Tuesday 24 May 2005 11:48, Marc Gràcia wrote:
> > But there is a problem with Perls getppid() implementation. Modern Perls
> > issue the syscall only once and cache the result. Maybe you somehow hit
> > that. Normally the cache is invalidated when Perl forks, but Apache does
> > its own fork. Thus maybe the cache remains.
>
> In Apache::GTopLimit i had to modify the source to use Linux::Pid
> package to get the pid instead of the default
> function. If not allways returned the parent pid.
> After all this, everything worked fine...
> It seems to me the same problem.

I've just uploaded Perl::AfterFork to CPAN. The module implements a function 
that does what Perl is doing after a successful fork in the child. That also 
may help.

Torsten

Re: Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Posted by Marc Gràcia <mg...@oasyssoft.com>.
El dt 24 de 05 del 2005 a les 11:19 +0200, en/na Torsten Foertsch va
escriure:

> On Tuesday 24 May 2005 09:39, Andreas.Nolte@Bertelsmann.de wrote:
> > I claim, the "main process " detection does never work and does not make
> > sense. Why? Not even when the apache is started on boot through init, the
> > PPID will be 1, but some shell / rc pid.  You can only find the PPID in the
> > PID file that apache writes. But still: this should never be the case -
> > right ? 
> 
> Normally Apache forks on startup to get rid of its parent. So the init-process 
> (1) inherits the orphan. Then Apache spawns its workers that are direct 
> children of the master Apache. Hence the test is in principle right.
> 
> r2@opi:~> ps -lC httpd
> F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
> 5 S     0  7155     1  0  76   0 -  2756 -      ?        00:00:00 httpd
> 5 S    30  7158  7155  0  80   0 -  2774 322495 ?        00:00:00 httpd
> 5 S    30  7159  7155  0  80   0 -  2774 semtim ?        00:00:00 httpd
> 
> PID 7155 is the main apache. It's PPID is 1.
> 
> But there is a problem with Perls getppid() implementation. Modern Perls issue 
> the syscall only once and cache the result. Maybe you somehow hit that. 
> Normally the cache is invalidated when Perl forks, but Apache does its own 
> fork. Thus maybe the cache remains.

In Apache::GTopLimit i had to modify the source to use Linux::Pid
package to get the pid instead of the default
function. If not allways returned the parent pid.
After all this, everything worked fine...
It seems to me the same problem.


> 
> I'd try to replace getppid with syscall( &SYS_getppid ) and see if it changes 
> anything.
> 
> Torsten

Re: Apache::SizeLimit ( mp1 and mp2 )-> I think there is a logical error in the code ...

Posted by Torsten Foertsch <to...@gmx.net>.
On Tuesday 24 May 2005 09:39, Andreas.Nolte@Bertelsmann.de wrote:
> I claim, the "main process " detection does never work and does not make
> sense. Why? Not even when the apache is started on boot through init, the
> PPID will be 1, but some shell / rc pid.  You can only find the PPID in the
> PID file that apache writes. But still: this should never be the case -
> right ? 

Normally Apache forks on startup to get rid of its parent. So the init-process 
(1) inherits the orphan. Then Apache spawns its workers that are direct 
children of the master Apache. Hence the test is in principle right.

r2@opi:~> ps -lC httpd
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
5 S     0  7155     1  0  76   0 -  2756 -      ?        00:00:00 httpd
5 S    30  7158  7155  0  80   0 -  2774 322495 ?        00:00:00 httpd
5 S    30  7159  7155  0  80   0 -  2774 semtim ?        00:00:00 httpd

PID 7155 is the main apache. It's PPID is 1.

But there is a problem with Perls getppid() implementation. Modern Perls issue 
the syscall only once and cache the result. Maybe you somehow hit that. 
Normally the cache is invalidated when Perl forks, but Apache does its own 
fork. Thus maybe the cache remains.

I'd try to replace getppid with syscall( &SYS_getppid ) and see if it changes 
anything.

Torsten