[tools] testbot/LibvirtTool: Always shut down for '-off' snapshots.

Francois Gouget fgouget at codeweavers.com
Tue Mar 16 06:13:25 CDT 2021


Snapshots with a name ending in '-off' request that the VM be cleanly
shut down if possible rather than summarily powered off.
So check the domain's current snapshot and do a clean shutdown before
powering off for every operation, including checkoff, monitor and
revert.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
 testbot/bin/LibvirtTool.pl | 118 ++++++++++++++++++++++---------------
 1 file changed, 72 insertions(+), 46 deletions(-)

diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl
index f135b9b51..c4dbffbaa 100755
--- a/testbot/bin/LibvirtTool.pl
+++ b/testbot/bin/LibvirtTool.pl
@@ -257,6 +257,66 @@ sub ChangeStatus($$;$)
   return 0;
 }
 
+sub ShutDown()
+{
+  my $Domain = $VM->GetDomain();
+  my $CurrentSnapshot = $Domain->GetSnapshotName();
+  if (!defined $CurrentSnapshot or $CurrentSnapshot !~ /-off$/ or
+      !$Domain->IsPoweredOn())
+  {
+    return 1;
+  }
+
+  Debug(Elapsed($Start), " Performing a clean shutdown of $VMKey $CurrentSnapshot\n");
+  LogMsg "Performing a clean shutdown of $VMKey $CurrentSnapshot\n";
+
+  # 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();
+      return 0;
+    }
+  }
+
+  my $Success = 1;
+  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";
+    $Success = 0;
+  }
+  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 $VMKey to perform a clean shutdown. Forcefully shutting down now...\n";
+        $Success = 0;
+        last;
+      }
+      sleep(1);
+    }
+  }
+  $TA->Disconnect();
+  Debug(Elapsed($Start), " Successfully shut down $VMKey\n");
+  LogMsg "Successfully shut down $VMKey\n";
+  return $Success;
+}
+
 sub Monitor()
 {
   # Still try recovering the VM in case of repeated errors, but space out
@@ -301,6 +361,9 @@ sub Monitor()
     my $IsReady = $VM->GetDomain()->IsReady();
     if ($IsReady and $VM->GetDomain()->IsPoweredOn())
     {
+      # Try to perform a clean shutdown if requested
+      ShutDown();
+
       my $ErrMessage = $VM->GetDomain()->PowerOff();
       if (defined $ErrMessage)
       {
@@ -324,55 +387,12 @@ sub Monitor()
 
 sub PowerOff()
 {
-  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);
-        }
-      }
-    }
-  }
+  # Try to perform a clean shutdown if requested
+  ShutDown();
 
   # Power off the VM no matter what its initial status is
   $CurrentStatus = $VM->Status;
-  my $ErrMessage = $Domain->PowerOff();
+  my $ErrMessage = $VM->GetDomain()->PowerOff();
   FatalError("$ErrMessage\n") if (defined $ErrMessage);
 
   return ChangeStatus(undef, "off", "done");
@@ -407,6 +427,9 @@ sub CheckOff()
     FatalError("$ErrMessage\n") if (defined $ErrMessage);
     if ($SnapshotName eq $VM->IdleSnapshot)
     {
+      # Try to perform a clean shutdown if requested
+      ShutDown();
+
       my $ErrMessage = $VM->GetDomain()->PowerOff();
       FatalError("$ErrMessage\n") if (defined $ErrMessage);
     }
@@ -584,6 +607,9 @@ sub Revert()
     $VM->Save();
   }
 
+  # Before reverting, try to perform a clean shutdown if requested
+  ShutDown();
+
   # Revert the VM (and power it on if necessary)
   Debug(Elapsed($Start), " Reverting $VMKey to $DomainSnapshot\n");
   my ($ErrMessage, $Booting) = $Domain->RevertToSnapshot($DomainSnapshot);
-- 
2.20.1



More information about the wine-devel mailing list