[libvirt] [PATCH 04/10] Move QEMU private data & namespace code into separate file

Daniel P. Berrange berrange at redhat.com
Thu Dec 16 16:50:04 UTC 2010


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 at 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 at 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




More information about the libvir-list mailing list