Introduce the new xen-xl parser that {formats,parses} xl disk and spice graphics format Signed-off-by: Kiarie Kahurani <davidkiarie4@xxxxxxxxx> --- 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@xxxxxxxxx> + */ +#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@xxxxxxxxx> + */ +#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@xxxxxxxxxx> + * Author: Kiarie Kahurani <davidkiarie4@xxxxxxxxx> + * + */ + +#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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list