]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/ringbuf.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #define __STDC_FORMAT_MACROS
18 #include "syscall_wrappers.h"
21 int lxc_ringbuf_create(struct lxc_ringbuf
*buf
, size_t size
)
31 /* verify that we are at least given the multiple of a page size */
32 if (buf
->size
% lxc_getpagesize())
35 buf
->addr
= mmap(NULL
, buf
->size
* 2, PROT_NONE
,
36 MAP_ANONYMOUS
| MAP_PRIVATE
, -1, 0);
37 if (buf
->addr
== MAP_FAILED
)
40 memfd
= memfd_create(".lxc_ringbuf", MFD_CLOEXEC
);
42 char template[] = P_tmpdir
"/.lxc_ringbuf_XXXXXX";
47 memfd
= lxc_make_tmpfile(template, true);
52 ret
= ftruncate(memfd
, buf
->size
);
56 tmp
= mmap(buf
->addr
, buf
->size
, PROT_READ
| PROT_WRITE
,
57 MAP_FIXED
| MAP_SHARED
, memfd
, 0);
58 if (tmp
== MAP_FAILED
|| tmp
!= buf
->addr
)
61 tmp
= mmap(buf
->addr
+ buf
->size
, buf
->size
, PROT_READ
| PROT_WRITE
,
62 MAP_FIXED
| MAP_SHARED
, memfd
, 0);
63 if (tmp
== MAP_FAILED
|| tmp
!= (buf
->addr
+ buf
->size
))
71 lxc_ringbuf_release(buf
);
77 void lxc_ringbuf_move_read_addr(struct lxc_ringbuf
*buf
, size_t len
)
81 if (buf
->r_off
< buf
->size
)
85 buf
->r_off
-= buf
->size
;
86 buf
->w_off
-= buf
->size
;
90 * lxc_ringbuf_write - write a message to the ringbuffer
91 * - The size of the message should never be greater than the size of the whole
93 * - The write method will always succeed i.e. it will always advance the r_off
94 * if it detects that there's not enough space available to write the
97 int lxc_ringbuf_write(struct lxc_ringbuf
*buf
, const char *msg
, size_t len
)
102 /* sanity check: a write should never exceed the ringbuffer's total size */
106 free
= lxc_ringbuf_free(buf
);
108 /* not enough space left so advance read address */
110 lxc_ringbuf_move_read_addr(buf
, len
);
111 w_addr
= lxc_ringbuf_get_write_addr(buf
);
112 memcpy(w_addr
, msg
, len
);
113 lxc_ringbuf_move_write_addr(buf
, len
);
117 int lxc_ringbuf_read(struct lxc_ringbuf
*buf
, char *out
, size_t *len
)
121 /* there's nothing to read */
122 if (buf
->r_off
== buf
->w_off
)
125 /* read maximum amount available */
126 used
= lxc_ringbuf_used(buf
);
130 /* copy data to reader but don't advance addr */
131 memcpy(out
, lxc_ringbuf_get_read_addr(buf
), *len
);
132 out
[*len
- 1] = '\0';