unified cgroup support (#5407)
* WiP unified cgroup support * add cpu usage support and disk iops support * memory limits * WIP working memory charts * detailed memory chart * docs change
skrzyp1 committed
Apr 9, 2019 at 11:36 UTC
6724b631de8eae6bdc6825adf1ca6a3c609835fd
3 files changed
+590
-273
CONTRIBUTORS.md
+1
@@ -123,5 +123,6 @@ username|name|email (optional)
123
@vladmovchan|Vladyslav Movchan|vladislav.movchan@gmail.com
124
@gmosx|George Moschovitis
125
@adherzog|Adam Herzog|adam@adamherzog.com
126
+@skrzyp1|Jerzy S.|
127
128
[]()
collectors/cgroups.plugin/README.md
+12
@@ -56,6 +56,18 @@ To provide a sane default for this setting, netdata uses the following pattern l
56
57
So, we disable checking for **child cgroups** in systemd internal cgroups ([systemd services are monitored by netdata](#monitoring-systemd-services)), user cgroups (normally used for desktop and remote user sessions), qemu virtual machines (child cgroups of virtual machines) and `init.scope`. All others are enabled.
58
59
+### unified cgroups (cgroups v2) support
60
+
61
+Basic unified cgroups metrics are supported. To use them instead of v1 cgroups add:
62
+
63
+```
64
+[plugin:cgroups]
65
+ use unified cgroups = yes
66
+ path to unified cgroups = /sys/fs/cgroup
67
+```
68
+
69
+Unified cgroups use same name pattern matching as v1 cgroups. `cgroup_enable_systemd_services_detailed_memory` is currently unsupported when using unified cgroups.
70
+
71
72
### enabled cgroups
73
collectors/cgroups.plugin/sys_fs_cgroup.c
+577
-273
@@ -28,6 +28,9 @@ static int cgroup_enable_systemd_services = CONFIG_BOOLEAN_YES;
28
static int cgroup_enable_systemd_services_detailed_memory = CONFIG_BOOLEAN_NO;
29
static int cgroup_used_memory_without_cache = CONFIG_BOOLEAN_YES;
30
31
+static int cgroup_use_unified_cgroups = CONFIG_BOOLEAN_NO;
32
+static int cgroup_unified_exist = CONFIG_BOOLEAN_AUTO;
33
+
34
static int cgroup_search_in_devices = 1;
35
36
static int cgroup_enable_new_cgroups_detected_at_runtime = 1;
@@ -44,6 +47,7 @@ static char *cgroup_cpuset_base = NULL;
47
static char *cgroup_blkio_base = NULL;
48
static char *cgroup_memory_base = NULL;
49
static char *cgroup_devices_base = NULL;
50
+static char *cgroup_unified_base = NULL;
51
52
static int cgroup_root_count = 0;
53
static int cgroup_root_max = 1000;
@@ -80,6 +84,8 @@ void read_cgroup_plugin_configuration() {
84
if(cgroup_check_for_new_every < cgroup_update_every)
85
cgroup_check_for_new_every = cgroup_update_every;
86
87
+ cgroup_use_unified_cgroups = config_get_boolean_ondemand("plugin:cgroups", "use unified cgroups", cgroup_use_unified_cgroups);
88
+
89
cgroup_containers_chart_priority = (int)config_get_number("plugin:cgroups", "containers priority", cgroup_containers_chart_priority);
90
if(cgroup_containers_chart_priority < 1)
91
cgroup_containers_chart_priority = NETDATA_CHART_PRIO_CGROUPS_CONTAINERS;
@@ -109,56 +115,90 @@ void read_cgroup_plugin_configuration() {
115
116
char filename[FILENAME_MAX + 1], *s;
117
struct mountinfo *mi, *root = mountinfo_read(0);
112
-
113
- mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "cpuacct");
114
- if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "cpuacct");
115
- if(!mi) {
116
- error("CGROUP: cannot find cpuacct mountinfo. Assuming default: /sys/fs/cgroup/cpuacct");
117
- s = "/sys/fs/cgroup/cpuacct";
118
- }
119
- else s = mi->mount_point;
120
- snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
121
- cgroup_cpuacct_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/cpuacct", filename);
122
-
123
- mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "cpuset");
124
- if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "cpuset");
125
- if(!mi) {
126
- error("CGROUP: cannot find cpuset mountinfo. Assuming default: /sys/fs/cgroup/cpuset");
127
- s = "/sys/fs/cgroup/cpuset";
128
- }
129
- else s = mi->mount_point;
130
- snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
131
- cgroup_cpuset_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/cpuset", filename);
132
-
133
- mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "blkio");
134
- if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "blkio");
135
- if(!mi) {
136
- error("CGROUP: cannot find blkio mountinfo. Assuming default: /sys/fs/cgroup/blkio");
137
- s = "/sys/fs/cgroup/blkio";
138
- }
139
- else s = mi->mount_point;
140
- snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
141
- cgroup_blkio_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/blkio", filename);
142
-
143
- mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "memory");
144
- if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "memory");
145
- if(!mi) {
146
- error("CGROUP: cannot find memory mountinfo. Assuming default: /sys/fs/cgroup/memory");
147
- s = "/sys/fs/cgroup/memory";
118
+ if(!cgroup_use_unified_cgroups) {
119
+ mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "cpuacct");
120
+ if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "cpuacct");
121
+ if(!mi) {
122
+ error("CGROUP: cannot find cpuacct mountinfo. Assuming default: /sys/fs/cgroup/cpuacct");
123
+ s = "/sys/fs/cgroup/cpuacct";
124
+ }
125
+ else s = mi->mount_point;
126
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
127
+ cgroup_cpuacct_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/cpuacct", filename);
128
+
129
+ mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "cpuset");
130
+ if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "cpuset");
131
+ if(!mi) {
132
+ error("CGROUP: cannot find cpuset mountinfo. Assuming default: /sys/fs/cgroup/cpuset");
133
+ s = "/sys/fs/cgroup/cpuset";
134
+ }
135
+ else s = mi->mount_point;
136
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
137
+ cgroup_cpuset_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/cpuset", filename);
138
+
139
+ mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "blkio");
140
+ if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "blkio");
141
+ if(!mi) {
142
+ error("CGROUP: cannot find blkio mountinfo. Assuming default: /sys/fs/cgroup/blkio");
143
+ s = "/sys/fs/cgroup/blkio";
144
+ }
145
+ else s = mi->mount_point;
146
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
147
+ cgroup_blkio_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/blkio", filename);
148
+
149
+ mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "memory");
150
+ if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "memory");
151
+ if(!mi) {
152
+ error("CGROUP: cannot find memory mountinfo. Assuming default: /sys/fs/cgroup/memory");
153
+ s = "/sys/fs/cgroup/memory";
154
+ }
155
+ else s = mi->mount_point;
156
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
157
+ cgroup_memory_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/memory", filename);
158
+
159
+ mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "devices");
160
+ if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "devices");
161
+ if(!mi) {
162
+ error("CGROUP: cannot find devices mountinfo. Assuming default: /sys/fs/cgroup/devices");
163
+ s = "/sys/fs/cgroup/devices";
164
+ }
165
+ else s = mi->mount_point;
166
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
167
+ cgroup_devices_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/devices", filename);
168
}
149
- else s = mi->mount_point;
150
- snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
151
- cgroup_memory_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/memory", filename);
152
-
153
- mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "devices");
154
- if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "devices");
155
- if(!mi) {
156
- error("CGROUP: cannot find devices mountinfo. Assuming default: /sys/fs/cgroup/devices");
157
- s = "/sys/fs/cgroup/devices";
169
+ else {
170
+ //cgroup_enable_cpuacct_stat =
171
+ cgroup_enable_cpuacct_usage =
172
+ //cgroup_enable_memory =
173
+ //cgroup_enable_detailed_memory =
174
+ cgroup_enable_memory_failcnt =
175
+ //cgroup_enable_swap =
176
+ //cgroup_enable_blkio_io =
177
+ //cgroup_enable_blkio_ops =
178
+ cgroup_enable_blkio_throttle_io =
179
+ cgroup_enable_blkio_throttle_ops =
180
+ cgroup_enable_blkio_merged_ops =
181
+ cgroup_enable_blkio_queued_ops = CONFIG_BOOLEAN_NO;
182
+ cgroup_search_in_devices = 0;
183
+ cgroup_enable_systemd_services_detailed_memory = CONFIG_BOOLEAN_NO;
184
+ cgroup_used_memory_without_cache = CONFIG_BOOLEAN_NO; //unified cgroups use different values
185
+
186
+ //TODO: can there be more than 1 cgroup2 mount point?
187
+ mi = mountinfo_find_by_filesystem_super_option(root, "cgroup2", "rw"); //there is no cgroup2 specific super option - for now use 'rw' option
188
+ if(mi) debug(D_CGROUP, "found unified cgroup root using super options, with path: '%s'", mi->mount_point);
189
+ if(!mi) {
190
+ mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup2", "cgroup");
191
+ if(mi) debug(D_CGROUP, "found unified cgroup root using mountsource info, with path: '%s'", mi->mount_point);
192
+ }
193
+ if(!mi) {
194
+ error("CGROUP: cannot find cgroup2 mountinfo. Assuming default: /sys/fs/cgroup");
195
+ s = "/sys/fs/cgroup";
196
+ }
197
+ else s = mi->mount_point;
198
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
199
+ cgroup_unified_base = config_get("plugin:cgroups", "path to unified cgroups", filename);
200
+ debug(D_CGROUP, "using cgroup root: '%s'", cgroup_unified_base);
201
}
159
- else s = mi->mount_point;
160
- snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s);
161
- cgroup_devices_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/devices", filename);
202
203
cgroup_root_max = (int)config_get_number("plugin:cgroups", "max cgroups to allow", cgroup_root_max);
204
cgroup_max_depth = (int)config_get_number("plugin:cgroups", "max cgroups depth to monitor", cgroup_max_depth);
@@ -321,6 +361,17 @@ struct memory {
361
unsigned long long unevictable;
362
unsigned long long hierarchical_memory_limit;
363
*/
364
+ //unified cgroups metrics
365
+ unsigned long long anon;
366
+ unsigned long long kernel_stack;
367
+ unsigned long long slab;
368
+ unsigned long long sock;
369
+ unsigned long long shmem;
370
+ unsigned long long anon_thp;
371
+ //unsigned long long file_writeback;
372
+ //unsigned long long file_dirty;
373
+ //unsigned long long file;
374
+
375
unsigned long long total_cache;
376
unsigned long long total_rss;
377
unsigned long long total_rss_huge;
@@ -376,6 +427,7 @@ struct cgroup_network_interface {
427
428
#define CGROUP_OPTIONS_DISABLED_DUPLICATE 0x00000001
429
#define CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE 0x00000002
430
+#define CGROUP_OPTIONS_IS_UNIFIED 0x00000004
431
432
struct cgroup {
433
uint32_t options;
@@ -528,6 +580,42 @@ static inline void cgroup_read_cpuacct_stat(struct cpuacct_stat *cp) {
580
}
581
}
582
583
+static inline void cgroup2_read_cpuacct_stat(struct cpuacct_stat *cp) {
584
+ static procfile *ff = NULL;
585
+
586
+ if(likely(cp->filename)) {
587
+ ff = procfile_reopen(ff, cp->filename, NULL, PROCFILE_FLAG_DEFAULT);
588
+ if(unlikely(!ff)) {
589
+ cp->updated = 0;
590
+ cgroups_check = 1;
591
+ return;
592
+ }
593
+
594
+ ff = procfile_readall(ff);
595
+ if(unlikely(!ff)) {
596
+ cp->updated = 0;
597
+ cgroups_check = 1;
598
+ return;
599
+ }
600
+
601
+ unsigned long lines = procfile_lines(ff);
602
+
603
+ if(unlikely(lines < 3)) {
604
+ error("CGROUP: file '%s' should have 3+ lines.", cp->filename);
605
+ cp->updated = 0;
606
+ return;
607
+ }
608
+
609
+ cp->user = str2ull(procfile_lineword(ff, 1, 1));
610
+ cp->system = str2ull(procfile_lineword(ff, 2, 1));
611
+
612
+ cp->updated = 1;
613
+
614
+ if(unlikely(cp->enabled == CONFIG_BOOLEAN_AUTO && (cp->user || cp->system)))
615
+ cp->enabled = CONFIG_BOOLEAN_YES;
616
+ }
617
+}
618
+
619
static inline void cgroup_read_cpuacct_usage(struct cpuacct_usage *ca) {
620
static procfile *ff = NULL;
621
@@ -657,7 +745,57 @@ static inline void cgroup_read_blkio(struct blkio *io) {
745
}
746
}
747
660
-static inline void cgroup_read_memory(struct memory *mem) {
748
+static inline void cgroup2_read_blkio(struct blkio *io, unsigned int word_offset) {
749
+ if(unlikely(io->enabled == CONFIG_BOOLEAN_AUTO && io->delay_counter > 0)) {
750
+ io->delay_counter--;
751
+ return;
752
+ }
753
+
754
+ if(likely(io->filename)) {
755
+ static procfile *ff = NULL;
756
+
757
+ ff = procfile_reopen(ff, io->filename, NULL, PROCFILE_FLAG_DEFAULT);
758
+ if(unlikely(!ff)) {
759
+ io->updated = 0;
760
+ cgroups_check = 1;
761
+ return;
762
+ }
763
+
764
+ ff = procfile_readall(ff);
765
+ if(unlikely(!ff)) {
766
+ io->updated = 0;
767
+ cgroups_check = 1;
768
+ return;
769
+ }
770
+
771
+ unsigned long i, lines = procfile_lines(ff);
772
+
773
+ if (unlikely(lines < 1)) {
774
+ error("CGROUP: file '%s' should have 1+ lines.", io->filename);
775
+ io->updated = 0;
776
+ return;
777
+ }
778
+
779
+ io->Read = 0;
780
+ io->Write = 0;
781
+
782
+ for (i = 0; i < lines; i++) {
783
+ io->Read += str2ull(procfile_lineword(ff, i, 2 + word_offset));
784
+ io->Write += str2ull(procfile_lineword(ff, i, 4 + word_offset));
785
+ }
786
+
787
+ io->updated = 1;
788
+
789
+ if(unlikely(io->enabled == CONFIG_BOOLEAN_AUTO)) {
790
+ if(unlikely(io->Read || io->Write))
791
+ io->enabled = CONFIG_BOOLEAN_YES;
792
+ else
793
+ io->delay_counter = cgroup_recheck_zero_blkio_every_iterations;
794
+ }
795
+ }
796
+}
797
+
798
+static inline void cgroup_read_memory(struct memory *mem, char parent_cg_is_unified) {
799
static procfile *ff = NULL;
800
801
// read detailed ram usage
@@ -689,20 +827,36 @@ static inline void cgroup_read_memory(struct memory *mem) {
827
goto memory_next;
828
}
829
692
- if(unlikely(!mem->arl_base)) {
693
- mem->arl_base = arl_create("cgroup/memory", NULL, 60);
830
695
- arl_expect(mem->arl_base, "total_cache", &mem->total_cache);
696
- arl_expect(mem->arl_base, "total_rss", &mem->total_rss);
697
- arl_expect(mem->arl_base, "total_rss_huge", &mem->total_rss_huge);
698
- arl_expect(mem->arl_base, "total_mapped_file", &mem->total_mapped_file);
699
- arl_expect(mem->arl_base, "total_writeback", &mem->total_writeback);
700
- mem->arl_dirty = arl_expect(mem->arl_base, "total_dirty", &mem->total_dirty);
701
- mem->arl_swap = arl_expect(mem->arl_base, "total_swap", &mem->total_swap);
702
- arl_expect(mem->arl_base, "total_pgpgin", &mem->total_pgpgin);
703
- arl_expect(mem->arl_base, "total_pgpgout", &mem->total_pgpgout);
704
- arl_expect(mem->arl_base, "total_pgfault", &mem->total_pgfault);
705
- arl_expect(mem->arl_base, "total_pgmajfault", &mem->total_pgmajfault);
831
+ if(unlikely(!mem->arl_base)) {
832
+ if(parent_cg_is_unified == 0){
833
+ mem->arl_base = arl_create("cgroup/memory", NULL, 60);
834
+
835
+ arl_expect(mem->arl_base, "total_cache", &mem->total_cache);
836
+ arl_expect(mem->arl_base, "total_rss", &mem->total_rss);
837
+ arl_expect(mem->arl_base, "total_rss_huge", &mem->total_rss_huge);
838
+ arl_expect(mem->arl_base, "total_mapped_file", &mem->total_mapped_file);
839
+ arl_expect(mem->arl_base, "total_writeback", &mem->total_writeback);
840
+ mem->arl_dirty = arl_expect(mem->arl_base, "total_dirty", &mem->total_dirty);
841
+ mem->arl_swap = arl_expect(mem->arl_base, "total_swap", &mem->total_swap);
842
+ arl_expect(mem->arl_base, "total_pgpgin", &mem->total_pgpgin);
843
+ arl_expect(mem->arl_base, "total_pgpgout", &mem->total_pgpgout);
844
+ arl_expect(mem->arl_base, "total_pgfault", &mem->total_pgfault);
845
+ arl_expect(mem->arl_base, "total_pgmajfault", &mem->total_pgmajfault);
846
+ } else {
847
+ mem->arl_base = arl_create("cgroup/memory", NULL, 60);
848
+
849
+ arl_expect(mem->arl_base, "anon", &mem->anon);
850
+ arl_expect(mem->arl_base, "kernel_stack", &mem->kernel_stack);
851
+ arl_expect(mem->arl_base, "slab", &mem->slab);
852
+ arl_expect(mem->arl_base, "sock", &mem->sock);
853
+ arl_expect(mem->arl_base, "anon_thp", &mem->anon_thp);
854
+ arl_expect(mem->arl_base, "file", &mem->total_mapped_file);
855
+ arl_expect(mem->arl_base, "file_writeback", &mem->total_writeback);
856
+ mem->arl_dirty = arl_expect(mem->arl_base, "file_dirty", &mem->total_dirty);
857
+ arl_expect(mem->arl_base, "pgfault", &mem->total_pgfault);
858
+ arl_expect(mem->arl_base, "pgmajfault", &mem->total_pgmajfault);
859
+ }
860
}
861
862
arl_begin(mem->arl_base);
@@ -716,7 +870,7 @@ static inline void cgroup_read_memory(struct memory *mem) {
870
if(unlikely(mem->arl_dirty->flags & ARL_ENTRY_FLAG_FOUND))
871
mem->detailed_has_dirty = 1;
872
719
- if(unlikely(mem->arl_swap->flags & ARL_ENTRY_FLAG_FOUND))
873
+ if(unlikely(parent_cg_is_unified == 0 && mem->arl_swap->flags & ARL_ENTRY_FLAG_FOUND))
874
mem->detailed_has_swap = 1;
875
876
// fprintf(stderr, "READ: '%s', cache: %llu, rss: %llu, rss_huge: %llu, mapped_file: %llu, writeback: %llu, dirty: %llu, swap: %llu, pgpgin: %llu, pgpgout: %llu, pgfault: %llu, pgmajfault: %llu, inactive_anon: %llu, active_anon: %llu, inactive_file: %llu, active_file: %llu, unevictable: %llu, hierarchical_memory_limit: %llu, total_cache: %llu, total_rss: %llu, total_rss_huge: %llu, total_mapped_file: %llu, total_writeback: %llu, total_dirty: %llu, total_swap: %llu, total_pgpgin: %llu, total_pgpgout: %llu, total_pgfault: %llu, total_pgmajfault: %llu, total_inactive_anon: %llu, total_active_anon: %llu, total_inactive_file: %llu, total_active_file: %llu, total_unevictable: %llu\n", mem->filename, mem->cache, mem->rss, mem->rss_huge, mem->mapped_file, mem->writeback, mem->dirty, mem->swap, mem->pgpgin, mem->pgpgout, mem->pgfault, mem->pgmajfault, mem->inactive_anon, mem->active_anon, mem->inactive_file, mem->active_file, mem->unevictable, mem->hierarchical_memory_limit, mem->total_cache, mem->total_rss, mem->total_rss_huge, mem->total_mapped_file, mem->total_writeback, mem->total_dirty, mem->total_swap, mem->total_pgpgin, mem->total_pgpgout, mem->total_pgfault, mem->total_pgmajfault, mem->total_inactive_anon, mem->total_active_anon, mem->total_inactive_file, mem->total_active_file, mem->total_unevictable);
@@ -724,8 +878,10 @@ static inline void cgroup_read_memory(struct memory *mem) {
878
mem->updated_detailed = 1;
879
880
if(unlikely(mem->enabled_detailed == CONFIG_BOOLEAN_AUTO)) {
727
- if(mem->total_cache || mem->total_dirty || mem->total_rss || mem->total_rss_huge || mem->total_mapped_file || mem->total_writeback
728
- || mem->total_swap || mem->total_pgpgin || mem->total_pgpgout || mem->total_pgfault || mem->total_pgmajfault)
881
+ if(( (!parent_cg_is_unified) && ( mem->total_cache || mem->total_dirty || mem->total_rss || mem->total_rss_huge || mem->total_mapped_file || mem->total_writeback
882
+ || mem->total_swap || mem->total_pgpgin || mem->total_pgpgout || mem->total_pgfault || mem->total_pgmajfault))
883
+ || (parent_cg_is_unified && ( mem->anon || mem->total_dirty || mem->kernel_stack || mem->slab || mem->sock || mem->total_writeback
884
+ || mem->anon_thp || mem->total_pgfault || mem->total_pgmajfault)))
885
mem->enabled_detailed = CONFIG_BOOLEAN_YES;
886
else
887
mem->delay_counter_detailed = cgroup_recheck_zero_mem_detailed_every_iterations;
@@ -768,16 +924,24 @@ memory_next:
924
925
static inline void cgroup_read(struct cgroup *cg) {
926
debug(D_CGROUP, "reading metrics for cgroups '%s'", cg->id);
771
-
772
- cgroup_read_cpuacct_stat(&cg->cpuacct_stat);
773
- cgroup_read_cpuacct_usage(&cg->cpuacct_usage);
774
- cgroup_read_memory(&cg->memory);
775
- cgroup_read_blkio(&cg->io_service_bytes);
776
- cgroup_read_blkio(&cg->io_serviced);
777
- cgroup_read_blkio(&cg->throttle_io_service_bytes);
778
- cgroup_read_blkio(&cg->throttle_io_serviced);
779
- cgroup_read_blkio(&cg->io_merged);
780
- cgroup_read_blkio(&cg->io_queued);
927
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
928
+ cgroup_read_cpuacct_stat(&cg->cpuacct_stat);
929
+ cgroup_read_cpuacct_usage(&cg->cpuacct_usage);
930
+ cgroup_read_memory(&cg->memory, 0);
931
+ cgroup_read_blkio(&cg->io_service_bytes);
932
+ cgroup_read_blkio(&cg->io_serviced);
933
+ cgroup_read_blkio(&cg->throttle_io_service_bytes);
934
+ cgroup_read_blkio(&cg->throttle_io_serviced);
935
+ cgroup_read_blkio(&cg->io_merged);
936
+ cgroup_read_blkio(&cg->io_queued);
937
+ }
938
+ else {
939
+ //TODO: io_service_bytes and io_serviced use same file merge into 1 function
940
+ cgroup2_read_blkio(&cg->io_service_bytes, 0);
941
+ cgroup2_read_blkio(&cg->io_serviced, 4);
942
+ cgroup2_read_cpuacct_stat(&cg->cpuacct_stat);
943
+ cgroup_read_memory(&cg->memory, 1);
944
+ }
945
}
946
947
static inline void read_all_cgroups(struct cgroup *root) {
@@ -800,7 +964,12 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) {
964
pid_t cgroup_pid;
965
char command[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1];
966
803
- snprintfz(command, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec %s --cgroup '%s%s'", cgroups_network_interface_script, cgroup_cpuacct_base, cg->id);
967
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
968
+ snprintfz(command, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec %s --cgroup '%s%s'", cgroups_network_interface_script, cgroup_cpuacct_base, cg->id);
969
+ }
970
+ else {
971
+ snprintfz(command, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec %s --cgroup '%s%s'", cgroups_network_interface_script, cgroup_unified_base, cg->id);
972
+ }
973
974
debug(D_CGROUP, "executing command '%s' for cgroup '%s'", command, cg->id);
975
FILE *fp = mypopen(command, &cgroup_pid);
@@ -955,6 +1124,8 @@ static inline struct cgroup *cgroup_add(const char *id) {
1124
cg->chart_id = cgroup_chart_id_strdupz(id);
1125
cg->hash_chart = simple_hash(cg->chart_id);
1126
1127
+ if(cgroup_use_unified_cgroups) cg->options |= CGROUP_OPTIONS_IS_UNIFIED;
1128
+
1129
if(!cgroup_root)
1130
cgroup_root = cg;
1131
else {
@@ -1295,41 +1466,48 @@ static inline void find_all_cgroups() {
1466
debug(D_CGROUP, "searching for cgroups");
1467
1468
mark_all_cgroups_as_not_available();
1469
+ if(!cgroup_use_unified_cgroups) {
1470
+ if(cgroup_enable_cpuacct_stat || cgroup_enable_cpuacct_usage) {
1471
+ if(find_dir_in_subdirs(cgroup_cpuacct_base, NULL, found_subdir_in_dir) == -1) {
1472
+ cgroup_enable_cpuacct_stat =
1473
+ cgroup_enable_cpuacct_usage = CONFIG_BOOLEAN_NO;
1474
+ error("CGROUP: disabled cpu statistics.");
1475
+ }
1476
+ }
1477
1299
- if(cgroup_enable_cpuacct_stat || cgroup_enable_cpuacct_usage) {
1300
- if(find_dir_in_subdirs(cgroup_cpuacct_base, NULL, found_subdir_in_dir) == -1) {
1301
- cgroup_enable_cpuacct_stat =
1302
- cgroup_enable_cpuacct_usage = CONFIG_BOOLEAN_NO;
1303
- error("CGROUP: disabled cpu statistics.");
1478
+ if(cgroup_enable_blkio_io || cgroup_enable_blkio_ops || cgroup_enable_blkio_throttle_io || cgroup_enable_blkio_throttle_ops || cgroup_enable_blkio_merged_ops || cgroup_enable_blkio_queued_ops) {
1479
+ if(find_dir_in_subdirs(cgroup_blkio_base, NULL, found_subdir_in_dir) == -1) {
1480
+ cgroup_enable_blkio_io =
1481
+ cgroup_enable_blkio_ops =
1482
+ cgroup_enable_blkio_throttle_io =
1483
+ cgroup_enable_blkio_throttle_ops =
1484
+ cgroup_enable_blkio_merged_ops =
1485
+ cgroup_enable_blkio_queued_ops = CONFIG_BOOLEAN_NO;
1486
+ error("CGROUP: disabled blkio statistics.");
1487
+ }
1488
}
1305
- }
1489
1307
- if(cgroup_enable_blkio_io || cgroup_enable_blkio_ops || cgroup_enable_blkio_throttle_io || cgroup_enable_blkio_throttle_ops || cgroup_enable_blkio_merged_ops || cgroup_enable_blkio_queued_ops) {
1308
- if(find_dir_in_subdirs(cgroup_blkio_base, NULL, found_subdir_in_dir) == -1) {
1309
- cgroup_enable_blkio_io =
1310
- cgroup_enable_blkio_ops =
1311
- cgroup_enable_blkio_throttle_io =
1312
- cgroup_enable_blkio_throttle_ops =
1313
- cgroup_enable_blkio_merged_ops =
1314
- cgroup_enable_blkio_queued_ops = CONFIG_BOOLEAN_NO;
1315
- error("CGROUP: disabled blkio statistics.");
1490
+ if(cgroup_enable_memory || cgroup_enable_detailed_memory || cgroup_enable_swap || cgroup_enable_memory_failcnt) {
1491
+ if(find_dir_in_subdirs(cgroup_memory_base, NULL, found_subdir_in_dir) == -1) {
1492
+ cgroup_enable_memory =
1493
+ cgroup_enable_detailed_memory =
1494
+ cgroup_enable_swap =
1495
+ cgroup_enable_memory_failcnt = CONFIG_BOOLEAN_NO;
1496
+ error("CGROUP: disabled memory statistics.");
1497
+ }
1498
}
1317
- }
1499
1319
- if(cgroup_enable_memory || cgroup_enable_detailed_memory || cgroup_enable_swap || cgroup_enable_memory_failcnt) {
1320
- if(find_dir_in_subdirs(cgroup_memory_base, NULL, found_subdir_in_dir) == -1) {
1321
- cgroup_enable_memory =
1322
- cgroup_enable_detailed_memory =
1323
- cgroup_enable_swap =
1324
- cgroup_enable_memory_failcnt = CONFIG_BOOLEAN_NO;
1325
- error("CGROUP: disabled memory statistics.");
1500
+ if(cgroup_search_in_devices) {
1501
+ if(find_dir_in_subdirs(cgroup_devices_base, NULL, found_subdir_in_dir) == -1) {
1502
+ cgroup_search_in_devices = 0;
1503
+ error("CGROUP: disabled devices statistics.");
1504
+ }
1505
}
1506
}
1328
-
1329
- if(cgroup_search_in_devices) {
1330
- if(find_dir_in_subdirs(cgroup_devices_base, NULL, found_subdir_in_dir) == -1) {
1331
- cgroup_search_in_devices = 0;
1332
- error("CGROUP: disabled devices statistics.");
1507
+ else {
1508
+ if (find_dir_in_subdirs(cgroup_unified_base, NULL, found_subdir_in_dir) == -1) {
1509
+ cgroup_unified_exist = CONFIG_BOOLEAN_NO;
1510
+ error("CGROUP: disabled unified cgroups statistics.");
1511
}
1512
}
1513
@@ -1352,146 +1530,217 @@ static inline void find_all_cgroups() {
1530
// check for newly added cgroups
1531
// and update the filenames they read
1532
char filename[FILENAME_MAX + 1];
1355
- if(unlikely(cgroup_enable_cpuacct_stat && !cg->cpuacct_stat.filename)) {
1356
- snprintfz(filename, FILENAME_MAX, "%s%s/cpuacct.stat", cgroup_cpuacct_base, cg->id);
1357
- if(likely(stat(filename, &buf) != -1)) {
1358
- cg->cpuacct_stat.filename = strdupz(filename);
1359
- cg->cpuacct_stat.enabled = cgroup_enable_cpuacct_stat;
1360
- snprintfz(filename, FILENAME_MAX, "%s%s/cpuset.cpus", cgroup_cpuset_base, cg->id);
1361
- cg->filename_cpuset_cpus = strdupz(filename);
1362
- snprintfz(filename, FILENAME_MAX, "%s%s/cpu.cfs_period_us", cgroup_cpuacct_base, cg->id);
1363
- cg->filename_cpu_cfs_period = strdupz(filename);
1364
- snprintfz(filename, FILENAME_MAX, "%s%s/cpu.cfs_quota_us", cgroup_cpuacct_base, cg->id);
1365
- cg->filename_cpu_cfs_quota = strdupz(filename);
1366
- debug(D_CGROUP, "cpuacct.stat filename for cgroup '%s': '%s'", cg->id, cg->cpuacct_stat.filename);
1533
+ if(!cgroup_use_unified_cgroups) {
1534
+ if(unlikely(cgroup_enable_cpuacct_stat && !cg->cpuacct_stat.filename)) {
1535
+ snprintfz(filename, FILENAME_MAX, "%s%s/cpuacct.stat", cgroup_cpuacct_base, cg->id);
1536
+ if(likely(stat(filename, &buf) != -1)) {
1537
+ cg->cpuacct_stat.filename = strdupz(filename);
1538
+ cg->cpuacct_stat.enabled = cgroup_enable_cpuacct_stat;
1539
+ snprintfz(filename, FILENAME_MAX, "%s%s/cpuset.cpus", cgroup_cpuset_base, cg->id);
1540
+ cg->filename_cpuset_cpus = strdupz(filename);
1541
+ snprintfz(filename, FILENAME_MAX, "%s%s/cpu.cfs_period_us", cgroup_cpuacct_base, cg->id);
1542
+ cg->filename_cpu_cfs_period = strdupz(filename);
1543
+ snprintfz(filename, FILENAME_MAX, "%s%s/cpu.cfs_quota_us", cgroup_cpuacct_base, cg->id);
1544
+ cg->filename_cpu_cfs_quota = strdupz(filename);
1545
+ debug(D_CGROUP, "cpuacct.stat filename for cgroup '%s': '%s'", cg->id, cg->cpuacct_stat.filename);
1546
+ }
1547
+ else
1548
+ debug(D_CGROUP, "cpuacct.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1549
}
1368
- else
1369
- debug(D_CGROUP, "cpuacct.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1370
- }
1550
1372
- if(unlikely(cgroup_enable_cpuacct_usage && !cg->cpuacct_usage.filename && !(cg->options & CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE))) {
1373
- snprintfz(filename, FILENAME_MAX, "%s%s/cpuacct.usage_percpu", cgroup_cpuacct_base, cg->id);
1374
- if(likely(stat(filename, &buf) != -1)) {
1375
- cg->cpuacct_usage.filename = strdupz(filename);
1376
- cg->cpuacct_usage.enabled = cgroup_enable_cpuacct_usage;
1377
- debug(D_CGROUP, "cpuacct.usage_percpu filename for cgroup '%s': '%s'", cg->id, cg->cpuacct_usage.filename);
1551
+ if(unlikely(cgroup_enable_cpuacct_usage && !cg->cpuacct_usage.filename && !(cg->options & CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE))) {
1552
+ snprintfz(filename, FILENAME_MAX, "%s%s/cpuacct.usage_percpu", cgroup_cpuacct_base, cg->id);
1553
+ if(likely(stat(filename, &buf) != -1)) {
1554
+ cg->cpuacct_usage.filename = strdupz(filename);
1555
+ cg->cpuacct_usage.enabled = cgroup_enable_cpuacct_usage;
1556
+ debug(D_CGROUP, "cpuacct.usage_percpu filename for cgroup '%s': '%s'", cg->id, cg->cpuacct_usage.filename);
1557
+ }
1558
+ else
1559
+ debug(D_CGROUP, "cpuacct.usage_percpu file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1560
}
1379
- else
1380
- debug(D_CGROUP, "cpuacct.usage_percpu file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1381
- }
1561
1383
- if(unlikely((cgroup_enable_detailed_memory || cgroup_used_memory_without_cache) && !cg->memory.filename_detailed && (cgroup_used_memory_without_cache || cgroup_enable_systemd_services_detailed_memory || !(cg->options & CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE)))) {
1384
- snprintfz(filename, FILENAME_MAX, "%s%s/memory.stat", cgroup_memory_base, cg->id);
1385
- if(likely(stat(filename, &buf) != -1)) {
1386
- cg->memory.filename_detailed = strdupz(filename);
1387
- cg->memory.enabled_detailed = (cgroup_enable_detailed_memory == CONFIG_BOOLEAN_YES)?CONFIG_BOOLEAN_YES:CONFIG_BOOLEAN_AUTO;
1388
- debug(D_CGROUP, "memory.stat filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_detailed);
1562
+ if(unlikely((cgroup_enable_detailed_memory || cgroup_used_memory_without_cache) && !cg->memory.filename_detailed && (cgroup_used_memory_without_cache || cgroup_enable_systemd_services_detailed_memory || !(cg->options & CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE)))) {
1563
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.stat", cgroup_memory_base, cg->id);
1564
+ if(likely(stat(filename, &buf) != -1)) {
1565
+ cg->memory.filename_detailed = strdupz(filename);
1566
+ cg->memory.enabled_detailed = (cgroup_enable_detailed_memory == CONFIG_BOOLEAN_YES)?CONFIG_BOOLEAN_YES:CONFIG_BOOLEAN_AUTO;
1567
+ debug(D_CGROUP, "memory.stat filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_detailed);
1568
+ }
1569
+ else
1570
+ debug(D_CGROUP, "memory.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1571
}
1390
- else
1391
- debug(D_CGROUP, "memory.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1392
- }
1572
1394
- if(unlikely(cgroup_enable_memory && !cg->memory.filename_usage_in_bytes)) {
1395
- snprintfz(filename, FILENAME_MAX, "%s%s/memory.usage_in_bytes", cgroup_memory_base, cg->id);
1396
- if(likely(stat(filename, &buf) != -1)) {
1397
- cg->memory.filename_usage_in_bytes = strdupz(filename);
1398
- cg->memory.enabled_usage_in_bytes = cgroup_enable_memory;
1399
- debug(D_CGROUP, "memory.usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_usage_in_bytes);
1400
- snprintfz(filename, FILENAME_MAX, "%s%s/memory.limit_in_bytes", cgroup_memory_base, cg->id);
1401
- cg->filename_memory_limit = strdupz(filename);
1573
+ if(unlikely(cgroup_enable_memory && !cg->memory.filename_usage_in_bytes)) {
1574
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.usage_in_bytes", cgroup_memory_base, cg->id);
1575
+ if(likely(stat(filename, &buf) != -1)) {
1576
+ cg->memory.filename_usage_in_bytes = strdupz(filename);
1577
+ cg->memory.enabled_usage_in_bytes = cgroup_enable_memory;
1578
+ debug(D_CGROUP, "memory.usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_usage_in_bytes);
1579
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.limit_in_bytes", cgroup_memory_base, cg->id);
1580
+ cg->filename_memory_limit = strdupz(filename);
1581
+ }
1582
+ else
1583
+ debug(D_CGROUP, "memory.usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1584
}
1403
- else
1404
- debug(D_CGROUP, "memory.usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1405
- }
1585
1407
- if(unlikely(cgroup_enable_swap && !cg->memory.filename_msw_usage_in_bytes)) {
1408
- snprintfz(filename, FILENAME_MAX, "%s%s/memory.memsw.usage_in_bytes", cgroup_memory_base, cg->id);
1409
- if(likely(stat(filename, &buf) != -1)) {
1410
- cg->memory.filename_msw_usage_in_bytes = strdupz(filename);
1411
- cg->memory.enabled_msw_usage_in_bytes = cgroup_enable_swap;
1412
- snprintfz(filename, FILENAME_MAX, "%s%s/memory.memsw.limit_in_bytes", cgroup_memory_base, cg->id);
1413
- cg->filename_memoryswap_limit = strdupz(filename);
1414
- debug(D_CGROUP, "memory.msw_usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_msw_usage_in_bytes);
1586
+ if(unlikely(cgroup_enable_swap && !cg->memory.filename_msw_usage_in_bytes)) {
1587
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.memsw.usage_in_bytes", cgroup_memory_base, cg->id);
1588
+ if(likely(stat(filename, &buf) != -1)) {
1589
+ cg->memory.filename_msw_usage_in_bytes = strdupz(filename);
1590
+ cg->memory.enabled_msw_usage_in_bytes = cgroup_enable_swap;
1591
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.memsw.limit_in_bytes", cgroup_memory_base, cg->id);
1592
+ cg->filename_memoryswap_limit = strdupz(filename);
1593
+ debug(D_CGROUP, "memory.msw_usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_msw_usage_in_bytes);
1594
+ }
1595
+ else
1596
+ debug(D_CGROUP, "memory.msw_usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1597
}
1416
- else
1417
- debug(D_CGROUP, "memory.msw_usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1418
- }
1598
1420
- if(unlikely(cgroup_enable_memory_failcnt && !cg->memory.filename_failcnt)) {
1421
- snprintfz(filename, FILENAME_MAX, "%s%s/memory.failcnt", cgroup_memory_base, cg->id);
1422
- if(likely(stat(filename, &buf) != -1)) {
1423
- cg->memory.filename_failcnt = strdupz(filename);
1424
- cg->memory.enabled_failcnt = cgroup_enable_memory_failcnt;
1425
- debug(D_CGROUP, "memory.failcnt filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_failcnt);
1599
+ if(unlikely(cgroup_enable_memory_failcnt && !cg->memory.filename_failcnt)) {
1600
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.failcnt", cgroup_memory_base, cg->id);
1601
+ if(likely(stat(filename, &buf) != -1)) {
1602
+ cg->memory.filename_failcnt = strdupz(filename);
1603
+ cg->memory.enabled_failcnt = cgroup_enable_memory_failcnt;
1604
+ debug(D_CGROUP, "memory.failcnt filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_failcnt);
1605
+ }
1606
+ else
1607
+ debug(D_CGROUP, "memory.failcnt file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1608
}
1427
- else
1428
- debug(D_CGROUP, "memory.failcnt file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1429
- }
1609
1431
- if(unlikely(cgroup_enable_blkio_io && !cg->io_service_bytes.filename)) {
1432
- snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_service_bytes", cgroup_blkio_base, cg->id);
1433
- if(likely(stat(filename, &buf) != -1)) {
1434
- cg->io_service_bytes.filename = strdupz(filename);
1435
- cg->io_service_bytes.enabled = cgroup_enable_blkio_io;
1436
- debug(D_CGROUP, "io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->io_service_bytes.filename);
1610
+ if(unlikely(cgroup_enable_blkio_io && !cg->io_service_bytes.filename)) {
1611
+ snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_service_bytes", cgroup_blkio_base, cg->id);
1612
+ if(likely(stat(filename, &buf) != -1)) {
1613
+ cg->io_service_bytes.filename = strdupz(filename);
1614
+ cg->io_service_bytes.enabled = cgroup_enable_blkio_io;
1615
+ debug(D_CGROUP, "io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->io_service_bytes.filename);
1616
+ }
1617
+ else
1618
+ debug(D_CGROUP, "io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1619
}
1438
- else
1439
- debug(D_CGROUP, "io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1440
- }
1620
1442
- if(unlikely(cgroup_enable_blkio_ops && !cg->io_serviced.filename)) {
1443
- snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_serviced", cgroup_blkio_base, cg->id);
1444
- if(likely(stat(filename, &buf) != -1)) {
1445
- cg->io_serviced.filename = strdupz(filename);
1446
- cg->io_serviced.enabled = cgroup_enable_blkio_ops;
1447
- debug(D_CGROUP, "io_serviced filename for cgroup '%s': '%s'", cg->id, cg->io_serviced.filename);
1621
+ if(unlikely(cgroup_enable_blkio_ops && !cg->io_serviced.filename)) {
1622
+ snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_serviced", cgroup_blkio_base, cg->id);
1623
+ if(likely(stat(filename, &buf) != -1)) {
1624
+ cg->io_serviced.filename = strdupz(filename);
1625
+ cg->io_serviced.enabled = cgroup_enable_blkio_ops;
1626
+ debug(D_CGROUP, "io_serviced filename for cgroup '%s': '%s'", cg->id, cg->io_serviced.filename);
1627
+ }
1628
+ else
1629
+ debug(D_CGROUP, "io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1630
+ }
1631
+
1632
+ if(unlikely(cgroup_enable_blkio_throttle_io && !cg->throttle_io_service_bytes.filename)) {
1633
+ snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_service_bytes", cgroup_blkio_base, cg->id);
1634
+ if(likely(stat(filename, &buf) != -1)) {
1635
+ cg->throttle_io_service_bytes.filename = strdupz(filename);
1636
+ cg->throttle_io_service_bytes.enabled = cgroup_enable_blkio_throttle_io;
1637
+ debug(D_CGROUP, "throttle_io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_service_bytes.filename);
1638
+ }
1639
+ else
1640
+ debug(D_CGROUP, "throttle_io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1641
}
1449
- else
1450
- debug(D_CGROUP, "io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1451
- }
1642
1453
- if(unlikely(cgroup_enable_blkio_throttle_io && !cg->throttle_io_service_bytes.filename)) {
1454
- snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_service_bytes", cgroup_blkio_base, cg->id);
1455
- if(likely(stat(filename, &buf) != -1)) {
1456
- cg->throttle_io_service_bytes.filename = strdupz(filename);
1457
- cg->throttle_io_service_bytes.enabled = cgroup_enable_blkio_throttle_io;
1458
- debug(D_CGROUP, "throttle_io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_service_bytes.filename);
1643
+ if(unlikely(cgroup_enable_blkio_throttle_ops && !cg->throttle_io_serviced.filename)) {
1644
+ snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_serviced", cgroup_blkio_base, cg->id);
1645
+ if(likely(stat(filename, &buf) != -1)) {
1646
+ cg->throttle_io_serviced.filename = strdupz(filename);
1647
+ cg->throttle_io_serviced.enabled = cgroup_enable_blkio_throttle_ops;
1648
+ debug(D_CGROUP, "throttle_io_serviced filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_serviced.filename);
1649
+ }
1650
+ else
1651
+ debug(D_CGROUP, "throttle_io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1652
}
1460
- else
1461
- debug(D_CGROUP, "throttle_io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1462
- }
1653
1464
- if(unlikely(cgroup_enable_blkio_throttle_ops && !cg->throttle_io_serviced.filename)) {
1465
- snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_serviced", cgroup_blkio_base, cg->id);
1466
- if(likely(stat(filename, &buf) != -1)) {
1467
- cg->throttle_io_serviced.filename = strdupz(filename);
1468
- cg->throttle_io_serviced.enabled = cgroup_enable_blkio_throttle_ops;
1469
- debug(D_CGROUP, "throttle_io_serviced filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_serviced.filename);
1654
+ if(unlikely(cgroup_enable_blkio_merged_ops && !cg->io_merged.filename)) {
1655
+ snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_merged", cgroup_blkio_base, cg->id);
1656
+ if(likely(stat(filename, &buf) != -1)) {
1657
+ cg->io_merged.filename = strdupz(filename);
1658
+ cg->io_merged.enabled = cgroup_enable_blkio_merged_ops;
1659
+ debug(D_CGROUP, "io_merged filename for cgroup '%s': '%s'", cg->id, cg->io_merged.filename);
1660
+ }
1661
+ else
1662
+ debug(D_CGROUP, "io_merged file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1663
}
1471
- else
1472
- debug(D_CGROUP, "throttle_io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1473
- }
1664
1475
- if(unlikely(cgroup_enable_blkio_merged_ops && !cg->io_merged.filename)) {
1476
- snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_merged", cgroup_blkio_base, cg->id);
1477
- if(likely(stat(filename, &buf) != -1)) {
1478
- cg->io_merged.filename = strdupz(filename);
1479
- cg->io_merged.enabled = cgroup_enable_blkio_merged_ops;
1480
- debug(D_CGROUP, "io_merged filename for cgroup '%s': '%s'", cg->id, cg->io_merged.filename);
1665
+ if(unlikely(cgroup_enable_blkio_queued_ops && !cg->io_queued.filename)) {
1666
+ snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_queued", cgroup_blkio_base, cg->id);
1667
+ if(likely(stat(filename, &buf) != -1)) {
1668
+ cg->io_queued.filename = strdupz(filename);
1669
+ cg->io_queued.enabled = cgroup_enable_blkio_queued_ops;
1670
+ debug(D_CGROUP, "io_queued filename for cgroup '%s': '%s'", cg->id, cg->io_queued.filename);
1671
+ }
1672
+ else
1673
+ debug(D_CGROUP, "io_queued file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1674
}
1482
- else
1483
- debug(D_CGROUP, "io_merged file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1675
}
1676
+ else if(likely(cgroup_unified_exist)) {
1677
+ if(unlikely(cgroup_enable_blkio_io && !cg->io_service_bytes.filename)) {
1678
+ snprintfz(filename, FILENAME_MAX, "%s%s/io.stat", cgroup_unified_base, cg->id);
1679
+ if(likely(stat(filename, &buf) != -1)) {
1680
+ cg->io_service_bytes.filename = strdupz(filename);
1681
+ cg->io_service_bytes.enabled = cgroup_enable_blkio_io;
1682
+ debug(D_CGROUP, "io.stat filename for unified cgroup '%s': '%s'", cg->id, cg->io_service_bytes.filename);
1683
+ } else
1684
+ debug(D_CGROUP, "io.stat file for unified cgroup '%s': '%s' does not exist.", cg->id, filename);
1685
+ }
1686
+ if (unlikely(cgroup_enable_blkio_ops && !cg->io_serviced.filename)) {
1687
+ snprintfz(filename, FILENAME_MAX, "%s%s/io.stat", cgroup_unified_base, cg->id);
1688
+ if (likely(stat(filename, &buf) != -1)) {
1689
+ cg->io_serviced.filename = strdupz(filename);
1690
+ cg->io_serviced.enabled = cgroup_enable_blkio_ops;
1691
+ debug(D_CGROUP, "io.stat filename for unified cgroup '%s': '%s'", cg->id, cg->io_service_bytes.filename);
1692
+ } else
1693
+ debug(D_CGROUP, "io.stat file for unified cgroup '%s': '%s' does not exist.", cg->id, filename);
1694
+ }
1695
+ if(unlikely(cgroup_enable_cpuacct_stat && !cg->cpuacct_stat.filename)) {
1696
+ snprintfz(filename, FILENAME_MAX, "%s%s/cpu.stat", cgroup_unified_base, cg->id);
1697
+ if(likely(stat(filename, &buf) != -1)) {
1698
+ cg->cpuacct_stat.filename = strdupz(filename);
1699
+ cg->cpuacct_stat.enabled = cgroup_enable_cpuacct_stat;
1700
+ cg->filename_cpuset_cpus = NULL;
1701
+ cg->filename_cpu_cfs_period = NULL;
1702
+ cg->filename_cpu_cfs_quota = NULL;
1703
+ debug(D_CGROUP, "cpu.stat filename for unified cgroup '%s': '%s'", cg->id, cg->cpuacct_stat.filename);
1704
+ }
1705
+ else
1706
+ debug(D_CGROUP, "cpu.stat file for unified cgroup '%s': '%s' does not exist.", cg->id, filename);
1707
+ }
1708
+ if(unlikely((cgroup_enable_detailed_memory || cgroup_used_memory_without_cache) && !cg->memory.filename_detailed && (cgroup_used_memory_without_cache || cgroup_enable_systemd_services_detailed_memory || !(cg->options & CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE)))) {
1709
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.stat", cgroup_unified_base, cg->id);
1710
+ if(likely(stat(filename, &buf) != -1)) {
1711
+ cg->memory.filename_detailed = strdupz(filename);
1712
+ cg->memory.enabled_detailed = (cgroup_enable_detailed_memory == CONFIG_BOOLEAN_YES)?CONFIG_BOOLEAN_YES:CONFIG_BOOLEAN_AUTO;
1713
+ debug(D_CGROUP, "memory.stat filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_detailed);
1714
+ }
1715
+ else
1716
+ debug(D_CGROUP, "memory.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1717
+ }
1718
+
1719
+ if(unlikely(cgroup_enable_memory && !cg->memory.filename_usage_in_bytes)) {
1720
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.current", cgroup_unified_base, cg->id);
1721
+ if(likely(stat(filename, &buf) != -1)) {
1722
+ cg->memory.filename_usage_in_bytes = strdupz(filename);
1723
+ cg->memory.enabled_usage_in_bytes = cgroup_enable_memory;
1724
+ debug(D_CGROUP, "memory.current filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_usage_in_bytes);
1725
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.max", cgroup_unified_base, cg->id);
1726
+ cg->filename_memory_limit = strdupz(filename);
1727
+ }
1728
+ else
1729
+ debug(D_CGROUP, "memory.current file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1730
+ }
1731
1486
- if(unlikely(cgroup_enable_blkio_queued_ops && !cg->io_queued.filename)) {
1487
- snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_queued", cgroup_blkio_base, cg->id);
1488
- if(likely(stat(filename, &buf) != -1)) {
1489
- cg->io_queued.filename = strdupz(filename);
1490
- cg->io_queued.enabled = cgroup_enable_blkio_queued_ops;
1491
- debug(D_CGROUP, "io_queued filename for cgroup '%s': '%s'", cg->id, cg->io_queued.filename);
1732
+ if(unlikely(cgroup_enable_swap && !cg->memory.filename_msw_usage_in_bytes)) {
1733
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.swap.current", cgroup_unified_base, cg->id);
1734
+ if(likely(stat(filename, &buf) != -1)) {
1735
+ cg->memory.filename_msw_usage_in_bytes = strdupz(filename);
1736
+ cg->memory.enabled_msw_usage_in_bytes = cgroup_enable_swap;
1737
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.swap.max", cgroup_unified_base, cg->id);
1738
+ cg->filename_memoryswap_limit = strdupz(filename);
1739
+ debug(D_CGROUP, "memory.swap.current filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_msw_usage_in_bytes);
1740
+ }
1741
+ else
1742
+ debug(D_CGROUP, "memory.swap file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1743
}
1493
- else
1494
- debug(D_CGROUP, "io_queued file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1744
}
1745
}
1746
@@ -2083,8 +2332,15 @@ void update_systemd_services_charts(
2332
continue;
2333
2334
if(likely(do_cpu && cg->cpuacct_stat.updated)) {
2086
- if(unlikely(!cg->rd_cpu))
2087
- cg->rd_cpu = rrddim_add(st_cpu, cg->chart_id, cg->chart_title, 100, system_hz, RRD_ALGORITHM_INCREMENTAL);
2335
+ if(unlikely(!cg->rd_cpu)){
2336
+
2337
+
2338
+ if (!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
2339
+ cg->rd_cpu = rrddim_add(st_cpu, cg->chart_id, cg->chart_title, 100, system_hz, RRD_ALGORITHM_INCREMENTAL);
2340
+ } else {
2341
+ cg->rd_cpu = rrddim_add(st_cpu, cg->chart_id, cg->chart_title, 100, 1000000, RRD_ALGORITHM_INCREMENTAL);
2342
+ }
2343
+ }
2344
2345
rrddim_set_by_pointer(st_cpu, cg->rd_cpu, cg->cpuacct_stat.user + cg->cpuacct_stat.system);
2346
}
@@ -2368,12 +2624,32 @@ static inline int update_memory_limits(char **filename, RRDSETVAR **chart_var, u
2624
}
2625
2626
if(*filename && *chart_var) {
2371
- if(read_single_number_file(*filename, value)) {
2372
- error("Cannot refresh cgroup %s memory limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
2373
- freez(*filename);
2374
- *filename = NULL;
2375
- }
2376
- else {
2627
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
2628
+ if(read_single_number_file(*filename, value)) {
2629
+ error("Cannot refresh cgroup %s memory limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
2630
+ freez(*filename);
2631
+ *filename = NULL;
2632
+ }
2633
+ else {
2634
+ rrdsetvar_custom_chart_variable_set(*chart_var, (calculated_number)(*value / (1024 * 1024)));
2635
+ return 1;
2636
+ }
2637
+ } else {
2638
+ char buffer[30 + 1];
2639
+ int ret = read_file(*filename, buffer, 30);
2640
+ if(ret) {
2641
+ error("Cannot refresh cgroup %s memory limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
2642
+ freez(*filename);
2643
+ *filename = NULL;
2644
+ return 0;
2645
+ }
2646
+ char *s = "max\n\0";
2647
+ if(strsame(s, buffer) == 0){
2648
+ *value = UINT64_MAX;
2649
+ rrdsetvar_custom_chart_variable_set(*chart_var, (calculated_number)(*value / (1024 * 1024)));
2650
+ return 1;
2651
+ }
2652
+ *value = str2ull(buffer);
2653
rrdsetvar_custom_chart_variable_set(*chart_var, (calculated_number)(*value / (1024 * 1024)));
2654
return 1;
2655
}
@@ -2442,9 +2718,14 @@ void update_cgroup_charts(int update_every) {
2718
, update_every
2719
, RRDSET_TYPE_STACKED
2720
);
2445
-
2446
- rrddim_add(cg->st_cpu, "user", NULL, 100, system_hz, RRD_ALGORITHM_INCREMENTAL);
2447
- rrddim_add(cg->st_cpu, "system", NULL, 100, system_hz, RRD_ALGORITHM_INCREMENTAL);
2721
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
2722
+ rrddim_add(cg->st_cpu, "user", NULL, 100, system_hz, RRD_ALGORITHM_INCREMENTAL);
2723
+ rrddim_add(cg->st_cpu, "system", NULL, 100, system_hz, RRD_ALGORITHM_INCREMENTAL);
2724
+ }
2725
+ else {
2726
+ rrddim_add(cg->st_cpu, "user", NULL, 100, 1000000, RRD_ALGORITHM_INCREMENTAL);
2727
+ rrddim_add(cg->st_cpu, "system", NULL, 100, 1000000, RRD_ALGORITHM_INCREMENTAL);
2728
+ }
2729
}
2730
else
2731
rrdset_next(cg->st_cpu);
@@ -2585,27 +2866,44 @@ void update_cgroup_charts(int update_every) {
2866
, update_every
2867
, RRDSET_TYPE_STACKED
2868
);
2588
-
2589
- rrddim_add(cg->st_mem, "cache", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2590
- rrddim_add(cg->st_mem, "rss", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2591
-
2592
- if(cg->memory.detailed_has_swap)
2593
- rrddim_add(cg->st_mem, "swap", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2594
-
2595
- rrddim_add(cg->st_mem, "rss_huge", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2596
- rrddim_add(cg->st_mem, "mapped_file", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2869
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
2870
+ rrddim_add(cg->st_mem, "cache", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2871
+ rrddim_add(cg->st_mem, "rss", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2872
+
2873
+ if(cg->memory.detailed_has_swap)
2874
+ rrddim_add(cg->st_mem, "swap", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2875
+
2876
+ rrddim_add(cg->st_mem, "rss_huge", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2877
+ rrddim_add(cg->st_mem, "mapped_file", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2878
+ } else {
2879
+ rrddim_add(cg->st_mem, "anon", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2880
+ rrddim_add(cg->st_mem, "kernel_stack", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2881
+ rrddim_add(cg->st_mem, "slab", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2882
+ rrddim_add(cg->st_mem, "sock", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2883
+ rrddim_add(cg->st_mem, "anon_thp", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2884
+ rrddim_add(cg->st_mem, "file", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2885
+ }
2886
}
2887
else
2888
rrdset_next(cg->st_mem);
2889
2601
- rrddim_set(cg->st_mem, "cache", cg->memory.total_cache);
2602
- rrddim_set(cg->st_mem, "rss", (cg->memory.total_rss > cg->memory.total_rss_huge)?(cg->memory.total_rss - cg->memory.total_rss_huge):0);
2603
-
2604
- if(cg->memory.detailed_has_swap)
2605
- rrddim_set(cg->st_mem, "swap", cg->memory.total_swap);
2890
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
2891
+ rrddim_set(cg->st_mem, "cache", cg->memory.total_cache);
2892
+ rrddim_set(cg->st_mem, "rss", (cg->memory.total_rss > cg->memory.total_rss_huge)?(cg->memory.total_rss - cg->memory.total_rss_huge):0);
2893
2607
- rrddim_set(cg->st_mem, "rss_huge", cg->memory.total_rss_huge);
2608
- rrddim_set(cg->st_mem, "mapped_file", cg->memory.total_mapped_file);
2894
+ if(cg->memory.detailed_has_swap)
2895
+ rrddim_set(cg->st_mem, "swap", cg->memory.total_swap);
2896
+
2897
+ rrddim_set(cg->st_mem, "rss_huge", cg->memory.total_rss_huge);
2898
+ rrddim_set(cg->st_mem, "mapped_file", cg->memory.total_mapped_file);
2899
+ } else {
2900
+ rrddim_set(cg->st_mem, "anon", cg->memory.anon);
2901
+ rrddim_set(cg->st_mem, "kernel_stack", cg->memory.kernel_stack);
2902
+ rrddim_set(cg->st_mem, "slab", cg->memory.slab);
2903
+ rrddim_set(cg->st_mem, "sock", cg->memory.sock);
2904
+ rrddim_set(cg->st_mem, "anon_thp", cg->memory.anon_thp);
2905
+ rrddim_set(cg->st_mem, "file", cg->memory.total_mapped_file);
2906
+ }
2907
rrdset_done(cg->st_mem);
2908
2909
if(unlikely(!cg->st_writeback)) {
@@ -2640,33 +2938,35 @@ void update_cgroup_charts(int update_every) {
2938
rrddim_set(cg->st_writeback, "writeback", cg->memory.total_writeback);
2939
rrdset_done(cg->st_writeback);
2940
2643
- if(unlikely(!cg->st_mem_activity)) {
2644
- snprintfz(title, CHART_TITLE_MAX, "Memory Activity for cgroup %s", cg->chart_title);
2645
-
2646
- cg->st_mem_activity = rrdset_create_localhost(
2647
- cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2648
- , "mem_activity"
2649
- , NULL
2650
- , "mem"
2651
- , "cgroup.mem_activity"
2652
- , title
2653
- , "MiB/s"
2654
- , PLUGIN_CGROUPS_NAME
2655
- , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
2656
- , cgroup_containers_chart_priority + 400
2657
- , update_every
2658
- , RRDSET_TYPE_LINE
2659
- );
2941
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
2942
+ if(unlikely(!cg->st_mem_activity)) {
2943
+ snprintfz(title, CHART_TITLE_MAX, "Memory Activity for cgroup %s", cg->chart_title);
2944
+
2945
+ cg->st_mem_activity = rrdset_create_localhost(
2946
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2947
+ , "mem_activity"
2948
+ , NULL
2949
+ , "mem"
2950
+ , "cgroup.mem_activity"
2951
+ , title
2952
+ , "MiB/s"
2953
+ , PLUGIN_CGROUPS_NAME
2954
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
2955
+ , cgroup_containers_chart_priority + 400
2956
+ , update_every
2957
+ , RRDSET_TYPE_LINE
2958
+ );
2959
+
2960
+ rrddim_add(cg->st_mem_activity, "pgpgin", "in", system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2961
+ rrddim_add(cg->st_mem_activity, "pgpgout", "out", -system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2962
+ }
2963
+ else
2964
+ rrdset_next(cg->st_mem_activity);
2965
2661
- rrddim_add(cg->st_mem_activity, "pgpgin", "in", system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2662
- rrddim_add(cg->st_mem_activity, "pgpgout", "out", -system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2966
+ rrddim_set(cg->st_mem_activity, "pgpgin", cg->memory.total_pgpgin);
2967
+ rrddim_set(cg->st_mem_activity, "pgpgout", cg->memory.total_pgpgout);
2968
+ rrdset_done(cg->st_mem_activity);
2969
}
2664
- else
2665
- rrdset_next(cg->st_mem_activity);
2666
-
2667
- rrddim_set(cg->st_mem_activity, "pgpgin", cg->memory.total_pgpgin);
2668
- rrddim_set(cg->st_mem_activity, "pgpgout", cg->memory.total_pgpgout);
2669
- rrdset_done(cg->st_mem_activity);
2970
2971
if(unlikely(!cg->st_pgfaults)) {
2972
snprintfz(title, CHART_TITLE_MAX, "Memory Page Faults for cgroup %s", cg->chart_title);
@@ -2723,7 +3023,11 @@ void update_cgroup_charts(int update_every) {
3023
rrdset_next(cg->st_mem_usage);
3024
3025
rrddim_set(cg->st_mem_usage, "ram", cg->memory.usage_in_bytes - ((cgroup_used_memory_without_cache)?cg->memory.total_cache:0));
2726
- rrddim_set(cg->st_mem_usage, "swap", (cg->memory.msw_usage_in_bytes > cg->memory.usage_in_bytes)?cg->memory.msw_usage_in_bytes - cg->memory.usage_in_bytes:0);
3026
+ if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
3027
+ rrddim_set(cg->st_mem_usage, "swap", (cg->memory.msw_usage_in_bytes > cg->memory.usage_in_bytes)?cg->memory.msw_usage_in_bytes - cg->memory.usage_in_bytes:0);
3028
+ } else {
3029
+ rrddim_set(cg->st_mem_usage, "swap", cg->memory.msw_usage_in_bytes);
3030
+ }
3031
rrdset_done(cg->st_mem_usage);
3032
3033
if (likely(update_memory_limits(&cg->filename_memory_limit, &cg->chart_var_memory_limit, &cg->memory_limit, "memory_limit", cg))) {