]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
process: wait longer on kill per assigned Hostdev
authorChristian Ehrhardt <christian.ehrhardt@canonical.com>
Thu, 2 Aug 2018 07:05:18 +0000 (09:05 +0200)
committerChristian Ehrhardt <christian.ehrhardt@canonical.com>
Tue, 21 Aug 2018 15:37:10 +0000 (17:37 +0200)
It was found that in cases with host devices virProcessKillPainfully
might be able to send signal zero to the target PID for quite a while
with the process already being gone from /proc/<PID>.

That is due to cleanup and reset of devices which might include a
secondary bus reset that on top of the actions taken has a 1s delay
to let the bus settle. Due to that guests with plenty of Host devices
could easily exceed the default timeouts.

To solve that, this adds an extra delay of 2s per hostdev that is associated
to a VM.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
src/libvirt_private.syms
src/qemu/qemu_process.c
src/util/virprocess.c
src/util/virprocess.h

index ca4a192a4a22266064977ab15a28714a5b0ab876..47ea35f864cb0af1c6aa65a005c8cb0d0e6d08ba 100644 (file)
@@ -2605,6 +2605,7 @@ virProcessGetPids;
 virProcessGetStartTime;
 virProcessKill;
 virProcessKillPainfully;
+virProcessKillPainfullyDelay;
 virProcessNamespaceAvailable;
 virProcessRunInMountNamespace;
 virProcessSchedPolicyTypeFromString;
index b899eed14316c88e0a8af9fb182a1f5b2a415464..ab749389eebdcc65974aaed6c9342c0a2525a338 100644 (file)
@@ -6908,8 +6908,11 @@ qemuProcessKill(virDomainObjPtr vm, unsigned int flags)
         return 0;
     }
 
-    ret = virProcessKillPainfully(vm->pid,
-                                  !!(flags & VIR_QEMU_PROCESS_KILL_FORCE));
+    /* Request an extra delay of two seconds per current nhostdevs
+     * to be safe against stalls by the kernel freeing up the resources */
+    ret = virProcessKillPainfullyDelay(vm->pid,
+                                       !!(flags & VIR_QEMU_PROCESS_KILL_FORCE),
+                                       vm->def->nhostdevs * 2);
 
     return ret;
 }
index ecea27a2d4f0b2ce75de68f596e4be588a65f401..4c7f2ed97ca423cdbba8a731a6b61cb9fa0bba21 100644 (file)
@@ -341,15 +341,21 @@ int virProcessKill(pid_t pid, int sig)
  * Returns 0 if it was killed gracefully, 1 if it
  * was killed forcibly, -1 if it is still alive,
  * or another error occurred.
+ *
+ * Callers can proide an extra delay in seconds to
+ * wait longer than the default.
  */
 int
-virProcessKillPainfully(pid_t pid, bool force)
+virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay)
 {
     size_t i;
     int ret = -1;
+    /* This is in 1/5th seconds since polling is on a 0.2s interval */
+    unsigned int polldelay = 75 + (extradelay*5);
     const char *signame = "TERM";
 
-    VIR_DEBUG("vpid=%lld force=%d", (long long)pid, force);
+    VIR_DEBUG("vpid=%lld force=%d extradelay=%u",
+              (long long)pid, force, extradelay);
 
     /* This loop sends SIGTERM, then waits a few iterations (10 seconds)
      * to see if it dies. If the process still hasn't exited, and
@@ -357,9 +363,12 @@ virProcessKillPainfully(pid_t pid, bool force)
      * wait up to 5 seconds more for the process to exit before
      * returning.
      *
+     * An extra delay can be passed by the caller for cases that are
+     * expected to clean up slower than usual.
+     *
      * Note that setting @force could result in dataloss for the process.
      */
-    for (i = 0; i < 75; i++) {
+    for (i = 0; i < polldelay; i++) {
         int signum;
         if (i == 0) {
             signum = SIGTERM; /* kindly suggest it should exit */
@@ -402,6 +411,11 @@ virProcessKillPainfully(pid_t pid, bool force)
 }
 
 
+int virProcessKillPainfully(pid_t pid, bool force)
+{
+    return virProcessKillPainfullyDelay(pid, force, 0);
+}
+
 #if HAVE_SCHED_GETAFFINITY
 
 int virProcessSetAffinity(pid_t pid, virBitmapPtr map)
index 3c5a8827728863e3837f31cf60de550e7558af11..5faa0892fef91d65225e447cfea2a34e581c18fe 100644 (file)
@@ -55,6 +55,9 @@ virProcessWait(pid_t pid, int *exitstatus, bool raw)
 int virProcessKill(pid_t pid, int sig);
 
 int virProcessKillPainfully(pid_t pid, bool force);
+int virProcessKillPainfullyDelay(pid_t pid,
+                                 bool force,
+                                 unsigned int extradelay);
 
 int virProcessSetAffinity(pid_t pid, virBitmapPtr map);