[PATCH v9 2/8] qapi: introduce query-backend-transfer-support

Vladimir Sementsov-Ogievskiy posted 8 patches 2 weeks ago
[PATCH v9 2/8] qapi: introduce query-backend-transfer-support
Posted by Vladimir Sementsov-Ogievskiy 2 weeks ago
We are going to implement backend-transfer feature: some devices
will be able to transfer their backend through migration stream
for local migration through UNIX domain socket. For example,
virtio-net will migrate its attached TAP netdev, with all its
connected file descriptors.

Let's add a command to list supporting devices (no one for now),
together with necessary infrastructure in qdev code.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 include/hw/qdev-core.h |  7 +++++++
 qapi/qdev.json         | 26 +++++++++++++++++++++++++
 system/qdev-monitor.c  | 43 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 2caa0cbd26..0551fbaa6c 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -96,6 +96,7 @@ typedef void (*DeviceReset)(DeviceState *dev);
 typedef void (*BusRealize)(BusState *bus, Error **errp);
 typedef void (*BusUnrealize)(BusState *bus);
 typedef int (*DeviceSyncConfig)(DeviceState *dev, Error **errp);
+typedef bool (*DeviceSupportBackendTransfer)(DeviceState *dev, Error **errp);
 
 /**
  * struct DeviceClass - The base class for all devices.
@@ -174,6 +175,12 @@ struct DeviceClass {
     DeviceUnrealize unrealize;
     DeviceSyncConfig sync_config;
 
+    /**
+     * @backend_transfer_support: reports support for backend-transfer
+     * migration of the device.
+     */
+    DeviceSupportBackendTransfer backend_transfer_support;
+
     /**
      * @vmsd: device state serialisation description for
      * migration/save/restore
diff --git a/qapi/qdev.json b/qapi/qdev.json
index e14a0c9259..d7e878d58d 100644
--- a/qapi/qdev.json
+++ b/qapi/qdev.json
@@ -188,3 +188,29 @@
 { 'command': 'device-sync-config',
   'features': [ 'unstable' ],
   'data': {'id': 'str'} }
+
+##
+# @DevPath:
+#
+# @path: the device's QOM path
+#
+# Since: 10.2
+##
+{ 'struct': 'DevPath',
+  'data': { 'path': 'str' } }
+
+##
+# @query-backend-transfer-support:
+#
+# Returns list of devices, supporting backend-transfer
+# migration.
+#
+# Features:
+#
+# @unstable: The command is experimental.
+#
+# Since: 10.2
+##
+{ 'command': 'query-backend-transfer-support',
+  'features': [ 'unstable' ],
+  'returns': [ 'DevPath' ] }
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index ec4a2394ce..9d3d961c15 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -939,6 +939,49 @@ void qmp_device_del(const char *id, Error **errp)
     }
 }
 
+static bool qdev_backend_transfer_support(DeviceState *dev, Error **errp)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (!dc->backend_transfer_support) {
+        error_setg(errp, "backend-transfer is not supported for '%s'",
+                   object_get_typename(OBJECT(dev)));
+        return false;
+    }
+
+    return dc->backend_transfer_support(dev, errp);
+}
+
+static int qdev_add_if_backend_transfer_supported(Object *obj, void *opaque)
+{
+    DevPathList **list = opaque;
+    DeviceState *dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
+
+    if (dev != NULL && qdev_backend_transfer_support(dev, NULL)) {
+        DevPath *el = g_new(DevPath, 1);
+        *el = (DevPath) {
+            .path = g_strdup(dev->canonical_path),
+        };
+        QAPI_LIST_PREPEND(*list, el);
+    }
+
+    /* Recursively check all children */
+    object_child_foreach(obj, qdev_add_if_backend_transfer_supported, opaque);
+
+    return 0;
+}
+
+DevPathList *qmp_query_backend_transfer_support(Error **errp)
+{
+    DevPathList *result = NULL;
+    Object *peripheral = machine_get_container("peripheral");
+
+    object_child_foreach(peripheral, qdev_add_if_backend_transfer_supported,
+                         &result);
+
+    return result;
+}
+
 int qdev_sync_config(DeviceState *dev, Error **errp)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
-- 
2.48.1
Re: [PATCH v9 2/8] qapi: introduce query-backend-transfer-support
Posted by Markus Armbruster 1 week, 1 day ago
Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:

> We are going to implement backend-transfer feature: some devices
> will be able to transfer their backend through migration stream
> for local migration through UNIX domain socket. For example,
> virtio-net will migrate its attached TAP netdev, with all its
> connected file descriptors.
>
> Let's add a command to list supporting devices (no one for now),
> together with necessary infrastructure in qdev code.

Use case?

> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>  include/hw/qdev-core.h |  7 +++++++
>  qapi/qdev.json         | 26 +++++++++++++++++++++++++
>  system/qdev-monitor.c  | 43 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 76 insertions(+)
>
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 2caa0cbd26..0551fbaa6c 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -96,6 +96,7 @@ typedef void (*DeviceReset)(DeviceState *dev);
>  typedef void (*BusRealize)(BusState *bus, Error **errp);
>  typedef void (*BusUnrealize)(BusState *bus);
>  typedef int (*DeviceSyncConfig)(DeviceState *dev, Error **errp);
> +typedef bool (*DeviceSupportBackendTransfer)(DeviceState *dev, Error **errp);
>  
>  /**
>   * struct DeviceClass - The base class for all devices.
> @@ -174,6 +175,12 @@ struct DeviceClass {
>      DeviceUnrealize unrealize;
>      DeviceSyncConfig sync_config;
>  
> +    /**
> +     * @backend_transfer_support: reports support for backend-transfer
> +     * migration of the device.
> +     */
> +    DeviceSupportBackendTransfer backend_transfer_support;
> +
>      /**
>       * @vmsd: device state serialisation description for
>       * migration/save/restore
> diff --git a/qapi/qdev.json b/qapi/qdev.json
> index e14a0c9259..d7e878d58d 100644
> --- a/qapi/qdev.json
> +++ b/qapi/qdev.json
> @@ -188,3 +188,29 @@
>  { 'command': 'device-sync-config',
>    'features': [ 'unstable' ],
>    'data': {'id': 'str'} }
> +
> +##
> +# @DevPath:
> +#
> +# @path: the device's QOM path
> +#
> +# Since: 10.2
> +##
> +{ 'struct': 'DevPath',
> +  'data': { 'path': 'str' } }
> +
> +##
> +# @query-backend-transfer-support:
> +#
> +# Returns list of devices, supporting backend-transfer
> +# migration.

Suggest

   # Return the devices that support backend-transfer migration.

> +#
> +# Features:
> +#
> +# @unstable: The command is experimental.

The conventional text ist "This command is experimental."

> +#
> +# Since: 10.2
> +##
> +{ 'command': 'query-backend-transfer-support',
> +  'features': [ 'unstable' ],
> +  'returns': [ 'DevPath' ] }
> diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
> index ec4a2394ce..9d3d961c15 100644
> --- a/system/qdev-monitor.c
> +++ b/system/qdev-monitor.c
> @@ -939,6 +939,49 @@ void qmp_device_del(const char *id, Error **errp)
>      }
>  }
>  
> +static bool qdev_backend_transfer_support(DeviceState *dev, Error **errp)
> +{
> +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> +
> +    if (!dc->backend_transfer_support) {
> +        error_setg(errp, "backend-transfer is not supported for '%s'",
> +                   object_get_typename(OBJECT(dev)));
> +        return false;
> +    }
> +
> +    return dc->backend_transfer_support(dev, errp);
> +}

@errp is useless in this patch: the only caller passes NULL.  Took me a
minute to check it doesn't remain useless.  The next patch puts it to
use.

> +
> +static int qdev_add_if_backend_transfer_supported(Object *obj, void *opaque)
> +{
> +    DevPathList **list = opaque;
> +    DeviceState *dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
> +
> +    if (dev != NULL && qdev_backend_transfer_support(dev, NULL)) {
> +        DevPath *el = g_new(DevPath, 1);
> +        *el = (DevPath) {
> +            .path = g_strdup(dev->canonical_path),
> +        };
> +        QAPI_LIST_PREPEND(*list, el);
> +    }
> +
> +    /* Recursively check all children */
> +    object_child_foreach(obj, qdev_add_if_backend_transfer_supported, opaque);
> +
> +    return 0;
> +}
> +
> +DevPathList *qmp_query_backend_transfer_support(Error **errp)
> +{
> +    DevPathList *result = NULL;
> +    Object *peripheral = machine_get_container("peripheral");
> +
> +    object_child_foreach(peripheral, qdev_add_if_backend_transfer_supported,
> +                         &result);
> +
> +    return result;
> +}
> +
>  int qdev_sync_config(DeviceState *dev, Error **errp)
>  {
>      DeviceClass *dc = DEVICE_GET_CLASS(dev);
Re: [PATCH v9 2/8] qapi: introduce query-backend-transfer-support
Posted by Vladimir Sementsov-Ogievskiy 1 week ago
On 06.11.25 18:30, Markus Armbruster wrote:
> Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:
> 
>> We are going to implement backend-transfer feature: some devices
>> will be able to transfer their backend through migration stream
>> for local migration through UNIX domain socket. For example,
>> virtio-net will migrate its attached TAP netdev, with all its
>> connected file descriptors.
>>
>> Let's add a command to list supporting devices (no one for now),
>> together with necessary infrastructure in qdev code.
> 
> Use case?

Will add:

With this command management tool can query such lists on source and
target, and get intersection of them, to now the set of devices, for
which we can enable backend-transfer for given source and target QEMUs.


> 
>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
>> ---
>>   include/hw/qdev-core.h |  7 +++++++
>>   qapi/qdev.json         | 26 +++++++++++++++++++++++++
>>   system/qdev-monitor.c  | 43 ++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 76 insertions(+)
>>
>> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
>> index 2caa0cbd26..0551fbaa6c 100644




-- 
Best regards,
Vladimir
Re: [PATCH v9 2/8] qapi: introduce query-backend-transfer-support
Posted by Markus Armbruster 1 week ago
Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:

> On 06.11.25 18:30, Markus Armbruster wrote:
>> Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:
>> 
>>> We are going to implement backend-transfer feature: some devices
>>> will be able to transfer their backend through migration stream
>>> for local migration through UNIX domain socket. For example,
>>> virtio-net will migrate its attached TAP netdev, with all its
>>> connected file descriptors.
>>>
>>> Let's add a command to list supporting devices (no one for now),
>>> together with necessary infrastructure in qdev code.
>>
>> Use case?
>
> Will add:
>
> With this command management tool can query such lists on source and
> target, and get intersection of them, to now the set of devices, for
> which we can enable backend-transfer for given source and target QEMUs.

I like it.  Would it make sense to add something similar to QAPI schema
doc comments?

[...]
Re: [PATCH v9 2/8] qapi: introduce query-backend-transfer-support
Posted by Vladimir Sementsov-Ogievskiy 1 week ago
On 07.11.25 08:28, Markus Armbruster wrote:
> Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:
> 
>> On 06.11.25 18:30, Markus Armbruster wrote:
>>> Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:
>>>
>>>> We are going to implement backend-transfer feature: some devices
>>>> will be able to transfer their backend through migration stream
>>>> for local migration through UNIX domain socket. For example,
>>>> virtio-net will migrate its attached TAP netdev, with all its
>>>> connected file descriptors.
>>>>
>>>> Let's add a command to list supporting devices (no one for now),
>>>> together with necessary infrastructure in qdev code.
>>>
>>> Use case?
>>
>> Will add:
>>
>> With this command management tool can query such lists on source and
>> target, and get intersection of them, to now the set of devices, for
>> which we can enable backend-transfer for given source and target QEMUs.
> 
> I like it.  Would it make sense to add something similar to QAPI schema
> doc comments?
> 

Agree, will do.

-- 
Best regards,
Vladimir