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