Live migration works after memory hot-add events, as long as the qemu command line "-dimm" arguments are changed on the destination host to specify "populated=on" for the dimms that have been hot-added.
If a command-line change has not occured, the destination host does not yet have the corresponding ramblock in its ram_list. Activate the dimm on the destination during ram_load.
Perhaps several fields of the DimmDevice should be part of a VMStateDescription to handle migration in a cleaner way. But the problem is that ramblocks are checked before qdev vmstates.
Signed-off-by: Vasilis Liaskovitis vasilis.liaskovitis@profitbricks.com --- arch_init.c | 24 +++++++++++++++++++++--- 1 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/arch_init.c b/arch_init.c index 5a1173e..b63caa7 100644 --- a/arch_init.c +++ b/arch_init.c @@ -45,6 +45,7 @@ #include "hw/pcspk.h" #include "qemu/page_cache.h" #include "qmp-commands.h" +#include "hw/dimm.h"
#ifdef DEBUG_ARCH_INIT #define DPRINTF(fmt, ...) \ @@ -740,10 +741,27 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) }
if (!block) { - fprintf(stderr, "Unknown ramblock "%s", cannot " + /* this can happen if a dimm was hot-added at source host */ + bool ramblock_found = false; + if (dimm_add(id)) { + fprintf(stderr, "Cannot add unknown ramblock "%s", " + "cannot accept migration\n", id); + ret = -EINVAL; + goto done; + } + /* rescan ram_list, verify ramblock is there now */ + QLIST_FOREACH(block, &ram_list.blocks, next) { + if (!strncmp(id, block->idstr, sizeof(id))) { + ramblock_found = true; + break; + } + } + if (!ramblock_found) { + fprintf(stderr, "Unknown ramblock "%s", cannot " "accept migration\n", id); - ret = -EINVAL; - goto done; + ret = -EINVAL; + goto done; + } }
total_ram_bytes -= length;