]> xenbits.xensource.com Git - libvirt.git/commitdiff
Basic domain XML conversions for Xen/QEMU drivers
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 21 May 2009 14:14:01 +0000 (14:14 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 21 May 2009 14:14:01 +0000 (14:14 +0000)
ChangeLog
src/qemu_conf.c
src/qemu_conf.h
src/qemu_driver.c
src/xen_unified.c
src/xen_unified.h

index fc31a9fc1cb136da5ebfc9460bcaa1834dfb95cf..72b6b93dc41c8c6d65f7af555184290807734091 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Thu May 21 14:59:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+
+       Basic domain XML conversions
+       * src/qemu_conf.c, src/qemu_conf.h, src/qemu_driver.c: Wire up
+       API for conversion from XML to native argv
+       * src/xen_unified.c, src/xen_unified.h: Wire up API for domain
+       XML conversions to & from native
+
 Thu May 21 14:48:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
 
        Remote protocol support for domain XML conversion APIs
index bfaab33c8c23e52678c246beb8fbd715e923e999..d7b5d3258bc25d5c0f3f89a13c205e3a90d29087 100644 (file)
@@ -1251,21 +1251,18 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
             case VIR_DOMAIN_NET_TYPE_ETHERNET:
                 {
-                    char arg[PATH_MAX];
-                    if (net->ifname) {
-                        if (snprintf(arg, PATH_MAX-1, "tap,ifname=%s,script=%s,vlan=%d",
-                                     net->ifname,
-                                     net->data.ethernet.script,
-                                     vlan) >= (PATH_MAX-1))
-                            goto error;
-                    } else {
-                        if (snprintf(arg, PATH_MAX-1, "tap,script=%s,vlan=%d",
-                                     net->data.ethernet.script,
-                                     vlan) >= (PATH_MAX-1))
-                            goto error;
-                    }
+                    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+                    virBufferAddLit(&buf, "tap");
+                    if (net->ifname)
+                        virBufferVSprintf(&buf, ",ifname=%s", net->ifname);
+                    if (net->data.ethernet.script)
+                        virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
+                    virBufferVSprintf(&buf, ",vlan=%d", vlan);
+                    if (virBufferError(&buf))
+                        goto error;
 
-                    ADD_ARG_LIT(arg);
+                    ADD_ARG(virBufferContentAndReset(&buf));
                 }
                 break;
 
index c6dc9dfba96be2aeef75f544fd20aa4ab2ce787b..d7e262e082d0af7696ea83c89d3b0a270b45a08b 100644 (file)
@@ -106,6 +106,9 @@ struct _qemudDomainStatus {
 #define QEMUD_MIGRATION_FIRST_PORT 49152
 #define QEMUD_MIGRATION_NUM_PORTS 64
 
+/* Config type for XML import/export conversions */
+#define QEMU_CONFIG_FORMAT_ARGV "qemu-argv"
+
 #define qemudReportError(conn, dom, net, code, fmt...)                       \
         virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__,          \
                                __FUNCTION__, __LINE__, fmt)
index 2cac1bf08f47981051964e87c2d72a70d3507a1e..c2b4c1ab5ce9a2039d9cc28f40bf1daf16bd70be 100644 (file)
@@ -3422,6 +3422,133 @@ cleanup:
 }
 
 
+static char *qemuDomainXMLToNative(virConnectPtr conn,
+                                   const char *format,
+                                   const char *xmlData,
+                                   unsigned int flags ATTRIBUTE_UNUSED) {
+    struct qemud_driver *driver = conn->privateData;
+    virDomainDefPtr def = NULL;
+    const char *emulator;
+    unsigned int qemuCmdFlags;
+    struct stat sb;
+    const char **retargv = NULL;
+    const char **retenv = NULL;
+    const char **tmp;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    char *ret = NULL;
+    int i;
+
+    if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_ARG,
+                         _("unsupported config type %s"), format);
+        goto cleanup;
+    }
+
+    def = virDomainDefParseString(conn, driver->caps, xmlData, 0);
+    if (!def)
+        goto cleanup;
+
+    /* Since we're just exporting args, we can't do bridge/network
+     * setups, since libvirt will normally create TAP devices
+     * directly. We convert those configs into generic 'ethernet'
+     * config and assume the user has suitable 'ifup-qemu' scripts
+     */
+    for (i = 0 ; i < def->nnets ; i++) {
+        virDomainNetDefPtr net = def->nets[i];
+        if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+            VIR_FREE(net->data.network.name);
+
+            memset(net, 0, sizeof *net);
+
+            net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
+            net->data.ethernet.dev = NULL;
+            net->data.ethernet.script = NULL;
+            net->data.ethernet.ipaddr = NULL;
+        } else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+            char *brname = net->data.bridge.brname;
+            char *script = net->data.bridge.script;
+            char *ipaddr = net->data.bridge.ipaddr;
+
+            memset(net, 0, sizeof *net);
+
+            net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
+            net->data.ethernet.dev = brname;
+            net->data.ethernet.script = script;
+            net->data.ethernet.ipaddr = ipaddr;
+        }
+    }
+    for (i = 0 ; i < def->ngraphics ; i++) {
+        if (def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+            def->graphics[i]->data.vnc.autoport)
+            def->graphics[i]->data.vnc.port = 5900;
+    }
+    emulator = def->emulator;
+    if (!emulator)
+        emulator = virDomainDefDefaultEmulator(conn, def, driver->caps);
+    if (!emulator)
+        goto cleanup;
+
+    /* Make sure the binary we are about to try exec'ing exists.
+     * Technically we could catch the exec() failure, but that's
+     * in a sub-process so its hard to feed back a useful error
+     */
+    if (stat(emulator, &sb) < 0) {
+        virReportSystemError(conn, errno,
+                             _("Cannot find QEMU binary %s"),
+                             emulator);
+        goto cleanup;
+    }
+
+    if (qemudExtractVersionInfo(emulator,
+                                NULL,
+                                &qemuCmdFlags) < 0) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("Cannot determine QEMU argv syntax %s"),
+                         emulator);
+        goto cleanup;
+    }
+
+
+    if (qemudBuildCommandLine(conn, driver, def,
+                              qemuCmdFlags,
+                              &retargv, &retenv,
+                              NULL, NULL, /* Don't want it to create TAP devices */
+                              NULL) < 0) {
+        goto cleanup;
+    }
+
+    tmp = retenv;
+    while (*tmp) {
+        virBufferAdd(&buf, *tmp, strlen(*tmp));
+        virBufferAddLit(&buf, " ");
+        tmp++;
+    }
+    tmp = retargv;
+    while (*tmp) {
+        virBufferAdd(&buf, *tmp, strlen(*tmp));
+        virBufferAddLit(&buf, " ");
+        tmp++;
+    }
+
+    if (virBufferError(&buf))
+        goto cleanup;
+
+    ret = virBufferContentAndReset(&buf);
+
+cleanup:
+    for (tmp = retargv ; tmp && *tmp ; tmp++)
+        VIR_FREE(*tmp);
+    VIR_FREE(retargv);
+
+    for (tmp = retenv ; tmp && *tmp ; tmp++)
+        VIR_FREE(*tmp);
+    VIR_FREE(retenv);
+
+    virDomainDefFree(def);
+    return ret;
+}
+
+
 static int qemudListDefinedDomains(virConnectPtr conn,
                             char **const names, int nnames) {
     struct qemud_driver *driver = conn->privateData;
@@ -5225,7 +5352,7 @@ static virDriver qemuDriver = {
     qemudNodeGetSecurityModel, /* nodeGetSecurityModel */
     qemudDomainDumpXML, /* domainDumpXML */
     NULL, /* domainXmlFromNative */
-    NULL, /* domainXmlToNative */
+    qemuDomainXMLToNative, /* domainXMLToNative */
     qemudListDefinedDomains, /* listDefinedDomains */
     qemudNumDefinedDomains, /* numOfDefinedDomains */
     qemudDomainStart, /* domainCreate */
index bd363ffe3b4aac9f9c0f06c20c6efeff58673b9f..7ff23b821692c8b22cacfd6f62f06fd3d440d065 100644 (file)
@@ -1043,6 +1043,97 @@ xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
     return NULL;
 }
 
+
+static char *
+xenUnifiedDomainXMLFromNative(virConnectPtr conn,
+                              const char *format,
+                              const char *config,
+                              unsigned int flags ATTRIBUTE_UNUSED)
+{
+    virDomainDefPtr def = NULL;
+    char *ret = NULL;
+    virConfPtr conf = NULL;
+    GET_PRIVATE(conn);
+
+    if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
+        STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+        xenUnifiedError(conn, VIR_ERR_INVALID_ARG,
+                        _("unsupported config type %s"), format);
+        return NULL;
+    }
+
+    if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
+        conf = virConfReadMem(config, strlen(config));
+        if (!conf)
+            goto cleanup;
+
+        def = xenXMDomainConfigParse(conn, conf);
+    } else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+        def = xenDaemonParseSxprString(conn, config, priv->xendConfigVersion);
+    }
+    if (!def)
+        goto cleanup;
+
+    ret = virDomainDefFormat(conn, def, 0);
+
+cleanup:
+    virDomainDefFree(def);
+    return ret;
+}
+
+
+#define MAX_CONFIG_SIZE (1024 * 65)
+static char *
+xenUnifiedDomainXMLToNative(virConnectPtr conn,
+                            const char *format,
+                            const char *xmlData,
+                            unsigned int flags ATTRIBUTE_UNUSED)
+{
+    virDomainDefPtr def = NULL;
+    char *ret = NULL;
+    virConfPtr conf = NULL;
+    GET_PRIVATE(conn);
+
+    if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
+        STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+        xenUnifiedError(conn, VIR_ERR_INVALID_ARG,
+                        _("unsupported config type %s"), format);
+        goto cleanup;
+    }
+
+    if (!(def = virDomainDefParseString(conn,
+                                        priv->caps,
+                                        xmlData,
+                                        0)))
+        goto cleanup;
+
+    if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
+        int len = MAX_CONFIG_SIZE;
+        conf = xenXMDomainConfigFormat(conn, def);
+        if (!conf)
+            goto cleanup;
+
+        if (VIR_ALLOC_N(ret, len) < 0) {
+            virReportOOMError(conn);
+            goto cleanup;
+        }
+
+        if (virConfWriteMem(ret, &len, conf) < 0) {
+            VIR_FREE(ret);
+            goto cleanup;
+        }
+    } else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+        ret = xenDaemonFormatSxpr(conn, def, priv->xendConfigVersion);
+    }
+
+cleanup:
+    virDomainDefFree(def);
+    if (conf)
+        virConfFree(conf);
+    return ret;
+}
+
+
 static int
 xenUnifiedDomainMigratePrepare (virConnectPtr dconn,
                                 char **cookie,
@@ -1580,8 +1671,8 @@ static virDriver xenUnifiedDriver = {
     NULL, /* domainGetSecurityLabel */
     NULL, /* nodeGetSecurityModel */
     xenUnifiedDomainDumpXML, /* domainDumpXML */
-    NULL, /* domainXmlFromNative */
-    NULL, /* domainXmlToNative */
+    xenUnifiedDomainXMLFromNative, /* domainXmlFromNative */
+    xenUnifiedDomainXMLToNative, /* domainXmlToNative */
     xenUnifiedListDefinedDomains, /* listDefinedDomains */
     xenUnifiedNumOfDefinedDomains, /* numOfDefinedDomains */
     xenUnifiedDomainCreate, /* domainCreate */
index 6ec19c19ba756e1128ac4109e48c4765a9ca6955..9cc877b03a30ff2cb51c105374f1554619b1d3b6 100644 (file)
@@ -46,6 +46,9 @@ extern int xenRegister (void);
 
 #define MIN_XEN_GUEST_SIZE 64  /* 64 megabytes */
 
+#define XEN_CONFIG_FORMAT_XM    "xen-xm"
+#define XEN_CONFIG_FORMAT_SEXPR "xen-sxpr"
+
 /* _xenUnifiedDriver:
  *
  * Entry points into the underlying Xen drivers.  This structure