Module: tools Branch: master Commit: 74aeb1e5cb401da6c11e351c1c9afb0196ed5f30 URL: http://source.winehq.org/git/tools.git/?a=commit;h=74aeb1e5cb401da6c11e351c1...
Author: Francois Gouget fgouget@codeweavers.com Date: Wed Oct 18 20:14:32 2017 +0200
testbot: Make it possible to power off VMs using LibvirtTool.
Signed-off-by: Francois Gouget fgouget@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
testbot/bin/LibvirtTool.pl | 26 +++++++++++++----- testbot/lib/WineTestBot/Jobs.pm | 3 ++- testbot/lib/WineTestBot/VMs.pm | 60 +++++++++++++++++++++++++++++++++++------ 3 files changed, 74 insertions(+), 15 deletions(-)
diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl index 6aaaf82..64f0575 100755 --- a/testbot/bin/LibvirtTool.pl +++ b/testbot/bin/LibvirtTool.pl @@ -1,9 +1,9 @@ #!/usr/bin/perl -Tw # -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*- # -# Reverts a VM so that it is ready to run jobs. -# This operation can take quite a bit of time, particularly in case of -# network trouble, and thus is best performed in a separate process. +# Performs poweroff and revert operations on the specified VM. +# These operations can take quite a bit of time, particularly in case of +# network trouble, and thus are best performed in a separate process. # # Copyright 2009 Ge van Geldorp # Copyright 2012-2017 Francois Gouget @@ -104,7 +104,7 @@ while (@ARGV) { $LogOnly = 1; } - elsif ($Arg eq "revert") + elsif ($Arg =~ /^(?:poweroff|revert)$/) { $Action = $Arg; } @@ -163,7 +163,7 @@ if (!defined $Usage) } if (defined $Usage) { - print "Usage: $Name0 [--debug] [--log-only] [--help] revert VMName\n"; + print "Usage: $Name0 [--debug] [--log-only] [--help] (poweroff|revert) VMName\n"; exit $Usage; }
@@ -251,6 +251,16 @@ sub ChangeStatus($$;$) return 0; }
+sub PowerOff() +{ + # Power off VMs no matter what their initial status is + $CurrentStatus = $VM->Status; + my $ErrMessage = $VM->GetDomain()->PowerOff(1); + FatalError("$ErrMessage\n") if (defined $ErrMessage); + + return ChangeStatus(undef, "off", "done"); +} + sub Revert() { my $VM = CreateVMs()->GetItem($VMKey); @@ -308,7 +318,11 @@ sub Revert()
my $Rc; -if ($Action eq "revert") +if ($Action eq "poweroff") +{ + $Rc = PowerOff(); +} +elsif ($Action eq "revert") { $Rc = Revert(); } diff --git a/testbot/lib/WineTestBot/Jobs.pm b/testbot/lib/WineTestBot/Jobs.pm index c26ff92..26538fa 100644 --- a/testbot/lib/WineTestBot/Jobs.pm +++ b/testbot/lib/WineTestBot/Jobs.pm @@ -562,7 +562,8 @@ sub ScheduleOnHost($$$) $SleepingCount++; $PrepareNextStep = 1; } - elsif ($VMStatus eq "off" || $VMStatus eq "dirty") + elsif (($VMStatus eq "off" or $VMStatus eq "dirty") and + !$VM->HasRunningChild()) { $RevertNiceness++; $VMsToRevert{$VMKey} = $RevertNiceness; diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm index 86dee6c..a6b2a8b 100644 --- a/testbot/lib/WineTestBot/VMs.pm +++ b/testbot/lib/WineTestBot/VMs.pm @@ -241,7 +241,7 @@ Returns true if the VM status is compatible with ChildPid being set. sub CanHaveChild($) { my ($self) = @_; - return ($self->Status =~ /^(?:reverting|sleeping)$/); + return ($self->Status =~ /^(?:dirty|reverting|sleeping)$/); }
=pod @@ -307,12 +307,12 @@ sub OnSaved($) } }
-sub RunRevert($) +sub _RunVMTool($$$) { - my ($self) = @_; + my ($self, $NewStatus, $Args) = @_;
my $Tool = "LibvirtTool.pl"; - my $Args = ["$BinDir/$Tool", "--log-only", "revert", $self->GetKey()]; + unshift @$Args, "$BinDir/$Tool";
# There are two $VM->ChildPid race conditions to avoid: # - Between the child process and new calls to ScheduleJobs(). @@ -321,8 +321,8 @@ sub RunRevert($) # which would result in a new child being started. # Note that the status is not guaranteed to change in _RunVMTool() so it # cannot be relied on to avoid this race. - # - Between RunRevert() and the exit of the child process. - # The child process may exit before RunRevert() gets around to setting + # - Between _RunVMTool() and the exit of the child process. + # The child process may exit before _RunVMTool() gets around to setting # ChildPid after the fork(). This would result in ChildPid remaining set # indefinitely. # So set ChildPid in the parent and synchronize with the child so it only @@ -347,7 +347,7 @@ sub RunRevert($) close($fd_read);
# Set the Status and ChildPid - $self->Status("reverting"); + $self->Status($NewStatus); $self->ChildPid($Pid); my ($ErrProperty, $ErrMessage) = $self->Save(); if ($ErrMessage) @@ -396,6 +396,51 @@ sub RunRevert($) exit 1; }
+=pod +=over 12 + +=item C<RunPowerOff()> + +Powers off the VM so that it stops using resources. + +The power off need not perform a clean shut down of the guest OS. +This operation can take a long time so it is performed in a separate process. + +=back +=cut + +sub RunPowerOff($) +{ + my ($self) = @_; + # This can be used to power off VMs from any state, including 'idle' but we + # don't want the job scheduler to think it can use the VM while it is being + # powered off. So force the status to dirty. + return $self->_RunVMTool("dirty", ["--log-only", "poweroff", $self->GetKey()]); +} + +=pod +=over 12 + +=item C<RunRevert()> + +Reverts the VM so that it is ready to run jobs. + +Note that in addition to the hypervisor revert operation this implies checking +that it responds to our commands ($WaitForToolsInVM) and possibly letting the +VM settle down ($SleepAfterRevert). If this operation fails the administrator +is notified and the VM is marked as offline. + +This operation can take a long time so it is performed in a separate process. + +=back +=cut + +sub RunRevert($) +{ + my ($self) = @_; + return $self->_RunVMTool("reverting", ["--log-only", "revert", $self->GetKey()]); +} +
package WineTestBot::VMs;
@@ -430,7 +475,6 @@ BEGIN CreateEnumPropertyDescriptor("Type", "Type of VM", !1, 1, ['win32', 'win64', 'build']), CreateEnumPropertyDescriptor("Role", "VM Role", !1, 1, ['extra', 'base', 'winetest', 'retired', 'deleted']), CreateEnumPropertyDescriptor("Status", "Current status", !1, 1, ['dirty', 'reverting', 'sleeping', 'idle', 'running', 'off', 'offline', 'maintenance']), - # Note: ChildPid is only valid when Status == 'reverting' or 'sleeping'. CreateBasicPropertyDescriptor("ChildPid", "Child process id", !1, !1, "N", 5), CreateBasicPropertyDescriptor("VirtURI", "LibVirt URI of the VM", !1, 1, "A", 64), CreateBasicPropertyDescriptor("VirtDomain", "LibVirt Domain for the VM", !1, 1, "A", 32),