diff mbox series

[4/5] qmp: Added new command to retrieve eBPF blob.

Message ID 20230501072101.22890-5-andrew@daynix.com
State New
Headers show
Series eBPF RSS through QMP support. | expand

Commit Message

Andrew Melnichenko May 1, 2023, 7:21 a.m. UTC
Added command "request-ebpf". This command returns
eBPF program encoded base64. The program taken from the
skeleton and essentially is an ELF object that can be
loaded in the future with libbpf.

Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
---
 monitor/qmp-cmds.c | 16 ++++++++++++++++
 qapi/misc.json     | 28 ++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

Comments

Daniel P. Berrangé May 3, 2023, 11:09 a.m. UTC | #1
On Mon, May 01, 2023 at 10:21:00AM +0300, Andrew Melnychenko wrote:
> Added command "request-ebpf". This command returns
> eBPF program encoded base64. The program taken from the
> skeleton and essentially is an ELF object that can be
> loaded in the future with libbpf.
> 
> Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
> ---
>  monitor/qmp-cmds.c | 16 ++++++++++++++++
>  qapi/misc.json     | 28 ++++++++++++++++++++++++++++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> index b0f948d3376..f7641bb55b9 100644
> --- a/monitor/qmp-cmds.c
> +++ b/monitor/qmp-cmds.c
> @@ -32,6 +32,7 @@
>  #include "hw/mem/memory-device.h"
>  #include "hw/intc/intc.h"
>  #include "hw/rdma/rdma.h"
> +#include "ebpf/ebpf.h"
>  
>  NameInfo *qmp_query_name(Error **errp)
>  {
> @@ -209,3 +210,18 @@ static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
>                           qmp_marshal_qmp_capabilities,
>                           QCO_ALLOW_PRECONFIG, 0);
>  }
> +
> +EbpfObject *qmp_request_ebpf(const char *id, Error **errp)
> +{
> +    EbpfObject *ret = NULL;
> +    size_t size = 0;
> +    const void *data = ebpf_find_binary_by_id(id, &size, errp);
> +    if (!data) {
> +        return NULL;
> +    }
> +
> +    ret = g_new0(EbpfObject, 1);
> +    ret->object = g_base64_encode(data, size);
> +
> +    return ret;
> +}
> diff --git a/qapi/misc.json b/qapi/misc.json
> index 6ddd16ea283..81613fd1b13 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -618,3 +618,31 @@
>  { 'event': 'VFU_CLIENT_HANGUP',
>    'data': { 'vfu-id': 'str', 'vfu-qom-path': 'str',
>              'dev-id': 'str', 'dev-qom-path': 'str' } }
> +
> +##
> +# @EbpfObject:
> +#
> +# Structure that holds eBPF ELF object encoded in base64.
> +#
> +# Since: 8.1
> +#
> +##
> +{ 'struct': 'EbpfObject',
> +  'data': {'object': 'str'} }
> +
> +##
> +# @request-ebpf:
> +#
> +# Function returns eBPF object that can be loaded with libbpf.
> +# Management applications (g.e. libvirt) may load it and pass file
> +# descriptors to QEMU. Which allows running QEMU without BPF capabilities.
> +#
> +# Returns: RSS eBPF object encoded in base64.
> +#
> +# Since: 8.1
> +#
> +##
> +{ 'command': 'request-ebpf',
> +  'data': { 'id': 'str' },

Since the number of EBPF program IDs is finite and known at build
time, I think we'd be better using an enum instead of str. That
will let apps introspect the QAPI schema to query whether the
particular EBPF program ID is known to this version fo QEMU.

> +  'returns': 'EbpfObject' }
> +
> -- 
> 2.39.1
> 

With regards,
Daniel
Andrew Melnichenko May 7, 2023, 10:05 p.m. UTC | #2
Hi all,

On Wed, May 3, 2023 at 2:09 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Mon, May 01, 2023 at 10:21:00AM +0300, Andrew Melnychenko wrote:
> > Added command "request-ebpf". This command returns
> > eBPF program encoded base64. The program taken from the
> > skeleton and essentially is an ELF object that can be
> > loaded in the future with libbpf.
> >
> > Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
> > ---
> >  monitor/qmp-cmds.c | 16 ++++++++++++++++
> >  qapi/misc.json     | 28 ++++++++++++++++++++++++++++
> >  2 files changed, 44 insertions(+)
> >
> > diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> > index b0f948d3376..f7641bb55b9 100644
> > --- a/monitor/qmp-cmds.c
> > +++ b/monitor/qmp-cmds.c
> > @@ -32,6 +32,7 @@
> >  #include "hw/mem/memory-device.h"
> >  #include "hw/intc/intc.h"
> >  #include "hw/rdma/rdma.h"
> > +#include "ebpf/ebpf.h"
> >
> >  NameInfo *qmp_query_name(Error **errp)
> >  {
> > @@ -209,3 +210,18 @@ static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
> >                           qmp_marshal_qmp_capabilities,
> >                           QCO_ALLOW_PRECONFIG, 0);
> >  }
> > +
> > +EbpfObject *qmp_request_ebpf(const char *id, Error **errp)
> > +{
> > +    EbpfObject *ret = NULL;
> > +    size_t size = 0;
> > +    const void *data = ebpf_find_binary_by_id(id, &size, errp);
> > +    if (!data) {
> > +        return NULL;
> > +    }
> > +
> > +    ret = g_new0(EbpfObject, 1);
> > +    ret->object = g_base64_encode(data, size);
> > +
> > +    return ret;
> > +}
> > diff --git a/qapi/misc.json b/qapi/misc.json
> > index 6ddd16ea283..81613fd1b13 100644
> > --- a/qapi/misc.json
> > +++ b/qapi/misc.json
> > @@ -618,3 +618,31 @@
> >  { 'event': 'VFU_CLIENT_HANGUP',
> >    'data': { 'vfu-id': 'str', 'vfu-qom-path': 'str',
> >              'dev-id': 'str', 'dev-qom-path': 'str' } }
> > +
> > +##
> > +# @EbpfObject:
> > +#
> > +# Structure that holds eBPF ELF object encoded in base64.
> > +#
> > +# Since: 8.1
> > +#
> > +##
> > +{ 'struct': 'EbpfObject',
> > +  'data': {'object': 'str'} }
> > +
> > +##
> > +# @request-ebpf:
> > +#
> > +# Function returns eBPF object that can be loaded with libbpf.
> > +# Management applications (g.e. libvirt) may load it and pass file
> > +# descriptors to QEMU. Which allows running QEMU without BPF capabilities.
> > +#
> > +# Returns: RSS eBPF object encoded in base64.
> > +#
> > +# Since: 8.1
> > +#
> > +##
> > +{ 'command': 'request-ebpf',
> > +  'data': { 'id': 'str' },
>
> Since the number of EBPF program IDs is finite and known at build
> time, I think we'd be better using an enum instead of str. That
> will let apps introspect the QAPI schema to query whether the
> particular EBPF program ID is known to this version fo QEMU.
>

I've researched that issue a bit. I'll add the qapi enum.

> > +  'returns': 'EbpfObject' }
> > +
> > --
> > 2.39.1
> >
>
> With regards,
> Daniel
> --
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
>
diff mbox series

Patch

diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index b0f948d3376..f7641bb55b9 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -32,6 +32,7 @@ 
 #include "hw/mem/memory-device.h"
 #include "hw/intc/intc.h"
 #include "hw/rdma/rdma.h"
+#include "ebpf/ebpf.h"
 
 NameInfo *qmp_query_name(Error **errp)
 {
@@ -209,3 +210,18 @@  static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
                          qmp_marshal_qmp_capabilities,
                          QCO_ALLOW_PRECONFIG, 0);
 }
+
+EbpfObject *qmp_request_ebpf(const char *id, Error **errp)
+{
+    EbpfObject *ret = NULL;
+    size_t size = 0;
+    const void *data = ebpf_find_binary_by_id(id, &size, errp);
+    if (!data) {
+        return NULL;
+    }
+
+    ret = g_new0(EbpfObject, 1);
+    ret->object = g_base64_encode(data, size);
+
+    return ret;
+}
diff --git a/qapi/misc.json b/qapi/misc.json
index 6ddd16ea283..81613fd1b13 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -618,3 +618,31 @@ 
 { 'event': 'VFU_CLIENT_HANGUP',
   'data': { 'vfu-id': 'str', 'vfu-qom-path': 'str',
             'dev-id': 'str', 'dev-qom-path': 'str' } }
+
+##
+# @EbpfObject:
+#
+# Structure that holds eBPF ELF object encoded in base64.
+#
+# Since: 8.1
+#
+##
+{ 'struct': 'EbpfObject',
+  'data': {'object': 'str'} }
+
+##
+# @request-ebpf:
+#
+# Function returns eBPF object that can be loaded with libbpf.
+# Management applications (g.e. libvirt) may load it and pass file
+# descriptors to QEMU. Which allows running QEMU without BPF capabilities.
+#
+# Returns: RSS eBPF object encoded in base64.
+#
+# Since: 8.1
+#
+##
+{ 'command': 'request-ebpf',
+  'data': { 'id': 'str' },
+  'returns': 'EbpfObject' }
+