Commit 38e0735e authored by Anthony Liguori's avatar Anthony Liguori
Browse files

ivshmem: use migration blockers to prevent live migration in peer mode (v2)



Now when you try to migrate with ivshmem, you get a proper QMP error:

(qemu) migrate tcp:localhost:1025
Migration is disabled when using feature 'peer mode' in device 'ivshmem'
(qemu)
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent fa2756b7
......@@ -18,6 +18,8 @@
#include "pci.h"
#include "msix.h"
#include "kvm.h"
#include "migration.h"
#include "qerror.h"
#include <sys/mman.h>
#include <sys/types.h>
......@@ -78,6 +80,8 @@ typedef struct IVShmemState {
uint32_t features;
EventfdEntry *eventfd_table;
Error *migration_blocker;
char * shmobj;
char * sizearg;
char * role;
......@@ -646,7 +650,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
}
if (s->role_val == IVSHMEM_PEER) {
register_device_unmigratable(&s->dev.qdev, "ivshmem", s);
error_set(&s->migration_blocker, QERR_DEVICE_FEATURE_BLOCKS_MIGRATION, "ivshmem", "peer mode");
migrate_add_blocker(s->migration_blocker);
}
pci_conf = s->dev.config;
......@@ -741,6 +746,11 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
{
IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
if (s->migration_blocker) {
migrate_del_blocker(s->migration_blocker);
error_free(s->migration_blocker);
}
memory_region_destroy(&s->ivshmem_mmio);
memory_region_del_subregion(&s->bar, &s->ivshmem);
memory_region_destroy(&s->ivshmem);
......
......@@ -72,6 +72,10 @@ static const QErrorStringTable qerror_table[] = {
.error_fmt = QERR_DEVICE_IN_USE,
.desc = "Device '%(device)' is in use",
},
{
.error_fmt = QERR_DEVICE_FEATURE_BLOCKS_MIGRATION,
.desc = "Migration is disabled when using feature '%(feature)' in device '%(device)'",
},
{
.error_fmt = QERR_DEVICE_LOCKED,
.desc = "Device '%(device)' is locked",
......
......@@ -72,6 +72,9 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_DEVICE_IN_USE \
"{ 'class': 'DeviceInUse', 'data': { 'device': %s } }"
#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \
"{ 'class': 'DeviceFeatureBlocksMigration', 'data': { 'device': %s, 'feature': %s } }"
#define QERR_DEVICE_LOCKED \
"{ 'class': 'DeviceLocked', 'data': { 'device': %s } }"
......
......@@ -1255,31 +1255,6 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
}
}
/* mark a device as not to be migrated, that is the device should be
unplugged before migration */
void register_device_unmigratable(DeviceState *dev, const char *idstr,
void *opaque)
{
SaveStateEntry *se;
char id[256] = "";
if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
char *path = dev->parent_bus->info->get_dev_path(dev);
if (path) {
pstrcpy(id, sizeof(id), path);
pstrcat(id, sizeof(id), "/");
g_free(path);
}
}
pstrcat(id, sizeof(id), idstr);
QTAILQ_FOREACH(se, &savevm_handlers, entry) {
if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
se->no_migrate = 1;
}
}
}
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
const VMStateDescription *vmsd,
void *opaque, int alias_id,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment