[libvirt] [PATCH 0/3] capabilities: Sanitize handling of 'features'

Peter Krempa (3): schema: capabilities: Add 'hap' feature flag conf: Refactor storage of guest capabilities conf: capabilities: Refactor API for setting guest capability features docs/schemas/capability.rng | 6 + src/conf/capabilities.c | 149 +++++++++++++-------- src/conf/capabilities.h | 35 +++-- src/libvirt_private.syms | 1 + src/libxl/libxl_capabilities.c | 46 ++----- src/qemu/qemu_capabilities.c | 34 ++--- src/test/test_driver.c | 6 +- tests/qemucaps2xmloutdata/caps.aarch64.xml | 2 +- tests/qemucaps2xmloutdata/caps.x86_64.xml | 4 +- tests/testutilsqemu.c | 6 +- 10 files changed, 156 insertions(+), 133 deletions(-) -- 2.23.0

The libxl driver exposes a 'hap' feature in the capability XML but our schema didn't cover it. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/schemas/capability.rng | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 8f3266b9f1..26d313d652 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -546,6 +546,12 @@ <empty/> </element> </optional> + <optional> + <element name='hap'> + <ref name='featuretoggle'/> + <empty/> + </element> + </optional> </interleave> </element> </define> -- 2.23.0

The capabilities are declared in the XML schema so passing feature names as strings from hypervisor drivers makes no sense. Additionally some of the features expose so called 'toggles' while others not. This knowledge was encoded by a bunch of 'STREQ's in the formatter. Change all of this by declaring the features as an enum and use it instead of a dynamically allocated array. Presence of 'toggles' is encoded together with the conversion strings rather than in the formatter directly. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/capabilities.c | 123 +++++++++++++-------- src/conf/capabilities.h | 24 +++- tests/qemucaps2xmloutdata/caps.aarch64.xml | 2 +- tests/qemucaps2xmloutdata/caps.x86_64.xml | 4 +- 4 files changed, 95 insertions(+), 58 deletions(-) diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 953464b09d..1666e1e496 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -150,15 +150,6 @@ virCapabilitiesFreeGuestDomain(virCapsGuestDomainPtr dom) VIR_FREE(dom); } -static void -virCapabilitiesFreeGuestFeature(virCapsGuestFeaturePtr feature) -{ - if (feature == NULL) - return; - VIR_FREE(feature->name); - VIR_FREE(feature); -} - void virCapabilitiesFreeGuest(virCapsGuestPtr guest) { @@ -176,10 +167,6 @@ virCapabilitiesFreeGuest(virCapsGuestPtr guest) virCapabilitiesFreeGuestDomain(guest->arch.domains[i]); VIR_FREE(guest->arch.domains); - for (i = 0; i < guest->nfeatures; i++) - virCapabilitiesFreeGuestFeature(guest->features[i]); - VIR_FREE(guest->features); - VIR_FREE(guest); } @@ -552,6 +539,24 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest, } +struct virCapsGuestFeatureInfo { + const char *name; + bool togglesRequired; +}; + +static const struct virCapsGuestFeatureInfo virCapsGuestFeatureInfos[VIR_CAPS_GUEST_FEATURE_TYPE_LAST] = { + [VIR_CAPS_GUEST_FEATURE_TYPE_PAE] = { "pae", false }, + [VIR_CAPS_GUEST_FEATURE_TYPE_NONPAE] = { "nonpae", false }, + [VIR_CAPS_GUEST_FEATURE_TYPE_IA64_BE] = { "ia64_be", false }, + [VIR_CAPS_GUEST_FEATURE_TYPE_ACPI] = { "acpi", true }, + [VIR_CAPS_GUEST_FEATURE_TYPE_APIC] = { "apic", true }, + [VIR_CAPS_GUEST_FEATURE_TYPE_CPUSELECTION] = { "cpuselection", false }, + [VIR_CAPS_GUEST_FEATURE_TYPE_DEVICEBOOT] = { "deviceboot", false }, + [VIR_CAPS_GUEST_FEATURE_TYPE_DISKSNAPSHOT] = { "disksnapshot", true }, + [VIR_CAPS_GUEST_FEATURE_TYPE_HAP] = { "hap", true }, +}; + + /** * virCapabilitiesAddGuestFeature: * @guest: guest to associate feature with @@ -567,25 +572,32 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, bool defaultOn, bool toggle) { - virCapsGuestFeaturePtr feature; + virCapsGuestFeaturePtr feature = NULL; + bool togglesRequired = false; + size_t i; - if (VIR_ALLOC(feature) < 0) - goto no_memory; + for (i = 0; i < VIR_CAPS_GUEST_FEATURE_TYPE_LAST; i++) { + if (STRNEQ(name, virCapsGuestFeatureInfos[i].name)) + continue; - feature->name = g_strdup(name); - feature->defaultOn = defaultOn; - feature->toggle = toggle; + feature = guest->features + i; + togglesRequired = virCapsGuestFeatureInfos[i].togglesRequired; + } - if (VIR_RESIZE_N(guest->features, guest->nfeatures_max, - guest->nfeatures, 1) < 0) - goto no_memory; - guest->features[guest->nfeatures++] = feature; + if (!feature) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid feature '%s'"), name); + return NULL; + } - return feature; + feature->present = true; - no_memory: - virCapabilitiesFreeGuestFeature(feature); - return NULL; + if (togglesRequired) { + feature->defaultOn = virTristateSwitchFromBool(defaultOn); + feature->toggle = virTristateBoolFromBool(toggle); + } + + return feature; } /** @@ -1204,6 +1216,40 @@ virCapabilitiesFormatHostXML(virCapsHostPtr host, } +static void +virCapabilitiesFormatGuestFeatures(virCapsGuestPtr guest, + virBufferPtr buf) +{ + g_auto(virBuffer) childBuf = VIR_BUFFER_INITIALIZER; + size_t i; + + virBufferSetChildIndent(&childBuf, buf); + + for (i = 0; i < VIR_CAPS_GUEST_FEATURE_TYPE_LAST; i++) { + virCapsGuestFeaturePtr feature = guest->features + i; + + if (!feature->present) + continue; + + virBufferAsprintf(&childBuf, "<%s", virCapsGuestFeatureInfos[i].name); + + if (feature->defaultOn) { + virBufferAsprintf(&childBuf, " default='%s'", + virTristateSwitchTypeToString(feature->defaultOn)); + } + + if (feature->toggle) { + virBufferAsprintf(&childBuf, " toggle='%s'", + virTristateBoolTypeToString(feature->toggle)); + } + + virBufferAddLit(&childBuf, "/>\n"); + } + + virXMLFormatElement(buf, "features", NULL, &childBuf); +} + + static void virCapabilitiesFormatGuestXML(virCapsGuestPtr *guests, size_t nguests, @@ -1273,29 +1319,8 @@ virCapabilitiesFormatGuestXML(virCapsGuestPtr *guests, virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</arch>\n"); - if (guests[i]->nfeatures) { - virBufferAddLit(buf, "<features>\n"); - virBufferAdjustIndent(buf, 2); + virCapabilitiesFormatGuestFeatures(guests[i], buf); - for (j = 0; j < guests[i]->nfeatures; j++) { - if (STREQ(guests[i]->features[j]->name, "pae") || - STREQ(guests[i]->features[j]->name, "nonpae") || - STREQ(guests[i]->features[j]->name, "ia64_be") || - STREQ(guests[i]->features[j]->name, "cpuselection") || - STREQ(guests[i]->features[j]->name, "deviceboot")) { - virBufferAsprintf(buf, "<%s/>\n", - guests[i]->features[j]->name); - } else { - virBufferAsprintf(buf, "<%s default='%s' toggle='%s'/>\n", - guests[i]->features[j]->name, - guests[i]->features[j]->defaultOn ? "on" : "off", - guests[i]->features[j]->toggle ? "yes" : "no"); - } - } - - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</features>\n"); - } virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</guest>\n\n"); } diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index 4abd3dcabd..dd972b1a67 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -32,10 +32,24 @@ #include <libxml/xpath.h> +typedef enum { + VIR_CAPS_GUEST_FEATURE_TYPE_PAE = 0, + VIR_CAPS_GUEST_FEATURE_TYPE_NONPAE, + VIR_CAPS_GUEST_FEATURE_TYPE_IA64_BE, + VIR_CAPS_GUEST_FEATURE_TYPE_ACPI, + VIR_CAPS_GUEST_FEATURE_TYPE_APIC, + VIR_CAPS_GUEST_FEATURE_TYPE_CPUSELECTION, + VIR_CAPS_GUEST_FEATURE_TYPE_DEVICEBOOT, + VIR_CAPS_GUEST_FEATURE_TYPE_DISKSNAPSHOT, + VIR_CAPS_GUEST_FEATURE_TYPE_HAP, + + VIR_CAPS_GUEST_FEATURE_TYPE_LAST +} virCapsGuestFeatureType; + struct _virCapsGuestFeature { - char *name; - bool defaultOn; - bool toggle; + bool present; + virTristateSwitch defaultOn; + virTristateBool toggle; }; struct _virCapsGuestMachine { @@ -68,9 +82,7 @@ struct _virCapsGuestArch { struct _virCapsGuest { int ostype; virCapsGuestArch arch; - size_t nfeatures; - size_t nfeatures_max; - virCapsGuestFeaturePtr *features; + virCapsGuestFeature features[VIR_CAPS_GUEST_FEATURE_TYPE_LAST]; }; struct _virCapsHostNUMACellCPU { diff --git a/tests/qemucaps2xmloutdata/caps.aarch64.xml b/tests/qemucaps2xmloutdata/caps.aarch64.xml index f6572c8ecd..5dca6d3102 100644 --- a/tests/qemucaps2xmloutdata/caps.aarch64.xml +++ b/tests/qemucaps2xmloutdata/caps.aarch64.xml @@ -17,10 +17,10 @@ <domain type='kvm'/> </arch> <features> + <acpi default='on' toggle='yes'/> <cpuselection/> <deviceboot/> <disksnapshot default='on' toggle='no'/> - <acpi default='on' toggle='yes'/> </features> </guest> diff --git a/tests/qemucaps2xmloutdata/caps.x86_64.xml b/tests/qemucaps2xmloutdata/caps.x86_64.xml index d41693a001..35359780c4 100644 --- a/tests/qemucaps2xmloutdata/caps.x86_64.xml +++ b/tests/qemucaps2xmloutdata/caps.x86_64.xml @@ -17,11 +17,11 @@ <domain type='kvm'/> </arch> <features> + <acpi default='on' toggle='yes'/> + <apic default='on' toggle='no'/> <cpuselection/> <deviceboot/> <disksnapshot default='on' toggle='no'/> - <acpi default='on' toggle='yes'/> - <apic default='on' toggle='no'/> </features> </guest> -- 2.23.0

Remove the need to pass around strings and switch to the enum values instead. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/capabilities.c | 68 ++++++++++++++++++---------------- src/conf/capabilities.h | 11 ++++-- src/libvirt_private.syms | 1 + src/libxl/libxl_capabilities.c | 46 +++++++---------------- src/qemu/qemu_capabilities.c | 34 +++++++---------- src/test/test_driver.c | 6 +-- tests/testutilsqemu.c | 6 +-- 7 files changed, 76 insertions(+), 96 deletions(-) diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 1666e1e496..6e5dde7394 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -557,49 +557,55 @@ static const struct virCapsGuestFeatureInfo virCapsGuestFeatureInfos[VIR_CAPS_GU }; +static void +virCapabilitiesAddGuestFeatureInternal(virCapsGuestPtr guest, + virCapsGuestFeatureType feature, + bool defaultOn, + bool toggle) +{ + guest->features[feature].present = true; + + if (virCapsGuestFeatureInfos[feature].togglesRequired) { + guest->features[feature].defaultOn = virTristateSwitchFromBool(defaultOn); + guest->features[feature].toggle = virTristateBoolFromBool(toggle); + } +} + + /** * virCapabilitiesAddGuestFeature: * @guest: guest to associate feature with - * @name: name of feature ('pae', 'acpi', 'apic') - * @defaultOn: true if it defaults to on - * @toggle: true if its state can be toggled + * @feature: feature to add * * Registers a feature for a guest domain. */ -virCapsGuestFeaturePtr +void virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, - const char *name, - bool defaultOn, - bool toggle) + virCapsGuestFeatureType feature) { - virCapsGuestFeaturePtr feature = NULL; - bool togglesRequired = false; - size_t i; - - for (i = 0; i < VIR_CAPS_GUEST_FEATURE_TYPE_LAST; i++) { - if (STRNEQ(name, virCapsGuestFeatureInfos[i].name)) - continue; - - feature = guest->features + i; - togglesRequired = virCapsGuestFeatureInfos[i].togglesRequired; - } - - if (!feature) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid feature '%s'"), name); - return NULL; - } - - feature->present = true; + virCapabilitiesAddGuestFeatureInternal(guest, feature, false, false); +} - if (togglesRequired) { - feature->defaultOn = virTristateSwitchFromBool(defaultOn); - feature->toggle = virTristateBoolFromBool(toggle); - } - return feature; +/** + * virCapabilitiesAddGuestFeatureToggle: + * @guest: guest to associate feature with + * @feature: feature to add + * @defaultOn: true if it defaults to on + * @toggle: true if its state can be toggled + * + * Registers a feature with toggles for a guest domain. + */ +void +virCapabilitiesAddGuestFeatureToggle(virCapsGuestPtr guest, + virCapsGuestFeatureType feature, + bool defaultOn, + bool toggle) +{ + virCapabilitiesAddGuestFeatureInternal(guest, feature, defaultOn, toggle); } + /** * virCapabilitiesHostSecModelAddBaseLabel * @secmodel: Security model to add a base label for diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index dd972b1a67..2d33adddeb 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -283,11 +283,14 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest, int nmachines, virCapsGuestMachinePtr *machines); -virCapsGuestFeaturePtr +void virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, - const char *name, - bool defaultOn, - bool toggle); + virCapsGuestFeatureType feature); +void +virCapabilitiesAddGuestFeatureToggle(virCapsGuestPtr guest, + virCapsGuestFeatureType feature, + bool defaultOn, + bool toggle); int virCapabilitiesAddStoragePool(virCapsPtr caps, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 94509d6f43..f764837688 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -46,6 +46,7 @@ virAccessPermStorageVolTypeToString; virCapabilitiesAddGuest; virCapabilitiesAddGuestDomain; virCapabilitiesAddGuestFeature; +virCapabilitiesAddGuestFeatureToggle; virCapabilitiesAddHostFeature; virCapabilitiesAddHostMigrateTransport; virCapabilitiesAddHostNUMACell; diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c index 3b88121dca..ce1c63d518 100644 --- a/src/libxl/libxl_capabilities.c +++ b/src/libxl/libxl_capabilities.c @@ -547,46 +547,26 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps) NULL) == NULL) return -1; - if (guest_archs[i].pae && - virCapabilitiesAddGuestFeature(guest, - "pae", - 1, - 0) == NULL) - return -1; + if (guest_archs[i].pae) + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_PAE); - if (guest_archs[i].nonpae && - virCapabilitiesAddGuestFeature(guest, - "nonpae", - 1, - 0) == NULL) - return -1; + if (guest_archs[i].nonpae) + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_NONPAE); - if (guest_archs[i].ia64_be && - virCapabilitiesAddGuestFeature(guest, - "ia64_be", - 1, - 0) == NULL) - return -1; + if (guest_archs[i].ia64_be) + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_IA64_BE); if (guest_archs[i].hvm) { - if (virCapabilitiesAddGuestFeature(guest, - "acpi", - 1, - 1) == NULL) - return -1; - - if (virCapabilitiesAddGuestFeature(guest, "apic", - 1, - 0) == NULL) - return -1; + virCapabilitiesAddGuestFeatureToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_ACPI, + true, true); + + virCapabilitiesAddGuestFeatureToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_APIC, + true, false); } if (guest_archs[i].hvm || guest_archs[i].pvh) { - if (virCapabilitiesAddGuestFeature(guest, - "hap", - 1, - 1) == NULL) - return -1; + virCapabilitiesAddGuestFeatureToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_HAP, + true, true); } } diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index fc6473651c..ab14e0fdfe 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -850,14 +850,10 @@ virQEMUCapsInitGuestFromBinary(virCapsPtr caps, /* CPU selection is always available, because all QEMU versions * we support can use at least '-cpu host' */ - if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false)) - goto cleanup; - - if (!virCapabilitiesAddGuestFeature(guest, "deviceboot", true, false)) - goto cleanup; - - if (!virCapabilitiesAddGuestFeature(guest, "disksnapshot", true, false)) - goto cleanup; + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_CPUSELECTION); + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_DEVICEBOOT); + virCapabilitiesAddGuestFeatureToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_DISKSNAPSHOT, + true, false); if (virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, @@ -878,20 +874,18 @@ virQEMUCapsInitGuestFromBinary(virCapsPtr caps, } } - if ((ARCH_IS_X86(guestarch) || guestarch == VIR_ARCH_AARCH64) && - virCapabilitiesAddGuestFeature(guest, "acpi", true, true) == NULL) { - goto cleanup; - } + if ((ARCH_IS_X86(guestarch) || guestarch == VIR_ARCH_AARCH64)) + virCapabilitiesAddGuestFeatureToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_ACPI, + true, true); - if (ARCH_IS_X86(guestarch) && - virCapabilitiesAddGuestFeature(guest, "apic", true, false) == NULL) { - goto cleanup; - } + if (ARCH_IS_X86(guestarch)) + virCapabilitiesAddGuestFeatureToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_APIC, + true, false); - if ((guestarch == VIR_ARCH_I686) && - (virCapabilitiesAddGuestFeature(guest, "pae", true, false) == NULL || - virCapabilitiesAddGuestFeature(guest, "nonpae", true, false) == NULL)) - goto cleanup; + if (guestarch == VIR_ARCH_I686) { + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_PAE); + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_NONPAE); + } ret = 0; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 6c1c56d446..d1a83ffa3c 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -350,10 +350,8 @@ testBuildCapabilities(virConnectPtr conn) NULL) == NULL) goto error; - if (virCapabilitiesAddGuestFeature(guest, "pae", true, true) == NULL) - goto error; - if (virCapabilitiesAddGuestFeature(guest, "nonpae", true, true) == NULL) - goto error; + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_PAE); + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_NONPAE); } caps->host.nsecModels = 1; diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 34a6bd2653..ca35e4ee75 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -110,8 +110,7 @@ testQemuAddI686Guest(virCapsPtr caps) machines))) goto error; - if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false)) - goto error; + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_CPUSELECTION); machines = NULL; @@ -161,8 +160,7 @@ testQemuAddX86_64Guest(virCapsPtr caps) machines))) goto error; - if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false)) - goto error; + virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_CPUSELECTION); machines = NULL; -- 2.23.0

On Tue, Nov 12, 2019 at 02:33:46PM +0100, Peter Krempa wrote:
Remove the need to pass around strings and switch to the enum values instead.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/capabilities.c | 68 ++++++++++++++++++---------------- src/conf/capabilities.h | 11 ++++-- src/libvirt_private.syms | 1 + src/libxl/libxl_capabilities.c | 46 +++++++---------------- src/qemu/qemu_capabilities.c | 34 +++++++---------- src/test/test_driver.c | 6 +-- tests/testutilsqemu.c | 6 +-- 7 files changed, 76 insertions(+), 96 deletions(-)
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 1666e1e496..6e5dde7394 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -557,49 +557,55 @@ static const struct virCapsGuestFeatureInfo virCapsGuestFeatureInfos[VIR_CAPS_GU };
+static void +virCapabilitiesAddGuestFeatureInternal(virCapsGuestPtr guest, + virCapsGuestFeatureType feature, + bool defaultOn, + bool toggle) +{ + guest->features[feature].present = true; + + if (virCapsGuestFeatureInfos[feature].togglesRequired) { + guest->features[feature].defaultOn = virTristateSwitchFromBool(defaultOn); + guest->features[feature].toggle = virTristateBoolFromBool(toggle); + } +} + + /** * virCapabilitiesAddGuestFeature: * @guest: guest to associate feature with - * @name: name of feature ('pae', 'acpi', 'apic') - * @defaultOn: true if it defaults to on - * @toggle: true if its state can be toggled + * @feature: feature to add * * Registers a feature for a guest domain. */ -virCapsGuestFeaturePtr +void virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, - const char *name, - bool defaultOn, - bool toggle) + virCapsGuestFeatureType feature) { - virCapsGuestFeaturePtr feature = NULL; - bool togglesRequired = false; - size_t i; - - for (i = 0; i < VIR_CAPS_GUEST_FEATURE_TYPE_LAST; i++) { - if (STRNEQ(name, virCapsGuestFeatureInfos[i].name)) - continue; - - feature = guest->features + i; - togglesRequired = virCapsGuestFeatureInfos[i].togglesRequired; - } - - if (!feature) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid feature '%s'"), name); - return NULL; - } - - feature->present = true; + virCapabilitiesAddGuestFeatureInternal(guest, feature, false, false); +}
- if (togglesRequired) { - feature->defaultOn = virTristateSwitchFromBool(defaultOn); - feature->toggle = virTristateBoolFromBool(toggle); - }
- return feature; +/** + * virCapabilitiesAddGuestFeatureToggle:
consider using 'WithToggle' instead of Toggle Jano
+ * @guest: guest to associate feature with + * @feature: feature to add + * @defaultOn: true if it defaults to on + * @toggle: true if its state can be toggled + * + * Registers a feature with toggles for a guest domain. + */ +void +virCapabilitiesAddGuestFeatureToggle(virCapsGuestPtr guest, + virCapsGuestFeatureType feature, + bool defaultOn, + bool toggle) +{ + virCapabilitiesAddGuestFeatureInternal(guest, feature, defaultOn, toggle); }
+ /** * virCapabilitiesHostSecModelAddBaseLabel * @secmodel: Security model to add a base label for

On Tue, Nov 12, 2019 at 02:33:43PM +0100, Peter Krempa wrote:
Peter Krempa (3): schema: capabilities: Add 'hap' feature flag conf: Refactor storage of guest capabilities conf: capabilities: Refactor API for setting guest capability features
docs/schemas/capability.rng | 6 + src/conf/capabilities.c | 149 +++++++++++++-------- src/conf/capabilities.h | 35 +++-- src/libvirt_private.syms | 1 + src/libxl/libxl_capabilities.c | 46 ++----- src/qemu/qemu_capabilities.c | 34 ++--- src/test/test_driver.c | 6 +- tests/qemucaps2xmloutdata/caps.aarch64.xml | 2 +- tests/qemucaps2xmloutdata/caps.x86_64.xml | 4 +- tests/testutilsqemu.c | 6 +- 10 files changed, 156 insertions(+), 133 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa