From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <d.csapak@proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id 0223380999
 for <pve-devel@lists.proxmox.com>; Thu, 18 Nov 2021 14:29:04 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id DB31C1C402
 for <pve-devel@lists.proxmox.com>; Thu, 18 Nov 2021 14:28:33 +0100 (CET)
Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com
 [94.136.29.106])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by firstgate.proxmox.com (Proxmox) with ESMTPS id C0B741C3ED
 for <pve-devel@lists.proxmox.com>; Thu, 18 Nov 2021 14:28:32 +0100 (CET)
Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1])
 by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 5AFED43CC9
 for <pve-devel@lists.proxmox.com>; Thu, 18 Nov 2021 14:28:32 +0100 (CET)
From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Date: Thu, 18 Nov 2021 14:28:31 +0100
Message-Id: <20211118132831.839774-3-d.csapak@proxmox.com>
X-Mailer: git-send-email 2.30.2
In-Reply-To: <20211118132831.839774-1-d.csapak@proxmox.com>
References: <20211118132831.839774-1-d.csapak@proxmox.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.212 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pve-devel] [PATCH manager 3/3] pvescheduler: implement graceful
 reloading
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Thu, 18 Nov 2021 13:29:04 -0000

utilize PVE::Daemons 'hup' functionality to reload gracefully.

Leaves the children running (if any) and give them to the new instance
via ENV variables. After loading, check if they are still around

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
the only weird behaviour is that the re-exec can be up to one minute
after the reload, since we only get into the loop once a minute

we can shorten the loop cycle if we want though..

 PVE/Service/pvescheduler.pm   | 22 +++++++++++++++++++++-
 services/pvescheduler.service |  1 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/PVE/Service/pvescheduler.pm b/PVE/Service/pvescheduler.pm
index 466cc599..700c96ec 100755
--- a/PVE/Service/pvescheduler.pm
+++ b/PVE/Service/pvescheduler.pm
@@ -24,19 +24,35 @@ my $finish_jobs = sub {
     for my $type (@types) {
 	if (my $cpid = $self->{jobs}->{$type}) {
 	    my $waitpid = waitpid($cpid, WNOHANG);
-	    if (defined($waitpid) && ($waitpid == $cpid)) {
+	    if (defined($waitpid) && ($waitpid == $cpid) || $waitpid == -1) {
 		$self->{jobs}->{$type} = undef;
 	    }
 	}
     }
 };
 
+sub hup {
+    my ($self) = @_;
+
+    for my $type (@types) {
+	my $pid = $self->{jobs}->{$type};
+	next if !defined($pid);
+	$ENV{"PVE_DAEMON_${type}_PID"} = $pid;
+    }
+}
+
 sub run {
     my ($self) = @_;
 
     my $jobs = {};
     $self->{jobs} = $jobs;
 
+    for my $type (@types) {
+	$self->{jobs}->{$type} = delete $ENV{"PVE_DAEMON_${type}_PID"};
+	# check if children finished in the meantime
+	$finish_jobs->($self);
+    }
+
     my $old_sig_chld = $SIG{CHLD};
     local $SIG{CHLD} = sub {
 	local ($@, $!, $?); # do not overwrite error vars
@@ -82,6 +98,8 @@ sub run {
 
     for (my $count = 1000;;$count++) {
 	last if $self->{shutdown_request};
+	# we got a reload signal, return gracefully and leave the forks running
+	return if $self->{got_hup_signal};
 
 	$run_jobs->();
 
@@ -125,11 +143,13 @@ sub shutdown {
 
 $daemon->register_start_command();
 $daemon->register_stop_command();
+$daemon->register_restart_command(1);
 $daemon->register_status_command();
 
 our $cmddef = {
     start => [ __PACKAGE__, 'start', []],
     stop => [ __PACKAGE__, 'stop', []],
+    restart => [ __PACKAGE__, 'restart', []],
     status => [ __PACKAGE__, 'status', [], undef, sub { print shift . "\n";} ],
 };
 
diff --git a/services/pvescheduler.service b/services/pvescheduler.service
index 11769e80..e6f10832 100644
--- a/services/pvescheduler.service
+++ b/services/pvescheduler.service
@@ -8,6 +8,7 @@ After=pve-storage.target
 [Service]
 ExecStart=/usr/bin/pvescheduler start
 ExecStop=/usr/bin/pvescheduler stop
+ExecReload=/usr/bin/pvescheduler restart
 PIDFile=/var/run/pvescheduler.pid
 KillMode=process
 Type=forking
-- 
2.30.2