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 memslot on the destination during ram_load.
Perhaps several fields of the DimmState struct should be part of a VMStateDescription to handle migration in a cleaner way.
Signed-off-by: Vasilis Liaskovitis vasilis.liaskovitis@profitbricks.com --- arch_init.c | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/arch_init.c b/arch_init.c index a9e8b74..5f46b98 100644 --- a/arch_init.c +++ b/arch_init.c @@ -43,6 +43,7 @@ #include "hw/smbios.h" #include "exec-memory.h" #include "hw/pcspk.h" +#include "hw/dimm.h"
#ifdef TARGET_SPARC int graphic_width = 1024; @@ -452,9 +453,25 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) }
if (!block) { - fprintf(stderr, "Unknown ramblock "%s", cannot " - "accept migration\n", id); - return -EINVAL; + /* this can happen if a dimm was hot-added at source host */ + DimmState *slot = dimm_find_from_name(id); + if (slot) { + dimm_activate(slot); + /* rescan ram_list, verify ramblock is there now */ + QLIST_FOREACH(block, &ram_list.blocks, next) { + if (!strncmp(id, block->idstr, sizeof(id))) { + if (block->length != length) + return -EINVAL; + break; + } + } + assert(block); + } + else { + fprintf(stderr, "Unknown ramblock "%s", cannot " + "accept migration\n", id); + return -EINVAL; + } }
total_ram_bytes -= length;