Move the code for handling the QEMU virDomainObjPtr private
data, and custom XML namespace into a separate file
* src/qemu/qemu_domain.c, src/qemu/qemu_domain.h: New file
for private data & namespace code
* src/qemu/qemu_driver.c, src/qemu/qemu_driver.h: Remove
private data & namespace code
* src/qemu/qemu_driver.h, src/qemu/qemu_command.h: Update
includes
* src/Makefile.am: Add src/qemu/qemu_domain.c
---
src/Makefile.am | 1 +
src/qemu/qemu_command.h | 1 +
src/qemu/qemu_conf.h | 3 -
src/qemu/qemu_domain.c | 374 +++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 83 +++++++++++
src/qemu/qemu_driver.c | 329 +-----------------------------------------
src/qemu/qemu_driver.h | 9 -
7 files changed, 461 insertions(+), 339 deletions(-)
create mode 100644 src/qemu/qemu_domain.c
create mode 100644 src/qemu/qemu_domain.h
diff --git a/src/Makefile.am b/src/Makefile.am
index d4626d9..d2fcd5f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -269,6 +269,7 @@ VBOX_DRIVER_EXTRA_DIST = vbox/vbox_tmpl.c vbox/README
QEMU_DRIVER_SOURCES = \
qemu/qemu_capabilities.c qemu/qemu_capabilities.h\
qemu/qemu_command.c qemu/qemu_command.h \
+ qemu/qemu_domain.c qemu/qemu_domain.h \
qemu/qemu_conf.c qemu/qemu_conf.h \
qemu/qemu_monitor.c qemu/qemu_monitor.h \
qemu/qemu_monitor_text.c \
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index da35d3b..5545e54 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -28,6 +28,7 @@
#include "command.h"
#include "capabilities.h"
#include "qemu_conf.h"
+#include "qemu_domain.h"
/* Config type for XML import/export conversions */
# define QEMU_CONFIG_FORMAT_ARGV "qemu-argv"
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index eac8603..4c61891 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -130,9 +130,6 @@ struct qemud_driver {
virSysinfoDefPtr hostsysinfo;
};
-typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
-typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
-
typedef struct _qemuDomainCmdlineDef qemuDomainCmdlineDef;
typedef qemuDomainCmdlineDef *qemuDomainCmdlineDefPtr;
struct _qemuDomainCmdlineDef {
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
new file mode 100644
index 0000000..14364ff
--- /dev/null
+++ b/src/qemu/qemu_domain.c
@@ -0,0 +1,374 @@
+/*
+ * qemu_domain.h: QEMU domain private state
+ *
+ * Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "qemu_domain.h"
+#include "qemu_command.h"
+#include "memory.h"
+#include "logging.h"
+#include "virterror_internal.h"
+#include "c-ctype.h"
+
+#include <libxml/xpathInternals.h>
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+#define QEMU_NAMESPACE_HREF "http://libvirt.org/schemas/domain/qemu/1.0"
+
+static void *qemuDomainObjPrivateAlloc(void)
+{
+ qemuDomainObjPrivatePtr priv;
+
+ if (VIR_ALLOC(priv) < 0)
+ return NULL;
+
+ return priv;
+}
+
+static void qemuDomainObjPrivateFree(void *data)
+{
+ qemuDomainObjPrivatePtr priv = data;
+
+ qemuDomainPCIAddressSetFree(priv->pciaddrs);
+ virDomainChrDefFree(priv->monConfig);
+ VIR_FREE(priv->vcpupids);
+
+ /* This should never be non-NULL if we get here, but just in case... */
+ if (priv->mon) {
+ VIR_ERROR0(_("Unexpected QEMU monitor still active during domain
deletion"));
+ qemuMonitorClose(priv->mon);
+ }
+ VIR_FREE(priv);
+}
+
+
+static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data)
+{
+ qemuDomainObjPrivatePtr priv = data;
+ const char *monitorpath;
+
+ /* priv->monitor_chr is set only for qemu */
+ if (priv->monConfig) {
+ switch (priv->monConfig->type) {
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ monitorpath = priv->monConfig->data.nix.path;
+ break;
+ default:
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ monitorpath = priv->monConfig->data.file.path;
+ break;
+ }
+
+ virBufferEscapeString(buf, " <monitor path='%s'",
monitorpath);
+ if (priv->monJSON)
+ virBufferAddLit(buf, " json='1'");
+ virBufferVSprintf(buf, " type='%s'/>\n",
+ virDomainChrTypeToString(priv->monConfig->type));
+ }
+
+
+ if (priv->nvcpupids) {
+ int i;
+ virBufferAddLit(buf, " <vcpus>\n");
+ for (i = 0 ; i < priv->nvcpupids ; i++) {
+ virBufferVSprintf(buf, " <vcpu pid='%d'/>\n",
priv->vcpupids[i]);
+ }
+ virBufferAddLit(buf, " </vcpus>\n");
+ }
+
+ return 0;
+}
+
+static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
+{
+ qemuDomainObjPrivatePtr priv = data;
+ char *monitorpath;
+ char *tmp;
+ int n, i;
+ xmlNodePtr *nodes = NULL;
+
+ if (VIR_ALLOC(priv->monConfig) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (!(priv->monConfig->info.alias = strdup("monitor"))) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (!(monitorpath =
+ virXPathString("string(./monitor[1]/@path)", ctxt))) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("no monitor path"));
+ goto error;
+ }
+
+ tmp = virXPathString("string(./monitor[1]/@type)", ctxt);
+ if (tmp)
+ priv->monConfig->type = virDomainChrTypeFromString(tmp);
+ else
+ priv->monConfig->type = VIR_DOMAIN_CHR_TYPE_PTY;
+ VIR_FREE(tmp);
+
+ if (virXPathBoolean("count(./monitor[@json = '1']) > 0", ctxt))
{
+ priv->monJSON = 1;
+ } else {
+ priv->monJSON = 0;
+ }
+
+ switch (priv->monConfig->type) {
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ priv->monConfig->data.file.path = monitorpath;
+ break;
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ priv->monConfig->data.nix.path = monitorpath;
+ break;
+ default:
+ VIR_FREE(monitorpath);
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unsupported monitor type '%s'"),
+ virDomainChrTypeToString(priv->monConfig->type));
+ goto error;
+ }
+
+ n = virXPathNodeSet("./vcpus/vcpu", ctxt, &nodes);
+ if (n < 0)
+ goto error;
+ if (n) {
+ priv->nvcpupids = n;
+ if (VIR_REALLOC_N(priv->vcpupids, priv->nvcpupids) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ for (i = 0 ; i < n ; i++) {
+ char *pidstr = virXMLPropString(nodes[i], "pid");
+ if (!pidstr)
+ goto error;
+
+ if (virStrToLong_i(pidstr, NULL, 10, &(priv->vcpupids[i])) < 0) {
+ VIR_FREE(pidstr);
+ goto error;
+ }
+ VIR_FREE(pidstr);
+ }
+ VIR_FREE(nodes);
+ }
+
+ return 0;
+
+error:
+ virDomainChrDefFree(priv->monConfig);
+ priv->monConfig = NULL;
+ VIR_FREE(nodes);
+ return -1;
+}
+
+
+static void
+qemuDomainDefNamespaceFree(void *nsdata)
+{
+ qemuDomainCmdlineDefPtr cmd = nsdata;
+ unsigned int i;
+
+ if (!cmd)
+ return;
+
+ for (i = 0; i < cmd->num_args; i++)
+ VIR_FREE(cmd->args[i]);
+ for (i = 0; i < cmd->num_env; i++) {
+ VIR_FREE(cmd->env_name[i]);
+ VIR_FREE(cmd->env_value[i]);
+ }
+ VIR_FREE(cmd->args);
+ VIR_FREE(cmd->env_name);
+ VIR_FREE(cmd->env_value);
+ VIR_FREE(cmd);
+}
+
+static int
+qemuDomainDefNamespaceParse(xmlDocPtr xml,
+ xmlNodePtr root,
+ xmlXPathContextPtr ctxt,
+ void **data)
+{
+ qemuDomainCmdlineDefPtr cmd = NULL;
+ xmlNsPtr ns;
+ xmlNodePtr *nodes = NULL;
+ int n, i;
+
+ ns = xmlSearchNs(xml, root, BAD_CAST "qemu");
+ if (!ns)
+ /* this is fine; it just means there was no qemu namespace listed */
+ return 0;
+
+ if (STRNEQ((const char *)ns->href, QEMU_NAMESPACE_HREF)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Found namespace '%s' doesn't match expected
'%s'"),
+ ns->href, QEMU_NAMESPACE_HREF);
+ return -1;
+ }
+
+ if (xmlXPathRegisterNs(ctxt, ns->prefix, ns->href) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to register xml namespace '%s'"),
ns->href);
+ return -1;
+ }
+
+ if (VIR_ALLOC(cmd) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ /* first handle the extra command-line arguments */
+ n = virXPathNodeSet("./qemu:commandline/qemu:arg", ctxt, &nodes);
+ if (n < 0)
+ /* virXPathNodeSet already set the error */
+ goto error;
+
+ if (n && VIR_ALLOC_N(cmd->args, n) < 0)
+ goto no_memory;
+
+ for (i = 0; i < n; i++) {
+ cmd->args[cmd->num_args] = virXMLPropString(nodes[i], "value");
+ if (cmd->args[cmd->num_args] == NULL) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("No qemu command-line argument
specified"));
+ goto error;
+ }
+ cmd->num_args++;
+ }
+
+ VIR_FREE(nodes);
+
+ /* now handle the extra environment variables */
+ n = virXPathNodeSet("./qemu:commandline/qemu:env", ctxt, &nodes);
+ if (n < 0)
+ /* virXPathNodeSet already set the error */
+ goto error;
+
+ if (n && VIR_ALLOC_N(cmd->env_name, n) < 0)
+ goto no_memory;
+
+ if (n && VIR_ALLOC_N(cmd->env_value, n) < 0)
+ goto no_memory;
+
+ for (i = 0; i < n; i++) {
+ char *tmp;
+
+ tmp = virXMLPropString(nodes[i], "name");
+ if (tmp == NULL) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("No qemu environment name
specified"));
+ goto error;
+ }
+ if (tmp[0] == '\0') {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Empty qemu environment name
specified"));
+ goto error;
+ }
+ if (!c_isalpha(tmp[0]) && tmp[0] != '_') {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid environment name, it must
begin with a letter or underscore"));
+ goto error;
+ }
+ if (strspn(tmp,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_") !=
strlen(tmp)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid environment name, it must
contain only alphanumerics and underscore"));
+ goto error;
+ }
+
+ cmd->env_name[cmd->num_env] = tmp;
+
+ cmd->env_value[cmd->num_env] = virXMLPropString(nodes[i],
"value");
+ /* a NULL value for command is allowed, since it might be empty */
+ cmd->num_env++;
+ }
+
+ VIR_FREE(nodes);
+
+ *data = cmd;
+
+ return 0;
+
+no_memory:
+ virReportOOMError();
+
+error:
+ VIR_FREE(nodes);
+ qemuDomainDefNamespaceFree(cmd);
+ return -1;
+}
+
+static int
+qemuDomainDefNamespaceFormatXML(virBufferPtr buf,
+ void *nsdata)
+{
+ qemuDomainCmdlineDefPtr cmd = nsdata;
+ unsigned int i;
+
+ if (!cmd->num_args && !cmd->num_env)
+ return 0;
+
+ virBufferAddLit(buf, " <qemu:commandline>\n");
+ for (i = 0; i < cmd->num_args; i++)
+ virBufferEscapeString(buf, " <qemu:arg
value='%s'/>\n",
+ cmd->args[i]);
+ for (i = 0; i < cmd->num_env; i++) {
+ virBufferVSprintf(buf, " <qemu:env name='%s'",
cmd->env_name[i]);
+ if (cmd->env_value[i])
+ virBufferEscapeString(buf, " value='%s'",
cmd->env_value[i]);
+ virBufferAddLit(buf, "/>\n");
+ }
+ virBufferAddLit(buf, " </qemu:commandline>\n");
+
+ return 0;
+}
+
+static const char *
+qemuDomainDefNamespaceHref(void)
+{
+ return "xmlns:qemu='" QEMU_NAMESPACE_HREF "'";
+}
+
+
+void qemuDomainSetPrivateDataHooks(virCapsPtr caps)
+{
+ /* Domain XML parser hooks */
+ caps->privateDataAllocFunc = qemuDomainObjPrivateAlloc;
+ caps->privateDataFreeFunc = qemuDomainObjPrivateFree;
+ caps->privateDataXMLFormat = qemuDomainObjPrivateXMLFormat;
+ caps->privateDataXMLParse = qemuDomainObjPrivateXMLParse;
+
+}
+
+void qemuDomainSetNamespaceHooks(virCapsPtr caps)
+{
+ /* Domain Namespace XML parser hooks */
+ caps->ns.parse = qemuDomainDefNamespaceParse;
+ caps->ns.free = qemuDomainDefNamespaceFree;
+ caps->ns.format = qemuDomainDefNamespaceFormatXML;
+ caps->ns.href = qemuDomainDefNamespaceHref;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
new file mode 100644
index 0000000..0d1e222
--- /dev/null
+++ b/src/qemu/qemu_domain.h
@@ -0,0 +1,83 @@
+/*
+ * qemu_domain.h: QEMU domain private state
+ *
+ * Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __QEMU_DOMAIN_H__
+# define __QEMU_DOMAIN_H__
+
+# include "threads.h"
+# include "domain_conf.h"
+# include "qemu_monitor.h"
+
+/* Only 1 job is allowed at any time
+ * A job includes *all* monitor commands, even those just querying
+ * information, not merely actions */
+enum qemuDomainJob {
+ QEMU_JOB_NONE = 0, /* Always set to 0 for easy if (jobActive) conditions */
+ QEMU_JOB_UNSPECIFIED,
+ QEMU_JOB_MIGRATION_OUT,
+ QEMU_JOB_MIGRATION_IN,
+ QEMU_JOB_SAVE,
+ QEMU_JOB_DUMP,
+};
+
+enum qemuDomainJobSignals {
+ QEMU_JOB_SIGNAL_CANCEL = 1 << 0, /* Request job cancellation */
+ QEMU_JOB_SIGNAL_SUSPEND = 1 << 1, /* Request VM suspend to finish live
migration offline */
+ QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME = 1 << 2, /* Request migration downtime change
*/
+};
+
+struct qemuDomainJobSignalsData {
+ unsigned long long migrateDowntime; /* Data for QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME */
+};
+
+typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
+typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
+
+typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
+typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
+struct _qemuDomainObjPrivate {
+ virCond jobCond; /* Use in conjunction with main virDomainObjPtr lock */
+ enum qemuDomainJob jobActive; /* Currently running job */
+ unsigned int jobSignals; /* Signals for running job */
+ struct qemuDomainJobSignalsData jobSignalsData; /* Signal specific data */
+ virDomainJobInfo jobInfo;
+ unsigned long long jobStart;
+
+ qemuMonitorPtr mon;
+ virDomainChrDefPtr monConfig;
+ int monJSON;
+ int monitor_warned;
+ bool gotShutdown;
+
+ int nvcpupids;
+ int *vcpupids;
+
+ qemuDomainPCIAddressSetPtr pciaddrs;
+ int persistentAddrs;
+};
+
+
+void qemuDomainSetPrivateDataHooks(virCapsPtr caps);
+void qemuDomainSetNamespaceHooks(virCapsPtr caps);
+
+#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0489a7a..9ce8fbe 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -47,7 +47,6 @@
#include <sys/ioctl.h>
#include <sys/un.h>
-#include <libxml/xpathInternals.h>
#include "virterror_internal.h"
#include "logging.h"
@@ -96,7 +95,6 @@
#define QEMU_NB_MEM_PARAM 3
-#define QEMU_NAMESPACE_HREF "http://libvirt.org/schemas/domain/qemu/1.0"
#define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000))
@@ -158,158 +156,6 @@ static int qemudVMFiltersInstantiate(virConnectPtr conn,
static struct qemud_driver *qemu_driver = NULL;
-static void *qemuDomainObjPrivateAlloc(void)
-{
- qemuDomainObjPrivatePtr priv;
-
- if (VIR_ALLOC(priv) < 0)
- return NULL;
-
- return priv;
-}
-
-static void qemuDomainObjPrivateFree(void *data)
-{
- qemuDomainObjPrivatePtr priv = data;
-
- qemuDomainPCIAddressSetFree(priv->pciaddrs);
- virDomainChrDefFree(priv->monConfig);
- VIR_FREE(priv->vcpupids);
-
- /* This should never be non-NULL if we get here, but just in case... */
- if (priv->mon) {
- VIR_ERROR0(_("Unexpected QEMU monitor still active during domain
deletion"));
- qemuMonitorClose(priv->mon);
- }
- VIR_FREE(priv);
-}
-
-
-static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data)
-{
- qemuDomainObjPrivatePtr priv = data;
- const char *monitorpath;
-
- /* priv->monitor_chr is set only for qemu */
- if (priv->monConfig) {
- switch (priv->monConfig->type) {
- case VIR_DOMAIN_CHR_TYPE_UNIX:
- monitorpath = priv->monConfig->data.nix.path;
- break;
- default:
- case VIR_DOMAIN_CHR_TYPE_PTY:
- monitorpath = priv->monConfig->data.file.path;
- break;
- }
-
- virBufferEscapeString(buf, " <monitor path='%s'",
monitorpath);
- if (priv->monJSON)
- virBufferAddLit(buf, " json='1'");
- virBufferVSprintf(buf, " type='%s'/>\n",
- virDomainChrTypeToString(priv->monConfig->type));
- }
-
-
- if (priv->nvcpupids) {
- int i;
- virBufferAddLit(buf, " <vcpus>\n");
- for (i = 0 ; i < priv->nvcpupids ; i++) {
- virBufferVSprintf(buf, " <vcpu pid='%d'/>\n",
priv->vcpupids[i]);
- }
- virBufferAddLit(buf, " </vcpus>\n");
- }
-
- return 0;
-}
-
-static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
-{
- qemuDomainObjPrivatePtr priv = data;
- char *monitorpath;
- char *tmp;
- int n, i;
- xmlNodePtr *nodes = NULL;
-
- if (VIR_ALLOC(priv->monConfig) < 0) {
- virReportOOMError();
- goto error;
- }
-
- if (!(priv->monConfig->info.alias = strdup("monitor"))) {
- virReportOOMError();
- goto error;
- }
-
- if (!(monitorpath =
- virXPathString("string(./monitor[1]/@path)", ctxt))) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("no monitor path"));
- goto error;
- }
-
- tmp = virXPathString("string(./monitor[1]/@type)", ctxt);
- if (tmp)
- priv->monConfig->type = virDomainChrTypeFromString(tmp);
- else
- priv->monConfig->type = VIR_DOMAIN_CHR_TYPE_PTY;
- VIR_FREE(tmp);
-
- if (virXPathBoolean("count(./monitor[@json = '1']) > 0", ctxt))
{
- priv->monJSON = 1;
- } else {
- priv->monJSON = 0;
- }
-
- switch (priv->monConfig->type) {
- case VIR_DOMAIN_CHR_TYPE_PTY:
- priv->monConfig->data.file.path = monitorpath;
- break;
- case VIR_DOMAIN_CHR_TYPE_UNIX:
- priv->monConfig->data.nix.path = monitorpath;
- break;
- default:
- VIR_FREE(monitorpath);
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("unsupported monitor type '%s'"),
- virDomainChrTypeToString(priv->monConfig->type));
- goto error;
- }
-
- n = virXPathNodeSet("./vcpus/vcpu", ctxt, &nodes);
- if (n < 0)
- goto error;
- if (n) {
- priv->nvcpupids = n;
- if (VIR_REALLOC_N(priv->vcpupids, priv->nvcpupids) < 0) {
- virReportOOMError();
- goto error;
- }
-
- for (i = 0 ; i < n ; i++) {
- char *pidstr = virXMLPropString(nodes[i], "pid");
- if (!pidstr)
- goto error;
-
- if (virStrToLong_i(pidstr, NULL, 10, &(priv->vcpupids[i])) < 0) {
- VIR_FREE(pidstr);
- goto error;
- }
- VIR_FREE(pidstr);
- }
- VIR_FREE(nodes);
- }
-
- return 0;
-
-error:
- virDomainChrDefFree(priv->monConfig);
- priv->monConfig = NULL;
- VIR_FREE(nodes);
- return -1;
-}
-
-
-
/*
* obj must be locked before calling, qemud_driver must NOT be locked
*
@@ -567,168 +413,6 @@ static int doStopCPUs(struct qemud_driver *driver, virDomainObjPtr
vm)
return ret;
}
-void qemuDomainDefNamespaceFree(void *nsdata)
-{
- qemuDomainCmdlineDefPtr cmd = nsdata;
- unsigned int i;
-
- if (!cmd)
- return;
-
- for (i = 0; i < cmd->num_args; i++)
- VIR_FREE(cmd->args[i]);
- for (i = 0; i < cmd->num_env; i++) {
- VIR_FREE(cmd->env_name[i]);
- VIR_FREE(cmd->env_value[i]);
- }
- VIR_FREE(cmd->args);
- VIR_FREE(cmd->env_name);
- VIR_FREE(cmd->env_value);
- VIR_FREE(cmd);
-}
-
-int qemuDomainDefNamespaceParse(xmlDocPtr xml,
- xmlNodePtr root,
- xmlXPathContextPtr ctxt,
- void **data)
-{
- qemuDomainCmdlineDefPtr cmd = NULL;
- xmlNsPtr ns;
- xmlNodePtr *nodes = NULL;
- int n, i;
-
- ns = xmlSearchNs(xml, root, BAD_CAST "qemu");
- if (!ns)
- /* this is fine; it just means there was no qemu namespace listed */
- return 0;
-
- if (STRNEQ((const char *)ns->href, QEMU_NAMESPACE_HREF)) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("Found namespace '%s' doesn't match expected
'%s'"),
- ns->href, QEMU_NAMESPACE_HREF);
- return -1;
- }
-
- if (xmlXPathRegisterNs(ctxt, ns->prefix, ns->href) < 0) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("Failed to register xml namespace '%s'"),
ns->href);
- return -1;
- }
-
- if (VIR_ALLOC(cmd) < 0) {
- virReportOOMError();
- return -1;
- }
-
- /* first handle the extra command-line arguments */
- n = virXPathNodeSet("./qemu:commandline/qemu:arg", ctxt, &nodes);
- if (n < 0)
- /* virXPathNodeSet already set the error */
- goto error;
-
- if (n && VIR_ALLOC_N(cmd->args, n) < 0)
- goto no_memory;
-
- for (i = 0; i < n; i++) {
- cmd->args[cmd->num_args] = virXMLPropString(nodes[i], "value");
- if (cmd->args[cmd->num_args] == NULL) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("No qemu command-line argument
specified"));
- goto error;
- }
- cmd->num_args++;
- }
-
- VIR_FREE(nodes);
-
- /* now handle the extra environment variables */
- n = virXPathNodeSet("./qemu:commandline/qemu:env", ctxt, &nodes);
- if (n < 0)
- /* virXPathNodeSet already set the error */
- goto error;
-
- if (n && VIR_ALLOC_N(cmd->env_name, n) < 0)
- goto no_memory;
-
- if (n && VIR_ALLOC_N(cmd->env_value, n) < 0)
- goto no_memory;
-
- for (i = 0; i < n; i++) {
- char *tmp;
-
- tmp = virXMLPropString(nodes[i], "name");
- if (tmp == NULL) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("No qemu environment name
specified"));
- goto error;
- }
- if (tmp[0] == '\0') {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Empty qemu environment name
specified"));
- goto error;
- }
- if (!c_isalpha(tmp[0]) && tmp[0] != '_') {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid environment name, it must
begin with a letter or underscore"));
- goto error;
- }
- if (strspn(tmp,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_") !=
strlen(tmp)) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid environment name, it must
contain only alphanumerics and underscore"));
- goto error;
- }
-
- cmd->env_name[cmd->num_env] = tmp;
-
- cmd->env_value[cmd->num_env] = virXMLPropString(nodes[i],
"value");
- /* a NULL value for command is allowed, since it might be empty */
- cmd->num_env++;
- }
-
- VIR_FREE(nodes);
-
- *data = cmd;
-
- return 0;
-
-no_memory:
- virReportOOMError();
-
-error:
- VIR_FREE(nodes);
- qemuDomainDefNamespaceFree(cmd);
- return -1;
-}
-
-int qemuDomainDefNamespaceFormatXML(virBufferPtr buf,
- void *nsdata)
-{
- qemuDomainCmdlineDefPtr cmd = nsdata;
- unsigned int i;
-
- if (!cmd->num_args && !cmd->num_env)
- return 0;
-
- virBufferAddLit(buf, " <qemu:commandline>\n");
- for (i = 0; i < cmd->num_args; i++)
- virBufferEscapeString(buf, " <qemu:arg
value='%s'/>\n",
- cmd->args[i]);
- for (i = 0; i < cmd->num_env; i++) {
- virBufferVSprintf(buf, " <qemu:env name='%s'",
cmd->env_name[i]);
- if (cmd->env_value[i])
- virBufferEscapeString(buf, " value='%s'",
cmd->env_value[i]);
- virBufferAddLit(buf, "/>\n");
- }
- virBufferAddLit(buf, " </qemu:commandline>\n");
-
- return 0;
-}
-
-const char *qemuDomainDefNamespaceHref(void)
-{
- return "xmlns:qemu='" QEMU_NAMESPACE_HREF "'";
-}
-
static int qemuCgroupControllerActive(struct qemud_driver *driver,
int controller)
{
@@ -1614,11 +1298,8 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
caps->defaultDiskDriverType = "raw";
}
- /* Domain XML parser hooks */
- caps->privateDataAllocFunc = qemuDomainObjPrivateAlloc;
- caps->privateDataFreeFunc = qemuDomainObjPrivateFree;
- caps->privateDataXMLFormat = qemuDomainObjPrivateXMLFormat;
- caps->privateDataXMLParse = qemuDomainObjPrivateXMLParse;
+ qemuDomainSetPrivateDataHooks(caps);
+ qemuDomainSetNamespaceHooks(caps);
if (virGetHostUUID(caps->host.host_uuid)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1626,12 +1307,6 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
goto err_exit;
}
- /* Domain Namespace XML parser hooks */
- caps->ns.parse = qemuDomainDefNamespaceParse;
- caps->ns.free = qemuDomainDefNamespaceFree;
- caps->ns.format = qemuDomainDefNamespaceFormatXML;
- caps->ns.href = qemuDomainDefNamespaceHref;
-
/* Security driver data */
if (driver->securityPrimaryDriver) {
const char *doi, *model;
diff --git a/src/qemu/qemu_driver.h b/src/qemu/qemu_driver.h
index 60131a7..dac0935 100644
--- a/src/qemu/qemu_driver.h
+++ b/src/qemu/qemu_driver.h
@@ -51,13 +51,4 @@
int qemuRegister(void);
-void qemuDomainDefNamespaceFree(void *nsdata);
-int qemuDomainDefNamespaceParse(xmlDocPtr xml,
- xmlNodePtr root,
- xmlXPathContextPtr ctxt,
- void **data);
-int qemuDomainDefNamespaceFormatXML(virBufferPtr buf,
- void *nsdata);
-const char *qemuDomainDefNamespaceHref(void);
-
#endif /* QEMUD_DRIVER_H */
--
1.7.2.3