[libvirt] [PATCH 3/6] conf: Introduce infrastructure to add config validation to define time

John Ferlan jferlan at redhat.com
Tue May 17 20:41:30 UTC 2016



On 05/17/2016 10:25 AM, Peter Krempa wrote:
> Recently there were a few patches adding checks to the post parse
> callback infrastructure that rejected previously accepted configuration.
> This unfortunately was not acceptable since we would fail to load the
> configs from the disk and the VMs would vanish.
> 
> This patch adds helpers which are called in the appropriate places after
> the config is parsed when defining/starting a VM but not when reloading
> the configs.
> 
> This infrastructure is meant for invalid configurations that were
> accepted previously and thus it's not executed when starting a VM from
> any saved state. Any checks that are necessary to be executed at that
> point still need to be added to qemuProcessValidateXML.
> ---
>  src/conf/domain_conf.c   | 67 ++++++++++++++++++++++++++++++++++++++----------
>  src/conf/domain_conf.h   |  2 ++
>  src/libvirt_private.syms |  1 +
>  src/qemu/qemu_conf.h     |  2 ++
>  src/qemu/qemu_domain.c   | 21 +++++++++++++++
>  src/qemu/qemu_driver.c   |  6 +++++
>  src/qemu/qemu_process.c  | 22 +++++++++++-----
>  7 files changed, 100 insertions(+), 21 deletions(-)
> 
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 12f9da2..7359dc7 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -4145,20 +4145,6 @@ virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev,
>              }
>          }
> 
> -        /* Validate LUN configuration */
> -        if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
> -            /* volumes haven't been translated at this point, so accept them */
> -            if (!(disk->src->type == VIR_STORAGE_TYPE_BLOCK ||
> -                  disk->src->type == VIR_STORAGE_TYPE_VOLUME ||
> -                  (disk->src->type == VIR_STORAGE_TYPE_NETWORK &&
> -                   disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI))) {
> -                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> -                               _("disk '%s' improperly configured for a "
> -                                 "device='lun'"), disk->dst);
> -                return -1;
> -            }
> -        }
> -

Callers via virDomainDeviceDefParse now lose this check.

John

>          if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
>              virDomainDiskDefAssignAddress(xmlopt, disk, def) < 0)
>              return -1;
> @@ -24357,3 +24343,56 @@ virDomainObjGetShortName(virDomainObjPtr vm)
> 
>      return ret;
>  }
> +
> +
> +static int
> +virDomainDiskDefValidate(const virDomainDiskDef *disk)
> +{
> +    /* Validate LUN configuration */
> +    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
> +        /* volumes haven't been translated at this point, so accept them */
> +        if (!(disk->src->type == VIR_STORAGE_TYPE_BLOCK ||
> +              disk->src->type == VIR_STORAGE_TYPE_VOLUME ||
> +              (disk->src->type == VIR_STORAGE_TYPE_NETWORK &&
> +               disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI))) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                           _("disk '%s' improperly configured for a "
> +                             "device='lun'"), disk->dst);
> +            return -1;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
> +
> +#define VIR_DOMAIN_DEF_VALIDATE_DEVICES(dev, func)                             \
> +    for (i = 0; i < def->n ## dev ## s; i++) {                                 \
> +        if (func(def->dev ## s[i]) < 0)                                        \
> +            return -1;                                                         \
> +    }
> +
> +/**
> + * virDomainDefValidate:
> + * @def: domain definition
> + *
> + * This validation function is designed to take checks of globally invalid
> + * configurations that the parser needs to accept so that VMs don't vanish upon
> + * daemon restart. Such definition can be rejected upon startup or define, where
> + * this function shall be called.
> + *
> + * Returns 0 if domain definition is valid, -1 on error and reports an
> + * appropriate message.
> + */
> +int
> +virDomainDefValidate(const virDomainDef *def)
> +{
> +    size_t i;
> +
> +    /* check configuration of individual devices */
> +    VIR_DOMAIN_DEF_VALIDATE_DEVICES(disk, virDomainDiskDefValidate);
> +
> +    return 0;
> +}
> +
> +#undef VIR_DOMAIN_DEF_VALIDATE_DEVICES
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index b9e696d..f2704c0 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -3178,4 +3178,6 @@ bool virDomainDefHasMemballoon(const virDomainDef *def) ATTRIBUTE_NONNULL(1);
> 
>  char *virDomainObjGetShortName(virDomainObjPtr vm);
> 
> +int virDomainDefValidate(const virDomainDef *def);
> +
>  #endif /* __DOMAIN_CONF_H */
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 8408081..cc5d6c9 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -243,6 +243,7 @@ virDomainDefSetMemoryInitial;
>  virDomainDefSetMemoryTotal;
>  virDomainDefSetVcpus;
>  virDomainDefSetVcpusMax;
> +virDomainDefValidate;
>  virDomainDeleteConfig;
>  virDomainDeviceAddressIsValid;
>  virDomainDeviceAddressTypeToString;
> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> index a714b84..cbc5008 100644
> --- a/src/qemu/qemu_conf.h
> +++ b/src/qemu/qemu_conf.h
> @@ -333,4 +333,6 @@ int qemuTranslateSnapshotDiskSourcePool(virConnectPtr conn,
>  char * qemuGetHugepagePath(virHugeTLBFSPtr hugepage);
>  char * qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
>                                size_t nhugetlbfs);
> +
> +int qemuDomainDefValidate(const virDomainDef *def);
>  #endif /* __QEMUD_CONF_H */
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 0733872..5ccb483 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -5343,3 +5343,24 @@ qemuDomainDefValidateDiskLunSource(const virStorageSource *src)
> 
>      return 0;
>  }
> +
> +
> +/**
> + * qemuDomainDefValidate:
> + * @def: domain definition
> + *
> + * Validates that the domain definition is valid for the qemu driver. This check
> + * is run when the domain is defined or started as new. This check is explicitly
> + * not executed when starting a VM from snapshot/saved state/migration to allow
> + * partially invalid configs to still run.
> + *
> + * Returns 0 on success, -1 on error.
> + */
> +int
> +qemuDomainDefValidate(const virDomainDef *def)
> +{
> +    if (virDomainDefValidate(def) < 0)
> +        return -1;
> +
> +    return 0;
> +}
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 7f8dfc8..e6d22ec 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -1799,6 +1799,9 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
>      if (virDomainCreateXMLEnsureACL(conn, def) < 0)
>          goto cleanup;
> 
> +    if (qemuDomainDefValidate(def) < 0)
> +        goto cleanup;
> +
>      if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, def->emulator)))
>          goto cleanup;
> 
> @@ -7275,6 +7278,9 @@ qemuDomainDefineXMLFlags(virConnectPtr conn,
>      if (virDomainDefineXMLFlagsEnsureACL(conn, def) < 0)
>          goto cleanup;
> 
> +    if (qemuDomainDefValidate(def) < 0)
> +        goto cleanup;
> +
>      if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, def->emulator)))
>          goto cleanup;
> 
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index eddf3a7..d079b18 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -4620,13 +4620,6 @@ qemuProcessStartValidateXML(virDomainObjPtr vm,
>       * If back compat isn't a concern, XML validation should probably
>       * be done at parse time.
>       */
> -    if (qemuValidateCpuCount(vm->def, qemuCaps) < 0)
> -        return -1;
> -
> -    if (!migration && !snapshot &&
> -        virDomainDefCheckDuplicateDiskInfo(vm->def) < 0)
> -        return -1;
> -
>      if (vm->def->mem.min_guarantee) {
>          virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
>                         _("Parameter 'min_guarantee' "
> @@ -4634,6 +4627,21 @@ qemuProcessStartValidateXML(virDomainObjPtr vm,
>          return -1;
>      }
> 
> +    /* checks below should not be executed when starting a qemu process for a
> +     * VM that was running before (migration, snapshots, save). It's more
> +     * important to start such VM than keep the configuration clean */
> +    if (!migration && !snapshot) {
> +        if (qemuDomainDefValidate(vm->def) < 0)
> +            return -1;
> +
> +        if (virDomainDefCheckDuplicateDiskInfo(vm->def) < 0)
> +            return -1;
> +    }
> +
> +    /* checks below validate config that would make qemu fail to start */
> +    if (qemuValidateCpuCount(vm->def, qemuCaps) < 0)
> +        return -1;
> +
>      return 0;
>  }
> 




More information about the libvir-list mailing list