I have a daemonized script that is producing zombies under 5.8, but running prefectly fine under 5.6.1. Here is the script:
#!/usr/bin/perl
# report_server
# this script will run in the background and pickup
# .pld files waiting to be run.
# load up our modules
use Storable;
use MyModule::SEO;
use Proc::Fork;
use strict;
use Data::Dumper;
use POSIX;
# set some globals
use vars ('%processing','$seo_master') ;
# this code was borrowed from Net::Daemonize
# this code runs in conjunction with Apache and needs to
# share ownership with it for the files it generates
my $uid = getpwnam('nobody');
$< = $> = $uid;
if( $< != $uid ){
die "Couldn't become uid \"$uid\"\n";
}
POSIX::setuid( $uid ) || die "Couldn't POSIX::setuid to \"$uid\" [$!]\
+n";
# end borrowed code
use Proc::Daemon;
Proc::Daemon::Init;
# create our master object
# should this be in the loop?
# Its only purpose is to log file pickup
# to the master log file, handled by the
# error_to_log method
my $master_seo = MyModule::SEO->new;
$master_seo->_debug(1);
&loop;
sub loop {
# create our array of temp files to check
my @pld_file = </web/tmp/*.pld>;
foreach my $file (@pld_file) {
# delete a file from the processing hash if it
# has been in has for more then 20 minutes and
# the file still exists
if (time > ($processing{$file}[1] + 1200) ) {
delete $processing{$file};
}
# skip file if it is still flagged as being processed
next if $processing{$file}[0] == 1;
# log file pick
$master_seo->error_to_log("Picked up $file for processing",1);
# set our values to check against on future requests
$processing{$file}[0] = 1;
$processing{$file}[1] = time;
$file =~ /(\d{2,})\.pld/;
my $number = $1;
child {
exec('/web/bin/report_generator.pl',$number);
# in case it doesn't spawn just exit
exit;
};
}
# wait 15 seconds and then check again
sleep 15;
&loop;
}
The code is run unchanged between the development server (5.8) and the production server (5.6.1). The script has been in place in production and running without a problem for over 46 days. A recent upgrade of the development server to 5.8 exposed the zombie issue.
Is there a better way to daemonize the script and run as a specific none root user?
What is a way to debug to find the cause of zombies?