]> git.proxmox.com Git - pve-access-control.git/blobdiff - PVE/RPCEnvironment.pm
sen TERM to all pgrp members
[pve-access-control.git] / PVE / RPCEnvironment.pm
index dbfd0fdd578434a1164ae5ed0a0907231579ce63..5806107d9e7eb4a0546b503809e371dd170db854 100644 (file)
@@ -2,7 +2,7 @@ package PVE::RPCEnvironment;
 
 use strict;
 use warnings;
-use POSIX ":sys_wait_h";
+use POSIX qw(:sys_wait_h EINTR);
 use IO::File;
 use Fcntl qw(:flock);
 use PVE::SafeSyslog;
@@ -316,8 +316,10 @@ sub get_user {
 # read/update list of active workers 
 # we move all finished tasks to the archive index,
 # but keep aktive and most recent task in the active file.
+# $nocheck ... consider $new_upid still running (avoid that
+# we try to read the reult to early.
 sub active_workers  {
-    my ($new_upid) = @_;
+    my ($new_upid, $nocheck) = @_;
 
     my $lkfn = "/var/log/pve/tasks/.active.lock";
 
@@ -332,9 +334,9 @@ sub active_workers  {
        my $thash = {}; # only list task once
 
        my $check_task = sub {
-           my ($task) = @_;
+           my ($task, $running) = @_;
 
-           if (PVE::ProcFSTools::check_process_running($task->{pid}, $task->{pstart})) {
+           if ($running || PVE::ProcFSTools::check_process_running($task->{pid}, $task->{pstart})) {
                push @$tlist, $task;
            } else {
                delete $task->{pid};
@@ -354,7 +356,7 @@ sub active_workers  {
            $task = PVE::Tools::upid_decode($new_upid);
            $task->{upid} = $new_upid;
            $thash->{$new_upid} = $task;
-           &$check_task($task);
+           &$check_task($task, $nocheck);
        }
 
 
@@ -639,7 +641,7 @@ sub fork_worker {
 
     PVE::Cluster::log_msg('info', $user, "starting task $upid");
 
-    my $tlist = active_workers($upid);
+    my $tlist = active_workers($upid, $sync);
     PVE::Cluster::broadcast_tasklist($tlist);
    
     my $res = 0;
@@ -647,13 +649,27 @@ sub fork_worker {
     if ($sync) {
        my $count;
        my $outbuf = '';
+       my $int_count = 0;
        eval {
-           local $SIG{INT} = 
-               local $SIG{QUIT} = 
-               local $SIG{TERM} = sub { die "got interrupt\n"; };
+           local $SIG{INT} = local $SIG{QUIT} = local $SIG{TERM} = sub { 
+               # always send signal to all pgrp members
+               my $kpid = -$cpid;
+               if ($int_count < 3) {
+                   kill(15, $kpid); # send TERM signal
+               } else {
+                   kill(9, $kpid); # send KILL signal
+               }
+               $int_count++;
+           };
            local $SIG{PIPE} = sub { die "broken pipe\n"; };
        
-           while (($count = POSIX::read($psync[0], $readbuf, 4096)) && ($count > 0)) {
+           while (1) {
+               if (!defined($count = POSIX::read($psync[0], $readbuf, 4096))) {
+                   next if $! == EINTR;
+                   last;
+               }
+               last if $count == 0; # eof
+
                $outbuf .= $readbuf;
                while ($outbuf =~ s/^(([^\010\r\n]*)(\r|\n|(\010)+|\r\n))//s) {
                    my $line = $1;