]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
proc_fuse: improve swap calculation
authorStéphane Graber <stgraber@ubuntu.com>
Fri, 17 Apr 2020 19:59:53 +0000 (21:59 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 17 Apr 2020 20:02:53 +0000 (22:02 +0200)
Stéphane has been running into issues with wrong sawp limits. The logic
he suggested does:
- if memory == memory+swap, we list both at the memlimit for total size
- if memory+swap is larger than memory, then we add the extra amount to
  total swap but still cap to physical swap limit

We came to the conclusion that this is currently the best approach as we
show the mem limit as both Memory and Swap so advertising twice as much
as allowed but there's no way around that really or we'd need to
dynamically update both MemTotal and SwapTotal based on what's used to
keep MemTotal+SwapTotal == limit that's certainly doable but it will be
somewhat racy and also likely confused userspace more than mis-reporting
swap.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/proc_fuse.c

index b2e348e19b3b3bc054ff9dd386d85fdc6a894de8..b2edf76739e70f546ed856317ee66110278cf85e 100644 (file)
@@ -1019,7 +1019,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
        struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data;
        struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
-                hosttotal = 0;
+                hosttotal = 0, swtotal = 0;
        struct memory_stat mstat = {};
        size_t linelen = 0, total_len = 0;
        char *cache = d->buf;
@@ -1075,6 +1075,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
                if (safe_uint64(memswusage_str, &memswusage, 10) < 0)
                        lxcfs_error("Failed to convert memswusage %s", memswusage_str);
                memswusage = memswusage / 1024;
+               swtotal = memswlimit;
        }
 
        if (safe_uint64(memusage_str, &memusage, 10) < 0)
@@ -1110,27 +1111,25 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
                        uint64_t hostswtotal = 0;
 
                        sscanf(line + STRLITERALLEN("SwapTotal:"), "%" PRIu64, &hostswtotal);
-                       if (hostswtotal < memswlimit)
-                               memswlimit = hostswtotal;
 
-                       if (memswlimit >= memlimit)
-                               memswlimit -= memlimit;
+                       /* Don't advertise more SWAP than the total memory allowed. */
+                       if (hostswtotal < swtotal)
+                               swtotal = hostswtotal;
 
-                       snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " kB\n", memswlimit);
+                       snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " kB\n", swtotal);
                        printme = lbuf;
                } else if (startswith(line, "SwapTotal:") && opts && opts->swap_off == true) {
                        snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "SwapFree:") && memswlimit > 0 &&
-                          memswusage > 0 && opts && opts->swap_off == false) {
-                       uint64_t swaptotal = memswlimit,
-                                swapusage = memusage > memswusage
-                                                ? 0
-                                                : memswusage - memusage,
-                                swapfree = swapusage < swaptotal
-                                               ? swaptotal - swapusage
-                                               : 0;
-                       snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " kB\n", swapfree);
+                          opts && opts->swap_off == false) {
+                       uint64_t swfree = 0;
+                       uint64_t swusage = 0;
+
+                       swusage = memswusage - memusage;
+                       swfree = swtotal - swusage;
+
+                       snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " kB\n", swfree);
                        printme = lbuf;
                } else if (startswith(line, "SwapFree:") && opts && opts->swap_off == true) {
                        snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " kB\n", (uint64_t)0);