all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH pve-manager] pvescheduler: hold off HUP and CHLD while a child is forked and recorded
@ 2026-09-15 13:36 Hannes Laimer
  0 siblings, 0 replies; only message in thread
From: Hannes Laimer @ 2026-09-15 13:36 UTC (permalink / raw)
  To: pve-devel

A HUP that lands between the fork and recording neither stops nor hands
over that child, since the hand-over string is built in the HUP handler
from what is recorded. A CHLD from a child that exits right after the
fork, before it is recorded, is missed by the reap it triggers and
cleared only at the next CHLD from an unrelated child.

Hold both signals off until the child is recorded, and once a HUP came
in fork nothing more, since the hand-over is already put together.

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
really really tight timeframe, but these workers can be really fast if
nothing has to be done, either way, we should address this, even if
unlikely

 PVE/Service/pvescheduler.pm | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/PVE/Service/pvescheduler.pm b/PVE/Service/pvescheduler.pm
index f7271fc0..be33db6e 100755
--- a/PVE/Service/pvescheduler.pm
+++ b/PVE/Service/pvescheduler.pm
@@ -3,7 +3,7 @@ package PVE::Service::pvescheduler;
 use strict;
 use warnings;
 
-use POSIX qw(WNOHANG);
+use POSIX qw(WNOHANG SIGCHLD SIGHUP SIG_BLOCK SIG_SETMASK);
 
 use PVE::Jobs;
 use PVE::SafeSyslog;
@@ -80,10 +80,20 @@ sub run {
         # FIXME: some job types may handle this better themself or just not care - make configurable
         return if scalar(keys $self->{jobs}->{$type}->%*);
 
+        # recorded before a HUP hands children over or a CHLD reaps them
+        my $prev_mask = POSIX::SigSet->new();
+        POSIX::sigprocmask(SIG_BLOCK, POSIX::SigSet->new(SIGHUP, SIGCHLD), $prev_mask);
+        # the hand-over is already built once a HUP came in
+        if ($self->{got_hup_signal}) {
+            POSIX::sigprocmask(SIG_SETMASK, $prev_mask);
+            return;
+        }
         my $child = fork();
         if (!defined($child)) {
+            POSIX::sigprocmask(SIG_SETMASK, $prev_mask);
             die "fork failed: $!\n";
         } elsif ($child == 0) {
+            POSIX::sigprocmask(SIG_SETMASK, $prev_mask);
             $self->after_fork_cleanup();
             eval { $sub->(); };
             if (my $err = $@) {
@@ -93,6 +103,7 @@ sub run {
         }
 
         $jobs->{$type}->{$child} = 1;
+        POSIX::sigprocmask(SIG_SETMASK, $prev_mask);
     };
 
     my $first_run = 1;
-- 
2.47.3





^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-15 13:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-15 13:36 [PATCH pve-manager] pvescheduler: hold off HUP and CHLD while a child is forked and recorded Hannes Laimer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal