diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d3ea79b708..0425fbaca3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4213,16 +4213,11 @@ virDomainSkipBackcompatConsole(virDomainDefPtr def, } -enum { - DOMAIN_DEVICE_ITERATE_ALL_CONSOLES = 1 << 0, - DOMAIN_DEVICE_ITERATE_MISSING_INFO = 1 << 1, -} virDomainDeviceIterateFlags; - /* * Iterates over domain devices calling @cb on each device. The default * behaviour can be altered with virDomainDeviceIterateFlags. */ -static int +int virDomainDeviceInfoIterateFlags(virDomainDefPtr def, virDomainDeviceInfoCallback cb, unsigned int iteratorFlags, @@ -6427,143 +6422,6 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, } -struct virDomainDefValidateAliasesData { - GHashTable *aliases; -}; - - -static int -virDomainDeviceDefValidateAliasesIterator(virDomainDefPtr def, - virDomainDeviceDefPtr dev, - virDomainDeviceInfoPtr info, - void *opaque) -{ - struct virDomainDefValidateAliasesData *data = opaque; - const char *alias = info->alias; - - if (!virDomainDeviceAliasIsUserAlias(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 (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV && - dev->data.hostdev->parentnet) { - /* This hostdev is a copy of some previous interface. - * Aliases are duplicated. */ - 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(const virDomainDef *def, - GHashTable **aliases) -{ - struct virDomainDefValidateAliasesData data; - int ret = -1; - - /* We are not storing copies of aliases. Don't free them. */ - if (!(data.aliases = virHashNew(NULL))) - goto cleanup; - - if (virDomainDeviceInfoIterateFlags((virDomainDefPtr) def, - virDomainDeviceDefValidateAliasesIterator, - DOMAIN_DEVICE_ITERATE_ALL_CONSOLES, - &data) < 0) - goto cleanup; - - if (aliases) - *aliases = g_steal_pointer(&data.aliases); - - ret = 0; - cleanup: - virHashFree(data.aliases); - return ret; -} - - -static int -virDomainDeviceValidateAliasImpl(const virDomainDef *def, - virDomainDeviceDefPtr dev) -{ - GHashTable *aliases = NULL; - virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev); - int ret = -1; - - if (!info || !info->alias) - return 0; - - if (virDomainDefValidateAliases(def, &aliases) < 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(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(persDef, dev) < 0) - return -1; - - if (liveDef && - virDomainDeviceValidateAliasImpl(liveDef, dev) < 0) - return -1; - - return 0; -} - - static int virDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 71e42d6617..ba03a55c7b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2759,6 +2759,11 @@ typedef enum { VIR_DOMAIN_TAINT_LAST } virDomainTaintFlags; +typedef enum { + DOMAIN_DEVICE_ITERATE_ALL_CONSOLES = 1 << 0, + DOMAIN_DEVICE_ITERATE_MISSING_INFO = 1 << 1, +} virDomainDeviceIterateFlags; + /* Guest VM runtime state */ typedef struct _virDomainStateReason virDomainStateReason; struct _virDomainStateReason { @@ -2987,10 +2992,6 @@ int virDomainDefPostParse(virDomainDefPtr def, void *parseOpaque); bool virDomainDefHasUSB(const virDomainDef *def); -int virDomainDeviceValidateAliasForHotplug(virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - unsigned int flags); - bool virDomainDeviceAliasIsUserAlias(const char *aliasStr); int virDomainDefValidate(virDomainDefPtr def, @@ -3130,6 +3131,11 @@ virDomainChrSourceDefNew(virDomainXMLOptionPtr xmlopt); virDomainChrDefPtr virDomainChrDefNew(virDomainXMLOptionPtr xmlopt); +int virDomainDeviceInfoIterateFlags(virDomainDefPtr def, + virDomainDeviceInfoCallback cb, + unsigned int iteratorFlags, + void *opaque); + virDomainGraphicsDefPtr virDomainGraphicsDefNew(virDomainXMLOptionPtr xmlopt); diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 8bbd60c836..962336033f 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -760,3 +760,141 @@ virDomainDefDuplicateDriveAddressesValidate(const virDomainDef *def) return 0; } + + + +struct virDomainDefValidateAliasesData { + GHashTable *aliases; +}; + + +static int +virDomainDeviceDefValidateAliasesIterator(virDomainDefPtr def, + virDomainDeviceDefPtr dev, + virDomainDeviceInfoPtr info, + void *opaque) +{ + struct virDomainDefValidateAliasesData *data = opaque; + const char *alias = info->alias; + + if (!virDomainDeviceAliasIsUserAlias(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 (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV && + dev->data.hostdev->parentnet) { + /* This hostdev is a copy of some previous interface. + * Aliases are duplicated. */ + 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). + */ +int +virDomainDefValidateAliases(const virDomainDef *def, + GHashTable **aliases) +{ + struct virDomainDefValidateAliasesData data; + int ret = -1; + + /* We are not storing copies of aliases. Don't free them. */ + if (!(data.aliases = virHashNew(NULL))) + goto cleanup; + + if (virDomainDeviceInfoIterateFlags((virDomainDefPtr) def, + virDomainDeviceDefValidateAliasesIterator, + DOMAIN_DEVICE_ITERATE_ALL_CONSOLES, + &data) < 0) + goto cleanup; + + if (aliases) + *aliases = g_steal_pointer(&data.aliases); + + ret = 0; + cleanup: + virHashFree(data.aliases); + return ret; +} + + +static int +virDomainDeviceValidateAliasImpl(const virDomainDef *def, + virDomainDeviceDefPtr dev) +{ + GHashTable *aliases = NULL; + virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev); + int ret = -1; + + if (!info || !info->alias) + return 0; + + if (virDomainDefValidateAliases(def, &aliases) < 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(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(persDef, dev) < 0) + return -1; + + if (liveDef && + virDomainDeviceValidateAliasImpl(liveDef, dev) < 0) + return -1; + + return 0; +} diff --git a/src/conf/domain_validate.h b/src/conf/domain_validate.h index 1f1a5b1bd1..521a98ef11 100644 --- a/src/conf/domain_validate.h +++ b/src/conf/domain_validate.h @@ -47,3 +47,8 @@ int virDomainControllerDefValidate(const virDomainControllerDef *controller); int virDomainDefIdMapValidate(const virDomainDef *def); int virDomainDefDuplicateDiskInfoValidate(const virDomainDef *def); int virDomainDefDuplicateDriveAddressesValidate(const virDomainDef *def); +int virDomainDefValidateAliases(const virDomainDef *def, + GHashTable **aliases); +int virDomainDeviceValidateAliasForHotplug(virDomainObjPtr vm, + virDomainDeviceDefPtr dev, + unsigned int flags); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 992488f754..c3056232db 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -354,7 +354,6 @@ virDomainDeviceGetInfo; virDomainDeviceInfoIterate; virDomainDeviceSetData; virDomainDeviceTypeToString; -virDomainDeviceValidateAliasForHotplug; virDomainDiskBackingStoreFormat; virDomainDiskBackingStoreParse; virDomainDiskBusTypeToString; @@ -744,6 +743,10 @@ virDomainConfNWFilterTeardown; virDomainConfVMNWFilterTeardown; +# conf/domain_validate.h +virDomainDeviceValidateAliasForHotplug; + + # conf/interface_conf.h virInterfaceDefFormat; virInterfaceDefFree; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 58c376fbe5..5f0fb0a55f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -70,6 +70,7 @@ #include "domain_audit.h" #include "domain_cgroup.h" #include "domain_driver.h" +#include "domain_validate.h" #include "node_device_conf.h" #include "virpci.h" #include "virusb.h"