mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-28 05:50:37 +00:00
migration/next for 20170628
-----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJZU5AcAAoJEPSH7xhYctcj83kP/16EKfpH5yg1umObjTFSckH5 WV6daBIDGtQrHDCkE17I1ikz1XozaYuZs67tEFKbvPLSqk9c6cUB9YpJbgeFrXnY pbPPKkGCyV7Hm3eIgKYjjoI4Aj7vwNVHohlCOOztbR5ZFw8/W4SE+nzgMbmOAQl6 NzzXGGQQeGbiMrI2i+Xn81Tz0ZRV7tNSD0T+wmVZSbfyiHHBBHBSkhkoDijTUuxa c18C4j7btSWMWRX4lCDRhyfWcaov/jCjkZgYMUihtENwooB1MEBxo79gf0vO+Fp2 YN2mvJJs2uP0A9pbFfZlyWBa6Uj36VbmoMtTLu1PO4ZAUQHQgiVA5t7HtfP+4QLm y0RtcYSqIcB82MgdTh0f0PSxUM5rbmfTmhvwq98OCGBixE9FY6t6WVwe3UYAcyAm Mhu0V7FKuoskKzy+q3iKmff7dJAFoEwThMNvJIXf0FeClmp61I+QRJtMvcAFlvxi Tkloe/05NyySXWj85ASxUjDoJkKuyeG42sbYtFnRDNssYXFbivuUpMb5b1pD5fCh 82A+lMrQ8Ovf1fRdB1FHlIE0irxLJaPITrgZDhyS2uc0K3XGtywmTQjuYTm1ifHT mNGFzWAAN2QlgSpj2cDdRZuudiwMz/rz+0/sQ5jdNWV5ajUxn+XWvmRWVDUzx6ye Qh8iehTRmVJ006VnbckC =Geoi -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170628' into staging migration/next for 20170628 # gpg: Signature made Wed 28 Jun 2017 12:16:44 BST # gpg: using RSA key 0xF487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" # gpg: aka "Juan Quintela <quintela@trasno.org>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * remotes/juanquintela/tags/migration/20170628: exec: fix access to ram_list.dirty_memory when sync dirty bitmap migration: add "return-path" capability vmstate: error hint for failed equal checks migration: add comment for TYPE_MIGRATE migration: hmp: dump globals migration: merge enforce_config_section somewhat migration: move skip_section_footers migration: move skip_configuration out migration: move only_migratable to MigrationState migration: move global_state.optional out migration: let MigrationState be a qdev vl: clean up global property registration accel: introduce AccelClass.global_props machine: export register_compat_prop() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
4fe60423d7
@ -120,6 +120,12 @@ void configure_accelerator(MachineState *ms)
|
||||
}
|
||||
}
|
||||
|
||||
void accel_register_compat_props(AccelState *accel)
|
||||
{
|
||||
AccelClass *class = ACCEL_GET_CLASS(accel);
|
||||
register_compat_props_array(class->global_props);
|
||||
}
|
||||
|
||||
static void register_accel_types(void)
|
||||
{
|
||||
type_register_static(&accel_type);
|
||||
|
3
hmp.c
3
hmp.c
@ -43,6 +43,7 @@
|
||||
#include "exec/ramlist.h"
|
||||
#include "hw/intc/intc.h"
|
||||
#include "migration/snapshot.h"
|
||||
#include "migration/misc.h"
|
||||
|
||||
#ifdef CONFIG_SPICE
|
||||
#include <spice/enums.h>
|
||||
@ -164,6 +165,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
||||
info = qmp_query_migrate(NULL);
|
||||
caps = qmp_query_migrate_capabilities(NULL);
|
||||
|
||||
migration_global_dump(mon);
|
||||
|
||||
/* do not display parameters during setup */
|
||||
if (info->has_status && caps) {
|
||||
monitor_printf(mon, "capabilities: ");
|
||||
|
@ -1217,7 +1217,7 @@ static const VMStateDescription vmstate_fdc = {
|
||||
VMSTATE_UINT8(config, FDCtrl),
|
||||
VMSTATE_UINT8(lock, FDCtrl),
|
||||
VMSTATE_UINT8(pwrd, FDCtrl),
|
||||
VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl),
|
||||
VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl, NULL),
|
||||
VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1,
|
||||
vmstate_fdrive, FDrive),
|
||||
VMSTATE_END_OF_LIST()
|
||||
|
@ -770,19 +770,6 @@ static void machine_class_finalize(ObjectClass *klass, void *data)
|
||||
g_free(mc->name);
|
||||
}
|
||||
|
||||
static void register_compat_prop(const char *driver,
|
||||
const char *property,
|
||||
const char *value)
|
||||
{
|
||||
GlobalProperty *p = g_new0(GlobalProperty, 1);
|
||||
/* Machine compat_props must never cause errors: */
|
||||
p->errp = &error_abort;
|
||||
p->driver = driver;
|
||||
p->property = property;
|
||||
p->value = value;
|
||||
qdev_prop_register_global(p);
|
||||
}
|
||||
|
||||
static void machine_register_compat_for_subclass(ObjectClass *oc, void *opaque)
|
||||
{
|
||||
GlobalProperty *p = opaque;
|
||||
|
@ -1084,6 +1084,27 @@ void qdev_prop_register_global(GlobalProperty *prop)
|
||||
global_props = g_list_append(global_props, prop);
|
||||
}
|
||||
|
||||
void register_compat_prop(const char *driver,
|
||||
const char *property,
|
||||
const char *value)
|
||||
{
|
||||
GlobalProperty *p = g_new0(GlobalProperty, 1);
|
||||
|
||||
/* Any compat_props must never cause error */
|
||||
p->errp = &error_abort;
|
||||
p->driver = driver;
|
||||
p->property = property;
|
||||
p->value = value;
|
||||
qdev_prop_register_global(p);
|
||||
}
|
||||
|
||||
void register_compat_props_array(GlobalProperty *prop)
|
||||
{
|
||||
for (; prop && prop->driver; prop++) {
|
||||
register_compat_prop(prop->driver, prop->property, prop->value);
|
||||
}
|
||||
}
|
||||
|
||||
void qdev_prop_register_global_list(GlobalProperty *props)
|
||||
{
|
||||
int i;
|
||||
|
@ -2373,12 +2373,12 @@ static VMStateDescription qxl_vmstate = {
|
||||
VMSTATE_UINT32(last_release_offset, PCIQXLDevice),
|
||||
VMSTATE_UINT32(mode, PCIQXLDevice),
|
||||
VMSTATE_UINT32(ssd.unique, PCIQXLDevice),
|
||||
VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice),
|
||||
VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice, NULL),
|
||||
VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, 0,
|
||||
qxl_memslot, struct guest_slots),
|
||||
VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
|
||||
qxl_surface, QXLSurfaceCreate),
|
||||
VMSTATE_INT32_EQUAL(ssd.num_surfaces, PCIQXLDevice),
|
||||
VMSTATE_INT32_EQUAL(ssd.num_surfaces, PCIQXLDevice, NULL),
|
||||
VMSTATE_VARRAY_INT32(guest_surfaces.cmds, PCIQXLDevice,
|
||||
ssd.num_surfaces, 0,
|
||||
vmstate_info_uint64, uint64_t),
|
||||
|
@ -2099,7 +2099,7 @@ const VMStateDescription vmstate_vga_common = {
|
||||
VMSTATE_BUFFER(palette, VGACommonState),
|
||||
|
||||
VMSTATE_INT32(bank_offset, VGACommonState),
|
||||
VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
|
||||
VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState, NULL),
|
||||
VMSTATE_UINT16(vbe_index, VGACommonState),
|
||||
VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
|
||||
VMSTATE_UINT32(vbe_start_addr, VGACommonState),
|
||||
|
@ -962,7 +962,7 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts = {
|
||||
.version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32(enable, struct VirtIOGPU),
|
||||
VMSTATE_UINT32_EQUAL(conf.max_outputs, struct VirtIOGPU),
|
||||
VMSTATE_UINT32_EQUAL(conf.max_outputs, struct VirtIOGPU, NULL),
|
||||
VMSTATE_STRUCT_VARRAY_UINT32(scanout, struct VirtIOGPU,
|
||||
conf.max_outputs, 1,
|
||||
vmstate_virtio_gpu_scanout,
|
||||
|
@ -1192,7 +1192,7 @@ static const VMStateDescription vmstate_vmware_vga_internal = {
|
||||
.minimum_version_id = 0,
|
||||
.post_load = vmsvga_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(new_depth, struct vmsvga_state_s),
|
||||
VMSTATE_INT32_EQUAL(new_depth, struct vmsvga_state_s, NULL),
|
||||
VMSTATE_INT32(enable, struct vmsvga_state_s),
|
||||
VMSTATE_INT32(config, struct vmsvga_state_s),
|
||||
VMSTATE_INT32(cursor.id, struct vmsvga_state_s),
|
||||
|
@ -314,12 +314,9 @@ static void pc_init1(MachineState *machine,
|
||||
static void pc_compat_2_3(MachineState *machine)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(machine);
|
||||
savevm_skip_section_footers();
|
||||
if (kvm_enabled()) {
|
||||
pcms->smm = ON_OFF_AUTO_OFF;
|
||||
}
|
||||
global_state_set_optional();
|
||||
savevm_skip_configuration();
|
||||
}
|
||||
|
||||
static void pc_compat_2_2(MachineState *machine)
|
||||
|
@ -1669,7 +1669,7 @@ const VMStateDescription vmstate_ahci = {
|
||||
VMSTATE_UINT32(control_regs.impl, AHCIState),
|
||||
VMSTATE_UINT32(control_regs.version, AHCIState),
|
||||
VMSTATE_UINT32(idp_index, AHCIState),
|
||||
VMSTATE_INT32_EQUAL(ports, AHCIState),
|
||||
VMSTATE_INT32_EQUAL(ports, AHCIState, NULL),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
@ -243,7 +243,7 @@ static const VMStateDescription vmstate_vmmouse = {
|
||||
.minimum_version_id = 0,
|
||||
.post_load = vmmouse_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(queue_size, VMMouseState),
|
||||
VMSTATE_INT32_EQUAL(queue_size, VMMouseState, NULL),
|
||||
VMSTATE_UINT32_ARRAY(queue, VMMouseState, VMMOUSE_QUEUE_SIZE),
|
||||
VMSTATE_UINT16(nb_queue, VMMouseState),
|
||||
VMSTATE_UINT16(status, VMMouseState),
|
||||
|
@ -1499,7 +1499,7 @@ static const VMStateDescription vmstate_openpic = {
|
||||
VMSTATE_UINT32(max_irq, OpenPICState),
|
||||
VMSTATE_STRUCT_VARRAY_UINT32(src, OpenPICState, max_irq, 0,
|
||||
vmstate_openpic_irqsource, IRQSource),
|
||||
VMSTATE_UINT32_EQUAL(nb_cpus, OpenPICState),
|
||||
VMSTATE_UINT32_EQUAL(nb_cpus, OpenPICState, NULL),
|
||||
VMSTATE_STRUCT_VARRAY_UINT32(dst, OpenPICState, nb_cpus, 0,
|
||||
vmstate_openpic_irqdest, IRQDest),
|
||||
VMSTATE_STRUCT_ARRAY(timers, OpenPICState, OPENPIC_MAX_TMR, 0,
|
||||
|
@ -574,7 +574,7 @@ static const VMStateDescription vmstate_ics_simple = {
|
||||
.post_load = ics_simple_dispatch_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
/* Sanity check */
|
||||
VMSTATE_UINT32_EQUAL(nr_irqs, ICSState),
|
||||
VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL),
|
||||
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
|
||||
vmstate_ics_simple_irq,
|
||||
|
@ -116,7 +116,7 @@ static const VMStateDescription vmstate_max111x = {
|
||||
VMSTATE_UINT8(tb1, MAX111xState),
|
||||
VMSTATE_UINT8(rb2, MAX111xState),
|
||||
VMSTATE_UINT8(rb3, MAX111xState),
|
||||
VMSTATE_INT32_EQUAL(inputs, MAX111xState),
|
||||
VMSTATE_INT32_EQUAL(inputs, MAX111xState, NULL),
|
||||
VMSTATE_INT32(com, MAX111xState),
|
||||
VMSTATE_ARRAY_INT32_UNSAFE(input, MAX111xState, inputs,
|
||||
vmstate_info_uint8, uint8_t),
|
||||
|
@ -143,7 +143,7 @@ static const VMStateDescription vmstate_eeprom = {
|
||||
VMSTATE_UINT8(addrbits, eeprom_t),
|
||||
VMSTATE_UINT16_HACK_TEST(size, eeprom_t, is_old_eeprom_version),
|
||||
VMSTATE_UNUSED_TEST(is_old_eeprom_version, 1),
|
||||
VMSTATE_UINT16_EQUAL_V(size, eeprom_t, EEPROM_VERSION),
|
||||
VMSTATE_UINT16_EQUAL_V(size, eeprom_t, EEPROM_VERSION, NULL),
|
||||
VMSTATE_UINT16(data, eeprom_t),
|
||||
VMSTATE_VARRAY_UINT16_UNSAFE(contents, eeprom_t, size, 0,
|
||||
vmstate_info_uint16, uint16_t),
|
||||
|
@ -74,7 +74,7 @@ static const VMStateDescription vmstate_pcibus = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(nirq, PCIBus),
|
||||
VMSTATE_INT32_EQUAL(nirq, PCIBus, NULL),
|
||||
VMSTATE_VARRAY_INT32(irq_count, PCIBus,
|
||||
nirq, 0, vmstate_info_int32,
|
||||
int32_t),
|
||||
|
@ -813,7 +813,7 @@ const VMStateDescription vmstate_pcie_aer_log = {
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT16(log_num, PCIEAERLog),
|
||||
VMSTATE_UINT16_EQUAL(log_max, PCIEAERLog),
|
||||
VMSTATE_UINT16_EQUAL(log_max, PCIEAERLog, NULL),
|
||||
VMSTATE_VALIDATE("log_num <= log_max", pcie_aer_state_log_num_valid),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT16(log, PCIEAERLog, log_num,
|
||||
vmstate_pcie_aer_err, PCIEAERErr),
|
||||
|
@ -3580,9 +3580,6 @@ DEFINE_SPAPR_MACHINE(2_4, "2.4", false);
|
||||
static void spapr_machine_2_3_instance_options(MachineState *machine)
|
||||
{
|
||||
spapr_machine_2_4_instance_options(machine);
|
||||
savevm_skip_section_footers();
|
||||
global_state_set_optional();
|
||||
savevm_skip_configuration();
|
||||
}
|
||||
|
||||
static void spapr_machine_2_3_class_options(MachineClass *mc)
|
||||
|
@ -231,7 +231,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
|
||||
.post_load = spapr_tce_table_post_load,
|
||||
.fields = (VMStateField []) {
|
||||
/* Sanity check */
|
||||
VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable),
|
||||
VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable, NULL),
|
||||
|
||||
/* IOMMU state */
|
||||
VMSTATE_UINT32(mig_nb_table, sPAPRTCETable),
|
||||
|
@ -1848,7 +1848,7 @@ static const VMStateDescription vmstate_spapr_pci_lsi = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_EQUAL(irq, struct spapr_pci_lsi),
|
||||
VMSTATE_UINT32_EQUAL(irq, struct spapr_pci_lsi, NULL),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
@ -1936,7 +1936,7 @@ static const VMStateDescription vmstate_spapr_pci = {
|
||||
.pre_save = spapr_pci_pre_save,
|
||||
.post_load = spapr_pci_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState),
|
||||
VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState, NULL),
|
||||
VMSTATE_UINT32_TEST(mig_liobn, sPAPRPHBState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_mem_win_addr, sPAPRPHBState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_mem_win_size, sPAPRPHBState, pre_2_8_migration),
|
||||
|
@ -557,8 +557,8 @@ const VMStateDescription vmstate_spapr_vio = {
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
/* Sanity check */
|
||||
VMSTATE_UINT32_EQUAL(reg, VIOsPAPRDevice),
|
||||
VMSTATE_UINT32_EQUAL(irq, VIOsPAPRDevice),
|
||||
VMSTATE_UINT32_EQUAL(reg, VIOsPAPRDevice, NULL),
|
||||
VMSTATE_UINT32_EQUAL(irq, VIOsPAPRDevice, NULL),
|
||||
|
||||
/* General VIO device state */
|
||||
VMSTATE_UINT64(signal_state, VIOsPAPRDevice),
|
||||
|
@ -415,7 +415,7 @@ static const VMStateDescription vmstate_uhci = {
|
||||
.post_load = uhci_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(dev, UHCIState),
|
||||
VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState),
|
||||
VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState, NULL),
|
||||
VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1,
|
||||
vmstate_uhci_port, UHCIPort),
|
||||
VMSTATE_UINT16(cmd, UHCIState),
|
||||
|
@ -138,20 +138,35 @@ static int xen_init(MachineState *ms)
|
||||
return -1;
|
||||
}
|
||||
qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
|
||||
|
||||
global_state_set_optional();
|
||||
savevm_skip_configuration();
|
||||
savevm_skip_section_footers();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static GlobalProperty xen_compat_props[] = {
|
||||
{
|
||||
.driver = "migration",
|
||||
.property = "store-global-state",
|
||||
.value = "off",
|
||||
},
|
||||
{
|
||||
.driver = "migration",
|
||||
.property = "send-configuration",
|
||||
.value = "off",
|
||||
},
|
||||
{
|
||||
.driver = "migration",
|
||||
.property = "send-section-footer",
|
||||
.value = "off",
|
||||
},
|
||||
{ /* end of list */ },
|
||||
};
|
||||
|
||||
static void xen_accel_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
AccelClass *ac = ACCEL_CLASS(oc);
|
||||
ac->name = "Xen";
|
||||
ac->init_machine = xen_init;
|
||||
ac->allowed = &xen_allowed;
|
||||
ac->global_props = xen_compat_props;
|
||||
}
|
||||
|
||||
#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
|
||||
|
@ -386,8 +386,9 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
|
||||
int k;
|
||||
int nr = BITS_TO_LONGS(length >> TARGET_PAGE_BITS);
|
||||
unsigned long * const *src;
|
||||
unsigned long idx = (page * BITS_PER_LONG) / DIRTY_MEMORY_BLOCK_SIZE;
|
||||
unsigned long offset = BIT_WORD((page * BITS_PER_LONG) %
|
||||
unsigned long word = BIT_WORD((start + rb->offset) >> TARGET_PAGE_BITS);
|
||||
unsigned long idx = (word * BITS_PER_LONG) / DIRTY_MEMORY_BLOCK_SIZE;
|
||||
unsigned long offset = BIT_WORD((word * BITS_PER_LONG) %
|
||||
DIRTY_MEMORY_BLOCK_SIZE);
|
||||
|
||||
rcu_read_lock();
|
||||
@ -414,9 +415,11 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
|
||||
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
ram_addr_t offset = rb->offset;
|
||||
|
||||
for (addr = 0; addr < length; addr += TARGET_PAGE_SIZE) {
|
||||
if (cpu_physical_memory_test_and_clear_dirty(
|
||||
start + addr,
|
||||
start + addr + offset,
|
||||
TARGET_PAGE_SIZE,
|
||||
DIRTY_MEMORY_MIGRATION)) {
|
||||
*real_dirty_pages += 1;
|
||||
|
@ -181,6 +181,18 @@
|
||||
.driver = TYPE_PCI_DEVICE,\
|
||||
.property = "x-pcie-lnksta-dllla",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "migration",\
|
||||
.property = "send-configuration",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "migration",\
|
||||
.property = "send-section-footer",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "migration",\
|
||||
.property = "store-global-state",\
|
||||
.value = "off",\
|
||||
},
|
||||
|
||||
#define HW_COMPAT_2_2 \
|
||||
|
@ -209,6 +209,35 @@ void qdev_prop_set_globals(DeviceState *dev);
|
||||
void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
|
||||
Property *prop, const char *value);
|
||||
|
||||
/**
|
||||
* register_compat_prop:
|
||||
*
|
||||
* Register internal (not user-provided) global property, changing the
|
||||
* default value of a given property in a device type. This can be used
|
||||
* for enabling machine-type compatibility or for enabling
|
||||
* accelerator-specific defaults in devices.
|
||||
*
|
||||
* The property values set using this function must be always valid and
|
||||
* never report setter errors, as the property will have
|
||||
* GlobalProperty::errp set to &error_abort.
|
||||
*
|
||||
* User-provided global properties should override internal global
|
||||
* properties, so callers of this function should ensure that it is
|
||||
* called before user-provided global properties are registered.
|
||||
*
|
||||
* @driver: Device type to be affected
|
||||
* @property: Property whose default value is going to be changed
|
||||
* @value: New default value for the property
|
||||
*/
|
||||
void register_compat_prop(const char *driver, const char *property,
|
||||
const char *value);
|
||||
/*
|
||||
* register_compat_props_array(): using register_compat_prop(), which
|
||||
* only registers internal global properties (which has lower priority
|
||||
* than user-provided global properties)
|
||||
*/
|
||||
void register_compat_props_array(GlobalProperty *prop);
|
||||
|
||||
/**
|
||||
* qdev_property_add_static:
|
||||
* @dev: Device to add the property to.
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
void register_global_state(void);
|
||||
void global_state_set_optional(void);
|
||||
int global_state_store(void);
|
||||
void global_state_store_running(void);
|
||||
bool global_state_received(void);
|
||||
|
@ -41,10 +41,9 @@ int64_t self_announce_delay(int round)
|
||||
/* migration/savevm.c */
|
||||
|
||||
void dump_vmstate_json_to_file(FILE *out_fp);
|
||||
void savevm_skip_section_footers(void);
|
||||
void savevm_skip_configuration(void);
|
||||
|
||||
/* migration/migration.c */
|
||||
void migration_object_init(void);
|
||||
void qemu_start_incoming_migration(const char *uri, Error **errp);
|
||||
bool migration_is_idle(void);
|
||||
void add_migration_state_change_notifier(Notifier *notify);
|
||||
@ -54,4 +53,7 @@ bool migration_has_finished(MigrationState *);
|
||||
bool migration_has_failed(MigrationState *);
|
||||
/* ...and after the device transmission */
|
||||
bool migration_in_postcopy_after_devices(MigrationState *);
|
||||
void migration_only_migratable_set(void);
|
||||
void migration_global_dump(Monitor *mon);
|
||||
|
||||
#endif
|
||||
|
@ -155,6 +155,7 @@ typedef enum {
|
||||
|
||||
struct VMStateField {
|
||||
const char *name;
|
||||
const char *err_hint;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
size_t start;
|
||||
@ -256,6 +257,18 @@ extern const VMStateInfo vmstate_info_qtailq;
|
||||
.offset = vmstate_offset_value(_state, _field, _type), \
|
||||
}
|
||||
|
||||
#define VMSTATE_SINGLE_FULL(_field, _state, _test, _version, _info, \
|
||||
_type, _err_hint) { \
|
||||
.name = (stringify(_field)), \
|
||||
.err_hint = (_err_hint), \
|
||||
.version_id = (_version), \
|
||||
.field_exists = (_test), \
|
||||
.size = sizeof(_type), \
|
||||
.info = &(_info), \
|
||||
.flags = VMS_SINGLE, \
|
||||
.offset = vmstate_offset_value(_state, _field, _type), \
|
||||
}
|
||||
|
||||
/* Validate state using a boolean predicate. */
|
||||
#define VMSTATE_VALIDATE(_name, _test) { \
|
||||
.name = (_name), \
|
||||
@ -762,29 +775,35 @@ extern const VMStateInfo vmstate_info_qtailq;
|
||||
#define VMSTATE_UINT64(_f, _s) \
|
||||
VMSTATE_UINT64_V(_f, _s, 0)
|
||||
|
||||
#define VMSTATE_UINT8_EQUAL(_f, _s) \
|
||||
VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint8_equal, uint8_t)
|
||||
#define VMSTATE_UINT8_EQUAL(_f, _s, _err_hint) \
|
||||
VMSTATE_SINGLE_FULL(_f, _s, 0, 0, \
|
||||
vmstate_info_uint8_equal, uint8_t, _err_hint)
|
||||
|
||||
#define VMSTATE_UINT16_EQUAL(_f, _s) \
|
||||
VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint16_equal, uint16_t)
|
||||
#define VMSTATE_UINT16_EQUAL(_f, _s, _err_hint) \
|
||||
VMSTATE_SINGLE_FULL(_f, _s, 0, 0, \
|
||||
vmstate_info_uint16_equal, uint16_t, _err_hint)
|
||||
|
||||
#define VMSTATE_UINT16_EQUAL_V(_f, _s, _v) \
|
||||
VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16_equal, uint16_t)
|
||||
#define VMSTATE_UINT16_EQUAL_V(_f, _s, _v, _err_hint) \
|
||||
VMSTATE_SINGLE_FULL(_f, _s, 0, _v, \
|
||||
vmstate_info_uint16_equal, uint16_t, _err_hint)
|
||||
|
||||
#define VMSTATE_INT32_EQUAL(_f, _s) \
|
||||
VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_equal, int32_t)
|
||||
#define VMSTATE_INT32_EQUAL(_f, _s, _err_hint) \
|
||||
VMSTATE_SINGLE_FULL(_f, _s, 0, 0, \
|
||||
vmstate_info_int32_equal, int32_t, _err_hint)
|
||||
|
||||
#define VMSTATE_UINT32_EQUAL_V(_f, _s, _v) \
|
||||
VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32_equal, uint32_t)
|
||||
#define VMSTATE_UINT32_EQUAL_V(_f, _s, _v, _err_hint) \
|
||||
VMSTATE_SINGLE_FULL(_f, _s, 0, _v, \
|
||||
vmstate_info_uint32_equal, uint32_t, _err_hint)
|
||||
|
||||
#define VMSTATE_UINT32_EQUAL(_f, _s) \
|
||||
VMSTATE_UINT32_EQUAL_V(_f, _s, 0)
|
||||
#define VMSTATE_UINT32_EQUAL(_f, _s, _err_hint) \
|
||||
VMSTATE_UINT32_EQUAL_V(_f, _s, 0, _err_hint)
|
||||
|
||||
#define VMSTATE_UINT64_EQUAL_V(_f, _s, _v) \
|
||||
VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64_equal, uint64_t)
|
||||
#define VMSTATE_UINT64_EQUAL_V(_f, _s, _v, _err_hint) \
|
||||
VMSTATE_SINGLE_FULL(_f, _s, 0, _v, \
|
||||
vmstate_info_uint64_equal, uint64_t, _err_hint)
|
||||
|
||||
#define VMSTATE_UINT64_EQUAL(_f, _s) \
|
||||
VMSTATE_UINT64_EQUAL_V(_f, _s, 0)
|
||||
#define VMSTATE_UINT64_EQUAL(_f, _s, _err_hint) \
|
||||
VMSTATE_UINT64_EQUAL_V(_f, _s, 0, _err_hint)
|
||||
|
||||
#define VMSTATE_INT32_POSITIVE_LE(_f, _s) \
|
||||
VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define HW_ACCEL_H
|
||||
|
||||
#include "qom/object.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
|
||||
typedef struct AccelState {
|
||||
/*< private >*/
|
||||
@ -40,6 +41,14 @@ typedef struct AccelClass {
|
||||
int (*available)(void);
|
||||
int (*init_machine)(MachineState *ms);
|
||||
bool *allowed;
|
||||
/*
|
||||
* Array of global properties that would be applied when specific
|
||||
* accelerator is chosen. It works like MachineClass.compat_props
|
||||
* but it's for accelerators not machines. Accelerator-provided
|
||||
* global properties may be overridden by machine-type
|
||||
* compat_props or user-provided global properties.
|
||||
*/
|
||||
GlobalProperty *global_props;
|
||||
} AccelClass;
|
||||
|
||||
#define TYPE_ACCEL "accel"
|
||||
@ -57,5 +66,7 @@ typedef struct AccelClass {
|
||||
extern int tcg_tb_size;
|
||||
|
||||
void configure_accelerator(MachineState *ms);
|
||||
/* Register accelerator specific global properties */
|
||||
void accel_register_compat_props(AccelState *accel);
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,6 @@
|
||||
/* vl.c */
|
||||
|
||||
extern const char *bios_name;
|
||||
extern int only_migratable;
|
||||
extern const char *qemu_name;
|
||||
extern QemuUUID qemu_uuid;
|
||||
extern bool qemu_uuid_set;
|
||||
|
@ -15,12 +15,12 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/util.h"
|
||||
#include "migration.h"
|
||||
#include "migration/global_state.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "trace.h"
|
||||
|
||||
typedef struct {
|
||||
bool optional;
|
||||
uint32_t size;
|
||||
uint8_t runstate[100];
|
||||
RunState state;
|
||||
@ -57,11 +57,6 @@ RunState global_state_get_runstate(void)
|
||||
return global_state.state;
|
||||
}
|
||||
|
||||
void global_state_set_optional(void)
|
||||
{
|
||||
global_state.optional = true;
|
||||
}
|
||||
|
||||
static bool global_state_needed(void *opaque)
|
||||
{
|
||||
GlobalState *s = opaque;
|
||||
@ -69,7 +64,7 @@ static bool global_state_needed(void *opaque)
|
||||
|
||||
/* If it is not optional, it is mandatory */
|
||||
|
||||
if (s->optional == false) {
|
||||
if (migrate_get_current()->store_global_state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "exec/target_page.h"
|
||||
#include "io/channel-buffer.h"
|
||||
#include "migration/colo.h"
|
||||
#include "hw/boards.h"
|
||||
#include "monitor/monitor.h"
|
||||
|
||||
#define MAX_THROTTLE (32 << 20) /* Migration transfer speed throttling */
|
||||
|
||||
@ -98,32 +100,37 @@ enum mig_rp_message_type {
|
||||
migrations at once. For now we don't need to add
|
||||
dynamic creation of migration */
|
||||
|
||||
static MigrationState *current_migration;
|
||||
|
||||
void migration_object_init(void)
|
||||
{
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
|
||||
/* This can only be called once. */
|
||||
assert(!current_migration);
|
||||
current_migration = MIGRATION_OBJ(object_new(TYPE_MIGRATION));
|
||||
|
||||
/*
|
||||
* We cannot really do this in migration_instance_init() since at
|
||||
* that time global properties are not yet applied, then this
|
||||
* value will be definitely replaced by something else.
|
||||
*/
|
||||
if (ms->enforce_config_section) {
|
||||
current_migration->send_configuration = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* For outgoing */
|
||||
MigrationState *migrate_get_current(void)
|
||||
{
|
||||
static bool once;
|
||||
static MigrationState current_migration = {
|
||||
.state = MIGRATION_STATUS_NONE,
|
||||
.xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
|
||||
.mbps = -1,
|
||||
.parameters = {
|
||||
.compress_level = DEFAULT_MIGRATE_COMPRESS_LEVEL,
|
||||
.compress_threads = DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT,
|
||||
.decompress_threads = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
|
||||
.cpu_throttle_initial = DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL,
|
||||
.cpu_throttle_increment = DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT,
|
||||
.max_bandwidth = MAX_THROTTLE,
|
||||
.downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME,
|
||||
.x_checkpoint_delay = DEFAULT_MIGRATE_X_CHECKPOINT_DELAY,
|
||||
},
|
||||
};
|
||||
/* This can only be called after the object created. */
|
||||
assert(current_migration);
|
||||
return current_migration;
|
||||
}
|
||||
|
||||
if (!once) {
|
||||
current_migration.parameters.tls_creds = g_strdup("");
|
||||
current_migration.parameters.tls_hostname = g_strdup("");
|
||||
once = true;
|
||||
}
|
||||
return ¤t_migration;
|
||||
void migration_only_migratable_set(void)
|
||||
{
|
||||
migrate_get_current()->only_migratable = true;
|
||||
}
|
||||
|
||||
MigrationIncomingState *migration_incoming_get_current(void)
|
||||
@ -997,7 +1004,7 @@ static GSList *migration_blockers;
|
||||
|
||||
int migrate_add_blocker(Error *reason, Error **errp)
|
||||
{
|
||||
if (only_migratable) {
|
||||
if (migrate_get_current()->only_migratable) {
|
||||
error_propagate(errp, error_copy(reason));
|
||||
error_prepend(errp, "disallowing migration blocker "
|
||||
"(--only_migratable) for: ");
|
||||
@ -1304,6 +1311,15 @@ bool migrate_use_block(void)
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_BLOCK];
|
||||
}
|
||||
|
||||
bool migrate_use_return_path(void)
|
||||
{
|
||||
MigrationState *s;
|
||||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
|
||||
}
|
||||
|
||||
bool migrate_use_block_incremental(void)
|
||||
{
|
||||
MigrationState *s;
|
||||
@ -1968,10 +1984,11 @@ void migrate_fd_connect(MigrationState *s)
|
||||
notifier_list_notify(&migration_state_notifiers, s);
|
||||
|
||||
/*
|
||||
* Open the return path; currently for postcopy but other things might
|
||||
* also want it.
|
||||
* Open the return path. For postcopy, it is used exclusively. For
|
||||
* precopy, only if user specified "return-path" capability would
|
||||
* QEMU uses the return path.
|
||||
*/
|
||||
if (migrate_postcopy_ram()) {
|
||||
if (migrate_postcopy_ram() || migrate_use_return_path()) {
|
||||
if (open_return_path_on_source(s)) {
|
||||
error_report("Unable to open return-path for postcopy");
|
||||
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
|
||||
@ -1987,3 +2004,76 @@ void migrate_fd_connect(MigrationState *s)
|
||||
s->migration_thread_running = true;
|
||||
}
|
||||
|
||||
void migration_global_dump(Monitor *mon)
|
||||
{
|
||||
MigrationState *ms = migrate_get_current();
|
||||
|
||||
monitor_printf(mon, "globals: store-global-state=%d, only_migratable=%d, "
|
||||
"send-configuration=%d, send-section-footer=%d\n",
|
||||
ms->store_global_state, ms->only_migratable,
|
||||
ms->send_configuration, ms->send_section_footer);
|
||||
}
|
||||
|
||||
static Property migration_properties[] = {
|
||||
DEFINE_PROP_BOOL("store-global-state", MigrationState,
|
||||
store_global_state, true),
|
||||
DEFINE_PROP_BOOL("only-migratable", MigrationState, only_migratable, false),
|
||||
DEFINE_PROP_BOOL("send-configuration", MigrationState,
|
||||
send_configuration, true),
|
||||
DEFINE_PROP_BOOL("send-section-footer", MigrationState,
|
||||
send_section_footer, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void migration_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->user_creatable = false;
|
||||
dc->props = migration_properties;
|
||||
}
|
||||
|
||||
static void migration_instance_init(Object *obj)
|
||||
{
|
||||
MigrationState *ms = MIGRATION_OBJ(obj);
|
||||
|
||||
ms->state = MIGRATION_STATUS_NONE;
|
||||
ms->xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE;
|
||||
ms->mbps = -1;
|
||||
ms->parameters = (MigrationParameters) {
|
||||
.compress_level = DEFAULT_MIGRATE_COMPRESS_LEVEL,
|
||||
.compress_threads = DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT,
|
||||
.decompress_threads = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
|
||||
.cpu_throttle_initial = DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL,
|
||||
.cpu_throttle_increment = DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT,
|
||||
.max_bandwidth = MAX_THROTTLE,
|
||||
.downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME,
|
||||
.x_checkpoint_delay = DEFAULT_MIGRATE_X_CHECKPOINT_DELAY,
|
||||
};
|
||||
ms->parameters.tls_creds = g_strdup("");
|
||||
ms->parameters.tls_hostname = g_strdup("");
|
||||
}
|
||||
|
||||
static const TypeInfo migration_type = {
|
||||
.name = TYPE_MIGRATION,
|
||||
/*
|
||||
* NOTE: "migration" itself is not really a device. We used
|
||||
* TYPE_DEVICE here only to leverage some existing QDev features
|
||||
* like "-global" properties, and HW_COMPAT_* fields (which are
|
||||
* finally applied as global properties as well). If one day the
|
||||
* global property feature can be migrated from QDev to QObject in
|
||||
* general, then we can switch to QObject as well.
|
||||
*/
|
||||
.parent = TYPE_DEVICE,
|
||||
.class_init = migration_class_init,
|
||||
.class_size = sizeof(MigrationClass),
|
||||
.instance_size = sizeof(MigrationState),
|
||||
.instance_init = migration_instance_init,
|
||||
};
|
||||
|
||||
static void register_migration_types(void)
|
||||
{
|
||||
type_register_static(&migration_type);
|
||||
}
|
||||
|
||||
type_init(register_migration_types);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qapi-types.h"
|
||||
#include "exec/cpu-common.h"
|
||||
#include "qemu/coroutine_int.h"
|
||||
#include "hw/qdev.h"
|
||||
|
||||
/* State for the incoming migration */
|
||||
struct MigrationIncomingState {
|
||||
@ -62,8 +63,26 @@ struct MigrationIncomingState {
|
||||
MigrationIncomingState *migration_incoming_get_current(void);
|
||||
void migration_incoming_state_destroy(void);
|
||||
|
||||
#define TYPE_MIGRATION "migration"
|
||||
|
||||
#define MIGRATION_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(MigrationClass, (klass), TYPE_MIGRATION)
|
||||
#define MIGRATION_OBJ(obj) \
|
||||
OBJECT_CHECK(MigrationState, (obj), TYPE_MIGRATION)
|
||||
#define MIGRATION_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(MigrationClass, (obj), TYPE_MIGRATION)
|
||||
|
||||
typedef struct MigrationClass {
|
||||
/*< private >*/
|
||||
DeviceClass parent_class;
|
||||
} MigrationClass;
|
||||
|
||||
struct MigrationState
|
||||
{
|
||||
/*< private >*/
|
||||
DeviceState parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
size_t bytes_xfer;
|
||||
size_t xfer_limit;
|
||||
QemuThread thread;
|
||||
@ -114,6 +133,20 @@ struct MigrationState
|
||||
/* Do we have to clean up -b/-i from old migrate parameters */
|
||||
/* This feature is deprecated and will be removed */
|
||||
bool must_remove_block_options;
|
||||
|
||||
/*
|
||||
* Global switch on whether we need to store the global state
|
||||
* during migration.
|
||||
*/
|
||||
bool store_global_state;
|
||||
|
||||
/* Whether the VM is only allowing for migratable devices */
|
||||
bool only_migratable;
|
||||
|
||||
/* Whether we send QEMU_VM_CONFIGURATION during migration */
|
||||
bool send_configuration;
|
||||
/* Whether we send section footer during migration */
|
||||
bool send_section_footer;
|
||||
};
|
||||
|
||||
void migrate_set_state(int *state, int old_state, int new_state);
|
||||
@ -144,6 +177,7 @@ bool migrate_colo_enabled(void);
|
||||
|
||||
bool migrate_use_block(void);
|
||||
bool migrate_use_block_incremental(void);
|
||||
bool migrate_use_return_path(void);
|
||||
|
||||
bool migrate_use_compression(void);
|
||||
int migrate_compress_level(void);
|
||||
|
@ -62,8 +62,6 @@
|
||||
|
||||
const unsigned int postcopy_ram_discard_version = 0;
|
||||
|
||||
static bool skip_section_footers;
|
||||
|
||||
/* Subcommands for QEMU_VM_COMMAND */
|
||||
enum qemu_vm_cmd {
|
||||
MIG_CMD_INVALID = 0, /* Must be 0 */
|
||||
@ -287,7 +285,6 @@ typedef struct SaveStateEntry {
|
||||
typedef struct SaveState {
|
||||
QTAILQ_HEAD(, SaveStateEntry) handlers;
|
||||
int global_section_id;
|
||||
bool skip_configuration;
|
||||
uint32_t len;
|
||||
const char *name;
|
||||
uint32_t target_page_bits;
|
||||
@ -296,15 +293,8 @@ typedef struct SaveState {
|
||||
static SaveState savevm_state = {
|
||||
.handlers = QTAILQ_HEAD_INITIALIZER(savevm_state.handlers),
|
||||
.global_section_id = 0,
|
||||
.skip_configuration = false,
|
||||
};
|
||||
|
||||
void savevm_skip_configuration(void)
|
||||
{
|
||||
savevm_state.skip_configuration = true;
|
||||
}
|
||||
|
||||
|
||||
static void configuration_pre_save(void *opaque)
|
||||
{
|
||||
SaveState *state = opaque;
|
||||
@ -769,11 +759,6 @@ static void vmstate_save(QEMUFile *f, SaveStateEntry *se, QJSON *vmdesc)
|
||||
vmstate_save_state(f, se->vmsd, se->opaque, vmdesc);
|
||||
}
|
||||
|
||||
void savevm_skip_section_footers(void)
|
||||
{
|
||||
skip_section_footers = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the header for device section (QEMU_VM_SECTION START/END/PART/FULL)
|
||||
*/
|
||||
@ -801,7 +786,7 @@ static void save_section_header(QEMUFile *f, SaveStateEntry *se,
|
||||
*/
|
||||
static void save_section_footer(QEMUFile *f, SaveStateEntry *se)
|
||||
{
|
||||
if (!skip_section_footers) {
|
||||
if (migrate_get_current()->send_section_footer) {
|
||||
qemu_put_byte(f, QEMU_VM_SECTION_FOOTER);
|
||||
qemu_put_be32(f, se->section_id);
|
||||
}
|
||||
@ -958,23 +943,16 @@ bool qemu_savevm_state_blocked(Error **errp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool enforce_config_section(void)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
return machine->enforce_config_section;
|
||||
}
|
||||
|
||||
void qemu_savevm_state_header(QEMUFile *f)
|
||||
{
|
||||
trace_savevm_state_header();
|
||||
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
|
||||
qemu_put_be32(f, QEMU_VM_FILE_VERSION);
|
||||
|
||||
if (!savevm_state.skip_configuration || enforce_config_section()) {
|
||||
if (migrate_get_current()->send_configuration) {
|
||||
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
|
||||
vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void qemu_savevm_state_begin(QEMUFile *f)
|
||||
@ -1810,7 +1788,7 @@ static bool check_section_footer(QEMUFile *f, SaveStateEntry *se)
|
||||
uint8_t read_mark;
|
||||
uint32_t read_section_id;
|
||||
|
||||
if (skip_section_footers) {
|
||||
if (!migrate_get_current()->send_section_footer) {
|
||||
/* No footer to check */
|
||||
return true;
|
||||
}
|
||||
@ -1995,7 +1973,7 @@ int qemu_loadvm_state(QEMUFile *f)
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!savevm_state.skip_configuration || enforce_config_section()) {
|
||||
if (migrate_get_current()->send_configuration) {
|
||||
if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) {
|
||||
error_report("Configuration section missing");
|
||||
return -EINVAL;
|
||||
@ -2336,7 +2314,7 @@ void vmstate_register_ram_global(MemoryRegion *mr)
|
||||
bool vmstate_check_only_migratable(const VMStateDescription *vmsd)
|
||||
{
|
||||
/* check needed if --only-migratable is specified */
|
||||
if (!only_migratable) {
|
||||
if (!migrate_get_current()->only_migratable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,9 @@ static int get_int32_equal(QEMUFile *f, void *pv, size_t size,
|
||||
return 0;
|
||||
}
|
||||
error_report("%" PRIx32 " != %" PRIx32, *v, v2);
|
||||
if (field->err_hint) {
|
||||
error_printf("%s\n", field->err_hint);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -267,6 +270,9 @@ static int get_uint32_equal(QEMUFile *f, void *pv, size_t size,
|
||||
return 0;
|
||||
}
|
||||
error_report("%" PRIx32 " != %" PRIx32, *v, v2);
|
||||
if (field->err_hint) {
|
||||
error_printf("%s\n", field->err_hint);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -341,6 +347,9 @@ static int get_uint64_equal(QEMUFile *f, void *pv, size_t size,
|
||||
return 0;
|
||||
}
|
||||
error_report("%" PRIx64 " != %" PRIx64, *v, v2);
|
||||
if (field->err_hint) {
|
||||
error_printf("%s\n", field->err_hint);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -364,6 +373,9 @@ static int get_uint8_equal(QEMUFile *f, void *pv, size_t size,
|
||||
return 0;
|
||||
}
|
||||
error_report("%x != %x", *v, v2);
|
||||
if (field->err_hint) {
|
||||
error_printf("%s\n", field->err_hint);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -387,6 +399,9 @@ static int get_uint16_equal(QEMUFile *f, void *pv, size_t size,
|
||||
return 0;
|
||||
}
|
||||
error_report("%x != %x", *v, v2);
|
||||
if (field->err_hint) {
|
||||
error_printf("%s\n", field->err_hint);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -900,12 +900,15 @@
|
||||
# offers more flexibility.
|
||||
# (Since 2.10)
|
||||
#
|
||||
# @return-path: If enabled, migration will use the return path even
|
||||
# for precopy. (since 2.10)
|
||||
#
|
||||
# Since: 1.2
|
||||
##
|
||||
{ 'enum': 'MigrationCapability',
|
||||
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
|
||||
'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
|
||||
'block' ] }
|
||||
'block', 'return-path' ] }
|
||||
|
||||
##
|
||||
# @MigrationCapabilityStatus:
|
||||
|
@ -419,7 +419,7 @@ static const VMStateDescription vmstate_slb = {
|
||||
.needed = slb_needed,
|
||||
.post_load = slb_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(env.slb_nr, PowerPCCPU),
|
||||
VMSTATE_INT32_EQUAL(env.slb_nr, PowerPCCPU, NULL),
|
||||
VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, MAX_SLB_ENTRIES),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
@ -452,7 +452,7 @@ static const VMStateDescription vmstate_tlb6xx = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = tlb6xx_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
|
||||
VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlb6, PowerPCCPU,
|
||||
env.nb_tlb,
|
||||
vmstate_tlb6xx_entry,
|
||||
@ -510,7 +510,7 @@ static const VMStateDescription vmstate_tlbemb = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = tlbemb_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
|
||||
VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbe, PowerPCCPU,
|
||||
env.nb_tlb,
|
||||
vmstate_tlbemb_entry,
|
||||
@ -551,7 +551,7 @@ static const VMStateDescription vmstate_tlbmas = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = tlbmas_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
|
||||
VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbm, PowerPCCPU,
|
||||
env.nb_tlb,
|
||||
vmstate_tlbmas_entry,
|
||||
|
41
vl.c
41
vl.c
@ -188,7 +188,6 @@ bool boot_strict;
|
||||
uint8_t *boot_splash_filedata;
|
||||
size_t boot_splash_filedata_size;
|
||||
uint8_t qemu_extra_params_fw[2];
|
||||
int only_migratable; /* turn it off unless user states otherwise */
|
||||
|
||||
int icount_align_option;
|
||||
|
||||
@ -2969,6 +2968,25 @@ static int qemu_read_default_config_file(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void user_register_global_props(void)
|
||||
{
|
||||
qemu_opts_foreach(qemu_find_opts("global"),
|
||||
global_init_func, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: we should see that these properties are actually having a
|
||||
* priority: accel < machine < user. This means e.g. when user
|
||||
* specifies something in "-global", it'll always be used with highest
|
||||
* priority than either machine/accelerator compat properties.
|
||||
*/
|
||||
static void register_global_properties(MachineState *ms)
|
||||
{
|
||||
accel_register_compat_props(ms->accelerator);
|
||||
machine_register_compat_props(ms);
|
||||
user_register_global_props();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
int i;
|
||||
@ -3934,7 +3952,13 @@ int main(int argc, char **argv, char **envp)
|
||||
incoming = optarg;
|
||||
break;
|
||||
case QEMU_OPTION_only_migratable:
|
||||
only_migratable = 1;
|
||||
/*
|
||||
* TODO: we can remove this option one day, and we
|
||||
* should all use:
|
||||
*
|
||||
* "-global migration.only-migratable=true"
|
||||
*/
|
||||
migration_only_migratable_set();
|
||||
break;
|
||||
case QEMU_OPTION_nodefaults:
|
||||
has_defaults = 0;
|
||||
@ -4571,10 +4595,17 @@ int main(int argc, char **argv, char **envp)
|
||||
exit (i == 1 ? 1 : 0);
|
||||
}
|
||||
|
||||
machine_register_compat_props(current_machine);
|
||||
/*
|
||||
* Register all the global properties, including accel properties,
|
||||
* machine properties, and user-specified ones.
|
||||
*/
|
||||
register_global_properties(current_machine);
|
||||
|
||||
qemu_opts_foreach(qemu_find_opts("global"),
|
||||
global_init_func, NULL, NULL);
|
||||
/*
|
||||
* Migration object can only be created after global properties
|
||||
* are applied correctly.
|
||||
*/
|
||||
migration_object_init();
|
||||
|
||||
/* This checkpoint is required by replay to separate prior clock
|
||||
reading from the other reads, because timer polling functions query
|
||||
|
Loading…
Reference in New Issue
Block a user