use POSIX::_exit instead of exit in forked child

This avoids calling the END blocks and destructor routines most of
which have nothing to do with the fork, so it cannot be assumed to be
safe to do from the fork.

Move the call to pve_rados_shutdown from the destructor routine,
which will not be called by the child anymore. Make sure the cleanup
is also done when the worker dies.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
Fiona Ebner 2023-08-08 13:23:12 +02:00 committed by Wolfgang Bumiller
parent 8cab00fca3
commit 8d524b3e0f

View File

@ -7,6 +7,7 @@ use warnings;
use Carp;
use JSON;
use POSIX;
use Socket;
use PVE::Tools;
@ -195,24 +196,30 @@ sub new {
} else { # child
$0 = 'pverados';
PVE::INotify::inotify_close();
eval {
PVE::INotify::inotify_close();
if (my $atfork = $rpcenv->{atfork}) {
&$atfork();
}
if (my $atfork = $rpcenv->{atfork}) {
&$atfork();
}
# override signal handlers inherited from the parent
local $SIG{HUP} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
exit(1);
# override signal handlers inherited from the parent
local $SIG{HUP} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
pve_rados_shutdown($self->{conn}) if $self->{conn};
POSIX::_exit(1);
};
# fixme: timeout?
close $child;
$self->pve_rados_work($parent, $timeout, %params);
};
my $err = $@;
warn $err if $err;
# fixme: timeout?
close $child;
$self->pve_rados_work($parent, $timeout, %params);
exit(0);
pve_rados_shutdown($self->{conn}) if $self->{conn};
POSIX::_exit($err ? 1 : 0);
}
return $self;
@ -233,9 +240,6 @@ sub DESTROY {
#print "$$: DESTROY WAIT0\n";
&$kill_worker($self);
#print "$$: DESTROY WAIT\n";
} else {
#print "$$: DESTROY SHUTDOWN\n";
pve_rados_shutdown($self->{conn}) if $self->{conn};
}
}