3e5111
From 57b2e02a1c4cf52f3ea1ec3af469dd4e44402595 Mon Sep 17 00:00:00 2001
3e5111
Message-Id: <57b2e02a1c4cf52f3ea1ec3af469dd4e44402595@dist-git>
3e5111
From: Jiri Denemark <jdenemar@redhat.com>
3e5111
Date: Wed, 29 Mar 2017 14:45:44 +0200
3e5111
Subject: [PATCH] cpu: Introduce virCPUCopyMigratable
3e5111
3e5111
This new internal API makes a copy of virCPUDef while removing all
3e5111
features which would block migration. It uses cpu_map.xml as a database
3e5111
of such features, which should only be used as a fallback when we cannot
3e5111
get the data from a hypervisor. The main goal of this API is to decouple
3e5111
this filtering from virCPUUpdate so that the hypervisor driver can
3e5111
filter the features according to the hypervisor.
3e5111
3e5111
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
3e5111
(cherry picked from commit 05e91c79f19e0be96526098d58a3498dac3f8529)
3e5111
3e5111
https://bugzilla.redhat.com/show_bug.cgi?id=1444421
3e5111
3e5111
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
3e5111
---
3e5111
 src/cpu/cpu.c            | 31 +++++++++++++++++++++++++++++++
3e5111
 src/cpu/cpu.h            |  8 ++++++++
3e5111
 src/cpu/cpu_x86.c        | 25 +++++++++++++++++++++++++
3e5111
 src/libvirt_private.syms |  1 +
3e5111
 4 files changed, 65 insertions(+)
3e5111
3e5111
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
3e5111
index 93647a2ed..8a407ac18 100644
3e5111
--- a/src/cpu/cpu.c
3e5111
+++ b/src/cpu/cpu.c
3e5111
@@ -1130,3 +1130,34 @@ virCPUExpandFeatures(virArch arch,
3e5111
     VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
3e5111
     return 0;
3e5111
 }
3e5111
+
3e5111
+
3e5111
+/**
3e5111
+ * virCPUCopyMigratable:
3e5111
+ *
3e5111
+ * @arch: CPU architecture
3e5111
+ * @cpu: CPU definition to be copied
3e5111
+ *
3e5111
+ * Makes a copy of @cpu with all features which would block migration removed.
3e5111
+ * If this doesn't make sense for a given architecture, the function returns a
3e5111
+ * plain copy of @cpu (i.e., a copy with no features removed).
3e5111
+ *
3e5111
+ * Returns the copy of the CPU or NULL on error.
3e5111
+ */
3e5111
+virCPUDefPtr
3e5111
+virCPUCopyMigratable(virArch arch,
3e5111
+                     virCPUDefPtr cpu)
3e5111
+{
3e5111
+    struct cpuArchDriver *driver;
3e5111
+
3e5111
+    VIR_DEBUG("arch=%s, cpu=%p, model=%s",
3e5111
+              virArchToString(arch), cpu, NULLSTR(cpu->model));
3e5111
+
3e5111
+    if (!(driver = cpuGetSubDriver(arch)))
3e5111
+        return NULL;
3e5111
+
3e5111
+    if (driver->copyMigratable)
3e5111
+        return driver->copyMigratable(cpu);
3e5111
+    else
3e5111
+        return virCPUDefCopy(cpu);
3e5111
+}
3e5111
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
3e5111
index 8c238ad55..352445c40 100644
3e5111
--- a/src/cpu/cpu.h
3e5111
+++ b/src/cpu/cpu.h
3e5111
@@ -118,6 +118,9 @@ typedef int
3e5111
 typedef int
3e5111
 (*virCPUArchExpandFeatures)(virCPUDefPtr cpu);
3e5111
 
3e5111
+typedef virCPUDefPtr
3e5111
+(*virCPUArchCopyMigratable)(virCPUDefPtr cpu);
3e5111
+
3e5111
 struct cpuArchDriver {
3e5111
     const char *name;
3e5111
     const virArch *arch;
3e5111
@@ -138,6 +141,7 @@ struct cpuArchDriver {
3e5111
     virCPUArchTranslate translate;
3e5111
     virCPUArchConvertLegacy convertLegacy;
3e5111
     virCPUArchExpandFeatures expandFeatures;
3e5111
+    virCPUArchCopyMigratable copyMigratable;
3e5111
 };
3e5111
 
3e5111
 
3e5111
@@ -254,6 +258,10 @@ int
3e5111
 virCPUExpandFeatures(virArch arch,
3e5111
                      virCPUDefPtr cpu);
3e5111
 
3e5111
+virCPUDefPtr
3e5111
+virCPUCopyMigratable(virArch arch,
3e5111
+                     virCPUDefPtr cpu);
3e5111
+
3e5111
 /* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
3e5111
  * have no real-life usage
3e5111
  */
3e5111
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
3e5111
index 48648a7f4..a771b251e 100644
3e5111
--- a/src/cpu/cpu_x86.c
3e5111
+++ b/src/cpu/cpu_x86.c
3e5111
@@ -2903,6 +2903,30 @@ virCPUx86ExpandFeatures(virCPUDefPtr cpu)
3e5111
 }
3e5111
 
3e5111
 
3e5111
+static virCPUDefPtr
3e5111
+virCPUx86CopyMigratable(virCPUDefPtr cpu)
3e5111
+{
3e5111
+    virCPUDefPtr copy;
3e5111
+    virCPUx86MapPtr map;
3e5111
+
3e5111
+    if (!(map = virCPUx86GetMap()))
3e5111
+        return NULL;
3e5111
+
3e5111
+    if (!(copy = virCPUDefCopyWithoutModel(cpu)))
3e5111
+        return NULL;
3e5111
+
3e5111
+    if (virCPUDefCopyModelFilter(copy, cpu, false,
3e5111
+                                 x86FeatureIsMigratable, map) < 0)
3e5111
+        goto error;
3e5111
+
3e5111
+    return copy;
3e5111
+
3e5111
+ error:
3e5111
+    virCPUDefFree(copy);
3e5111
+    return NULL;
3e5111
+}
3e5111
+
3e5111
+
3e5111
 int
3e5111
 virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
3e5111
                       const virCPUx86CPUID *cpuid)
3e5111
@@ -2978,4 +3002,5 @@ struct cpuArchDriver cpuDriverX86 = {
3e5111
     .getModels  = virCPUx86GetModels,
3e5111
     .translate  = virCPUx86Translate,
3e5111
     .expandFeatures = virCPUx86ExpandFeatures,
3e5111
+    .copyMigratable = virCPUx86CopyMigratable,
3e5111
 };
3e5111
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
3e5111
index 9a334311d..cc78c5975 100644
3e5111
--- a/src/libvirt_private.syms
3e5111
+++ b/src/libvirt_private.syms
3e5111
@@ -1018,6 +1018,7 @@ virCPUCheckFeature;
3e5111
 virCPUCompare;
3e5111
 virCPUCompareXML;
3e5111
 virCPUConvertLegacy;
3e5111
+virCPUCopyMigratable;
3e5111
 virCPUDataCheckFeature;
3e5111
 virCPUDataFormat;
3e5111
 virCPUDataFree;
3e5111
-- 
3e5111
2.12.2
3e5111