]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
proc_fuse: provide host values when kernel does not support swap accounting
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 24 Jun 2020 11:13:25 +0000 (13:13 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 24 Jun 2020 11:13:51 +0000 (13:13 +0200)
Link: https://discuss.linuxcontainers.org/t/invalid-swaptotal-in-proc-meminfo-swaptotal-0
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/bindings.c
src/bindings.h
src/cgroups/cgfsng.c
src/cgroups/cgroup.h
src/proc_fuse.c

index 28da74b086a5e4b07bb2e155ca4612688d74c6ea..8dc885da777b1fecc1210f572c0315d54bff7489 100644 (file)
@@ -50,6 +50,7 @@
 #include "utils.h"
 
 static bool can_use_pidfd;
+static bool can_use_swap;
 
 static volatile sig_atomic_t reload_successful;
 
@@ -58,6 +59,11 @@ bool liblxcfs_functional(void)
        return reload_successful != 0;
 }
 
+bool liblxcfs_can_use_swap(void)
+{
+       return can_use_swap;
+}
+
 /* Define pivot_root() if missing from the C library */
 #ifndef HAVE_PIVOT_ROOT
 static int pivot_root(const char *new_root, const char *put_old)
@@ -880,6 +886,12 @@ static void __attribute__((constructor)) lxcfs_init(void)
                lxcfs_info("Kernel supports pidfds");
        }
 
+       can_use_swap = cgroup_ops->can_use_swap(cgroup_ops);
+       if (can_use_swap)
+               lxcfs_info("Kernel supports swap accounting");
+       else
+               lxcfs_info("Kernel does not support swap accounting");
+
        lxcfs_info("api_extensions:");
        for (i = 0; i < nr_api_extensions; i++)
                lxcfs_info("- %s", api_extensions[i]);
index 28543dc064e7e4f451e7eeb569b073dbb20ece08..4ab4f721aa8d06f85199baf4cb5abf5729dc0b42 100644 (file)
@@ -91,6 +91,7 @@ extern pid_t lookup_initpid_in_store(pid_t qpid);
 extern void prune_init_slice(char *cg);
 extern bool supports_pidfd(void);
 extern bool liblxcfs_functional(void);
+extern bool liblxcfs_can_use_swap(void);
 
 static inline int install_signal_handler(int signo,
                                         void (*handler)(int, siginfo_t *, void *))
index 89f7cab1d43419e1584025a66d73d24421a950de..cf891b3ba0429810463df3e03b155917a323df0d 100644 (file)
@@ -619,6 +619,36 @@ static int cgfsng_get_memory_swap_max(struct cgroup_ops *ops,
        return cgfsng_get_memory(ops, cgroup, "memory.swap.max", value);
 }
 
+static bool cgfsng_can_use_swap(struct cgroup_ops *ops)
+{
+       bool has_swap = false;
+       struct hierarchy *h;
+
+       h = ops->get_hierarchy(ops, "memory");
+       if (!h)
+               return false;
+
+       if (is_unified_hierarchy(h)) {
+               if (faccessat(h->fd, "memory.swap.max", F_OK, 0))
+                       return false;
+
+               if (faccessat(h->fd, "memory.swap.current", F_OK, 0))
+                       return false;
+
+               has_swap = true;
+       } else {
+               if (faccessat(h->fd, "memory.memsw.limit_in_bytes", F_OK, 0))
+                       return false;
+
+               if (faccessat(h->fd, "memory.memsw.usage_in_bytes", F_OK, 0))
+                       return false;
+
+               has_swap = true;
+       }
+
+       return has_swap;
+}
+
 static int cgfsng_get_memory_stats(struct cgroup_ops *ops, const char *cgroup,
                                   char **value)
 {
@@ -977,6 +1007,7 @@ struct cgroup_ops *cgfsng_ops_init(void)
        cgfsng_ops->get_memory_swap_max = cgfsng_get_memory_swap_max;
        cgfsng_ops->get_memory_current = cgfsng_get_memory_current;
        cgfsng_ops->get_memory_swap_current = cgfsng_get_memory_swap_current;
+       cgfsng_ops->can_use_swap = cgfsng_can_use_swap;
 
        /* cpuset */
        cgfsng_ops->get_cpuset_cpus = cgfsng_get_cpuset_cpus;
index e8327fd319ea263d1576be0c89c0eb1c46ccd241..ad4a3ae7c658373b74ba87b483ed2d58e32d4003 100644 (file)
@@ -153,6 +153,7 @@ struct cgroup_ops {
                              char **value);
        int (*get_memory_swap_max)(struct cgroup_ops *ops, const char *cgroup,
                                   char **value);
+       bool (*can_use_swap)(struct cgroup_ops *ops);
 
        /* cpuset */
        int (*get_cpuset_cpus)(struct cgroup_ops *ops, const char *cgroup,
index c78b9e8df03bfa4e7350d1843e550a8cae9c7f5f..21bed1edca16cde99ff680473cb50a80b0c94880 100644 (file)
@@ -248,7 +248,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
                       *memswusage_str = NULL;
        struct fuse_context *fc = fuse_get_context();
        struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data;
-       bool wants_swap = opts && !opts->swap_off;
+       bool wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap();
        struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        uint64_t memswlimit = 0, memlimit = 0, memusage = 0, memswusage = 0,
                 swtotal = 0, swfree = 0, swusage = 0;
@@ -1021,7 +1021,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
        __do_fclose FILE *f = NULL;
        struct fuse_context *fc = fuse_get_context();
        struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data;
-       bool wants_swap = opts && !opts->swap_off, host_swap = false;
+       bool wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap(), host_swap = false;
        struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
                 hosttotal = 0, swfree = 0, swusage = 0, swtotal = 0;