Re: [PATCH 2/2] libxl: handle external domain destroy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 12/7/18 7:46 PM, Marek Marczykowski-Górecki wrote:
If domain is killed with `xl destroy`, libvirt will not notice it and
still report the domain as running. Also trying to destroy the domain
through libvirt will fail. The only way to recover from such a situation
is to restart libvirt daemon. The problem is that even though libxl
report LIBXL_EVENT_TYPE_DOMAIN_DEATH, libvirt ignore it as all the
domain cleanup is done in a function actually destroying the domain. If
destroy is done outside of libvirt, there is no place where it would be
handled.

Fix this by doing domain cleanup in LIBXL_EVENT_TYPE_DOMAIN_DEATH too.
To avoid doing it twice, add a ignoreDeathEvent flag
libxlDomainObjPrivate, set when the domain death is triggered by libvirt
itself.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
  src/libxl/libxl_domain.c | 71 ++++++++++++++++++++++++++++++++++++++--
  src/libxl/libxl_domain.h |  3 ++
  2 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 5fe3f44fbe..6d1e15b14c 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -609,6 +609,54 @@ libxlDomainShutdownThread(void *opaque)
      virObjectUnref(cfg);
  }
+static void
+libxlDomainDeathThread(void *opaque)
+{
+    struct libxlShutdownThreadInfo *shutdown_info = opaque;
+    virDomainObjPtr vm = NULL;
+    libxl_event *ev = shutdown_info->event;
+    libxlDriverPrivatePtr driver = shutdown_info->driver;
+    virObjectEventPtr dom_event = NULL;
+    libxlDriverConfigPtr cfg;
+    libxlDomainObjPrivatePtr priv;
+
+    cfg = libxlDriverConfigGet(driver);
+
+    vm = virDomainObjListFindByID(driver->domains, ev->domid);
+    if (!vm) {
+        /* vm->def->id already cleared, means the death was handled by the
+         * driver already */
+        goto cleanup;
+    }
+
+    priv = vm->privateData;
+
+    if (priv->ignoreDeathEvent) {
+        priv->ignoreDeathEvent = false;
+        goto cleanup;
+    }
+
+    if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
+    virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED);
+    dom_event = virDomainEventLifecycleNewFromObj(vm,
+                                                  VIR_DOMAIN_EVENT_STOPPED,
+                                                  VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
+    libxlDomainCleanup(driver, vm);
+    if (!vm->persistent)
+        virDomainObjListRemove(driver->domains, vm);
+    libxlDomainObjEndJob(driver, vm);
+
+ cleanup:
+    virDomainObjEndAPI(&vm);
+    virObjectEventStateQueue(driver->domainEventState, dom_event);
+    libxl_event_free(cfg->ctx, ev);
+    VIR_FREE(shutdown_info);
+    virObjectUnref(cfg);
+}

Thanks for adding death handling in a new function. libxlDomainShutdownThread() is getting a bit unwieldy.

+
+
  /*
   * Handle previously registered domain event notification from libxenlight.
   */
@@ -619,8 +667,10 @@ libxlDomainEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event)
      struct libxlShutdownThreadInfo *shutdown_info = NULL;
      virThread thread;
      libxlDriverConfigPtr cfg;
+    int ret = -1;
- if (event->type != LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
+    if (event->type != LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN &&
+            event->type != LIBXL_EVENT_TYPE_DOMAIN_DEATH) {
          VIR_INFO("Unhandled event type %d", event->type);
          goto error;
      }
@@ -634,8 +684,14 @@ libxlDomainEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event)
shutdown_info->driver = driver;
      shutdown_info->event = (libxl_event *)event;
-    if (virThreadCreate(&thread, false, libxlDomainShutdownThread,
-                        shutdown_info) < 0) {
+    if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN)
+        ret = virThreadCreate(&thread, false, libxlDomainShutdownThread,
+                              shutdown_info);
+    else if (event->type == LIBXL_EVENT_TYPE_DOMAIN_DEATH)
+        ret = virThreadCreate(&thread, false, libxlDomainDeathThread,
+                              shutdown_info);
+
+    if (ret < 0) {
          /*
           * Not much we can do on error here except log it.
           */
@@ -751,14 +807,21 @@ libxlDomainDestroyInternal(libxlDriverPrivatePtr driver,
                             virDomainObjPtr vm)
  {
      libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
+    libxlDomainObjPrivatePtr priv = vm->privateData;
      int ret = -1;
+ /* Ignore next LIBXL_EVENT_TYPE_DOMAIN_DEATH as the caller will handle
+     * domain death appropriately already (having more info, like the reason).
+     */
+    priv->ignoreDeathEvent = true;
      /* Unlock virDomainObj during destroy, which can take considerable
       * time on large memory domains.
       */
      virObjectUnlock(vm);
      ret = libxl_domain_destroy(cfg->ctx, vm->def->id, NULL);
      virObjectLock(vm);
+    if (ret)
+        priv->ignoreDeathEvent = false;
virObjectUnref(cfg);
      return ret;
@@ -811,6 +874,8 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver,
          priv->deathW = NULL;
      }
+ priv->ignoreDeathEvent = false;
+
      if (virAtomicIntDecAndTest(&driver->nactive) && driver->inhibitCallback)
          driver->inhibitCallback(false, driver->inhibitOpaque);
diff --git a/src/libxl/libxl_domain.h b/src/libxl/libxl_domain.h
index e193881450..993fd18f30 100644
--- a/src/libxl/libxl_domain.h
+++ b/src/libxl/libxl_domain.h
@@ -65,6 +65,9 @@ struct _libxlDomainObjPrivate {
      /* console */
      virChrdevsPtr devs;
      libxl_evgen_domain_death *deathW;
+    /* the upcoming LIBXL_EVENT_TYPE_DOMAIN_DEATH is caused by libvirt and
+     * should not be handled separately */

I tweaked this comment a tiny bit by prefixing the sentence with "Flag to indicate ".

+    bool ignoreDeathEvent;
      virThreadPtr migrationDstReceiveThr;
      unsigned short migrationPort;
      char *lockState;


Reviewed-by: Jim Fehlig <jfehlig@xxxxxxxx>

I've pushed both patches. Thanks!

Regards,
Jim

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux