提交 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 @@
virReportErrorHelper(VIR_FROM_CPU, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
VIR_ENUM_IMPL(virCPU, VIR_CPU_TYPE_LAST,
"host", "guest", "auto")
VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
"minimum",
"exact",
......@@ -446,3 +449,99 @@ no_memory:
virReportOOMError();
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 @@
enum virCPUType {
VIR_CPU_TYPE_HOST,
VIR_CPU_TYPE_GUEST,
VIR_CPU_TYPE_AUTO
VIR_CPU_TYPE_AUTO,
VIR_CPU_TYPE_LAST
};
VIR_ENUM_DECL(virCPU)
enum virCPUMatch {
VIR_CPU_MATCH_MINIMUM,
VIR_CPU_MATCH_EXACT,
......@@ -96,6 +100,9 @@ enum virCPUFormatFlags {
* in host capabilities */
};
bool
virCPUDefIsEqual(virCPUDefPtr src,
virCPUDefPtr dst);
char *
virCPUDefFormat(virCPUDefPtr def,
......
此差异已折叠。
......@@ -1096,7 +1096,12 @@ virDomainVcpupinDefPtr virDomainVcpupinFindByVcpu(virDomainVcpupinDefPtr *def,
int nvcpupin,
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 virDomainDef *virDomainDefPtr;
struct _virDomainDef {
......@@ -1342,6 +1347,9 @@ virDomainDefPtr virDomainDefParseNode(virCapsPtr caps,
virDomainObjPtr virDomainObjParseFile(virCapsPtr caps,
const char *filename);
bool virDomainDefCheckABIStability(virDomainDefPtr src,
virDomainDefPtr dst);
int virDomainDefAddImplicitControllers(virDomainDefPtr def);
char *virDomainDefFormat(virDomainDefPtr def,
......@@ -1503,7 +1511,6 @@ VIR_ENUM_DECL(virDomainChrTcpProtocol)
VIR_ENUM_DECL(virDomainChrSpicevmc)
VIR_ENUM_DECL(virDomainSoundModel)
VIR_ENUM_DECL(virDomainMemballoonModel)
VIR_ENUM_DECL(virDomainSysinfo)
VIR_ENUM_DECL(virDomainSmbiosMode)
VIR_ENUM_DECL(virDomainWatchdogModel)
VIR_ENUM_DECL(virDomainWatchdogAction)
......
......@@ -224,6 +224,7 @@ virDomainControllerTypeToString;
virDomainCpuSetFormat;
virDomainCpuSetParse;
virDomainDefAddImplicitControllers;
virDomainDefCheckABIStability;
virDomainDefClearDeviceAliases;
virDomainDefClearPCIAddresses;
virDomainDefFormat;
......
......@@ -33,7 +33,6 @@
#include "virterror_internal.h"
#include "sysinfo.h"
#include "util.h"
#include "conf/domain_conf.h"
#include "logging.h"
#include "memory.h"
#include "command.h"
......@@ -46,6 +45,9 @@
#define SYSINFO_SMBIOS_DECODER "dmidecode"
VIR_ENUM_IMPL(virSysinfo, VIR_SYSINFO_LAST,
"smbios");
/**
* virSysinfoDefFree:
* @def: a sysinfo structure
......@@ -131,7 +133,7 @@ virSysinfoRead(void) {
if (VIR_ALLOC(ret) < 0)
goto no_memory;
ret->type = VIR_DOMAIN_SYSINFO_SMBIOS;
ret->type = VIR_SYSINFO_SMBIOS;
base = outbuf;
......@@ -230,7 +232,7 @@ no_memory:
char *
virSysinfoFormat(virSysinfoDefPtr def, const char *prefix)
{
const char *type = virDomainSysinfoTypeToString(def->type);
const char *type = virSysinfoTypeToString(def->type);
virBuffer buf = VIR_BUFFER_INITIALIZER;
size_t len = strlen(prefix);
......@@ -326,4 +328,56 @@ virSysinfoFormat(virSysinfoDefPtr def, const char *prefix)
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 */
......@@ -27,10 +27,10 @@
# include "internal.h"
# include "util.h"
enum virDomainSysinfoType {
VIR_DOMAIN_SYSINFO_SMBIOS,
enum virSysinfoType {
VIR_SYSINFO_SMBIOS,
VIR_DOMAIN_SYSINFO_LAST
VIR_SYSINFO_LAST
};
typedef struct _virSysinfoDef virSysinfoDef;
......@@ -59,4 +59,9 @@ void virSysinfoDefFree(virSysinfoDefPtr def);
char *virSysinfoFormat(virSysinfoDefPtr def, const char *prefix)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
bool virSysinfoIsEqual(virSysinfoDefPtr src,
virSysinfoDefPtr dst);
VIR_ENUM_DECL(virSysinfo)
#endif /* __VIR_SYSINFOS_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册