Create libxl_domain.[ch] and move all functions operating on
libxlDomainObjPrivate to these files. This will be useful for
future patches that e.g. add job support for libxlDomainObjPrivate.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/libxl/libxl_conf.c | 2 +-
src/libxl/libxl_conf.h | 18 --
src/libxl/libxl_domain.c | 469 +++++++++++++++++++++++++++++++++++++++++++++++
src/libxl/libxl_domain.h | 61 ++++++
src/libxl/libxl_driver.c | 436 +------------------------------------------
7 files changed, 535 insertions(+), 453 deletions(-)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9a83069..281274e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -67,6 +67,7 @@ src/lxc/lxc_conf.c
src/lxc/lxc_controller.c
src/lxc/lxc_driver.c
src/lxc/lxc_process.c
+src/libxl/libxl_domain.c
src/libxl/libxl_driver.c
src/libxl/libxl_conf.c
src/network/bridge_driver.c
diff --git a/src/Makefile.am b/src/Makefile.am
index d8b943d..82aefe3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -657,6 +657,7 @@ XENAPI_DRIVER_SOURCES = \
LIBXL_DRIVER_SOURCES = \
libxl/libxl_conf.c libxl/libxl_conf.h \
+ libxl/libxl_domain.c libxl/libxl_domain.h \
libxl/libxl_driver.c libxl/libxl_driver.h
UML_DRIVER_SOURCES = \
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index f8937a4..f9ffe5d 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -39,7 +39,7 @@
#include "viralloc.h"
#include "viruuid.h"
#include "capabilities.h"
-#include "libxl_driver.h"
+#include "libxl_domain.h"
#include "libxl_conf.h"
#include "libxl_utils.h"
#include "virstoragefile.h"
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 0498012..68e770c 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -89,24 +89,6 @@ struct _libxlDriverPrivate {
typedef struct _libxlEventHookInfo libxlEventHookInfo;
typedef libxlEventHookInfo *libxlEventHookInfoPtr;
-typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
-typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
-struct _libxlDomainObjPrivate {
- virObjectLockable parent;
-
- /* per domain log stream for libxl messages */
- FILE *logger_file;
- xentoollog_logger *logger;
- /* per domain libxl ctx */
- libxl_ctx *ctx;
- /* console */
- virChrdevsPtr devs;
- libxl_evgen_domain_death *deathW;
-
- /* list of libxl timeout registrations */
- libxlEventHookInfoPtr timerRegistrations;
-};
-
# define LIBXL_SAVE_MAGIC "libvirt-xml\n \0 \r"
# define LIBXL_SAVE_VERSION 1
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
new file mode 100644
index 0000000..1d03797
--- /dev/null
+++ b/src/libxl/libxl_domain.c
@@ -0,0 +1,469 @@
+/*---------------------------------------------------------------------------*/
+/* Copyright (C) 2011-2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jim Fehlig <jfehlig(a)suse.com>
+ */
+/*---------------------------------------------------------------------------*/
+
+#include <config.h>
+
+#include "libxl_domain.h"
+
+#include "viralloc.h"
+#include "virfile.h"
+#include "virerror.h"
+#include "virlog.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_LIBXL
+
+
+/* Append an event registration to the list of registrations */
+#define LIBXL_EV_REG_APPEND(head, add) \
+ do { \
+ libxlEventHookInfoPtr temp; \
+ if (head) { \
+ temp = head; \
+ while (temp->next) \
+ temp = temp->next; \
+ temp->next = add; \
+ } else { \
+ head = add; \
+ } \
+ } while (0)
+
+/* Remove an event registration from the list of registrations */
+#define LIBXL_EV_REG_REMOVE(head, del) \
+ do { \
+ libxlEventHookInfoPtr temp; \
+ if (head == del) { \
+ head = head->next; \
+ } else { \
+ temp = head; \
+ while (temp->next && temp->next != del) \
+ temp = temp->next; \
+ if (temp->next) { \
+ temp->next = del->next; \
+ } \
+ } \
+ } while (0)
+
+/* Object used to store info related to libxl event registrations */
+struct _libxlEventHookInfo {
+ libxlEventHookInfoPtr next;
+ libxlDomainObjPrivatePtr priv;
+ void *xl_priv;
+ int id;
+};
+
+static virClassPtr libxlDomainObjPrivateClass;
+
+static void
+libxlDomainObjPrivateDispose(void *obj);
+
+static int
+libxlDomainObjPrivateOnceInit(void)
+{
+ if (!(libxlDomainObjPrivateClass = virClassNew(virClassForObjectLockable(),
+ "libxlDomainObjPrivate",
+ sizeof(libxlDomainObjPrivate),
+ libxlDomainObjPrivateDispose)))
+ return -1;
+
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(libxlDomainObjPrivate)
+
+static void
+libxlDomainObjEventHookInfoFree(void *obj)
+{
+ libxlEventHookInfoPtr info = obj;
+
+ /* Drop reference on libxlDomainObjPrivate */
+ virObjectUnref(info->priv);
+ VIR_FREE(info);
+}
+
+static void
+libxlDomainObjFDEventCallback(int watch ATTRIBUTE_UNUSED,
+ int fd,
+ int vir_events,
+ void *fd_info)
+{
+ libxlEventHookInfoPtr info = fd_info;
+ int events = 0;
+
+ virObjectLock(info->priv);
+ if (vir_events & VIR_EVENT_HANDLE_READABLE)
+ events |= POLLIN;
+ if (vir_events & VIR_EVENT_HANDLE_WRITABLE)
+ events |= POLLOUT;
+ if (vir_events & VIR_EVENT_HANDLE_ERROR)
+ events |= POLLERR;
+ if (vir_events & VIR_EVENT_HANDLE_HANGUP)
+ events |= POLLHUP;
+
+ virObjectUnlock(info->priv);
+ libxl_osevent_occurred_fd(info->priv->ctx, info->xl_priv, fd, 0, events);
+}
+
+static int
+libxlDomainObjFDRegisterEventHook(void *priv,
+ int fd,
+ void **hndp,
+ short events,
+ void *xl_priv)
+{
+ int vir_events = VIR_EVENT_HANDLE_ERROR;
+ libxlEventHookInfoPtr info;
+
+ if (VIR_ALLOC(info) < 0)
+ return -1;
+
+ info->priv = priv;
+ /*
+ * Take a reference on the domain object. Reference is dropped in
+ * libxlDomainObjEventHookInfoFree, ensuring the domain object outlives
+ * the fd event objects.
+ */
+ virObjectRef(info->priv);
+ info->xl_priv = xl_priv;
+
+ if (events & POLLIN)
+ vir_events |= VIR_EVENT_HANDLE_READABLE;
+ if (events & POLLOUT)
+ vir_events |= VIR_EVENT_HANDLE_WRITABLE;
+
+ info->id = virEventAddHandle(fd, vir_events, libxlDomainObjFDEventCallback,
+ info, libxlDomainObjEventHookInfoFree);
+ if (info->id < 0) {
+ virObjectUnref(info->priv);
+ VIR_FREE(info);
+ return -1;
+ }
+
+ *hndp = info;
+
+ return 0;
+}
+
+static int
+libxlDomainObjFDModifyEventHook(void *priv ATTRIBUTE_UNUSED,
+ int fd ATTRIBUTE_UNUSED,
+ void **hndp,
+ short events)
+{
+ libxlEventHookInfoPtr info = *hndp;
+ int vir_events = VIR_EVENT_HANDLE_ERROR;
+
+ virObjectLock(info->priv);
+ if (events & POLLIN)
+ vir_events |= VIR_EVENT_HANDLE_READABLE;
+ if (events & POLLOUT)
+ vir_events |= VIR_EVENT_HANDLE_WRITABLE;
+
+ virEventUpdateHandle(info->id, vir_events);
+ virObjectUnlock(info->priv);
+
+ return 0;
+}
+
+static void
+libxlDomainObjFDDeregisterEventHook(void *priv ATTRIBUTE_UNUSED,
+ int fd ATTRIBUTE_UNUSED,
+ void *hnd)
+{
+ libxlEventHookInfoPtr info = hnd;
+ libxlDomainObjPrivatePtr p = info->priv;
+
+ virObjectLock(p);
+ virEventRemoveHandle(info->id);
+ virObjectUnlock(p);
+}
+
+static void
+libxlDomainObjTimerCallback(int timer ATTRIBUTE_UNUSED, void *timer_info)
+{
+ libxlEventHookInfoPtr info = timer_info;
+ libxlDomainObjPrivatePtr p = info->priv;
+
+ virObjectLock(p);
+ /*
+ * libxl expects the event to be deregistered when calling
+ * libxl_osevent_occurred_timeout, but we dont want the event info
+ * destroyed. Disable the timeout and only remove it after returning
+ * from libxl.
+ */
+ virEventUpdateTimeout(info->id, -1);
+ virObjectUnlock(p);
+ libxl_osevent_occurred_timeout(p->ctx, info->xl_priv);
+ virObjectLock(p);
+ /*
+ * Timeout could have been freed while the lock was dropped.
+ * Only remove it from the list if it still exists.
+ */
+ if (virEventRemoveTimeout(info->id) == 0)
+ LIBXL_EV_REG_REMOVE(p->timerRegistrations, info);
+ virObjectUnlock(p);
+}
+
+static int
+libxlDomainObjTimeoutRegisterEventHook(void *priv,
+ void **hndp,
+ struct timeval abs_t,
+ void *xl_priv)
+{
+ libxlEventHookInfoPtr info;
+ struct timeval now;
+ struct timeval res;
+ static struct timeval zero;
+ int timeout;
+
+ if (VIR_ALLOC(info) < 0)
+ return -1;
+
+ info->priv = priv;
+ /*
+ * Also take a reference on the domain object. Reference is dropped in
+ * libxlDomainObjEventHookInfoFree, ensuring the domain object outlives the
+ * timeout event objects.
+ */
+ virObjectRef(info->priv);
+ info->xl_priv = xl_priv;
+
+ gettimeofday(&now, NULL);
+ timersub(&abs_t, &now, &res);
+ /* Ensure timeout is not overflowed */
+ if (timercmp(&res, &zero, <)) {
+ timeout = 0;
+ } else if (res.tv_sec > INT_MAX / 1000) {
+ timeout = INT_MAX;
+ } else {
+ timeout = res.tv_sec * 1000 + (res.tv_usec + 999) / 1000;
+ }
+ info->id = virEventAddTimeout(timeout, libxlDomainObjTimerCallback,
+ info, libxlDomainObjEventHookInfoFree);
+ if (info->id < 0) {
+ virObjectUnref(info->priv);
+ VIR_FREE(info);
+ return -1;
+ }
+
+ virObjectLock(info->priv);
+ LIBXL_EV_REG_APPEND(info->priv->timerRegistrations, info);
+ virObjectUnlock(info->priv);
+ *hndp = info;
+
+ return 0;
+}
+
+/*
+ * Note: There are two changes wrt timeouts starting with xen-unstable
+ * changeset 26469:
+ *
+ * 1. Timeout modify callbacks will only be invoked with an abs_t of {0,0},
+ * i.e. make the timeout fire immediately. Prior to this commit, timeout
+ * modify callbacks were never invoked.
+ *
+ * 2. Timeout deregister hooks will no longer be called.
+ */
+static int
+libxlDomainObjTimeoutModifyEventHook(void *priv ATTRIBUTE_UNUSED,
+ void **hndp,
+ struct timeval abs_t ATTRIBUTE_UNUSED)
+{
+ libxlEventHookInfoPtr info = *hndp;
+
+ virObjectLock(info->priv);
+ /* Make the timeout fire */
+ virEventUpdateTimeout(info->id, 0);
+ virObjectUnlock(info->priv);
+
+ return 0;
+}
+
+static void
+libxlDomainObjTimeoutDeregisterEventHook(void *priv ATTRIBUTE_UNUSED,
+ void *hnd)
+{
+ libxlEventHookInfoPtr info = hnd;
+ libxlDomainObjPrivatePtr p = info->priv;
+
+ virObjectLock(p);
+ /*
+ * Only remove the timeout from the list if removal from the
+ * event loop is successful.
+ */
+ if (virEventRemoveTimeout(info->id) == 0)
+ LIBXL_EV_REG_REMOVE(p->timerRegistrations, info);
+ virObjectUnlock(p);
+}
+
+
+static const libxl_osevent_hooks libxl_event_callbacks = {
+ .fd_register = libxlDomainObjFDRegisterEventHook,
+ .fd_modify = libxlDomainObjFDModifyEventHook,
+ .fd_deregister = libxlDomainObjFDDeregisterEventHook,
+ .timeout_register = libxlDomainObjTimeoutRegisterEventHook,
+ .timeout_modify = libxlDomainObjTimeoutModifyEventHook,
+ .timeout_deregister = libxlDomainObjTimeoutDeregisterEventHook,
+};
+
+static void *
+libxlDomainObjPrivateAlloc(void)
+{
+ libxlDomainObjPrivatePtr priv;
+
+ if (libxlDomainObjPrivateInitialize() < 0)
+ return NULL;
+
+ if (!(priv = virObjectLockableNew(libxlDomainObjPrivateClass)))
+ return NULL;
+
+ if (!(priv->devs = virChrdevAlloc())) {
+ virObjectUnref(priv);
+ return NULL;
+ }
+
+ return priv;
+}
+
+static void
+libxlDomainObjPrivateDispose(void *obj)
+{
+ libxlDomainObjPrivatePtr priv = obj;
+
+ if (priv->deathW)
+ libxl_evdisable_domain_death(priv->ctx, priv->deathW);
+
+ virChrdevFree(priv->devs);
+
+ xtl_logger_destroy(priv->logger);
+ if (priv->logger_file)
+ VIR_FORCE_FCLOSE(priv->logger_file);
+
+ libxl_ctx_free(priv->ctx);
+}
+
+static void
+libxlDomainObjPrivateFree(void *data)
+{
+ libxlDomainObjPrivatePtr priv = data;
+
+ if (priv->deathW) {
+ libxl_evdisable_domain_death(priv->ctx, priv->deathW);
+ priv->deathW = NULL;
+ }
+
+ virObjectUnref(priv);
+}
+
+virDomainXMLPrivateDataCallbacks libxlDomainXMLPrivateDataCallbacks = {
+ .alloc = libxlDomainObjPrivateAlloc,
+ .free = libxlDomainObjPrivateFree,
+};
+
+
+static int
+libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
+ virDomainDefPtr def,
+ virCapsPtr caps ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ if (dev->type == VIR_DOMAIN_DEVICE_CHR &&
+ dev->data.chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
+ dev->data.chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE
&&
+ STRNEQ(def->os.type, "hvm"))
+ dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
+
+ return 0;
+}
+
+virDomainDefParserConfig libxlDomainDefParserConfig = {
+ .macPrefix = { 0x00, 0x16, 0x3e },
+ .devicesPostParseCallback = libxlDomainDeviceDefPostParse,
+};
+
+int
+libxlDomainObjPrivateInitCtx(virDomainObjPtr vm)
+{
+ libxlDomainObjPrivatePtr priv = vm->privateData;
+ char *log_file;
+ int ret = -1;
+
+ if (priv->ctx)
+ return 0;
+
+ if (virAsprintf(&log_file, "%s/%s.log", LIBXL_LOG_DIR,
vm->def->name) < 0)
+ return -1;
+
+ if ((priv->logger_file = fopen(log_file, "a")) == NULL) {
+ virReportSystemError(errno,
+ _("failed to open logfile %s"),
+ log_file);
+ goto cleanup;
+ }
+
+ priv->logger =
+ (xentoollog_logger *)xtl_createlogger_stdiostream(priv->logger_file,
+ XTL_DEBUG, 0);
+ if (!priv->logger) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot create libxenlight logger for domain %s"),
+ vm->def->name);
+ goto cleanup;
+ }
+
+ if (libxl_ctx_alloc(&priv->ctx, LIBXL_VERSION, 0, priv->logger)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed libxl context initialization"));
+ goto cleanup;
+ }
+
+ libxl_osevent_register_hooks(priv->ctx, &libxl_event_callbacks, priv);
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(log_file);
+ return ret;
+}
+
+void
+libxlDomainObjRegisteredTimeoutsCleanup(libxlDomainObjPrivatePtr priv)
+{
+ libxlEventHookInfoPtr info;
+
+ virObjectLock(priv);
+ info = priv->timerRegistrations;
+ while (info) {
+ /*
+ * libxl expects the event to be deregistered when calling
+ * libxl_osevent_occurred_timeout, but we dont want the event info
+ * destroyed. Disable the timeout and only remove it after returning
+ * from libxl.
+ */
+ virEventUpdateTimeout(info->id, -1);
+ libxl_osevent_occurred_timeout(priv->ctx, info->xl_priv);
+ virEventRemoveTimeout(info->id);
+ info = info->next;
+ }
+ priv->timerRegistrations = NULL;
+ virObjectUnlock(priv);
+}
diff --git a/src/libxl/libxl_domain.h b/src/libxl/libxl_domain.h
new file mode 100644
index 0000000..2797d38
--- /dev/null
+++ b/src/libxl/libxl_domain.h
@@ -0,0 +1,61 @@
+/*---------------------------------------------------------------------------*/
+/* Copyright (C) 2011-2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jim Fehlig <jfehlig(a)suse.com>
+ */
+/*---------------------------------------------------------------------------*/
+
+#ifndef LIBXL_DOMAIN_H
+# define LIBXL_DOMAIN_H
+
+# include <libxl.h>
+
+# include "domain_conf.h"
+# include "libxl_conf.h"
+# include "virchrdev.h"
+
+typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
+typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
+struct _libxlDomainObjPrivate {
+ virObjectLockable parent;
+
+ /* per domain log stream for libxl messages */
+ FILE *logger_file;
+ xentoollog_logger *logger;
+ /* per domain libxl ctx */
+ libxl_ctx *ctx;
+ /* console */
+ virChrdevsPtr devs;
+ libxl_evgen_domain_death *deathW;
+
+ /* list of libxl timeout registrations */
+ libxlEventHookInfoPtr timerRegistrations;
+};
+
+
+extern virDomainXMLPrivateDataCallbacks libxlDomainXMLPrivateDataCallbacks;
+extern virDomainDefParserConfig libxlDomainDefParserConfig;
+
+
+int
+libxlDomainObjPrivateInitCtx(virDomainObjPtr vm);
+
+void
+libxlDomainObjRegisteredTimeoutsCleanup(libxlDomainObjPrivatePtr priv);
+
+#endif /* LIBXL_DOMAIN_H */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 91beb30..ff4f6be 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -41,6 +41,7 @@
#include "viralloc.h"
#include "viruuid.h"
#include "vircommand.h"
+#include "libxl_domain.h"
#include "libxl_driver.h"
#include "libxl_conf.h"
#include "xen_xm.h"
@@ -63,45 +64,6 @@
/* Number of Xen scheduler parameters */
#define XEN_SCHED_CREDIT_NPARAM 2
-/* Append an event registration to the list of registrations */
-#define LIBXL_EV_REG_APPEND(head, add) \
- do { \
- libxlEventHookInfoPtr temp; \
- if (head) { \
- temp = head; \
- while (temp->next) \
- temp = temp->next; \
- temp->next = add; \
- } else { \
- head = add; \
- } \
- } while (0)
-
-/* Remove an event registration from the list of registrations */
-#define LIBXL_EV_REG_REMOVE(head, del) \
- do { \
- libxlEventHookInfoPtr temp; \
- if (head == del) { \
- head = head->next; \
- } else { \
- temp = head; \
- while (temp->next && temp->next != del) \
- temp = temp->next; \
- if (temp->next) { \
- temp->next = del->next; \
- } \
- } \
- } while (0)
-
-/* Object used to store info related to libxl event registrations */
-struct _libxlEventHookInfo {
- libxlEventHookInfoPtr next;
- libxlDomainObjPrivatePtr priv;
- void *xl_priv;
- int id;
-};
-
-static virClassPtr libxlDomainObjPrivateClass;
static libxlDriverPrivatePtr libxl_driver = NULL;
@@ -115,24 +77,6 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
bool start_paused, int restore_fd);
static void
-libxlDomainObjPrivateDispose(void *obj);
-
-/* Function definitions */
-static int
-libxlDomainObjPrivateOnceInit(void)
-{
- if (!(libxlDomainObjPrivateClass = virClassNew(virClassForObjectLockable(),
- "libxlDomainObjPrivate",
- sizeof(libxlDomainObjPrivate),
- libxlDomainObjPrivateDispose)))
- return -1;
-
- return 0;
-}
-
-VIR_ONCE_GLOBAL_INIT(libxlDomainObjPrivate)
-
-static void
libxlDriverLock(libxlDriverPrivatePtr driver)
{
virMutexLock(&driver->lock);
@@ -144,382 +88,6 @@ libxlDriverUnlock(libxlDriverPrivatePtr driver)
virMutexUnlock(&driver->lock);
}
-static void
-libxlEventHookInfoFree(void *obj)
-{
- libxlEventHookInfoPtr info = obj;
-
- /* Drop reference on libxlDomainObjPrivate */
- virObjectUnref(info->priv);
- VIR_FREE(info);
-}
-
-static void
-libxlFDEventCallback(int watch ATTRIBUTE_UNUSED,
- int fd,
- int vir_events,
- void *fd_info)
-{
- libxlEventHookInfoPtr info = fd_info;
- int events = 0;
-
- virObjectLock(info->priv);
- if (vir_events & VIR_EVENT_HANDLE_READABLE)
- events |= POLLIN;
- if (vir_events & VIR_EVENT_HANDLE_WRITABLE)
- events |= POLLOUT;
- if (vir_events & VIR_EVENT_HANDLE_ERROR)
- events |= POLLERR;
- if (vir_events & VIR_EVENT_HANDLE_HANGUP)
- events |= POLLHUP;
-
- virObjectUnlock(info->priv);
- libxl_osevent_occurred_fd(info->priv->ctx, info->xl_priv, fd, 0, events);
-}
-
-static int
-libxlFDRegisterEventHook(void *priv, int fd, void **hndp,
- short events, void *xl_priv)
-{
- int vir_events = VIR_EVENT_HANDLE_ERROR;
- libxlEventHookInfoPtr info;
-
- if (VIR_ALLOC(info) < 0)
- return -1;
-
- info->priv = priv;
- /*
- * Take a reference on the domain object. Reference is dropped in
- * libxlEventHookInfoFree, ensuring the domain object outlives the fd
- * event objects.
- */
- virObjectRef(info->priv);
- info->xl_priv = xl_priv;
-
- if (events & POLLIN)
- vir_events |= VIR_EVENT_HANDLE_READABLE;
- if (events & POLLOUT)
- vir_events |= VIR_EVENT_HANDLE_WRITABLE;
-
- info->id = virEventAddHandle(fd, vir_events, libxlFDEventCallback,
- info, libxlEventHookInfoFree);
- if (info->id < 0) {
- virObjectUnref(info->priv);
- VIR_FREE(info);
- return -1;
- }
-
- *hndp = info;
-
- return 0;
-}
-
-static int
-libxlFDModifyEventHook(void *priv ATTRIBUTE_UNUSED,
- int fd ATTRIBUTE_UNUSED,
- void **hndp,
- short events)
-{
- libxlEventHookInfoPtr info = *hndp;
- int vir_events = VIR_EVENT_HANDLE_ERROR;
-
- virObjectLock(info->priv);
- if (events & POLLIN)
- vir_events |= VIR_EVENT_HANDLE_READABLE;
- if (events & POLLOUT)
- vir_events |= VIR_EVENT_HANDLE_WRITABLE;
-
- virEventUpdateHandle(info->id, vir_events);
- virObjectUnlock(info->priv);
-
- return 0;
-}
-
-static void
-libxlFDDeregisterEventHook(void *priv ATTRIBUTE_UNUSED,
- int fd ATTRIBUTE_UNUSED,
- void *hnd)
-{
- libxlEventHookInfoPtr info = hnd;
- libxlDomainObjPrivatePtr p = info->priv;
-
- virObjectLock(p);
- virEventRemoveHandle(info->id);
- virObjectUnlock(p);
-}
-
-static void
-libxlTimerCallback(int timer ATTRIBUTE_UNUSED, void *timer_info)
-{
- libxlEventHookInfoPtr info = timer_info;
- libxlDomainObjPrivatePtr p = info->priv;
-
- virObjectLock(p);
- /*
- * libxl expects the event to be deregistered when calling
- * libxl_osevent_occurred_timeout, but we dont want the event info
- * destroyed. Disable the timeout and only remove it after returning
- * from libxl.
- */
- virEventUpdateTimeout(info->id, -1);
- virObjectUnlock(p);
- libxl_osevent_occurred_timeout(p->ctx, info->xl_priv);
- virObjectLock(p);
- /*
- * Timeout could have been freed while the lock was dropped.
- * Only remove it from the list if it still exists.
- */
- if (virEventRemoveTimeout(info->id) == 0)
- LIBXL_EV_REG_REMOVE(p->timerRegistrations, info);
- virObjectUnlock(p);
-}
-
-static int
-libxlTimeoutRegisterEventHook(void *priv,
- void **hndp,
- struct timeval abs_t,
- void *xl_priv)
-{
- libxlEventHookInfoPtr info;
- struct timeval now;
- struct timeval res;
- static struct timeval zero;
- int timeout;
-
- if (VIR_ALLOC(info) < 0)
- return -1;
-
- info->priv = priv;
- /*
- * Also take a reference on the domain object. Reference is dropped in
- * libxlEventHookInfoFree, ensuring the domain object outlives the timeout
- * event objects.
- */
- virObjectRef(info->priv);
- info->xl_priv = xl_priv;
-
- gettimeofday(&now, NULL);
- timersub(&abs_t, &now, &res);
- /* Ensure timeout is not overflowed */
- if (timercmp(&res, &zero, <))
- timeout = 0;
- else if (res.tv_sec > INT_MAX / 1000)
- timeout = INT_MAX;
- else
- timeout = res.tv_sec * 1000 + (res.tv_usec + 999) / 1000;
-
- info->id = virEventAddTimeout(timeout, libxlTimerCallback,
- info, libxlEventHookInfoFree);
- if (info->id < 0) {
- virObjectUnref(info->priv);
- VIR_FREE(info);
- return -1;
- }
-
- virObjectLock(info->priv);
- LIBXL_EV_REG_APPEND(info->priv->timerRegistrations, info);
- virObjectUnlock(info->priv);
- *hndp = info;
-
- return 0;
-}
-
-/*
- * Note: There are two changes wrt timeouts starting with xen-unstable
- * changeset 26469:
- *
- * 1. Timeout modify callbacks will only be invoked with an abs_t of {0,0},
- * i.e. make the timeout fire immediately. Prior to this commit, timeout
- * modify callbacks were never invoked.
- *
- * 2. Timeout deregister hooks will no longer be called.
- */
-static int
-libxlTimeoutModifyEventHook(void *priv ATTRIBUTE_UNUSED,
- void **hndp,
- struct timeval abs_t ATTRIBUTE_UNUSED)
-{
- libxlEventHookInfoPtr info = *hndp;
-
- virObjectLock(info->priv);
- /* Make the timeout fire */
- virEventUpdateTimeout(info->id, 0);
- virObjectUnlock(info->priv);
-
- return 0;
-}
-
-static void
-libxlTimeoutDeregisterEventHook(void *priv ATTRIBUTE_UNUSED,
- void *hnd)
-{
- libxlEventHookInfoPtr info = hnd;
- libxlDomainObjPrivatePtr p = info->priv;
-
- virObjectLock(p);
- /*
- * Only remove the timeout from the list if removal from the
- * event loop is successful.
- */
- if (virEventRemoveTimeout(info->id) == 0)
- LIBXL_EV_REG_REMOVE(p->timerRegistrations, info);
- virObjectUnlock(p);
-}
-
-static void
-libxlRegisteredTimeoutsCleanup(libxlDomainObjPrivatePtr priv)
-{
- libxlEventHookInfoPtr info;
-
- virObjectLock(priv);
- info = priv->timerRegistrations;
- while (info) {
- /*
- * libxl expects the event to be deregistered when calling
- * libxl_osevent_occurred_timeout, but we dont want the event info
- * destroyed. Disable the timeout and only remove it after returning
- * from libxl.
- */
- virEventUpdateTimeout(info->id, -1);
- libxl_osevent_occurred_timeout(priv->ctx, info->xl_priv);
- virEventRemoveTimeout(info->id);
- info = info->next;
- }
- priv->timerRegistrations = NULL;
- virObjectUnlock(priv);
-}
-
-static const libxl_osevent_hooks libxl_event_callbacks = {
- .fd_register = libxlFDRegisterEventHook,
- .fd_modify = libxlFDModifyEventHook,
- .fd_deregister = libxlFDDeregisterEventHook,
- .timeout_register = libxlTimeoutRegisterEventHook,
- .timeout_modify = libxlTimeoutModifyEventHook,
- .timeout_deregister = libxlTimeoutDeregisterEventHook,
-};
-
-static int
-libxlDomainObjPrivateInitCtx(virDomainObjPtr vm)
-{
- libxlDomainObjPrivatePtr priv = vm->privateData;
- char *log_file;
- int ret = -1;
-
- if (priv->ctx)
- return 0;
-
- if (virAsprintf(&log_file, "%s/%s.log", LIBXL_LOG_DIR,
vm->def->name) < 0)
- return -1;
-
- if ((priv->logger_file = fopen(log_file, "a")) == NULL) {
- virReportSystemError(errno,
- _("failed to open logfile %s"),
- log_file);
- goto cleanup;
- }
-
- priv->logger =
- (xentoollog_logger *)xtl_createlogger_stdiostream(priv->logger_file,
- XTL_DEBUG, 0);
- if (!priv->logger) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot create libxenlight logger for domain %s"),
- vm->def->name);
- goto cleanup;
- }
-
- if (libxl_ctx_alloc(&priv->ctx, LIBXL_VERSION, 0, priv->logger)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Failed libxl context initialization"));
- goto cleanup;
- }
-
- libxl_osevent_register_hooks(priv->ctx, &libxl_event_callbacks, priv);
-
- ret = 0;
-
-cleanup:
- VIR_FREE(log_file);
- return ret;
-}
-
-static void *
-libxlDomainObjPrivateAlloc(void)
-{
- libxlDomainObjPrivatePtr priv;
-
- if (libxlDomainObjPrivateInitialize() < 0)
- return NULL;
-
- if (!(priv = virObjectLockableNew(libxlDomainObjPrivateClass)))
- return NULL;
-
- if (!(priv->devs = virChrdevAlloc())) {
- virObjectUnref(priv);
- return NULL;
- }
-
- return priv;
-}
-
-static void
-libxlDomainObjPrivateDispose(void *obj)
-{
- libxlDomainObjPrivatePtr priv = obj;
-
- if (priv->deathW)
- libxl_evdisable_domain_death(priv->ctx, priv->deathW);
-
- virChrdevFree(priv->devs);
-
- xtl_logger_destroy(priv->logger);
- if (priv->logger_file)
- VIR_FORCE_FCLOSE(priv->logger_file);
-
- libxl_ctx_free(priv->ctx);
-}
-
-static void
-libxlDomainObjPrivateFree(void *data)
-{
- libxlDomainObjPrivatePtr priv = data;
-
- if (priv->deathW) {
- libxl_evdisable_domain_death(priv->ctx, priv->deathW);
- priv->deathW = NULL;
- }
-
- virObjectUnref(priv);
-}
-
-virDomainXMLPrivateDataCallbacks libxlDomainXMLPrivateDataCallbacks = {
- .alloc = libxlDomainObjPrivateAlloc,
- .free = libxlDomainObjPrivateFree,
-};
-
-
-static int
-libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
- virDomainDefPtr def,
- virCapsPtr caps ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
- if (dev->type == VIR_DOMAIN_DEVICE_CHR &&
- dev->data.chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
- dev->data.chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE
&&
- STRNEQ(def->os.type, "hvm"))
- dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
-
- return 0;
-}
-
-
-virDomainDefParserConfig libxlDomainDefParserConfig = {
- .macPrefix = { 0x00, 0x16, 0x3e },
- .devicesPostParseCallback = libxlDomainDeviceDefPostParse,
-};
-
-
/* driver must be locked before calling */
static void
libxlDomainEventQueue(libxlDriverPrivatePtr driver, virDomainEventPtr event)
@@ -728,7 +296,7 @@ libxlVmCleanup(libxlDriverPrivatePtr driver,
vm->newDef = NULL;
}
- libxlRegisteredTimeoutsCleanup(priv);
+ libxlDomainObjRegisteredTimeoutsCleanup(priv);
}
/*
--
1.8.1.4