From: Jim Fehlig <jfehlig@suse.com>
To: libvir-list@redhat.com
Cc: Jim Fehlig <jfehlig@suse.com>, bjzhang@suse.com, xen-devel@lists.xen.org
Subject: [PATCH 3/4] libxl: handle domain shutdown events in a thread
Date: Wed, 5 Feb 2014 10:39:45 -0700 [thread overview]
Message-ID: <1391621986-7341-4-git-send-email-jfehlig@suse.com> (raw)
In-Reply-To: <1391621986-7341-1-git-send-email-jfehlig@suse.com>
Handling the domain shutdown event within the event handler seems
a bit unfair to libxl's event machinery. Domain "shutdown" could
take considerable time. E.g. if the shutdown reason is reboot,
the domain must be reaped and then started again.
Spawn a shutdown handler thread to do this work, allowing libxl's
event machinery to go about its business.
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
---
src/libxl/libxl_driver.c | 132 ++++++++++++++++++++++++++++++++---------------
1 file changed, 89 insertions(+), 43 deletions(-)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index d639011..a1c6c0f 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -352,61 +352,107 @@ libxlVmReap(libxlDriverPrivatePtr driver,
# define VIR_LIBXL_EVENT_CONST const
#endif
+struct libxlShutdownThreadInfo
+{
+ virDomainObjPtr vm;
+ libxl_event *event;
+};
+
+
static void
-libxlEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event)
+libxlDomainShutdownThread(void *opaque)
{
libxlDriverPrivatePtr driver = libxl_driver;
- libxlDomainObjPrivatePtr priv = ((virDomainObjPtr)data)->privateData;
- virDomainObjPtr vm = NULL;
+ struct libxlShutdownThreadInfo *shutdown_info = opaque;
+ virDomainObjPtr vm = shutdown_info->vm;
+ libxlDomainObjPrivatePtr priv = vm->privateData;
+ libxl_event *ev = shutdown_info->event;
+ libxl_ctx *ctx = priv->ctx;
virObjectEventPtr dom_event = NULL;
- libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
-
- if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
- virDomainShutoffReason reason;
-
- /*
- * Similar to the xl implementation, ignore SUSPEND. Any actions needed
- * after calling libxl_domain_suspend() are handled by it's callers.
- */
- if (xl_reason == LIBXL_SHUTDOWN_REASON_SUSPEND)
- goto cleanup;
+ libxl_shutdown_reason xl_reason = ev->u.domain_shutdown.shutdown_reason;
+ virDomainShutoffReason reason;
- vm = virDomainObjListFindByID(driver->domains, event->domid);
- if (!vm)
- goto cleanup;
+ virObjectLock(vm);
- switch (xl_reason) {
- case LIBXL_SHUTDOWN_REASON_POWEROFF:
- case LIBXL_SHUTDOWN_REASON_CRASH:
- if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) {
- dom_event = virDomainEventLifecycleNewFromObj(vm,
- VIR_DOMAIN_EVENT_STOPPED,
- VIR_DOMAIN_EVENT_STOPPED_CRASHED);
- reason = VIR_DOMAIN_SHUTOFF_CRASHED;
- } else {
- reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
- }
- libxlVmReap(driver, vm, reason);
- if (!vm->persistent) {
- virDomainObjListRemove(driver->domains, vm);
- vm = NULL;
- }
- break;
- case LIBXL_SHUTDOWN_REASON_REBOOT:
- libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
- libxlVmStart(driver, vm, 0, -1);
- break;
- default:
- VIR_INFO("Unhandled shutdown_reason %d", xl_reason);
- break;
- }
+ switch (xl_reason) {
+ case LIBXL_SHUTDOWN_REASON_POWEROFF:
+ case LIBXL_SHUTDOWN_REASON_CRASH:
+ if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) {
+ dom_event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_CRASHED);
+ reason = VIR_DOMAIN_SHUTOFF_CRASHED;
+ } else {
+ reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
+ }
+ libxlVmReap(driver, vm, reason);
+ if (!vm->persistent) {
+ virDomainObjListRemove(driver->domains, vm);
+ vm = NULL;
+ }
+ break;
+ case LIBXL_SHUTDOWN_REASON_REBOOT:
+ libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+ libxlVmStart(driver, vm, 0, -1);
+ break;
+ default:
+ VIR_INFO("Unhandled shutdown_reason %d", xl_reason);
+ break;
}
-cleanup:
if (vm)
virObjectUnlock(vm);
if (dom_event)
libxlDomainEventQueue(driver, dom_event);
+ libxl_event_free(ctx, ev);
+ VIR_FREE(shutdown_info);
+}
+
+static void
+libxlEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event)
+{
+ virDomainObjPtr vm = data;
+ libxlDomainObjPrivatePtr priv = vm->privateData;
+ libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
+ struct libxlShutdownThreadInfo *shutdown_info;
+ virThread thread;
+
+ if (event->type != LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
+ VIR_INFO("Unhandled event type %d", event->type);
+ goto cleanup;
+ }
+
+ /*
+ * Similar to the xl implementation, ignore SUSPEND. Any actions needed
+ * after calling libxl_domain_suspend() are handled by it's callers.
+ */
+ if (xl_reason == LIBXL_SHUTDOWN_REASON_SUSPEND)
+ goto cleanup;
+
+ /*
+ * Start a thread to handle shutdown. We don't want to be tying up
+ * libxl's event machinery by doing a potentially lengthy shutdown.
+ */
+ if (VIR_ALLOC(shutdown_info) < 0)
+ goto cleanup;
+
+ shutdown_info->vm = data;
+ shutdown_info->event = (libxl_event *)event;
+ if (virThreadCreate(&thread, true, libxlDomainShutdownThread,
+ shutdown_info) < 0) {
+ /*
+ * Not much we can do on error here except log it.
+ */
+ VIR_ERROR(_("Failed to create thread to handle domain shutdown"));
+ goto cleanup;
+ }
+
+ /*
+ * libxl_event freed in shutdown thread
+ */
+ return;
+
+cleanup:
/* Cast away any const */
libxl_event_free(priv->ctx, (libxl_event *)event);
}
--
1.8.1.4
next prev parent reply other threads:[~2014-02-05 17:39 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-05 17:39 [PATCH 0/4] libxl: fixes related to concurrency improvements Jim Fehlig
2014-02-05 17:39 ` [PATCH 1/4] libxl: fix leaking libxlDomainObjPrivate Jim Fehlig
2014-02-05 17:39 ` [PATCH 2/4] libxl: remove list of timer registrations from libxlDomainObjPrivate Jim Fehlig
2014-02-05 17:39 ` Jim Fehlig [this message]
2014-02-06 12:53 ` [libvirt] [PATCH 3/4] libxl: handle domain shutdown events in a thread Michal Privoznik
2014-02-05 17:39 ` [PATCH 4/4] libxl: improve subprocess handling Jim Fehlig
2014-02-06 12:53 ` [libvirt] [PATCH 0/4] libxl: fixes related to concurrency improvements Michal Privoznik
[not found] ` <52F385BE.5020509@redhat.com>
2014-02-06 17:36 ` Jim Fehlig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1391621986-7341-4-git-send-email-jfehlig@suse.com \
--to=jfehlig@suse.com \
--cc=bjzhang@suse.com \
--cc=libvir-list@redhat.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).