# Abstract class to implement Daemons
#
# Features:
-# * lock and write PID file /var/run/$name.pid to make sure onyl
+# * lock and write PID file /var/run/$name.pid to make sure only
# one instance is running.
# * keep lock open during restart
# * correctly daemonize (redirect STDIN/STDOUT)
my ($running, $pid) = $self->running();
if ($running) {
- die "can't aquire lock '$lkfn' - daemon already started (pid = $pid)\n";
+ die "can't acquire lock '$lkfn' - daemon already started (pid = $pid)\n";
} else {
- die "can't aquire lock '$lkfn' - $err\n";
+ die "can't acquire lock '$lkfn' - $err\n";
}
}
};
return if $self->{terminate};
- my $count = 0;
- foreach my $cpid (keys %{$self->{workers}}) {
- $count++;
- }
-
+ my $count = scalar keys %{$self->{workers}};
my $need = $self->{max_workers} - $count;
return if $need <= 0;
}
};
+my $terminate_old_workers = sub {
+ my ($self) = @_;
+
+ # if list is empty kill sends no signal, so no checks needed
+ kill 15, keys %{$self->{old_workers}};
+};
+
my $terminate_server = sub {
my ($self, $allow_open_children) = @_;
$self->{terminate} = 1; # set flag to avoid worker restart
- if (!$self->{max_workers}) {
- eval { $self->shutdown(); };
- warn $@ if $@;
- return;
- }
-
eval { $self->shutdown(); };
warn $@ if $@;
- # we have workers - send TERM signal
-
- foreach my $cpid (keys %{$self->{workers}}) {
- kill(15, $cpid); # TERM childs
- }
+ return if !$self->{max_workers}; # if we have no workers we're done here
# if configured, leave children running on HUP
- return if $allow_open_children &&
- $self->{leave_children_open_on_reload};
+ return if $allow_open_children && $self->{leave_children_open_on_reload};
- # else, send TERM to old workers
- foreach my $cpid (keys %{$self->{old_workers}}) {
- kill(15, $cpid); # TERM childs
- }
+ # else send TERM to all (old and current) child workers
+ kill 15, (keys %{$self->{workers}}, keys %{$self->{old_workers}});
# nicely shutdown childs (give them max 10 seconds to shut down)
my $previous_alarm = alarm(10);
if ($restart && $self->{max_workers}) {
if (my $wpids = $ENV{PVE_DAEMON_WORKER_PIDS}) {
foreach my $pid (split(':', $wpids)) {
+ # check & untaint
if ($pid =~ m/^(\d+)$/) {
$self->{old_workers}->{$1} = 1;
}
&$old_sig_chld(@_) if $old_sig_chld;
};
- # catch worker finished during restart phase
- &$finish_workers($self);
-
# now loop forever (until we receive terminate signal)
for (;;) {
&$start_workers($self);
sleep(5);
+ &$terminate_old_workers($self);
&$finish_workers($self);
last if $self->{terminate};
}
}
if ($self->{max_workers}) {
- my @workers = keys %{$self->{workers}};
- push @workers, keys %{$self->{old_workers}};
+ my @workers = (keys %{$self->{workers}}, keys %{$self->{old_workers}});
$ENV{PVE_DAEMON_WORKER_PIDS} = join(':', @workers);
}