@cryptotaxi247 / netdata-1 / commits / 6724b631d

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 [![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2FCONTRIBUTORS&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
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))) {