1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
From ba823cc3cd2ea8b7eef714c317a212a9d7b5afe0 Mon Sep 17 00:00:00 2001
From: Anoop Rachakonda <anooprac@utexas.edu>
Date: Wed, 1 May 2024 13:56:30 -0500
Subject: [PATCH] stats_get: Changed paths to be aligned with cgroup2
specifications
Closes #4376
Signed-off-by: Devon Schwartz <devon.s.schwartz@utexas.edu>
---
src/lxc/tools/lxc_top.c | 64 ++++++++++++++++++++++++++++++++---------
1 file changed, 51 insertions(+), 13 deletions(-)
diff --git a/src/lxc/tools/lxc_top.c b/src/lxc/tools/lxc_top.c
index aa6e7209e3..f27025f730 100644
--- a/src/lxc/tools/lxc_top.c
+++ b/src/lxc/tools/lxc_top.c
@@ -276,27 +276,33 @@ static uint64_t stat_match_get_int(struct lxc_container *c, const char *item,
Total 149327872
*/
static void stat_get_blk_stats(struct lxc_container *c, const char *item,
- struct blkio_stats *stats) {
+ struct blkio_stats *stats, bool *success) {
char buf[4096];
int i, len;
char **lines, **cols;
+ *success = true;
len = c->get_cgroup_item(c, item, buf, sizeof(buf));
if (len <= 0 || (size_t)len >= sizeof(buf)) {
fprintf(stderr, "Unable to read cgroup item %s\n", item);
+ *success = false;
return;
}
lines = lxc_string_split_and_trim(buf, '\n');
- if (!lines)
+ if (!lines) {
+ *success = false;
return;
+ }
memset(stats, 0, sizeof(struct blkio_stats));
for (i = 0; lines[i]; i++) {
cols = lxc_string_split_and_trim(lines[i], ' ');
- if (!cols)
+ if (!cols) {
+ *success = false;
goto out;
+ }
if (strncmp(cols[1], "Read", strlen(cols[1])) == 0)
stats->read += strtoull(cols[2], NULL, 0);
@@ -314,21 +320,53 @@ static void stat_get_blk_stats(struct lxc_container *c, const char *item,
return;
}
+static void try_cgroup2(struct lxc_container *c, u_int64_t *stat, const char* path_cgroup1, const char* path_cgroup2,
+ const char* match, bool call_match) {
+
+ int ret_cgroup2;
+
+ if (call_match) {
+ ret_cgroup2 = stat_match_get_int(c, path_cgroup2, match, 1);
+ if (ret_cgroup2 < 0) {
+ *stat = stat_match_get_int(c, path_cgroup1, match, 1);
+ }
+
+ } else {
+ ret_cgroup2 = stat_get_int(c, path_cgroup2);
+
+ if (ret_cgroup2 < 0) {
+ *stat = stat_get_int(c, path_cgroup1);
+ } else {
+ *stat = ret_cgroup2;
+ }
+ }
+}
+
+
static void stats_get(struct lxc_container *c, struct container_stats *ct, struct stats *total)
{
ct->c = c;
- ct->stats->mem_used = stat_get_int(c, "memory.usage_in_bytes");
- ct->stats->mem_limit = stat_get_int(c, "memory.limit_in_bytes");
- ct->stats->memsw_used = stat_get_int(c, "memory.memsw.usage_in_bytes");
- ct->stats->memsw_limit = stat_get_int(c, "memory.memsw.limit_in_bytes");
+
+ // handle stat_get_int cases
+ try_cgroup2(c, &(ct->stats->mem_used), "memory.usage_in_bytes", "memory.current", NULL, false);
+ try_cgroup2(c, &(ct->stats->mem_limit), "memory.limit_in_bytes", "memory.max", NULL, false);
+ try_cgroup2(c, &(ct->stats->memsw_used), "memory.memsw.usage_in_bytes", "memory.swap.current", NULL, false);
+ try_cgroup2(c, &(ct->stats->memsw_limit), "memory.memsw.limit_in_bytes", "memory.swap.max", NULL, false);
+ try_cgroup2(c, &(ct->stats->cpu_use_nanos), "cpuacct.usage", "cpu.stat", NULL, false);
+ try_cgroup2(c, &(ct->stats->cpu_use_user), "cpuacct.stat", "cpu.stat", "user", true);
+ try_cgroup2(c, &(ct->stats->cpu_use_sys), "cpuacct.stat", "cpu.stat", "system", true);
+
+ // singular cgroup2 case for get blk stats
+ bool success;
+ stat_get_blk_stats(c, "io.stat", &ct->stats->io_service_bytes, &success);
+ if (!success) {
+ stat_get_blk_stats(c, "blkio.throttle.io_service_bytes", &ct->stats->io_service_bytes, &success);
+ }
+
+ // paths only exist in cgroup1
ct->stats->kmem_used = stat_get_int(c, "memory.kmem.usage_in_bytes");
ct->stats->kmem_limit = stat_get_int(c, "memory.kmem.limit_in_bytes");
- ct->stats->cpu_use_nanos = stat_get_int(c, "cpuacct.usage");
- ct->stats->cpu_use_user = stat_match_get_int(c, "cpuacct.stat", "user", 1);
- ct->stats->cpu_use_sys = stat_match_get_int(c, "cpuacct.stat", "system", 1);
-
- stat_get_blk_stats(c, "blkio.throttle.io_service_bytes", &ct->stats->io_service_bytes);
- stat_get_blk_stats(c, "blkio.throttle.io_serviced", &ct->stats->io_serviced);
+ stat_get_blk_stats(c, "blkio.throttle.io_serviced", &ct->stats->io_serviced, &success);
if (total) {
total->mem_used = total->mem_used + ct->stats->mem_used;
|