]> git.proxmox.com Git - mirror_lxcfs.git/blobdiff - proc_fuse.c
Merge pull request #339 from brauner/2020-03-02/cleanup
[mirror_lxcfs.git] / proc_fuse.c
index 623a4150331ab67c2e2074d4cd75cb7664edf697..c6a972f1f1d0a40b1a1439358f56927145b9e501 100644 (file)
 #include "proc_cpuview.h"
 #include "utils.h"
 
+struct memory_stat {
+       uint64_t hierarchical_memory_limit;
+       uint64_t hierarchical_memsw_limit;
+       uint64_t total_cache;
+       uint64_t total_rss;
+       uint64_t total_rss_huge;
+       uint64_t total_shmem;
+       uint64_t total_mapped_file;
+       uint64_t total_dirty;
+       uint64_t total_writeback;
+       uint64_t total_swap;
+       uint64_t total_pgpgin;
+       uint64_t total_pgpgout;
+       uint64_t total_pgfault;
+       uint64_t total_pgmajfault;
+       uint64_t total_inactive_anon;
+       uint64_t total_active_anon;
+       uint64_t total_inactive_file;
+       uint64_t total_active_file;
+       uint64_t total_unevictable;
+};
+
 int proc_getattr(const char *path, struct stat *sb)
 {
        struct timespec now;
@@ -99,7 +121,7 @@ int proc_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
 
 static off_t get_procfile_size(const char *which)
 {
-       FILE *f = fopen(which, "r");
+       FILE *f = fopen(which, "re");
        char *line = NULL;
        size_t len = 0;
        ssize_t sz, answer = 0;
@@ -116,8 +138,8 @@ static off_t get_procfile_size(const char *which)
 
 int proc_open(const char *path, struct fuse_file_info *fi)
 {
+       __do_free struct file_info *info = NULL;
        int type = -1;
-       struct file_info *info;
 
        if (strcmp(path, "/proc/meminfo") == 0)
                type = LXC_TYPE_PROC_MEMINFO;
@@ -153,7 +175,7 @@ int proc_open(const char *path, struct fuse_file_info *fi)
        /* set actual size to buffer size */
        info->size = info->buflen;
 
-       fi->fh = (unsigned long)info;
+       fi->fh = PTR_TO_UINT64(move_ptr(info));
        return 0;
 }
 
@@ -224,7 +246,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
        __do_free char *cg = NULL, *memswlimit_str = NULL, *memusage_str = NULL,
                       *memswusage_str = NULL;
        struct fuse_context *fc = fuse_get_context();
-       struct file_info *d = (struct file_info *)fi->fh;
+       struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        unsigned long memswlimit = 0, memlimit = 0, memusage = 0,
                      memswusage = 0, swap_total = 0, swap_free = 0;
        ssize_t total_len = 0;
@@ -279,10 +301,11 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
        /* When no mem + swap limit is specified or swapaccount=0*/
        if (!memswlimit) {
                __do_free char *line = NULL;
+               __do_free void *fopen_cache = NULL;
                __do_fclose FILE *f = NULL;
                size_t linelen = 0;
 
-               f = fopen("/proc/meminfo", "r");
+               f = fopen_cached("/proc/meminfo", "re", &fopen_cache);
                if (!f)
                        return 0;
 
@@ -345,9 +368,10 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
                       *io_merged_str = NULL, *io_service_bytes_str = NULL,
                       *io_wait_time_str = NULL, *io_service_time_str = NULL,
                       *line = NULL;
+       __do_free void *fopen_cache = NULL;
        __do_fclose FILE *f = NULL;
        struct fuse_context *fc = fuse_get_context();
-       struct file_info *d = (struct file_info *)fi->fh;
+       struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        unsigned long read = 0, write = 0;
        unsigned long read_merged = 0, write_merged = 0;
        unsigned long read_sectors = 0, write_sectors = 0;
@@ -416,7 +440,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
                        return read_file_fuse("/proc/diskstats", buf, size, d);
        }
 
-       f = fopen("/proc/diskstats", "r");
+       f = fopen_cached("/proc/diskstats", "re", &fopen_cache);
        if (!f)
                return 0;
 
@@ -483,13 +507,9 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
 }
 
 #if RELOADTEST
-void iwashere(void)
+static inline void iwashere(void)
 {
-       int fd;
-
-       fd = creat("/tmp/lxcfs-iwashere", 0644);
-       if (fd >= 0)
-               close(fd);
+       mknod("/tmp/lxcfs-iwashere", S_IFREG, 0644);
 }
 #endif
 
@@ -524,8 +544,9 @@ static double get_reaper_busy(pid_t task)
 
 static uint64_t get_reaper_start_time(pid_t pid)
 {
+       __do_free void *fopen_cache = NULL;
+       __do_fclose FILE *f = NULL;
        int ret;
-       FILE *f;
        uint64_t starttime;
        /* strlen("/proc/") = 6
         * +
@@ -553,7 +574,7 @@ static uint64_t get_reaper_start_time(pid_t pid)
                return 0;
        }
 
-       f = fopen(path, "r");
+       f = fopen_cached(path, "re", &fopen_cache);
        if (!f) {
                /* Caller can check for EINVAL on 0. */
                errno = EINVAL;
@@ -588,17 +609,10 @@ static uint64_t get_reaper_start_time(pid_t pid)
                        "%*d "      /* (21) itrealvalue %ld  */
                        "%" PRIu64, /* (22) starttime   %llu */
                     &starttime);
-       if (ret != 1) {
-               fclose(f);
-               /* Caller can check for EINVAL on 0. */
-               errno = EINVAL;
-               return 0;
-       }
+       if (ret != 1)
+               return ret_set_errno(0, EINVAL);
 
-       fclose(f);
-
-       errno = 0;
-       return starttime;
+       return ret_set_errno(starttime, 0);
 }
 
 static double get_reaper_start_time_in_sec(pid_t pid)
@@ -666,7 +680,7 @@ static int proc_uptime_read(char *buf, size_t size, off_t offset,
                            struct fuse_file_info *fi)
 {
        struct fuse_context *fc = fuse_get_context();
-       struct file_info *d = (struct file_info *)fi->fh;
+       struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        double busytime = get_reaper_busy(fc->pid);
        char *cache = d->buf;
        ssize_t total_len = 0;
@@ -715,10 +729,11 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
                          struct fuse_file_info *fi)
 {
        __do_free char *cg = NULL, *cpuset = NULL, *line = NULL;
+       __do_free void *fopen_cache = NULL;
        __do_free struct cpuacct_usage *cg_cpu_usage = NULL;
        __do_fclose FILE *f = NULL;
        struct fuse_context *fc = fuse_get_context();
-       struct file_info *d = (struct file_info *)fi->fh;
+       struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        size_t linelen = 0, total_len = 0;
        int curcpu = -1; /* cpu numbering starts at 0 */
        int physcpu = 0;
@@ -773,12 +788,10 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
         * If the cpuacct cgroup is present, it is used to calculate the container's
         * CPU usage. If not, values from the host's /proc/stat are used.
         */
-       if (read_cpuacct_usage_all(cg, cpuset, &cg_cpu_usage, &cg_cpu_usage_size) != 0) {
-               lxcfs_v("%s\n", "proc_stat_read failed to read from cpuacct, "
-                               "falling back to the host's /proc/stat");
-       }
+       if (read_cpuacct_usage_all(cg, cpuset, &cg_cpu_usage, &cg_cpu_usage_size) != 0)
+               lxcfs_v("%s\n", "proc_stat_read failed to read from cpuacct, falling back to the host's /proc/stat");
 
-       f = fopen("/proc/stat", "r");
+       f = fopen_cached("/proc/stat", "re", &fopen_cache);
        if (!f)
                return 0;
 
@@ -824,7 +837,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
                        continue;
                if (!cpu_in_cpuset(physcpu, cpuset))
                        continue;
-               curcpu ++;
+               curcpu++;
 
                ret = sscanf(line, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
                           &user,
@@ -872,15 +885,15 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
                                new_idle = idle + (all_used - cg_used);
 
                        } else {
-                               lxcfs_error("cpu%d from %s has unexpected cpu time: %lu in /proc/stat, "
-                                               "%lu in cpuacct.usage_all; unable to determine idle time\n",
-                                               curcpu, cg, all_used, cg_used);
+                               lxcfs_error("cpu%d from %s has unexpected cpu time: %" PRIu64 " in /proc/stat, %" PRIu64 " in cpuacct.usage_all; unable to determine idle time",
+                                           curcpu, cg, all_used, cg_used);
                                new_idle = idle;
                        }
 
-                       l = snprintf(cache, cache_size, "cpu%d %lu 0 %lu %lu 0 0 0 0 0 0\n",
-                                       curcpu, cg_cpu_usage[physcpu].user, cg_cpu_usage[physcpu].system,
-                                       new_idle);
+                       l = snprintf(cache, cache_size,
+                                    "cpu%d %" PRIu64 " 0 %" PRIu64 " %" PRIu64 " 0 0 0 0 0 0\n",
+                                    curcpu, cg_cpu_usage[physcpu].user,
+                                    cg_cpu_usage[physcpu].system, new_idle);
 
                        if (l < 0) {
                                perror("Error writing to cache");
@@ -950,60 +963,69 @@ out:
 }
 
 /* Note that "memory.stat" in cgroup2 is hierarchical by default. */
-static void parse_memstat(int version,
-                         char *memstat,
-                         unsigned long *cached,
-                         unsigned long *active_anon,
-                         unsigned long *inactive_anon,
-                         unsigned long *active_file,
-                         unsigned long *inactive_file,
-                         unsigned long *unevictable,
-                         unsigned long *shmem)
+static bool cgroup_parse_memory_stat(const char *cgroup, struct memory_stat *mstat)
 {
-       char *eol;
+       __do_close_prot_errno int fd = -EBADF;
+       __do_fclose FILE *f = NULL;
+       __do_free char *line = NULL;
+       bool unified;
+       size_t len = 0;
+       ssize_t linelen;
+
+       fd = cgroup_ops->get_memory_stats_fd(cgroup_ops, cgroup);
+       if (fd < 0)
+               return false;
 
-       while (*memstat) {
-               if (startswith(memstat, is_unified_controller(version)
-                                           ? "cache"
-                                           : "total_cache")) {
-                       sscanf(memstat + 11, "%lu", cached);
-                       *cached /= 1024;
-               } else if (startswith(memstat, is_unified_controller(version)
-                                                  ? "active_anon"
-                                                  : "total_active_anon")) {
-                       sscanf(memstat + 17, "%lu", active_anon);
-                       *active_anon /= 1024;
-               } else if (startswith(memstat, is_unified_controller(version)
-                                                  ? "inactive_anon"
-                                                  : "total_inactive_anon")) {
-                       sscanf(memstat + 19, "%lu", inactive_anon);
-                       *inactive_anon /= 1024;
-               } else if (startswith(memstat, is_unified_controller(version)
-                                                  ? "active_file"
-                                                  : "total_active_file")) {
-                       sscanf(memstat + 17, "%lu", active_file);
-                       *active_file /= 1024;
-               } else if (startswith(memstat, is_unified_controller(version)
-                                                  ? "inactive_file"
-                                                  : "total_inactive_file")) {
-                       sscanf(memstat + 19, "%lu", inactive_file);
-                       *inactive_file /= 1024;
-               } else if (startswith(memstat, is_unified_controller(version)
-                                                  ? "unevictable"
-                                                  : "total_unevictable")) {
-                       sscanf(memstat + 17, "%lu", unevictable);
-                       *unevictable /= 1024;
-               } else if (startswith(memstat, is_unified_controller(version)
-                                                  ? "shmem"
-                                                  : "total_shmem")) {
-                       sscanf(memstat + 11, "%lu", shmem);
-                       *shmem /= 1024;
+       f = fdopen(fd, "re");
+       if (!f)
+               return false;
+       /* Transferring ownership to fdopen(). */
+       move_fd(fd);
+
+       unified = pure_unified_layout(cgroup_ops);
+       while ((linelen = getline(&line, &len, f)) != -1) {
+               if (!unified && startswith(line, "hierarchical_memory_limit")) {
+                       sscanf(line, "hierarchical_memory_limit %" PRIu64, &(mstat->hierarchical_memory_limit));
+               } else if (!unified && startswith(line, "hierarchical_memsw_limit")) {
+                       sscanf(line, "hierarchical_memsw_limit %" PRIu64, &(mstat->hierarchical_memsw_limit));
+               } else if (startswith(line, unified ? "file" :"total_cache")) {
+                       sscanf(line, unified ? "file %" PRIu64 : "total_cache %" PRIu64, &(mstat->total_cache));
+               } else if (!unified && startswith(line, "total_rss")) {
+                       sscanf(line, "total_rss %" PRIu64, &(mstat->total_rss));
+               } else if (!unified && startswith(line, "total_rss_huge")) {
+                       sscanf(line, "total_rss_huge %" PRIu64, &(mstat->total_rss_huge));
+               } else if (startswith(line, unified ? "shmem" : "total_shmem")) {
+                       sscanf(line, unified ? "shmem %" PRIu64 : "total_shmem %" PRIu64, &(mstat->total_shmem));
+               } else if (startswith(line, unified ? "file_mapped" : "total_mapped_file")) {
+                       sscanf(line, unified ? "file_mapped %" PRIu64 : "total_mapped_file %" PRIu64, &(mstat->total_mapped_file));
+               } else if (!unified && startswith(line, "total_dirty")) {
+                       sscanf(line, "total_dirty %" PRIu64, &(mstat->total_dirty));
+               } else if (!unified && startswith(line, "total_writeback")) {
+                       sscanf(line, "total_writeback %" PRIu64, &(mstat->total_writeback));
+               } else if (!unified && startswith(line, "total_swap")) {
+                       sscanf(line, "total_swap %" PRIu64, &(mstat->total_swap));
+               } else if (!unified && startswith(line, "total_pgpgin")) {
+                       sscanf(line, "total_pgpgin %" PRIu64, &(mstat->total_pgpgin));
+               } else if (!unified && startswith(line, "total_pgpgout")) {
+                       sscanf(line, "total_pgpgout %" PRIu64, &(mstat->total_pgpgout));
+               } else if (startswith(line, unified ? "pgfault" : "total_pgfault")) {
+                       sscanf(line, unified ? "pgfault %" PRIu64 : "total_pgfault %" PRIu64, &(mstat->total_pgfault));
+               } else if (startswith(line, unified ? "pgmajfault" : "total_pgmajfault")) {
+                       sscanf(line, unified ? "pgmajfault %" PRIu64 : "total_pgmajfault %" PRIu64, &(mstat->total_pgmajfault));
+               } else if (startswith(line, unified ? "inactive_anon" : "total_inactive_anon")) {
+                       sscanf(line, unified ? "inactive_anon %" PRIu64 : "total_inactive_anon %" PRIu64, &(mstat->total_inactive_anon));
+               } else if (startswith(line, unified ? "active_anon" : "total_active_anon")) {
+                       sscanf(line, unified ? "active_anon %" PRIu64 : "total_active_anon %" PRIu64, &(mstat->total_active_anon));
+               } else if (startswith(line, unified ? "inactive_file" : "total_inactive_file")) {
+                       sscanf(line, unified ? "inactive_file %" PRIu64 : "total_inactive_file %" PRIu64, &(mstat->total_inactive_file));
+               } else if (startswith(line, unified ? "active_file" : "total_active_file")) {
+                       sscanf(line, unified ? "active_file %" PRIu64 : "total_active_file %" PRIu64, &(mstat->total_active_file));
+               } else if (startswith(line, unified ? "unevictable" : "total_unevictable")) {
+                       sscanf(line, unified ? "unevictable %" PRIu64 : "total_unevictable %" PRIu64, &(mstat->total_unevictable));
                }
-               eol = strchr(memstat, '\n');
-               if (!eol)
-                       return;
-               memstat = eol+1;
        }
+
+       return true;
 }
 
 static int proc_meminfo_read(char *buf, size_t size, off_t offset,
@@ -1012,14 +1034,14 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
        __do_free char *cgroup = NULL, *line = NULL,
                       *memusage_str = NULL, *memstat_str = NULL,
                       *memswlimit_str = NULL, *memswusage_str = NULL;
+       __do_free void *fopen_cache = NULL;
        __do_fclose FILE *f = NULL;
        struct fuse_context *fc = fuse_get_context();
        struct lxcfs_opts *opts = (struct lxcfs_opts *) fuse_get_context()->private_data;
-       struct file_info *d = (struct file_info *)fi->fh;
-       unsigned long memlimit = 0, memusage = 0, memswlimit = 0,
-                     memswusage = 0, cached = 0, hosttotal = 0, active_anon = 0,
-                     inactive_anon = 0, active_file = 0, inactive_file = 0,
-                     unevictable = 0, shmem = 0, hostswtotal = 0;
+       struct file_info *d = INTTYPE_TO_PTR(fi->fh);
+       uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
+                hosttotal = 0;
+       struct memory_stat mstat = {};
        size_t linelen = 0, total_len = 0;
        char *cache = d->buf;
        size_t cache_size = d->buflen;
@@ -1057,11 +1079,8 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
        if (ret < 0)
                return 0;
 
-       ret = cgroup_ops->get_memory_stats(cgroup_ops, cgroup, &memstat_str);
-       if (ret < 0)
+       if (!cgroup_parse_memory_stat(cgroup, &mstat))
                return 0;
-       parse_memstat(ret, memstat_str, &cached, &active_anon, &inactive_anon,
-                     &active_file, &inactive_file, &unevictable, &shmem);
 
        /*
         * Following values are allowed to fail, because swapaccount might be
@@ -1081,7 +1100,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
        memlimit /= 1024;
        memusage /= 1024;
 
-       f = fopen("/proc/meminfo", "r");
+       f = fopen_cached("/proc/meminfo", "re", &fopen_cache);
        if (!f)
                return 0;
 
@@ -1091,93 +1110,125 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
 
                memset(lbuf, 0, 100);
                if (startswith(line, "MemTotal:")) {
-                       sscanf(line+sizeof("MemTotal:")-1, "%lu", &hosttotal);
+                       sscanf(line+sizeof("MemTotal:")-1, "%" PRIu64, &hosttotal);
                        if (hosttotal < memlimit)
                                memlimit = hosttotal;
-                       snprintf(lbuf, 100, "MemTotal:       %8lu kB\n", memlimit);
+                       snprintf(lbuf, 100, "MemTotal:       %8" PRIu64 " kB\n", memlimit);
                        printme = lbuf;
                } else if (startswith(line, "MemFree:")) {
-                       snprintf(lbuf, 100, "MemFree:        %8lu kB\n", memlimit - memusage);
+                       snprintf(lbuf, 100, "MemFree:        %8" PRIu64 " kB\n", memlimit - memusage);
                        printme = lbuf;
                } else if (startswith(line, "MemAvailable:")) {
-                       snprintf(lbuf, 100, "MemAvailable:   %8lu kB\n", memlimit - memusage + cached);
+                       snprintf(lbuf, 100, "MemAvailable:   %8" PRIu64 " kB\n", memlimit - memusage + mstat.total_cache / 1024);
                        printme = lbuf;
                } else if (startswith(line, "SwapTotal:") && memswlimit > 0 &&
                           opts && opts->swap_off == false) {
-                       sscanf(line+sizeof("SwapTotal:")-1, "%lu", &hostswtotal);
-                       if (hostswtotal < memswlimit)
-                               memswlimit = hostswtotal;
-                       snprintf(lbuf, 100, "SwapTotal:      %8lu kB\n", memswlimit);
+                       memswlimit -= memlimit;
+                       snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " kB\n", memswlimit);
                        printme = lbuf;
                } else if (startswith(line, "SwapTotal:") && opts && opts->swap_off == true) {
-                       snprintf(lbuf, 100, "SwapTotal:      %8lu kB\n", 0UL);
+                       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) {
-                       unsigned long swaptotal = memswlimit,
-                                     swapusage = memusage > memswusage
-                                                     ? 0
-                                                     : memswusage - memusage,
-                                     swapfree = swapusage < swaptotal
-                                                    ? swaptotal - swapusage
-                                                    : 0;
-                       snprintf(lbuf, 100, "SwapFree:       %8lu kB\n", swapfree);
+                       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);
                        printme = lbuf;
                } else if (startswith(line, "SwapFree:") && opts && opts->swap_off == true) {
-                       snprintf(lbuf, 100, "SwapFree:       %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "Slab:")) {
-                       snprintf(lbuf, 100, "Slab:        %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "Slab:        %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "Buffers:")) {
-                       snprintf(lbuf, 100, "Buffers:        %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "Buffers:        %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "Cached:")) {
-                       snprintf(lbuf, 100, "Cached:         %8lu kB\n", cached);
+                       snprintf(lbuf, 100, "Cached:         %8" PRIu64 " kB\n",
+                                mstat.total_cache / 1024);
                        printme = lbuf;
                } else if (startswith(line, "SwapCached:")) {
-                       snprintf(lbuf, 100, "SwapCached:     %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "SwapCached:     %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "Active:")) {
-                       snprintf(lbuf, 100, "Active:         %8lu kB\n",
-                                       active_anon + active_file);
+                       snprintf(lbuf, 100, "Active:         %8" PRIu64 " kB\n",
+                                (mstat.total_active_anon +
+                                 mstat.total_active_file) /
+                                    1024);
                        printme = lbuf;
                } else if (startswith(line, "Inactive:")) {
-                       snprintf(lbuf, 100, "Inactive:       %8lu kB\n",
-                                       inactive_anon + inactive_file);
+                       snprintf(lbuf, 100, "Inactive:       %8" PRIu64 " kB\n",
+                                (mstat.total_inactive_anon +
+                                 mstat.total_inactive_file) /
+                                    1024);
                        printme = lbuf;
                } else if (startswith(line, "Active(anon)")) {
-                       snprintf(lbuf, 100, "Active(anon):   %8lu kB\n", active_anon);
+                       snprintf(lbuf, 100, "Active(anon):   %8" PRIu64 " kB\n",
+                                mstat.total_active_anon / 1024);
                        printme = lbuf;
                } else if (startswith(line, "Inactive(anon)")) {
-                       snprintf(lbuf, 100, "Inactive(anon): %8lu kB\n", inactive_anon);
+                       snprintf(lbuf, 100, "Inactive(anon): %8" PRIu64 " kB\n",
+                                mstat.total_inactive_anon / 1024);
                        printme = lbuf;
                } else if (startswith(line, "Active(file)")) {
-                       snprintf(lbuf, 100, "Active(file):   %8lu kB\n", active_file);
+                       snprintf(lbuf, 100, "Active(file):   %8" PRIu64 " kB\n",
+                                mstat.total_active_file / 1024);
                        printme = lbuf;
                } else if (startswith(line, "Inactive(file)")) {
-                       snprintf(lbuf, 100, "Inactive(file): %8lu kB\n", inactive_file);
+                       snprintf(lbuf, 100, "Inactive(file): %8" PRIu64 " kB\n",
+                                mstat.total_inactive_file / 1024);
                        printme = lbuf;
                } else if (startswith(line, "Unevictable")) {
-                       snprintf(lbuf, 100, "Unevictable:    %8lu kB\n", unevictable);
+                       snprintf(lbuf, 100, "Unevictable:    %8" PRIu64 " kB\n",
+                                mstat.total_unevictable / 1024);
+                       printme = lbuf;
+               } else if (startswith(line, "Dirty")) {
+                       snprintf(lbuf, 100, "Dirty:          %8" PRIu64 " kB\n",
+                                mstat.total_dirty / 1024);
+                       printme = lbuf;
+               } else if (startswith(line, "Writeback")) {
+                       snprintf(lbuf, 100, "Writeback:      %8" PRIu64 " kB\n",
+                                mstat.total_writeback / 1024);
+                       printme = lbuf;
+               } else if (startswith(line, "AnonPages")) {
+                       snprintf(lbuf, 100, "AnonPages:      %8" PRIu64 " kB\n",
+                                (mstat.total_active_anon +
+                                 mstat.total_inactive_anon - mstat.total_shmem) /
+                                    1024);
+                       printme = lbuf;
+               } else if (startswith(line, "Mapped")) {
+                       snprintf(lbuf, 100, "Mapped:         %8" PRIu64 " kB\n",
+                                mstat.total_mapped_file / 1024);
                        printme = lbuf;
                } else if (startswith(line, "SReclaimable")) {
-                       snprintf(lbuf, 100, "SReclaimable:   %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "SReclaimable:   %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "SUnreclaim")) {
-                       snprintf(lbuf, 100, "SUnreclaim:     %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "SUnreclaim:     %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "Shmem:")) {
-                       snprintf(lbuf, 100, "Shmem:          %8lu kB\n", shmem);
+                       snprintf(lbuf, 100, "Shmem:          %8" PRIu64 " kB\n",
+                                mstat.total_shmem / 1024);
                        printme = lbuf;
                } else if (startswith(line, "ShmemHugePages")) {
-                       snprintf(lbuf, 100, "ShmemHugePages: %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "ShmemHugePages: %8" PRIu64 " kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "ShmemPmdMapped")) {
-                       snprintf(lbuf, 100, "ShmemPmdMapped: %8lu kB\n", 0UL);
+                       snprintf(lbuf, 100, "ShmemPmdMapped: %8" PRIu64 " kB\n", (uint64_t)0);
+                       printme = lbuf;
+               } else if (startswith(line, "AnonHugePages")) {
+                       snprintf(lbuf, 100, "AnonHugePages:  %8" PRIu64 " kB\n",
+                                mstat.total_rss_huge / 1024);
                        printme = lbuf;
-               } else
-                       printme = line;
+               } else {
+                       printme = line;
+               }
 
                l = snprintf(cache, cache_size, "%s", printme);
                if (l < 0) {
@@ -1204,9 +1255,9 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
 }
 
 int proc_read(const char *path, char *buf, size_t size, off_t offset,
-               struct fuse_file_info *fi)
+             struct fuse_file_info *fi)
 {
-       struct file_info *f = (struct file_info *) fi->fh;
+       struct file_info *f = INTTYPE_TO_PTR(fi->fh);
 
        switch (f->type) {
        case LXC_TYPE_PROC_MEMINFO:
@@ -1223,7 +1274,7 @@ int proc_read(const char *path, char *buf, size_t size, off_t offset,
                return proc_swaps_read(buf, size, offset, fi);
        case LXC_TYPE_PROC_LOADAVG:
                return proc_loadavg_read(buf, size, offset, fi);
-       default:
-               return -EINVAL;
        }
+
+       return -EINVAL;
 }