Skip to content

Commit

Permalink
Merge tag 'migration-20231102-pull-request' of https://gitlab.com/jua…
Browse files Browse the repository at this point in the history
…n.quintela/qemu into staging

Migration Pull request (20231102)

Hi

In this pull request:

- migration reboot mode (steve)
  * I disabled the test because our CI don't like programs using so
    much shared memory.  Searching for a fix.
- test for postcopy recover (fabiano)
- MigrateAddress QAPI (het)
- better return path error handling (peter)
- traces for downtime (peter)
- vmstate_register() check for duplicates (juan)
  thomas find better solutions for s390x and ipmi.
  now also works on s390x

Please, apply.

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmVDipMACgkQ9IfvGFhy
# 1yNYnQ/9E5Cywsoqljqa/9FiKBSII2qMrmkfu6JLKqePnsh5pFZiukbudYRuJCCe
# ZTDEmD0NmKRJbDx2xRU1qx/e6gKJy+gz37KP89Buuh/WwZHPboPYtxQpGvCSiH26
# J3i+1+TgaqmkLzcO35wa8tp6gneQclWeAwKgMvdb4cm2pJEhgWRKI62ccyLzxeve
# UCzFQn60t55ETyVZGnRD4YwdTQvGKH+DPlyTuJOLR3DePuvZd8EdH+ypvB4RLAy7
# 3+CuQOxmF5LRXPbpJuAeOsudbmhhHzrO/yL7ZmsiKQTthsJv+SzC1bO94jhQrawZ
# Q7GCii5KpGq0KnRTRKZRGk6XKwxcYRduXMX3R5tXuVmDmCZsjhXzziU8yEdftph8
# 5TJdk1o0Gb043EFu81mrsQYS+9yJqe6sy6m3PTJaec54cAty5ln+c17WOvpAOaSV
# +1phe05ftuVPmQ3KWhbIR/tCmavNLwEZxpVIfyaKJx04bFbtQ9gRpRyURORX4KXc
# s4WXvNirQEohxYBnP4TPvA09xBTW3V08pk/wRDwt0YDXnLiqCltOuxD8r05K8K4B
# MkCLcWj0g7he2tBkF60oz1KSIE0oTB81um9AzLIv5F2YSYLaJM5BIcoC437MR2f4
# MOR7drR1fP5GsRu/SeU5BWvhVq3IvdOxR7G2MLNRJJvl7ZtGXDc=
# =uaqL
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 02 Nov 2023 19:40:03 HKT
# gpg:                using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full]
# gpg:                 aka "Juan Quintela <quintela@trasno.org>" [full]
# Primary key fingerprint: 1899 FF8E DEBF 58CC EE03  4B82 F487 EF18 5872 D723

* tag 'migration-20231102-pull-request' of https://gitlab.com/juan.quintela/qemu: (40 commits)
  migration: modify test_multifd_tcp_none() to use new QAPI syntax.
  migration: Implement MigrateChannelList to hmp migration flow.
  migration: Implement MigrateChannelList to qmp migration flow.
  migration: modify migration_channels_and_uri_compatible() for new QAPI syntax
  migration: New migrate and migrate-incoming argument 'channels'
  migration: Convert the file backend to the new QAPI syntax
  migration: convert exec backend to accept MigrateAddress.
  migration: convert rdma backend to accept MigrateAddress
  migration: convert socket backend to accept MigrateAddress
  migration: convert migration 'uri' into 'MigrateAddress'
  migration: New QAPI type 'MigrateAddress'
  migration: Change ram_dirty_bitmap_reload() retval to bool
  tests/migration-test: Add a test for postcopy hangs during RECOVER
  migration: Allow network to fail even during recovery
  migration: Refactor error handling in source return path
  tests/qtest: migration: add reboot mode test
  cpr: reboot mode
  cpr: relax vhost migration blockers
  cpr: relax blockdev migration blockers
  migration: per-mode blockers
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Nov 3, 2023
2 parents 4a6a6cb + 8e3766e commit 75b7b25
Show file tree
Hide file tree
Showing 61 changed files with 1,307 additions and 467 deletions.
2 changes: 1 addition & 1 deletion audio/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,7 @@ static AudioState *audio_init(Audiodev *dev, Error **errp)

QTAILQ_INSERT_TAIL(&audio_states, s, list);
QLIST_INIT (&s->card_head);
vmstate_register (NULL, 0, &vmstate_audio, s);
vmstate_register_any(NULL, &vmstate_audio, s);
return s;

out:
Expand Down
3 changes: 1 addition & 2 deletions backends/dbus-vmstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,7 @@ dbus_vmstate_complete(UserCreatable *uc, Error **errp)
return;
}

if (vmstate_register(VMSTATE_IF(self), VMSTATE_INSTANCE_ID_ANY,
&dbus_vmstate, self) < 0) {
if (vmstate_register_any(VMSTATE_IF(self), &dbus_vmstate, self) < 0) {
error_setg(errp, "Failed to register vmstate");
}
}
Expand Down
3 changes: 1 addition & 2 deletions backends/tpm/tpm_emulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,7 @@ static void tpm_emulator_inst_init(Object *obj)
qemu_add_vm_change_state_handler(tpm_emulator_vm_state_change,
tpm_emu);

vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
&vmstate_tpm_emulator, obj);
vmstate_register_any(NULL, &vmstate_tpm_emulator, obj);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion block/parallels.c
Original file line number Diff line number Diff line change
Expand Up @@ -1369,7 +1369,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
bdrv_get_device_or_node_name(bs));
bdrv_graph_rdunlock_main_loop();

ret = migrate_add_blocker(&s->migration_blocker, errp);
ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion block/qcow.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
bdrv_get_device_or_node_name(bs));
bdrv_graph_rdunlock_main_loop();

ret = migrate_add_blocker(&s->migration_blocker, errp);
ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion block/vdi.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
bdrv_get_device_or_node_name(bs));
bdrv_graph_rdunlock_main_loop();

ret = migrate_add_blocker(&s->migration_blocker, errp);
ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
goto fail_free_bmap;
}
Expand Down
2 changes: 1 addition & 1 deletion block/vhdx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
error_setg(&s->migration_blocker, "The vhdx format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
ret = migrate_add_blocker(&s->migration_blocker, errp);
ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion block/vmdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1386,7 +1386,7 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
error_setg(&s->migration_blocker, "The vmdk format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
ret = migrate_add_blocker(&s->migration_blocker, errp);
ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion block/vpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
bdrv_get_device_or_node_name(bs));
bdrv_graph_rdunlock_main_loop();

ret = migrate_add_blocker(&s->migration_blocker, errp);
ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion block/vvfat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
"The vvfat (rw) format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
ret = migrate_add_blocker(&s->migration_blocker, errp);
ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
goto fail;
}
Expand Down
12 changes: 8 additions & 4 deletions docs/devel/migration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,17 @@ An example (from hw/input/pckbd.c)
}
};
We are declaring the state with name "pckbd".
The ``version_id`` is 3, and the fields are 4 uint8_t in a KBDState structure.
We registered this with:
We are declaring the state with name "pckbd". The ``version_id`` is
3, and there are 4 uint8_t fields in the KBDState structure. We
registered this ``VMSTATEDescription`` with one of the following
functions. The first one will generate a device ``instance_id``
different for each registration. Use the second one if you already
have an id that is different for each instance of the device:
.. code:: c
vmstate_register(NULL, 0, &vmstate_kbd, s);
vmstate_register_any(NULL, &vmstate_kbd, s);
vmstate_register(NULL, instance_id, &vmstate_kbd, s);
For devices that are ``qdev`` based, we can register the device in the class
init function:
Expand Down
14 changes: 14 additions & 0 deletions hw/core/qdev-properties-system.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,20 @@ const PropertyInfo qdev_prop_multifd_compression = {
.set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- MigMode --- */

QEMU_BUILD_BUG_ON(sizeof(MigMode) != sizeof(int));

const PropertyInfo qdev_prop_mig_mode = {
.name = "MigMode",
.description = "mig_mode values, "
"normal,cpr-reboot",
.enum_table = &MigMode_lookup,
.get = qdev_propinfo_get_enum,
.set = qdev_propinfo_set_enum,
.set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- Reserved Region --- */

/*
Expand Down
2 changes: 1 addition & 1 deletion hw/display/vmware_vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s,

vga_common_init(&s->vga, OBJECT(dev), &error_fatal);
vga_init(&s->vga, OBJECT(dev), address_space, io, true);
vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
vmstate_register_any(NULL, &vmstate_vga_common, &s->vga);
s->new_depth = 32;
}

Expand Down
2 changes: 1 addition & 1 deletion hw/i2c/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
QLIST_INIT(&bus->current_devs);
QSIMPLEQ_INIT(&bus->pending_masters);
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
vmstate_register_any(NULL, &vmstate_i2c_bus, bus);
return bus;
}

Expand Down
2 changes: 1 addition & 1 deletion hw/ide/isa.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
ide_bus_init(&s->bus, sizeof(s->bus), dev, 0, 2);
ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
ide_bus_init_output_irq(&s->bus, isa_get_irq(isadev, s->irqnum));
vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_isa, s);
vmstate_register_any(VMSTATE_IF(dev), &vmstate_ide_isa, s);
ide_bus_register_restart_cb(&s->bus);
}

Expand Down
2 changes: 1 addition & 1 deletion hw/input/adb.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ static void adb_bus_realize(BusState *qbus, Error **errp)
adb_bus->autopoll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, adb_autopoll,
adb_bus);

vmstate_register(NULL, -1, &vmstate_adb_bus, adb_bus);
vmstate_register_any(NULL, &vmstate_adb_bus, adb_bus);
}

static void adb_bus_unrealize(BusState *qbus)
Expand Down
2 changes: 1 addition & 1 deletion hw/input/ads7846.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ static void ads7846_realize(SSIPeripheral *d, Error **errp)

ads7846_int_update(s);

vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_ads7846, s);
vmstate_register_any(NULL, &vmstate_ads7846, s);
}

static void ads7846_class_init(ObjectClass *klass, void *data)
Expand Down
3 changes: 1 addition & 2 deletions hw/input/stellaris_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,5 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
}
s->num_buttons = n;
qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
&vmstate_stellaris_gamepad, s);
vmstate_register_any(NULL, &vmstate_stellaris_gamepad, s);
}
18 changes: 16 additions & 2 deletions hw/intc/xics.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,22 @@ static void icp_realize(DeviceState *dev, Error **errp)
return;
}
}

vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
/*
* The way that pre_2_10_icp is handling is really, really hacky.
* We used to have here this call:
*
* vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
*
* But we were doing:
* pre_2_10_vmstate_register_dummy_icp()
* this vmstate_register()
* pre_2_10_vmstate_unregister_dummy_icp()
*
* So for a short amount of time we had to vmstate entries with
* the same name. This fixes it.
*/
vmstate_replace_hack_for_ppc(NULL, icp->cs->cpu_index,
&vmstate_icp_server, icp);
}

static void icp_unrealize(DeviceState *dev)
Expand Down
29 changes: 15 additions & 14 deletions hw/ipmi/ipmi_bmc_extern.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,19 +453,6 @@ static void ipmi_bmc_extern_handle_reset(IPMIBmc *b)
continue_send(ibe);
}

static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
{
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);

if (!qemu_chr_fe_backend_connected(&ibe->chr)) {
error_setg(errp, "IPMI external bmc requires chardev attribute");
return;
}

qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
chr_event, NULL, ibe, NULL, true);
}

static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id)
{
IPMIBmcExtern *ibe = opaque;
Expand Down Expand Up @@ -499,12 +486,26 @@ static const VMStateDescription vmstate_ipmi_bmc_extern = {
}
};

static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
{
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);

if (!qemu_chr_fe_backend_connected(&ibe->chr)) {
error_setg(errp, "IPMI external bmc requires chardev attribute");
return;
}

qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
chr_event, NULL, ibe, NULL, true);

vmstate_register(NULL, 0, &vmstate_ipmi_bmc_extern, ibe);
}

static void ipmi_bmc_extern_init(Object *obj)
{
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);

ibe->extern_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, extern_timeout, ibe);
vmstate_register(NULL, 0, &vmstate_ipmi_bmc_extern, ibe);
}

static void ipmi_bmc_extern_finalize(Object *obj)
Expand Down
34 changes: 17 additions & 17 deletions hw/ipmi/isa_ipmi_bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ static void isa_ipmi_bt_lower_irq(IPMIBT *ib)
qemu_irq_lower(iib->irq);
}

static const VMStateDescription vmstate_ISAIPMIBTDevice = {
.name = TYPE_IPMI_INTERFACE_PREFIX "isa-bt",
.version_id = 2,
.minimum_version_id = 2,
/*
* Version 1 had messed up the array transfer, it's not even usable
* because it used VMSTATE_VBUFFER_UINT32, but it did not transfer
* the buffer length, so random things would happen.
*/
.fields = (VMStateField[]) {
VMSTATE_STRUCT(bt, ISAIPMIBTDevice, 1, vmstate_IPMIBT, IPMIBT),
VMSTATE_END_OF_LIST()
}
};

static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
{
Error *err = NULL;
Expand Down Expand Up @@ -102,30 +117,15 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length);

isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base);
}

static const VMStateDescription vmstate_ISAIPMIBTDevice = {
.name = TYPE_IPMI_INTERFACE_PREFIX "isa-bt",
.version_id = 2,
.minimum_version_id = 2,
/*
* Version 1 had messed up the array transfer, it's not even usable
* because it used VMSTATE_VBUFFER_UINT32, but it did not transfer
* the buffer length, so random things would happen.
*/
.fields = (VMStateField[]) {
VMSTATE_STRUCT(bt, ISAIPMIBTDevice, 1, vmstate_IPMIBT, IPMIBT),
VMSTATE_END_OF_LIST()
}
};
vmstate_register(NULL, 0, &vmstate_ISAIPMIBTDevice, dev);
}

static void isa_ipmi_bt_init(Object *obj)
{
ISAIPMIBTDevice *iib = ISA_IPMI_BT(obj);

ipmi_bmc_find_and_link(obj, (Object **) &iib->bt.bmc);

vmstate_register(NULL, 0, &vmstate_ISAIPMIBTDevice, iib);
}

static void *isa_ipmi_bt_get_backend_data(IPMIInterface *ii)
Expand Down
48 changes: 24 additions & 24 deletions hw/ipmi/isa_ipmi_kcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,24 @@ static void isa_ipmi_kcs_lower_irq(IPMIKCS *ik)
qemu_irq_lower(iik->irq);
}

static bool vmstate_kcs_before_version2(void *opaque, int version)
{
return version <= 1;
}

static const VMStateDescription vmstate_ISAIPMIKCSDevice = {
.name = TYPE_IPMI_INTERFACE,
.version_id = 2,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_VSTRUCT_TEST(kcs, ISAIPMIKCSDevice, vmstate_kcs_before_version2,
0, vmstate_IPMIKCS, IPMIKCS, 1),
VMSTATE_VSTRUCT_V(kcs, ISAIPMIKCSDevice, 2, vmstate_IPMIKCS,
IPMIKCS, 2),
VMSTATE_END_OF_LIST()
}
};

static void ipmi_isa_realize(DeviceState *dev, Error **errp)
{
Error *err = NULL;
Expand Down Expand Up @@ -101,38 +119,20 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length);

isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base);
}

static bool vmstate_kcs_before_version2(void *opaque, int version)
{
return version <= 1;
/*
* Version 1 had an incorrect name, it clashed with the BT
* IPMI device, so receive it, but transmit a different
* version.
*/
vmstate_register(NULL, 0, &vmstate_ISAIPMIKCSDevice, iik);
}

static const VMStateDescription vmstate_ISAIPMIKCSDevice = {
.name = TYPE_IPMI_INTERFACE,
.version_id = 2,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_VSTRUCT_TEST(kcs, ISAIPMIKCSDevice, vmstate_kcs_before_version2,
0, vmstate_IPMIKCS, IPMIKCS, 1),
VMSTATE_VSTRUCT_V(kcs, ISAIPMIKCSDevice, 2, vmstate_IPMIKCS,
IPMIKCS, 2),
VMSTATE_END_OF_LIST()
}
};

static void isa_ipmi_kcs_init(Object *obj)
{
ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(obj);

ipmi_bmc_find_and_link(obj, (Object **) &iik->kcs.bmc);

/*
* Version 1 had an incorrect name, it clashed with the BT
* IPMI device, so receive it, but transmit a different
* version.
*/
vmstate_register(NULL, 0, &vmstate_ISAIPMIKCSDevice, iik);
}

static void *isa_ipmi_kcs_get_backend_data(IPMIInterface *ii)
Expand Down
3 changes: 1 addition & 2 deletions hw/net/eepro100.c
Original file line number Diff line number Diff line change
Expand Up @@ -1883,8 +1883,7 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)

s->vmstate = g_memdup(&vmstate_eepro100, sizeof(vmstate_eepro100));
s->vmstate->name = qemu_get_queue(s->nic)->model;
vmstate_register(VMSTATE_IF(&pci_dev->qdev), VMSTATE_INSTANCE_ID_ANY,
s->vmstate, s);
vmstate_register_any(VMSTATE_IF(&pci_dev->qdev), s->vmstate, s);
}

static void eepro100_instance_init(Object *obj)
Expand Down

0 comments on commit 75b7b25

Please sign in to comment.