Am 02.06.2016 um 17:06 schrieb Dietmar Maurer:
>> I can see the reason to use waitpid instead of check_process_running(),
>> but why do you change the rest of the code?
>>
>> Can we have minimal patches, where each patch states the reason for the 
>> change
>> in the commit log?
> 
> I thought about something like this:
> 
> diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
> index a25efff..ce5774e 100644
> --- a/PVE/QemuMigrate.pm
> +++ b/PVE/QemuMigrate.pm
> @@ -71,6 +71,8 @@ sub finish_command_pipe {
>      $self->log('info', "ssh tunnel still running - terminating now with
> SIGKILL\n");
>      kill 9, $cpid;
>      sleep 1;
> +
> +    waitpid($cpid); # avoid zombies

That doesn't fixes it :)

You have returns above so this statement is only reached if all fails
and the tunnel has to be killed, in normal cases the child does not get
selected.

Also the writer/reader may get double closed here, i thought about
something like
diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index a25efff..d869fa3 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -42,37 +42,53 @@ sub fork_command_pipe {
 }

 sub finish_command_pipe {
     my ($self, $cmdpipe, $timeout) = @_;

+    my $cpid = $cmdpipe->{pid};
+    return if !defined($cpid);
+
     my $writer = $cmdpipe->{writer};
     my $reader = $cmdpipe->{reader};

     $writer->close();
     $reader->close();

-    my $cpid = $cmdpipe->{pid};
-
+    my $waitpid;
     if ($timeout) {
        for (my $i = 0; $i < $timeout; $i++) {
-           return if !PVE::ProcFSTools::check_process_running($cpid);
+           $waitpid = waitpid($cpid, WNOHANG);
+           if (defined($waitpid) && $waitpid == $cpid) {
+               delete $cmdpipe->{cpid};
+               return;
+           }
            sleep(1);
        }
     }

     $self->log('info', "ssh tunnel still running - terminating now with
SIGTERM\n");
     kill(15, $cpid);

     # wait again
     for (my $i = 0; $i < 10; $i++) {
-       return if !PVE::ProcFSTools::check_process_running($cpid);
+       $waitpid = waitpid($cpid, WNOHANG);
+       if (defined($waitpid) && $waitpid == $cpid) {
+           delete $cmdpipe->{cpid};
+           return;
+       }
        sleep(1);
     }

     $self->log('info', "ssh tunnel still running - terminating now with
SIGKILL\n");
     kill 9, $cpid;
     sleep 1;
+
+    $waitpid = waitpid($cpid, WNOHANG);
+    $self->log('err', "Tunnel process (PID $cpid) could not be
collected after kill")
+       if (!(defined($waitpid) && $waitpid == $cpid));
+
+    delete $cmdpipe->{cpid};
 }


>  }
> 
>  sub fork_tunnel {
> 

_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to