Fabiano Rosas <[email protected]> writes:

> Add capabilities to MigrationParameters. This structure will hold all
> migration options. Capabilities will go away in the next patch.
>
> From this point on, both QMP and HMP versions of
> migrate-set-parameters and query-migrate-parameters gain the ability
> to work with capabilities.
>
> With MigrationParameters now having members for each capability, the
> migration capabilities commands (query-migrate-capabilities,
> migrate-set-capabilities) will soon be deprecated. Add a set of
> helpers to convert between the old MigrationCapability representation
> and the new representation as members of MigrationParameters.
>
> Acked-by: Peter Xu <[email protected]>
> Signed-off-by: Fabiano Rosas <[email protected]>
> ---
>  migration/migration.c |   8 +++
>  migration/options.c   | 127 ++++++++++++++++++++++++++++++++++++++++++
>  migration/options.h   |   5 ++
>  qapi/migration.json   | 118 ++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 255 insertions(+), 3 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index dab282dd2f3..c8e7e86ea05 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -4086,6 +4086,14 @@ static bool migration_object_check(MigrationState *ms, 
> Error **errp)
>          return false;
>      }
>  
> +    /*
> +     * FIXME: Temporarily while -global capabilties are still using
> +     * s->capabilities. Will be gone by the end of the series.
> +     */
> +    for (int i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
> +        migrate_capability_set_compat(&ms->parameters, i, 
> ms->capabilities[i]);
> +    }
> +
>      return migrate_caps_check(old_caps, ms->capabilities, errp);
>  }
>  
> diff --git a/migration/options.c b/migration/options.c
> index f988b181f0e..7c638e204a1 100644
> --- a/migration/options.c
> +++ b/migration/options.c
> @@ -778,6 +778,108 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, 
> Error **errp)
>      return true;
>  }
>  
> +static bool *migrate_capability_get_addr(MigrationParameters *params, int i)
> +{
> +    bool *cap_addr = NULL;
> +
> +    switch (i) {
> +    case MIGRATION_CAPABILITY_XBZRLE:
> +        cap_addr = &params->xbzrle;
> +        break;
> +    case MIGRATION_CAPABILITY_RDMA_PIN_ALL:
> +        cap_addr = &params->rdma_pin_all;
> +        break;
> +    case MIGRATION_CAPABILITY_AUTO_CONVERGE:
> +        cap_addr = &params->auto_converge;
> +        break;
> +    case MIGRATION_CAPABILITY_EVENTS:
> +        cap_addr = &params->events;
> +        break;
> +    case MIGRATION_CAPABILITY_POSTCOPY_RAM:
> +        cap_addr = &params->postcopy_ram;
> +        break;
> +    case MIGRATION_CAPABILITY_X_COLO:
> +        cap_addr = &params->x_colo;
> +        break;
> +    case MIGRATION_CAPABILITY_RELEASE_RAM:
> +        cap_addr = &params->release_ram;
> +        break;
> +    case MIGRATION_CAPABILITY_RETURN_PATH:
> +        cap_addr = &params->return_path;
> +        break;
> +    case MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER:
> +        cap_addr = &params->pause_before_switchover;
> +        break;
> +    case MIGRATION_CAPABILITY_MULTIFD:
> +        cap_addr = &params->multifd;
> +        break;
> +    case MIGRATION_CAPABILITY_DIRTY_BITMAPS:
> +        cap_addr = &params->dirty_bitmaps;
> +        break;
> +    case MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME:
> +        cap_addr = &params->postcopy_blocktime;
> +        break;
> +    case MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE:
> +        cap_addr = &params->late_block_activate;
> +        break;
> +    case MIGRATION_CAPABILITY_X_IGNORE_SHARED:
> +        cap_addr = &params->x_ignore_shared;
> +        break;
> +    case MIGRATION_CAPABILITY_VALIDATE_UUID:
> +        cap_addr = &params->validate_uuid;
> +        break;
> +    case MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT:
> +        cap_addr = &params->background_snapshot;
> +        break;
> +    case MIGRATION_CAPABILITY_ZERO_COPY_SEND:
> +        cap_addr = &params->zero_copy_send;
> +        break;
> +    case MIGRATION_CAPABILITY_POSTCOPY_PREEMPT:
> +        cap_addr = &params->postcopy_preempt;
> +        break;
> +    case MIGRATION_CAPABILITY_SWITCHOVER_ACK:
> +        cap_addr = &params->switchover_ack;
> +        break;
> +    case MIGRATION_CAPABILITY_DIRTY_LIMIT:
> +        cap_addr = &params->dirty_limit;
> +        break;
> +    case MIGRATION_CAPABILITY_MAPPED_RAM:
> +        cap_addr = &params->mapped_ram;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }

I'd use an array instead of a switch.  Matter of taste.

> +
> +    return cap_addr;
> +}
> +
> +/* Compatibility for code that reads capabilities in a loop */
> +bool migrate_capability_get_compat(MigrationParameters *params, int i)
> +{
> +    return *(migrate_capability_get_addr(params, i));
> +}
> +
> +/* Compatibility for code that writes capabilities in a loop */
> +void migrate_capability_set_compat(MigrationParameters *params, int i, bool 
> val)
> +{
> +    *(migrate_capability_get_addr(params, i)) = val;
> +}
> +
> +/*
> + * Set capabilities for compatibility with the old
> + * migrate-set-capabilities command.
> + */
> +void migrate_capabilities_set_compat(MigrationParameters *params,
> +                                     MigrationCapabilityStatusList *caps)
> +{
> +    MigrationCapabilityStatusList *cap;
> +
> +    for (cap = caps; cap; cap = cap->next) {
> +        migrate_capability_set_compat(params, cap->value->capability,
> +                                      cap->value->state);
> +    }
> +}
> +
>  MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
>  {
>      MigrationCapabilityStatusList *head = NULL, **tail = &head;
> @@ -819,6 +921,8 @@ void 
> qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
>      for (cap = params; cap; cap = cap->next) {
>          s->capabilities[cap->value->capability] = cap->value->state;
>      }
> +
> +    migrate_capabilities_set_compat(&s->parameters, params);
>  }
>  
>  /* parameters */
> @@ -1141,6 +1245,15 @@ static void 
> migrate_mark_all_params_present(MigrationParameters *p)
>          &p->has_x_vcpu_dirty_limit_period, &p->has_vcpu_dirty_limit,
>          &p->has_mode, &p->has_zero_page_detection, &p->has_direct_io,
>          &p->has_x_rdma_chunk_size, &p->has_cpr_exec_command,
> +        &p->has_xbzrle, &p->has_rdma_pin_all,
> +        &p->has_auto_converge, &p->has_events,
> +        &p->has_postcopy_ram, &p->has_x_colo, &p->has_release_ram,
> +        &p->has_return_path, &p->has_pause_before_switchover, 
> &p->has_multifd,
> +        &p->has_dirty_bitmaps, &p->has_postcopy_blocktime,
> +        &p->has_late_block_activate, &p->has_x_ignore_shared,
> +        &p->has_validate_uuid, &p->has_background_snapshot,
> +        &p->has_zero_copy_send, &p->has_postcopy_preempt,
> +        &p->has_switchover_ack, &p->has_dirty_limit, &p->has_mapped_ram,
>      };
>  
>      for (int i = 0; i < ARRAY_SIZE(has_fields); i++) {
> @@ -1465,6 +1578,20 @@ void qmp_migrate_set_parameters(MigrationParameters 
> *input, Error **errp)
>      tls_opt_to_str(input->tls_hostname);
>      tls_opt_to_str(input->tls_authz);
>  
> +    /*
> +     * FIXME: Temporarily while migrate_caps_check is not
> +     * converted to look at s->parameters. Will be gone the end of
> +     * the series.
> +     */
> +    bool new_caps[MIGRATION_CAPABILITY__MAX] = { 0 };
> +    for (int i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
> +        new_caps[i] = migrate_capability_get_compat(cur, i);
> +    }
> +    if (!migrate_caps_check(migrate_get_current()->capabilities, new_caps,
> +                            errp)) {
> +        return;
> +    }
> +
>      /* merge input on top of current */
>      if (!migrate_params_merge(cur, input, &new, errp)) {
>          return;
> diff --git a/migration/options.h b/migration/options.h
> index c7da2d0b5b0..eedd1aa1f93 100644
> --- a/migration/options.h
> +++ b/migration/options.h
> @@ -94,4 +94,9 @@ uint64_t migrate_rdma_chunk_size(void);
>  bool migrate_params_check(MigrationParameters *params, Error **errp);
>  void migrate_params_init(MigrationParameters *params);
>  bool migrate_params_free(MigrationParameters *params, Error **errp);
> +bool migrate_capability_get_compat(MigrationParameters *params, int i);
> +void migrate_capability_set_compat(MigrationParameters *params, int i,
> +                                   bool val);
> +void migrate_capabilities_set_compat(MigrationParameters *params,
> +                                     MigrationCapabilityStatusList *caps);
>  #endif
> diff --git a/qapi/migration.json b/qapi/migration.json
> index 78c6e933cf1..7952ef44db9 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -976,10 +976,101 @@
>  #     Must be set to the same value on both source and destination
>  #     before migration starts.  (Since 11.1)
>  #
> +# @xbzrle: Migration supports xbzrle (Xor Based Zero Run Length
> +#     Encoding).  This feature allows us to minimize migration traffic
> +#     for certain work loads, by sending compressed difference of the
> +#     pages
> +#
> +# @rdma-pin-all: Controls whether or not the entire VM memory
> +#     footprint is mlock()'d on demand or all at once.  Refer to
> +#     docs/rdma.txt for usage.  Disabled by default.  (since 2.0)
> +#
> +# @events: Generate events for each migration state change.
> +#     (since 2.4)
> +#
> +# @auto-converge: If enabled, QEMU will automatically throttle down
> +#     the guest to speed up convergence of RAM migration.  (since 1.6)
> +#
> +# @postcopy-ram: Start executing on the migration target before all of
> +#     RAM has been migrated, pulling the remaining pages along as
> +#     needed.  The capacity must have the same setting on both source
> +#     and target or migration will not even start.  **Note:** If the
> +#     migration fails during postcopy the VM will fail.  (since 2.6)
> +#
> +# @x-colo: If enabled, migration will never end, and the state of the
> +#     VM on the primary side will be migrated continuously to the VM
> +#     on secondary side, this process is called COarse-Grain LOck
> +#     Stepping (COLO) for Non-stop Service.  (since 2.8)
> +#
> +# @release-ram: If enabled, QEMU will free the migrated ram pages on
> +#     the source during postcopy-ram migration.  (since 2.9)
> +#
> +# @return-path: If enabled, migration will use the return path even
> +#     for precopy.  (since 2.10)
> +#
> +# @pause-before-switchover: Pause outgoing migration before
> +#     serialising device state and before disabling block IO.
> +#     (since 2.11)
> +#
> +# @multifd: Use more than one fd for migration.  (since 4.0)
> +#
> +# @dirty-bitmaps: If enabled, QEMU will migrate named dirty bitmaps.
> +#     (since 2.12)
> +#
> +# @postcopy-blocktime: Calculate downtime for postcopy live migration.
> +#     (since 3.0)
> +#
> +# @late-block-activate: If enabled, the destination will not activate
> +#     block devices (and thus take locks) immediately at the end of
> +#     migration.  (since 3.0)
> +#
> +# @x-ignore-shared: If enabled, QEMU will not migrate shared memory
> +#     that is accessible on the destination machine.  (since 4.0)
> +#
> +# @validate-uuid: Send the UUID of the source to allow the destination
> +#     to ensure it is the same.  (since 4.2)
> +#
> +# @background-snapshot: If enabled, the migration stream will be a
> +#     snapshot of the VM exactly at the point when the migration
> +#     procedure starts.  The VM RAM is saved with running VM.
> +#     (since 6.0)
> +#
> +# @zero-copy-send: Controls behavior on sending memory pages on
> +#     migration.  When true, enables a zero-copy mechanism for sending
> +#     memory pages, if host supports it.  Requires that QEMU be
> +#     permitted to use locked memory for guest RAM pages.  (since 7.1)
> +#
> +# @postcopy-preempt: If enabled, the migration process will allow
> +#     postcopy requests to preempt precopy stream, so postcopy
> +#     requests will be handled faster.  This is a performance feature
> +#     and should not affect the correctness of postcopy migration.
> +#     (since 7.1)
> +#
> +# @switchover-ack: If enabled, migration will not stop the source VM
> +#     and complete the migration until an ACK is received from the
> +#     destination that it's OK to do so.  Exactly when this ACK is
> +#     sent depends on the migrated devices that use this feature.  For
> +#     example, a device can use it to make sure some of its data is
> +#     sent and loaded in the destination before doing switchover.
> +#     This can reduce downtime if devices that support this capability
> +#     are present.  'return-path' capability must be enabled to use
> +#     it.  (since 8.1)
> +#
> +# @dirty-limit: If enabled, migration will throttle vCPUs as needed to
> +#     keep their dirty page rate within @vcpu-dirty-limit.  This can
> +#     improve responsiveness of large guests during live migration,
> +#     and can result in more stable read performance.  Requires KVM
> +#     with accelerator property "dirty-ring-size" set.  (Since 8.1)
> +#
> +# @mapped-ram: Migrate using fixed offsets in the migration file for
> +#     each RAM page.  Requires a migration URI that supports seeking,
> +#     such as a file.  (since 9.0)
> +#
>  # Features:
>  #
> -# @unstable: Members @x-checkpoint-delay, @x-rdma-chunk-size, and
> -#     @x-vcpu-dirty-limit-period are experimental.
> +# @unstable: Members @x-checkpoint-delay, @x-vcpu-dirty-limit-period,
> +#     @x-colo, @x-ignore-shared and @x-rdma-chunk-size are
> +#     experimental.

This isn't a clean copy from MigrationCapability.  Why?

>  #
>  # Since: 2.4
>  ##
> @@ -1017,7 +1108,28 @@
>              '*direct-io': 'bool',
>              '*x-rdma-chunk-size': { 'type': 'uint64',
>                                      'features': [ 'unstable' ] },
> -            '*cpr-exec-command': [ 'str' ]} }
> +            '*cpr-exec-command': [ 'str' ],
> +            '*xbzrle': 'bool',
> +            '*rdma-pin-all': 'bool',
> +            '*auto-converge': 'bool',
> +            '*events': 'bool',
> +            '*postcopy-ram': 'bool',
> +            '*x-colo': { 'type': 'bool', 'features': [ 'unstable' ] },
> +            '*release-ram': 'bool',
> +            '*return-path': 'bool',
> +            '*pause-before-switchover': 'bool',
> +            '*multifd': 'bool',
> +            '*dirty-bitmaps': 'bool',
> +            '*postcopy-blocktime': 'bool',
> +            '*late-block-activate': 'bool',
> +            '*x-ignore-shared': { 'type': 'bool', 'features': [ 'unstable' ] 
> },
> +            '*validate-uuid': 'bool',
> +            '*background-snapshot': 'bool',
> +            '*zero-copy-send': 'bool',
> +            '*postcopy-preempt': 'bool',
> +            '*switchover-ack': 'bool',
> +            '*dirty-limit': 'bool',
> +            '*mapped-ram': 'bool' } }
>  
>  ##
>  # @query-migrate-parameters:


Reply via email to