mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-06-15 01:14:30 +00:00
qmpclient: now if the QMP command starts with guest-+ , it will bind dynamicly to the VMID.qga socket
Signed-off-by: Wolfgang Link <wolfgang@linksystems.org>
This commit is contained in:
parent
bcfbc40b39
commit
c5a07de5af
@ -20,7 +20,7 @@ use Data::Dumper;
|
|||||||
# Note: kvm can onyl handle 1 connection, so we close connections asap
|
# Note: kvm can onyl handle 1 connection, so we close connections asap
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ($class, $eventcb, $qga) = @_;
|
my ($class, $eventcb) = @_;
|
||||||
|
|
||||||
my $mux = new IO::Multiplex;
|
my $mux = new IO::Multiplex;
|
||||||
|
|
||||||
@ -34,7 +34,6 @@ sub new {
|
|||||||
}, $class;
|
}, $class;
|
||||||
|
|
||||||
$self->{eventcb} = $eventcb if $eventcb;
|
$self->{eventcb} = $eventcb if $eventcb;
|
||||||
$self->{qga} = $qga if $qga;
|
|
||||||
|
|
||||||
$mux->set_callback_object($self);
|
$mux->set_callback_object($self);
|
||||||
|
|
||||||
@ -106,9 +105,17 @@ sub cmd {
|
|||||||
};
|
};
|
||||||
|
|
||||||
my $cmdid_seq = 0;
|
my $cmdid_seq = 0;
|
||||||
|
my $cmdid_seq_qga = 0;
|
||||||
my $next_cmdid = sub {
|
my $next_cmdid = sub {
|
||||||
$cmdid_seq++;
|
my ($qga) = @_;
|
||||||
return "$$"."0".$cmdid_seq;
|
|
||||||
|
if($qga){
|
||||||
|
$cmdid_seq_qga++;
|
||||||
|
return "$$"."0".$cmdid_seq_qga;
|
||||||
|
} else {
|
||||||
|
$cmdid_seq++;
|
||||||
|
return "$$:$cmdid_seq";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
my $close_connection = sub {
|
my $close_connection = sub {
|
||||||
@ -124,9 +131,9 @@ my $close_connection = sub {
|
|||||||
};
|
};
|
||||||
|
|
||||||
my $open_connection = sub {
|
my $open_connection = sub {
|
||||||
my ($self, $vmid, $timeout) = @_;
|
my ($self, $vmid, $timeout, $qga) = @_;
|
||||||
|
|
||||||
my $sname = PVE::QemuServer::qmp_socket($vmid, $self->{qga});
|
my $sname = PVE::QemuServer::qmp_socket($vmid, $qga);
|
||||||
|
|
||||||
$timeout = 1 if !$timeout;
|
$timeout = 1 if !$timeout;
|
||||||
|
|
||||||
@ -181,7 +188,7 @@ my $check_queue = sub {
|
|||||||
eval {
|
eval {
|
||||||
|
|
||||||
my $cmd = $self->{current}->{$vmid} = shift @{$self->{queue}->{$vmid}};
|
my $cmd = $self->{current}->{$vmid} = shift @{$self->{queue}->{$vmid}};
|
||||||
$cmd->{id} = &$next_cmdid();
|
$cmd->{id} = &$next_cmdid($cmd->{qga});
|
||||||
|
|
||||||
my $fd = -1;
|
my $fd = -1;
|
||||||
if ($cmd->{execute} eq 'add-fd' || $cmd->{execute} eq 'getfd') {
|
if ($cmd->{execute} eq 'add-fd' || $cmd->{execute} eq 'getfd') {
|
||||||
@ -191,7 +198,7 @@ my $check_queue = sub {
|
|||||||
|
|
||||||
my $qmpcmd = undef;
|
my $qmpcmd = undef;
|
||||||
|
|
||||||
if($self->{qga}){
|
if($self->{current}->{$vmid}->{qga}){
|
||||||
|
|
||||||
my $qmpcmdid =to_json({
|
my $qmpcmdid =to_json({
|
||||||
execute => 'guest-sync',
|
execute => 'guest-sync',
|
||||||
@ -243,10 +250,14 @@ sub queue_execute {
|
|||||||
foreach my $vmid (keys %{$self->{queue}}) {
|
foreach my $vmid (keys %{$self->{queue}}) {
|
||||||
next if !scalar(@{$self->{queue}->{$vmid}}); # no commands for the VM
|
next if !scalar(@{$self->{queue}->{$vmid}}); # no commands for the VM
|
||||||
|
|
||||||
eval {
|
if ($self->{queue}->{$vmid}[0]->{execute} =~ /^guest\-+/){
|
||||||
my $fh = &$open_connection($self, $vmid, $timeout);
|
$self->{queue}->{$vmid}[0]->{qga} = "1";
|
||||||
|
}
|
||||||
|
|
||||||
if(!$self->{qga}){
|
eval {
|
||||||
|
my $fh = &$open_connection($self, $vmid, $timeout, $self->{queue}->{$vmid}[0]->{qga});
|
||||||
|
|
||||||
|
if(!$self->{queue}->{$vmid}[0]->{qga}){
|
||||||
my $cmd = { execute => 'qmp_capabilities', arguments => {} };
|
my $cmd = { execute => 'qmp_capabilities', arguments => {} };
|
||||||
unshift @{$self->{queue}->{$vmid}}, $cmd;
|
unshift @{$self->{queue}->{$vmid}}, $cmd;
|
||||||
}
|
}
|
||||||
@ -292,26 +303,29 @@ sub mux_close {
|
|||||||
sub mux_input {
|
sub mux_input {
|
||||||
my ($self, $mux, $fh, $input) = @_;
|
my ($self, $mux, $fh, $input) = @_;
|
||||||
|
|
||||||
my $raw;
|
my $vmid = $self->{fhs_lookup}->{$fh};
|
||||||
|
|
||||||
if($self->{qga}){
|
|
||||||
return if $$input !~ s/^([^\n]+}\n[^\n]+})\n(.*)$/$2/so;
|
|
||||||
$raw = $1;
|
|
||||||
}else{
|
|
||||||
return if $$input !~ s/^([^\n]+})\r?\n(.*)$/$2/so;
|
|
||||||
$raw = $1;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $vmid = $self->{fhs_lookup}->{$fh};
|
|
||||||
if (!$vmid) {
|
if (!$vmid) {
|
||||||
warn "internal error - unable to lookup vmid";
|
warn "internal error - unable to lookup vmid";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $curcmd = $self->{current}->{$vmid};
|
||||||
|
die "unable to lookup current command for VM $vmid\n" if !$curcmd;
|
||||||
|
|
||||||
|
my $raw;
|
||||||
|
|
||||||
|
if ($curcmd->{qga}) {
|
||||||
|
return if $$input !~ s/^([^\n]+}\n[^\n]+})\n(.*)$/$2/so;
|
||||||
|
$raw = $1;
|
||||||
|
} else {
|
||||||
|
return if $$input !~ s/^([^\n]+})\r?\n(.*)$/$2/so;
|
||||||
|
$raw = $1;
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
my @jsons = split("\n", $raw);
|
my @jsons = split("\n", $raw);
|
||||||
|
|
||||||
if($self->{qga}){
|
if ($curcmd->{qga}) {
|
||||||
|
|
||||||
die "response is not complete" if @jsons != 2 ;
|
die "response is not complete" if @jsons != 2 ;
|
||||||
|
|
||||||
@ -319,9 +333,6 @@ sub mux_input {
|
|||||||
my $cmdid = $obj->{return};
|
my $cmdid = $obj->{return};
|
||||||
die "received responsed without command id\n" if !$cmdid;
|
die "received responsed without command id\n" if !$cmdid;
|
||||||
|
|
||||||
my $curcmd = $self->{current}->{$vmid};
|
|
||||||
die "unable to lookup current command for VM $vmid\n" if !$curcmd;
|
|
||||||
|
|
||||||
delete $self->{current}->{$vmid};
|
delete $self->{current}->{$vmid};
|
||||||
|
|
||||||
if ($curcmd->{id} ne $cmdid) {
|
if ($curcmd->{id} ne $cmdid) {
|
||||||
|
@ -3459,13 +3459,6 @@ sub vm_start {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sub vm_qga_cmd {
|
|
||||||
my ($vmid, $execute, %params) = @_;
|
|
||||||
|
|
||||||
my $cmd = { execute => $execute, arguments => \%params };
|
|
||||||
vm_qmp_command($vmid, $cmd, undef, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub vm_mon_cmd {
|
sub vm_mon_cmd {
|
||||||
my ($vmid, $execute, %params) = @_;
|
my ($vmid, $execute, %params) = @_;
|
||||||
|
|
||||||
@ -3481,7 +3474,7 @@ sub vm_mon_cmd_nocheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub vm_qmp_command {
|
sub vm_qmp_command {
|
||||||
my ($vmid, $cmd, $nocheck, $qga) = @_;
|
my ($vmid, $cmd, $nocheck) = @_;
|
||||||
|
|
||||||
my $res;
|
my $res;
|
||||||
|
|
||||||
@ -3493,12 +3486,13 @@ sub vm_qmp_command {
|
|||||||
|
|
||||||
eval {
|
eval {
|
||||||
die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
|
die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
|
||||||
|
my $qga = ($cmd->{execute} =~ /^guest\-+/)?1:0;
|
||||||
my $sname = qmp_socket($vmid, $qga);
|
my $sname = qmp_socket($vmid, $qga);
|
||||||
if (-e $sname) {
|
if (-e $sname) {
|
||||||
my $qmpclient = PVE::QMPClient->new(undef, $qga);
|
my $qmpclient = PVE::QMPClient->new();
|
||||||
|
|
||||||
$res = $qmpclient->cmd($vmid, $cmd, $timeout);
|
$res = $qmpclient->cmd($vmid, $cmd, $timeout);
|
||||||
} elsif (-e "${var_run_tmpdir}/$vmid.mon" && !$qga) {
|
} elsif (-e "${var_run_tmpdir}/$vmid.mon") {
|
||||||
die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
|
die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
|
||||||
if scalar(%{$cmd->{arguments}});
|
if scalar(%{$cmd->{arguments}});
|
||||||
vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
|
vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
|
||||||
|
Loading…
Reference in New Issue
Block a user