[libvirt] [PATCH v3 03/15] vircgroup: introduce virCgroupV2DevicesAttachProg

Pavel Hrdina phrdina at redhat.com
Fri Jun 14 10:55:01 UTC 2019


On Thu, Jun 13, 2019 at 01:16:21PM +0200, Ján Tomko wrote:
> On Thu, Apr 25, 2019 at 09:44:20AM +0200, Pavel Hrdina wrote:
> > This function loads the BPF prog with prepared map into kernel and
> > attaches it into guest cgroup.  It can be also used to replace existing
> > program in the cgroup if we need to resize BPF map to store more rules
> > for devices. The old program will be closed and removed from kernel.
> > 
> > There are two possible ways how to create BPF program:
> > 
> >    - One way is to write simple C-like code which can by compiled into
> >      BPF object file which can be loaded into kernel using elfutils.
> > 
> >    - The second way is to define macros which looks like assembler
> 
> s/looks/look/
> 
> >      instructions and can be used directly to create BPF program that
> >      can be directly loaded into kernel.
> > 
> > Since the program is not too complex we can use the second option.
> 
> I can live with that, since it saves us the dependency on clang,
> and it probably won't require many changes, but please include all
> the steps necessary to regenerate it (see below).
> 
> > 
> > If there is no program, all devices are allowed, if there is some
> > program it is executed and based on the exit status the access is
> > denied for 0 and allowed for 1.
> > 
> > Our program will follow these rules:
> > 
> >    - first it will try to look for the specific key using major and
> >      minor to see if there is any rule for that specific device
> > 
> >    - if there is no specific rule it will try to look for any rule that
> >      matches only major of the device
> > 
> >    - if there is no match with major it will try the same but with
> >      minor of the device
> > 
> >    - as the last attempt it will try to look for rule for all devices
> >      and if there is no match it will return 0 to deny that access
> > 
> > Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
> > ---
> > src/libvirt_private.syms      |   1 +
> > src/util/vircgrouppriv.h      |  10 ++
> > src/util/vircgroupv2devices.c | 276 ++++++++++++++++++++++++++++++++++
> > src/util/vircgroupv2devices.h |   5 +
> > 4 files changed, 292 insertions(+)
> > 
> > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> > index 9eac05009c..24a783840f 100644
> > --- a/src/libvirt_private.syms
> > +++ b/src/libvirt_private.syms
> > @@ -1653,6 +1653,7 @@ virCgroupV1Register;
> > virCgroupV2Register;
> > 
> > # util/vircgroupv2devices.h
> > +virCgroupV2DevicesAttachProg;
> > virCgroupV2DevicesAvailable;
> > 
> > # util/virclosecallbacks.h
> > diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
> > index 9110c77297..7eba4ade23 100644
> > --- a/src/util/vircgrouppriv.h
> > +++ b/src/util/vircgrouppriv.h
> > @@ -41,10 +41,20 @@ struct _virCgroupV1Controller {
> > typedef struct _virCgroupV1Controller virCgroupV1Controller;
> > typedef virCgroupV1Controller *virCgroupV1ControllerPtr;
> > 
> > +struct _virCgroupV2Devices {
> > +    int mapfd;
> > +    int progfd;
> > +    ssize_t count;
> > +    ssize_t max;
> > +};
> > +typedef struct _virCgroupV2Devices virCgroupV2Devices;
> > +typedef virCgroupV2Devices *virCgroupV2DevicesPtr;
> > +
> > struct _virCgroupV2Controller {
> >     int controllers;
> >     char *mountPoint;
> >     char *placement;
> > +    virCgroupV2Devices devices;
> > };
> > typedef struct _virCgroupV2Controller virCgroupV2Controller;
> > typedef virCgroupV2Controller *virCgroupV2ControllerPtr;
> > diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c
> > index 10080d4fff..c8686e8768 100644
> > --- a/src/util/vircgroupv2devices.c
> > +++ b/src/util/vircgroupv2devices.c
> > @@ -30,6 +30,7 @@
> > #define LIBVIRT_VIRCGROUPPRIV_H_ALLOW
> > #include "vircgrouppriv.h"
> > 
> > +#include "viralloc.h"
> > #include "virbpf.h"
> > #include "vircgroup.h"
> > #include "vircgroupv2devices.h"
> > @@ -64,10 +65,285 @@ virCgroupV2DevicesAvailable(virCgroupPtr group)
> >     VIR_FORCE_CLOSE(cgroupfd);
> >     return ret;
> > }
> > +
> > +
> > +/* Steps to get assembly version of devices BPF program:
> > + *
> > + * Save the following program into bpfprog.c, compile it using clang:
> 
> It would be nicer to have the file separate, with this comment there,
> to save the developer the trouble of stripping the asterisks.

Sure, I can move that into a separate file, I just wanted to have it
closer to the assembly-like code.

> > + *
> > + *     clang -O2 -Wall -target bpf -c bpfprog.c -o bpfprog.o
> > + *
> > + * Now you can use llvm-objdump to get the list if instructions:
> > + *
> > + *     llvm-objdump -S -no-show-raw-insn bpfprog.o
> > + *
> > + * which can be converted into program using VIR_BPF_* macros.
> 
> Did you convert them manually? Can you share the script here?

Yes, it was done manually as I did not create any script to do it.

Pavel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20190614/62cabcf4/attachment-0001.sig>


More information about the libvir-list mailing list