[libvirt] [PREPOST] src/xenconfig: XL parser

Kiarie Kahurani davidkiarie4 at gmail.com
Mon Aug 18 17:54:21 UTC 2014


Introduce the new xen-xl parser that {formats,parses} xl disk
and spice graphics format

Signed-off-by: Kiarie Kahurani <davidkiarie4 at gmail.com>
---
 po/POTFILES.in                                |   1 +
 src/Makefile.am                               |   3 +-
 src/libvirt_xenconfig.syms                    |   5 +
 src/libxl/libxl_driver.c                      |  44 ++-
 src/xenconfig/xen_common.c                    | 140 ++++----
 src/xenconfig/xen_common.h                    |  24 +-
 src/xenconfig/xen_xl.c                        | 461 ++++++++++++++++++++++++++
 src/xenconfig/xen_xl.h                        |  29 ++
 tests/Makefile.am                             |   9 +-
 tests/testutilsxen.c                          |  50 +++
 tests/testutilsxen.h                          |   9 +-
 tests/xlconfigdata/test-fullvirt-new-disk.cfg |  27 ++
 tests/xlconfigdata/test-fullvirt-new-disk.xml |  46 +++
 tests/xlconfigtest.c                          | 222 +++++++++++++
 14 files changed, 981 insertions(+), 89 deletions(-)
 create mode 100644 src/xenconfig/xen_xl.c
 create mode 100644 src/xenconfig/xen_xl.h
 create mode 100644 tests/xlconfigdata/test-fullvirt-new-disk.cfg
 create mode 100644 tests/xlconfigdata/test-fullvirt-new-disk.xml
 create mode 100644 tests/xlconfigtest.c

diff --git a/po/POTFILES.in b/po/POTFILES.in
index f17b35f..3ac31fe 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -234,6 +234,7 @@ src/xenapi/xenapi_driver.c
 src/xenapi/xenapi_utils.c
 src/xenconfig/xen_common.c
 src/xenconfig/xen_sxpr.c
+src/xenconfig/xen_xl.c
 src/xenconfig/xen_xm.c
 tools/libvirt-guests.sh.in
 tools/virsh.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 538530e..f0c05b3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -968,7 +968,8 @@ XENCONFIG_SOURCES =						\
 		xenconfig/xenxs_private.h			\
 		xenconfig/xen_common.c xenconfig/xen_common.h   \
 		xenconfig/xen_sxpr.c xenconfig/xen_sxpr.h	\
-		xenconfig/xen_xm.c xenconfig/xen_xm.h
+		xenconfig/xen_xm.c xenconfig/xen_xm.h   \
+		xenconfig/xen_xl.c xenconfig/xen_xl.h
 
 pkgdata_DATA =	cpu/cpu_map.xml
 
diff --git a/src/libvirt_xenconfig.syms b/src/libvirt_xenconfig.syms
index 6541685..efd7a00 100644
--- a/src/libvirt_xenconfig.syms
+++ b/src/libvirt_xenconfig.syms
@@ -16,10 +16,15 @@ xenParseSxprChar;
 xenParseSxprSound;
 xenParseSxprString;
 
+#xenconfig/xen_xl.h
+xenFormatXL;
+xenParseXL;
+
 # xenconfig/xen_xm.h
 xenFormatXM;
 xenParseXM;
 
+
 # Let emacs know we want case-insensitive sorting
 # Local Variables:
 # sort-fold-case: t
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 67fd7bc6..aa7d861 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -48,6 +48,7 @@
 #include "libxl_migration.h"
 #include "xen_xm.h"
 #include "xen_sxpr.h"
+#include "xen_xl.h"
 #include "virtypedparam.h"
 #include "viruri.h"
 #include "virstring.h"
@@ -67,6 +68,7 @@ VIR_LOG_INIT("libxl.libxl_driver");
 #define LIBXL_DOM_REQ_CRASH    3
 #define LIBXL_DOM_REQ_HALT     4
 
+#define LIBXL_CONFIG_FORMAT_XL "xen-xl"
 #define LIBXL_CONFIG_FORMAT_XM "xen-xm"
 #define LIBXL_CONFIG_FORMAT_SEXPR "xen-sxpr"
 
@@ -2217,7 +2219,17 @@ libxlConnectDomainXMLFromNative(virConnectPtr conn,
     if (virConnectDomainXMLFromNativeEnsureACL(conn) < 0)
         goto cleanup;
 
-    if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XM)) {
+    if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XL)) {
+        if (!(conf = virConfReadMem(nativeConfig, strlen(nativeConfig), 0)))
+            goto cleanup;
+        if (!(def = xenParseXL(conf,
+                               cfg->caps,
+                               cfg->verInfo->xen_version_major))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("parsing xl config failed"));
+            goto cleanup;
+        }
+    } else if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XM)) {
         if (!(conf = virConfReadMem(nativeConfig, strlen(nativeConfig), 0)))
             goto cleanup;
 
@@ -2272,21 +2284,31 @@ libxlConnectDomainXMLToNative(virConnectPtr conn, const char * nativeFormat,
     if (virConnectDomainXMLToNativeEnsureACL(conn) < 0)
         goto cleanup;
 
-    if (STRNEQ(nativeFormat, LIBXL_CONFIG_FORMAT_XM)) {
+    if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XL)) {
+        if (!(def = virDomainDefParseString(domainXml,
+                                            cfg->caps, driver->xmlopt,
+                                            1 << VIR_DOMAIN_VIRT_XEN,
+                                            VIR_DOMAIN_XML_INACTIVE)))
+            goto cleanup;
+
+        if (!(conf = xenFormatXL(def, conn, cfg->verInfo->xen_version_major)))
+            goto cleanup;
+    } else if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XM)) {
+        if (!(def = virDomainDefParseString(domainXml,
+                                            cfg->caps, driver->xmlopt,
+                                            1 << VIR_DOMAIN_VIRT_XEN,
+                                            VIR_DOMAIN_XML_INACTIVE)))
+            goto cleanup;
+
+        if (!(conf = xenFormatXM(conn, def, cfg->verInfo->xen_version_major)))
+            goto cleanup;
+    } else {
+
         virReportError(VIR_ERR_INVALID_ARG,
                        _("unsupported config type %s"), nativeFormat);
         goto cleanup;
     }
 
-    if (!(def = virDomainDefParseString(domainXml,
-                                        cfg->caps, driver->xmlopt,
-                                        1 << VIR_DOMAIN_VIRT_XEN,
-                                        VIR_DOMAIN_XML_INACTIVE)))
-        goto cleanup;
-
-    if (!(conf = xenFormatXM(conn, def, cfg->verInfo->xen_version_major)))
-        goto cleanup;
-
     if (VIR_ALLOC_N(ret, len) < 0)
         goto cleanup;
 
diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c
index 398e9ec..4666b8c 100644
--- a/src/xenconfig/xen_common.c
+++ b/src/xenconfig/xen_common.c
@@ -43,7 +43,7 @@
 /*
  * Convenience method to grab a long int from the config file object
  */
-static int
+int
 xenConfigGetBool(virConfPtr conf,
                  const char *name,
                  int *value,
@@ -73,7 +73,7 @@ xenConfigGetBool(virConfPtr conf,
 /*
  * Convenience method to grab a int from the config file object
  */
-static int
+int
 xenConfigGetULong(virConfPtr conf,
                   const char *name,
                   unsigned long *value,
@@ -179,7 +179,7 @@ xenConfigCopyString(virConfPtr conf, const char *name, char **value)
 }
 
 
-static int
+int
 xenConfigCopyStringOpt(virConfPtr conf, const char *name, char **value)
 {
     return xenConfigCopyStringInternal(conf, name, value, 1);
@@ -262,8 +262,8 @@ xenConfigGetString(virConfPtr conf,
 }
 
 
-static int
-xenXMConfigSetInt(virConfPtr conf, const char *setting, long long l)
+int
+xenConfigSetInt(virConfPtr conf, const char *setting, long long l)
 {
     virConfValuePtr value = NULL;
 
@@ -283,8 +283,8 @@ xenXMConfigSetInt(virConfPtr conf, const char *setting, long long l)
 }
 
 
-static int
-xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str)
+int
+xenConfigSetString(virConfPtr conf, const char *setting, const char *str)
 {
     virConfValuePtr value = NULL;
 
@@ -1387,11 +1387,11 @@ xenFormatGeneralMeta(virConfPtr conf, virDomainDefPtr def)
 {
     char uuid[VIR_UUID_STRING_BUFLEN];
 
-    if (xenXMConfigSetString(conf, "name", def->name) < 0)
+    if (xenConfigSetString(conf, "name", def->name) < 0)
         return -1;
 
     virUUIDFormat(def->uuid, uuid);
-    if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
+    if (xenConfigSetString(conf, "uuid", uuid) < 0)
         return -1;
 
     return 0;
@@ -1401,12 +1401,12 @@ xenFormatGeneralMeta(virConfPtr conf, virDomainDefPtr def)
 static int
 xenFormatMem(virConfPtr conf, virDomainDefPtr def)
 {
-    if (xenXMConfigSetInt(conf, "maxmem",
-                          VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
+    if (xenConfigSetInt(conf, "maxmem",
+                        VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
         return -1;
 
-    if (xenXMConfigSetInt(conf, "memory",
-                          VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
+    if (xenConfigSetInt(conf, "memory",
+                        VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
         return -1;
 
     return 0;
@@ -1468,7 +1468,7 @@ xenFormatTimeOffset(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion)
                                virDomainClockOffsetTypeToString(def->clock.offset));
                 return -1;
             }
-            if (xenXMConfigSetInt(conf, "rtc_timeoffset", rtc_timeoffset) < 0)
+            if (xenConfigSetInt(conf, "rtc_timeoffset", rtc_timeoffset) < 0)
                 return -1;
 
         } else {
@@ -1489,7 +1489,7 @@ xenFormatTimeOffset(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion)
         } /* !hvm */
     }
 
-    if (xenXMConfigSetInt(conf, "localtime", vmlocaltime) < 0)
+    if (xenConfigSetInt(conf, "localtime", vmlocaltime) < 0)
         return -1;
 
     return 0;
@@ -1506,7 +1506,7 @@ xenFormatEventActions(virConfPtr conf, virDomainDefPtr def)
                        _("unexpected lifecycle action %d"), def->onPoweroff);
         return -1;
     }
-    if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
+    if (xenConfigSetString(conf, "on_poweroff", lifecycle) < 0)
         return -1;
 
 
@@ -1515,7 +1515,7 @@ xenFormatEventActions(virConfPtr conf, virDomainDefPtr def)
                        _("unexpected lifecycle action %d"), def->onReboot);
         return -1;
     }
-    if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
+    if (xenConfigSetString(conf, "on_reboot", lifecycle) < 0)
         return -1;
 
 
@@ -1524,7 +1524,7 @@ xenFormatEventActions(virConfPtr conf, virDomainDefPtr def)
                        _("unexpected lifecycle action %d"), def->onCrash);
         return -1;
     }
-    if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
+    if (xenConfigSetString(conf, "on_crash", lifecycle) < 0)
         return -1;
 
     return 0;
@@ -1545,12 +1545,12 @@ xenFormatCharDev(virConfPtr conf, virDomainDefPtr def)
             ret = xenFormatSxprChr(def->parallels[0], &buf);
             str = virBufferContentAndReset(&buf);
             if (ret == 0)
-                ret = xenXMConfigSetString(conf, "parallel", str);
+                ret = xenConfigSetString(conf, "parallel", str);
             VIR_FREE(str);
             if (ret < 0)
                 return -1;
         } else {
-            if (xenXMConfigSetString(conf, "parallel", "none") < 0)
+            if (xenConfigSetString(conf, "parallel", "none") < 0)
                 return -1;
         }
 
@@ -1563,7 +1563,7 @@ xenFormatCharDev(virConfPtr conf, virDomainDefPtr def)
                 ret = xenFormatSxprChr(def->serials[0], &buf);
                 str = virBufferContentAndReset(&buf);
                 if (ret == 0)
-                    ret = xenXMConfigSetString(conf, "serial", str);
+                    ret = xenConfigSetString(conf, "serial", str);
                 VIR_FREE(str);
                 if (ret < 0)
                     return -1;
@@ -1608,7 +1608,7 @@ xenFormatCharDev(virConfPtr conf, virDomainDefPtr def)
                 VIR_FREE(serialVal);
             }
         } else {
-            if (xenXMConfigSetString(conf, "serial", "none") < 0)
+            if (xenConfigSetString(conf, "serial", "none") < 0)
                 return -1;
         }
     }
@@ -1623,13 +1623,13 @@ xenFormatCPUAllocation(virConfPtr conf, virDomainDefPtr def)
     int ret = -1;
     char *cpus = NULL;
 
-    if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
+    if (xenConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
         goto cleanup;
 
     /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
        either 32, or 64 on a platform where long is big enough.  */
     if (def->vcpus < def->maxvcpus &&
-        xenXMConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
+        xenConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
         goto cleanup;
 
     if ((def->cpumask != NULL) &&
@@ -1638,7 +1638,7 @@ xenFormatCPUAllocation(virConfPtr conf, virDomainDefPtr def)
     }
 
     if (cpus &&
-        xenXMConfigSetString(conf, "cpus", cpus) < 0)
+        xenConfigSetString(conf, "cpus", cpus) < 0)
         goto cleanup;
 
     ret = 0;
@@ -1655,37 +1655,37 @@ xenFormatCPUFeatures(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion
     size_t i;
 
     if (STREQ(def->os.type, "hvm")) {
-        if (xenXMConfigSetInt(conf, "pae",
-                              (def->features[VIR_DOMAIN_FEATURE_PAE] ==
-                               VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
+        if (xenConfigSetInt(conf, "pae",
+                            (def->features[VIR_DOMAIN_FEATURE_PAE] ==
+                            VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
             return -1;
 
-        if (xenXMConfigSetInt(conf, "acpi",
-                              (def->features[VIR_DOMAIN_FEATURE_ACPI] ==
-                               VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
+        if (xenConfigSetInt(conf, "acpi",
+                            (def->features[VIR_DOMAIN_FEATURE_ACPI] ==
+                            VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
             return -1;
 
-        if (xenXMConfigSetInt(conf, "apic",
-                              (def->features[VIR_DOMAIN_FEATURE_APIC] ==
-                               VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
+        if (xenConfigSetInt(conf, "apic",
+                            (def->features[VIR_DOMAIN_FEATURE_APIC] ==
+                            VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
             return -1;
 
         if (xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4) {
-            if (xenXMConfigSetInt(conf, "hap",
-                                  (def->features[VIR_DOMAIN_FEATURE_HAP] ==
-                                   VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
+            if (xenConfigSetInt(conf, "hap",
+                                (def->features[VIR_DOMAIN_FEATURE_HAP] ==
+                                VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
                 return -1;
 
-            if (xenXMConfigSetInt(conf, "viridian",
-                                  (def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] ==
-                                   VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
+            if (xenConfigSetInt(conf, "viridian",
+                                (def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] ==
+                                VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
                 return -1;
         }
 
         for (i = 0; i < def->clock.ntimers; i++) {
             if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_HPET &&
                 def->clock.timers[i]->present != -1 &&
-                xenXMConfigSetInt(conf, "hpet", def->clock.timers[i]->present) < 0)
+                xenConfigSetInt(conf, "hpet", def->clock.timers[i]->present) < 0)
                 return -1;
         }
     }
@@ -1698,7 +1698,7 @@ static int
 xenFormatEmulator(virConfPtr conf, virDomainDefPtr def)
 {
     if (def->emulator &&
-        xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
+        xenConfigSetString(conf, "device_model", def->emulator) < 0)
         return -1;
 
     return 0;
@@ -1717,7 +1717,7 @@ xenFormatCDROM(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion)
                     def->disks[i]->dst &&
                     STREQ(def->disks[i]->dst, "hdc") &&
                     virDomainDiskGetSource(def->disks[i])) {
-                    if (xenXMConfigSetString(conf, "cdrom",
+                    if (xenConfigSetString(conf, "cdrom",
                                              virDomainDiskGetSource(def->disks[i])) < 0)
                         return -1;
                     break;
@@ -1737,11 +1737,11 @@ xenFormatOS(virConfPtr conf, virDomainDefPtr def)
 
     if (STREQ(def->os.type, "hvm")) {
         char boot[VIR_DOMAIN_BOOT_LAST+1];
-        if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
+        if (xenConfigSetString(conf, "builder", "hvm") < 0)
             return -1;
 
         if (def->os.loader &&
-            xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
+            xenConfigSetString(conf, "kernel", def->os.loader) < 0)
             return -1;
 
         for (i = 0; i < def->os.nBootDevs; i++) {
@@ -1769,29 +1769,29 @@ xenFormatOS(virConfPtr conf, virDomainDefPtr def)
             boot[def->os.nBootDevs] = '\0';
         }
 
-        if (xenXMConfigSetString(conf, "boot", boot) < 0)
+        if (xenConfigSetString(conf, "boot", boot) < 0)
             return -1;
 
         /* XXX floppy disks */
     } else {
         if (def->os.bootloader &&
-             xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
+             xenConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
             return -1;
 
          if (def->os.bootloaderArgs &&
-             xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
+             xenConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
             return -1;
 
          if (def->os.kernel &&
-             xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
+             xenConfigSetString(conf, "kernel", def->os.kernel) < 0)
             return -1;
 
          if (def->os.initrd &&
-             xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
+             xenConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
             return -1;
 
          if (def->os.cmdline &&
-             xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
+             xenConfigSetString(conf, "extra", def->os.cmdline) < 0)
             return -1;
      } /* !hvm */
 
@@ -1807,52 +1807,52 @@ xenFormatVfb(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion)
     if (def->ngraphics == 1) {
         if (hvm || (xendConfigVersion < XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
             if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
-                if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
+                if (xenConfigSetInt(conf, "sdl", 1) < 0)
                     return -1;
 
-                if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
+                if (xenConfigSetInt(conf, "vnc", 0) < 0)
                     return -1;
 
                 if (def->graphics[0]->data.sdl.display &&
-                    xenXMConfigSetString(conf, "display",
+                    xenConfigSetString(conf, "display",
                                      def->graphics[0]->data.sdl.display) < 0)
                     return -1;
 
                 if (def->graphics[0]->data.sdl.xauth &&
-                    xenXMConfigSetString(conf, "xauthority",
+                    xenConfigSetString(conf, "xauthority",
                                          def->graphics[0]->data.sdl.xauth) < 0)
                     return -1;
             } else {
                 const char *listenAddr;
 
-                if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
+                if (xenConfigSetInt(conf, "sdl", 0) < 0)
                     return -1;
 
-                if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
+                if (xenConfigSetInt(conf, "vnc", 1) < 0)
                     return -1;
 
-                if (xenXMConfigSetInt(conf, "vncunused",
+                if (xenConfigSetInt(conf, "vncunused",
                               def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
                     return -1;
 
                 if (!def->graphics[0]->data.vnc.autoport &&
-                    xenXMConfigSetInt(conf, "vncdisplay",
-                                  def->graphics[0]->data.vnc.port - 5900) < 0)
+                    xenConfigSetInt(conf, "vncdisplay",
+                                    def->graphics[0]->data.vnc.port - 5900) < 0)
                     return -1;
 
                 listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
                 if (listenAddr &&
-                    xenXMConfigSetString(conf, "vnclisten", listenAddr) < 0)
+                    xenConfigSetString(conf, "vnclisten", listenAddr) < 0)
                     return -1;
 
                 if (def->graphics[0]->data.vnc.auth.passwd &&
-                    xenXMConfigSetString(conf, "vncpasswd",
-                                        def->graphics[0]->data.vnc.auth.passwd) < 0)
+                    xenConfigSetString(conf, "vncpasswd",
+                                       def->graphics[0]->data.vnc.auth.passwd) < 0)
                     return -1;
 
                 if (def->graphics[0]->data.vnc.keymap &&
-                    xenXMConfigSetString(conf, "keymap",
-                                        def->graphics[0]->data.vnc.keymap) < 0)
+                    xenConfigSetString(conf, "keymap",
+                                       def->graphics[0]->data.vnc.keymap) < 0)
                     return -1;
             }
         } else {
@@ -1928,7 +1928,7 @@ xenFormatSound(virConfPtr conf, virDomainDefPtr def)
 
             str = virBufferContentAndReset(&buf);
             if (ret == 0)
-                ret = xenXMConfigSetString(conf, "soundhw", str);
+                ret = xenConfigSetString(conf, "soundhw", str);
 
             VIR_FREE(str);
             if (ret < 0)
@@ -1948,22 +1948,22 @@ xenFormatInputDevs(virConfPtr conf, virDomainDefPtr def)
     if (STREQ(def->os.type, "hvm")) {
         for (i = 0; i < def->ninputs; i++) {
             if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
-                if (xenXMConfigSetInt(conf, "usb", 1) < 0)
+                if (xenConfigSetInt(conf, "usb", 1) < 0)
                     return -1;
 
                 switch (def->inputs[i]->type) {
                     case VIR_DOMAIN_INPUT_TYPE_MOUSE:
-                        if (xenXMConfigSetString(conf, "usbdevice", "mouse") < 0)
+                        if (xenConfigSetString(conf, "usbdevice", "mouse") < 0)
                             return -1;
 
                         break;
                     case VIR_DOMAIN_INPUT_TYPE_TABLET:
-                        if (xenXMConfigSetString(conf, "usbdevice", "tablet") < 0)
+                        if (xenConfigSetString(conf, "usbdevice", "tablet") < 0)
                             return -1;
 
                         break;
                     case VIR_DOMAIN_INPUT_TYPE_KBD:
-                        if (xenXMConfigSetString(conf, "usbdevice", "keyboard") < 0)
+                        if (xenConfigSetString(conf, "usbdevice", "keyboard") < 0)
                             return -1;
 
                         break;
diff --git a/src/xenconfig/xen_common.h b/src/xenconfig/xen_common.h
index 9f50aef..e993b21 100644
--- a/src/xenconfig/xen_common.h
+++ b/src/xenconfig/xen_common.h
@@ -27,11 +27,25 @@
 # include "virconf.h"
 # include "domain_conf.h"
 
-int
-xenConfigGetString(virConfPtr conf,
-                   const char *name,
-                   const char **value,
-                   const char *def);
+int xenConfigGetString(virConfPtr conf,
+                       const char *name,
+                       const char **value,
+                       const char *def);
+
+int xenConfigGetBool(virConfPtr conf, const char *name, int *value, int def);
+
+int xenConfigSetInt(virConfPtr conf, const char *name, long long value);
+
+int xenConfigSetString(virConfPtr conf, const char *setting, const char *value);
+
+int xenConfigGetULong(virConfPtr conf,
+                      const char *name,
+                      unsigned long *value,
+                      unsigned long def);
+
+int xenConfigCopyStringOpt(virConfPtr conf,
+                           const char *name,
+                           char **value);
 
 int xenParseConfigCommon(virConfPtr conf,
                          virDomainDefPtr def,
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
new file mode 100644
index 0000000..294b82d
--- /dev/null
+++ b/src/xenconfig/xen_xl.c
@@ -0,0 +1,461 @@
+/*
+ * xen_xl.c: Xen XL parsing functions
+ *
+ * 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/>.
+ *
+ * Author: Kiarie Kahurani <davidkiarie4 at gmail.com>
+ */
+#include <config.h>
+#include "virconf.h"
+#include "domain_conf.h"
+#include "viralloc.h"
+#include "virstring.h"
+#include "xen_xl.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+static int
+xenParseXLSpice(virConfPtr conf, virDomainDefPtr def)
+{
+    virDomainGraphicsDefPtr graphics = NULL;
+    unsigned long port;
+    char *listenAddr = NULL;
+    int val = 0;
+
+    if (STREQ(def->os.type, "hvm")) {
+        if (xenConfigGetBool(conf, "spice", &val, 0) < 0)
+            return -1;
+
+        if (val) {
+            if (VIR_ALLOC(graphics) < 0)
+                return -1;
+
+            graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SPICE;
+            if (xenConfigCopyStringOpt(conf, "spicehost", &listenAddr) < 0)
+                goto cleanup;
+            if (listenAddr &&
+                virDomainGraphicsListenSetAddress(graphics, 0, listenAddr,
+                                                  -1, true) < 0) {
+                goto cleanup;
+            }
+
+            VIR_FREE(listenAddr);
+            if (xenConfigGetULong(conf, "spicetls_port", &port, 0) < 0)
+                goto cleanup;
+            graphics->data.spice.tlsPort = (int)port;
+
+            if (xenConfigGetULong(conf, "spiceport", &port, 0) < 0)
+                goto cleanup;
+
+            graphics->data.spice.port = (int)port;
+
+            if (!graphics->data.spice.tlsPort &&
+                !graphics->data.spice.port)
+            graphics->data.spice.autoport = 1;
+
+            if (xenConfigGetBool(conf, "spicedisable_ticketing", &val, 0) < 0)
+                goto cleanup;
+            if (val) {
+                if (xenConfigCopyStringOpt(conf, "spicepasswd",
+                                           &graphics->data.spice.auth.passwd) < 0)
+                    goto cleanup;
+            }
+
+            if (xenConfigGetBool(conf, "spiceagent_mouse",
+                                 &graphics->data.spice.mousemode, 0) < 0)
+                goto cleanup;
+            if (xenConfigGetBool(conf, "spicedvagent", &val, 0) < 0)
+                goto cleanup;
+            if (val) {
+                if (xenConfigGetBool(conf, "spice_clipboard_sharing",
+                                     &graphics->data.spice.copypaste,
+                                     0) < 0)
+                    goto cleanup;
+            }
+
+            if (VIR_ALLOC_N(def->graphics, 1) < 0)
+                goto cleanup;
+            def->graphics[0] = graphics;
+            def->ngraphics = 1;
+            graphics = NULL;
+        }
+    }
+
+    return 0;
+
+ cleanup:
+    virDomainGraphicsDefFree(graphics);
+    return -1;
+}
+
+
+static int
+xenParseXLDisk(virConfPtr conf, virDomainDefPtr def)
+{
+    virDomainDiskDefPtr disk = NULL;
+    virConfValuePtr list = virConfGetValue(conf, "disk");
+
+    if (list && list->type == VIR_CONF_LIST) {
+        list = list->list;
+        while (list) {
+            char *head;
+            char *offset;
+            char *tmp;
+
+            if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
+                goto skipdisk;
+
+            head = list->str;
+            if (!(disk = virDomainDiskDefNew()))
+                return -1;
+
+            if (!(offset = strchr(head, ',')))
+                goto skipdisk;
+
+            if (offset == head) {
+                ignore_value(virDomainDiskSetSource(disk, NULL));
+            } else {
+                if (VIR_STRNDUP(tmp, head, offset - head) < 0)
+                    goto cleanup;
+
+                if (virDomainDiskSetSource(disk, tmp) < 0) {
+                    VIR_FREE(tmp);
+                    goto cleanup;
+                }
+
+                VIR_FREE(tmp);
+            }
+
+            head = (offset + 1);
+
+            if (!(offset = strchr(head, ',')))
+                goto skipdisk;
+
+            if (VIR_STRNDUP(tmp, head, offset - head) < 0)
+                goto cleanup;
+
+            if (STREQ(tmp, "raw")) {
+                    virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW);
+
+            } else if (STREQ(tmp, "qcow2")) {
+                virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_QCOW2);
+
+            } else if (STREQ(tmp, "qcow")) {
+                    virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_QCOW);
+
+            } else if (STREQ(tmp, "xvhd")) {
+                    virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_VHD);
+            } else {
+                virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW);
+            }
+
+            VIR_FREE(tmp);
+            head = offset + 1;
+
+            if (!(offset = strchr(head, ',')))
+                goto skipdisk;
+
+            if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0)
+                goto cleanup;
+
+            if (virStrncpy(disk->dst, head, offset - head,
+                           (offset - head) + 1) == NULL) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("Dest device %s too big for destination"), head);
+                goto cleanup;
+            }
+
+            head = offset + 1;
+
+            if (!(offset = strchr(head, ',')))
+                goto skipdisk;
+
+            if (VIR_STRNDUP(tmp, head, offset - head) < 0)
+                goto cleanup;
+
+            if (STREQ(tmp, "r") || STREQ(tmp, "ro"))
+                disk->src->readonly = true;
+            else if ((STREQ(tmp, "w!")) || (STREQ(tmp, "!")))
+                disk->src->shared = true;
+
+            switch (virDomainDiskGetFormat(disk)) {
+
+                case VIR_STORAGE_FILE_RAW:
+                    ignore_value(virDomainDiskSetDriver(disk, "phy"));
+                    break;
+                case VIR_STORAGE_FILE_QCOW:
+                case VIR_STORAGE_FILE_QCOW2:
+                    ignore_value(virDomainDiskSetDriver(disk, "qemu"));
+                case VIR_STORAGE_FILE_VHD:
+                    ignore_value(virDomainDiskSetDriver(disk, "tap"));
+            }
+
+            virDomainDiskSetType(disk, STREQ(virDomainDiskGetDriver(disk), "phy") ?
+                                 VIR_STORAGE_TYPE_BLOCK:
+                                 VIR_STORAGE_TYPE_FILE);
+
+            head = offset + 1;
+
+            if (!(offset = strchr(head, ',')) < 0)
+                goto skipdisk;
+
+            if (VIR_STRNDUP(tmp, head, (offset - head)) < 0)
+                goto cleanup;
+
+            if (STREQ(tmp, "cdrom")) {
+                disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
+            } else {
+                disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
+            }
+
+            if (STRPREFIX(disk->dst, "xvhd") || !STREQ(def->os.type, "hvm")) {
+                disk->bus = VIR_DOMAIN_DISK_BUS_XEN;
+            } else if (STRPREFIX(disk->dst, "sd")) {
+                disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
+            } else {
+                disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
+            }
+
+            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
+                return -1;
+
+            skipdisk:
+            list = list->next;
+            virDomainDiskDefFree(disk);
+        }
+    }
+
+    return 0;
+
+ cleanup:
+    virDomainDiskDefFree(disk);
+    return -1;
+}
+
+
+virDomainDefPtr
+xenParseXL(virConfPtr conf, virCapsPtr caps,
+           int xendConfigVersion)
+{
+    virDomainDefPtr def = NULL;
+
+    if (VIR_ALLOC(def) < 0)
+        return NULL;
+
+    def->virtType = VIR_DOMAIN_VIRT_XEN;
+    def->id = -1;
+
+    if (xenParseConfigCommon(conf, def, caps, xendConfigVersion) < 0)
+        goto cleanup;
+
+    if (xenParseXLDisk(conf, def) < 0)
+        goto cleanup;
+
+    if (xenParseXLSpice(conf, def) < 0)
+        goto cleanup;
+
+    return def;
+
+ cleanup:
+    virDomainDefFree(def);
+    return NULL;
+}
+
+
+static int
+xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    virConfValuePtr val, tmp;
+    const char *src = virDomainDiskGetSource(disk);
+    int format = virDomainDiskGetFormat(disk);
+
+    /* target */
+    virBufferAsprintf(&buf, "%s,", src);
+    /* format */
+    switch (format) {
+        case VIR_STORAGE_FILE_RAW:
+            virBufferAddLit(&buf, "raw,");
+            break;
+        case VIR_STORAGE_FILE_VHD:
+            virBufferAddLit(&buf, "xvhd,");
+            break;
+        case VIR_STORAGE_FILE_QCOW:
+            virBufferAddLit(&buf, "qcow,");
+            break;
+        case VIR_STORAGE_FILE_QCOW2:
+            virBufferAddLit(&buf, "qcow2,");
+            break;
+      /* set default */
+        default:
+            virBufferAddLit(&buf, "raw,");
+    }
+
+    /* device */
+    virBufferAdd(&buf, disk->dst, -1);
+
+    virBufferAddLit(&buf, ",");
+
+    if (disk->src->readonly)
+        virBufferAddLit(&buf, "r,");
+    else if (disk->src->shared)
+        virBufferAddLit(&buf, "!,");
+    else
+        virBufferAddLit(&buf, "w,");
+    if (disk->transient) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("transient disks not supported yet"));
+        goto cleanup;
+    }
+
+    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
+        virBufferAddLit(&buf, "cdrom");
+
+    if (virBufferCheckError(&buf) < 0)
+        goto cleanup;
+
+    if (VIR_ALLOC(val) < 0)
+        goto cleanup;
+
+    val->type = VIR_CONF_STRING;
+    val->str = virBufferContentAndReset(&buf);
+    tmp = list->list;
+    while (tmp && tmp->next)
+        tmp = tmp->next;
+    if (tmp)
+        tmp->next = val;
+    else
+        list->list = val;
+    return 0;
+
+ cleanup:
+    virBufferFreeAndReset(&buf);
+    return -1;
+}
+
+
+static int
+xenFormatXLDomainDisks(virConfPtr conf, virDomainDefPtr def)
+{
+    virConfValuePtr diskVal = NULL;
+    size_t i = 0;
+
+    if (VIR_ALLOC(diskVal) < 0)
+        return -1;
+
+    diskVal->type = VIR_CONF_LIST;
+    diskVal->list = NULL;
+
+    for (i = 0; i < def->ndisks; i++) {
+        if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
+            continue;
+        if (xenFormatXLDisk(diskVal, def->disks[i]) < 0)
+
+                goto cleanup;
+    }
+
+    if (diskVal->list != NULL) {
+        int ret = virConfSetValue(conf, "disk", diskVal);
+        diskVal = NULL;
+        if (ret < 0)
+            goto cleanup;
+    }
+
+    return 0;
+
+ cleanup:
+    virConfFreeValue(diskVal);
+    return 0;
+}
+
+
+static int
+xenFormatXLSpice(virConfPtr conf, virDomainDefPtr def)
+{
+    const char *listenAddr = NULL;
+
+    if (STREQ(def->os.type, "hvm")) { /*save's CPU :-) */
+        if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
+            /* set others to false but may not be necessary */
+            if (xenConfigSetInt(conf, "sdl", 0) < 0)
+                return -1;
+
+            if (xenConfigSetInt(conf, "vnc", 0) < 0)
+                return -1;
+
+            if (xenConfigSetInt(conf, "spice", 1) < 0)
+                return -1;
+
+            if (xenConfigSetInt(conf, "spiceport",
+                                def->graphics[0]->data.spice.port) < 0)
+                return -1;
+
+            if (xenConfigSetInt(conf, "spicetls_port",
+                                def->graphics[0]->data.spice.tlsPort) < 0)
+                return -1;
+
+            if (def->graphics[0]->data.spice.auth.passwd &&
+                xenConfigSetString(conf, "spicepasswd",
+                                   def->graphics[0]->data.spice.auth.passwd) < 0)
+                return -1;
+
+            listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
+            if (listenAddr &&
+                xenConfigSetString(conf, "spice_host", listenAddr) < 0) {
+                return -1;
+            }
+
+            if (xenConfigSetInt(conf, "spice_mouse_agent",
+                                def->graphics[0]->data.spice.mousemode) < 0)
+                return -1;
+
+            if (xenConfigSetInt(conf, "disable_ticketing",
+                                def->graphics[0]->data.spice.mousemode) < 0)
+                return -1;
+
+            if (xenConfigSetInt(conf, "spice_clipboard_sharing",
+                                def->graphics[0]->data.spice.copypaste) < 0)
+                return -1;
+        }
+    }
+
+    return 0;
+}
+
+
+virConfPtr xenFormatXL(virDomainDefPtr def, virConnectPtr conn,
+                       int xendConfigVersion)
+{
+    virConfPtr conf = NULL;
+
+    if (!(conf = virConfNew()))
+        goto cleanup;
+
+    if (xenFormatConfigCommon(conf, def, conn, xendConfigVersion) < 0)
+        goto cleanup;
+
+    if (xenFormatXLDomainDisks(conf, def) < 0)
+        goto cleanup;
+
+    if (xenFormatXLSpice(conf, def) < 0)
+        goto cleanup;
+
+    return conf;
+
+ cleanup:
+    if (conf)
+        virConfFree(conf);
+    return NULL;
+}
diff --git a/src/xenconfig/xen_xl.h b/src/xenconfig/xen_xl.h
new file mode 100644
index 0000000..d60fe5e
--- /dev/null
+++ b/src/xenconfig/xen_xl.h
@@ -0,0 +1,29 @@
+/*
+ * xen_xl.h: Xen XL parsing functions
+ *
+ * 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/>.
+ *
+ * Author: Kiarie Kahurani<davidkiarie4 at gmail.com>
+ */
+#ifndef _XEN_XL_H_
+# define _XEN_XL_H_
+
+# include "xen_common.h"
+
+virDomainDefPtr xenParseXL(virConfPtr conn, virCapsPtr caps,
+                           int xendConfigVersion);
+virConfPtr xenFormatXL(virDomainDefPtr def,
+                       virConnectPtr, int xendConfigVersion);
+#endif /* _XEN_XL_H_ */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3e71069..aa18a4a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -136,6 +136,7 @@ EXTRA_DIST =		\
 	vmx2xmldata \
 	xencapsdata \
 	xmconfigdata \
+	xlconfigdata \
 	xml2sexprdata \
 	xml2vmxdata \
 	vmwareverdata \
@@ -220,7 +221,8 @@ ssh_LDADD = $(COVERAGE_LDFLAGS)
 
 if WITH_XEN
 test_programs += xml2sexprtest sexpr2xmltest \
-	xmconfigtest xencapstest statstest reconnect
+	xmconfigtest xencapstest statstest reconnect \
+	xlconfigtest
 endif WITH_XEN
 if WITH_QEMU
 test_programs += qemuxml2argvtest qemuxml2xmltest qemuxmlnstest \
@@ -468,6 +470,11 @@ sexpr2xmltest_SOURCES = \
 	testutils.c testutils.h
 sexpr2xmltest_LDADD = $(xen_LDADDS)
 
+xlconfigtest_SOURCES = \
+	xlconfigtest.c testutilsxen.c testutilsxen.h \
+	testutils.c testutils.h
+xlconfigtest_LDADD =$(xen_LDADDS)
+
 xmconfigtest_SOURCES = \
 	xmconfigtest.c testutilsxen.c testutilsxen.h \
 	testutils.c testutils.h
diff --git a/tests/testutilsxen.c b/tests/testutilsxen.c
index a50a8a2..df1d124 100644
--- a/tests/testutilsxen.c
+++ b/tests/testutilsxen.c
@@ -69,3 +69,53 @@ virCapsPtr testXenCapsInit(void)
     virObjectUnref(caps);
     return NULL;
 }
+
+
+virCapsPtr
+testXLInitCaps(void)
+{
+    virCapsPtr caps;
+    virCapsGuestPtr guest;
+    virCapsGuestMachinePtr *machines;
+    int nmachines;
+    static const char *const x86_machines[] = {
+        "xenfv"
+    };
+    static const char *const xen_machines[] = {
+        "xenpv"
+    };
+
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
+                                   false, false)) == NULL)
+        return NULL;
+    nmachines = ARRAY_CARDINALITY(x86_machines);
+    if ((machines = virCapabilitiesAllocMachines(x86_machines, nmachines)) == NULL)
+        goto cleanup;
+    if ((guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_X86_64,
+                                         "/usr/lib/xen/bin/qemu-dm", NULL,
+                                         nmachines, machines)) == NULL)
+        goto cleanup;
+    machines = NULL;
+    if (virCapabilitiesAddGuestDomain(guest, "xen", NULL,
+                                      NULL, 0, NULL) == NULL)
+        goto cleanup;
+    nmachines = ARRAY_CARDINALITY(xen_machines);
+    if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL)
+        goto cleanup;
+
+    if ((guest = virCapabilitiesAddGuest(caps, "xen", VIR_ARCH_X86_64,
+                                        "/usr/lib/xen/bin/qemu-dm", NULL,
+                                        nmachines, machines)) == NULL)
+        goto cleanup;
+    machines = NULL;
+
+    if (virCapabilitiesAddGuestDomain(guest, "xen", NULL,
+                                      NULL, 0, NULL) == NULL)
+        goto cleanup;
+    return caps;
+
+ cleanup:
+    virCapabilitiesFreeMachines(machines, nmachines);
+    virObjectUnref(caps);
+    return NULL;
+}
diff --git a/tests/testutilsxen.h b/tests/testutilsxen.h
index 54155e5..c78350d 100644
--- a/tests/testutilsxen.h
+++ b/tests/testutilsxen.h
@@ -1,3 +1,10 @@
-#include "capabilities.h"
+#ifndef _TESTUTILSXEN_H_
+# define _TESTUTILSXEN_H_
+
+# include "capabilities.h"
 
 virCapsPtr testXenCapsInit(void);
+
+virCapsPtr testXLInitCaps(void);
+
+#endif /* _TESTUTILSXEN_H_ */
diff --git a/tests/xlconfigdata/test-fullvirt-new-disk.cfg b/tests/xlconfigdata/test-fullvirt-new-disk.cfg
new file mode 100644
index 0000000..2e76625
--- /dev/null
+++ b/tests/xlconfigdata/test-fullvirt-new-disk.cfg
@@ -0,0 +1,27 @@
+name = "XenGuest2"
+uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 1
+builder = "hvm"
+kernel = "/usr/lib/xen/boot/hvmloader"
+boot = "d"
+pae = 1
+acpi = 1
+apic = 1
+hap = 0
+viridian = 0
+rtc_timeoffset = 0
+localtime = 1
+on_poweroff = "destroy"
+on_reboot = "restart"
+on_crash = "restart"
+device_model = "/usr/lib/xen/bin/qemu-dm"
+sdl = 0
+vnc = 1
+vncunused = 1
+vnclisten = "127.0.0.1"
+vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000" ]
+parallel = "none"
+serial = "none"
+disk = [ "/dev/HostVG/XenGuest2,raw,hda,w,", "/root/boot.iso,raw,hdc,r,cdrom" ]
diff --git a/tests/xlconfigdata/test-fullvirt-new-disk.xml b/tests/xlconfigdata/test-fullvirt-new-disk.xml
new file mode 100644
index 0000000..330be5c
--- /dev/null
+++ b/tests/xlconfigdata/test-fullvirt-new-disk.xml
@@ -0,0 +1,46 @@
+<domain type='xen'>
+  <name>XenGuest2</name>
+  <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>592896</memory>
+  <currentMemory unit='KiB'>403456</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='xenfv'>hvm</type>
+    <loader>/usr/lib/xen/boot/hvmloader</loader>
+    <boot dev='cdrom'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+    <pae/>
+  </features>
+  <clock offset='variable' adjustment='0' basis='localtime'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
+    <disk type='block' device='disk'>
+      <driver name='phy' type='raw'/>
+      <source dev='/dev/HostVG/XenGuest2'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+    <disk type='block' device='cdrom'>
+      <driver name='phy' type='raw'/>
+      <source dev='/root/boot.iso'/>
+      <target dev='hdc' bus='ide'/>
+      <readonly/>
+    </disk>
+    <interface type='bridge'>
+      <mac address='00:16:3e:66:92:9c'/>
+      <source bridge='xenbr1'/>
+      <script path='vif-bridge'/>
+      <model type='e1000'/>
+    </interface>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1'>
+      <listen type='address' address='127.0.0.1'/>
+    </graphics>
+  </devices>
+</domain>
diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c
new file mode 100644
index 0000000..7b2a143
--- /dev/null
+++ b/tests/xlconfigtest.c
@@ -0,0 +1,222 @@
+/*
+ * xlconfigtest.c: Test backend for xl_internal config file handling
+ *
+ * Copyright (C) 2007, 2010-2011, 2014 Red Hat, Inc.
+ *
+ * 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/>.
+ *
+ * Author: Daniel P. Berrange <berrange at redhat.com>
+ * Author: Kiarie Kahurani <davidkiarie4 at gmail.com>
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "xenconfig/xen_xl.h"
+#include "viralloc.h"
+#include "virstring.h"
+#include "testutils.h"
+#include "testutilsxen.h"
+#include "xen/xen_driver.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+static virCapsPtr caps;
+static virDomainXMLOptionPtr xmlopt;
+/*
+ * parses the xml, creates a domain def and compare with equivalent xm config
+ */
+static int
+testCompareParseXML(const char *xmcfg, const char *xml, int xendConfigVersion)
+{
+    char *xmlData = NULL;
+    char *xmcfgData = NULL;
+    char *gotxmcfgData = NULL;
+    virConfPtr conf = NULL;
+    virConnectPtr conn = NULL;
+    int wrote = 4096;
+    int ret = -1;
+    virDomainDefPtr def = NULL;
+
+    if (VIR_ALLOC_N(gotxmcfgData, wrote) < 0)
+        goto fail;
+
+    conn = virGetConnect();
+    if (!conn) goto fail;
+
+    if (virtTestLoadFile(xml, &xmlData) < 0)
+        goto fail;
+
+    if (virtTestLoadFile(xmcfg, &xmcfgData) < 0)
+        goto fail;
+
+    if (!(def = virDomainDefParseString(xmlData, caps, xmlopt,
+                                        1 << VIR_DOMAIN_VIRT_XEN,
+                                        VIR_DOMAIN_XML_INACTIVE)))
+        goto fail;
+
+    if (!virDomainDefCheckABIStability(def, def)) {
+        fprintf(stderr, "ABI stability check failed on %s", xml);
+        goto fail;
+    }
+
+    if (!(conf = xenFormatXL(def, conn,  xendConfigVersion)))
+        goto fail;
+
+    if (virConfWriteMem(gotxmcfgData, &wrote, conf) < 0)
+        goto fail;
+    gotxmcfgData[wrote] = '\0';
+
+    if (STRNEQ(xmcfgData, gotxmcfgData)) {
+        virtTestDifference(stderr, xmcfgData, gotxmcfgData);
+        goto fail;
+    }
+
+    ret = 0;
+
+ fail:
+    VIR_FREE(xmlData);
+    VIR_FREE(xmcfgData);
+    VIR_FREE(gotxmcfgData);
+    if (conf)
+        virConfFree(conf);
+    virDomainDefFree(def);
+    virObjectUnref(conn);
+
+    return ret;
+}
+/*
+ * parses the xl config, develops domain def and compares with equivalent xm config
+ */
+static int
+testCompareFormatXML(const char *xmcfg, const char *xml, int xendConfigVersion)
+{
+    char *xmlData = NULL;
+    char *xmcfgData = NULL;
+    char *gotxml = NULL;
+    virConfPtr conf = NULL;
+    int ret = -1;
+    virConnectPtr conn;
+    virDomainDefPtr def = NULL;
+
+    conn = virGetConnect();
+    if (!conn) goto fail;
+
+    if (virtTestLoadFile(xml, &xmlData) < 0)
+        goto fail;
+
+    if (virtTestLoadFile(xmcfg, &xmcfgData) < 0)
+        goto fail;
+
+    if (!(conf = virConfReadMem(xmcfgData, strlen(xmcfgData), 0)))
+        goto fail;
+
+    if (!(def = xenParseXL(conf, caps, xendConfigVersion)))
+        goto fail;
+
+    if (!(gotxml = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE)))
+        goto fail;
+
+    if (STRNEQ(xmlData, gotxml)) {
+        virtTestDifference(stderr, xmlData, gotxml);
+        goto fail;
+    }
+
+    ret = 0;
+
+ fail:
+    if (conf)
+        virConfFree(conf);
+    VIR_FREE(xmlData);
+    VIR_FREE(xmcfgData);
+    VIR_FREE(gotxml);
+    virDomainDefFree(def);
+    virObjectUnref(conn);
+
+    return ret;
+}
+
+
+struct testInfo {
+    const char *name;
+    int version;
+    int mode;
+};
+
+static int
+testCompareHelper(const void *data)
+{
+    int result = -1;
+    const struct testInfo *info = data;
+    char *xml = NULL;
+    char *cfg = NULL;
+
+    if (virAsprintf(&xml, "%s/xlconfigdata/test-%s.xml",
+                    abs_srcdir, info->name) < 0 ||
+        virAsprintf(&cfg, "%s/xlconfigdata/test-%s.cfg",
+                    abs_srcdir, info->name) < 0)
+        goto cleanup;
+
+    if (info->mode == 0)
+        result = testCompareParseXML(cfg, xml, info->version);
+    else
+        result = testCompareFormatXML(cfg, xml, info->version);
+
+ cleanup:
+    VIR_FREE(xml);
+    VIR_FREE(cfg);
+
+    return result;
+}
+
+
+static int
+mymain(void)
+{
+    int ret = 0;
+
+    if (!(caps = testXLInitCaps()))
+        return EXIT_FAILURE;
+
+    if (!(xmlopt = xenDomainXMLConfInit()))
+        return EXIT_FAILURE;
+
+#define DO_TEST(name, version)                                          \
+    do {                                                                \
+        struct testInfo info0 = { name, version, 0 };                   \
+        struct testInfo info1 = { name, version, 1 };                   \
+        if (virtTestRun("Xen XM-2-XML Parse  " name,                    \
+                        testCompareHelper, &info0) < 0)                 \
+            ret = -1;                                                   \
+        if (virtTestRun("Xen XM-2-XML Format " name,                    \
+                        testCompareHelper, &info1) < 0)                 \
+            ret = -1;                                                   \
+    } while (0)
+
+    DO_TEST("fullvirt-new-disk", 7);
+
+    virObjectUnref(caps);
+    virObjectUnref(xmlopt);
+
+    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIRT_TEST_MAIN(mymain)
-- 
1.8.4.5




More information about the libvir-list mailing list