[pve-devel] [RFC qemu-server 1/2] add better error handling for vncproxy task

Dominik Csapak d.csapak at proxmox.com
Mon Jan 23 13:51:20 CET 2017


this changes from nc6 to socat, so that we can parse the error messages
from qm vncproxy, to get rid of the ugly
'nc6 ... failed with exit code 1'
which nobody understood

but since socat has no builtin timeout for tcp connections, we have
to use run_command with a timeout and abort if we detect a connection
in socats notice messages

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
sadly i did not find a better alternative, other than doing my own
"listening on port and redirect in/output and still be able to read the
error message"

but since socats notice messages are not that much (~10 lines), i think
it is a good tradeoff

 PVE/API2/Qemu.pm | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 2c1e2c9..3ac2ba4 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1409,11 +1409,35 @@ __PACKAGE__->register_method({
 
 		my $qmstr = join(' ', @$qmcmd);
 
-		# also redirect stderr (else we get RFB protocol errors)
-		$cmd = ['/bin/nc6', '-l', '-p', $port, '-w', $timeout, '-e', "$qmstr 2>/dev/null"];
+		# open socat with notice messages, because we want to parse the
+		# "accepting connection" message
+		$cmd = ['/usr/bin/socat', '-d', '-d', '-t', $timeout, "TCP-LISTEN:$port", "EXEC:$qmstr"];
 	    }
 
-	    PVE::Tools::run_command($cmd);
+	    my $errlog = "";
+	    eval {
+		PVE::Tools::run_command($cmd, timeout => $timeout, errfunc => sub {
+		    my ($line) = @_;
+
+		    # only save the lines not from socat
+		    if ($line !~ m/socat/) {
+			# this collects the stderr from the qm vncproxy command
+			$errlog .= $line . "\n";
+		    } elsif ($line =~ m/accepting connection/) {
+			# if we detect a connection, we disable the timeout
+			# from run_command,
+			# this is ok because we are the only thing in a worker,
+			# and there is no other run_command with timeout
+			alarm 0;
+		    }
+		});
+	    };
+
+	    if ($errlog ne "") {
+		die "$errlog\n";
+	    } elsif ((my $err = $@)) {
+		die "$err\n";
+	    }
 
 	    return;
 	};
-- 
2.1.4




More information about the pve-devel mailing list