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
|
prefork: untaint the value of the --interface option (reported by
|
||||||
Diego d'Ambra)
|
Diego d'Ambra)
|
||||||
|
|
||||||
|
@ -327,18 +327,26 @@ sub main_loop {
|
|||||||
if (defined($chld_busy)) {
|
if (defined($chld_busy)) {
|
||||||
info("busy children: $chld_busy");
|
info("busy children: $chld_busy");
|
||||||
$chld_pool = $chld_busy + $idle_children;
|
$chld_pool = $chld_busy + $idle_children;
|
||||||
}
|
|
||||||
|
|
||||||
# ensure pool limit is max_children
|
# ensure pool limit is max_children
|
||||||
$chld_pool = $max_children if ($chld_pool > $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
|
# spawn children
|
||||||
for (my $i = scalar(keys %children) ; $i < $chld_pool ; $i++) {
|
for (my $i = scalar(keys %children) ; $i < $chld_pool ; $i++) {
|
||||||
new_child(); # add to the child pool
|
new_child(); # add to the child pool
|
||||||
}
|
}
|
||||||
info( "children pool: $chld_pool (currently spawned: "
|
|
||||||
. scalar(keys %children)
|
|
||||||
. ")");
|
|
||||||
|
|
||||||
# unblock signals
|
# unblock signals
|
||||||
unblock_signal($sigset);
|
unblock_signal($sigset);
|
||||||
@ -530,9 +538,21 @@ sub shmem_opt {
|
|||||||
$chld_shmem = &shmem($d_port."qpsmtpd", 0); #connect to shared memory hash
|
$chld_shmem = &shmem($d_port."qpsmtpd", 0); #connect to shared memory hash
|
||||||
|
|
||||||
if (tied %{$chld_shmem}) {
|
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);
|
(tied %{$chld_shmem})->shlock(LOCK_EX);
|
||||||
|
|
||||||
|
alarm 0;
|
||||||
|
};
|
||||||
|
die $@ if $@;
|
||||||
|
|
||||||
# delete
|
# delete
|
||||||
if ($ref_pid_del) {
|
if ($ref_pid_del) {
|
||||||
foreach my $pid_del (@{$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);
|
$$chld_shmem{$pid_add_key} = $pid_add_value if ($pid_add_key);
|
||||||
# copy
|
# copy
|
||||||
%{$ref_shmem} = %{$chld_shmem} if ($ref_shmem);
|
%{$ref_shmem} = %{$chld_shmem} if ($ref_shmem);
|
||||||
|
|
||||||
|
# check
|
||||||
if ($check) {
|
if ($check) {
|
||||||
# loop through pid list and delete orphaned processes
|
# loop through pid list and delete orphaned processes
|
||||||
foreach my $pid (keys %{$chld_shmem}) {
|
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});
|
$chld_busy = scalar(keys %{$chld_shmem});
|
||||||
|
|
||||||
|
# unlock shared memory
|
||||||
(tied %{$chld_shmem})->shunlock;
|
(tied %{$chld_shmem})->shunlock;
|
||||||
|
|
||||||
# untie from shared memory
|
# untie from shared memory
|
||||||
untie $chld_shmem || die "unable to 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
|
# check for error
|
||||||
@ -669,8 +696,13 @@ sub qpsmtpd_session {
|
|||||||
warn("$@");
|
warn("$@");
|
||||||
}
|
}
|
||||||
|
|
||||||
# child is now idle again so remove it's pid from shared mem
|
# child is now idle again
|
||||||
shmem_opt(undef, [$$], undef, undef);
|
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