mirror of https://github.com/xemu-project/xemu.git
Migration Pull request (take 2)
Remove the two atomic patches that broke mips32. Please, apply. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmRGYTkACgkQ9IfvGFhy 1yMD5RAApL8bJTMpmkZ8afxG124/CID7fvg/WMp3vOTG/6923XZHfosUwqrCCvzN 8qfSfOl4P5Gtv1dOU+ZBcgoFS3tj00Ud2YhcZiSVUy5LZPJNJEfv4YzIErDTJq3I wcv/CgHvK1CKJ5DZ1g9hqnRvw9qYiodDEHS7UxvhGzckFExHps2oWt9nDuEZefKV XptOX7YDFYmWE87fp8+rQMYGZEN/6Cc7p4HmSt9I11CgLbeaqTpmKuwTv89PU9qV 7/X9kfoHNsKsVKw5WosEdRvEqhVQbvcCCxq+TGpeQz6d5U2mY7RVxQSNJxXNdD3P uz7uannx+UhESgzf5GnwOMIcxWD6UMAcDt349IAWFbq5d1QGaXJ9fVVHVJDV1Irl XHqxkugNMxRVZ8hQy5gSE6UTpeIjkIpSoZGnGS7E/iLMZHZBgv7s5VK21mYxn/QF F9g3Ewo2lF+kpQ/ZEnQ9mFyCYtqOHOAOLAUa7/6WdGnUMuqQ47Fh+jbb+KdEyCLg l7yXk2gXAb8SN6957Tlvo9okOB4NzhDPDXgvewAG/1yW4zL9hA+YCMvEvy90N8Be rRKO7H9YlsW4wKjA//i2YNAbtaZN5+zeAS39m0exYmXA54AMufjWq/a7Ya/ix5Jo 452LEz5hA4ckXXtP715pKQjqafxWXbHSS1qw9LBfMYr5TEEWC6c= =JTxg -----END PGP SIGNATURE----- Merge tag 'migration-20230420-pull-request' of https://gitlab.com/juan.quintela/qemu into staging Migration Pull request (take 2) Remove the two atomic patches that broke mips32. Please, apply. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmRGYTkACgkQ9IfvGFhy # 1yMD5RAApL8bJTMpmkZ8afxG124/CID7fvg/WMp3vOTG/6923XZHfosUwqrCCvzN # 8qfSfOl4P5Gtv1dOU+ZBcgoFS3tj00Ud2YhcZiSVUy5LZPJNJEfv4YzIErDTJq3I # wcv/CgHvK1CKJ5DZ1g9hqnRvw9qYiodDEHS7UxvhGzckFExHps2oWt9nDuEZefKV # XptOX7YDFYmWE87fp8+rQMYGZEN/6Cc7p4HmSt9I11CgLbeaqTpmKuwTv89PU9qV # 7/X9kfoHNsKsVKw5WosEdRvEqhVQbvcCCxq+TGpeQz6d5U2mY7RVxQSNJxXNdD3P # uz7uannx+UhESgzf5GnwOMIcxWD6UMAcDt349IAWFbq5d1QGaXJ9fVVHVJDV1Irl # XHqxkugNMxRVZ8hQy5gSE6UTpeIjkIpSoZGnGS7E/iLMZHZBgv7s5VK21mYxn/QF # F9g3Ewo2lF+kpQ/ZEnQ9mFyCYtqOHOAOLAUa7/6WdGnUMuqQ47Fh+jbb+KdEyCLg # l7yXk2gXAb8SN6957Tlvo9okOB4NzhDPDXgvewAG/1yW4zL9hA+YCMvEvy90N8Be # rRKO7H9YlsW4wKjA//i2YNAbtaZN5+zeAS39m0exYmXA54AMufjWq/a7Ya/ix5Jo # 452LEz5hA4ckXXtP715pKQjqafxWXbHSS1qw9LBfMYr5TEEWC6c= # =JTxg # -----END PGP SIGNATURE----- # gpg: Signature made Mon 24 Apr 2023 12:00:09 PM BST # gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [undefined] # gpg: aka "Juan Quintela <quintela@trasno.org>" [undefined] # 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 * tag 'migration-20230420-pull-request' of https://gitlab.com/juan.quintela/qemu: migration: Pass migrate_caps_check() the old and new caps migration: rename enabled_capabilities to capabilities migration/postcopy: Detect file system on dest host vl.c: Create late backends before migration object util/mmap-alloc: qemu_fd_getfs() migration: Handle block device inactivation failures better migration: Rename normal to normal_pages migration: Rename duplicate to zero_pages migration: Make postcopy_requests atomic migration: Make dirty_sync_count atomic migration: Make downtime_bytes atomic migration: Make precopy_bytes atomic migration: Make dirty_sync_missed_zero_copy atomic migration: Make multifd_bytes atomic migration: Update atomic stats out of the mutex migration: Merge ram_counters and ram_atomic_counters migration: remove extra whitespace character for code style Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
81072abf15
|
@ -1,8 +1,15 @@
|
|||
#ifndef QEMU_MMAP_ALLOC_H
|
||||
#define QEMU_MMAP_ALLOC_H
|
||||
|
||||
typedef enum {
|
||||
QEMU_FS_TYPE_UNKNOWN = 0,
|
||||
QEMU_FS_TYPE_TMPFS,
|
||||
QEMU_FS_TYPE_HUGETLBFS,
|
||||
QEMU_FS_TYPE_NUM,
|
||||
} QemuFsType;
|
||||
|
||||
size_t qemu_fd_getpagesize(int fd);
|
||||
QemuFsType qemu_fd_getfs(int fd);
|
||||
|
||||
/**
|
||||
* qemu_ram_mmap: mmap anonymous memory, the specified file or device.
|
||||
|
|
|
@ -364,8 +364,7 @@ static bool migrate_late_block_activate(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[
|
||||
MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -944,7 +943,7 @@ MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
|
|||
#endif
|
||||
caps = g_malloc0(sizeof(*caps));
|
||||
caps->capability = i;
|
||||
caps->state = s->enabled_capabilities[i];
|
||||
caps->state = s->capabilities[i];
|
||||
QAPI_LIST_APPEND(tail, caps);
|
||||
}
|
||||
|
||||
|
@ -1140,24 +1139,26 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
|
|||
size_t page_size = qemu_target_page_size();
|
||||
|
||||
info->ram = g_malloc0(sizeof(*info->ram));
|
||||
info->ram->transferred = stat64_get(&ram_atomic_counters.transferred);
|
||||
info->ram->transferred = stat64_get(&ram_counters.transferred);
|
||||
info->ram->total = ram_bytes_total();
|
||||
info->ram->duplicate = stat64_get(&ram_atomic_counters.duplicate);
|
||||
info->ram->duplicate = stat64_get(&ram_counters.zero_pages);
|
||||
/* legacy value. It is not used anymore */
|
||||
info->ram->skipped = 0;
|
||||
info->ram->normal = stat64_get(&ram_atomic_counters.normal);
|
||||
info->ram->normal = stat64_get(&ram_counters.normal_pages);
|
||||
info->ram->normal_bytes = info->ram->normal * page_size;
|
||||
info->ram->mbps = s->mbps;
|
||||
info->ram->dirty_sync_count = ram_counters.dirty_sync_count;
|
||||
info->ram->dirty_sync_count =
|
||||
stat64_get(&ram_counters.dirty_sync_count);
|
||||
info->ram->dirty_sync_missed_zero_copy =
|
||||
ram_counters.dirty_sync_missed_zero_copy;
|
||||
info->ram->postcopy_requests = ram_counters.postcopy_requests;
|
||||
stat64_get(&ram_counters.dirty_sync_missed_zero_copy);
|
||||
info->ram->postcopy_requests =
|
||||
stat64_get(&ram_counters.postcopy_requests);
|
||||
info->ram->page_size = page_size;
|
||||
info->ram->multifd_bytes = ram_counters.multifd_bytes;
|
||||
info->ram->multifd_bytes = stat64_get(&ram_counters.multifd_bytes);
|
||||
info->ram->pages_per_second = s->pages_per_second;
|
||||
info->ram->precopy_bytes = ram_counters.precopy_bytes;
|
||||
info->ram->downtime_bytes = ram_counters.downtime_bytes;
|
||||
info->ram->postcopy_bytes = stat64_get(&ram_atomic_counters.postcopy_bytes);
|
||||
info->ram->precopy_bytes = stat64_get(&ram_counters.precopy_bytes);
|
||||
info->ram->downtime_bytes = stat64_get(&ram_counters.downtime_bytes);
|
||||
info->ram->postcopy_bytes = stat64_get(&ram_counters.postcopy_bytes);
|
||||
|
||||
if (migrate_use_xbzrle()) {
|
||||
info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache));
|
||||
|
@ -1298,30 +1299,20 @@ WriteTrackingSupport migrate_query_write_tracking(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @migration_caps_check - check capability validity
|
||||
* @migration_caps_check - check capability compatibility
|
||||
*
|
||||
* @cap_list: old capability list, array of bool
|
||||
* @params: new capabilities to be applied soon
|
||||
* @old_caps: old capability list
|
||||
* @new_caps: new capability list
|
||||
* @errp: set *errp if the check failed, with reason
|
||||
*
|
||||
* Returns true if check passed, otherwise false.
|
||||
*/
|
||||
static bool migrate_caps_check(bool *cap_list,
|
||||
MigrationCapabilityStatusList *params,
|
||||
Error **errp)
|
||||
static bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
|
||||
{
|
||||
MigrationCapabilityStatusList *cap;
|
||||
bool old_postcopy_cap;
|
||||
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||
|
||||
old_postcopy_cap = cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM];
|
||||
|
||||
for (cap = params; cap; cap = cap->next) {
|
||||
cap_list[cap->value->capability] = cap->value->state;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LIVE_BLOCK_MIGRATION
|
||||
if (cap_list[MIGRATION_CAPABILITY_BLOCK]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_BLOCK]) {
|
||||
error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) "
|
||||
"block migration");
|
||||
error_append_hint(errp, "Use drive_mirror+NBD instead.\n");
|
||||
|
@ -1330,7 +1321,7 @@ static bool migrate_caps_check(bool *cap_list,
|
|||
#endif
|
||||
|
||||
#ifndef CONFIG_REPLICATION
|
||||
if (cap_list[MIGRATION_CAPABILITY_X_COLO]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
|
||||
error_setg(errp, "QEMU compiled without replication module"
|
||||
" can't enable COLO");
|
||||
error_append_hint(errp, "Please enable replication before COLO.\n");
|
||||
|
@ -1338,12 +1329,13 @@ static bool migrate_caps_check(bool *cap_list,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
|
||||
/* This check is reasonably expensive, so only when it's being
|
||||
* set the first time, also it's only the destination that needs
|
||||
* special support.
|
||||
*/
|
||||
if (!old_postcopy_cap && runstate_check(RUN_STATE_INMIGRATE) &&
|
||||
if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
|
||||
runstate_check(RUN_STATE_INMIGRATE) &&
|
||||
!postcopy_ram_supported_by_host(mis)) {
|
||||
/* postcopy_ram_supported_by_host will have emitted a more
|
||||
* detailed message
|
||||
|
@ -1352,13 +1344,13 @@ static bool migrate_caps_check(bool *cap_list,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (cap_list[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
|
||||
error_setg(errp, "Postcopy is not compatible with ignore-shared");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (cap_list[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
|
||||
WriteTrackingSupport wt_support;
|
||||
int idx;
|
||||
/*
|
||||
|
@ -1382,7 +1374,7 @@ static bool migrate_caps_check(bool *cap_list,
|
|||
*/
|
||||
for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
|
||||
int incomp_cap = check_caps_background_snapshot.caps[idx];
|
||||
if (cap_list[incomp_cap]) {
|
||||
if (new_caps[incomp_cap]) {
|
||||
error_setg(errp,
|
||||
"Background-snapshot is not compatible with %s",
|
||||
MigrationCapability_str(incomp_cap));
|
||||
|
@ -1392,10 +1384,10 @@ static bool migrate_caps_check(bool *cap_list,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
if (cap_list[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
|
||||
(!cap_list[MIGRATION_CAPABILITY_MULTIFD] ||
|
||||
cap_list[MIGRATION_CAPABILITY_COMPRESS] ||
|
||||
cap_list[MIGRATION_CAPABILITY_XBZRLE] ||
|
||||
if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
|
||||
(!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
|
||||
new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
|
||||
new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
|
||||
migrate_multifd_compression() ||
|
||||
migrate_use_tls())) {
|
||||
error_setg(errp,
|
||||
|
@ -1403,15 +1395,15 @@ static bool migrate_caps_check(bool *cap_list,
|
|||
return false;
|
||||
}
|
||||
#else
|
||||
if (cap_list[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
|
||||
error_setg(errp,
|
||||
"Zero copy currently only available on Linux");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cap_list[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
|
||||
if (!cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
|
||||
if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
|
||||
error_setg(errp, "Postcopy preempt requires postcopy-ram");
|
||||
return false;
|
||||
}
|
||||
|
@ -1422,14 +1414,14 @@ static bool migrate_caps_check(bool *cap_list,
|
|||
* different compression channels, which is not compatible with the
|
||||
* preempt assumptions on channel assignments.
|
||||
*/
|
||||
if (cap_list[MIGRATION_CAPABILITY_COMPRESS]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
|
||||
error_setg(errp, "Postcopy preempt not compatible with compress");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (cap_list[MIGRATION_CAPABILITY_MULTIFD]) {
|
||||
if (cap_list[MIGRATION_CAPABILITY_COMPRESS]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
|
||||
if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
|
||||
error_setg(errp, "Multifd is not compatible with compress");
|
||||
return false;
|
||||
}
|
||||
|
@ -1485,20 +1477,24 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
|
|||
{
|
||||
MigrationState *s = migrate_get_current();
|
||||
MigrationCapabilityStatusList *cap;
|
||||
bool cap_list[MIGRATION_CAPABILITY__MAX];
|
||||
bool new_caps[MIGRATION_CAPABILITY__MAX];
|
||||
|
||||
if (migration_is_running(s->state)) {
|
||||
error_setg(errp, QERR_MIGRATION_ACTIVE);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(cap_list, s->enabled_capabilities, sizeof(cap_list));
|
||||
if (!migrate_caps_check(cap_list, params, errp)) {
|
||||
memcpy(new_caps, s->capabilities, sizeof(new_caps));
|
||||
for (cap = params; cap; cap = cap->next) {
|
||||
new_caps[cap->value->capability] = cap->value->state;
|
||||
}
|
||||
|
||||
if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (cap = params; cap; cap = cap->next) {
|
||||
s->enabled_capabilities[cap->value->capability] = cap->value->state;
|
||||
s->capabilities[cap->value->capability] = cap->value->state;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2567,7 +2563,7 @@ bool migrate_release_ram(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
|
||||
}
|
||||
|
||||
bool migrate_postcopy_ram(void)
|
||||
|
@ -2576,7 +2572,7 @@ bool migrate_postcopy_ram(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
|
||||
}
|
||||
|
||||
bool migrate_postcopy(void)
|
||||
|
@ -2590,7 +2586,7 @@ bool migrate_auto_converge(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
|
||||
}
|
||||
|
||||
bool migrate_zero_blocks(void)
|
||||
|
@ -2599,7 +2595,7 @@ bool migrate_zero_blocks(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
|
||||
}
|
||||
|
||||
bool migrate_postcopy_blocktime(void)
|
||||
|
@ -2608,7 +2604,7 @@ bool migrate_postcopy_blocktime(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
|
||||
}
|
||||
|
||||
bool migrate_use_compression(void)
|
||||
|
@ -2617,7 +2613,7 @@ bool migrate_use_compression(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_COMPRESS];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
|
||||
}
|
||||
|
||||
int migrate_compress_level(void)
|
||||
|
@ -2662,7 +2658,7 @@ bool migrate_dirty_bitmaps(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
|
||||
}
|
||||
|
||||
bool migrate_ignore_shared(void)
|
||||
|
@ -2671,7 +2667,7 @@ bool migrate_ignore_shared(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
|
||||
}
|
||||
|
||||
bool migrate_validate_uuid(void)
|
||||
|
@ -2680,7 +2676,7 @@ bool migrate_validate_uuid(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
|
||||
}
|
||||
|
||||
bool migrate_use_events(void)
|
||||
|
@ -2689,7 +2685,7 @@ bool migrate_use_events(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_EVENTS];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
|
||||
}
|
||||
|
||||
bool migrate_use_multifd(void)
|
||||
|
@ -2698,7 +2694,7 @@ bool migrate_use_multifd(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_MULTIFD];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
|
||||
}
|
||||
|
||||
bool migrate_pause_before_switchover(void)
|
||||
|
@ -2707,8 +2703,7 @@ bool migrate_pause_before_switchover(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[
|
||||
MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
|
||||
}
|
||||
|
||||
int migrate_multifd_channels(void)
|
||||
|
@ -2755,7 +2750,7 @@ bool migrate_use_zero_copy_send(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2774,7 +2769,7 @@ int migrate_use_xbzrle(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
|
||||
}
|
||||
|
||||
uint64_t migrate_xbzrle_cache_size(void)
|
||||
|
@ -2801,7 +2796,7 @@ bool migrate_use_block(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_BLOCK];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_BLOCK];
|
||||
}
|
||||
|
||||
bool migrate_use_return_path(void)
|
||||
|
@ -2810,7 +2805,7 @@ bool migrate_use_return_path(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
|
||||
}
|
||||
|
||||
bool migrate_use_block_incremental(void)
|
||||
|
@ -2828,7 +2823,7 @@ bool migrate_background_snapshot(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
|
||||
}
|
||||
|
||||
bool migrate_postcopy_preempt(void)
|
||||
|
@ -2837,7 +2832,7 @@ bool migrate_postcopy_preempt(void)
|
|||
|
||||
s = migrate_get_current();
|
||||
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
|
||||
}
|
||||
|
||||
/* migration thread support */
|
||||
|
@ -3444,13 +3439,11 @@ static void migration_completion(MigrationState *s)
|
|||
MIGRATION_STATUS_DEVICE);
|
||||
}
|
||||
if (ret >= 0) {
|
||||
s->block_inactive = inactivate;
|
||||
qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
|
||||
ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
|
||||
inactivate);
|
||||
}
|
||||
if (inactivate && ret >= 0) {
|
||||
s->block_inactive = true;
|
||||
}
|
||||
}
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
||||
|
@ -3522,6 +3515,7 @@ fail_invalidate:
|
|||
bdrv_activate_all(&local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
s->block_inactive = true;
|
||||
} else {
|
||||
s->block_inactive = false;
|
||||
}
|
||||
|
@ -3580,7 +3574,7 @@ fail:
|
|||
bool migrate_colo_enabled(void)
|
||||
{
|
||||
MigrationState *s = migrate_get_current();
|
||||
return s->enabled_capabilities[MIGRATION_CAPABILITY_X_COLO];
|
||||
return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
|
||||
}
|
||||
|
||||
typedef enum MigThrError {
|
||||
|
@ -3778,7 +3772,7 @@ static MigThrError migration_detect_error(MigrationState *s)
|
|||
static uint64_t migration_total_bytes(MigrationState *s)
|
||||
{
|
||||
return qemu_file_total_transferred(s->to_dst_file) +
|
||||
ram_counters.multifd_bytes;
|
||||
stat64_get(&ram_counters.multifd_bytes);
|
||||
}
|
||||
|
||||
static void migration_calculate_complete(MigrationState *s)
|
||||
|
@ -4443,7 +4437,7 @@ void migration_global_dump(Monitor *mon)
|
|||
}
|
||||
|
||||
#define DEFINE_PROP_MIG_CAP(name, x) \
|
||||
DEFINE_PROP_BOOL(name, MigrationState, enabled_capabilities[x], false)
|
||||
DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false)
|
||||
|
||||
static Property migration_properties[] = {
|
||||
DEFINE_PROP_BOOL("store-global-state", MigrationState,
|
||||
|
@ -4632,27 +4626,14 @@ static void migration_instance_init(Object *obj)
|
|||
*/
|
||||
static bool migration_object_check(MigrationState *ms, Error **errp)
|
||||
{
|
||||
MigrationCapabilityStatusList *head = NULL;
|
||||
/* Assuming all off */
|
||||
bool cap_list[MIGRATION_CAPABILITY__MAX] = { 0 }, ret;
|
||||
int i;
|
||||
bool old_caps[MIGRATION_CAPABILITY__MAX] = { 0 };
|
||||
|
||||
if (!migrate_params_check(&ms->parameters, errp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
|
||||
if (ms->enabled_capabilities[i]) {
|
||||
QAPI_LIST_PREPEND(head, migrate_cap_add(i, true));
|
||||
}
|
||||
}
|
||||
|
||||
ret = migrate_caps_check(cap_list, head, errp);
|
||||
|
||||
/* It works with head == NULL */
|
||||
qapi_free_MigrationCapabilityStatusList(head);
|
||||
|
||||
return ret;
|
||||
return migrate_caps_check(old_caps, ms->capabilities, errp);
|
||||
}
|
||||
|
||||
static const TypeInfo migration_type = {
|
||||
|
|
|
@ -310,7 +310,7 @@ struct MigrationState {
|
|||
int64_t downtime_start;
|
||||
int64_t downtime;
|
||||
int64_t expected_downtime;
|
||||
bool enabled_capabilities[MIGRATION_CAPABILITY__MAX];
|
||||
bool capabilities[MIGRATION_CAPABILITY__MAX];
|
||||
int64_t setup_time;
|
||||
/*
|
||||
* Whether guest was running when we enter the completion stage.
|
||||
|
|
|
@ -432,9 +432,9 @@ static int multifd_send_pages(QEMUFile *f)
|
|||
p->pages = pages;
|
||||
transferred = ((uint64_t) pages->num) * p->page_size + p->packet_len;
|
||||
qemu_file_acct_rate_limit(f, transferred);
|
||||
ram_counters.multifd_bytes += transferred;
|
||||
stat64_add(&ram_atomic_counters.transferred, transferred);
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
stat64_add(&ram_counters.transferred, transferred);
|
||||
stat64_add(&ram_counters.multifd_bytes, transferred);
|
||||
qemu_sem_post(&p->sem);
|
||||
|
||||
return 1;
|
||||
|
@ -576,7 +576,7 @@ static int multifd_zero_copy_flush(QIOChannel *c)
|
|||
return -1;
|
||||
}
|
||||
if (ret == 1) {
|
||||
dirty_sync_missed_zero_copy();
|
||||
stat64_add(&ram_counters.dirty_sync_missed_zero_copy, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -627,9 +627,9 @@ int multifd_send_sync_main(QEMUFile *f)
|
|||
p->flags |= MULTIFD_FLAG_SYNC;
|
||||
p->pending_job++;
|
||||
qemu_file_acct_rate_limit(f, p->packet_len);
|
||||
ram_counters.multifd_bytes += p->packet_len;
|
||||
stat64_add(&ram_atomic_counters.transferred, p->packet_len);
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
stat64_add(&ram_counters.transferred, p->packet_len);
|
||||
stat64_add(&ram_counters.multifd_bytes, p->packet_len);
|
||||
qemu_sem_post(&p->sem);
|
||||
}
|
||||
for (i = 0; i < migrate_multifd_channels(); i++) {
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "yank_functions.h"
|
||||
#include "tls.h"
|
||||
#include "qemu/userfaultfd.h"
|
||||
#include "qemu/mmap-alloc.h"
|
||||
|
||||
/* Arbitrary limit on size of each discard command,
|
||||
* keeps them around ~200 bytes
|
||||
|
@ -336,11 +337,12 @@ static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis)
|
|||
|
||||
/* Callback from postcopy_ram_supported_by_host block iterator.
|
||||
*/
|
||||
static int test_ramblock_postcopiable(RAMBlock *rb, void *opaque)
|
||||
static int test_ramblock_postcopiable(RAMBlock *rb)
|
||||
{
|
||||
const char *block_name = qemu_ram_get_idstr(rb);
|
||||
ram_addr_t length = qemu_ram_get_used_length(rb);
|
||||
size_t pagesize = qemu_ram_pagesize(rb);
|
||||
QemuFsType fs;
|
||||
|
||||
if (length % pagesize) {
|
||||
error_report("Postcopy requires RAM blocks to be a page size multiple,"
|
||||
|
@ -348,6 +350,15 @@ static int test_ramblock_postcopiable(RAMBlock *rb, void *opaque)
|
|||
"page size of 0x%zx", block_name, length, pagesize);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rb->fd >= 0) {
|
||||
fs = qemu_fd_getfs(rb->fd);
|
||||
if (fs != QEMU_FS_TYPE_TMPFS && fs != QEMU_FS_TYPE_HUGETLBFS) {
|
||||
error_report("Host backend files need to be TMPFS or HUGETLBFS only");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -366,6 +377,7 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis)
|
|||
struct uffdio_range range_struct;
|
||||
uint64_t feature_mask;
|
||||
Error *local_err = NULL;
|
||||
RAMBlock *block;
|
||||
|
||||
if (qemu_target_page_size() > pagesize) {
|
||||
error_report("Target page size bigger than host page size");
|
||||
|
@ -390,9 +402,23 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* We don't support postcopy with shared RAM yet */
|
||||
if (foreach_not_ignored_block(test_ramblock_postcopiable, NULL)) {
|
||||
goto out;
|
||||
/*
|
||||
* We don't support postcopy with some type of ramblocks.
|
||||
*
|
||||
* NOTE: we explicitly ignored ramblock_is_ignored() instead we checked
|
||||
* all possible ramblocks. This is because this function can be called
|
||||
* when creating the migration object, during the phase RAM_MIGRATABLE
|
||||
* is not even properly set for all the ramblocks.
|
||||
*
|
||||
* A side effect of this is we'll also check against RAM_SHARED
|
||||
* ramblocks even if migrate_ignore_shared() is set (in which case
|
||||
* we'll never migrate RAM_SHARED at all), but normally this shouldn't
|
||||
* affect in reality, or we can revisit.
|
||||
*/
|
||||
RAMBLOCK_FOREACH(block) {
|
||||
if (test_ramblock_postcopiable(block)) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -458,30 +458,18 @@ uint64_t ram_bytes_remaining(void)
|
|||
0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: not all stats in ram_counters are used in reality. See comments
|
||||
* for struct MigrationAtomicStats. The ultimate result of ram migration
|
||||
* counters will be a merged version with both ram_counters and the atomic
|
||||
* fields in ram_atomic_counters.
|
||||
*/
|
||||
MigrationStats ram_counters;
|
||||
MigrationAtomicStats ram_atomic_counters;
|
||||
RAMStats ram_counters;
|
||||
|
||||
void ram_transferred_add(uint64_t bytes)
|
||||
{
|
||||
if (runstate_is_running()) {
|
||||
ram_counters.precopy_bytes += bytes;
|
||||
stat64_add(&ram_counters.precopy_bytes, bytes);
|
||||
} else if (migration_in_postcopy()) {
|
||||
stat64_add(&ram_atomic_counters.postcopy_bytes, bytes);
|
||||
stat64_add(&ram_counters.postcopy_bytes, bytes);
|
||||
} else {
|
||||
ram_counters.downtime_bytes += bytes;
|
||||
stat64_add(&ram_counters.downtime_bytes, bytes);
|
||||
}
|
||||
stat64_add(&ram_atomic_counters.transferred, bytes);
|
||||
}
|
||||
|
||||
void dirty_sync_missed_zero_copy(void)
|
||||
{
|
||||
ram_counters.dirty_sync_missed_zero_copy++;
|
||||
stat64_add(&ram_counters.transferred, bytes);
|
||||
}
|
||||
|
||||
struct MigrationOps {
|
||||
|
@ -756,7 +744,7 @@ void mig_throttle_counter_reset(void)
|
|||
|
||||
rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
rs->num_dirty_pages_period = 0;
|
||||
rs->bytes_xfer_prev = stat64_get(&ram_atomic_counters.transferred);
|
||||
rs->bytes_xfer_prev = stat64_get(&ram_counters.transferred);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -776,7 +764,7 @@ static void xbzrle_cache_zero_page(RAMState *rs, ram_addr_t current_addr)
|
|||
/* We don't care if this fails to allocate a new cache page
|
||||
* as long as it updated an old one */
|
||||
cache_insert(XBZRLE.cache, current_addr, XBZRLE.zero_target_page,
|
||||
ram_counters.dirty_sync_count);
|
||||
stat64_get(&ram_counters.dirty_sync_count));
|
||||
}
|
||||
|
||||
#define ENCODING_FLAG_XBZRLE 0x1
|
||||
|
@ -802,13 +790,13 @@ static int save_xbzrle_page(RAMState *rs, PageSearchStatus *pss,
|
|||
int encoded_len = 0, bytes_xbzrle;
|
||||
uint8_t *prev_cached_page;
|
||||
QEMUFile *file = pss->pss_channel;
|
||||
uint64_t generation = stat64_get(&ram_counters.dirty_sync_count);
|
||||
|
||||
if (!cache_is_cached(XBZRLE.cache, current_addr,
|
||||
ram_counters.dirty_sync_count)) {
|
||||
if (!cache_is_cached(XBZRLE.cache, current_addr, generation)) {
|
||||
xbzrle_counters.cache_miss++;
|
||||
if (!rs->last_stage) {
|
||||
if (cache_insert(XBZRLE.cache, current_addr, *current_data,
|
||||
ram_counters.dirty_sync_count) == -1) {
|
||||
generation) == -1) {
|
||||
return -1;
|
||||
} else {
|
||||
/* update *current_data when the page has been
|
||||
|
@ -1130,8 +1118,8 @@ uint64_t ram_pagesize_summary(void)
|
|||
|
||||
uint64_t ram_get_total_transferred_pages(void)
|
||||
{
|
||||
return stat64_get(&ram_atomic_counters.normal) +
|
||||
stat64_get(&ram_atomic_counters.duplicate) +
|
||||
return stat64_get(&ram_counters.normal_pages) +
|
||||
stat64_get(&ram_counters.zero_pages) +
|
||||
compression_counters.pages + xbzrle_counters.pages;
|
||||
}
|
||||
|
||||
|
@ -1192,7 +1180,7 @@ static void migration_trigger_throttle(RAMState *rs)
|
|||
MigrationState *s = migrate_get_current();
|
||||
uint64_t threshold = s->parameters.throttle_trigger_threshold;
|
||||
uint64_t bytes_xfer_period =
|
||||
stat64_get(&ram_atomic_counters.transferred) - rs->bytes_xfer_prev;
|
||||
stat64_get(&ram_counters.transferred) - rs->bytes_xfer_prev;
|
||||
uint64_t bytes_dirty_period = rs->num_dirty_pages_period * TARGET_PAGE_SIZE;
|
||||
uint64_t bytes_dirty_threshold = bytes_xfer_period * threshold / 100;
|
||||
|
||||
|
@ -1221,7 +1209,7 @@ static void migration_bitmap_sync(RAMState *rs)
|
|||
RAMBlock *block;
|
||||
int64_t end_time;
|
||||
|
||||
ram_counters.dirty_sync_count++;
|
||||
stat64_add(&ram_counters.dirty_sync_count, 1);
|
||||
|
||||
if (!rs->time_last_bitmap_sync) {
|
||||
rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
|
@ -1255,10 +1243,11 @@ static void migration_bitmap_sync(RAMState *rs)
|
|||
/* reset period counters */
|
||||
rs->time_last_bitmap_sync = end_time;
|
||||
rs->num_dirty_pages_period = 0;
|
||||
rs->bytes_xfer_prev = stat64_get(&ram_atomic_counters.transferred);
|
||||
rs->bytes_xfer_prev = stat64_get(&ram_counters.transferred);
|
||||
}
|
||||
if (migrate_use_events()) {
|
||||
qapi_event_send_migration_pass(ram_counters.dirty_sync_count);
|
||||
uint64_t generation = stat64_get(&ram_counters.dirty_sync_count);
|
||||
qapi_event_send_migration_pass(generation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1331,7 +1320,7 @@ static int save_zero_page(PageSearchStatus *pss, QEMUFile *f, RAMBlock *block,
|
|||
int len = save_zero_page_to_file(pss, f, block, offset);
|
||||
|
||||
if (len) {
|
||||
stat64_add(&ram_atomic_counters.duplicate, 1);
|
||||
stat64_add(&ram_counters.zero_pages, 1);
|
||||
ram_transferred_add(len);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1368,9 +1357,9 @@ static bool control_save_page(PageSearchStatus *pss, RAMBlock *block,
|
|||
}
|
||||
|
||||
if (bytes_xmit > 0) {
|
||||
stat64_add(&ram_atomic_counters.normal, 1);
|
||||
stat64_add(&ram_counters.normal_pages, 1);
|
||||
} else if (bytes_xmit == 0) {
|
||||
stat64_add(&ram_atomic_counters.duplicate, 1);
|
||||
stat64_add(&ram_counters.zero_pages, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1402,7 +1391,7 @@ static int save_normal_page(PageSearchStatus *pss, RAMBlock *block,
|
|||
qemu_put_buffer(file, buf, TARGET_PAGE_SIZE);
|
||||
}
|
||||
ram_transferred_add(TARGET_PAGE_SIZE);
|
||||
stat64_add(&ram_atomic_counters.normal, 1);
|
||||
stat64_add(&ram_counters.normal_pages, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1458,7 +1447,7 @@ static int ram_save_multifd_page(QEMUFile *file, RAMBlock *block,
|
|||
if (multifd_queue_page(file, block, offset) < 0) {
|
||||
return -1;
|
||||
}
|
||||
stat64_add(&ram_atomic_counters.normal, 1);
|
||||
stat64_add(&ram_counters.normal_pages, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1497,7 +1486,7 @@ update_compress_thread_counts(const CompressParam *param, int bytes_xmit)
|
|||
ram_transferred_add(bytes_xmit);
|
||||
|
||||
if (param->zero_page) {
|
||||
stat64_add(&ram_atomic_counters.duplicate, 1);
|
||||
stat64_add(&ram_counters.zero_pages, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2180,7 +2169,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len)
|
|||
RAMBlock *ramblock;
|
||||
RAMState *rs = ram_state;
|
||||
|
||||
ram_counters.postcopy_requests++;
|
||||
stat64_add(&ram_counters.postcopy_requests, 1);
|
||||
RCU_READ_LOCK_GUARD();
|
||||
|
||||
if (!rbname) {
|
||||
|
@ -2632,9 +2621,9 @@ void acct_update_position(QEMUFile *f, size_t size, bool zero)
|
|||
uint64_t pages = size / TARGET_PAGE_SIZE;
|
||||
|
||||
if (zero) {
|
||||
stat64_add(&ram_atomic_counters.duplicate, pages);
|
||||
stat64_add(&ram_counters.zero_pages, pages);
|
||||
} else {
|
||||
stat64_add(&ram_atomic_counters.normal, pages);
|
||||
stat64_add(&ram_counters.normal_pages, pages);
|
||||
ram_transferred_add(size);
|
||||
qemu_file_credit_transfer(f, size);
|
||||
}
|
||||
|
@ -3293,7 +3282,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
|||
|
||||
migration_ops = g_malloc0(sizeof(MigrationOps));
|
||||
migration_ops->ram_save_target_page = ram_save_target_page_legacy;
|
||||
ret = multifd_send_sync_main(f);
|
||||
ret = multifd_send_sync_main(f);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -35,25 +35,27 @@
|
|||
#include "qemu/stats64.h"
|
||||
|
||||
/*
|
||||
* These are the migration statistic counters that need to be updated using
|
||||
* atomic ops (can be accessed by more than one thread). Here since we
|
||||
* cannot modify MigrationStats directly to use Stat64 as it was defined in
|
||||
* the QAPI scheme, we define an internal structure to hold them, and we
|
||||
* propagate the real values when QMP queries happen.
|
||||
*
|
||||
* IOW, the corresponding fields within ram_counters on these specific
|
||||
* fields will be always zero and not being used at all; they're just
|
||||
* placeholders to make it QAPI-compatible.
|
||||
* These are the ram migration statistic counters. It is loosely
|
||||
* based on MigrationStats. We change to Stat64 any counter that
|
||||
* needs to be updated using atomic ops (can be accessed by more than
|
||||
* one thread).
|
||||
*/
|
||||
typedef struct {
|
||||
Stat64 transferred;
|
||||
Stat64 duplicate;
|
||||
Stat64 normal;
|
||||
int64_t dirty_pages_rate;
|
||||
Stat64 dirty_sync_count;
|
||||
Stat64 dirty_sync_missed_zero_copy;
|
||||
Stat64 downtime_bytes;
|
||||
Stat64 zero_pages;
|
||||
Stat64 multifd_bytes;
|
||||
Stat64 normal_pages;
|
||||
Stat64 postcopy_bytes;
|
||||
} MigrationAtomicStats;
|
||||
Stat64 postcopy_requests;
|
||||
Stat64 precopy_bytes;
|
||||
int64_t remaining;
|
||||
Stat64 transferred;
|
||||
} RAMStats;
|
||||
|
||||
extern MigrationAtomicStats ram_atomic_counters;
|
||||
extern MigrationStats ram_counters;
|
||||
extern RAMStats ram_counters;
|
||||
extern XBZRLECacheStats xbzrle_counters;
|
||||
extern CompressionStats compression_counters;
|
||||
|
||||
|
@ -112,6 +114,4 @@ void ram_write_tracking_prepare(void);
|
|||
int ram_write_tracking_start(void);
|
||||
void ram_write_tracking_stop(void);
|
||||
|
||||
void dirty_sync_missed_zero_copy(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4179,7 +4179,7 @@ void rdma_start_outgoing_migration(void *opaque,
|
|||
}
|
||||
|
||||
ret = qemu_rdma_source_init(rdma,
|
||||
s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp);
|
||||
s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp);
|
||||
|
||||
if (ret) {
|
||||
goto err;
|
||||
|
@ -4201,7 +4201,7 @@ void rdma_start_outgoing_migration(void *opaque,
|
|||
}
|
||||
|
||||
ret = qemu_rdma_source_init(rdma_return_path,
|
||||
s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp);
|
||||
s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp);
|
||||
|
||||
if (ret) {
|
||||
goto return_path_err;
|
||||
|
|
|
@ -253,7 +253,7 @@ static uint32_t get_validatable_capabilities_count(void)
|
|||
uint32_t result = 0;
|
||||
int i;
|
||||
for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
|
||||
if (should_validate_capability(i) && s->enabled_capabilities[i]) {
|
||||
if (should_validate_capability(i) && s->capabilities[i]) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ static int configuration_pre_save(void *opaque)
|
|||
state->capabilities = g_renew(MigrationCapability, state->capabilities,
|
||||
state->caps_count);
|
||||
for (i = j = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
|
||||
if (should_validate_capability(i) && s->enabled_capabilities[i]) {
|
||||
if (should_validate_capability(i) && s->capabilities[i]) {
|
||||
state->capabilities[j++] = i;
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ static bool configuration_validate_capabilities(SaveState *state)
|
|||
continue;
|
||||
}
|
||||
source_state = test_bit(i, source_caps_bm);
|
||||
target_state = s->enabled_capabilities[i];
|
||||
target_state = s->capabilities[i];
|
||||
if (source_state != target_state) {
|
||||
error_report("Capability %s is %s, but received capability is %s",
|
||||
MigrationCapability_str(i),
|
||||
|
|
|
@ -3583,14 +3583,19 @@ void qemu_init(int argc, char **argv)
|
|||
machine_class->name, machine_class->deprecation_reason);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create backends before creating migration objects, so that it can
|
||||
* check against compatibilities on the backend memories (e.g. postcopy
|
||||
* over memory-backend-file objects).
|
||||
*/
|
||||
qemu_create_late_backends();
|
||||
|
||||
/*
|
||||
* Note: creates a QOM object, must run only after global and
|
||||
* compat properties have been set up.
|
||||
*/
|
||||
migration_object_init();
|
||||
|
||||
qemu_create_late_backends();
|
||||
|
||||
/* parse features once if machine provides default cpu_type */
|
||||
current_machine->cpu_type = machine_class->default_cpu_type;
|
||||
if (cpu_option) {
|
||||
|
|
|
@ -27,8 +27,36 @@
|
|||
|
||||
#ifdef CONFIG_LINUX
|
||||
#include <sys/vfs.h>
|
||||
#include <linux/magic.h>
|
||||
#endif
|
||||
|
||||
QemuFsType qemu_fd_getfs(int fd)
|
||||
{
|
||||
#ifdef CONFIG_LINUX
|
||||
struct statfs fs;
|
||||
int ret;
|
||||
|
||||
if (fd < 0) {
|
||||
return QEMU_FS_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = fstatfs(fd, &fs);
|
||||
} while (ret != 0 && errno == EINTR);
|
||||
|
||||
switch (fs.f_type) {
|
||||
case TMPFS_MAGIC:
|
||||
return QEMU_FS_TYPE_TMPFS;
|
||||
case HUGETLBFS_MAGIC:
|
||||
return QEMU_FS_TYPE_HUGETLBFS;
|
||||
default:
|
||||
return QEMU_FS_TYPE_UNKNOWN;
|
||||
}
|
||||
#else
|
||||
return QEMU_FS_TYPE_UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t qemu_fd_getpagesize(int fd)
|
||||
{
|
||||
#ifdef CONFIG_LINUX
|
||||
|
|
Loading…
Reference in New Issue