]> git.proxmox.com Git - pve-common.git/commitdiff
RESTEnvironment: better SIGCHLD handling in AnyEvent event loop
authorDominik Csapak <d.csapak@proxmox.com>
Mon, 20 Feb 2023 10:08:28 +0000 (11:08 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 7 Mar 2023 17:36:47 +0000 (18:36 +0100)
when we're in an API server that uses AnyEvent, we must postpone
the worker_reaper, since it calls 'active_workers' which might already
be called and then we're inside the lock twice (flocks are per process
for us, see PVE::Tools::lock_file)

This resulted in an error like this:
close (rename) atomic file '/var/log/pve/tasks/active' failed: No such file or directory

We use the fact that only 'pub' and 'priv' RESTEnvironment types are an
api server with anyevent. For other types we call it like before.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
debian/control
src/PVE/RESTEnvironment.pm

index 232a0e45f7aec55d1d1650689fc92be6157dcf45..1c75985aa4ac4aa43ecd59e3ba568fd3b9c00d23 100644 (file)
@@ -3,6 +3,7 @@ Section: perl
 Priority: optional
 Maintainer: Proxmox Support Team <support@proxmox.com>
 Build-Depends: debhelper (>= 12~),
+               libanyevent-perl,
                libclone-perl,
                libdevel-cycle-perl,
                libfilesys-df-perl,
index bf89c1228ce6be4117a7edaa83ab16b030cc0f4b..c258b1e16aaf48e1ea9f8bed220caf54b540c404 100644 (file)
@@ -14,6 +14,7 @@ use IO::File;
 use IO::Handle;
 use IO::Select;
 use POSIX qw(:sys_wait_h EINTR);
+use AnyEvent;
 
 use PVE::Exception qw(raise raise_perm_exc);
 use PVE::INotify;
@@ -111,7 +112,17 @@ sub init {
     die "unknown environment type"
        if !$type || $type !~ m/^(cli|pub|priv|ha)$/;
 
-    $SIG{CHLD} = $worker_reaper;
+    my $has_anyevent = $type eq 'pub' || $type eq 'priv';
+
+    $SIG{CHLD} = sub {
+       # when we're in an api server, we have to postpone the call to worker_reaper, otherwise it
+       # might interfere with running api calls
+       if ($has_anyevent) {
+           AnyEvent::postpone { $worker_reaper->() };
+       } else {
+           $worker_reaper->();
+       }
+    };
 
     # environment types
     # cli  ... command started fron command line