Detect and reset locked shared memory.
git-svn-id: https://svn.perl.org/qpsmtpd/trunk@941 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
aa802e6844
commit
409372ce58
3
Changes
3
Changes
@ -1,3 +1,6 @@
|
||||
prefork: detect and reset locked shared memory (based on patch by
|
||||
Diego d'Ambra)
|
||||
|
||||
prefork: untaint the value of the --interface option (reported by
|
||||
Diego d'Ambra)
|
||||
|
||||
|
@ -327,18 +327,26 @@ sub main_loop {
|
||||
if (defined($chld_busy)) {
|
||||
info("busy children: $chld_busy");
|
||||
$chld_pool = $chld_busy + $idle_children;
|
||||
}
|
||||
|
||||
# ensure pool limit is max_children
|
||||
$chld_pool = $max_children if ($chld_pool > $max_children);
|
||||
info( "children pool: $chld_pool, spawned: "
|
||||
. scalar(keys %children)
|
||||
. ", busy: $chld_busy");
|
||||
}
|
||||
else {
|
||||
|
||||
# reset shared memory
|
||||
warn("unable to access shared memory - resetting it");
|
||||
IPC::Shareable->clean_up;
|
||||
my $shmem = shmem($d_port . "qpsmtpd", 1);
|
||||
untie $shmem;
|
||||
}
|
||||
|
||||
# spawn children
|
||||
for (my $i = scalar(keys %children) ; $i < $chld_pool ; $i++) {
|
||||
new_child(); # add to the child pool
|
||||
}
|
||||
info( "children pool: $chld_pool (currently spawned: "
|
||||
. scalar(keys %children)
|
||||
. ")");
|
||||
|
||||
# unblock signals
|
||||
unblock_signal($sigset);
|
||||
@ -530,9 +538,21 @@ sub shmem_opt {
|
||||
$chld_shmem = &shmem($d_port."qpsmtpd", 0); #connect to shared memory hash
|
||||
|
||||
if (tied %{$chld_shmem}) {
|
||||
# perform options
|
||||
|
||||
# lock shared memory
|
||||
eval {
|
||||
# ensure that hung shared memory is noticed
|
||||
local $SIG{ALRM} = sub {
|
||||
die "locking timed out\n";
|
||||
};
|
||||
alarm 15;
|
||||
|
||||
(tied %{$chld_shmem})->shlock(LOCK_EX);
|
||||
|
||||
alarm 0;
|
||||
};
|
||||
die $@ if $@;
|
||||
|
||||
# delete
|
||||
if ($ref_pid_del) {
|
||||
foreach my $pid_del (@{$ref_pid_del}) {
|
||||
@ -543,6 +563,8 @@ sub shmem_opt {
|
||||
$$chld_shmem{$pid_add_key} = $pid_add_value if ($pid_add_key);
|
||||
# copy
|
||||
%{$ref_shmem} = %{$chld_shmem} if ($ref_shmem);
|
||||
|
||||
# check
|
||||
if ($check) {
|
||||
# loop through pid list and delete orphaned processes
|
||||
foreach my $pid (keys %{$chld_shmem}) {
|
||||
@ -553,13 +575,18 @@ sub shmem_opt {
|
||||
}
|
||||
}
|
||||
|
||||
# count number of busy children
|
||||
# number of busy children
|
||||
$chld_busy = scalar(keys %{$chld_shmem});
|
||||
|
||||
# unlock shared memory
|
||||
(tied %{$chld_shmem})->shunlock;
|
||||
|
||||
# untie from shared memory
|
||||
untie $chld_shmem || die "unable to untie from shared memory";
|
||||
}
|
||||
else {
|
||||
die "failed to connect to shared memory";
|
||||
}
|
||||
};
|
||||
|
||||
# check for error
|
||||
@ -669,8 +696,13 @@ sub qpsmtpd_session {
|
||||
warn("$@");
|
||||
}
|
||||
|
||||
# child is now idle again so remove it's pid from shared mem
|
||||
shmem_opt(undef, [$$], undef, undef);
|
||||
# child is now idle again
|
||||
info("disconnect from: $nto_iaddr:$port");
|
||||
|
||||
info("remote host: $ENV{TCPREMOTEIP} left...");
|
||||
# remove pid from shared memory
|
||||
unless (defined(shmem_opt(undef, [$$], undef, undef))) {
|
||||
# exit because parent is down or shared memory is corrupted
|
||||
info("parent seems to be down, going to exit");
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user