[libvirt] [PATCH v2 00/11] Never ending story of user supplied aliases

v2 of: https://www.redhat.com/archives/libvir-list/2017-October/msg00790.html diff to v1: - new patch 1/11 to address Pavel's findings - reworked parsing so that the alias is set iff it follows the rules - added some tests - added news.xml entry Michal Privoznik (11): qemu_alias: Be more tolerant if alias don't follow our format conf: Parse user supplied aliases conf: Validate user supplied aliases qemuDomainABIStabilityCheck: Check for memory aliases too qemuxml2argvdata: Drop device aliases qemuhotplugtest: Load active XML conf: Format alias even for inactive XMLs docs: Document user aliases qemu: Parse alias from inactive XMLs tests: Test user set aliases for qemu news: Document user aliases docs/formatdomain.html.in | 23 +++ docs/news.xml | 9 ++ src/conf/domain_conf.c | 171 ++++++++++++++++++++- src/conf/domain_conf.h | 6 + src/libvirt_private.syms | 1 + src/qemu/qemu_alias.c | 22 +-- src/qemu/qemu_domain.c | 18 ++- src/qemu/qemu_driver.c | 3 + tests/qemuhotplugtest.c | 3 +- .../qemuxml2argv-disk-cdrom-network-ftp.xml | 1 - .../qemuxml2argv-disk-cdrom-network-ftps.xml | 1 - .../qemuxml2argv-disk-cdrom-network-http.xml | 1 - .../qemuxml2argv-disk-cdrom-network-https.xml | 1 - .../qemuxml2argv-disk-cdrom-network-tftp.xml | 1 - .../qemuxml2argv-usb-redir-filter.xml | 1 - .../qemuxml2argv-user-aliases.args | 71 +++++++++ .../qemuxml2argvdata/qemuxml2argv-user-aliases.xml | 140 +++++++++++++++++ tests/qemuxml2argvtest.c | 5 + .../qemuxml2xmlout-user-aliases.xml | 1 + tests/qemuxml2xmltest.c | 2 + 20 files changed, 449 insertions(+), 32 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.xml create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-user-aliases.xml -- 2.13.6

When assigning alias to a device we usually iterate over other devices of its kind trying to find next index. We do this by stripping down the prefix and then parsing number at the end, Usually, if the prefix doesn't match the one we are expecting, we just continue with next iteration. Except for couple of functions: qemuGetNextChrDevIndex(), qemuAssignDeviceRedirdevAlias() and qemuAssignDeviceShmemAlias(). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_alias.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index d06a3d63e..37fe2aa80 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -73,11 +73,8 @@ qemuGetNextChrDevIndex(virDomainDefPtr def, ssize_t thisidx; if (((thisidx = qemuDomainDeviceAliasIndex(&arrPtr[i]->info, prefix)) < 0) && (prefix2 && - (thisidx = qemuDomainDeviceAliasIndex(&arrPtr[i]->info, prefix2)) < 0)) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Unable to determine device index for character device")); - return -1; - } + (thisidx = qemuDomainDeviceAliasIndex(&arrPtr[i]->info, prefix2)) < 0)) + continue; if (thisidx >= idx) idx = thisidx + 1; } @@ -391,11 +388,8 @@ qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, idx = 0; for (i = 0; i < def->nredirdevs; i++) { int thisidx; - if ((thisidx = qemuDomainDeviceAliasIndex(&def->redirdevs[i]->info, "redir")) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Unable to determine device index for redirected device")); - return -1; - } + if ((thisidx = qemuDomainDeviceAliasIndex(&def->redirdevs[i]->info, "redir")) < 0) + continue; if (thisidx >= idx) idx = thisidx + 1; } @@ -491,12 +485,8 @@ qemuAssignDeviceShmemAlias(virDomainDefPtr def, int thisidx; if ((thisidx = qemuDomainDeviceAliasIndex(&def->shmems[i]->info, - "shmem")) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Unable to determine device index " - "for shmem device")); - return -1; - } + "shmem")) < 0) + continue; if (thisidx >= idx) idx = thisidx + 1; -- 2.13.6

If driver that is calling the parse supports user supplied aliases, they can be parsed even for inactive XMLs. However, to avoid any clashes with aliases that libvirt generates, the user ones have to have "ua-" prefix. Note, that some drivers don't have notion of device aliases at all. Also, in order to support user supplied aliases some extra checks need to be done (e.g. during hotplug). Therefore we can't just enable this feature for all the drivers. Thus we need a flag that drivers set to tell parsing code that they can handle user supplied device aliases. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 18 +++++++++++++++--- src/conf/domain_conf.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ce9b4ee7f..40fcbc7df 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6454,6 +6454,10 @@ virDomainDeviceAddressParseXML(xmlNodePtr address, } +#define USER_ALIAS_PREFIX "ua-" +#define USER_ALIAS_CHARS \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" + /* Parse the XML definition for a device address * @param node XML nodeset to parse for device address definition */ @@ -6472,6 +6476,7 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED, xmlNodePtr rom = NULL; char *type = NULL; char *rombar = NULL; + char *aliasStr = NULL; int ret = -1; virDomainDeviceInfoClear(info); @@ -6480,7 +6485,6 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED, while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { if (alias == NULL && - !(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) && virXMLNodeNameEqual(cur, "alias")) { alias = cur; } else if (address == NULL && @@ -6502,8 +6506,15 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED, cur = cur->next; } - if (alias) - info->alias = virXMLPropString(alias, "name"); + if (alias) { + aliasStr = virXMLPropString(alias, "name"); + + if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) || + (xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_USER_ALIAS && + STRPREFIX(aliasStr, USER_ALIAS_PREFIX) && + strspn(aliasStr, USER_ALIAS_CHARS) == strlen(aliasStr))) + VIR_STEAL_PTR(info->alias, aliasStr); + } if (master) { info->mastertype = VIR_DOMAIN_CONTROLLER_MASTER_USB; @@ -6537,6 +6548,7 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED, virDomainDeviceInfoClear(info); VIR_FREE(type); VIR_FREE(rombar); + VIR_FREE(aliasStr); return ret; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f251f390b..1a3574aa7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2488,6 +2488,7 @@ typedef enum { VIR_DOMAIN_DEF_FEATURE_OFFLINE_VCPUPIN = (1 << 2), VIR_DOMAIN_DEF_FEATURE_NAME_SLASH = (1 << 3), VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS = (1 << 4), + VIR_DOMAIN_DEF_FEATURE_USER_ALIAS = (1 << 5), } virDomainDefFeatures; -- 2.13.6

They have to be unique within the domain. As usual, backwards compatibility takes its price. In this particular situation we have a device that is represented twice in a domain and so is its alias. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 5 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 3 + 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 40fcbc7df..ad71e951b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5457,6 +5457,145 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, } +struct virDomainDefValidateAliasesData { + virHashTablePtr aliases; +}; + + +static int +virDomainDeviceDefValidateAliasesIterator(virDomainDefPtr def, + virDomainDeviceDefPtr dev, + virDomainDeviceInfoPtr info, + void *opaque) +{ + struct virDomainDefValidateAliasesData *data = opaque; + const char *alias = info->alias; + + if (!alias) + return 0; + + /* Some crazy backcompat for consoles. */ + if (def->nserials && def->nconsoles && + def->consoles[0]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE && + def->consoles[0]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL && + dev->type == VIR_DOMAIN_DEVICE_CHR && + virDomainChrEquals(def->serials[0], dev->data.chr)) + return 0; + + if (virHashLookup(data->aliases, alias)) { + virReportError(VIR_ERR_XML_ERROR, + _("non unique alias detected: %s"), + alias); + return -1; + } + + if (virHashAddEntry(data->aliases, alias, (void *) 1) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to construct table of device aliases")); + return -1; + } + + return 0; +} + + +/** + * virDomainDefValidateAliases: + * + * Check for uniqueness of device aliases. If @aliases is not + * NULL return hash table of all the aliases in it. + * + * Returns 0 on success, + * -1 otherwise (with error reported). + */ +static int +virDomainDefValidateAliases(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED, + const virDomainDef *def, + virHashTablePtr *aliases, + unsigned int parseFlags) +{ + struct virDomainDefValidateAliasesData data; + int ret = -1; + + /* validate configuration only in certain places */ + if (parseFlags & VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE) + return 0; + + /* We are not storing copies of aliases. Don't free them. */ + if (!(data.aliases = virHashCreate(10, NULL))) + goto cleanup; + + if (virDomainDeviceInfoIterateInternal((virDomainDefPtr) def, + virDomainDeviceDefValidateAliasesIterator, + true, &data) < 0) + goto cleanup; + + if (aliases) { + *aliases = data.aliases; + data.aliases = NULL; + } + + ret = 0; + cleanup: + virHashFree(data.aliases); + return ret; +} + + +static int +virDomainDeviceValidateAliasImpl(virDomainXMLOptionPtr xmlopt, + const virDomainDef *def, + virDomainDeviceDefPtr dev) +{ + virHashTablePtr aliases = NULL; + virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev); + int ret = -1; + + if (!info || !info->alias) + return 0; + + if (virDomainDefValidateAliases(xmlopt, def, &aliases, 0) < 0) + goto cleanup; + + if (virHashLookup(aliases, info->alias)) { + virReportError(VIR_ERR_XML_ERROR, + _("non unique alias detected: %s"), + info->alias); + goto cleanup; + } + + ret = 0; + cleanup: + + virHashFree(aliases); + return ret; +} + + +int +virDomainDeviceValidateAliasForHotplug(virDomainXMLOptionPtr xmlopt, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev, + unsigned int flags) +{ + virDomainDefPtr persDef = NULL; + virDomainDefPtr liveDef = NULL; + + if (virDomainObjGetDefs(vm, flags, &liveDef, &persDef) < 0) + return -1; + + if (persDef && + virDomainDeviceValidateAliasImpl(xmlopt, vm->def, dev) < 0) + return -1; + + if (liveDef && + virDomainDeviceValidateAliasImpl(xmlopt, vm->newDef, dev) < 0) + return -1; + + return 0; +} + + static int virDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def, @@ -5668,7 +5807,9 @@ virDomainDefLifecycleActionValidate(const virDomainDef *def) static int -virDomainDefValidateInternal(const virDomainDef *def) +virDomainDefValidateInternal(virDomainXMLOptionPtr xmlopt, + const virDomainDef *def, + unsigned int parseFlags) { if (virDomainDefCheckDuplicateDiskInfo(def) < 0) return -1; @@ -5679,6 +5820,9 @@ virDomainDefValidateInternal(const virDomainDef *def) if (virDomainDefGetVcpusTopology(def, NULL) < 0) return -1; + if (virDomainDefValidateAliases(xmlopt, def, NULL, parseFlags) < 0) + return -1; + if (def->iommu && def->iommu->intremap == VIR_TRISTATE_SWITCH_ON && (def->features[VIR_DOMAIN_FEATURE_IOAPIC] != VIR_TRISTATE_SWITCH_ON || @@ -5746,7 +5890,7 @@ virDomainDefValidate(virDomainDefPtr def, true, &data) < 0) return -1; - if (virDomainDefValidateInternal(def) < 0) + if (virDomainDefValidateInternal(xmlopt, def, parseFlags) < 0) return -1; return 0; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1a3574aa7..b3ecec4ed 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2639,6 +2639,11 @@ int virDomainDefPostParse(virDomainDefPtr def, virDomainXMLOptionPtr xmlopt, void *parseOpaque); +int virDomainDeviceValidateAliasForHotplug(virDomainXMLOptionPtr xmlopt, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev, + unsigned int flags); + int virDomainDefValidate(virDomainDefPtr def, virCapsPtr caps, unsigned int parseFlags, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4f076827b..448d962b2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -296,6 +296,7 @@ virDomainDeviceFindControllerModel; virDomainDeviceGetInfo; virDomainDeviceInfoIterate; virDomainDeviceTypeToString; +virDomainDeviceValidateAliasForHotplug; virDomainDiskBusTypeToString; virDomainDiskByAddress; virDomainDiskByName; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 826d1340e..b210e9233 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8396,6 +8396,9 @@ qemuDomainAttachDeviceLiveAndConfig(virConnectPtr conn, if (dev == NULL) goto cleanup; + if (virDomainDeviceValidateAliasForHotplug(driver->xmlopt, vm, dev, flags) < 0) + goto cleanup; + if (flags & VIR_DOMAIN_AFFECT_CONFIG && flags & VIR_DOMAIN_AFFECT_LIVE) { /* If we are affecting both CONFIG and LIVE -- 2.13.6

On Fri, Oct 20, 2017 at 04:52:13PM +0200, Michal Privoznik wrote:
They have to be unique within the domain. As usual, backwards compatibility takes its price. In this particular situation we have a device that is represented twice in a domain and so is its alias.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 5 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 3 + 4 files changed, 155 insertions(+), 2 deletions(-)
ACK with the 'xmlopt' and 'parseFlags' arguments removed, see below:
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 40fcbc7df..ad71e951b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5457,6 +5457,145 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, }
+struct virDomainDefValidateAliasesData { + virHashTablePtr aliases; +}; + + +static int +virDomainDeviceDefValidateAliasesIterator(virDomainDefPtr def, + virDomainDeviceDefPtr dev, + virDomainDeviceInfoPtr info, + void *opaque) +{ + struct virDomainDefValidateAliasesData *data = opaque; + const char *alias = info->alias; + + if (!alias) + return 0; + + /* Some crazy backcompat for consoles. */ + if (def->nserials && def->nconsoles && + def->consoles[0]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE && + def->consoles[0]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL && + dev->type == VIR_DOMAIN_DEVICE_CHR && + virDomainChrEquals(def->serials[0], dev->data.chr)) + return 0; + + if (virHashLookup(data->aliases, alias)) { + virReportError(VIR_ERR_XML_ERROR, + _("non unique alias detected: %s"), + alias); + return -1; + } + + if (virHashAddEntry(data->aliases, alias, (void *) 1) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to construct table of device aliases")); + return -1; + } + + return 0; +} + + +/** + * virDomainDefValidateAliases: + * + * Check for uniqueness of device aliases. If @aliases is not + * NULL return hash table of all the aliases in it. + * + * Returns 0 on success, + * -1 otherwise (with error reported). + */ +static int +virDomainDefValidateAliases(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED,
xmlopt is unused here and all the other occurences in this patch.
+ const virDomainDef *def, + virHashTablePtr *aliases, + unsigned int parseFlags) +{ + struct virDomainDefValidateAliasesData data; + int ret = -1; + + /* validate configuration only in certain places */ + if (parseFlags & VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE) + return 0;
This is checked from the virDomainDefValidateInternal path before virDomainDefValidateInternal is even called. And virDomainDeviceValidateAliasImpl always passes 0, so this condition is redundant and 'parseFlags' can be dropped too.
+ + /* We are not storing copies of aliases. Don't free them. */ + if (!(data.aliases = virHashCreate(10, NULL))) + goto cleanup; +
Jan

Since we will be allowing users to set device aliases and memory devices are fragile when it comes to aliases we have to make sure they won't change during migration. Other devices should be fine. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_domain.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ece8ee7dd..3b94db99f 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6428,6 +6428,8 @@ static bool qemuDomainABIStabilityCheck(const virDomainDef *src, const virDomainDef *dst) { + size_t i; + if (src->mem.source != dst->mem.source) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target memoryBacking source '%s' doesn't " @@ -6437,6 +6439,19 @@ qemuDomainABIStabilityCheck(const virDomainDef *src, return false; } + for (i = 0; i < src->nmems; i++) { + const char *srcAlias = src->mems[i]->info.alias; + const char *dstAlias = dst->mems[i]->info.alias; + + if (STRNEQ_NULLABLE(srcAlias, dstAlias)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memory device alias '%s' doesn't " + "match source alias '%s'"), + NULLSTR(srcAlias), NULLSTR(dstAlias)); + return false; + } + } + return true; } -- 2.13.6

The qemuxml2argvtest expects the domain XMLs to be inactive ones. Therefore we should pass inactive XMLs. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftp.xml | 1 - tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml | 1 - tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-http.xml | 1 - tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml | 1 - tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml | 1 - tests/qemuxml2argvdata/qemuxml2argv-usb-redir-filter.xml | 1 - 6 files changed, 6 deletions(-) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftp.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftp.xml index df41e5832..b4e331160 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftp.xml @@ -26,7 +26,6 @@ </source> <target dev='hdc' bus='ide'/> <readonly/> - <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml index 57049a266..4e6ca1bad 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml @@ -26,7 +26,6 @@ </source> <target dev='hdc' bus='ide'/> <readonly/> - <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-http.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-http.xml index 8a1286cb1..0eed65672 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-http.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-http.xml @@ -26,7 +26,6 @@ </source> <target dev='hdc' bus='ide'/> <readonly/> - <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml index 41b5a89b6..cd92fe44a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml @@ -26,7 +26,6 @@ </source> <target dev='hdc' bus='ide'/> <readonly/> - <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml index e2cb4a006..1c3b185b0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml @@ -26,7 +26,6 @@ </source> <target dev='hdc' bus='ide'/> <readonly/> - <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir-filter.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir-filter.xml index 32fb890a1..0bc15f0df 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir-filter.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir-filter.xml @@ -33,7 +33,6 @@ <address type='usb' bus='0' port='4'/> </redirdev> <redirdev bus='usb' type='spicevmc'> - <alias name='redir1'/> <address type='usb' bus='0' port='5'/> </redirdev> <redirfilter> -- 2.13.6

The point of this test is to load live XML and test hotplug. But even though the XMLs we are parsing are live, the parsing is done with VIR_DOMAIN_DEF_PARSE_INACTIVE flag. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemuhotplugtest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index df28a7fbd..8d77c0056 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -62,6 +62,7 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, { int ret = -1; qemuDomainObjPrivatePtr priv = NULL; + const unsigned int parseFlags = 0; if (!(*vm = virDomainObjNew(xmlopt))) goto cleanup; @@ -87,7 +88,7 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, driver.caps, driver.xmlopt, NULL, - VIR_DOMAIN_DEF_PARSE_INACTIVE))) + parseFlags))) goto cleanup; if (qemuDomainAssignAddresses((*vm)->def, priv->qemuCaps, -- 2.13.6

We need to format alias even for inactive XMLs since that's the way how users are going to identify their devices. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ad71e951b..38e7fee43 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5972,10 +5972,9 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAddLit(buf, "/>\n"); } - if (info->alias && - !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) { + + if (info->alias) virBufferAsprintf(buf, "<alias name='%s'/>\n", info->alias); - } if (info->mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) { virBufferAsprintf(buf, "<master startport='%d'/>\n", -- 2.13.6

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.html.in | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b7d7cba5a..4609e2ec2 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2256,6 +2256,29 @@ </dd> </dl> + <p> + To help users identifying devices they care about, every + device can have direct child <code>alias</code> element + which then has <code>name</code> attribute where users can + store identifier for the device. The identifier has to have + "ua-" prefix and must be unique within the domain. Additionally, the + identifier must consist only of the following characters: + <code>[a-zA-Z0-9_-]</code>. + <span class="since">Since 3.9.0</span> + </p> + +<pre> +<devices> + <disk type='file'> + <alias name='ua-myDisk'/> + </disk> + <interface type='network' trustGuestRxFilters='yes'> + <alias name='ua-myNIC'/> + </interface> + ... +</devices> +</pre> + <h4><a id="elementsDisks">Hard drives, floppy disks, CDROMs</a></h4> <p> -- 2.13.6

https://bugzilla.redhat.com/show_bug.cgi?id=1434451 This way users can uniquely identify devices at define time. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_domain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3b94db99f..c7c9e94da 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4176,7 +4176,8 @@ virDomainDefParserConfig virQEMUDriverDomainDefParserConfig = { .features = VIR_DOMAIN_DEF_FEATURE_MEMORY_HOTPLUG | VIR_DOMAIN_DEF_FEATURE_OFFLINE_VCPUPIN | - VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS, + VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS | + VIR_DOMAIN_DEF_FEATURE_USER_ALIAS, }; -- 2.13.6

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- .../qemuxml2argv-user-aliases.args | 71 +++++++++++ .../qemuxml2argvdata/qemuxml2argv-user-aliases.xml | 140 +++++++++++++++++++++ tests/qemuxml2argvtest.c | 5 + .../qemuxml2xmlout-user-aliases.xml | 1 + tests/qemuxml2xmltest.c | 2 + 5 files changed, 219 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.xml create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-user-aliases.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-user-aliases.args b/tests/qemuxml2argvdata/qemuxml2argv-user-aliases.args new file mode 100644 index 000000000..62fbd567b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-user-aliases.args @@ -0,0 +1,71 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name gentoo \ +-S \ +-M pc-i440fx-1.4 \ +-m 4096 \ +-smp 4,sockets=4,cores=1,threads=1 \ +-object memory-backend-file,id=ram-node0,prealloc=yes,\ +mem-path=/dev/hugepages1G/libvirt/qemu/-1-gentoo,size=1073741824 \ +-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +-object memory-backend-file,id=ram-node1,prealloc=yes,\ +mem-path=/dev/hugepages1G/libvirt/qemu/-1-gentoo,size=1073741824 \ +-numa node,nodeid=1,cpus=1,memdev=ram-node1 \ +-object memory-backend-file,id=ram-node2,prealloc=yes,\ +mem-path=/dev/hugepages1G/libvirt/qemu/-1-gentoo,size=1073741824 \ +-numa node,nodeid=2,cpus=2,memdev=ram-node2 \ +-object memory-backend-file,id=ram-node3,prealloc=yes,\ +mem-path=/dev/hugepages1G/libvirt/qemu/-1-gentoo,size=1073741824 \ +-numa node,nodeid=3,cpus=3,memdev=ram-node3 \ +-uuid a75aca4b-a02f-2bcb-4a91-c93cd848c34b \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-gentoo/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-global PIIX4_PM.disable_s3=0 \ +-global PIIX4_PM.disable_s4=0 \ +-boot cd \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x8 \ +-usb \ +-drive file=/var/lib/libvirt/images/fd.img,format=raw,if=none,\ +id=drive-ua-myDisk1,cache=none \ +-global isa-fdc.driveA=drive-ua-myDisk1 \ +-drive file=/var/lib/libvirt/images/gentoo.qcow2,format=qcow2,if=none,\ +id=drive-ua-myDisk2 \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-ua-myDisk2,id=ua-myDisk2 \ +-drive file=/var/lib/libvirt/images/OtherDemo.img,format=qcow2,if=none,\ +id=drive-ua-myEncryptedDisk1 \ +-device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-ua-myEncryptedDisk1,\ +id=ua-myEncryptedDisk1 \ +-drive file=/home/zippy/tmp/install-amd64-minimal-20140619.iso,format=raw,\ +if=none,media=cdrom,id=drive-ua-WhatAnAwesomeCDROM,readonly=on,cache=none \ +-device ide-drive,bus=ua-DoesAnybodyStillUseIDE.1,unit=0,\ +drive=drive-ua-WhatAnAwesomeCDROM,id=ua-WhatAnAwesomeCDROM \ +-device virtio-net-pci,vlan=0,id=ua-CheckoutThisNIC,mac=52:54:00:d6:c0:0b,\ +bus=pci.0,addr=0x3 \ +-net tap,fd=3,vlan=0,name=hostua-CheckoutThisNIC \ +-device rtl8139,vlan=1,id=ua-WeCanAlsoDoServerMode,mac=52:54:00:22:c9:42,\ +bus=pci.0,addr=0x9 \ +-net socket,listen=127.0.0.1:1234,vlan=1,name=hostua-WeCanAlsoDoServerMode \ +-device rtl8139,vlan=2,id=ua-AndAlsoClientMode,mac=52:54:00:8c:b1:f8,bus=pci.0,\ +addr=0xa \ +-net socket,connect=127.0.0.1:1234,vlan=2,name=hostua-AndAlsoClientMode \ +-chardev pty,id=charserial0 \ +-device isa-serial,chardev=charserial0,id=serial0 \ +-chardev pty,id=charserial1 \ +-device isa-serial,chardev=charserial1,id=serial1 \ +-chardev socket,id=charchannel0,\ +path=/var/lib/libvirt/qemu/channel/target/gentoo.org.qemu.guest_agent.0,server,\ +nowait \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\ +id=channel0,name=org.qemu.guest_agent.0 \ +-vnc 127.0.0.1:0 \ +-vga cirrus \ +-device intel-hda,id=sound0,bus=pci.0,addr=0x4 \ +-device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-user-aliases.xml b/tests/qemuxml2argvdata/qemuxml2argv-user-aliases.xml new file mode 100644 index 000000000..d1cb8fea6 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-user-aliases.xml @@ -0,0 +1,140 @@ +<domain type='kvm'> + <name>gentoo</name> + <uuid>a75aca4b-a02f-2bcb-4a91-c93cd848c34b</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <memoryBacking> + <hugepages> + <page size='1048576' unit='KiB' nodeset='0-3'/> + </hugepages> + </memoryBacking> + <vcpu placement='static'>4</vcpu> + <os> + <type arch='x86_64' machine='pc-i440fx-1.4'>hvm</type> + <boot dev='hd'/> + <boot dev='cdrom'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + <cell id='1' cpus='1' memory='1048576' unit='KiB'/> + <cell id='2' cpus='2' memory='1048576' unit='KiB'/> + <cell id='3' cpus='3' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='yes'/> + <suspend-to-disk enabled='yes'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='floppy'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/var/lib/libvirt/images/fd.img'/> + <target dev='fda' bus='fdc'/> + <alias name='ua-myDisk1'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/gentoo.qcow2'/> + <target dev='vda' bus='virtio'/> + <alias name='ua-myDisk2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/OtherDemo.img'/> + <target dev='vdb' bus='virtio'/> + <encryption format='qcow'> + <secret type='passphrase' uuid='e78d4b51-a2af-485f-b0f5-afca709a80f4'/> + </encryption> + <alias name='ua-myEncryptedDisk1'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/home/zippy/tmp/install-amd64-minimal-20140619.iso'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <shareable/> + <alias name='ua-WhatAnAwesomeCDROM'/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <alias name='ua-SomeWeirdController'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + <alias name='ua-DoesAnybodyStillUseIDE'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + </controller> + <controller type='fdc' index='0'/> + <interface type='ethernet'> + <mac address='52:54:00:d6:c0:0b'/> + <model type='virtio'/> + <alias name='ua-CheckoutThisNIC'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <interface type='server'> + <mac address='52:54:00:22:c9:42'/> + <source address='127.0.0.1' port='1234'/> + <bandwidth> + <inbound average='1234'/> + <outbound average='5678'/> + </bandwidth> + <model type='rtl8139'/> + <alias name='ua-WeCanAlsoDoServerMode'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </interface> + <interface type='client'> + <mac address='52:54:00:8c:b1:f8'/> + <source address='127.0.0.1' port='1234'/> + <model type='rtl8139'/> + <alias name='ua-AndAlsoClientMode'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </interface> + <serial type='pty'> + <target port='0'/> + </serial> + <serial type='pty'> + <target port='1'/> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='unix'> + <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/gentoo.org.qemu.guest_agent.0'/> + <target type='virtio' name='org.qemu.guest_agent.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='vnc' port='-1' autoport='yes'> + <listen type='address'/> + </graphics> + <sound model='ich6'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <video> + <model type='cirrus' vram='16384' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ec6fad453..03b1bcbcf 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2811,6 +2811,11 @@ mymain(void) DO_TEST_PARSE_ERROR("cpu-cache-passthrough3", QEMU_CAPS_KVM); DO_TEST_PARSE_ERROR("cpu-cache-passthrough-l3", QEMU_CAPS_KVM); + DO_TEST("user-aliases", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE_CIRRUS_VGA, + QEMU_CAPS_OBJECT_MEMORY_FILE, QEMU_CAPS_PIIX_DISABLE_S3, + QEMU_CAPS_PIIX_DISABLE_S4, QEMU_CAPS_VNC, + QEMU_CAPS_HDA_DUPLEX); + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-user-aliases.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-user-aliases.xml new file mode 120000 index 000000000..5fe737a69 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-user-aliases.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/qemuxml2argv-user-aliases.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 41663a0ea..fdba2adb9 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1271,6 +1271,8 @@ mymain(void) DO_TEST("pseries-cpu-compat", NONE); DO_TEST("pseries-cpu-exact", NONE); + DO_TEST("user-aliases", NONE); + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); -- 2.13.6

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/news.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index ff36c800a..989b82aa5 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -40,6 +40,15 @@ Add capability to allow hot (un)plug of a domain watchdog device </summary> </change> + <change> + <summary> + Allow users to set device aliases + </summary> + <description> + Users can set aliases to domain devices and thus identify them + easily. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.13.6

On Fri, Oct 20, 2017 at 04:52:10PM +0200, Michal Privoznik wrote:
v2 of:
https://www.redhat.com/archives/libvir-list/2017-October/msg00790.html
diff to v1: - new patch 1/11 to address Pavel's findings - reworked parsing so that the alias is set iff it follows the rules - added some tests - added news.xml entry
Michal Privoznik (11): qemu_alias: Be more tolerant if alias don't follow our format conf: Parse user supplied aliases conf: Validate user supplied aliases qemuDomainABIStabilityCheck: Check for memory aliases too qemuxml2argvdata: Drop device aliases qemuhotplugtest: Load active XML conf: Format alias even for inactive XMLs docs: Document user aliases qemu: Parse alias from inactive XMLs tests: Test user set aliases for qemu news: Document user aliases
docs/formatdomain.html.in | 23 +++ docs/news.xml | 9 ++ src/conf/domain_conf.c | 171 ++++++++++++++++++++- src/conf/domain_conf.h | 6 + src/libvirt_private.syms | 1 + src/qemu/qemu_alias.c | 22 +-- src/qemu/qemu_domain.c | 18 ++- src/qemu/qemu_driver.c | 3 + tests/qemuhotplugtest.c | 3 +- .../qemuxml2argv-disk-cdrom-network-ftp.xml | 1 - .../qemuxml2argv-disk-cdrom-network-ftps.xml | 1 - .../qemuxml2argv-disk-cdrom-network-http.xml | 1 - .../qemuxml2argv-disk-cdrom-network-https.xml | 1 - .../qemuxml2argv-disk-cdrom-network-tftp.xml | 1 - .../qemuxml2argv-usb-redir-filter.xml | 1 - .../qemuxml2argv-user-aliases.args | 71 +++++++++ .../qemuxml2argvdata/qemuxml2argv-user-aliases.xml | 140 +++++++++++++++++ tests/qemuxml2argvtest.c | 5 + .../qemuxml2xmlout-user-aliases.xml | 1 + tests/qemuxml2xmltest.c | 2 + 20 files changed, 449 insertions(+), 32 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.xml create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-user-aliases.xml
ACK series Jan

On 10/23/2017 07:53 AM, Ján Tomko wrote:
On Fri, Oct 20, 2017 at 04:52:10PM +0200, Michal Privoznik wrote:
v2 of:
https://www.redhat.com/archives/libvir-list/2017-October/msg00790.html
diff to v1: - new patch 1/11 to address Pavel's findings - reworked parsing so that the alias is set iff it follows the rules - added some tests - added news.xml entry
Michal Privoznik (11): qemu_alias: Be more tolerant if alias don't follow our format conf: Parse user supplied aliases conf: Validate user supplied aliases qemuDomainABIStabilityCheck: Check for memory aliases too qemuxml2argvdata: Drop device aliases qemuhotplugtest: Load active XML conf: Format alias even for inactive XMLs docs: Document user aliases qemu: Parse alias from inactive XMLs tests: Test user set aliases for qemu news: Document user aliases
docs/formatdomain.html.in | 23 +++ docs/news.xml | 9 ++ src/conf/domain_conf.c | 171 ++++++++++++++++++++- src/conf/domain_conf.h | 6 + src/libvirt_private.syms | 1 + src/qemu/qemu_alias.c | 22 +-- src/qemu/qemu_domain.c | 18 ++- src/qemu/qemu_driver.c | 3 + tests/qemuhotplugtest.c | 3 +- .../qemuxml2argv-disk-cdrom-network-ftp.xml | 1 - .../qemuxml2argv-disk-cdrom-network-ftps.xml | 1 - .../qemuxml2argv-disk-cdrom-network-http.xml | 1 - .../qemuxml2argv-disk-cdrom-network-https.xml | 1 - .../qemuxml2argv-disk-cdrom-network-tftp.xml | 1 - .../qemuxml2argv-usb-redir-filter.xml | 1 - .../qemuxml2argv-user-aliases.args | 71 +++++++++ .../qemuxml2argvdata/qemuxml2argv-user-aliases.xml | 140 +++++++++++++++++ tests/qemuxml2argvtest.c | 5 + .../qemuxml2xmlout-user-aliases.xml | 1 + tests/qemuxml2xmltest.c | 2 + 20 files changed, 449 insertions(+), 32 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-user-aliases.xml create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-user-aliases.xml
ACK series
Thanks. Fixed 03/11 and pushed. Michal
participants (2)
-
Ján Tomko
-
Michal Privoznik