]> git.proxmox.com Git - mirror_lxcfs.git/blobdiff - src/proc_fuse.c
make meminfo and swaps cgroupv2 aware
[mirror_lxcfs.git] / src / proc_fuse.c
index cbbcad2d21f6cb3713e0ebc8e56b649c14a29041..c9103771dca4be4cf218604bcdc0a9a4395c01e0 100644 (file)
@@ -1,12 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
 #include "config.h"
 
-#define __STDC_FORMAT_MACROS
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -308,6 +303,43 @@ static inline bool startswith(const char *line, const char *pref)
        return strncmp(line, pref, strlen(pref)) == 0;
 }
 
+static void get_swap_info(const char *cgroup, uint64_t memlimit,
+                         uint64_t memusage, uint64_t *swtotal,
+                         uint64_t *swusage, uint64_t *memswpriority)
+{
+       __do_free char *memswusage_str = NULL, *memswpriority_str = NULL;
+       size_t memswlimit = 0, memswusage = 0;
+       int ret;
+
+       *swtotal = *swusage = 0;
+       *memswpriority = 1;
+
+       memswlimit = get_min_memlimit(cgroup, true);
+       if (memswlimit > 0) {
+               ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str);
+               if (ret < 0 || safe_uint64(memswusage_str, &memswusage, 10) != 0)
+                       return;
+
+               if (liblxcfs_memory_is_cgroupv2()) {
+                       *swtotal = memswlimit / 1024;
+                       *swusage = memswusage / 1024;
+               } else {
+                       if (memlimit > memswlimit)
+                               *swtotal = 0;
+                       else
+                               *swtotal = (memswlimit - memlimit) / 1024;
+                       if (memusage > memswusage || swtotal == 0)
+                               *swusage = 0;
+                       else
+                               *swusage = (memswusage - memusage) / 1024;
+               }
+
+               ret = cgroup_ops->get_memory_swappiness(cgroup_ops, cgroup, &memswpriority_str);
+               if (ret >= 0)
+                       safe_uint64(memswpriority_str, memswpriority, 10);
+       }
+}
+
 static int proc_swaps_read(char *buf, size_t size, off_t offset,
                           struct fuse_file_info *fi)
 {
@@ -316,7 +348,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
        struct fuse_context *fc = fuse_get_context();
        bool wants_swap = lxcfs_has_opt(fuse_get_context()->private_data, LXCFS_SWAP_ON);
        struct file_info *d = INTTYPE_TO_PTR(fi->fh);
-       uint64_t memswlimit = 0, memlimit = 0, memusage = 0, memswusage = 0,
+       uint64_t memlimit = 0, memusage = 0,
                 swtotal = 0, swusage = 0, memswpriority = 1,
                 hostswtotal = 0, hostswfree = 0;
        ssize_t total_len = 0;
@@ -329,7 +361,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
        size_t linelen = 0;
 
        if (offset) {
-               int left;
+               size_t left;
 
                if (offset > d->size)
                        return -EINVAL;
@@ -362,26 +394,8 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
        if (safe_uint64(memusage_str, &memusage, 10) < 0)
                lxcfs_error("Failed to convert memusage %s", memusage_str);
 
-       if (wants_swap) {
-               memswlimit = get_min_memlimit(cgroup, true);
-               if (memswlimit > 0) {
-                       ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str);
-                       if (ret >= 0 && safe_uint64(memswusage_str, &memswusage, 10) == 0) {
-                               if (memlimit > memswlimit)
-                                       swtotal = 0;
-                               else
-                                       swtotal = (memswlimit - memlimit) / 1024;
-                               if (memusage > memswusage || swtotal == 0)
-                                       swusage = 0;
-                               else
-                                       swusage = (memswusage - memusage) / 1024;
-                       }
-
-                       ret = cgroup_ops->get_memory_swappiness(cgroup_ops, cgroup, &memswpriority_str);
-                       if (ret >= 0)
-                               safe_uint64(memswpriority_str, &memswpriority, 10);
-               }
-       }
+       if (wants_swap)
+               get_swap_info(cgroup, memlimit, memusage, &swtotal, &swusage, &memswpriority);
 
        total_len = snprintf(d->buf, d->size, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
 
@@ -426,7 +440,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
        d->cached = 1;
        d->size = (int)total_len;
 
-       if (total_len > size)
+       if ((size_t)total_len > size)
                total_len = size;
        memcpy(buf, d->buf, total_len);
 
@@ -500,7 +514,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
        int ret;
 
        if (offset) {
-               int left;
+               size_t left;
 
                if (offset > d->size)
                        return -EINVAL;
@@ -631,7 +645,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
                l = snprintf(cache, cache_size, "%s", lbuf);
                if (l < 0)
                        return log_error(0, "Failed to write cache");
-               if (l >= cache_size)
+               if ((size_t)l >= cache_size)
                        return log_error(0, "Write to cache was truncated");
 
                cache += l;
@@ -648,7 +662,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
        return total_len;
 }
 
-#if RELOADTEST
+#ifdef RELOADTEST
 static inline void iwashere(void)
 {
        mknod("/tmp/lxcfs-iwashere", S_IFREG, 0644);
@@ -803,12 +817,12 @@ static int proc_uptime_read(char *buf, size_t size, off_t offset,
        ssize_t total_len = 0, ret = 0;
        double busytime, idletime, reaperage;
 
-#if RELOADTEST
+#ifdef RELOADTEST
        iwashere();
 #endif
 
        if (offset) {
-               int left;
+               size_t left;
 
                if (offset > d->size)
                        return -EINVAL;
@@ -840,7 +854,7 @@ static int proc_uptime_read(char *buf, size_t size, off_t offset,
 
        d->cached = 1;
        d->size = total_len;
-       if (total_len > size)
+       if ((size_t)total_len > size)
                total_len = size;
        memcpy(buf, d->buf, total_len);
 
@@ -873,7 +887,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
        int cg_cpu_usage_size = 0;
 
        if (offset) {
-               int left;
+               size_t left;
 
                if (offset > d->size)
                        return -EINVAL;
@@ -947,7 +961,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
                        l = snprintf(cache, cache_size, "%s", line);
                        if (l < 0)
                                return log_error(0, "Failed to write cache");
-                       if (l >= cache_size)
+                       if ((size_t)l >= cache_size)
                                return log_error(0, "Write to cache was truncated");
 
                        cache += l;
@@ -984,7 +998,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
                        l = snprintf(cache, cache_size, "cpu%d%s", curcpu, c);
                        if (l < 0)
                                return log_error(0, "Failed to write cache");
-                       if (l >= cache_size)
+                       if ((size_t)l >= cache_size)
                                return log_error(0, "Write to cache was truncated");
 
                        cache += l;
@@ -1016,7 +1030,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
                                     cg_cpu_usage[physcpu].system, new_idle);
                        if (l < 0)
                                return log_error(0, "Failed to write cache");
-                       if (l >= cache_size)
+                       if ((size_t)l >= cache_size)
                                return log_error(0, "Write to cache was truncated");
 
                        cache += l;
@@ -1150,7 +1164,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
        struct fuse_context *fc = fuse_get_context();
        bool wants_swap = lxcfs_has_opt(fuse_get_context()->private_data, LXCFS_SWAP_ON);
        struct file_info *d = INTTYPE_TO_PTR(fi->fh);
-       uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
+       uint64_t memlimit = 0, memusage = 0,
                 hosttotal = 0, swfree = 0, swusage = 0, swtotal = 0,
                 memswpriority = 1;
        struct memory_stat mstat = {};
@@ -1160,7 +1174,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
        int ret;
 
        if (offset) {
-               int left;
+               size_t left;
 
                if (offset > d->size)
                        return -EINVAL;
@@ -1202,26 +1216,8 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
         * Following values are allowed to fail, because swapaccount might be
         * turned off for current kernel.
         */
-       if (wants_swap) {
-               memswlimit = get_min_memlimit(cgroup, true);
-               if (memswlimit > 0) {
-                       ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str);
-                       if (ret >= 0 && safe_uint64(memswusage_str, &memswusage, 10) == 0) {
-                               if (memlimit > memswlimit)
-                                       swtotal = 0;
-                               else
-                                       swtotal = (memswlimit - memlimit) / 1024;
-                               if (memusage > memswusage || swtotal == 0)
-                                       swusage = 0;
-                               else
-                                       swusage = (memswusage - memusage) / 1024;
-                       }
-               }
-
-               ret = cgroup_ops->get_memory_swappiness(cgroup_ops, cgroup, &memswpriority_str);
-               if (ret >= 0)
-                       safe_uint64(memswpriority_str, &memswpriority, 10);
-       }
+       if (wants_swap)
+               get_swap_info(cgroup, memlimit, memusage, &swtotal, &swusage, &memswpriority);
 
        f = fopen_cached("/proc/meminfo", "re", &fopen_cache);
        if (!f)
@@ -1260,7 +1256,9 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
                                   This is because the kernel can swap as much as it
                                   wants and not only up to swtotal. */
 
-                               swtotal = memlimit + swtotal;
+                               if (!liblxcfs_memory_is_cgroupv2())
+                                       swtotal += memlimit;
+
                                if (hostswtotal < swtotal) {
                                        swtotal = hostswtotal;
                                }
@@ -1281,7 +1279,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
                        snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " kB\n", swfree);
                        printme = lbuf;
                } else if (startswith(line, "Slab:")) {
-                       snprintf(lbuf, 100, "Slab:        %8" PRIu64 " kB\n", (uint64_t)0);
+                       snprintf(lbuf, 100, "Slab:           %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "Buffers:")) {
                        snprintf(lbuf, 100, "Buffers:        %8" PRIu64 " kB\n", (uint64_t)0);
@@ -1370,7 +1368,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
                l = snprintf(cache, cache_size, "%s", printme);
                if (l < 0)
                        return log_error(0, "Failed to write cache");
-               if (l >= cache_size)
+               if ((size_t)l >= cache_size)
                        return log_error(0, "Write to cache was truncated");
 
                cache += l;
@@ -1402,7 +1400,7 @@ static int proc_slabinfo_read(char *buf, size_t size, off_t offset,
        pid_t initpid;
 
        if (offset) {
-               int left;
+               size_t left;
 
                if (offset > d->size)
                        return -EINVAL;
@@ -1439,7 +1437,7 @@ static int proc_slabinfo_read(char *buf, size_t size, off_t offset,
                ssize_t l = snprintf(cache, cache_size, "%s", line);
                if (l < 0)
                        return log_error(0, "Failed to write cache");
-               if (l >= cache_size)
+               if ((size_t)l >= cache_size)
                        return log_error(0, "Write to cache was truncated");
 
                cache += l;