X-Git-Url: https://git.proxmox.com/?p=pve-access-control.git;a=blobdiff_plain;f=PVE%2FRPCEnvironment.pm;h=4cacd520f3c8261d1e28d068d110ad17f8ed7f00;hp=a18ceb1c8fbb568c976449dab23777f6fc1fefe6;hb=5a941ebef2e902b59449d15a3f21400989ae641c;hpb=2c3a6c0aaac7fbdaeb26bc5a596d21e897f3343a diff --git a/PVE/RPCEnvironment.pm b/PVE/RPCEnvironment.pm index a18ceb1..4cacd52 100644 --- a/PVE/RPCEnvironment.pm +++ b/PVE/RPCEnvironment.pm @@ -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,10 +334,9 @@ sub active_workers { my $thash = {}; # only list task once my $check_task = sub { - my ($task) = @_; + my ($task, $running) = @_; - my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid}); - if ($pstart && ($pstart == $task->{pstart})) { + if ($running || PVE::ProcFSTools::check_process_running($task->{pid}, $task->{pstart})) { push @$tlist, $task; } else { delete $task->{pid}; @@ -355,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); } @@ -427,6 +428,42 @@ sub active_workers { return $res; } +my $kill_process_group = sub { + my ($pid, $pstart) = @_; + + # send kill to process group (negative pid) + my $kpid = -$pid; + + # always send signal to all pgrp members + kill(15, $kpid); # send TERM signal + + # give max 5 seconds to shut down + for (my $i = 0; $i < 5; $i++) { + return if !PVE::ProcFSTools::check_process_running($pid, $pstart); + sleep (1); + } + + # to be sure + kill(9, $kpid); +}; + +sub check_worker { + my ($upid, $killit) = @_; + + my $task = PVE::Tools::upid_decode($upid); + + my $running = PVE::ProcFSTools::check_process_running($task->{pid}, $task->{pstart}); + + return 0 if !$running; + + if ($killit) { + &$kill_process_group($task->{pid}); + return 0; + } + + return 1; +} + # start long running workers # STDIN is redirected to /dev/null # STDOUT,STDERR are redirected to the filename returned by upid_decode @@ -494,13 +531,17 @@ sub fork_worker { # same algorythm as used inside SA # STDIN = /dev/null my $fd = fileno (STDIN); - close STDIN; - POSIX::close(0) if $fd != 0; - die "unable to redirect STDIN - $!" - if !open(STDIN, " 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; @@ -632,6 +687,7 @@ sub fork_worker { } if ($outfh) { print $outfh $line; + $outfh->flush(); } } } @@ -653,15 +709,13 @@ sub fork_worker { if ($outfh) { print $outfh "TASK ERROR: $err\n"; } - kill (15, $cpid); - - } else { - kill (9, $cpid); # make sure it gets killed } + &$kill_process_group($cpid, $pstart); # make sure it gets killed + close($outfh); - waitpid ($cpid, 0); + waitpid($cpid, 0); $res = $?; &$log_task_result($upid, $user, $res); }