Skip to content

Commit e6c916f

Browse files
committed
Consider cgroup when determining memory usage
This change modifies the oscap_sys_memusage function to take into account the memory constraints of the cgroup. Both cgroup and cgroup2 are supported.
1 parent 1347831 commit e6c916f

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

src/common/memusage.c

+44-7
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@
4848
#define GET_VM_FREE_PAGE_COUNT "vm.stats.vm.v_free_count"
4949
#define GET_VM_INACT_PAGE_COUNT "vm.stats.vm.v_inactive_count"
5050
#define GET_VM_ACT_PAGE_COUNT "vm.stats.vm.v_active_count"
51+
#endif
5152

5253
#define BYTES_TO_KIB(x) (x >> 10)
53-
#endif
5454

5555
#include "debug_priv.h"
5656
#include "memusage.h"
@@ -173,6 +173,26 @@ static int read_status(const char *source, void *base, struct stat_parser *spt,
173173
return processed == spt_size ? 0 : 1;
174174
}
175175

176+
static size_t get_sys_value(const char *source)
177+
{
178+
FILE *f;
179+
size_t v;
180+
181+
f = fopen(source, "r");
182+
if (f == NULL) {
183+
return (size_t)-1;
184+
}
185+
186+
if (fscanf(f, "%zu", &v) != 1) {
187+
fclose(f);
188+
return (size_t)-1;
189+
}
190+
191+
fclose(f);
192+
193+
return v;
194+
}
195+
176196
#define stat_sizet_field(name, stype, sfield) \
177197
{ (name), &read_common_sizet, (ptrdiff_t)offsetof(stype, sfield) }
178198

@@ -294,14 +314,31 @@ int oscap_sys_memusage(struct sys_memusage *mu)
294314
if (mu == NULL)
295315
return -1;
296316
#if defined(OS_LINUX)
297-
if (read_status(MEMUSAGE_LINUX_SYS_STATUS,
298-
mu, __sys_stat_ptable,
299-
(sizeof __sys_stat_ptable)/sizeof(struct stat_parser)) != 0)
300-
{
301-
return -1;
317+
// cgroup
318+
size_t cgroup_memory_usage = get_sys_value(MEMUSAGE_LINUX_SYS_CGROUP_USAGE);
319+
size_t cgroup_memory_limit = get_sys_value(MEMUSAGE_LINUX_SYS_CGROUP_LIMIT);
320+
if (cgroup_memory_usage != (size_t)-1 && cgroup_memory_limit != (size_t)-1) {
321+
mu->mu_total = BYTES_TO_KIB(cgroup_memory_limit);
322+
mu->mu_realfree = BYTES_TO_KIB(cgroup_memory_limit) - BYTES_TO_KIB(cgroup_memory_usage);
323+
} else {
324+
// cgroup2
325+
size_t cgroup_memory_current = get_sys_value(MEMUSAGE_LINUX_SYS_CGROUP2_CURRENT);
326+
size_t cgroup_memory_max = get_sys_value(MEMUSAGE_LINUX_SYS_CGROUP2_MAX);
327+
if (cgroup_memory_current != (size_t)-1 && cgroup_memory_max != (size_t)-1) {
328+
mu->mu_total = BYTES_TO_KIB(cgroup_memory_max);
329+
mu->mu_realfree = BYTES_TO_KIB(cgroup_memory_max) - BYTES_TO_KIB(cgroup_memory_current);
330+
} else {
331+
if (read_status(MEMUSAGE_LINUX_SYS_STATUS,
332+
mu, __sys_stat_ptable,
333+
(sizeof __sys_stat_ptable)/sizeof(struct stat_parser)) != 0)
334+
{
335+
return -1;
336+
}
337+
338+
mu->mu_realfree = mu->mu_free + mu->mu_cached + mu->mu_buffers;
339+
}
302340
}
303341

304-
mu->mu_realfree = mu->mu_free + mu->mu_cached + mu->mu_buffers;
305342
#elif defined(OS_FREEBSD)
306343
if (freebsd_sys_memusage(mu))
307344
return -1;

src/common/memusage.h

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
# define MEMUSAGE_LINUX_PROC_ENV "MEMUSAGE_PROC_STATUS"
99
# define MEMUSAGE_LINUX_SYS_STATUS "/proc/meminfo"
1010
# define MEMUSAGE_LINUX_SYS_ENV "MEMUSAGE_SYS_STATUS"
11+
# define MEMUSAGE_LINUX_SYS_CGROUP_USAGE "/sys/fs/cgroup/memory/memory.usage_in_bytes"
12+
# define MEMUSAGE_LINUX_SYS_CGROUP_LIMIT "/sys/fs/cgroup/memory/memory.limit_in_bytes"
13+
# define MEMUSAGE_LINUX_SYS_CGROUP2_CURRENT "/sys/fs/cgroup/memory.current"
14+
# define MEMUSAGE_LINUX_SYS_CGROUP2_MAX "/sys/fs/cgroup/memory.max"
15+
1116
#endif /* OS_LINUX */
1217

1318
struct proc_memusage {

0 commit comments

Comments
 (0)