qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3 03/12] vfio-user: define vfio-user-server object


From: Stefan Hajnoczi
Subject: Re: [PATCH v3 03/12] vfio-user: define vfio-user-server object
Date: Wed, 27 Oct 2021 16:40:10 +0100

On Mon, Oct 11, 2021 at 01:31:08AM -0400, Jagannathan Raman wrote:
> diff --git a/qapi/qom.json b/qapi/qom.json
> index 0222bb4506..97de79cc36 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -705,6 +705,20 @@
>  { 'struct': 'RemoteObjectProperties',
>    'data': { 'fd': 'str', 'devid': 'str' } }
>  
> +##
> +# @VfioUserServerProperties:
> +#
> +# Properties for vfio-user-server objects.
> +#
> +# @socket: socket to be used by the libvfiouser library
> +#
> +# @device: the id of the device to be emulated at the server
> +#
> +# Since: 6.0

6.2

> +##
> +{ 'struct': 'VfioUserServerProperties',
> +  'data': { 'socket': 'SocketAddress', 'device': 'str' } }
> +
>  ##
>  # @RngProperties:
>  #
> @@ -830,7 +844,8 @@
>      'tls-creds-psk',
>      'tls-creds-x509',
>      'tls-cipher-suites',
> -    'x-remote-object'
> +    'x-remote-object',
> +    'vfio-user-server'

Should it have the experimental prefix ('x-') or is the QAPI interface
stable? I think some things to think about are whether a single process
can host multiple device servers, whether hotplug is possible, etc. If
the interface is stable then it must be able to accomodate future
features (at least ones we can anticipate right now :)).

>    ] }
>  
>  ##
> @@ -887,7 +902,8 @@
>        'tls-creds-psk':              'TlsCredsPskProperties',
>        'tls-creds-x509':             'TlsCredsX509Properties',
>        'tls-cipher-suites':          'TlsCredsProperties',
> -      'x-remote-object':            'RemoteObjectProperties'
> +      'x-remote-object':            'RemoteObjectProperties',
> +      'vfio-user-server':           'VfioUserServerProperties'
>    } }
>  
>  ##
> diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c
> new file mode 100644
> index 0000000000..c2a300f0ff
> --- /dev/null
> +++ b/hw/remote/vfio-user-obj.c
> @@ -0,0 +1,173 @@
> +/**
> + * QEMU vfio-user-server server object
> + *
> + * Copyright © 2021 Oracle and/or its affiliates.
> + *
> + * This work is licensed under the terms of the GNU GPL-v2, version 2 or 
> later.
> + *
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +/**
> + * Usage: add options:
> + *     -machine x-remote
> + *     -device <PCI-device>,id=<pci-dev-id>
> + *     -object vfio-user-server,id=<id>,type=unix,path=<socket-path>,

I expected socket.type= and socket.path= based on the QAPI schema. Is
this command-line example correct?

> + *             device=<pci-dev-id>
> + *
> + * Note that vfio-user-server object must be used with x-remote machine only.
> + * This server could only support PCI devices for now.
> + *
> + * type - SocketAddress type - presently "unix" alone is supported. Required
> + *        option
> + *
> + * path - named unix socket, it will be created by the server. It is
> + *        a required option
> + *
> + * device - id of a device on the server, a required option. PCI devices
> + *          alone are supported presently.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +
> +#include "qom/object.h"
> +#include "qom/object_interfaces.h"
> +#include "qemu/error-report.h"
> +#include "trace.h"
> +#include "sysemu/runstate.h"
> +#include "hw/boards.h"
> +#include "hw/remote/machine.h"
> +#include "qapi/error.h"
> +#include "qapi/qapi-visit-sockets.h"
> +
> +#define TYPE_VFU_OBJECT "vfio-user-server"
> +OBJECT_DECLARE_TYPE(VfuObject, VfuObjectClass, VFU_OBJECT)
> +
> +struct VfuObjectClass {
> +    ObjectClass parent_class;
> +
> +    unsigned int nr_devs;
> +
> +    /* Maximum number of devices the server could support */
> +    unsigned int max_devs;
> +};
> +
> +struct VfuObject {
> +    /* private */
> +    Object parent;
> +
> +    SocketAddress *socket;
> +
> +    char *device;
> +};
> +
> +static void vfu_object_set_socket(Object *obj, Visitor *v, const char *name,
> +                                  void *opaque, Error **errp)
> +{
> +    VfuObject *o = VFU_OBJECT(obj);
> +
> +    g_free(o->socket);

qapi_free_SocketAddress(o->socket)?

> +
> +    o->socket = NULL;
> +
> +    visit_type_SocketAddress(v, name, &o->socket, errp);
> +
> +    if (o->socket->type != SOCKET_ADDRESS_TYPE_UNIX) {
> +        error_setg(&error_abort, "vfu: Unsupported socket type - %s",
> +                   o->socket->u.q_unix.path);

o->socket must be freed and set it to NULL again, otherwise setting the
property appears to fail but the SocketAddress actually retains the
invalid value.

> +        return;
> +    }
> +
> +    trace_vfu_prop("socket", o->socket->u.q_unix.path);
> +}
> +
> +static void vfu_object_set_device(Object *obj, const char *str, Error **errp)
> +{
> +    VfuObject *o = VFU_OBJECT(obj);
> +
> +    g_free(o->device);
> +
> +    o->device = g_strdup(str);
> +
> +    trace_vfu_prop("device", str);
> +}
> +
> +static void vfu_object_init(Object *obj)
> +{
> +    VfuObjectClass *k = VFU_OBJECT_GET_CLASS(obj);
> +
> +    if (!object_dynamic_cast(OBJECT(current_machine), TYPE_REMOTE_MACHINE)) {
> +        error_setg(&error_abort, "vfu: %s only compatible with %s machine",
> +                   TYPE_VFU_OBJECT, TYPE_REMOTE_MACHINE);
> +        return;
> +    }
> +
> +    if (k->nr_devs >= k->max_devs) {
> +        error_setg(&error_abort,
> +                   "Reached maximum number of vfio-user-server devices: %u",
> +                   k->max_devs);
> +        return;
> +    }
> +
> +    k->nr_devs++;
> +}
> +
> +static void vfu_object_finalize(Object *obj)
> +{
> +    VfuObjectClass *k = VFU_OBJECT_GET_CLASS(obj);
> +    VfuObject *o = VFU_OBJECT(obj);
> +
> +    k->nr_devs--;
> +
> +    g_free(o->socket);

qapi_free_SocketAddress(o->socket)?

> +
> +    g_free(o->device);
> +
> +    if (k->nr_devs == 0) {
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
> +    }

This won't work for all use cases. The user may wish to create/delete
vhost-user servers at runtime without terminating the process when there
are none left. An boolean option can be added in the future to control
this behavior, so it's okay to leave this as is.

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]