提交 08106e20 编写于 作者: D Daniel P. Berrange

Add an API for comparing the ABI of two guest configurations

To allow a client app to pass in custom XML during migration
of a guest it is neccessary to ensure the guest ABI remains
unchanged. The virDomainDefCheckABIStablity method accepts
two virDomainDefPtr structs and compares everything in them
that could impact the guest machine ABI

* src/conf/domain_conf.c, src/conf/domain_conf.h,
  src/libvirt_private.syms: Add virDomainDefCheckABIStablity
* src/conf/cpu_conf.c, src/conf/cpu_conf.h: Add virCPUDefIsEqual
* src/util/sysinfo.c, src/util/sysinfo.h: Add virSysinfoIsEqual
上级 0e4d4afb
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
virReportErrorHelper(VIR_FROM_CPU, code, __FILE__, \ virReportErrorHelper(VIR_FROM_CPU, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__) __FUNCTION__, __LINE__, __VA_ARGS__)
VIR_ENUM_IMPL(virCPU, VIR_CPU_TYPE_LAST,
"host", "guest", "auto")
VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST, VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
"minimum", "minimum",
"exact", "exact",
...@@ -446,3 +449,99 @@ no_memory: ...@@ -446,3 +449,99 @@ no_memory:
virReportOOMError(); virReportOOMError();
return -1; return -1;
} }
bool
virCPUDefIsEqual(virCPUDefPtr src,
virCPUDefPtr dst)
{
bool identical = false;
int i;
if (!src && !dst)
return true;
if ((src && !dst) || (!src && dst)) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Target CPU does not match source"));
goto cleanup;
}
if (src->type != dst->type) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU type %s does not match source %s"),
virCPUTypeToString(dst->type),
virCPUTypeToString(src->type));
goto cleanup;
}
if (STRNEQ_NULLABLE(src->arch, dst->arch)) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU arch %s does not match source %s"),
NULLSTR(dst->arch), NULLSTR(src->arch));
goto cleanup;
}
if (STRNEQ_NULLABLE(src->model, dst->model)) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU model %s does not match source %s"),
NULLSTR(dst->model), NULLSTR(src->model));
goto cleanup;
}
if (STRNEQ_NULLABLE(src->vendor, dst->vendor)) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU vendor %s does not match source %s"),
NULLSTR(dst->vendor), NULLSTR(src->vendor));
goto cleanup;
}
if (src->sockets != dst->sockets) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU sockets %d does not match source %d"),
dst->sockets, src->sockets);
goto cleanup;
}
if (src->cores != dst->cores) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU cores %d does not match source %d"),
dst->cores, src->cores);
goto cleanup;
}
if (src->threads != dst->threads) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU threads %d does not match source %d"),
dst->threads, src->threads);
goto cleanup;
}
if (src->nfeatures != dst->nfeatures) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU feature count %zu does not match source %zu"),
dst->nfeatures, src->nfeatures);
goto cleanup;
}
for (i = 0 ; i < src->nfeatures ; i++) {
if (STRNEQ(src->features[i].name, dst->features[i].name)) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU feature %s does not match source %s"),
dst->features[i].name, src->features[i].name);
goto cleanup;
}
if (src->features[i].policy != dst->features[i].policy) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU feature policy %s does not match source %s"),
virCPUFeaturePolicyTypeToString(dst->features[i].policy),
virCPUFeaturePolicyTypeToString(src->features[i].policy));
goto cleanup;
}
}
identical = true;
cleanup:
return identical;
}
...@@ -31,9 +31,13 @@ ...@@ -31,9 +31,13 @@
enum virCPUType { enum virCPUType {
VIR_CPU_TYPE_HOST, VIR_CPU_TYPE_HOST,
VIR_CPU_TYPE_GUEST, VIR_CPU_TYPE_GUEST,
VIR_CPU_TYPE_AUTO VIR_CPU_TYPE_AUTO,
VIR_CPU_TYPE_LAST
}; };
VIR_ENUM_DECL(virCPU)
enum virCPUMatch { enum virCPUMatch {
VIR_CPU_MATCH_MINIMUM, VIR_CPU_MATCH_MINIMUM,
VIR_CPU_MATCH_EXACT, VIR_CPU_MATCH_EXACT,
...@@ -96,6 +100,9 @@ enum virCPUFormatFlags { ...@@ -96,6 +100,9 @@ enum virCPUFormatFlags {
* in host capabilities */ * in host capabilities */
}; };
bool
virCPUDefIsEqual(virCPUDefPtr src,
virCPUDefPtr dst);
char * char *
virCPUDefFormat(virCPUDefPtr def, virCPUDefFormat(virCPUDefPtr def,
......
此差异已折叠。
...@@ -1096,7 +1096,12 @@ virDomainVcpupinDefPtr virDomainVcpupinFindByVcpu(virDomainVcpupinDefPtr *def, ...@@ -1096,7 +1096,12 @@ virDomainVcpupinDefPtr virDomainVcpupinFindByVcpu(virDomainVcpupinDefPtr *def,
int nvcpupin, int nvcpupin,
int vcpu); int vcpu);
/* Guest VM main configuration */ /*
* Guest VM main configuration
*
* NB: if adding to this struct, virDomainDefCheckABIStability
* may well need an update
*/
typedef struct _virDomainDef virDomainDef; typedef struct _virDomainDef virDomainDef;
typedef virDomainDef *virDomainDefPtr; typedef virDomainDef *virDomainDefPtr;
struct _virDomainDef { struct _virDomainDef {
...@@ -1342,6 +1347,9 @@ virDomainDefPtr virDomainDefParseNode(virCapsPtr caps, ...@@ -1342,6 +1347,9 @@ virDomainDefPtr virDomainDefParseNode(virCapsPtr caps,
virDomainObjPtr virDomainObjParseFile(virCapsPtr caps, virDomainObjPtr virDomainObjParseFile(virCapsPtr caps,
const char *filename); const char *filename);
bool virDomainDefCheckABIStability(virDomainDefPtr src,
virDomainDefPtr dst);
int virDomainDefAddImplicitControllers(virDomainDefPtr def); int virDomainDefAddImplicitControllers(virDomainDefPtr def);
char *virDomainDefFormat(virDomainDefPtr def, char *virDomainDefFormat(virDomainDefPtr def,
...@@ -1503,7 +1511,6 @@ VIR_ENUM_DECL(virDomainChrTcpProtocol) ...@@ -1503,7 +1511,6 @@ VIR_ENUM_DECL(virDomainChrTcpProtocol)
VIR_ENUM_DECL(virDomainChrSpicevmc) VIR_ENUM_DECL(virDomainChrSpicevmc)
VIR_ENUM_DECL(virDomainSoundModel) VIR_ENUM_DECL(virDomainSoundModel)
VIR_ENUM_DECL(virDomainMemballoonModel) VIR_ENUM_DECL(virDomainMemballoonModel)
VIR_ENUM_DECL(virDomainSysinfo)
VIR_ENUM_DECL(virDomainSmbiosMode) VIR_ENUM_DECL(virDomainSmbiosMode)
VIR_ENUM_DECL(virDomainWatchdogModel) VIR_ENUM_DECL(virDomainWatchdogModel)
VIR_ENUM_DECL(virDomainWatchdogAction) VIR_ENUM_DECL(virDomainWatchdogAction)
......
...@@ -224,6 +224,7 @@ virDomainControllerTypeToString; ...@@ -224,6 +224,7 @@ virDomainControllerTypeToString;
virDomainCpuSetFormat; virDomainCpuSetFormat;
virDomainCpuSetParse; virDomainCpuSetParse;
virDomainDefAddImplicitControllers; virDomainDefAddImplicitControllers;
virDomainDefCheckABIStability;
virDomainDefClearDeviceAliases; virDomainDefClearDeviceAliases;
virDomainDefClearPCIAddresses; virDomainDefClearPCIAddresses;
virDomainDefFormat; virDomainDefFormat;
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "virterror_internal.h" #include "virterror_internal.h"
#include "sysinfo.h" #include "sysinfo.h"
#include "util.h" #include "util.h"
#include "conf/domain_conf.h"
#include "logging.h" #include "logging.h"
#include "memory.h" #include "memory.h"
#include "command.h" #include "command.h"
...@@ -46,6 +45,9 @@ ...@@ -46,6 +45,9 @@
#define SYSINFO_SMBIOS_DECODER "dmidecode" #define SYSINFO_SMBIOS_DECODER "dmidecode"
VIR_ENUM_IMPL(virSysinfo, VIR_SYSINFO_LAST,
"smbios");
/** /**
* virSysinfoDefFree: * virSysinfoDefFree:
* @def: a sysinfo structure * @def: a sysinfo structure
...@@ -131,7 +133,7 @@ virSysinfoRead(void) { ...@@ -131,7 +133,7 @@ virSysinfoRead(void) {
if (VIR_ALLOC(ret) < 0) if (VIR_ALLOC(ret) < 0)
goto no_memory; goto no_memory;
ret->type = VIR_DOMAIN_SYSINFO_SMBIOS; ret->type = VIR_SYSINFO_SMBIOS;
base = outbuf; base = outbuf;
...@@ -230,7 +232,7 @@ no_memory: ...@@ -230,7 +232,7 @@ no_memory:
char * char *
virSysinfoFormat(virSysinfoDefPtr def, const char *prefix) virSysinfoFormat(virSysinfoDefPtr def, const char *prefix)
{ {
const char *type = virDomainSysinfoTypeToString(def->type); const char *type = virSysinfoTypeToString(def->type);
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
size_t len = strlen(prefix); size_t len = strlen(prefix);
...@@ -326,4 +328,56 @@ virSysinfoFormat(virSysinfoDefPtr def, const char *prefix) ...@@ -326,4 +328,56 @@ virSysinfoFormat(virSysinfoDefPtr def, const char *prefix)
return virBufferContentAndReset(&buf); return virBufferContentAndReset(&buf);
} }
bool virSysinfoIsEqual(virSysinfoDefPtr src,
virSysinfoDefPtr dst)
{
bool identical = false;
if (!src && !dst)
return true;
if ((src && !dst) || (!src && dst)) {
virSmbiosReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Target sysinfo does not match source"));
goto cleanup;
}
if (src->type != dst->type) {
virSmbiosReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target sysinfo %s does not match source %s"),
virSysinfoTypeToString(dst->type),
virSysinfoTypeToString(src->type));
goto cleanup;
}
# define CHECK_FIELD(name, desc) \
do { \
if (STRNEQ_NULLABLE(src->name, dst->name)) { \
virSmbiosReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
_("Target sysinfo %s %s does not match source %s"), \
desc, NULLSTR(src->name), NULLSTR(dst->name)); \
} \
} while (0)
CHECK_FIELD(bios_vendor, "BIOS vendor");
CHECK_FIELD(bios_version, "BIOS version");
CHECK_FIELD(bios_date, "BIOS date");
CHECK_FIELD(bios_release, "BIOS release");
CHECK_FIELD(system_manufacturer, "system vendor");
CHECK_FIELD(system_product, "system product");
CHECK_FIELD(system_version, "system version");
CHECK_FIELD(system_serial, "system serial");
CHECK_FIELD(system_uuid, "system uuid");
CHECK_FIELD(system_sku, "system sku");
CHECK_FIELD(system_family, "system family");
# undef CHECK_FIELD
identical = true;
cleanup:
return identical;
}
#endif /* !WIN32 */ #endif /* !WIN32 */
...@@ -27,10 +27,10 @@ ...@@ -27,10 +27,10 @@
# include "internal.h" # include "internal.h"
# include "util.h" # include "util.h"
enum virDomainSysinfoType { enum virSysinfoType {
VIR_DOMAIN_SYSINFO_SMBIOS, VIR_SYSINFO_SMBIOS,
VIR_DOMAIN_SYSINFO_LAST VIR_SYSINFO_LAST
}; };
typedef struct _virSysinfoDef virSysinfoDef; typedef struct _virSysinfoDef virSysinfoDef;
...@@ -59,4 +59,9 @@ void virSysinfoDefFree(virSysinfoDefPtr def); ...@@ -59,4 +59,9 @@ void virSysinfoDefFree(virSysinfoDefPtr def);
char *virSysinfoFormat(virSysinfoDefPtr def, const char *prefix) char *virSysinfoFormat(virSysinfoDefPtr def, const char *prefix)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
bool virSysinfoIsEqual(virSysinfoDefPtr src,
virSysinfoDefPtr dst);
VIR_ENUM_DECL(virSysinfo)
#endif /* __VIR_SYSINFOS_H__ */ #endif /* __VIR_SYSINFOS_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册