43fe83
From bbad015e6ffe6623b55a1c61aeb0a8d3e65bce6a Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <bbad015e6ffe6623b55a1c61aeb0a8d3e65bce6a.1383922567.git.jdenemar@redhat.com>
43fe83
From: Peter Krempa <pkrempa@redhat.com>
43fe83
Date: Fri, 8 Nov 2013 12:33:33 +0100
43fe83
Subject: [PATCH] conf: Refactor storing and usage of feature flags
43fe83
43fe83
https://bugzilla.redhat.com/show_bug.cgi?id=1008989
43fe83
43fe83
Currently we were storing domain feature flags in a bit field as the
43fe83
they were either enabled or disabled. New features such as paravirtual
43fe83
spinlocks however can be tri-state as the default option may depend on
43fe83
hypervisor version.
43fe83
43fe83
To allow storing tri-state feature state in the same place instead of
43fe83
having to declare dedicated variables for each feature this patch
43fe83
refactors the bit field to an array.
43fe83
43fe83
(cherry picked from commit de7b5faf43645229c74843032402c0d58a397e88)
43fe83
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 src/conf/domain_conf.c     | 159 ++++++++++++++++++++++++++++++---------------
43fe83
 src/conf/domain_conf.h     |   2 +-
43fe83
 src/libxl/libxl_conf.c     |   9 ++-
43fe83
 src/lxc/lxc_container.c    |   6 +-
43fe83
 src/qemu/qemu_command.c    |  15 ++---
43fe83
 src/vbox/vbox_tmpl.c       |  45 +++++++------
43fe83
 src/xenapi/xenapi_driver.c |  10 +--
43fe83
 src/xenapi/xenapi_utils.c  |  22 +++----
43fe83
 src/xenxs/xen_sxpr.c       |  20 +++---
43fe83
 src/xenxs/xen_xm.c         |  30 ++++-----
43fe83
 10 files changed, 187 insertions(+), 131 deletions(-)
43fe83
43fe83
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
43fe83
index 79dfb05..6664c2a 100644
43fe83
--- a/src/conf/domain_conf.c
43fe83
+++ b/src/conf/domain_conf.c
43fe83
@@ -11319,10 +11319,10 @@ virDomainDefParseXML(xmlDocPtr xml,
43fe83
                            _("unexpected feature '%s'"), nodes[i]->name);
43fe83
             goto error;
43fe83
         }
43fe83
-        def->features |= (1 << val);
43fe83
-        if (val == VIR_DOMAIN_FEATURE_APIC) {
43fe83
-            tmp = virXPathString("string(./features/apic/@eoi)", ctxt);
43fe83
-            if (tmp) {
43fe83
+
43fe83
+        switch ((enum virDomainFeature) val) {
43fe83
+        case VIR_DOMAIN_FEATURE_APIC:
43fe83
+            if ((tmp = virXPathString("string(./features/apic/@eoi)", ctxt))) {
43fe83
                 int eoi;
43fe83
                 if ((eoi = virDomainFeatureStateTypeFromString(tmp)) <= 0) {
43fe83
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
43fe83
@@ -11333,11 +11333,23 @@ virDomainDefParseXML(xmlDocPtr xml,
43fe83
                 def->apic_eoi = eoi;
43fe83
                 VIR_FREE(tmp);
43fe83
             }
43fe83
+            /* fallthrough */
43fe83
+        case VIR_DOMAIN_FEATURE_ACPI:
43fe83
+        case VIR_DOMAIN_FEATURE_PAE:
43fe83
+        case VIR_DOMAIN_FEATURE_HAP:
43fe83
+        case VIR_DOMAIN_FEATURE_VIRIDIAN:
43fe83
+        case VIR_DOMAIN_FEATURE_PRIVNET:
43fe83
+        case VIR_DOMAIN_FEATURE_HYPERV:
43fe83
+            def->features[val] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
+            break;
43fe83
+
43fe83
+        case VIR_DOMAIN_FEATURE_LAST:
43fe83
+            break;
43fe83
         }
43fe83
     }
43fe83
     VIR_FREE(nodes);
43fe83
 
43fe83
-    if (def->features & (1 << VIR_DOMAIN_FEATURE_HYPERV)) {
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
43fe83
         int feature;
43fe83
         int value;
43fe83
         node = ctxt->node;
43fe83
@@ -13321,12 +13333,16 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
43fe83
 {
43fe83
     size_t i;
43fe83
 
43fe83
-    /* basic check */
43fe83
-    if (src->features != dst->features) {
43fe83
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
43fe83
-                       _("Target domain features %d does not match source %d"),
43fe83
-                       dst->features, src->features);
43fe83
-        return false;
43fe83
+    for (i = 0; i < VIR_DOMAIN_FEATURE_LAST; i++) {
43fe83
+        if (src->features[i] != dst->features[i]) {
43fe83
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
43fe83
+                           _("State of feature '%s' differs: "
43fe83
+                             "source: '%s', destination: '%s'"),
43fe83
+                           virDomainFeatureTypeToString(i),
43fe83
+                           virDomainFeatureStateTypeToString(src->features[i]),
43fe83
+                           virDomainFeatureStateTypeToString(dst->features[i]));
43fe83
+            return false;
43fe83
+        }
43fe83
     }
43fe83
 
43fe83
     /* APIC EOI */
43fe83
@@ -13340,7 +13356,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
43fe83
     }
43fe83
 
43fe83
     /* hyperv */
43fe83
-    if (src->features & (1 << VIR_DOMAIN_FEATURE_HYPERV)) {
43fe83
+    if (src->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
43fe83
         for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
43fe83
             switch ((enum virDomainHyperv) i) {
43fe83
             case VIR_DOMAIN_HYPERV_RELAXED:
43fe83
@@ -16647,58 +16663,99 @@ virDomainDefFormatInternal(virDomainDefPtr def,
43fe83
         virBufferAddLit(buf, "  </idmap>\n");
43fe83
     }
43fe83
 
43fe83
+    for (i = 0; i < VIR_DOMAIN_FEATURE_LAST; i++) {
43fe83
+        if (def->features[i] != VIR_DOMAIN_FEATURE_STATE_DEFAULT)
43fe83
+            break;
43fe83
+    }
43fe83
 
43fe83
-    if (def->features) {
43fe83
+    if (i != VIR_DOMAIN_FEATURE_LAST) {
43fe83
         virBufferAddLit(buf, "  <features>\n");
43fe83
+
43fe83
         for (i = 0; i < VIR_DOMAIN_FEATURE_LAST; i++) {
43fe83
-            if (def->features & (1 << i) && i != VIR_DOMAIN_FEATURE_HYPERV) {
43fe83
-                const char *name = virDomainFeatureTypeToString(i);
43fe83
-                if (!name) {
43fe83
-                    virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
-                                   _("unexpected feature %zu"), i);
43fe83
-                    goto error;
43fe83
-                }
43fe83
-                virBufferAsprintf(buf, "    <%s", name);
43fe83
-                if (i == VIR_DOMAIN_FEATURE_APIC && def->apic_eoi) {
43fe83
-                    virBufferAsprintf(buf,
43fe83
-                                      " eoi='%s'",
43fe83
-                                      virDomainFeatureStateTypeToString(def->apic_eoi));
43fe83
-                }
43fe83
-                virBufferAddLit(buf, "/>\n");
43fe83
+            const char *name = virDomainFeatureTypeToString(i);
43fe83
+            size_t j;
43fe83
+
43fe83
+            if (!name) {
43fe83
+                virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
+                               _("unexpected feature %zu"), i);
43fe83
+                goto error;
43fe83
             }
43fe83
-        }
43fe83
 
43fe83
-        if (def->features & (1 << VIR_DOMAIN_FEATURE_HYPERV)) {
43fe83
-            virBufferAddLit(buf, "    <hyperv>\n");
43fe83
-            for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
43fe83
-                switch ((enum virDomainHyperv) i) {
43fe83
-                case VIR_DOMAIN_HYPERV_RELAXED:
43fe83
-                case VIR_DOMAIN_HYPERV_VAPIC:
43fe83
-                    if (def->hyperv_features[i])
43fe83
-                        virBufferAsprintf(buf, "      <%s state='%s'/>\n",
43fe83
-                                          virDomainHypervTypeToString(i),
43fe83
-                                          virDomainFeatureStateTypeToString(
43fe83
-                                              def->hyperv_features[i]));
43fe83
+            switch ((enum virDomainFeature) i) {
43fe83
+            case VIR_DOMAIN_FEATURE_ACPI:
43fe83
+            case VIR_DOMAIN_FEATURE_PAE:
43fe83
+            case VIR_DOMAIN_FEATURE_HAP:
43fe83
+            case VIR_DOMAIN_FEATURE_VIRIDIAN:
43fe83
+            case VIR_DOMAIN_FEATURE_PRIVNET:
43fe83
+                switch ((enum virDomainFeatureState) def->features[i]) {
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_DEFAULT:
43fe83
                     break;
43fe83
 
43fe83
-                case VIR_DOMAIN_HYPERV_SPINLOCKS:
43fe83
-                    if (def->hyperv_features[i] == 0)
43fe83
-                        break;
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_ON:
43fe83
+                   virBufferAsprintf(buf, "    <%s/>\n", name);
43fe83
+                   break;
43fe83
+
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_LAST:
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_OFF:
43fe83
+                   virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
+                                 _("Unexpected state of feature '%s'"), name);
43fe83
+
43fe83
+                   goto error;
43fe83
+                   break;
43fe83
+                }
43fe83
+
43fe83
+                break;
43fe83
 
43fe83
-                    virBufferAsprintf(buf, "      
43fe83
-                                      virDomainFeatureStateTypeToString(
43fe83
-                                          def->hyperv_features[i]));
43fe83
-                    if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
-                        virBufferAsprintf(buf, " retries='%d'",
43fe83
-                                          def->hyperv_spinlocks);
43fe83
+            case VIR_DOMAIN_FEATURE_APIC:
43fe83
+                if (def->features[i] == VIR_DOMAIN_FEATURE_STATE_ON) {
43fe83
+                    virBufferAddLit(buf, "    
43fe83
+                    if (def->apic_eoi) {
43fe83
+                        virBufferAsprintf(buf, " eoi='%s'",
43fe83
+                                          virDomainFeatureStateTypeToString(def->apic_eoi));
43fe83
+                    }
43fe83
                     virBufferAddLit(buf, "/>\n");
43fe83
-                    break;
43fe83
+                }
43fe83
+                break;
43fe83
 
43fe83
-                case VIR_DOMAIN_HYPERV_LAST:
43fe83
+            case VIR_DOMAIN_FEATURE_HYPERV:
43fe83
+                if (def->features[i] != VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                     break;
43fe83
+
43fe83
+                virBufferAddLit(buf, "    <hyperv>\n");
43fe83
+                for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) {
43fe83
+                    switch ((enum virDomainHyperv) j) {
43fe83
+                    case VIR_DOMAIN_HYPERV_RELAXED:
43fe83
+                    case VIR_DOMAIN_HYPERV_VAPIC:
43fe83
+                        if (def->hyperv_features[j])
43fe83
+                            virBufferAsprintf(buf, "      <%s state='%s'/>\n",
43fe83
+                                              virDomainHypervTypeToString(j),
43fe83
+                                              virDomainFeatureStateTypeToString(
43fe83
+                                                  def->hyperv_features[j]));
43fe83
+                        break;
43fe83
+
43fe83
+                    case VIR_DOMAIN_HYPERV_SPINLOCKS:
43fe83
+                        if (def->hyperv_features[j] == 0)
43fe83
+                            break;
43fe83
+
43fe83
+                        virBufferAsprintf(buf, "      
43fe83
+                                          virDomainFeatureStateTypeToString(
43fe83
+                                              def->hyperv_features[j]));
43fe83
+                        if (def->hyperv_features[j] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
+                            virBufferAsprintf(buf, " retries='%d'",
43fe83
+                                              def->hyperv_spinlocks);
43fe83
+                        virBufferAddLit(buf, "/>\n");
43fe83
+                        break;
43fe83
+
43fe83
+                    case VIR_DOMAIN_HYPERV_LAST:
43fe83
+                        break;
43fe83
+                    }
43fe83
                 }
43fe83
+                virBufferAddLit(buf, "    </hyperv>\n");
43fe83
+                break;
43fe83
+
43fe83
+            case VIR_DOMAIN_FEATURE_LAST:
43fe83
+                break;
43fe83
             }
43fe83
-            virBufferAddLit(buf, "    </hyperv>\n");
43fe83
         }
43fe83
 
43fe83
         virBufferAddLit(buf, "  </features>\n");
43fe83
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
43fe83
index 5ad0318..3d2b3a4 100644
43fe83
--- a/src/conf/domain_conf.h
43fe83
+++ b/src/conf/domain_conf.h
43fe83
@@ -1972,7 +1972,7 @@ struct _virDomainDef {
43fe83
 
43fe83
     virDomainOSDef os;
43fe83
     char *emulator;
43fe83
-    int features;
43fe83
+    int features[VIR_DOMAIN_FEATURE_LAST];
43fe83
     /* enum virDomainFeatureState */
43fe83
     int apic_eoi;
43fe83
     /* These options are of type virDomainFeatureState */
43fe83
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
43fe83
index 5273a26..6bfe934 100644
43fe83
--- a/src/libxl/libxl_conf.c
43fe83
+++ b/src/libxl/libxl_conf.c
43fe83
@@ -373,11 +373,14 @@ libxlMakeDomBuildInfo(virDomainObjPtr vm, libxl_domain_config *d_config)
43fe83
         char bootorder[VIR_DOMAIN_BOOT_LAST + 1];
43fe83
 
43fe83
         libxl_defbool_set(&b_info->u.hvm.pae,
43fe83
-                          def->features & (1 << VIR_DOMAIN_FEATURE_PAE));
43fe83
+                          def->features[VIR_DOMAIN_FEATURE_PAE] ==
43fe83
+                          VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
         libxl_defbool_set(&b_info->u.hvm.apic,
43fe83
-                          def->features & (1 << VIR_DOMAIN_FEATURE_APIC));
43fe83
+                          def->features[VIR_DOMAIN_FEATURE_APIC] ==
43fe83
+                          VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
         libxl_defbool_set(&b_info->u.hvm.acpi,
43fe83
-                          def->features & (1 << VIR_DOMAIN_FEATURE_ACPI));
43fe83
+                          def->features[VIR_DOMAIN_FEATURE_ACPI] ==
43fe83
+                          VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
         for (i = 0; i < def->clock.ntimers; i++) {
43fe83
             if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_HPET &&
43fe83
                 def->clock.timers[i]->present == 1) {
43fe83
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
43fe83
index 9479498..01ed93e 100644
43fe83
--- a/src/lxc/lxc_container.c
43fe83
+++ b/src/lxc/lxc_container.c
43fe83
@@ -1838,8 +1838,8 @@ static int lxcContainerChild(void *data)
43fe83
     }
43fe83
 
43fe83
     /* rename and enable interfaces */
43fe83
-    if (lxcContainerRenameAndEnableInterfaces(!!(vmDef->features &
43fe83
-                                                 (1 << VIR_DOMAIN_FEATURE_PRIVNET)),
43fe83
+    if (lxcContainerRenameAndEnableInterfaces(vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] ==
43fe83
+                                              VIR_DOMAIN_FEATURE_STATE_ON,
43fe83
                                               argv->nveths,
43fe83
                                               argv->veths) < 0) {
43fe83
         goto cleanup;
43fe83
@@ -1929,7 +1929,7 @@ lxcNeedNetworkNamespace(virDomainDefPtr def)
43fe83
     size_t i;
43fe83
     if (def->nets != NULL)
43fe83
         return true;
43fe83
-    if (def->features & (1 << VIR_DOMAIN_FEATURE_PRIVNET))
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_PRIVNET] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
         return true;
43fe83
     for (i = 0; i < def->nhostdevs; i++) {
43fe83
         if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES &&
43fe83
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
43fe83
index 0292b72..f14b0f2 100644
43fe83
--- a/src/qemu/qemu_command.c
43fe83
+++ b/src/qemu/qemu_command.c
43fe83
@@ -6574,7 +6574,7 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
43fe83
         have_cpu = true;
43fe83
     }
43fe83
 
43fe83
-    if (def->features & (1 << VIR_DOMAIN_FEATURE_HYPERV)) {
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
43fe83
         if (!have_cpu) {
43fe83
             virBufferAdd(&buf, default_model, -1);
43fe83
             have_cpu = true;
43fe83
@@ -7905,7 +7905,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
     }
43fe83
 
43fe83
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI)) {
43fe83
-        if (!(def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)))
43fe83
+        if (def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
             virCommandAddArg(cmd, "-no-acpi");
43fe83
     }
43fe83
 
43fe83
@@ -10634,7 +10634,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
43fe83
             if (*feature == '\0')
43fe83
                 goto syntax;
43fe83
 
43fe83
-            dom->features |= (1 << VIR_DOMAIN_FEATURE_HYPERV);
43fe83
+            dom->features[VIR_DOMAIN_FEATURE_HYPERV] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
 
43fe83
             if ((f = virDomainHypervTypeFromString(feature)) < 0) {
43fe83
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
43fe83
@@ -10888,7 +10888,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
43fe83
             goto error;
43fe83
         if (strstr(path, "kvm")) {
43fe83
             def->virtType = VIR_DOMAIN_VIRT_KVM;
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_PAE);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         }
43fe83
     }
43fe83
 
43fe83
@@ -10901,8 +10901,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
43fe83
 
43fe83
     if ((def->os.arch == VIR_ARCH_I686) ||
43fe83
         (def->os.arch == VIR_ARCH_X86_64))
43fe83
-        def->features |= (1 << VIR_DOMAIN_FEATURE_ACPI)
43fe83
-        /*| (1 << VIR_DOMAIN_FEATURE_APIC)*/;
43fe83
+        def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
 
43fe83
 #define WANT_VALUE()                                                   \
43fe83
     const char *val = progargv[++i];                                   \
43fe83
@@ -11196,7 +11195,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
43fe83
             def->disks[def->ndisks++] = disk;
43fe83
             disk = NULL;
43fe83
         } else if (STREQ(arg, "-no-acpi")) {
43fe83
-            def->features &= ~(1 << VIR_DOMAIN_FEATURE_ACPI);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_DEFAULT;
43fe83
         } else if (STREQ(arg, "-no-reboot")) {
43fe83
             def->onReboot = VIR_DOMAIN_LIFECYCLE_DESTROY;
43fe83
         } else if (STREQ(arg, "-no-kvm")) {
43fe83
@@ -11314,7 +11313,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
43fe83
                     def->mem.nosharepages = true;
43fe83
                 } else if (STRPREFIX(param, "accel=kvm")) {
43fe83
                     def->virtType = VIR_DOMAIN_VIRT_KVM;
43fe83
-                    def->features |= (1 << VIR_DOMAIN_FEATURE_PAE);
43fe83
+                    def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
                 }
43fe83
             }
43fe83
             virStringFreeList(list);
43fe83
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
43fe83
index 5b17048..3e9f0d9 100644
43fe83
--- a/src/vbox/vbox_tmpl.c
43fe83
+++ b/src/vbox/vbox_tmpl.c
43fe83
@@ -2362,7 +2362,6 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
43fe83
                 }
43fe83
             }
43fe83
 
43fe83
-            def->features = 0;
43fe83
 #if VBOX_API_VERSION < 3001
43fe83
             machine->vtbl->GetPAEEnabled(machine, &PAEEnabled);
43fe83
 #elif VBOX_API_VERSION == 3001
43fe83
@@ -2370,21 +2369,18 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
43fe83
 #elif VBOX_API_VERSION >= 3002
43fe83
             machine->vtbl->GetCPUProperty(machine, CPUPropertyType_PAE, &PAEEnabled);
43fe83
 #endif
43fe83
-            if (PAEEnabled) {
43fe83
-                def->features = def->features | (1 << VIR_DOMAIN_FEATURE_PAE);
43fe83
-            }
43fe83
+            if (PAEEnabled)
43fe83
+                def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
 
43fe83
             machine->vtbl->GetBIOSSettings(machine, &bios);
43fe83
             if (bios) {
43fe83
                 bios->vtbl->GetACPIEnabled(bios, &ACPIEnabled);
43fe83
-                if (ACPIEnabled) {
43fe83
-                    def->features = def->features | (1 << VIR_DOMAIN_FEATURE_ACPI);
43fe83
-                }
43fe83
+                if (ACPIEnabled)
43fe83
+                    def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
 
43fe83
                 bios->vtbl->GetIOAPICEnabled(bios, &IOAPICEnabled);
43fe83
-                if (IOAPICEnabled) {
43fe83
-                    def->features = def->features | (1 << VIR_DOMAIN_FEATURE_APIC);
43fe83
-                }
43fe83
+                if (IOAPICEnabled)
43fe83
+                    def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
 
43fe83
                 VBOX_RELEASE(bios);
43fe83
             }
43fe83
@@ -5101,40 +5097,43 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
43fe83
     }
43fe83
 
43fe83
 #if VBOX_API_VERSION < 3001
43fe83
-    rc = machine->vtbl->SetPAEEnabled(machine, (def->features) &
43fe83
-                                      (1 << VIR_DOMAIN_FEATURE_PAE));
43fe83
+    rc = machine->vtbl->SetPAEEnabled(machine,
43fe83
+                                      def->features[VIR_DOMAIN_FEATURE_PAE] ==
43fe83
+                                      VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
 #elif VBOX_API_VERSION == 3001
43fe83
     rc = machine->vtbl->SetCpuProperty(machine, CpuPropertyType_PAE,
43fe83
-                                       (def->features) &
43fe83
-                                       (1 << VIR_DOMAIN_FEATURE_PAE));
43fe83
+                                       def->features[VIR_DOMAIN_FEATURE_PAE] ==
43fe83
+                                       VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
 #elif VBOX_API_VERSION >= 3002
43fe83
     rc = machine->vtbl->SetCPUProperty(machine, CPUPropertyType_PAE,
43fe83
-                                       (def->features) &
43fe83
-                                       (1 << VIR_DOMAIN_FEATURE_PAE));
43fe83
+                                       def->features[VIR_DOMAIN_FEATURE_PAE] ==
43fe83
+                                       VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
 #endif
43fe83
     if (NS_FAILED(rc)) {
43fe83
         virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
                        _("could not change PAE status to: %s, rc=%08x"),
43fe83
-                       ((def->features) & (1 << VIR_DOMAIN_FEATURE_PAE))
43fe83
+                       (def->features[VIR_DOMAIN_FEATURE_PAE] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                        ? _("Enabled") : _("Disabled"), (unsigned)rc);
43fe83
     }
43fe83
 
43fe83
     machine->vtbl->GetBIOSSettings(machine, &bios);
43fe83
     if (bios) {
43fe83
-        rc = bios->vtbl->SetACPIEnabled(bios, (def->features) &
43fe83
-                                        (1 << VIR_DOMAIN_FEATURE_ACPI));
43fe83
+        rc = bios->vtbl->SetACPIEnabled(bios,
43fe83
+                                        def->features[VIR_DOMAIN_FEATURE_ACPI] ==
43fe83
+                                        VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
         if (NS_FAILED(rc)) {
43fe83
             virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
                            _("could not change ACPI status to: %s, rc=%08x"),
43fe83
-                           ((def->features) & (1 << VIR_DOMAIN_FEATURE_ACPI))
43fe83
+                           (def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                            ? _("Enabled") : _("Disabled"), (unsigned)rc);
43fe83
         }
43fe83
-        rc = bios->vtbl->SetIOAPICEnabled(bios, (def->features) &
43fe83
-                                          (1 << VIR_DOMAIN_FEATURE_APIC));
43fe83
+        rc = bios->vtbl->SetIOAPICEnabled(bios,
43fe83
+                                          def->features[VIR_DOMAIN_FEATURE_APIC] ==
43fe83
+                                          VIR_DOMAIN_FEATURE_STATE_ON);
43fe83
         if (NS_FAILED(rc)) {
43fe83
             virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
                            _("could not change APIC status to: %s, rc=%08x"),
43fe83
-                           ((def->features) & (1 << VIR_DOMAIN_FEATURE_APIC))
43fe83
+                           (def->features[VIR_DOMAIN_FEATURE_APIC] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                            ? _("Enabled") : _("Disabled"), (unsigned)rc);
43fe83
         }
43fe83
         VBOX_RELEASE(bios);
43fe83
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
43fe83
index bca19af..5f8ca08 100644
43fe83
--- a/src/xenapi/xenapi_driver.c
43fe83
+++ b/src/xenapi/xenapi_driver.c
43fe83
@@ -1474,15 +1474,15 @@ xenapiDomainGetXMLDesc(virDomainPtr dom, unsigned int flags)
43fe83
         for (i = 0; i < result->size; i++) {
43fe83
             if (STREQ(result->contents[i].val, "true")) {
43fe83
                 if (STREQ(result->contents[i].key, "acpi"))
43fe83
-                    defPtr->features = defPtr->features | (1<
43fe83
+                    defPtr->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
                 else if (STREQ(result->contents[i].key, "apic"))
43fe83
-                    defPtr->features = defPtr->features | (1<
43fe83
+                    defPtr->features[VIR_DOMAIN_FEATURE_APIC] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
                 else if (STREQ(result->contents[i].key, "pae"))
43fe83
-                    defPtr->features = defPtr->features | (1<
43fe83
+                    defPtr->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
                 else if (STREQ(result->contents[i].key, "hap"))
43fe83
-                    defPtr->features = defPtr->features | (1<
43fe83
+                    defPtr->features[VIR_DOMAIN_FEATURE_HAP] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
                 else if (STREQ(result->contents[i].key, "viridian"))
43fe83
-                    defPtr->features = defPtr->features | (1<
43fe83
+                    defPtr->features[VIR_DOMAIN_FEATURE_VIRIDIAN] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
             }
43fe83
         }
43fe83
         xen_string_string_map_free(result);
43fe83
diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c
43fe83
index 91ae54b..02d4885 100644
43fe83
--- a/src/xenapi/xenapi_utils.c
43fe83
+++ b/src/xenapi/xenapi_utils.c
43fe83
@@ -511,18 +511,16 @@ createVMRecordFromXml(virConnectPtr conn, virDomainDefPtr def,
43fe83
     if (def->onCrash)
43fe83
         (*record)->actions_after_crash = actionCrashLibvirt2XenapiEnum(def->onCrash);
43fe83
 
43fe83
-    if (def->features) {
43fe83
-        if (def->features & (1 << VIR_DOMAIN_FEATURE_ACPI))
43fe83
-            allocStringMap(&strings, (char *)"acpi", (char *)"true");
43fe83
-        if (def->features & (1 << VIR_DOMAIN_FEATURE_APIC))
43fe83
-            allocStringMap(&strings, (char *)"apic", (char *)"true");
43fe83
-        if (def->features & (1 << VIR_DOMAIN_FEATURE_PAE))
43fe83
-            allocStringMap(&strings, (char *)"pae", (char *)"true");
43fe83
-        if (def->features & (1 << VIR_DOMAIN_FEATURE_HAP))
43fe83
-            allocStringMap(&strings, (char *)"hap", (char *)"true");
43fe83
-        if (def->features & (1 << VIR_DOMAIN_FEATURE_VIRIDIAN))
43fe83
-            allocStringMap(&strings, (char *)"viridian", (char *)"true");
43fe83
-    }
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
+        allocStringMap(&strings, (char *)"acpi", (char *)"true");
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_APIC] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
+        allocStringMap(&strings, (char *)"apic", (char *)"true");
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_PAE] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
+        allocStringMap(&strings, (char *)"pae", (char *)"true");
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_HAP] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
+        allocStringMap(&strings, (char *)"hap", (char *)"true");
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
+        allocStringMap(&strings, (char *)"viridian", (char *)"true");
43fe83
     if (strings != NULL)
43fe83
         (*record)->platform = strings;
43fe83
 
43fe83
diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
43fe83
index fbbbaa9..fb01e0d 100644
43fe83
--- a/src/xenxs/xen_sxpr.c
43fe83
+++ b/src/xenxs/xen_sxpr.c
43fe83
@@ -1204,15 +1204,15 @@ xenParseSxpr(const struct sexpr *root,
43fe83
 
43fe83
     if (hvm) {
43fe83
         if (sexpr_int(root, "domain/image/hvm/acpi"))
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_ACPI);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (sexpr_int(root, "domain/image/hvm/apic"))
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_APIC);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (sexpr_int(root, "domain/image/hvm/pae"))
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_PAE);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (sexpr_int(root, "domain/image/hvm/hap"))
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_HAP);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_HAP] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (sexpr_int(root, "domain/image/hvm/viridian"))
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_VIRIDIAN);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
     }
43fe83
 
43fe83
     /* 12aaf4a2486b (3.0.3) added a second low-priority 'localtime' setting */
43fe83
@@ -2335,15 +2335,15 @@ xenFormatSxpr(virConnectPtr conn,
43fe83
                 }
43fe83
             }
43fe83
 
43fe83
-            if (def->features & (1 << VIR_DOMAIN_FEATURE_ACPI))
43fe83
+            if (def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                 virBufferAddLit(&buf, "(acpi 1)");
43fe83
-            if (def->features & (1 << VIR_DOMAIN_FEATURE_APIC))
43fe83
+            if (def->features[VIR_DOMAIN_FEATURE_APIC] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                 virBufferAddLit(&buf, "(apic 1)");
43fe83
-            if (def->features & (1 << VIR_DOMAIN_FEATURE_PAE))
43fe83
+            if (def->features[VIR_DOMAIN_FEATURE_PAE] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                 virBufferAddLit(&buf, "(pae 1)");
43fe83
-            if (def->features & (1 << VIR_DOMAIN_FEATURE_HAP))
43fe83
+            if (def->features[VIR_DOMAIN_FEATURE_HAP] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                 virBufferAddLit(&buf, "(hap 1)");
43fe83
-            if (def->features & (1 << VIR_DOMAIN_FEATURE_VIRIDIAN))
43fe83
+            if (def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
                 virBufferAddLit(&buf, "(viridian 1)");
43fe83
 
43fe83
             virBufferAddLit(&buf, "(usb 1)");
43fe83
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
43fe83
index 1ffea84..1a1cd12 100644
43fe83
--- a/src/xenxs/xen_xm.c
43fe83
+++ b/src/xenxs/xen_xm.c
43fe83
@@ -398,23 +398,23 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
43fe83
         if (xenXMConfigGetBool(conf, "pae", &val, 0) < 0)
43fe83
             goto cleanup;
43fe83
         else if (val)
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_PAE);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (xenXMConfigGetBool(conf, "acpi", &val, 0) < 0)
43fe83
             goto cleanup;
43fe83
         else if (val)
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_ACPI);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (xenXMConfigGetBool(conf, "apic", &val, 0) < 0)
43fe83
             goto cleanup;
43fe83
         else if (val)
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_APIC);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (xenXMConfigGetBool(conf, "hap", &val, 0) < 0)
43fe83
             goto cleanup;
43fe83
         else if (val)
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_HAP);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_HAP] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
         if (xenXMConfigGetBool(conf, "viridian", &val, 0) < 0)
43fe83
             goto cleanup;
43fe83
         else if (val)
43fe83
-            def->features |= (1 << VIR_DOMAIN_FEATURE_VIRIDIAN);
43fe83
+            def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
 
43fe83
         if (xenXMConfigGetBool(conf, "hpet", &val, -1) < 0)
43fe83
             goto cleanup;
43fe83
@@ -1569,29 +1569,29 @@ virConfPtr xenFormatXM(virConnectPtr conn,
43fe83
             goto cleanup;
43fe83
 
43fe83
         if (xenXMConfigSetInt(conf, "pae",
43fe83
-                              (def->features &
43fe83
-                               (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
43fe83
+                              (def->features[VIR_DOMAIN_FEATURE_PAE] ==
43fe83
+                               VIR_DOMAIN_FEATURE_STATE_ON) ? 1 : 0) < 0)
43fe83
             goto cleanup;
43fe83
 
43fe83
         if (xenXMConfigSetInt(conf, "acpi",
43fe83
-                              (def->features &
43fe83
-                               (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
43fe83
+                              (def->features[VIR_DOMAIN_FEATURE_ACPI] ==
43fe83
+                               VIR_DOMAIN_FEATURE_STATE_ON) ? 1 : 0) < 0)
43fe83
             goto cleanup;
43fe83
 
43fe83
         if (xenXMConfigSetInt(conf, "apic",
43fe83
-                              (def->features &
43fe83
-                               (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
43fe83
+                              (def->features[VIR_DOMAIN_FEATURE_APIC] ==
43fe83
+                               VIR_DOMAIN_FEATURE_STATE_ON) ? 1 : 0) < 0)
43fe83
             goto cleanup;
43fe83
 
43fe83
         if (xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4) {
43fe83
             if (xenXMConfigSetInt(conf, "hap",
43fe83
-                                  (def->features &
43fe83
-                                   (1 << VIR_DOMAIN_FEATURE_HAP)) ? 1 : 0) < 0)
43fe83
+                                  (def->features[VIR_DOMAIN_FEATURE_HAP] ==
43fe83
+                                   VIR_DOMAIN_FEATURE_STATE_ON) ? 1 : 0) < 0)
43fe83
                 goto cleanup;
43fe83
 
43fe83
             if (xenXMConfigSetInt(conf, "viridian",
43fe83
-                                  (def->features &
43fe83
-                                   (1 << VIR_DOMAIN_FEATURE_VIRIDIAN)) ? 1 : 0) < 0)
43fe83
+                                  (def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] ==
43fe83
+                                   VIR_DOMAIN_FEATURE_STATE_ON) ? 1 : 0) < 0)
43fe83
                 goto cleanup;
43fe83
         }
43fe83
 
43fe83
-- 
43fe83
1.8.4.2
43fe83