...in addition to PVE::QMPClient for low-level. Also move all references (most with exports, the methods are used a lot and have unique enough names IMO) and fix tests.
References in __snapshot_create_vol_snapshots_hook (in QemuConfig) is an exception, as using the exported functions breaks tests. Signed-off-by: Stefan Reiter <s.rei...@proxmox.com> --- PVE/API2/Qemu.pm | 13 ++++---- PVE/API2/Qemu/Agent.pm | 7 ++-- PVE/CLI/qm.pm | 11 ++++--- PVE/Makefile | 1 + PVE/QMP.pm | 71 ++++++++++++++++++++++++++++++++++++++++ PVE/QemuConfig.pm | 15 +++++---- PVE/QemuMigrate.pm | 21 ++++++------ PVE/QemuServer.pm | 65 ++++-------------------------------- PVE/QemuServer/Agent.pm | 3 +- PVE/QemuServer/Memory.pm | 9 ++--- PVE/VZDump/QemuServer.pm | 13 ++++---- test/snapshot-test.pm | 18 +++++++--- 12 files changed, 141 insertions(+), 106 deletions(-) create mode 100644 PVE/QMP.pm diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 9912e4d..50a0592 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -21,6 +21,7 @@ use PVE::GuestHelpers; use PVE::QemuConfig; use PVE::QemuServer; use PVE::QemuMigrate; +use PVE::QMP qw(vm_mon_cmd vm_qmp_command); use PVE::RPCEnvironment; use PVE::AccessControl; use PVE::INotify; @@ -1835,8 +1836,8 @@ __PACKAGE__->register_method({ my ($ticket, undef, $remote_viewer_config) = PVE::AccessControl::remote_viewer_config($authuser, $vmid, $node, $proxy, $title, $port); - PVE::QemuServer::vm_mon_cmd($vmid, "set_password", protocol => 'spice', password => $ticket); - PVE::QemuServer::vm_mon_cmd($vmid, "expire_password", protocol => 'spice', time => "+30"); + vm_mon_cmd($vmid, "set_password", protocol => 'spice', password => $ticket); + vm_mon_cmd($vmid, "expire_password", protocol => 'spice', time => "+30"); return $remote_viewer_config; }}); @@ -2261,7 +2262,7 @@ __PACKAGE__->register_method({ # checking the qmp status here to get feedback to the gui/cli/api # and the status query should not take too long my $qmpstatus = eval { - PVE::QemuServer::vm_qmp_command($vmid, { execute => "query-status" }, 0); + vm_qmp_command($vmid, { execute => "query-status" }, 0); }; my $err = $@ if $@; @@ -2341,7 +2342,7 @@ __PACKAGE__->register_method({ my $vmid = extract_param($param, 'vmid'); my $qmpstatus = eval { - PVE::QemuServer::vm_qmp_command($vmid, { execute => "query-status" }, 0); + vm_qmp_command($vmid, { execute => "query-status" }, 0); }; my $err = $@ if $@; @@ -3093,7 +3094,7 @@ __PACKAGE__->register_method({ PVE::QemuConfig->write_config($vmid, $conf); if ($running && PVE::QemuServer::parse_guest_agent($conf)->{fstrim_cloned_disks} && PVE::QemuServer::qga_check_running($vmid)) { - eval { PVE::QemuServer::vm_mon_cmd($vmid, "guest-fstrim"); }; + eval { vm_mon_cmd($vmid, "guest-fstrim"); }; } eval { @@ -3449,7 +3450,7 @@ __PACKAGE__->register_method({ my $res = ''; eval { - $res = PVE::QemuServer::vm_human_monitor_command($vmid, $param->{command}); + $res = PVE::QMP::vm_human_monitor_command($vmid, $param->{command}); }; $res = "ERROR: $@" if $@; diff --git a/PVE/API2/Qemu/Agent.pm b/PVE/API2/Qemu/Agent.pm index 839146c..da7111e 100644 --- a/PVE/API2/Qemu/Agent.pm +++ b/PVE/API2/Qemu/Agent.pm @@ -7,6 +7,7 @@ use PVE::RESTHandler; use PVE::JSONSchema qw(get_standard_option); use PVE::QemuServer; use PVE::QemuServer::Agent qw(agent_available agent_cmd check_agent_error); +use PVE::QMP qw(vm_mon_cmd); use MIME::Base64 qw(encode_base64 decode_base64); use JSON; @@ -190,7 +191,7 @@ sub register_command { agent_available($vmid, $conf); my $cmd = $param->{command} // $command; - my $res = PVE::QemuServer::vm_mon_cmd($vmid, "guest-$cmd"); + my $res = vm_mon_cmd($vmid, "guest-$cmd"); return { result => $res }; }}); @@ -415,7 +416,7 @@ __PACKAGE__->register_method({ my $content = ""; while ($bytes_left > 0 && !$eof) { - my $read = PVE::QemuServer::vm_mon_cmd($vmid, "guest-file-read", handle => $qgafh, count => int($read_size)); + my $read = vm_mon_cmd($vmid, "guest-file-read", handle => $qgafh, count => int($read_size)); check_agent_error($read, "can't read from file"); $content .= decode_base64($read->{'buf-b64'}); @@ -423,7 +424,7 @@ __PACKAGE__->register_method({ $eof = $read->{eof} // 0; } - my $res = PVE::QemuServer::vm_mon_cmd($vmid, "guest-file-close", handle => $qgafh); + my $res = vm_mon_cmd($vmid, "guest-file-close", handle => $qgafh); check_agent_error($res, "can't close file", 1); my $result = { diff --git a/PVE/CLI/qm.pm b/PVE/CLI/qm.pm index 4de0ae2..485334a 100755 --- a/PVE/CLI/qm.pm +++ b/PVE/CLI/qm.pm @@ -27,6 +27,7 @@ use PVE::QemuServer; use PVE::QemuServer::ImportDisk; use PVE::QemuServer::OVF; use PVE::QemuServer::Agent qw(agent_available); +use PVE::QMP qw(vm_mon_cmd); use PVE::API2::Qemu; use PVE::API2::Qemu::Agent; use JSON; @@ -214,12 +215,12 @@ __PACKAGE__->register_method ({ my $vnc_socket = PVE::QemuSchema::vnc_socket($vmid); if (my $ticket = $ENV{LC_PVE_TICKET}) { # NOTE: ssh on debian only pass LC_* variables - PVE::QemuServer::vm_mon_cmd($vmid, "change", device => 'vnc', target => "unix:$vnc_socket,password"); - PVE::QemuServer::vm_mon_cmd($vmid, "set_password", protocol => 'vnc', password => $ticket); - PVE::QemuServer::vm_mon_cmd($vmid, "expire_password", protocol => 'vnc', time => "+30"); + vm_mon_cmd($vmid, "change", device => 'vnc', target => "unix:$vnc_socket,password"); + vm_mon_cmd($vmid, "set_password", protocol => 'vnc', password => $ticket); + vm_mon_cmd($vmid, "expire_password", protocol => 'vnc', time => "+30"); } else { # FIXME: remove or allow to add tls-creds object, as x509 vnc param is removed with qemu 4?? - PVE::QemuServer::vm_mon_cmd($vmid, "change", device => 'vnc', target => "unix:$vnc_socket,password"); + vm_mon_cmd($vmid, "change", device => 'vnc', target => "unix:$vnc_socket,password"); } run_vnc_proxy($vnc_socket); @@ -399,7 +400,7 @@ __PACKAGE__->register_method ({ last if $input =~ m/^\s*q(uit)?\s*$/; eval { - print PVE::QemuServer::vm_human_monitor_command ($vmid, $input); + print PVE::QMP::vm_human_monitor_command ($vmid, $input); }; print "ERROR: $@" if $@; } diff --git a/PVE/Makefile b/PVE/Makefile index 5ec715e..2ed4580 100644 --- a/PVE/Makefile +++ b/PVE/Makefile @@ -4,6 +4,7 @@ PERLSOURCE = \ QMPClient.pm \ QemuConfig.pm \ QemuSchema.pm \ + QMP.pm \ .PHONY: install install: diff --git a/PVE/QMP.pm b/PVE/QMP.pm new file mode 100644 index 0000000..30bff20 --- /dev/null +++ b/PVE/QMP.pm @@ -0,0 +1,71 @@ +package PVE::QMP; + +use strict; +use warnings; + +use PVE::QemuConfig; +use PVE::QemuSchema; +use PVE::QMPClient; + +use base 'Exporter'; +our @EXPORT_OK = qw( +vm_qmp_command +vm_mon_cmd +vm_mon_cmd_nocheck +); + +sub vm_qmp_command { + my ($vmid, $cmd, $nocheck) = @_; + + my $res; + + my $timeout; + if ($cmd->{arguments}) { + $timeout = delete $cmd->{arguments}->{timeout}; + } + + eval { + die "VM $vmid not running\n" if !PVE::QemuConfig::check_running($vmid, $nocheck); + my $sname = PVE::QemuSchema::qmp_socket($vmid); + if (-e $sname) { # test if VM is reasonably new and supports qmp/qga + my $qmpclient = PVE::QMPClient->new(); + + $res = $qmpclient->cmd($vmid, $cmd, $timeout); + } else { + die "unable to open monitor socket\n"; + } + }; + if (my $err = $@) { + syslog("err", "VM $vmid qmp command failed - $err"); + die $err; + } + + return $res; +} + +sub vm_mon_cmd { + my ($vmid, $execute, %params) = @_; + + my $cmd = { execute => $execute, arguments => \%params }; + vm_qmp_command($vmid, $cmd); +} + +sub vm_mon_cmd_nocheck { + my ($vmid, $execute, %params) = @_; + + my $cmd = { execute => $execute, arguments => \%params }; + vm_qmp_command($vmid, $cmd, 1); +} + +sub vm_human_monitor_command { + my ($vmid, $cmdline) = @_; + + my $cmd = { + execute => 'human-monitor-command', + arguments => { 'command-line' => $cmdline}, + }; + + return vm_qmp_command($vmid, $cmd); +} + +1; diff --git a/PVE/QemuConfig.pm b/PVE/QemuConfig.pm index 77080a0..bcad9c8 100644 --- a/PVE/QemuConfig.pm +++ b/PVE/QemuConfig.pm @@ -10,6 +10,7 @@ use PVE::INotify; use PVE::ProcFSTools; use PVE::QemuSchema; use PVE::QemuServer; +use PVE::QMP qw(vm_mon_cmd vm_mon_cmd_nocheck); use PVE::Storage; use PVE::Tools; @@ -182,10 +183,10 @@ sub __snapshot_freeze { my ($class, $vmid, $unfreeze) = @_; if ($unfreeze) { - eval { PVE::QemuServer::vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); }; + eval { vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); }; warn "guest-fsfreeze-thaw problems - $@" if $@; } else { - eval { PVE::QemuServer::vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); }; + eval { vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); }; warn "guest-fsfreeze-freeze problems - $@" if $@; } } @@ -201,9 +202,9 @@ sub __snapshot_create_vol_snapshots_hook { my $path = PVE::Storage::path($storecfg, $snap->{vmstate}); PVE::Storage::activate_volumes($storecfg, [$snap->{vmstate}]); - PVE::QemuServer::vm_mon_cmd($vmid, "savevm-start", statefile => $path); + PVE::QMP::vm_mon_cmd($vmid, "savevm-start", statefile => $path); for(;;) { - my $stat = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-savevm"); + my $stat = PVE::QMP::vm_mon_cmd_nocheck($vmid, "query-savevm"); if (!$stat->{status}) { die "savevm not active\n"; } elsif ($stat->{status} eq 'active') { @@ -216,18 +217,18 @@ sub __snapshot_create_vol_snapshots_hook { } } } else { - PVE::QemuServer::vm_mon_cmd($vmid, "savevm-start"); + PVE::QMP::vm_mon_cmd($vmid, "savevm-start"); } } elsif ($hook eq "after") { eval { - PVE::QemuServer::vm_mon_cmd($vmid, "savevm-end"); + PVE::QMP::vm_mon_cmd($vmid, "savevm-end"); PVE::Storage::deactivate_volumes($storecfg, [$snap->{vmstate}]) if $snap->{vmstate}; }; warn $@ if $@; } elsif ($hook eq "after-freeze") { # savevm-end is async, we need to wait for (;;) { - my $stat = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-savevm"); + my $stat = PVE::QMP::vm_mon_cmd_nocheck($vmid, "query-savevm"); if (!$stat->{bytes}) { last; } else { diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm index e6993d4..aea7eac 100644 --- a/PVE/QemuMigrate.pm +++ b/PVE/QemuMigrate.pm @@ -12,6 +12,7 @@ use PVE::Cluster; use PVE::Storage; use PVE::QemuConfig; use PVE::QemuServer; +use PVE::QMP qw(vm_mon_cmd vm_mon_cmd_nocheck); use Time::HiRes qw( usleep ); use PVE::RPCEnvironment; use PVE::ReplicationConfig; @@ -552,7 +553,7 @@ sub phase2 { my $spice_ticket; if (PVE::QemuServer::vga_conf_has_spice($conf->{vga})) { - my $res = PVE::QemuServer::vm_mon_cmd($vmid, 'query-spice'); + my $res = vm_mon_cmd($vmid, 'query-spice'); $spice_ticket = $res->{ticket}; } @@ -707,7 +708,7 @@ sub phase2 { $migrate_speed *= 1024; $self->log('info', "migrate_set_speed: $migrate_speed"); eval { - PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate_set_speed", value => int($migrate_speed)); + vm_mon_cmd_nocheck($vmid, "migrate_set_speed", value => int($migrate_speed)); }; $self->log('info', "migrate_set_speed error: $@") if $@; @@ -716,7 +717,7 @@ sub phase2 { if (defined($migrate_downtime)) { $self->log('info', "migrate_set_downtime: $migrate_downtime"); eval { - PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate_set_downtime", value => int($migrate_downtime*100)/100); + vm_mon_cmd_nocheck($vmid, "migrate_set_downtime", value => int($migrate_downtime*100)/100); }; $self->log('info', "migrate_set_downtime error: $@") if $@; } @@ -734,7 +735,7 @@ sub phase2 { $self->log('info', "set cachesize: $cachesize"); eval { - PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate-set-cache-size", value => int($cachesize)); + vm_mon_cmd_nocheck($vmid, "migrate-set-cache-size", value => int($cachesize)); }; $self->log('info', "migrate-set-cache-size error: $@") if $@; @@ -750,7 +751,7 @@ sub phase2 { $self->log('info', "spice client_migrate_info"); eval { - PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "client_migrate_info", protocol => 'spice', + vm_mon_cmd_nocheck($vmid, "client_migrate_info", protocol => 'spice', hostname => $proxyticket, 'port' => 0, 'tls-port' => $spice_port, 'cert-subject' => $subject); }; @@ -760,7 +761,7 @@ sub phase2 { $self->log('info', "start migrate command to $ruri"); eval { - PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate", uri => $ruri); + vm_mon_cmd_nocheck($vmid, "migrate", uri => $ruri); }; my $merr = $@; $self->log('info', "migrate uri => $ruri failed: $merr") if $merr; @@ -778,7 +779,7 @@ sub phase2 { usleep($usleep); my $stat; eval { - $stat = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-migrate"); + $stat = vm_mon_cmd_nocheck($vmid, "query-migrate"); }; if (my $err = $@) { $err_count++; @@ -847,7 +848,7 @@ sub phase2 { $migrate_downtime *= 2; $self->log('info', "migrate_set_downtime: $migrate_downtime"); eval { - PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate_set_downtime", value => int($migrate_downtime*100)/100); + vm_mon_cmd_nocheck($vmid, "migrate_set_downtime", value => int($migrate_downtime*100)/100); }; $self->log('info', "migrate_set_downtime error: $@") if $@; } @@ -874,7 +875,7 @@ sub phase2_cleanup { $self->log('info', "migrate_cancel"); eval { - PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate_cancel"); + vm_mon_cmd_nocheck($vmid, "migrate_cancel"); }; $self->log('info', "migrate_cancel error: $@") if $@; @@ -1025,7 +1026,7 @@ sub phase3_cleanup { if (PVE::QemuServer::vga_conf_has_spice($conf->{vga}) && $self->{running}) { $self->log('info', "Waiting for spice server migration"); while (1) { - my $res = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, 'query-spice'); + my $res = vm_mon_cmd_nocheck($vmid, 'query-spice'); last if int($res->{'migrated'}) == 1; last if $timer > 50; $timer ++; diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index d5eba39..bf696a7 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -38,6 +38,7 @@ use PVE::SysFSTools; use PVE::Systemd; use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach get_host_arch $IPV6RE); +use PVE::QMP qw(vm_qmp_command vm_mon_cmd vm_mon_cmd_nocheck); use PVE::QMPClient; use PVE::QemuConfig; use PVE::QemuSchema; @@ -4333,7 +4334,7 @@ sub qemu_driveadd { my $drive = print_drive_full($storecfg, $vmid, $device); $drive =~ s/\\/\\\\/g; - my $ret = vm_human_monitor_command($vmid, "drive_add auto \"$drive\""); + my $ret = PVE::QMP::vm_human_monitor_command($vmid, "drive_add auto \"$drive\""); # If the command succeeds qemu prints: "OK" return 1 if $ret =~ m/OK/s; @@ -4344,7 +4345,7 @@ sub qemu_driveadd { sub qemu_drivedel { my($vmid, $deviceid) = @_; - my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid"); + my $ret = PVE::QMP::vm_human_monitor_command($vmid, "drive_del drive-$deviceid"); $ret =~ s/^\s+//; return 1 if $ret eq ""; @@ -5471,60 +5472,6 @@ sub vm_start { }); } -sub vm_mon_cmd { - my ($vmid, $execute, %params) = @_; - - my $cmd = { execute => $execute, arguments => \%params }; - vm_qmp_command($vmid, $cmd); -} - -sub vm_mon_cmd_nocheck { - my ($vmid, $execute, %params) = @_; - - my $cmd = { execute => $execute, arguments => \%params }; - vm_qmp_command($vmid, $cmd, 1); -} - -sub vm_qmp_command { - my ($vmid, $cmd, $nocheck) = @_; - - my $res; - - my $timeout; - if ($cmd->{arguments}) { - $timeout = delete $cmd->{arguments}->{timeout}; - } - - eval { - die "VM $vmid not running\n" if !PVE::QemuConfig::check_running($vmid, $nocheck); - my $sname = PVE::QemuSchema::qmp_socket($vmid); - if (-e $sname) { # test if VM is reasonambe new and supports qmp/qga - my $qmpclient = PVE::QMPClient->new(); - - $res = $qmpclient->cmd($vmid, $cmd, $timeout); - } else { - die "unable to open monitor socket\n"; - } - }; - if (my $err = $@) { - syslog("err", "VM $vmid qmp command failed - $err"); - die $err; - } - - return $res; -} - -sub vm_human_monitor_command { - my ($vmid, $cmdline) = @_; - - my $cmd = { - execute => 'human-monitor-command', - arguments => { 'command-line' => $cmdline}, - }; - - return vm_qmp_command($vmid, $cmd); -} - sub vm_commandline { my ($storecfg, $vmid, $snapname) = @_; @@ -5848,7 +5795,7 @@ sub vm_sendkey { my $conf = PVE::QemuConfig->load_config($vmid); # there is no qmp command, so we use the human monitor command - my $res = vm_human_monitor_command($vmid, "sendkey $key"); + my $res = PVE::QMP::vm_human_monitor_command($vmid, "sendkey $key"); die $res if $res ne ''; }); } @@ -6911,7 +6858,7 @@ sub qemu_drive_mirror_monitor { my $agent_running = $qga && qga_check_running($vmid); if ($agent_running) { print "freeze filesystem\n"; - eval { PVE::QemuServer::vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); }; + eval { vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); }; } else { print "suspend vm\n"; eval { PVE::QemuServer::vm_suspend($vmid, 1); }; @@ -6922,7 +6869,7 @@ sub qemu_drive_mirror_monitor { if ($agent_running) { print "unfreeze filesystem\n"; - eval { PVE::QemuServer::vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); }; + eval { vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); }; } else { print "resume vm\n"; eval { PVE::QemuServer::vm_resume($vmid, 1, 1); }; diff --git a/PVE/QemuServer/Agent.pm b/PVE/QemuServer/Agent.pm index 8ffe3bc..aa51316 100644 --- a/PVE/QemuServer/Agent.pm +++ b/PVE/QemuServer/Agent.pm @@ -5,6 +5,7 @@ use warnings; use PVE::QemuConfig; use PVE::QemuServer; +use PVE::QMP; use MIME::Base64 qw(decode_base64); use JSON; use base 'Exporter'; @@ -60,7 +61,7 @@ sub agent_cmd { my $conf = PVE::QemuConfig->load_config($vmid); # also checks if VM exists agent_available($vmid, $conf, $noerr); - my $res = PVE::QemuServer::vm_mon_cmd($vmid, "guest-$cmd", %$params); + my $res = PVE::QMP::vm_mon_cmd($vmid, "guest-$cmd", %$params); check_agent_error($res, $errormsg, $noerr); return $res; diff --git a/PVE/QemuServer/Memory.pm b/PVE/QemuServer/Memory.pm index 3f4088b..b4c9129 100644 --- a/PVE/QemuServer/Memory.pm +++ b/PVE/QemuServer/Memory.pm @@ -4,6 +4,7 @@ use strict; use warnings; use PVE::QemuConfig; use PVE::QemuServer; +use PVE::QMP qw(vm_mon_cmd vm_mon_cmd_nocheck); use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach); use PVE::Exception qw(raise raise_param_exc); @@ -140,7 +141,7 @@ sub qemu_memory_hotplug { my $hugepages_host_topology = hugepages_host_topology(); hugepages_allocate($hugepages_topology, $hugepages_host_topology); - eval { PVE::QemuServer::vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-file", id => "mem-$name", props => { + eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-file", id => "mem-$name", props => { size => int($dimm_size*1024*1024), 'mem-path' => $path, share => JSON::true, prealloc => JSON::true } ); }; if (my $err = $@) { hugepages_reset($hugepages_host_topology); @@ -152,7 +153,7 @@ sub qemu_memory_hotplug { eval { hugepages_update_locked($code); }; } else { - eval { PVE::QemuServer::vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) }; + eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) }; } if (my $err = $@) { @@ -160,7 +161,7 @@ sub qemu_memory_hotplug { die $err; } - eval { PVE::QemuServer::vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) }; + eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) }; if (my $err = $@) { eval { PVE::QemuServer::qemu_objectdel($vmid, "mem-$name"); }; die $err; @@ -200,7 +201,7 @@ sub qemu_memory_hotplug { sub qemu_dimm_list { my ($vmid) = @_; - my $dimmarray = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-memory-devices"); + my $dimmarray = vm_mon_cmd_nocheck($vmid, "query-memory-devices"); my $dimms = {}; foreach my $dimm (@$dimmarray) { diff --git a/PVE/VZDump/QemuServer.pm b/PVE/VZDump/QemuServer.pm index 91768de..dc6b29a 100644 --- a/PVE/VZDump/QemuServer.pm +++ b/PVE/VZDump/QemuServer.pm @@ -19,6 +19,7 @@ use PVE::VZDump; use PVE::QemuConfig; use PVE::QemuServer; +use PVE::QMP qw(vm_mon_cmd); use base qw (PVE::VZDump::Plugin); @@ -418,7 +419,7 @@ sub archive { } if ($agent_running){ - eval { PVE::QemuServer::vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); }; + eval { vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); }; if (my $err = $@) { $self->logerr($err); } @@ -428,7 +429,7 @@ sub archive { my $qmperr = $@; if ($agent_running){ - eval { PVE::QemuServer::vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); }; + eval { vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); }; if (my $err = $@) { $self->logerr($err); } @@ -453,7 +454,7 @@ sub archive { } else { $self->loginfo("resuming VM again"); } - PVE::QemuServer::vm_mon_cmd($vmid, 'cont'); + vm_mon_cmd($vmid, 'cont'); } my $status; @@ -466,7 +467,7 @@ sub archive { my $transferred; while(1) { - $status = PVE::QemuServer::vm_mon_cmd($vmid, 'query-backup'); + $status = vm_mon_cmd($vmid, 'query-backup'); my $total = $status->{total} || 0; $transferred = $status->{transferred} || 0; my $per = $total ? int(($transferred * 100)/$total) : 0; @@ -525,7 +526,7 @@ sub archive { if ($err) { $self->logerr($err); $self->loginfo("aborting backup job"); - eval { PVE::QemuServer::vm_mon_cmd($vmid, 'backup-cancel'); }; + eval { vm_mon_cmd($vmid, 'backup-cancel'); }; if (my $err1 = $@) { $self->logerr($err1); } @@ -534,7 +535,7 @@ sub archive { if ($stop_after_backup) { # stop if not running eval { - my $resp = PVE::QemuServer::vm_mon_cmd($vmid, 'query-status'); + my $resp = vm_mon_cmd($vmid, 'query-status'); my $status = $resp && $resp->{status} ? $resp->{status} : 'unknown'; if ($status eq 'prelaunch') { $self->loginfo("stopping kvm after backup task"); diff --git a/test/snapshot-test.pm b/test/snapshot-test.pm index 53d08e6..0ed0609 100644 --- a/test/snapshot-test.pm +++ b/test/snapshot-test.pm @@ -9,6 +9,7 @@ use PVE::Storage; use PVE::Storage::Plugin; use PVE::QemuServer; use PVE::QemuConfig; +use PVE::QMP; use PVE::Tools; use PVE::ReplicationConfig; @@ -304,11 +305,7 @@ sub check_running { # END mocked PVE::QemuConfig methods -# BEGIN redefine PVE::QemuServer methods - -sub do_snapshots_with_qemu { - return 0; -} +# BEGIN mocked PVE::QMP methods sub vm_qmp_command { my ($vmid, $cmd, $nocheck) = @_; @@ -343,6 +340,14 @@ sub vm_qmp_command { die "unexpected vm_qmp_command!\n"; } +# END mocked PVE::QMP methods + +# BEGIN redefine PVE::QemuServer methods + +sub do_snapshots_with_qemu { + return 0; +} + sub vm_start { my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine) = @_; @@ -369,6 +374,9 @@ sub vm_stop { PVE::Tools::run_command("rm -rf snapshot-working"); PVE::Tools::run_command("cp -a snapshot-input snapshot-working"); +my $qmp_module = new Test::MockModule('PVE::QMP'); +$qmp_module->mock('vm_qmp_command', \&vm_qmp_command); + my $qemu_config_module = new Test::MockModule('PVE::QemuConfig'); $qemu_config_module->mock('config_file_lock', \&config_file_lock); $qemu_config_module->mock('cfs_config_path', \&cfs_config_path); -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel