diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index 743b1f03b38e763b49f51ed2cb85dac5893cc3a5..bbc01972f5e6b0243ae88219c3139e689204d3bf 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -164,7 +164,6 @@ struct _virCaps { /* Move to virDomainXMLOption later */ unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN]; int (*defaultConsoleTargetType)(const char *ostype, virArch guestarch); - bool hasWideScsiBus; }; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ec2cf23289305a7f5437120e7c7a12463031a124..aac2b41838968f376881c1da9093c7be1073b204 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3593,7 +3593,8 @@ virDomainDiskFindByBusAndDst(virDomainDefPtr def, } int -virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def) +virDomainDiskDefAssignAddress(virDomainXMLOptionPtr xmlopt, + virDomainDiskDefPtr def) { int idx = virDiskNameToIndex(def->dst); if (idx < 0) { @@ -3607,7 +3608,7 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def) case VIR_DOMAIN_DISK_BUS_SCSI: def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; - if (caps->hasWideScsiBus) { + if (xmlopt->config.hasWideScsiBus) { /* For a wide SCSI bus we define the default mapping to be * 16 units per bus, 1 bus per controller, many controllers. * Unit 7 is the SCSI controller itself. Therefore unit 7 @@ -4046,7 +4047,7 @@ cleanup: * @param node XML nodeset to parse for disk definition */ static virDomainDiskDefPtr -virDomainDiskDefParseXML(virCapsPtr caps, +virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, xmlNodePtr node, xmlXPathContextPtr ctxt, virBitmapPtr bootMap, @@ -4837,7 +4838,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, } if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE - && virDomainDiskDefAssignAddress(caps, def) < 0) + && virDomainDiskDefAssignAddress(xmlopt, def) < 0) goto error; cleanup: @@ -8499,7 +8500,7 @@ virDomainDeviceDefParse(const char *xmlStr, if (xmlStrEqual(node->name, BAD_CAST "disk")) { dev->type = VIR_DOMAIN_DEVICE_DISK; - if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, ctxt, + if (!(dev->data.disk = virDomainDiskDefParseXML(xmlopt, node, ctxt, NULL, def->seclabels, def->nseclabels, flags))) @@ -10391,7 +10392,7 @@ virDomainDefParseXML(xmlDocPtr xml, goto no_memory; for (i = 0 ; i < n ; i++) { - virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, + virDomainDiskDefPtr disk = virDomainDiskDefParseXML(xmlopt, nodes[i], ctxt, bootMap, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 19a66ed1abb5d2f0ef89020356fc0502c3fe2d9b..f3647a3eea18ee09bdb3c76a6bc2f4c8b6208174 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1949,11 +1949,16 @@ typedef int (*virDomainDeviceDefPostParseCallback)(virDomainDeviceDefPtr dev, typedef struct _virDomainDefParserConfig virDomainDefParserConfig; typedef virDomainDefParserConfig *virDomainDefParserConfigPtr; struct _virDomainDefParserConfig { + /* driver domain definition callbacks */ virDomainDefPostParseCallback domainPostParseCallback; virDomainDeviceDefPostParseCallback devicesPostParseCallback; + /* private data for the callbacks */ void *priv; virFreeCallback privFree; + + /* data */ + bool hasWideScsiBus; }; typedef struct _virDomainXMLPrivateDataCallbacks virDomainXMLPrivateDataCallbacks; @@ -2151,7 +2156,8 @@ int virDomainDiskInsert(virDomainDefPtr def, virDomainDiskDefPtr disk); void virDomainDiskInsertPreAlloced(virDomainDefPtr def, virDomainDiskDefPtr disk); -int virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def); +int virDomainDiskDefAssignAddress(virDomainXMLOptionPtr xmlopt, + virDomainDiskDefPtr def); virDomainDiskDefPtr virDomainDiskRemove(virDomainDefPtr def, size_t i); diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 08381fca4d517249f63f0d8ef4844521023e76ec..c63919912f6279b8a5abf58bc5f0cf171d29f8f7 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -601,7 +601,6 @@ esxCapsInit(esxPrivate *priv) virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 }); virCapabilitiesAddHostMigrateTransport(caps, "vpxmigr"); - caps->hasWideScsiBus = true; caps->defaultConsoleTargetType = esxDefaultConsoleType; if (esxLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0) { @@ -1100,7 +1099,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, goto cleanup; } - if (!(priv->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL))) + if (!(priv->xmlopt = virVMXDomainXMLConfInit())) goto cleanup; conn->privateData = priv; @@ -2786,7 +2785,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) ctx.formatFileName = NULL; ctx.autodetectSCSIControllerModel = NULL; - def = virVMXParseConfig(&ctx, priv->caps, vmx); + def = virVMXParseConfig(&ctx, priv->xmlopt, vmx); if (def != NULL) { if (powerState != esxVI_VirtualMachinePowerState_PoweredOff) { @@ -2845,7 +2844,7 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat, ctx.formatFileName = NULL; ctx.autodetectSCSIControllerModel = NULL; - def = virVMXParseConfig(&ctx, priv->caps, nativeConfig); + def = virVMXParseConfig(&ctx, priv->xmlopt, nativeConfig); if (def != NULL) { xml = virDomainDefFormat(def, VIR_DOMAIN_XML_INACTIVE); @@ -2902,7 +2901,7 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat, ctx.formatFileName = esxFormatVMXFileName; ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel; - vmx = virVMXFormatConfig(&ctx, priv->caps, def, virtualHW_version); + vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version); virDomainDefFree(def); @@ -3149,7 +3148,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml) ctx.formatFileName = esxFormatVMXFileName; ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel; - vmx = virVMXFormatConfig(&ctx, priv->caps, def, virtualHW_version); + vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version); if (vmx == NULL) { goto cleanup; diff --git a/src/libvirt_vmx.syms b/src/libvirt_vmx.syms index 0b15f49c225341e525dd7ed9e6beae72f6f15bce..206ad445e7b7385ece5e72fff54dc486ba23b478 100644 --- a/src/libvirt_vmx.syms +++ b/src/libvirt_vmx.syms @@ -4,6 +4,7 @@ # vmx/vmx.h virVMXConvertToUTF8; +virVMXDomainXMLConfInit; virVMXEscapeHex; virVMXFormatCDROM; virVMXFormatConfig; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5866070779e7be11db4e2857cc901d2a8436328a..ae7c96be50f2d120cf2d7cf834703ce9bbefc2ed 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7971,7 +7971,7 @@ error: * Will fail if not using the 'index' keyword */ static virDomainDiskDefPtr -qemuParseCommandLineDisk(virCapsPtr qemuCaps, +qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, const char *val, int nvirtiodisk, bool old_style_ceph_args) @@ -8271,7 +8271,7 @@ qemuParseCommandLineDisk(virCapsPtr qemuCaps, else def->dst[2] = 'a' + idx; - if (virDomainDiskDefAssignAddress(qemuCaps, def) < 0) { + if (virDomainDiskDefAssignAddress(xmlopt, def) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("invalid device name '%s'"), def->dst); virDomainDiskDefFree(def); @@ -9345,7 +9345,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps, !disk->dst) goto no_memory; - if (virDomainDiskDefAssignAddress(qemuCaps, disk) < 0) { + if (virDomainDiskDefAssignAddress(xmlopt, disk) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Cannot assign address for device name '%s'"), disk->dst); @@ -9571,7 +9571,8 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps, } } else if (STREQ(arg, "-drive")) { WANT_VALUE(); - if (!(disk = qemuParseCommandLineDisk(qemuCaps, val, nvirtiodisk, + if (!(disk = qemuParseCommandLineDisk(xmlopt, val, + nvirtiodisk, ceph_args != NULL))) goto error; if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c index 3528f07672a641ffd09d062c7850f91a97d74d39..ed63f50100f4a269fd4547678308bce587b1f56f 100644 --- a/src/vmware/vmware_conf.c +++ b/src/vmware/vmware_conf.c @@ -174,7 +174,7 @@ vmwareLoadDomains(struct vmware_driver *driver) goto cleanup; if ((vmdef = - virVMXParseConfig(&ctx, driver->caps, vmx)) == NULL) { + virVMXParseConfig(&ctx, driver->xmlopt, vmx)) == NULL) { goto cleanup; } diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 0e0f59deb22ca3ca46ee97dd5a1f313bc4688de9..c7e493f0a45ceb660d243edd1a468048c0b456d2 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -330,7 +330,7 @@ vmwareDomainDefineXML(virConnectPtr conn, const char *xml) goto cleanup; /* generate vmx file */ - vmx = virVMXFormatConfig(&ctx, driver->caps, vmdef, 7); + vmx = virVMXFormatConfig(&ctx, driver->xmlopt, vmdef, 7); if (vmx == NULL) goto cleanup; @@ -601,7 +601,7 @@ vmwareDomainCreateXML(virConnectPtr conn, const char *xml, goto cleanup; /* generate vmx file */ - vmx = virVMXFormatConfig(&ctx, driver->caps, vmdef, 7); + vmx = virVMXFormatConfig(&ctx, driver->xmlopt, vmdef, 7); if (vmx == NULL) goto cleanup; @@ -943,7 +943,7 @@ vmwareDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat, ctx.parseFileName = vmwareCopyVMXFileName; - def = virVMXParseConfig(&ctx, driver->caps, nativeConfig); + def = virVMXParseConfig(&ctx, driver->xmlopt, nativeConfig); if (def != NULL) xml = virDomainDefFormat(def, VIR_DOMAIN_XML_INACTIVE); diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index d7eee0937c8f083d88ba54e807594c82a16ab59e..67fbe6c6f043a7f5a3e5da77a3e6e4b55a464d73 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -520,6 +520,18 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST, * Helpers */ +virDomainDefParserConfig virVMXDomainDefParserConfig = { + .hasWideScsiBus = true, +}; + + +virDomainXMLOptionPtr +virVMXDomainXMLConfInit(void) +{ + return virDomainXMLOptionNew(&virVMXDomainDefParserConfig, + NULL, NULL); +} + char * virVMXEscapeHex(const char *string, char escape, const char *special) { @@ -935,7 +947,7 @@ virVMXFloppyDiskNameToUnit(const char *name, int *unit) static int -virVMXVerifyDiskAddress(virCapsPtr caps, virDomainDiskDefPtr disk) +virVMXVerifyDiskAddress(virDomainXMLOptionPtr xmlopt, virDomainDiskDefPtr disk) { virDomainDiskDef def; virDomainDeviceDriveAddressPtr drive; @@ -954,7 +966,7 @@ virVMXVerifyDiskAddress(virCapsPtr caps, virDomainDiskDefPtr disk) def.dst = disk->dst; def.bus = disk->bus; - if (virDomainDiskDefAssignAddress(caps, &def) < 0) { + if (virDomainDiskDefAssignAddress(xmlopt, &def) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not verify disk address")); return -1; @@ -1211,7 +1223,9 @@ virVMXGatherSCSIControllers(virVMXContext *ctx, virDomainDefPtr def, */ virDomainDefPtr -virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) +virVMXParseConfig(virVMXContext *ctx, + virDomainXMLOptionPtr xmlopt, + const char *vmx) { bool success = false; virConfPtr conf = NULL; @@ -1588,7 +1602,7 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) continue; } - if (virVMXParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_DISK, + if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_BUS_SCSI, controller, unit, &def->disks[def->ndisks]) < 0) { goto cleanup; @@ -1599,7 +1613,7 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) continue; } - if (virVMXParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_CDROM, + if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_CDROM, VIR_DOMAIN_DISK_BUS_SCSI, controller, unit, &def->disks[def->ndisks]) < 0) { goto cleanup; @@ -1614,7 +1628,7 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) /* def:disks (ide) */ for (bus = 0; bus < 2; ++bus) { for (unit = 0; unit < 2; ++unit) { - if (virVMXParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_DISK, + if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_BUS_IDE, bus, unit, &def->disks[def->ndisks]) < 0) { goto cleanup; @@ -1625,7 +1639,7 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) continue; } - if (virVMXParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_CDROM, + if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_CDROM, VIR_DOMAIN_DISK_BUS_IDE, bus, unit, &def->disks[def->ndisks]) < 0) { goto cleanup; @@ -1639,7 +1653,7 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) /* def:disks (floppy) */ for (unit = 0; unit < 2; ++unit) { - if (virVMXParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY, + if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY, VIR_DOMAIN_DISK_BUS_FDC, 0, unit, &def->disks[def->ndisks]) < 0) { goto cleanup; @@ -1950,7 +1964,7 @@ virVMXParseSCSIController(virConfPtr conf, int controller, bool *present, int -virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf, +virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr conf, int device, int busType, int controllerOrBus, int unit, virDomainDiskDefPtr *def) { @@ -2284,7 +2298,7 @@ virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf, goto cleanup; } - if (virDomainDiskDefAssignAddress(caps, *def) < 0) { + if (virDomainDiskDefAssignAddress(xmlopt, *def) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not assign address to disk '%s'"), (*def)->src); goto cleanup; @@ -3022,7 +3036,7 @@ virVMXParseSVGA(virConfPtr conf, virDomainVideoDefPtr *def) */ char * -virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, virDomainDefPtr def, +virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virDomainDefPtr def, int virtualHW_version) { char *vmx = NULL; @@ -3231,7 +3245,7 @@ virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, virDomainDefPtr def, /* def:disks */ for (i = 0; i < def->ndisks; ++i) { - if (virVMXVerifyDiskAddress(caps, def->disks[i]) < 0 || + if (virVMXVerifyDiskAddress(xmlopt, def->disks[i]) < 0 || virVMXHandleLegacySCSIDiskDriverName(def, def->disks[i]) < 0) { goto cleanup; } diff --git a/src/vmx/vmx.h b/src/vmx/vmx.h index f4877b11c405cb65cc45187cb196a766b049c71f..ec63317c965c13c63c2d113683f10a8476711942 100644 --- a/src/vmx/vmx.h +++ b/src/vmx/vmx.h @@ -29,6 +29,7 @@ typedef struct _virVMXContext virVMXContext; +virDomainXMLOptionPtr virVMXDomainXMLConfInit(void); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -78,7 +79,8 @@ char *virVMXConvertToUTF8(const char *encoding, const char *string); * VMX -> Domain XML */ -virDomainDefPtr virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, +virDomainDefPtr virVMXParseConfig(virVMXContext *ctx, + virDomainXMLOptionPtr xmlopt, const char *vmx); int virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def); @@ -86,9 +88,9 @@ int virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def); int virVMXParseSCSIController(virConfPtr conf, int controller, bool *present, int *virtualDev); -int virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf, - int device, int busType, int controllerOrBus, int unit, - virDomainDiskDefPtr *def); +int virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, + virConfPtr conf, int device, int busType, + int controllerOrBus, int unit, virDomainDiskDefPtr *def); int virVMXParseFileSystem(virConfPtr conf, int number, virDomainFSDefPtr *def); @@ -108,7 +110,7 @@ int virVMXParseSVGA(virConfPtr conf, virDomainVideoDefPtr *def); * Domain XML -> VMX */ -char *virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, +char *virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virDomainDefPtr def, int virtualHW_version); int virVMXFormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer); diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c index cee4c3950cd503c3e6805c409726fcbc8324d164..429dc81ddc1450b9faa5d586441637ba468bff70 100644 --- a/tests/vmx2xmltest.c +++ b/tests/vmx2xmltest.c @@ -12,6 +12,7 @@ # include "vmx/vmx.h" static virCapsPtr caps; +static virDomainXMLOptionPtr xmlopt; static virVMXContext ctx; static int testDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED, @@ -36,8 +37,6 @@ testCapsInit(void) virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 }); virCapabilitiesAddHostMigrateTransport(caps, "esx"); - caps->hasWideScsiBus = true; - /* i686 guest */ guest = virCapabilitiesAddGuest(caps, "hvm", @@ -93,7 +92,7 @@ testCompareFiles(const char *vmx, const char *xml) goto failure; } - def = virVMXParseConfig(&ctx, caps, vmxData); + def = virVMXParseConfig(&ctx, xmlopt, vmxData); if (def == NULL) { err = virGetLastError(); @@ -221,6 +220,9 @@ mymain(void) return EXIT_FAILURE; } + if (!(xmlopt = virVMXDomainXMLConfInit())) + return EXIT_FAILURE; + ctx.opaque = NULL; ctx.parseFileName = testParseVMXFileName; ctx.formatFileName = NULL; @@ -296,6 +298,7 @@ mymain(void) DO_TEST("svga", "svga"); virObjectUnref(caps); + virObjectUnref(xmlopt); return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c index cee7f9e1a945c3ff3834c7e1c6af085c7057b20f..7e2d4caf1deddac005a5a7873aab64fedebd4bfe 100644 --- a/tests/xml2vmxtest.c +++ b/tests/xml2vmxtest.c @@ -37,7 +37,6 @@ testCapsInit(void) virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 }); virCapabilitiesAddHostMigrateTransport(caps, "esx"); - caps->hasWideScsiBus = true; /* i686 guest */ guest = @@ -102,7 +101,7 @@ testCompareFiles(const char *xml, const char *vmx, int virtualHW_version) goto failure; } - formatted = virVMXFormatConfig(&ctx, caps, def, virtualHW_version); + formatted = virVMXFormatConfig(&ctx, xmlopt, def, virtualHW_version); if (formatted == NULL) { goto failure; @@ -240,7 +239,7 @@ mymain(void) return EXIT_FAILURE; } - if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL))) + if (!(xmlopt = virVMXDomainXMLConfInit())) return EXIT_FAILURE; ctx.opaque = NULL; @@ -312,6 +311,7 @@ mymain(void) DO_TEST("svga", "svga", 4); virObjectUnref(caps); + virObjectUnref(xmlopt); return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }