]> git.ipfire.org Git - thirdparty/lxc.git/commit
ringbuf: implement simple and efficient ringbuffer
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 18 Oct 2017 12:19:31 +0000 (14:19 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sat, 21 Oct 2017 16:38:13 +0000 (18:38 +0200)
commitf3d05ee66dbf0e8283a2eeb6321e1bc7dfcb3034
tree2b9d332b53c98da09e3da757c3a804e83732b450
parente46361235c04c10a9dfb5f2485e23a187fae9189
ringbuf: implement simple and efficient ringbuffer

liblxc will use a ringbuffer implementation that employs mmap()ed memory.
Specifically, the ringbuffer will create an anonymous memory mapping twice the
requested size for the ringbuffer. Afterwards, an in-memory file the requested
size for the ringbuffer will be created. This in-memory file will then be
memory mapped twice into the previously established anonymous memory mapping
thereby effectively splitting the anoymous memory mapping in two halves of
equal size.  This will allow the ringbuffer to get rid of any complex boundary
and wrap-around calculation logic. Since the underlying physical memory is the
same in both halves of the memory mapping only a single memcpy() call for both
reads and writes from and to the ringbuffer is needed.

Design Notes:
- Since we're using MAP_FIXED memory mappings to map the same in-memory file
  twice into the anonymous memory mapping the kernel requires us to always
  operate on properly aligned pages. To guarantee proper page aligment the size
  of the ringbuffer must always be a muliple of the kernel's page size. This
  also implies that the minimum size of the ringbuffer must be at least equal to
  one page size. This additional requirement is reasonably unproblematic.
  First, any ringbuffer smaller than the size of a single page is very likely
  useless since the standard page size on linux is 4096 bytes.
- Because liblxc is not able to predict the output a user is going to produce
  (e.g. users could cat binary files onto the console) and because the
  ringbuffer is located in a hotpath and needs to be as performant as possible
  liblxc will not parse the buffer.

Use Case:
The ringbuffer is needed by liblxc in order to safely log the output of write
intensive callers that produce unpredictable output or unpredictable amounts of
output. The console output created by a booting system and the user is one of
those cases. Allowing a container to log the console's output to a file it
would be possible for a malicious user to fill up the host filesystem by
producing random ouput on the container's console if quota support is either
not enabled or not available for the underlying filesystem. Using a ringbuffer
is a reliable and secure way to ensure a fixed-size log.

Closes #1857.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/Makefile.am
src/lxc/ringbuf.c [new file with mode: 0644]
src/lxc/ringbuf.h [new file with mode: 0644]