[libvirt] [PATCH] virDomainDefCheckABIStabilityFlags: Check for memoryBacking

https://bugzilla.redhat.com/show_bug.cgi?id=1450349 Problem is, memoryBacking is part of guest ABI. Therefore changing it on migration/restore from an image can lead qemu/guest to rejecting the image. At the same time, move other partial checks of virDomainMemtune into the same function: virDomainMemtuneCheckABIStability. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 101 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 26 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9eba70a95..89b93f4ad 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -19786,6 +19786,80 @@ virDomainTPMDefCheckABIStability(virDomainTPMDefPtr src, return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } + +static bool +virDomainMemtuneCheckABIStability(const virDomainDef *src, + const virDomainDef *dst, + unsigned int flags) +{ + if (virDomainDefGetMemoryInitial(src) != virDomainDefGetMemoryInitial(dst)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain max memory %lld " + "does not match source %lld"), + virDomainDefGetMemoryInitial(dst), + virDomainDefGetMemoryInitial(src)); + return false; + } + + if (!(flags & VIR_DOMAIN_DEF_ABI_CHECK_SKIP_VOLATILE) && + src->mem.cur_balloon != dst->mem.cur_balloon) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain current memory %lld " + "does not match source %lld"), + dst->mem.cur_balloon, + src->mem.cur_balloon); + return false; + } + + if (src->mem.max_memory != dst->mem.max_memory) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target maximum memory size '%llu' " + "doesn't match source '%llu'"), + dst->mem.max_memory, + src->mem.max_memory); + return false; + } + + if (src->mem.memory_slots != dst->mem.memory_slots) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain memory slots " + "count '%u' doesn't match source '%u'"), + dst->mem.memory_slots, + src->mem.memory_slots); + return false; + } + + if (src->mem.source != dst->mem.source) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memoryBacking source '%s' doesn't " + "match source memoryBacking source'%s'"), + virDomainMemorySourceTypeToString(dst->mem.source), + virDomainMemorySourceTypeToString(src->mem.source)); + return false; + } + + if (src->mem.access != dst->mem.access) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memoryBacking access '%s' doesn't " + "match access memoryBacking access'%s'"), + virDomainMemoryAccessTypeToString(dst->mem.access), + virDomainMemoryAccessTypeToString(src->mem.access)); + return false; + } + + if (src->mem.allocation != dst->mem.allocation) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memoryBacking allocation '%s' doesn't " + "match allocation memoryBacking allocation'%s'"), + virDomainMemoryAllocationTypeToString(dst->mem.allocation), + virDomainMemoryAllocationTypeToString(src->mem.allocation)); + return false; + } + + return true; +} + + static bool virDomainMemoryDefCheckABIStability(virDomainMemoryDefPtr src, virDomainMemoryDefPtr dst) @@ -19940,37 +20014,12 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src, goto error; } - if (virDomainDefGetMemoryInitial(src) != virDomainDefGetMemoryInitial(dst)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain max memory %lld does not match source %lld"), - virDomainDefGetMemoryInitial(dst), - virDomainDefGetMemoryInitial(src)); + if (!virDomainMemtuneCheckABIStability(src, dst, flags)) goto error; - } - if (!(flags & VIR_DOMAIN_DEF_ABI_CHECK_SKIP_VOLATILE) && - src->mem.cur_balloon != dst->mem.cur_balloon) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain current memory %lld does not match source %lld"), - dst->mem.cur_balloon, src->mem.cur_balloon); - goto error; - } if (!virDomainNumaCheckABIStability(src->numa, dst->numa)) goto error; - if (src->mem.memory_slots != dst->mem.memory_slots) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain memory slots count '%u' doesn't match source '%u'"), - dst->mem.memory_slots, src->mem.memory_slots); - goto error; - } - if (src->mem.max_memory != dst->mem.max_memory) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target maximum memory size '%llu' doesn't match source '%llu'"), - dst->mem.max_memory, src->mem.max_memory); - goto error; - } - if (!virDomainDefVcpuCheckAbiStability(src, dst)) goto error; -- 2.13.0

https://bugzilla.redhat.com/show_bug.cgi?id=1450349
Problem is, memoryBacking is part of guest ABI. Therefore changing it on migration/restore from an image can lead qemu/guest to rejecting the image.
At the same time, move other partial checks of virDomainMemtune into the same function: virDomainMemtuneCheckABIStability.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 101 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 26 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9eba70a95..89b93f4ad 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -19786,6 +19786,80 @@ virDomainTPMDefCheckABIStability(virDomainTPMDefPtr src, return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); }
+ +static bool +virDomainMemtuneCheckABIStability(const virDomainDef *src, + const virDomainDef *dst, + unsigned int flags) +{ + if (virDomainDefGetMemoryInitial(src) != virDomainDefGetMemoryInitial(dst)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain max memory %lld " + "does not match source %lld"), + virDomainDefGetMemoryInitial(dst), + virDomainDefGetMemoryInitial(src)); + return false; + } + + if (!(flags & VIR_DOMAIN_DEF_ABI_CHECK_SKIP_VOLATILE) && + src->mem.cur_balloon != dst->mem.cur_balloon) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain current memory %lld " + "does not match source %lld"), + dst->mem.cur_balloon, + src->mem.cur_balloon); + return false; + } + + if (src->mem.max_memory != dst->mem.max_memory) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target maximum memory size '%llu' " + "doesn't match source '%llu'"), + dst->mem.max_memory, + src->mem.max_memory); + return false; + } + + if (src->mem.memory_slots != dst->mem.memory_slots) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain memory slots " + "count '%u' doesn't match source '%u'"), + dst->mem.memory_slots, + src->mem.memory_slots); + return false; + } + + if (src->mem.source != dst->mem.source) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memoryBacking source '%s' doesn't " + "match source memoryBacking source'%s'"), + virDomainMemorySourceTypeToString(dst->mem.source), + virDomainMemorySourceTypeToString(src->mem.source)); + return false; + } AFAIK this is guest ABI only because qemu uses this to generate hugepages rather than regular memory, not that it would be guest ABI
On Thu, May 18, 2017 at 10:05:55 +0200, Michal Privoznik wrote: per se.
+ + if (src->mem.access != dst->mem.access) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memoryBacking access '%s' doesn't " + "match access memoryBacking access'%s'"), + virDomainMemoryAccessTypeToString(dst->mem.access), + virDomainMemoryAccessTypeToString(src->mem.access)); + return false;
Same here, shared access does not really transform to guest ABI.
+ } + + if (src->mem.allocation != dst->mem.allocation) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memoryBacking allocation '%s' doesn't " + "match allocation memoryBacking allocation'%s'"), + virDomainMemoryAllocationTypeToString(dst->mem.allocation), + virDomainMemoryAllocationTypeToString(src->mem.allocation)); + return false;
This is definitely not guest ABI. Note that there's a difference between guest ABI and differences in configurations which are rejected by qemu. I think we need a mechanism to deal with these in a different way because it's possible that other hypervisors will have different ideas on the compatibility of these options.
participants (2)
-
Michal Privoznik
-
Peter Krempa