From 97baf9d9f768caac57bb98d79a1d878181e8a052 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 18 Feb 2015 19:21:52 +0100 Subject: migration: Avoid qerror_report_err() outside QMP command handlers qerror_report_err() is a transitional interface to help with converting existing monitor commands to QMP. It should not be used elsewhere. Replace by error_report_err() in process_incoming_migration_co(). Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Signed-off-by: Juan Quintela --- migration/migration.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 2c805f11f5..60da9fef3c 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -123,8 +123,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(&local_err); if (local_err) { - qerror_report_err(local_err); - error_free(local_err); + error_report_err(local_err); exit(EXIT_FAILURE); } -- cgit v1.2.1 From 1dbd2fd9cbf29c74131e439ce80fb2efde56ee32 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Mon, 16 Feb 2015 10:50:25 +0300 Subject: migration/rdma: clean up qemu_rdma_dest_init a bit Do not check for rdma->host being empty twice. This removes a large "if" block, so code indentation is changed. While at it, remove an ugly goto from the loop, replacing it with a cleaner if logic. And finally, there's no need to initialize `ret' variable since is always has a value. Signed-off-by: Michael Tokarev Reviewed-by: Dr. David Alan Gilbert Tested-by: Dr. David Alan Gilbert -- fixed space detected by Dave Signed-off-by: Juan Quintela --- migration/rdma.c | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index d1c19ffdac..5dd4863129 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -2364,10 +2364,10 @@ err_rdma_source_connect: static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) { - int ret = -EINVAL, idx; + int ret, idx; struct rdma_cm_id *listen_id; char ip[40] = "unknown"; - struct rdma_addrinfo *res; + struct rdma_addrinfo *res, *e; char port_str[16]; for (idx = 0; idx < RDMA_WRID_MAX; idx++) { @@ -2375,7 +2375,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) rdma->wr_data[idx].control_curr = NULL; } - if (rdma->host == NULL) { + if (!rdma->host || !rdma->host[0]) { ERROR(errp, "RDMA host is not set!"); rdma->error_state = -EINVAL; return -1; @@ -2398,40 +2398,33 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) snprintf(port_str, 16, "%d", rdma->port); port_str[15] = '\0'; - if (rdma->host && strcmp("", rdma->host)) { - struct rdma_addrinfo *e; + ret = rdma_getaddrinfo(rdma->host, port_str, NULL, &res); + if (ret < 0) { + ERROR(errp, "could not rdma_getaddrinfo address %s", rdma->host); + goto err_dest_init_bind_addr; + } - ret = rdma_getaddrinfo(rdma->host, port_str, NULL, &res); - if (ret < 0) { - ERROR(errp, "could not rdma_getaddrinfo address %s", rdma->host); - goto err_dest_init_bind_addr; + for (e = res; e != NULL; e = e->ai_next) { + inet_ntop(e->ai_family, + &((struct sockaddr_in *) e->ai_dst_addr)->sin_addr, ip, sizeof ip); + trace_qemu_rdma_dest_init_trying(rdma->host, ip); + ret = rdma_bind_addr(listen_id, e->ai_dst_addr); + if (ret) { + continue; } - - for (e = res; e != NULL; e = e->ai_next) { - inet_ntop(e->ai_family, - &((struct sockaddr_in *) e->ai_dst_addr)->sin_addr, ip, sizeof ip); - trace_qemu_rdma_dest_init_trying(rdma->host, ip); - ret = rdma_bind_addr(listen_id, e->ai_dst_addr); - if (!ret) { - if (e->ai_family == AF_INET6) { - ret = qemu_rdma_broken_ipv6_kernel(errp, listen_id->verbs); - if (ret) { - continue; - } - } - - goto listen; + if (e->ai_family == AF_INET6) { + ret = qemu_rdma_broken_ipv6_kernel(errp, listen_id->verbs); + if (ret) { + continue; } } + break; + } + if (!e) { ERROR(errp, "Error: could not rdma_bind_addr!"); goto err_dest_init_bind_addr; - } else { - ERROR(errp, "migration host and port not specified!"); - ret = -EINVAL; - goto err_dest_init_bind_addr; } -listen: rdma->listen_id = listen_id; qemu_rdma_dump_gid("dest_init", listen_id); -- cgit v1.2.1 From 3ac040c0ef525c4cc5ebf881c15421cfa6b095c7 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sat, 28 Feb 2015 19:09:42 +0100 Subject: migration: Fix some 32 bit compiler errors The current code won't compile on 32 bit hosts because there are lots of type casts between pointers and 64 bit integers. Fix some of them. Signed-off-by: Stefan Weil Signed-off-by: Juan Quintela --- migration/rdma.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index 5dd4863129..a52e96ae80 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -1103,7 +1103,7 @@ static int qemu_rdma_search_ram_block(RDMAContext *rdma, * to perform the actual RDMA operation. */ static int qemu_rdma_register_and_get_keys(RDMAContext *rdma, - RDMALocalBlock *block, uint8_t *host_addr, + RDMALocalBlock *block, uintptr_t host_addr, uint32_t *lkey, uint32_t *rkey, int chunk, uint8_t *chunk_start, uint8_t *chunk_end) { @@ -1140,11 +1140,12 @@ static int qemu_rdma_register_and_get_keys(RDMAContext *rdma, if (!block->pmr[chunk]) { perror("Failed to register chunk!"); fprintf(stderr, "Chunk details: block: %d chunk index %d" - " start %" PRIu64 " end %" PRIu64 " host %" PRIu64 - " local %" PRIu64 " registrations: %d\n", - block->index, chunk, (uint64_t) chunk_start, - (uint64_t) chunk_end, (uint64_t) host_addr, - (uint64_t) block->local_host_addr, + " start %" PRIuPTR " end %" PRIuPTR + " host %" PRIuPTR + " local %" PRIuPTR " registrations: %d\n", + block->index, chunk, (uintptr_t)chunk_start, + (uintptr_t)chunk_end, host_addr, + (uintptr_t)block->local_host_addr, rdma->total_registrations); return -1; } @@ -1931,8 +1932,7 @@ retry: } /* try to overlap this single registration with the one we sent. */ - if (qemu_rdma_register_and_get_keys(rdma, block, - (uint8_t *) sge.addr, + if (qemu_rdma_register_and_get_keys(rdma, block, sge.addr, &sge.lkey, NULL, chunk, chunk_start, chunk_end)) { error_report("cannot get lkey"); @@ -1951,8 +1951,7 @@ retry: block->remote_host_addr = reg_result->host_addr; } else { /* already registered before */ - if (qemu_rdma_register_and_get_keys(rdma, block, - (uint8_t *)sge.addr, + if (qemu_rdma_register_and_get_keys(rdma, block, sge.addr, &sge.lkey, NULL, chunk, chunk_start, chunk_end)) { error_report("cannot get lkey!"); @@ -1964,7 +1963,7 @@ retry: } else { send_wr.wr.rdma.rkey = block->remote_rkey; - if (qemu_rdma_register_and_get_keys(rdma, block, (uint8_t *)sge.addr, + if (qemu_rdma_register_and_get_keys(rdma, block, sge.addr, &sge.lkey, NULL, chunk, chunk_start, chunk_end)) { error_report("cannot get lkey!"); @@ -3027,7 +3026,7 @@ static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque, chunk_start = ram_chunk_start(block, chunk); chunk_end = ram_chunk_end(block, chunk + reg->chunks); if (qemu_rdma_register_and_get_keys(rdma, block, - (uint8_t *)host_addr, NULL, ®_result->rkey, + (uintptr_t)host_addr, NULL, ®_result->rkey, chunk, chunk_start, chunk_end)) { error_report("cannot get rkey"); ret = -EINVAL; -- cgit v1.2.1 From fbce8c25d886b207ebb290d911a7d99abd652676 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sat, 28 Feb 2015 19:09:43 +0100 Subject: migration: Fix remaining 32 bit compiler errors Fix type casts between pointers and 64 bit integers. Now 32 bit builds are possible again. Signed-off-by: Stefan Weil Signed-off-by: Juan Quintela --- migration/rdma.c | 53 +++++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index a52e96ae80..e6c3a67b54 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -493,8 +493,8 @@ static inline uint64_t ram_chunk_index(const uint8_t *start, static inline uint8_t *ram_chunk_start(const RDMALocalBlock *rdma_ram_block, uint64_t i) { - return (uint8_t *) (((uintptr_t) rdma_ram_block->local_host_addr) - + (i << RDMA_REG_CHUNK_SHIFT)); + return (uint8_t *)(uintptr_t)(rdma_ram_block->local_host_addr + + (i << RDMA_REG_CHUNK_SHIFT)); } static inline uint8_t *ram_chunk_end(const RDMALocalBlock *rdma_ram_block, @@ -515,7 +515,7 @@ static int rdma_add_block(RDMAContext *rdma, void *host_addr, { RDMALocalBlocks *local = &rdma->local_ram_blocks; RDMALocalBlock *block = g_hash_table_lookup(rdma->blockmap, - (void *) block_offset); + (void *)(uintptr_t)block_offset); RDMALocalBlock *old = local->block; assert(block == NULL); @@ -526,9 +526,11 @@ static int rdma_add_block(RDMAContext *rdma, void *host_addr, int x; for (x = 0; x < local->nb_blocks; x++) { - g_hash_table_remove(rdma->blockmap, (void *)old[x].offset); - g_hash_table_insert(rdma->blockmap, (void *)old[x].offset, - &local->block[x]); + g_hash_table_remove(rdma->blockmap, + (void *)(uintptr_t)old[x].offset); + g_hash_table_insert(rdma->blockmap, + (void *)(uintptr_t)old[x].offset, + &local->block[x]); } memcpy(local->block, old, sizeof(RDMALocalBlock) * local->nb_blocks); g_free(old); @@ -551,9 +553,9 @@ static int rdma_add_block(RDMAContext *rdma, void *host_addr, g_hash_table_insert(rdma->blockmap, (void *) block_offset, block); - trace_rdma_add_block(local->nb_blocks, (uint64_t) block->local_host_addr, + trace_rdma_add_block(local->nb_blocks, (uintptr_t) block->local_host_addr, block->offset, block->length, - (uint64_t) (block->local_host_addr + block->length), + (uintptr_t) (block->local_host_addr + block->length), BITS_TO_LONGS(block->nb_chunks) * sizeof(unsigned long) * 8, block->nb_chunks); @@ -634,7 +636,7 @@ static int rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset) block->remote_keys = NULL; for (x = 0; x < local->nb_blocks; x++) { - g_hash_table_remove(rdma->blockmap, (void *)old[x].offset); + g_hash_table_remove(rdma->blockmap, (void *)(uintptr_t)old[x].offset); } if (local->nb_blocks > 1) { @@ -657,9 +659,9 @@ static int rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset) } trace_rdma_delete_block(local->nb_blocks, - (uint64_t)block->local_host_addr, + (uintptr_t)block->local_host_addr, block->offset, block->length, - (uint64_t)(block->local_host_addr + block->length), + (uintptr_t)(block->local_host_addr + block->length), BITS_TO_LONGS(block->nb_chunks) * sizeof(unsigned long) * 8, block->nb_chunks); @@ -669,8 +671,9 @@ static int rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset) if (local->nb_blocks) { for (x = 0; x < local->nb_blocks; x++) { - g_hash_table_insert(rdma->blockmap, (void *)local->block[x].offset, - &local->block[x]); + g_hash_table_insert(rdma->blockmap, + (void *)(uintptr_t)local->block[x].offset, + &local->block[x]); } } @@ -1075,7 +1078,7 @@ static int qemu_rdma_reg_whole_ram_blocks(RDMAContext *rdma) * This search cannot fail or the migration will fail. */ static int qemu_rdma_search_ram_block(RDMAContext *rdma, - uint64_t block_offset, + uintptr_t block_offset, uint64_t offset, uint64_t length, uint64_t *block_index, @@ -1379,8 +1382,8 @@ static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out, RDMALocalBlock *block = &(rdma->local_ram_blocks.block[index]); trace_qemu_rdma_poll_write(print_wrid(wr_id), wr_id, rdma->nb_sent, - index, chunk, - block->local_host_addr, (void *)block->remote_host_addr); + index, chunk, block->local_host_addr, + (void *)(uintptr_t)block->remote_host_addr); clear_bit(chunk, block->transit_bitmap); @@ -1523,7 +1526,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf, RDMAWorkRequestData *wr = &rdma->wr_data[RDMA_WRID_CONTROL]; struct ibv_send_wr *bad_wr; struct ibv_sge sge = { - .addr = (uint64_t)(wr->control), + .addr = (uintptr_t)(wr->control), .length = head->len + sizeof(RDMAControlHeader), .lkey = wr->control_mr->lkey, }; @@ -1577,7 +1580,7 @@ static int qemu_rdma_post_recv_control(RDMAContext *rdma, int idx) { struct ibv_recv_wr *bad_wr; struct ibv_sge sge = { - .addr = (uint64_t)(rdma->wr_data[idx].control), + .addr = (uintptr_t)(rdma->wr_data[idx].control), .length = RDMA_CONTROL_MAX_BUFFER, .lkey = rdma->wr_data[idx].control_mr->lkey, }; @@ -1824,11 +1827,12 @@ static int qemu_rdma_write_one(QEMUFile *f, RDMAContext *rdma, }; retry: - sge.addr = (uint64_t)(block->local_host_addr + + sge.addr = (uintptr_t)(block->local_host_addr + (current_addr - block->offset)); sge.length = length; - chunk = ram_chunk_index(block->local_host_addr, (uint8_t *) sge.addr); + chunk = ram_chunk_index(block->local_host_addr, + (uint8_t *)(uintptr_t)sge.addr); chunk_start = ram_chunk_start(block, chunk); if (block->is_ram_block) { @@ -1881,8 +1885,9 @@ retry: * memset() + madvise() the entire chunk without RDMA. */ - if (can_use_buffer_find_nonzero_offset((void *)sge.addr, length) - && buffer_find_nonzero_offset((void *)sge.addr, + if (can_use_buffer_find_nonzero_offset((void *)(uintptr_t)sge.addr, + length) + && buffer_find_nonzero_offset((void *)(uintptr_t)sge.addr, length) == length) { RDMACompress comp = { .offset = current_addr, @@ -2969,7 +2974,7 @@ static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque, */ for (i = 0; i < local->nb_blocks; i++) { rdma->block[i].remote_host_addr = - (uint64_t)(local->block[i].local_host_addr); + (uintptr_t)(local->block[i].local_host_addr); if (rdma->pin_all) { rdma->block[i].remote_rkey = local->block[i].mr->rkey; @@ -3033,7 +3038,7 @@ static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque, goto out; } - reg_result->host_addr = (uint64_t) block->local_host_addr; + reg_result->host_addr = (uintptr_t)block->local_host_addr; trace_qemu_rdma_registration_handle_register_rkey( reg_result->rkey); -- cgit v1.2.1 From 1fa57f5543aaff62a6fff63782e6c7dd54773628 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 26 Feb 2015 14:54:39 +0000 Subject: migrate_incoming: use hmp_handle_error Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Amit Shah Signed-off-by: Juan Quintela --- hmp.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hmp.c b/hmp.c index f6cde86b93..84fb585dfd 100644 --- a/hmp.c +++ b/hmp.c @@ -1123,11 +1123,7 @@ void hmp_migrate_incoming(Monitor *mon, const QDict *qdict) qmp_migrate_incoming(uri, &err); - if (err) { - monitor_printf(mon, "%s\n", error_get_pretty(err)); - error_free(err); - return; - } + hmp_handle_error(mon, &err); } void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict) -- cgit v1.2.1 From d87605347879b67f156af085d772ab88cde40820 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 26 Feb 2015 14:54:40 +0000 Subject: Warn against the use of the string as uri parameter to migrate-incoming Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Amit Shah Signed-off-by: Juan Quintela --- qapi-schema.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qapi-schema.json b/qapi-schema.json index 2b3e275983..d1f65a1452 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1750,6 +1750,9 @@ # Returns: nothing on success # # Since: 2.3 +# Note: It's a bad idea to use a string for the uri, but it needs to stay +# compatible with -incoming and the format of the uri is already exposed +# above libvirt ## { 'command': 'migrate-incoming', 'data': {'uri': 'str' } } -- cgit v1.2.1 From 4debb5f553d816bf1f2d86bb61e833e79010cb3d Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 26 Feb 2015 14:54:41 +0000 Subject: migrate_incoming: Cleanup/clarify error messages Create a separate error for the case where migrate_incoming is used after a succesful migrate_incoming. Reword the error in the case where '-incoming defer' is missing to omit the command name so it's right for both hmp and qmp. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Amit Shah Signed-off-by: Juan Quintela --- migration/migration.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 60da9fef3c..1e44d9bb83 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -434,11 +434,15 @@ void migrate_del_blocker(Error *reason) void qmp_migrate_incoming(const char *uri, Error **errp) { Error *local_err = NULL; + static bool once = true; if (!deferred_incoming) { - error_setg(errp, "'-incoming defer' is required for migrate_incoming"); + error_setg(errp, "For use with '-incoming defer'"); return; } + if (!once) { + error_setg(errp, "The incoming migration has already been started"); + } qemu_start_incoming_migration(uri, &local_err); @@ -447,7 +451,7 @@ void qmp_migrate_incoming(const char *uri, Error **errp) return; } - deferred_incoming = false; + once = false; } void qmp_migrate(const char *uri, bool has_blk, bool blk, -- cgit v1.2.1 From f54a235f9b15ae59d70b40630417d8aaa88bc4ec Mon Sep 17 00:00:00 2001 From: zhanghailiang Date: Mon, 9 Mar 2015 17:27:38 +0800 Subject: arch_init: Count the total number of pages by using helper function There is already a helper function ram_bytes_total(), we can use it to help counting the total number of pages used by ram blocks. Signed-off-by: zhanghailiang Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Juan Quintela --- arch_init.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/arch_init.c b/arch_init.c index c3f7d3f56d..fcfa32828d 100644 --- a/arch_init.c +++ b/arch_init.c @@ -895,13 +895,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque) * Count the total number of pages used by ram blocks not including any * gaps due to alignment or unplugs. */ - migration_dirty_pages = 0; - QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { - uint64_t block_pages; - - block_pages = block->used_length >> TARGET_PAGE_BITS; - migration_dirty_pages += block_pages; - } + migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS; memory_global_dirty_log_start(); migration_bitmap_sync(); -- cgit v1.2.1 From 21cb4924f79579222459c2395f28d1a26d4ef0bd Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Sat, 14 Mar 2015 07:19:28 +0100 Subject: migration: Remove unused functions migrate_rdma_pin_all() and qsb_clone() are completely unused and thus can be deleted. Signed-off-by: Thomas Huth Cc: Juan Quintela Cc: Amit Shah Signed-off-by: Juan Quintela --- include/migration/migration.h | 1 - include/migration/qemu-file.h | 1 - migration/migration.c | 9 --------- migration/qemu-file-buf.c | 31 ------------------------------- 4 files changed, 42 deletions(-) diff --git a/include/migration/migration.h b/include/migration/migration.h index 5e16af60fd..bf09968d76 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -139,7 +139,6 @@ void migrate_add_blocker(Error *reason); */ void migrate_del_blocker(Error *reason); -bool migrate_rdma_pin_all(void); bool migrate_zero_blocks(void); bool migrate_auto_converge(void); diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index 94a8c978a4..745a850e51 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -133,7 +133,6 @@ bool qemu_file_mode_is_not_valid(const char *mode); bool qemu_file_is_writable(QEMUFile *f); QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len); -QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *); void qsb_free(QEMUSizedBuffer *); size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t length); size_t qsb_get_length(const QEMUSizedBuffer *qsb); diff --git a/migration/migration.c b/migration/migration.c index 1e44d9bb83..8465f91e93 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -579,15 +579,6 @@ void qmp_migrate_set_downtime(double value, Error **errp) max_downtime = (uint64_t)value; } -bool migrate_rdma_pin_all(void) -{ - MigrationState *s; - - s = migrate_get_current(); - - return s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]; -} - bool migrate_auto_converge(void) { MigrationState *s; diff --git a/migration/qemu-file-buf.c b/migration/qemu-file-buf.c index e56a8ad1e0..16a51a1e17 100644 --- a/migration/qemu-file-buf.c +++ b/migration/qemu-file-buf.c @@ -365,37 +365,6 @@ ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *source, return count; } -/** - * Create a deep copy of the given QEMUSizedBuffer. - * - * @qsb: A QEMUSizedBuffer - * - * Returns a clone of @qsb or NULL on allocation failure - */ -QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *qsb) -{ - QEMUSizedBuffer *out = qsb_create(NULL, qsb_get_length(qsb)); - size_t i; - ssize_t res; - off_t pos = 0; - - if (!out) { - return NULL; - } - - for (i = 0; i < qsb->n_iov; i++) { - res = qsb_write_at(out, qsb->iov[i].iov_base, - pos, qsb->iov[i].iov_len); - if (res < 0) { - qsb_free(out); - return NULL; - } - pos += res; - } - - return out; -} - typedef struct QEMUBuffer { QEMUSizedBuffer *qsb; QEMUFile *file; -- cgit v1.2.1 From 3119473166eeac017b249b408b07473aff5a7ca2 Mon Sep 17 00:00:00 2001 From: zhanghailiang Date: Fri, 13 Mar 2015 16:08:38 +0800 Subject: migration: Rename abbreviated macro MIG_STATE_* to MIGRATION_STATUS_* Rename all macro MIG_STATE_* to MIGRATION_STATUS_* except "MIG_STATE_ERROR", we rename it to "MIGRATION_STATUS_FAILED" which will match the migration status string 'failed'. Signed-off-by: zhanghailiang Reviewed-by: Eric Blake Signed-off-by: Juan Quintela --- migration/migration.c | 93 +++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 8465f91e93..b0860fa5c1 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -27,13 +27,13 @@ #include "trace.h" enum { - MIG_STATE_ERROR = -1, - MIG_STATE_NONE, - MIG_STATE_SETUP, - MIG_STATE_CANCELLING, - MIG_STATE_CANCELLED, - MIG_STATE_ACTIVE, - MIG_STATE_COMPLETED, + MIGRATION_STATUS_FAILED = -1, + MIGRATION_STATUS_NONE, + MIGRATION_STATUS_SETUP, + MIGRATION_STATUS_CANCELLING, + MIGRATION_STATUS_CANCELLED, + MIGRATION_STATUS_ACTIVE, + MIGRATION_STATUS_COMPLETED, }; #define MAX_THROTTLE (32 << 20) /* Migration speed throttling */ @@ -58,7 +58,7 @@ static bool deferred_incoming; MigrationState *migrate_get_current(void) { static MigrationState current_migration = { - .state = MIG_STATE_NONE, + .state = MIGRATION_STATUS_NONE, .bandwidth_limit = MAX_THROTTLE, .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE, .mbps = -1, @@ -200,16 +200,16 @@ MigrationInfo *qmp_query_migrate(Error **errp) MigrationState *s = migrate_get_current(); switch (s->state) { - case MIG_STATE_NONE: + case MIGRATION_STATUS_NONE: /* no migration has happened ever */ break; - case MIG_STATE_SETUP: + case MIGRATION_STATUS_SETUP: info->has_status = true; info->status = g_strdup("setup"); info->has_total_time = false; break; - case MIG_STATE_ACTIVE: - case MIG_STATE_CANCELLING: + case MIGRATION_STATUS_ACTIVE: + case MIGRATION_STATUS_CANCELLING: info->has_status = true; info->status = g_strdup("active"); info->has_total_time = true; @@ -243,7 +243,7 @@ MigrationInfo *qmp_query_migrate(Error **errp) get_xbzrle_cache_stats(info); break; - case MIG_STATE_COMPLETED: + case MIGRATION_STATUS_COMPLETED: get_xbzrle_cache_stats(info); info->has_status = true; @@ -267,11 +267,11 @@ MigrationInfo *qmp_query_migrate(Error **errp) info->ram->mbps = s->mbps; info->ram->dirty_sync_count = s->dirty_sync_count; break; - case MIG_STATE_ERROR: + case MIGRATION_STATUS_FAILED: info->has_status = true; info->status = g_strdup("failed"); break; - case MIG_STATE_CANCELLED: + case MIGRATION_STATUS_CANCELLED: info->has_status = true; info->status = g_strdup("cancelled"); break; @@ -286,7 +286,8 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, MigrationState *s = migrate_get_current(); MigrationCapabilityStatusList *cap; - if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP) { + if (s->state == MIGRATION_STATUS_ACTIVE || + s->state == MIGRATION_STATUS_SETUP) { error_set(errp, QERR_MIGRATION_ACTIVE); return; } @@ -322,12 +323,13 @@ static void migrate_fd_cleanup(void *opaque) s->file = NULL; } - assert(s->state != MIG_STATE_ACTIVE); + assert(s->state != MIGRATION_STATUS_ACTIVE); - if (s->state != MIG_STATE_COMPLETED) { + if (s->state != MIGRATION_STATUS_COMPLETED) { qemu_savevm_state_cancel(); - if (s->state == MIG_STATE_CANCELLING) { - migrate_set_state(s, MIG_STATE_CANCELLING, MIG_STATE_CANCELLED); + if (s->state == MIGRATION_STATUS_CANCELLING) { + migrate_set_state(s, MIGRATION_STATUS_CANCELLING, + MIGRATION_STATUS_CANCELLED); } } @@ -338,8 +340,8 @@ void migrate_fd_error(MigrationState *s) { trace_migrate_fd_error(); assert(s->file == NULL); - s->state = MIG_STATE_ERROR; - trace_migrate_set_state(MIG_STATE_ERROR); + s->state = MIGRATION_STATUS_FAILED; + trace_migrate_set_state(MIGRATION_STATUS_FAILED); notifier_list_notify(&migration_state_notifiers, s); } @@ -351,11 +353,12 @@ static void migrate_fd_cancel(MigrationState *s) do { old_state = s->state; - if (old_state != MIG_STATE_SETUP && old_state != MIG_STATE_ACTIVE) { + if (old_state != MIGRATION_STATUS_SETUP && + old_state != MIGRATION_STATUS_ACTIVE) { break; } - migrate_set_state(s, old_state, MIG_STATE_CANCELLING); - } while (s->state != MIG_STATE_CANCELLING); + migrate_set_state(s, old_state, MIGRATION_STATUS_CANCELLING); + } while (s->state != MIGRATION_STATUS_CANCELLING); /* * If we're unlucky the migration code might be stuck somewhere in a @@ -364,7 +367,7 @@ static void migrate_fd_cancel(MigrationState *s) * The outgoing qemu file gets closed in migrate_fd_cleanup that is * called in a bh, so there is no race against this cancel. */ - if (s->state == MIG_STATE_CANCELLING && f) { + if (s->state == MIGRATION_STATUS_CANCELLING && f) { qemu_file_shutdown(f); } } @@ -381,18 +384,18 @@ void remove_migration_state_change_notifier(Notifier *notify) bool migration_in_setup(MigrationState *s) { - return s->state == MIG_STATE_SETUP; + return s->state == MIGRATION_STATUS_SETUP; } bool migration_has_finished(MigrationState *s) { - return s->state == MIG_STATE_COMPLETED; + return s->state == MIGRATION_STATUS_COMPLETED; } bool migration_has_failed(MigrationState *s) { - return (s->state == MIG_STATE_CANCELLED || - s->state == MIG_STATE_ERROR); + return (s->state == MIGRATION_STATUS_CANCELLED || + s->state == MIGRATION_STATUS_FAILED); } static MigrationState *migrate_init(const MigrationParams *params) @@ -412,8 +415,8 @@ static MigrationState *migrate_init(const MigrationParams *params) s->xbzrle_cache_size = xbzrle_cache_size; s->bandwidth_limit = bandwidth_limit; - s->state = MIG_STATE_SETUP; - trace_migrate_set_state(MIG_STATE_SETUP); + s->state = MIGRATION_STATUS_SETUP; + trace_migrate_set_state(MIGRATION_STATUS_SETUP); s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); return s; @@ -466,8 +469,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, params.blk = has_blk && blk; params.shared = has_inc && inc; - if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP || - s->state == MIG_STATE_CANCELLING) { + if (s->state == MIGRATION_STATUS_ACTIVE || + s->state == MIGRATION_STATUS_SETUP || + s->state == MIGRATION_STATUS_CANCELLING) { error_set(errp, QERR_MIGRATION_ACTIVE); return; } @@ -504,7 +508,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, #endif } else { error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); - s->state = MIG_STATE_ERROR; + s->state = MIGRATION_STATUS_FAILED; return; } @@ -630,9 +634,9 @@ static void *migration_thread(void *opaque) qemu_savevm_state_begin(s->file, &s->params); s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start; - migrate_set_state(s, MIG_STATE_SETUP, MIG_STATE_ACTIVE); + migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_ACTIVE); - while (s->state == MIG_STATE_ACTIVE) { + while (s->state == MIGRATION_STATUS_ACTIVE) { int64_t current_time; uint64_t pending_size; @@ -657,19 +661,22 @@ static void *migration_thread(void *opaque) qemu_mutex_unlock_iothread(); if (ret < 0) { - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); + migrate_set_state(s, MIGRATION_STATUS_ACTIVE, + MIGRATION_STATUS_FAILED); break; } if (!qemu_file_get_error(s->file)) { - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); + migrate_set_state(s, MIGRATION_STATUS_ACTIVE, + MIGRATION_STATUS_COMPLETED); break; } } } if (qemu_file_get_error(s->file)) { - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); + migrate_set_state(s, MIGRATION_STATUS_ACTIVE, + MIGRATION_STATUS_FAILED); break; } current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); @@ -701,7 +708,7 @@ static void *migration_thread(void *opaque) } qemu_mutex_lock_iothread(); - if (s->state == MIG_STATE_COMPLETED) { + if (s->state == MIGRATION_STATUS_COMPLETED) { int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); uint64_t transferred_bytes = qemu_ftell(s->file); s->total_time = end_time - s->total_time; @@ -724,8 +731,8 @@ static void *migration_thread(void *opaque) void migrate_fd_connect(MigrationState *s) { - s->state = MIG_STATE_SETUP; - trace_migrate_set_state(MIG_STATE_SETUP); + s->state = MIGRATION_STATUS_SETUP; + trace_migrate_set_state(MIGRATION_STATUS_SETUP); /* This is a best 1st approximation. ns to ms */ s->expected_downtime = max_downtime/1000000; -- cgit v1.2.1 From e49f35bdb4974d6cfd7e5eb5cb9f8c50eef3f3a9 Mon Sep 17 00:00:00 2001 From: zhanghailiang Date: Fri, 13 Mar 2015 16:08:39 +0800 Subject: hmp: Rename 'MigrationStatus' to 'HMPMigrationStatus' We will use the typename 'MigrationStatus' for publicly exported typename, So here we rename the internal-only 'MigrationStatus' to 'HMPMigrationStatus'. Signed-off-by: zhanghailiang Reviewed-by: Eric Blake Signed-off-by: Juan Quintela --- hmp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hmp.c b/hmp.c index 84fb585dfd..8afce2d6d9 100644 --- a/hmp.c +++ b/hmp.c @@ -1341,16 +1341,16 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &error); } -typedef struct MigrationStatus +typedef struct HMPMigrationStatus { QEMUTimer *timer; Monitor *mon; bool is_block_migration; -} MigrationStatus; +} HMPMigrationStatus; static void hmp_migrate_status_cb(void *opaque) { - MigrationStatus *status = opaque; + HMPMigrationStatus *status = opaque; MigrationInfo *info; info = qmp_query_migrate(NULL); @@ -1398,7 +1398,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict) } if (!detach) { - MigrationStatus *status; + HMPMigrationStatus *status; if (monitor_suspend(mon) < 0) { monitor_printf(mon, "terminal does not allow synchronous " -- cgit v1.2.1 From 24b8c39b5c34b05f1ac870c421e2e61574abbdf9 Mon Sep 17 00:00:00 2001 From: zhanghailiang Date: Fri, 13 Mar 2015 16:08:40 +0800 Subject: migration: Convert 'status' of MigrationInfo to use an enum type The original 'status' is an open-coded 'str' type, convert it to use an enum type. This conversion is backwards compatible, better documented and more convenient for future extensibility. In addition, Fix a typo for qapi-schema.json (just remove the typo) : s/'completed'. 'comppleted' (since 1.2)/'completed' (since 1.2) Signed-off-by: zhanghailiang Reviewed-by: Eric Blake Signed-off-by: Juan Quintela --- hmp.c | 7 ++++--- migration/migration.c | 20 +++++--------------- qapi-schema.json | 34 +++++++++++++++++++++++++++++----- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/hmp.c b/hmp.c index 8afce2d6d9..7d5c81ed07 100644 --- a/hmp.c +++ b/hmp.c @@ -162,7 +162,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) } if (info->has_status) { - monitor_printf(mon, "Migration status: %s\n", info->status); + monitor_printf(mon, "Migration status: %s\n", + MigrationStatus_lookup[info->status]); monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n", info->total_time); if (info->has_expected_downtime) { @@ -1354,8 +1355,8 @@ static void hmp_migrate_status_cb(void *opaque) MigrationInfo *info; info = qmp_query_migrate(NULL); - if (!info->has_status || strcmp(info->status, "active") == 0 || - strcmp(info->status, "setup") == 0) { + if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE || + info->status == MIGRATION_STATUS_SETUP) { if (info->has_disk) { int progress; diff --git a/migration/migration.c b/migration/migration.c index b0860fa5c1..d7a1e7d2a3 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -26,16 +26,6 @@ #include "qmp-commands.h" #include "trace.h" -enum { - MIGRATION_STATUS_FAILED = -1, - MIGRATION_STATUS_NONE, - MIGRATION_STATUS_SETUP, - MIGRATION_STATUS_CANCELLING, - MIGRATION_STATUS_CANCELLED, - MIGRATION_STATUS_ACTIVE, - MIGRATION_STATUS_COMPLETED, -}; - #define MAX_THROTTLE (32 << 20) /* Migration speed throttling */ /* Amount of time to allocate to each "chunk" of bandwidth-throttled @@ -205,13 +195,13 @@ MigrationInfo *qmp_query_migrate(Error **errp) break; case MIGRATION_STATUS_SETUP: info->has_status = true; - info->status = g_strdup("setup"); + info->status = MIGRATION_STATUS_SETUP; info->has_total_time = false; break; case MIGRATION_STATUS_ACTIVE: case MIGRATION_STATUS_CANCELLING: info->has_status = true; - info->status = g_strdup("active"); + info->status = MIGRATION_STATUS_ACTIVE; info->has_total_time = true; info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - s->total_time; @@ -247,7 +237,7 @@ MigrationInfo *qmp_query_migrate(Error **errp) get_xbzrle_cache_stats(info); info->has_status = true; - info->status = g_strdup("completed"); + info->status = MIGRATION_STATUS_COMPLETED; info->has_total_time = true; info->total_time = s->total_time; info->has_downtime = true; @@ -269,11 +259,11 @@ MigrationInfo *qmp_query_migrate(Error **errp) break; case MIGRATION_STATUS_FAILED: info->has_status = true; - info->status = g_strdup("failed"); + info->status = MIGRATION_STATUS_FAILED; break; case MIGRATION_STATUS_CANCELLED: info->has_status = true; - info->status = g_strdup("cancelled"); + info->status = MIGRATION_STATUS_CANCELLED; break; } diff --git a/qapi-schema.json b/qapi-schema.json index d1f65a1452..ac9594d66d 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -410,19 +410,43 @@ 'cache-miss': 'int', 'cache-miss-rate': 'number', 'overflow': 'int' } } +# @MigrationStatus: +# +# An enumeration of migration status. +# +# @none: no migration has ever happened. +# +# @setup: migration process has been initiated. +# +# @cancelling: in the process of cancelling migration. +# +# @cancelled: cancelling migration is finished. +# +# @active: in the process of doing migration. +# +# @completed: migration is finished. +# +# @failed: some error occurred during migration process. +# +# Since: 2.3 +# +## +{ 'enum': 'MigrationStatus', + 'data': [ 'none', 'setup', 'cancelling', 'cancelled', + 'active', 'completed', 'failed' ] } + ## # @MigrationInfo # # Information about current migration process. # -# @status: #optional string describing the current migration status. -# As of 0.14.0 this can be 'setup', 'active', 'completed', 'failed' or -# 'cancelled'. If this field is not returned, no migration process +# @status: #optional @MigrationStatus describing the current migration status. +# If this field is not returned, no migration process # has been initiated # # @ram: #optional @MigrationStats containing detailed migration # status, only returned if status is 'active' or -# 'completed'. 'comppleted' (since 1.2) +# 'completed'(since 1.2) # # @disk: #optional @MigrationStats containing detailed disk migration # status, only returned if status is 'active' and it is a block @@ -453,7 +477,7 @@ # Since: 0.14.0 ## { 'type': 'MigrationInfo', - 'data': {'*status': 'str', '*ram': 'MigrationStats', + 'data': {'*status': 'MigrationStatus', '*ram': 'MigrationStats', '*disk': 'MigrationStats', '*xbzrle-cache': 'XBZRLECacheStats', '*total-time': 'int', -- cgit v1.2.1 From cde63fbed86e20dda98bf35025faedd994918f00 Mon Sep 17 00:00:00 2001 From: zhanghailiang Date: Fri, 13 Mar 2015 16:08:41 +0800 Subject: migration: Expose 'cancelling' status to user 'cancelling' status was introduced by commit 51cf4c1a, mainly to avoid a possible start of a new migration process while the previous one still exists. But we didn't expose this status to user, instead we returned the 'active' state. Here, we expose it to the user (such as libvirt), 'cancelling' status only occurs for a short window before the migration aborts, so for users, if they cancel a migration process, it will observe 'cancelling' status occasionally. Testing revealed that with older libvirt (anything 1.2.13 or less) will print an odd error message if the state is seen, but that the migration is still properly cancelled. Newer libvirt will be patched to recognize the new state without the odd error message. Signed-off-by: zhanghailiang Reviewed-by: Eric Blake Cc: libvir-list@redhat.com Signed-off-by: Juan Quintela --- migration/migration.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index d7a1e7d2a3..bc424907f3 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -195,13 +195,11 @@ MigrationInfo *qmp_query_migrate(Error **errp) break; case MIGRATION_STATUS_SETUP: info->has_status = true; - info->status = MIGRATION_STATUS_SETUP; info->has_total_time = false; break; case MIGRATION_STATUS_ACTIVE: case MIGRATION_STATUS_CANCELLING: info->has_status = true; - info->status = MIGRATION_STATUS_ACTIVE; info->has_total_time = true; info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - s->total_time; @@ -237,7 +235,6 @@ MigrationInfo *qmp_query_migrate(Error **errp) get_xbzrle_cache_stats(info); info->has_status = true; - info->status = MIGRATION_STATUS_COMPLETED; info->has_total_time = true; info->total_time = s->total_time; info->has_downtime = true; @@ -259,13 +256,12 @@ MigrationInfo *qmp_query_migrate(Error **errp) break; case MIGRATION_STATUS_FAILED: info->has_status = true; - info->status = MIGRATION_STATUS_FAILED; break; case MIGRATION_STATUS_CANCELLED: info->has_status = true; - info->status = MIGRATION_STATUS_CANCELLED; break; } + info->status = s->state; return info; } -- cgit v1.2.1