From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38956) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UopMs-0005xS-3A for qemu-devel@nongnu.org; Tue, 18 Jun 2013 02:26:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UopMq-0000ei-H1 for qemu-devel@nongnu.org; Tue, 18 Jun 2013 02:26:14 -0400 Received: from e28smtp08.in.ibm.com ([122.248.162.8]:46019) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UopMp-0000eY-M4 for qemu-devel@nongnu.org; Tue, 18 Jun 2013 02:26:12 -0400 Received: from /spool/local by e28smtp08.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 18 Jun 2013 11:47:46 +0530 Received: from d28relay01.in.ibm.com (d28relay01.in.ibm.com [9.184.220.58]) by d28dlp03.in.ibm.com (Postfix) with ESMTP id 1F949125804E for ; Tue, 18 Jun 2013 11:55:01 +0530 (IST) Received: from d28av05.in.ibm.com (d28av05.in.ibm.com [9.184.220.67]) by d28relay01.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r5I6Q8tG18546728 for ; Tue, 18 Jun 2013 11:56:08 +0530 Received: from d28av05.in.ibm.com (loopback [127.0.0.1]) by d28av05.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r5I6Q18f021682 for ; Tue, 18 Jun 2013 16:26:02 +1000 Message-ID: <51BFFD3F.40406@linux.vnet.ibm.com> Date: Tue, 18 Jun 2013 14:25:03 +0800 From: Lei Li MIME-Version: 1.0 References: <1371397053-4503-1-git-send-email-lilei@linux.vnet.ibm.com> <1371397053-4503-5-git-send-email-lilei@linux.vnet.ibm.com> <8761xehwe1.fsf@codemonkey.ws> In-Reply-To: <8761xehwe1.fsf@codemonkey.ws> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 4/7] migration-local: implementation of outgoing part List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: lagarcia@br.ibm.com, qemu-devel@nongnu.org, quintela@redhat.com On 06/17/2013 12:07 AM, Anthony Liguori wrote: > Lei Li writes: > >> Signed-off-by: Lei Li >> --- >> Makefile.objs | 1 + >> include/migration/migration.h | 15 +++++ >> migration-local.c | 116 +++++++++++++++++++++++++++++++++++++++++ >> migration-unix.c | 13 +++++ >> qapi-schema.json | 14 +++++ >> qmp-commands.hx | 22 ++++++++ >> 6 files changed, 181 insertions(+), 0 deletions(-) >> create mode 100644 migration-local.c >> >> diff --git a/Makefile.objs b/Makefile.objs >> index 5b288ba..2a3d9a5 100644 >> --- a/Makefile.objs >> +++ b/Makefile.objs >> @@ -53,6 +53,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/ >> common-obj-y += migration.o migration-tcp.o >> common-obj-y += qemu-char.o #aio.o >> common-obj-y += block-migration.o >> +common-obj-y += migration-local.o >> common-obj-y += page_cache.o xbzrle.o >> >> common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o >> diff --git a/include/migration/migration.h b/include/migration/migration.h >> index 9cc5285..12c75cf 100644 >> --- a/include/migration/migration.h >> +++ b/include/migration/migration.h >> @@ -58,6 +58,17 @@ struct MigrationState >> int64_t xbzrle_cache_size; >> }; >> >> + >> +typedef struct LocalMigState LocalMigState; >> + >> +struct LocalMigState >> +{ >> + int fd; >> + int state; >> + QEMUFile *file; >> + QemuThread thread; >> +}; >> + >> void process_incoming_migration(QEMUFile *f); >> >> void qemu_start_incoming_migration(const char *uri, Error **errp); >> @@ -80,6 +91,8 @@ void unix_start_incoming_migration(const char *path, Error **errp); >> >> void unix_start_outgoing_migration(MigrationState *s, const char *path, Error **errp); >> >> +void unix_start_local_outgoing_migration(LocalMigState *s, const char *path, Error **errp); >> + >> void fd_start_incoming_migration(const char *path, Error **errp); >> >> void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp); >> @@ -90,6 +103,8 @@ void migrate_fd_connect(MigrationState *s); >> >> int migrate_fd_close(MigrationState *s); >> >> +void migrate_fd_connect_local(LocalMigState *s); >> + >> void add_migration_state_change_notifier(Notifier *notify); >> void remove_migration_state_change_notifier(Notifier *notify); >> bool migration_is_active(MigrationState *); >> diff --git a/migration-local.c b/migration-local.c >> new file mode 100644 >> index 0000000..a97dd3a >> --- /dev/null >> +++ b/migration-local.c >> @@ -0,0 +1,116 @@ >> +/* >> + * QEMU localhost live migration >> + * >> + * Copyright IBM, Corp. 2013 >> + * >> + * This work is licensed under the terms of the GNU GPL, version 2. See >> + * the COPYING file in the top-level directory. >> + * >> + * Contributions are licensed under the terms of the GNU GPL, version 2 >> + * or (at your option) any later version. > You can just add the "or later" clause to the first paragraph. Sure. > >> + */ >> + >> +#include "qemu-common.h" >> +#include "migration/migration.h" >> +#include "monitor/monitor.h" >> +#include "migration/qemu-file.h" >> +#include "sysemu/sysemu.h" >> +#include "block/block.h" >> +#include "qemu/sockets.h" >> +#include "migration/block.h" >> +#include "qemu/thread.h" >> +#include "qmp-commands.h" >> +#include "exec/memory.h" >> +#include "trace.h" >> +#include "qemu/osdep.h" >> + >> +//#define DEBUG_MIGRATION_LOCAL >> + >> +#ifdef DEBUG_MIGRATION_LOCAL >> +#define DPRINTF(fmt, ...) \ >> + do { printf("migration-local: " fmt, ## __VA_ARGS__); } while (0) >> +#else >> +#define DPRINTF(fmt, ...) \ >> + do { } while (0) >> +#endif >> + >> + >> +/************************************************************************ >> + * Outgoing part >> + */ >> + >> +static void *migration_local_thread(void *opaque) >> +{ >> + LocalMigState *s = opaque; >> + int ret; >> + ram_addr_t size; >> + >> + DPRINTF("Beginning savevm\n"); >> + >> + /* This will be replaced by new function qemu_save_local_state(). */ >> + ret = qemu_save_device_state(s->file); >> + qemu_fclose(s->file); >> + >> + if (ret < 0) { >> + s->state = MIG_STATE_ERROR; >> + return NULL; >> + } else { >> + /* XXX: The logic will be changed, need more work here. */ >> + s->state = MIG_STATE_COMPLETED; >> + >> + size = ram_bytes_total(); >> + ram_madvise_free(size); >> + } >> + >> + return NULL; >> +} >> + >> +void migrate_fd_connect_local(LocalMigState *s) >> +{ >> + s->state = MIG_STATE_ACTIVE; >> + trace_migrate_set_state(MIG_STATE_ACTIVE); >> + >> + qemu_thread_create(&s->thread, migration_local_thread, s, >> + QEMU_THREAD_JOINABLE); >> +} >> + >> +void qmp_localhost_migrate(const char *uri, Error **errp) >> +{ >> + const char *path; >> + Error *local_err = NULL; >> + int is_vm_running; >> + LocalMigState *s; >> + >> + is_vm_running = runstate_is_running(); >> + >> + /* Stop the VM first */ >> + if (is_vm_running) { >> + vm_stop(RUN_STATE_SAVE_VM); >> + } >> + >> + bdrv_flush_all(); >> + >> + s = g_malloc0(sizeof(LocalMigState)); >> + >> + /* Start outgoing migration by unix socket. */ >> + if (strstart(uri, "unix:", &path)) { >> + /* XXX. Creat a new unix_start_outgoing_migration_* is not necessary, >> + * just for the first step. This will be replaced by vmsplice >> + * mechanism. */ >> + unix_start_local_outgoing_migration(s, path, &local_err); >> + } else { >> + error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); >> + goto fail; >> + } >> + >> + if (local_err) { >> + s->state = MIG_STATE_ERROR; >> + error_propagate(errp, local_err); >> + goto fail; >> + } >> + >> +fail: >> + if (!is_vm_running) { >> + vm_start(); >> + } >> +} >> diff --git a/migration-unix.c b/migration-unix.c >> index 94b7022..a21262a 100644 >> --- a/migration-unix.c >> +++ b/migration-unix.c >> @@ -49,6 +49,19 @@ void unix_start_outgoing_migration(MigrationState *s, const char *path, Error ** >> unix_nonblocking_connect(path, unix_wait_for_connect, s, errp); >> } >> >> +void unix_start_local_outgoing_migration(LocalMigState *s, const char *path, Error **errp) >> +{ >> + s->fd = unix_connect(path, errp); >> + if (s->fd < 0) { >> + s->file = NULL; >> + /* There should be a fd_error_set function */ >> + s->state = MIG_STATE_ERROR; >> + } else { >> + s->file = qemu_fopen_socket(s->fd, "wb"); >> + migrate_fd_connect_local(s); >> + } >> +} >> + > Skipping most of the above as it's a work-in-progress. > >> static void unix_accept_incoming_migration(void *opaque) >> { >> struct sockaddr_un addr; >> diff --git a/qapi-schema.json b/qapi-schema.json >> index 5ad6894..2890f70 100644 >> --- a/qapi-schema.json >> +++ b/qapi-schema.json >> @@ -648,6 +648,20 @@ >> { 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']} >> >> ## >> +# @localhost-migrate >> +# >> +# Migrates the current running guest to another localhost VM. >> +# >> +# @uri: the Uniform Resource Identifier of the destination VM >> +# >> +# Returns: nothing on success >> +# >> +# Since: 1.7 >> +## >> +{ 'command': 'localhost-migrate', >> + 'data': {'uri': 'str'} } > I suspect we should just do this as a flag to the existing migration > command. Perhaps we could even just use a capability. Yeah, I had thought about this by adding a flag to the existing migration command like: migrate -l for localhost migration. This is just for a easy start. > > Regards, > > Anthony Liguori > >> + >> +## >> # @MouseInfo: >> # >> # Information about a mouse device. >> diff --git a/qmp-commands.hx b/qmp-commands.hx >> index 8cea5e5..bf6d042 100644 >> --- a/qmp-commands.hx >> +++ b/qmp-commands.hx >> @@ -787,6 +787,28 @@ Example: >> EQMP >> >> { >> + .name = "localhost-migrate", >> + .args_type = "uri:s", >> + .mhandler.cmd_new = qmp_marshal_input_localhost_migrate, >> + }, >> + >> +SQMP >> +localhost-migrate >> + >> +Migrate VM in localhost. >> + >> +Arguments: >> + >> +- "uri": Destination URI (json-string) >> + >> +Example: >> + >> +-> { "execute": "localhost-migrate", "arguments": { "uri": "/tmp/foo" } >> +<- { "return": {} } >> + >> +EQMP >> + >> + { >> .name = "dump-guest-memory", >> .args_type = "paging:b,protocol:s,begin:i?,end:i?", >> .params = "-p protocol [begin] [length]", >> -- >> 1.7.7.6 -- Lei