Allow a notifier to be added for multiple migration modes. To allow a notifier to appear on multiple per-node lists, use a generic list type. We can no longer use NotifierWithReturnList, because it shoe horns the notifier onto a single list.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/migration/misc.h | 12 ++++++++++ migration/migration.c | 60 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/include/migration/misc.h b/include/migration/misc.h index a261f99..592b930 100644 --- a/include/migration/misc.h +++ b/include/migration/misc.h @@ -95,7 +95,19 @@ void migration_add_notifier(NotifierWithReturn *notify, void migration_add_notifier_mode(NotifierWithReturn *notify, MigrationNotifyFunc func, MigMode mode); +/* + * Same as migration_add_notifier, but applies to all @mode in the argument + * list. The list is terminated by -1 or MIG_MODE_ALL. For the latter, + * the notifier is added for all modes. + */ +void migration_add_notifier_modes(NotifierWithReturn *notify, + MigrationNotifyFunc func, MigMode mode, ...); + +/* + * Remove a notifier from all modes. + */ void migration_remove_notifier(NotifierWithReturn *notify); + void migration_file_set_error(int ret, Error *err); /* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */ diff --git a/migration/migration.c b/migration/migration.c index 49d1e7d..271c521 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -74,11 +74,7 @@ #define INMIGRATE_DEFAULT_EXIT_ON_ERROR true -static NotifierWithReturnList migration_state_notifiers[] = { - NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_NORMAL), - NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_CPR_REBOOT), - NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_CPR_TRANSFER), -}; +static GSList *migration_state_notifiers[MIG_MODE__MAX]; /* Messages sent on the return path from destination to source */ enum mig_rp_message_type { @@ -1666,23 +1662,51 @@ void migration_cancel(void) } } +static int get_modes(MigMode mode, va_list ap); + +static void add_notifiers(NotifierWithReturn *notify, int modes) +{ + for (MigMode mode = 0; mode < MIG_MODE__MAX; mode++) { + if (modes & BIT(mode)) { + migration_state_notifiers[mode] = + g_slist_prepend(migration_state_notifiers[mode], notify); + } + } +} + +void migration_add_notifier_modes(NotifierWithReturn *notify, + MigrationNotifyFunc func, MigMode mode, ...) +{ + int modes; + va_list ap; + + va_start(ap, mode); + modes = get_modes(mode, ap); + va_end(ap); + + notify->notify = (NotifierWithReturnFunc)func; + add_notifiers(notify, modes); +} + void migration_add_notifier_mode(NotifierWithReturn *notify, MigrationNotifyFunc func, MigMode mode) { - notify->notify = (NotifierWithReturnFunc)func; - notifier_with_return_list_add(&migration_state_notifiers[mode], notify); + migration_add_notifier_modes(notify, func, mode, -1); } void migration_add_notifier(NotifierWithReturn *notify, MigrationNotifyFunc func) { - migration_add_notifier_mode(notify, func, MIG_MODE_NORMAL); + migration_add_notifier_modes(notify, func, MIG_MODE_NORMAL, -1); } void migration_remove_notifier(NotifierWithReturn *notify) { if (notify->notify) { - notifier_with_return_remove(notify); + for (MigMode mode = 0; mode < MIG_MODE__MAX; mode++) { + migration_blockers[mode] = + g_slist_remove(migration_state_notifiers[mode], notify); + } notify->notify = NULL; } } @@ -1692,13 +1716,23 @@ int migration_call_notifiers(MigrationState *s, MigrationEventType type, { MigMode mode = s->parameters.mode; MigrationEvent e; + NotifierWithReturn *notifier; + GSList *elem, *next; int ret; e.type = type; - ret = notifier_with_return_list_notify(&migration_state_notifiers[mode], - &e, errp); - assert(!ret || type == MIG_EVENT_PRECOPY_SETUP); - return ret; + + for (elem = migration_state_notifiers[mode]; elem; elem = next) { + next = elem->next; + notifier = (NotifierWithReturn *)elem->data; + ret = notifier->notify(notifier, &e, errp); + if (ret) { + assert(type == MIG_EVENT_PRECOPY_SETUP); + return ret; + } + } + + return 0; } bool migration_has_failed(MigrationState *s) -- 1.8.3.1