Message ID | 1501229198-30588-26-git-send-email-peterx@redhat.com |
---|---|
State | New |
Headers | show |
* Peter Xu (peterx@redhat.com) wrote: > This is hook function to be called when a postcopy migration wants to > resume from a failure. For each module, it should provide its own > recovery logic before we switch to the postcopy-active state. Would a change-state handler be able to do this, or perhaps the notifier chain I have in my shared memory world: https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg06459.html Dave > Signed-off-by: Peter Xu <peterx@redhat.com> > --- > include/migration/register.h | 2 ++ > migration/migration.c | 20 +++++++++++++++++++- > migration/savevm.c | 25 +++++++++++++++++++++++++ > migration/savevm.h | 1 + > migration/trace-events | 1 + > 5 files changed, 48 insertions(+), 1 deletion(-) > > diff --git a/include/migration/register.h b/include/migration/register.h > index a0f1edd..b669362 100644 > --- a/include/migration/register.h > +++ b/include/migration/register.h > @@ -41,6 +41,8 @@ typedef struct SaveVMHandlers { > LoadStateHandler *load_state; > int (*load_setup)(QEMUFile *f, void *opaque); > int (*load_cleanup)(void *opaque); > + /* Called when postcopy migration wants to resume from failure */ > + int (*resume_prepare)(MigrationState *s, void *opaque); > } SaveVMHandlers; > > int register_savevm_live(DeviceState *dev, > diff --git a/migration/migration.c b/migration/migration.c > index 62f91ce..6cb0ad3 100644 > --- a/migration/migration.c > +++ b/migration/migration.c > @@ -2150,7 +2150,25 @@ static bool postcopy_should_start(MigrationState *s) > /* Return zero if success, or <0 for error */ > static int postcopy_do_resume(MigrationState *s) > { > - /* TODO: do the resume logic */ > + int ret; > + > + /* > + * Call all the resume_prepare() hooks, so that modules can be > + * ready for the migration resume. > + */ > + ret = qemu_savevm_state_resume_prepare(s); > + if (ret) { > + error_report("%s: resume_prepare() failure detected: %d", > + __func__, ret); > + return ret; > + } > + > + /* > + * TODO: handshake with dest using MIG_CMD_RESUME, > + * MIG_RP_MSG_RESUME_ACK, then switch source state to > + * "postcopy-active" > + */ > + > return 0; > } > > diff --git a/migration/savevm.c b/migration/savevm.c > index 02a67ac..08a4712 100644 > --- a/migration/savevm.c > +++ b/migration/savevm.c > @@ -1004,6 +1004,31 @@ void qemu_savevm_state_setup(QEMUFile *f) > } > } > > +int qemu_savevm_state_resume_prepare(MigrationState *s) > +{ > + SaveStateEntry *se; > + int ret; > + > + trace_savevm_state_resume_prepare(); > + > + QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { > + if (!se->ops || !se->ops->resume_prepare) { > + continue; > + } > + if (se->ops && se->ops->is_active) { > + if (!se->ops->is_active(se->opaque)) { > + continue; > + } > + } > + ret = se->ops->resume_prepare(s, se->opaque); > + if (ret < 0) { > + return ret; > + } > + } > + > + return 0; > +} > + > /* > * this function has three return values: > * negative: there was one error, and we have -errno. > diff --git a/migration/savevm.h b/migration/savevm.h > index a5f3879..3193f04 100644 > --- a/migration/savevm.h > +++ b/migration/savevm.h > @@ -31,6 +31,7 @@ > > bool qemu_savevm_state_blocked(Error **errp); > void qemu_savevm_state_setup(QEMUFile *f); > +int qemu_savevm_state_resume_prepare(MigrationState *s); > void qemu_savevm_state_header(QEMUFile *f); > int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy); > void qemu_savevm_state_cleanup(void); > diff --git a/migration/trace-events b/migration/trace-events > index 0b43fec..0fb2d1e 100644 > --- a/migration/trace-events > +++ b/migration/trace-events > @@ -37,6 +37,7 @@ savevm_send_postcopy_run(void) "" > savevm_send_postcopy_resume(void) "" > savevm_send_recv_bitmap(char *name) "%s" > savevm_state_setup(void) "" > +savevm_state_resume_prepare(void) "" > savevm_state_header(void) "" > savevm_state_iterate(void) "" > savevm_state_cleanup(void) "" > -- > 2.7.4 > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
On Thu, Aug 03, 2017 at 12:38:01PM +0100, Dr. David Alan Gilbert wrote: > * Peter Xu (peterx@redhat.com) wrote: > > This is hook function to be called when a postcopy migration wants to > > resume from a failure. For each module, it should provide its own > > recovery logic before we switch to the postcopy-active state. > > Would a change-state handler be able to do this, We don't have such a change-state handler, do we? > or perhaps > the notifier chain I have in my shared memory world: > https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg06459.html The postcopy_notify() can do this as well. I just need a way to hook up all the system modules for migration. In our case, it's only RAM, but I think maybe one day we need block support. So as long as the mechanism (either current SaveVMHandlers interface, or postcopy_notify) can do the notification, IMHO it'll be fine.
diff --git a/include/migration/register.h b/include/migration/register.h index a0f1edd..b669362 100644 --- a/include/migration/register.h +++ b/include/migration/register.h @@ -41,6 +41,8 @@ typedef struct SaveVMHandlers { LoadStateHandler *load_state; int (*load_setup)(QEMUFile *f, void *opaque); int (*load_cleanup)(void *opaque); + /* Called when postcopy migration wants to resume from failure */ + int (*resume_prepare)(MigrationState *s, void *opaque); } SaveVMHandlers; int register_savevm_live(DeviceState *dev, diff --git a/migration/migration.c b/migration/migration.c index 62f91ce..6cb0ad3 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -2150,7 +2150,25 @@ static bool postcopy_should_start(MigrationState *s) /* Return zero if success, or <0 for error */ static int postcopy_do_resume(MigrationState *s) { - /* TODO: do the resume logic */ + int ret; + + /* + * Call all the resume_prepare() hooks, so that modules can be + * ready for the migration resume. + */ + ret = qemu_savevm_state_resume_prepare(s); + if (ret) { + error_report("%s: resume_prepare() failure detected: %d", + __func__, ret); + return ret; + } + + /* + * TODO: handshake with dest using MIG_CMD_RESUME, + * MIG_RP_MSG_RESUME_ACK, then switch source state to + * "postcopy-active" + */ + return 0; } diff --git a/migration/savevm.c b/migration/savevm.c index 02a67ac..08a4712 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1004,6 +1004,31 @@ void qemu_savevm_state_setup(QEMUFile *f) } } +int qemu_savevm_state_resume_prepare(MigrationState *s) +{ + SaveStateEntry *se; + int ret; + + trace_savevm_state_resume_prepare(); + + QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { + if (!se->ops || !se->ops->resume_prepare) { + continue; + } + if (se->ops && se->ops->is_active) { + if (!se->ops->is_active(se->opaque)) { + continue; + } + } + ret = se->ops->resume_prepare(s, se->opaque); + if (ret < 0) { + return ret; + } + } + + return 0; +} + /* * this function has three return values: * negative: there was one error, and we have -errno. diff --git a/migration/savevm.h b/migration/savevm.h index a5f3879..3193f04 100644 --- a/migration/savevm.h +++ b/migration/savevm.h @@ -31,6 +31,7 @@ bool qemu_savevm_state_blocked(Error **errp); void qemu_savevm_state_setup(QEMUFile *f); +int qemu_savevm_state_resume_prepare(MigrationState *s); void qemu_savevm_state_header(QEMUFile *f); int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy); void qemu_savevm_state_cleanup(void); diff --git a/migration/trace-events b/migration/trace-events index 0b43fec..0fb2d1e 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -37,6 +37,7 @@ savevm_send_postcopy_run(void) "" savevm_send_postcopy_resume(void) "" savevm_send_recv_bitmap(char *name) "%s" savevm_state_setup(void) "" +savevm_state_resume_prepare(void) "" savevm_state_header(void) "" savevm_state_iterate(void) "" savevm_state_cleanup(void) ""
This is hook function to be called when a postcopy migration wants to resume from a failure. For each module, it should provide its own recovery logic before we switch to the postcopy-active state. Signed-off-by: Peter Xu <peterx@redhat.com> --- include/migration/register.h | 2 ++ migration/migration.c | 20 +++++++++++++++++++- migration/savevm.c | 25 +++++++++++++++++++++++++ migration/savevm.h | 1 + migration/trace-events | 1 + 5 files changed, 48 insertions(+), 1 deletion(-)