If a snapshot has the '-off' suffix, try cleanly powering of the VM after running the tests. This may avoid perma-crashing the GPU when using PCI-passthrough. Forcefully power of the VM as usual if it does not cleanly shuts down within $WaitForShutdown seconds.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- testbot/bin/LibvirtTool.pl | 50 +++++++++++++++++++++++++++++-- testbot/lib/WineTestBot/Config.pm | 9 ++++-- 2 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl index a2939e738..59adf2f7f 100755 --- a/testbot/bin/LibvirtTool.pl +++ b/testbot/bin/LibvirtTool.pl @@ -323,9 +323,55 @@ sub Monitor()
sub PowerOff() { - # Power off VMs no matter what their initial status is + my $Domain = $VM->GetDomain(); + if ($VM->IdleSnapshot =~ /-off$/ and $Domain->IsPoweredOn()) + { + # Attempt to perform a clean shutdown. + # Use SetTime() to detect if privileged operations are allowed. + my $TA = $VM->GetAgent(); + if (!$TA->SetTime()) + { + # Not a fatal error. Try the next port in case the VM runs a privileged + # TestAgentd daemon there. + $TA->Disconnect(); + $TA = $VM->GetAgent(1); + if (!$TA->SetTime()) + { + Error "Unable to get a privileged TestAgent: ". $TA->GetLastError() ."\n"; + $TA->Disconnect(); + $TA = undef; + } + } + if ($TA) + { + my $Cmd = $VM->Type =~ /^win(?:32|64)$/ ? + ["shutdown.exe", "/p", "/d", "00:00"] : + ["/sbin/shutdown", "--poweroff", "now"]; + Debug(Elapsed($Start), " Running @$Cmd\n"); + if (!$TA->Run($Cmd, 0)) + { + Error "Could not run @$Cmd: ". $TA->GetLastError() ."\n"; + } + else + { + Debug(Elapsed($Start), " Waiting for the VM to power off\n"); + my $Deadline = time() + $WaitForShutdown; + while ($Domain->IsPoweredOn()) + { + if (time() >= $Deadline) + { + Error "Timed out waiting for ". $VM->Name ." to perform a clean shutdown. Forcefully shutting down now...\n"; + last; + } + sleep(1); + } + } + } + } + + # Power off the VM no matter what its initial status is $CurrentStatus = $VM->Status; - my $ErrMessage = $VM->GetDomain()->PowerOff(); + my $ErrMessage = $Domain->PowerOff(); FatalError("$ErrMessage\n") if (defined $ErrMessage);
return ChangeStatus(undef, "off", "done"); diff --git a/testbot/lib/WineTestBot/Config.pm b/testbot/lib/WineTestBot/Config.pm index 312797229..a4aba2c55 100644 --- a/testbot/lib/WineTestBot/Config.pm +++ b/testbot/lib/WineTestBot/Config.pm @@ -29,7 +29,8 @@ use vars qw (@ISA @EXPORT @EXPORT_OK $UseSSL $LogDir $DataDir $BinDir %RepoURLs $DbDataSource $DbUsername $DbPassword $MaxRevertingVMs $MaxRevertsWhileRunningVMs $MaxActiveVMs $MaxRunningVMs $MaxVMsWhenIdle $WaitForBoot $SleepAfterBoot $SleepAfterRevert - $VMToolTimeout $MaxVMErrors $MaxTaskTries $AdminEMail $RobotEMail + $VMToolTimeout $WaitForShutdown $MaxVMErrors $MaxTaskTries + $AdminEMail $RobotEMail $WinePatchToOverride $WinePatchCc $ReconfigBuildTimeout $ExeBuildTimeout $ExeModuleTimeout $WineBuildTimeout $WineModuleTimeout $TimeoutMargin @@ -45,8 +46,8 @@ require Exporter; @EXPORT = qw($UseSSL $LogDir $DataDir $BinDir %RepoURLs $MaxRevertingVMs $MaxRevertsWhileRunningVMs $MaxActiveVMs $MaxRunningVMs $MaxVMsWhenIdle $WaitForBoot $SleepAfterBoot - $SleepAfterRevert - $VMToolTimeout $MaxVMErrors $MaxTaskTries $AdminEMail + $SleepAfterRevert $VMToolTimeout $WaitForShutdown + $MaxVMErrors $MaxTaskTries $AdminEMail $RobotEMail $WinePatchToOverride $WinePatchCc $SuiteTimeout $ReconfigBuildTimeout $ExeBuildTimeout $ExeModuleTimeout $WineBuildTimeout $WineModuleTimeout $TimeoutMargin @@ -101,6 +102,8 @@ $SleepAfterRevert = 0; # How long to wait before considering a VM operation is stuck. In particular # for reverts this should take into account the time it may need to boot. $VMToolTimeout = 6 * 60; +# How long to wait for the VM to perform a clean shutdown. +$WaitForShutdown = 30;
# Notify the administrator that a VM probably needs manual fixing after # $MaxVMErrors consecutive revert errors.