diff mbox series

[1/3] migration: Add x-validate-uuid capability

Message ID 20190827120221.15725-2-yury-kotov@yandex-team.ru (mailing list archive)
State New, archived
Headers show
Series UUID validation during migration | expand

Commit Message

Yury Kotov Aug. 27, 2019, 12:02 p.m. UTC
This capability realizes simple source validation by UUID.
It's useful for live migration between hosts.

Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru>
---
 migration/migration.c |  9 +++++++++
 migration/migration.h |  1 +
 migration/savevm.c    | 45 +++++++++++++++++++++++++++++++++++++++++++
 qapi/migration.json   |  5 ++++-
 4 files changed, 59 insertions(+), 1 deletion(-)

Comments

Eric Blake Aug. 27, 2019, 2:01 p.m. UTC | #1
On 8/27/19 7:02 AM, Yury Kotov wrote:
> This capability realizes simple source validation by UUID.
> It's useful for live migration between hosts.
> 
> Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru>
> ---
>  migration/migration.c |  9 +++++++++
>  migration/migration.h |  1 +
>  migration/savevm.c    | 45 +++++++++++++++++++++++++++++++++++++++++++
>  qapi/migration.json   |  5 ++++-
>  4 files changed, 59 insertions(+), 1 deletion(-)

Any reason why this is marked experimental?  It seems useful enough that
we could probably just add it as a fully-supported feature (dropping the
x- prefix) - but I'll leave that up to the migration maintainers.

In fact, do we even need this to be a tunable feature?  Why not just
always enable it?  As long as the UUID is sent in a way that new->old
doesn't break the old qemu from receiving the migration stream, and that
old->new copes with UUID being absent, then new->new will always benefit
from the additional safety check.

> +++ b/qapi/migration.json
> @@ -415,6 +415,9 @@
>  #
>  # @x-ignore-shared: If enabled, QEMU will not migrate shared memory (since 4.0)
>  #
> +# @x-validate-uuid: Check whether the UUID is the same on both sides or not.
> +#                   (since 4.2)

Maybe:

@x-validate-uuid: Send the UUID of the source to allow the destination
to ensure it is the same.

if we even need a tunable capability.

> +#
>  # Since: 1.2
>  ##
>  { 'enum': 'MigrationCapability',
> @@ -422,7 +425,7 @@
>             'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
>             'block', 'return-path', 'pause-before-switchover', 'multifd',
>             'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
> -           'x-ignore-shared' ] }
> +           'x-ignore-shared', 'x-validate-uuid' ] }
>  
>  ##
>  # @MigrationCapabilityStatus:
>
Yury Kotov Aug. 27, 2019, 3:36 p.m. UTC | #2
27.08.2019, 17:02, "Eric Blake" <eblake@redhat.com>:
> On 8/27/19 7:02 AM, Yury Kotov wrote:
>>  This capability realizes simple source validation by UUID.
>>  It's useful for live migration between hosts.
>>
>>  Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru>
>>  ---
>>   migration/migration.c | 9 +++++++++
>>   migration/migration.h | 1 +
>>   migration/savevm.c | 45 +++++++++++++++++++++++++++++++++++++++++++
>>   qapi/migration.json | 5 ++++-
>>   4 files changed, 59 insertions(+), 1 deletion(-)
>
> Any reason why this is marked experimental? It seems useful enough that
> we could probably just add it as a fully-supported feature (dropping the
> x- prefix) - but I'll leave that up to the migration maintainers.
>

I thought that all new capabilities have x- prefix... May be it's really
unnecessary here, I'm not sure.

> In fact, do we even need this to be a tunable feature? Why not just
> always enable it? As long as the UUID is sent in a way that new->old
> doesn't break the old qemu from receiving the migration stream, and that
> old->new copes with UUID being absent, then new->new will always benefit
> from the additional safety check.
>

In such case we couldn't migrate from e.g. 4.2 to 3.1
If it's not a problem then we can always use it.

>>  +++ b/qapi/migration.json
>>  @@ -415,6 +415,9 @@
>>   #
>>   # @x-ignore-shared: If enabled, QEMU will not migrate shared memory (since 4.0)
>>   #
>>  +# @x-validate-uuid: Check whether the UUID is the same on both sides or not.
>>  +# (since 4.2)
>
> Maybe:
>
> @x-validate-uuid: Send the UUID of the source to allow the destination
> to ensure it is the same.
>
> if we even need a tunable capability.
>

Yes, it sounds better. Thanks!

>>  +#
>>   # Since: 1.2
>>   ##
>>   { 'enum': 'MigrationCapability',
>>  @@ -422,7 +425,7 @@
>>              'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
>>              'block', 'return-path', 'pause-before-switchover', 'multifd',
>>              'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
>>  - 'x-ignore-shared' ] }
>>  + 'x-ignore-shared', 'x-validate-uuid' ] }
>>
>>   ##
>>   # @MigrationCapabilityStatus:
>
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc. +1-919-301-3226
> Virtualization: qemu.org | libvirt.org

Regards,
Yury
Eric Blake Aug. 27, 2019, 4:18 p.m. UTC | #3
On 8/27/19 10:36 AM, Yury Kotov wrote:
> 27.08.2019, 17:02, "Eric Blake" <eblake@redhat.com>:
>> On 8/27/19 7:02 AM, Yury Kotov wrote:
>>>  This capability realizes simple source validation by UUID.
>>>  It's useful for live migration between hosts.
>>>

>>
>> Any reason why this is marked experimental? It seems useful enough that
>> we could probably just add it as a fully-supported feature (dropping the
>> x- prefix) - but I'll leave that up to the migration maintainers.
>>
> 
> I thought that all new capabilities have x- prefix... May be it's really
> unnecessary here, I'm not sure.

New features that need some testing or possible changes to behavior need
x- to mark them as experimental, so we can make those changes without
worrying about breaking back-compat.  But new features that are outright
useful and presumably in their final form, with no further
experimentation needed, can skip going through an x- phase.

> 
>> In fact, do we even need this to be a tunable feature? Why not just
>> always enable it? As long as the UUID is sent in a way that new->old
>> doesn't break the old qemu from receiving the migration stream, and that
>> old->new copes with UUID being absent, then new->new will always benefit
>> from the additional safety check.
>>
> 
> In such case we couldn't migrate from e.g. 4.2 to 3.1

I don't know the migration format enough to know if there is a way for
4.2 to unconditionally send a UUID as a subsection such that a receiving
3.1 will ignore the unknown subsection. If so, then you don't need a
knob; if not, then you need something to say whether sending the
subsection is safe (perhaps default on in new machine types, but default
off for machine types that might still be migrated back to 3.1).  That's
where I'm hoping the migration experts will chime in.
Dr. David Alan Gilbert Sept. 3, 2019, 11:25 a.m. UTC | #4
* Eric Blake (eblake@redhat.com) wrote:
> On 8/27/19 10:36 AM, Yury Kotov wrote:
> > 27.08.2019, 17:02, "Eric Blake" <eblake@redhat.com>:
> >> On 8/27/19 7:02 AM, Yury Kotov wrote:
> >>>  This capability realizes simple source validation by UUID.
> >>>  It's useful for live migration between hosts.
> >>>
> 
> >>
> >> Any reason why this is marked experimental? It seems useful enough that
> >> we could probably just add it as a fully-supported feature (dropping the
> >> x- prefix) - but I'll leave that up to the migration maintainers.
> >>
> > 
> > I thought that all new capabilities have x- prefix... May be it's really
> > unnecessary here, I'm not sure.
> 
> New features that need some testing or possible changes to behavior need
> x- to mark them as experimental, so we can make those changes without
> worrying about breaking back-compat.  But new features that are outright
> useful and presumably in their final form, with no further
> experimentation needed, can skip going through an x- phase.
> 
> > 
> >> In fact, do we even need this to be a tunable feature? Why not just
> >> always enable it? As long as the UUID is sent in a way that new->old
> >> doesn't break the old qemu from receiving the migration stream, and that
> >> old->new copes with UUID being absent, then new->new will always benefit
> >> from the additional safety check.
> >>
> > 
> > In such case we couldn't migrate from e.g. 4.2 to 3.1
> 
> I don't know the migration format enough to know if there is a way for
> 4.2 to unconditionally send a UUID as a subsection such that a receiving
> 3.1 will ignore the unknown subsection. If so, then you don't need a
> knob; if not, then you need something to say whether sending the
> subsection is safe (perhaps default on in new machine types, but default
> off for machine types that might still be migrated back to 3.1).  That's
> where I'm hoping the migration experts will chime in.

Right; the migration format can't ignore chunks of data; so it does need
to know somehow; the choice is either a capability or wiring it to the
machine type;  my preference is to wire it to the machine type; the
arguments are:
    a) Machine type
       Pro: libvirt doesn't need to do anything
       Con: It doesn't protect old machine types
            It's not really part of the guest state

    b) Capability
       Pro: Works on all machine types
       Con: Libvirt needs to enable it

So, no strong preference but I think I prefer (a).

Dave

> -- 
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3226
> Virtualization:  qemu.org | libvirt.org
> 



--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
Dr. David Alan Gilbert Sept. 3, 2019, 11:34 a.m. UTC | #5
* Yury Kotov (yury-kotov@yandex-team.ru) wrote:
> This capability realizes simple source validation by UUID.
> It's useful for live migration between hosts.
> 
> Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru>

So, ignoring the question of whether it should be a capaibility or not,
I'm actually OK with this; I would remove the x- - it's simple enough
not to need to go through experimental I think.

Dave

> ---
>  migration/migration.c |  9 +++++++++
>  migration/migration.h |  1 +
>  migration/savevm.c    | 45 +++++++++++++++++++++++++++++++++++++++++++
>  qapi/migration.json   |  5 ++++-
>  4 files changed, 59 insertions(+), 1 deletion(-)
> 
> diff --git a/migration/migration.c b/migration/migration.c
> index 8b9f2fe30a..910e11b7d7 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -2140,6 +2140,15 @@ bool migrate_ignore_shared(void)
>      return s->enabled_capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
>  }
>  
> +bool migrate_validate_uuid(void)
> +{
> +    MigrationState *s;
> +
> +    s = migrate_get_current();
> +
> +    return s->enabled_capabilities[MIGRATION_CAPABILITY_X_VALIDATE_UUID];
> +}
> +
>  bool migrate_use_events(void)
>  {
>      MigrationState *s;
> diff --git a/migration/migration.h b/migration/migration.h
> index 3e1ea2b5dc..4f2fe193dc 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -290,6 +290,7 @@ bool migrate_postcopy_ram(void);
>  bool migrate_zero_blocks(void);
>  bool migrate_dirty_bitmaps(void);
>  bool migrate_ignore_shared(void);
> +bool migrate_validate_uuid(void);
>  
>  bool migrate_auto_converge(void);
>  bool migrate_use_multifd(void);
> diff --git a/migration/savevm.c b/migration/savevm.c
> index 4a86128ac4..493dc24fd2 100644
> --- a/migration/savevm.c
> +++ b/migration/savevm.c
> @@ -256,6 +256,7 @@ typedef struct SaveState {
>      uint32_t target_page_bits;
>      uint32_t caps_count;
>      MigrationCapability *capabilities;
> +    QemuUUID uuid;
>  } SaveState;
>  
>  static SaveState savevm_state = {
> @@ -307,6 +308,7 @@ static int configuration_pre_save(void *opaque)
>              state->capabilities[j++] = i;
>          }
>      }
> +    state->uuid = qemu_uuid;
>  
>      return 0;
>  }
> @@ -464,6 +466,48 @@ static const VMStateDescription vmstate_capabilites = {
>      }
>  };
>  
> +static bool vmstate_uuid_needed(void *opaque)
> +{
> +    return qemu_uuid_set && migrate_validate_uuid();
> +}
> +
> +static int vmstate_uuid_post_load(void *opaque, int version_id)
> +{
> +    SaveState *state = opaque;
> +    char uuid_src[UUID_FMT_LEN + 1];
> +    char uuid_dst[UUID_FMT_LEN + 1];
> +
> +    if (!qemu_uuid_set) {
> +        /*
> +         * It's warning because user might not know UUID in some cases,
> +         * e.g. load an old snapshot
> +         */
> +        qemu_uuid_unparse(&state->uuid, uuid_src);
> +        warn_report("UUID is received %s, but local uuid isn't set",
> +                     uuid_src);
> +        return 0;
> +    }
> +    if (!qemu_uuid_is_equal(&state->uuid, &qemu_uuid)) {
> +        qemu_uuid_unparse(&state->uuid, uuid_src);
> +        qemu_uuid_unparse(&qemu_uuid, uuid_dst);
> +        error_report("UUID received is %s and local is %s", uuid_src, uuid_dst);
> +        return -EINVAL;
> +    }
> +    return 0;
> +}
> +
> +static const VMStateDescription vmstate_uuid = {
> +    .name = "configuration/uuid",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = vmstate_uuid_needed,
> +    .post_load = vmstate_uuid_post_load,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT8_ARRAY_V(uuid.data, SaveState, sizeof(QemuUUID), 1),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
>  static const VMStateDescription vmstate_configuration = {
>      .name = "configuration",
>      .version_id = 1,
> @@ -478,6 +522,7 @@ static const VMStateDescription vmstate_configuration = {
>      .subsections = (const VMStateDescription*[]) {
>          &vmstate_target_page_bits,
>          &vmstate_capabilites,
> +        &vmstate_uuid,
>          NULL
>      }
>  };
> diff --git a/qapi/migration.json b/qapi/migration.json
> index 9cfbaf8c6c..b7a8064745 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -415,6 +415,9 @@
>  #
>  # @x-ignore-shared: If enabled, QEMU will not migrate shared memory (since 4.0)
>  #
> +# @x-validate-uuid: Check whether the UUID is the same on both sides or not.
> +#                   (since 4.2)
> +#
>  # Since: 1.2
>  ##
>  { 'enum': 'MigrationCapability',
> @@ -422,7 +425,7 @@
>             'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
>             'block', 'return-path', 'pause-before-switchover', 'multifd',
>             'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
> -           'x-ignore-shared' ] }
> +           'x-ignore-shared', 'x-validate-uuid' ] }
>  
>  ##
>  # @MigrationCapabilityStatus:
> -- 
> 2.22.0
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
Yury Kotov Sept. 3, 2019, 4:39 p.m. UTC | #6
03.09.2019, 14:25, "Dr. David Alan Gilbert" <dgilbert@redhat.com>:
> * Eric Blake (eblake@redhat.com) wrote:
>>  On 8/27/19 10:36 AM, Yury Kotov wrote:
>>  > 27.08.2019, 17:02, "Eric Blake" <eblake@redhat.com>:
>>  >> On 8/27/19 7:02 AM, Yury Kotov wrote:
>>  >>>  This capability realizes simple source validation by UUID.
>>  >>>  It's useful for live migration between hosts.
>>  >>>
>>
>>  >>
>>  >> Any reason why this is marked experimental? It seems useful enough that
>>  >> we could probably just add it as a fully-supported feature (dropping the
>>  >> x- prefix) - but I'll leave that up to the migration maintainers.
>>  >>
>>  >
>>  > I thought that all new capabilities have x- prefix... May be it's really
>>  > unnecessary here, I'm not sure.
>>
>>  New features that need some testing or possible changes to behavior need
>>  x- to mark them as experimental, so we can make those changes without
>>  worrying about breaking back-compat. But new features that are outright
>>  useful and presumably in their final form, with no further
>>  experimentation needed, can skip going through an x- phase.
>>
>>  >
>>  >> In fact, do we even need this to be a tunable feature? Why not just
>>  >> always enable it? As long as the UUID is sent in a way that new->old
>>  >> doesn't break the old qemu from receiving the migration stream, and that
>>  >> old->new copes with UUID being absent, then new->new will always benefit
>>  >> from the additional safety check.
>>  >>
>>  >
>>  > In such case we couldn't migrate from e.g. 4.2 to 3.1
>>
>>  I don't know the migration format enough to know if there is a way for
>>  4.2 to unconditionally send a UUID as a subsection such that a receiving
>>  3.1 will ignore the unknown subsection. If so, then you don't need a
>>  knob; if not, then you need something to say whether sending the
>>  subsection is safe (perhaps default on in new machine types, but default
>>  off for machine types that might still be migrated back to 3.1). That's
>>  where I'm hoping the migration experts will chime in.
>
> Right; the migration format can't ignore chunks of data; so it does need
> to know somehow; the choice is either a capability or wiring it to the
> machine type; my preference is to wire it to the machine type; the
> arguments are:
>     a) Machine type
>        Pro: libvirt doesn't need to do anything
>        Con: It doesn't protect old machine types
>             It's not really part of the guest state
>
>     b) Capability
>        Pro: Works on all machine types
>        Con: Libvirt needs to enable it
>
> So, no strong preference but I think I prefer (a).

IIUC the (a) option requires to add a piece of code to every machine type.
This is much more complicated than adding a capability.
If you don't mind, I suggest to keep the current version.

>
> Dave
>
>>  --
>>  Eric Blake, Principal Software Engineer
>>  Red Hat, Inc. +1-919-301-3226
>>  Virtualization: qemu.org | libvirt.org
>
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

Regards,
Yury
Dr. David Alan Gilbert Sept. 3, 2019, 5:13 p.m. UTC | #7
* Yury Kotov (yury-kotov@yandex-team.ru) wrote:
> 03.09.2019, 14:25, "Dr. David Alan Gilbert" <dgilbert@redhat.com>:
> > * Eric Blake (eblake@redhat.com) wrote:
> >>  On 8/27/19 10:36 AM, Yury Kotov wrote:
> >>  > 27.08.2019, 17:02, "Eric Blake" <eblake@redhat.com>:
> >>  >> On 8/27/19 7:02 AM, Yury Kotov wrote:
> >>  >>>  This capability realizes simple source validation by UUID.
> >>  >>>  It's useful for live migration between hosts.
> >>  >>>
> >>
> >>  >>
> >>  >> Any reason why this is marked experimental? It seems useful enough that
> >>  >> we could probably just add it as a fully-supported feature (dropping the
> >>  >> x- prefix) - but I'll leave that up to the migration maintainers.
> >>  >>
> >>  >
> >>  > I thought that all new capabilities have x- prefix... May be it's really
> >>  > unnecessary here, I'm not sure.
> >>
> >>  New features that need some testing or possible changes to behavior need
> >>  x- to mark them as experimental, so we can make those changes without
> >>  worrying about breaking back-compat. But new features that are outright
> >>  useful and presumably in their final form, with no further
> >>  experimentation needed, can skip going through an x- phase.
> >>
> >>  >
> >>  >> In fact, do we even need this to be a tunable feature? Why not just
> >>  >> always enable it? As long as the UUID is sent in a way that new->old
> >>  >> doesn't break the old qemu from receiving the migration stream, and that
> >>  >> old->new copes with UUID being absent, then new->new will always benefit
> >>  >> from the additional safety check.
> >>  >>
> >>  >
> >>  > In such case we couldn't migrate from e.g. 4.2 to 3.1
> >>
> >>  I don't know the migration format enough to know if there is a way for
> >>  4.2 to unconditionally send a UUID as a subsection such that a receiving
> >>  3.1 will ignore the unknown subsection. If so, then you don't need a
> >>  knob; if not, then you need something to say whether sending the
> >>  subsection is safe (perhaps default on in new machine types, but default
> >>  off for machine types that might still be migrated back to 3.1). That's
> >>  where I'm hoping the migration experts will chime in.
> >
> > Right; the migration format can't ignore chunks of data; so it does need
> > to know somehow; the choice is either a capability or wiring it to the
> > machine type; my preference is to wire it to the machine type; the
> > arguments are:
> >     a) Machine type
> >        Pro: libvirt doesn't need to do anything
> >        Con: It doesn't protect old machine types
> >             It's not really part of the guest state
> >
> >     b) Capability
> >        Pro: Works on all machine types
> >        Con: Libvirt needs to enable it
> >
> > So, no strong preference but I think I prefer (a).
> 
> IIUC the (a) option requires to add a piece of code to every machine type.
> This is much more complicated than adding a capability.

Actually it doesn't - you just add a property, default it to true and
then add an entry in hw_compat_4_1 to turn it off for older types.

> If you don't mind, I suggest to keep the current version.

That's OK.

Dave

> >
> > Dave
> >
> >>  --
> >>  Eric Blake, Principal Software Engineer
> >>  Red Hat, Inc. +1-919-301-3226
> >>  Virtualization: qemu.org | libvirt.org
> >
> > --
> > Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
> 
> Regards,
> Yury
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff mbox series

Patch

diff --git a/migration/migration.c b/migration/migration.c
index 8b9f2fe30a..910e11b7d7 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2140,6 +2140,15 @@  bool migrate_ignore_shared(void)
     return s->enabled_capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
 }
 
+bool migrate_validate_uuid(void)
+{
+    MigrationState *s;
+
+    s = migrate_get_current();
+
+    return s->enabled_capabilities[MIGRATION_CAPABILITY_X_VALIDATE_UUID];
+}
+
 bool migrate_use_events(void)
 {
     MigrationState *s;
diff --git a/migration/migration.h b/migration/migration.h
index 3e1ea2b5dc..4f2fe193dc 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -290,6 +290,7 @@  bool migrate_postcopy_ram(void);
 bool migrate_zero_blocks(void);
 bool migrate_dirty_bitmaps(void);
 bool migrate_ignore_shared(void);
+bool migrate_validate_uuid(void);
 
 bool migrate_auto_converge(void);
 bool migrate_use_multifd(void);
diff --git a/migration/savevm.c b/migration/savevm.c
index 4a86128ac4..493dc24fd2 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -256,6 +256,7 @@  typedef struct SaveState {
     uint32_t target_page_bits;
     uint32_t caps_count;
     MigrationCapability *capabilities;
+    QemuUUID uuid;
 } SaveState;
 
 static SaveState savevm_state = {
@@ -307,6 +308,7 @@  static int configuration_pre_save(void *opaque)
             state->capabilities[j++] = i;
         }
     }
+    state->uuid = qemu_uuid;
 
     return 0;
 }
@@ -464,6 +466,48 @@  static const VMStateDescription vmstate_capabilites = {
     }
 };
 
+static bool vmstate_uuid_needed(void *opaque)
+{
+    return qemu_uuid_set && migrate_validate_uuid();
+}
+
+static int vmstate_uuid_post_load(void *opaque, int version_id)
+{
+    SaveState *state = opaque;
+    char uuid_src[UUID_FMT_LEN + 1];
+    char uuid_dst[UUID_FMT_LEN + 1];
+
+    if (!qemu_uuid_set) {
+        /*
+         * It's warning because user might not know UUID in some cases,
+         * e.g. load an old snapshot
+         */
+        qemu_uuid_unparse(&state->uuid, uuid_src);
+        warn_report("UUID is received %s, but local uuid isn't set",
+                     uuid_src);
+        return 0;
+    }
+    if (!qemu_uuid_is_equal(&state->uuid, &qemu_uuid)) {
+        qemu_uuid_unparse(&state->uuid, uuid_src);
+        qemu_uuid_unparse(&qemu_uuid, uuid_dst);
+        error_report("UUID received is %s and local is %s", uuid_src, uuid_dst);
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static const VMStateDescription vmstate_uuid = {
+    .name = "configuration/uuid",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = vmstate_uuid_needed,
+    .post_load = vmstate_uuid_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8_ARRAY_V(uuid.data, SaveState, sizeof(QemuUUID), 1),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_configuration = {
     .name = "configuration",
     .version_id = 1,
@@ -478,6 +522,7 @@  static const VMStateDescription vmstate_configuration = {
     .subsections = (const VMStateDescription*[]) {
         &vmstate_target_page_bits,
         &vmstate_capabilites,
+        &vmstate_uuid,
         NULL
     }
 };
diff --git a/qapi/migration.json b/qapi/migration.json
index 9cfbaf8c6c..b7a8064745 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -415,6 +415,9 @@ 
 #
 # @x-ignore-shared: If enabled, QEMU will not migrate shared memory (since 4.0)
 #
+# @x-validate-uuid: Check whether the UUID is the same on both sides or not.
+#                   (since 4.2)
+#
 # Since: 1.2
 ##
 { 'enum': 'MigrationCapability',
@@ -422,7 +425,7 @@ 
            'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
            'block', 'return-path', 'pause-before-switchover', 'multifd',
            'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
-           'x-ignore-shared' ] }
+           'x-ignore-shared', 'x-validate-uuid' ] }
 
 ##
 # @MigrationCapabilityStatus: