[libvirt] [PATCH] conf: rewrite filtering for capabilities lookup
Daniel P. Berrangé
berrange at redhat.com
Thu Aug 9 10:18:37 UTC 2018
ping
On Fri, Aug 03, 2018 at 03:28:16PM +0100, Daniel P. Berrangé wrote:
> The virCapabilitiesDomainDataLookupInternal() is given a list of
> parameters representing the desired domain characteristics. It then has
> to look throught the capabilities to identify an acceptable match.
>
> The virCapsDomainDataCompare() method is used for filtering out
> candidates which don't match the desired criteria. It is called
> primarily from the innermost loops and as such is doing many repeated
> checks. For example if architcture and os type were checked at the top
> level loop the two inner loops could be avoided entirely. If emulator
> and domain type were checked in the 2nd level loop the 3rd level loop
> can be avoided too.
>
> This change thus removes the virCapsDomainDataCompare() method and puts
> suitable checks at the start of each loop to ensure it executes the
> minimal number of loop iterations possible. The code becomes clearer to
> understand as a nice side-effect.
>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
> src/conf/capabilities.c | 100 ++++++++++++++++++----------------------
> 1 file changed, 45 insertions(+), 55 deletions(-)
>
> diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
> index 0f96500294..cfd5132329 100644
> --- a/src/conf/capabilities.c
> +++ b/src/conf/capabilities.c
> @@ -604,46 +604,6 @@ virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel,
> return -1;
> }
>
> -static bool
> -virCapsDomainDataCompare(virCapsGuestPtr guest,
> - virCapsGuestDomainPtr domain,
> - virCapsGuestMachinePtr machine,
> - int ostype,
> - virArch arch,
> - virDomainVirtType domaintype,
> - const char *emulator,
> - const char *machinetype)
> -{
> - const char *check_emulator = NULL;
> -
> - if (ostype != -1 && guest->ostype != ostype)
> - return false;
> - if ((arch != VIR_ARCH_NONE) && (guest->arch.id != arch))
> - return false;
> -
> - if (domaintype != VIR_DOMAIN_VIRT_NONE &&
> - (!domain || domain->type != domaintype))
> - return false;
> -
> - if (emulator) {
> - if (domain)
> - check_emulator = domain->info.emulator;
> - if (!check_emulator)
> - check_emulator = guest->arch.defaultInfo.emulator;
> - if (STRNEQ_NULLABLE(check_emulator, emulator))
> - return false;
> - }
> -
> - if (machinetype) {
> - if (!machine)
> - return false;
> - if (STRNEQ(machine->name, machinetype) &&
> - (STRNEQ_NULLABLE(machine->canonical, machinetype)))
> - return false;
> - }
> -
> - return true;
> -}
>
> static virCapsDomainDataPtr
> virCapabilitiesDomainDataLookupInternal(virCapsPtr caps,
> @@ -659,13 +619,45 @@ virCapabilitiesDomainDataLookupInternal(virCapsPtr caps,
> virCapsDomainDataPtr ret = NULL;
> size_t i, j, k;
>
> + VIR_DEBUG("Lookup ostype=%d arch=%d domaintype=%d emulator=%s machine=%s",
> + ostype, arch, domaintype, NULLSTR(emulator), NULLSTR(machinetype));
> for (i = 0; i < caps->nguests; i++) {
> virCapsGuestPtr guest = caps->guests[i];
>
> + if (ostype != -1 && guest->ostype != ostype) {
> + VIR_DEBUG("Skip os type want=%d vs got=%d", ostype, guest->ostype);
> + continue;
> + }
> + VIR_DEBUG("Match os type %d", ostype);
> +
> + if ((arch != VIR_ARCH_NONE) && (guest->arch.id != arch)) {
> + VIR_DEBUG("Skip arch want=%d vs got=%d", arch, guest->arch.id);
> + continue;
> + }
> + VIR_DEBUG("Match arch %d", arch);
> +
> for (j = 0; j < guest->arch.ndomains; j++) {
> virCapsGuestDomainPtr domain = guest->arch.domains[j];
> virCapsGuestMachinePtr *machinelist;
> int nmachines;
> + const char *check_emulator = NULL;
> +
> + if (domaintype != VIR_DOMAIN_VIRT_NONE &&
> + (domain->type != domaintype)) {
> + VIR_DEBUG("Skip domain type want=%d vs got=%d", domaintype, domain->type);
> + continue;
> + }
> + VIR_DEBUG("Match domain type %d", domaintype);
> +
> + check_emulator = domain->info.emulator;
> + if (!check_emulator)
> + check_emulator = guest->arch.defaultInfo.emulator;
> + if (emulator && STRNEQ_NULLABLE(check_emulator, emulator)) {
> + VIR_DEBUG("Skip emulator got=%s vs want=%s",
> + emulator, NULLSTR(check_emulator));
> + continue;
> + }
> + VIR_DEBUG("Match emulator %s", NULLSTR(emulator));
>
> if (domain->info.nmachines) {
> nmachines = domain->info.nmachines;
> @@ -677,32 +669,29 @@ virCapabilitiesDomainDataLookupInternal(virCapsPtr caps,
>
> for (k = 0; k < nmachines; k++) {
> virCapsGuestMachinePtr machine = machinelist[k];
> - if (!virCapsDomainDataCompare(guest, domain, machine,
> - ostype, arch, domaintype,
> - emulator, machinetype))
> +
> + if (machinetype &&
> + STRNEQ(machine->name, machinetype) &&
> + STRNEQ_NULLABLE(machine->canonical, machinetype)) {
> + VIR_DEBUG("Skip machine type want=%s vs got=%s got=%s",
> + machinetype, machine->name, NULLSTR(machine->canonical));
> continue;
> + }
> + VIR_DEBUG("Match machine type machine %s\n", NULLSTR(machinetype));
>
> foundmachine = machine;
> break;
> }
>
> - if (!foundmachine) {
> - if (!virCapsDomainDataCompare(guest, domain, NULL,
> - ostype, arch, domaintype,
> - emulator, machinetype))
> - continue;
> - }
> + if (!foundmachine && nmachines)
> + continue;
>
> founddomain = domain;
> break;
> }
>
> - if (!founddomain) {
> - if (!virCapsDomainDataCompare(guest, NULL, NULL,
> - ostype, arch, domaintype,
> - emulator, machinetype))
> - continue;
> - }
> + if (!founddomain)
> + continue;
>
> foundguest = guest;
> break;
> @@ -731,6 +720,7 @@ virCapabilitiesDomainDataLookupInternal(virCapsPtr caps,
> goto error;
> }
>
> + VIR_DEBUG("No match %s", virBufferCurrentContent(&buf));
> virReportError(VIR_ERR_INVALID_ARG,
> _("could not find capabilities for %s"),
> virBufferCurrentContent(&buf));
> --
> 2.17.1
>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the libvir-list
mailing list