Built over https://github.com/tssge/lxcfs/commit/50b75e3

Example Output:

[root@lxc-dev ~]# lxc-attach -n ubuntuwily --  /bin/cat /proc/swaps
Filename                                Type            Size    Used    Priority
none                                    virtual         1048572 1048572 0


Signed-off-by: Nehal J Wani <nehaljw.k...@gmail.com>
---
 lxcfs.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 116 insertions(+), 2 deletions(-)

diff --git a/lxcfs.c b/lxcfs.c
index a561882..9c52862 100644
--- a/lxcfs.c
+++ b/lxcfs.c
@@ -43,6 +43,7 @@ enum {
        LXC_TYPE_PROC_UPTIME,
        LXC_TYPE_PROC_STAT,
        LXC_TYPE_PROC_DISKSTATS,
+       LXC_TYPE_PROC_SWAPS,
 };
 
 struct file_info {
@@ -2394,6 +2395,113 @@ err:
        return rv;
 }
 
+static int proc_swaps_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;
+       char *cg;
+       char *memswlimit_str = NULL, *memlimit_str = NULL, *memusage_str = 
NULL, *memswusage_str = NULL,
+             *memswlimit_default_str = NULL, *memswusage_default_str = NULL;
+       unsigned long memswlimit = 0, memlimit = 0, memusage = 0, memswusage = 
0, swap_total = 0, swap_free = 0;
+       size_t total_len = 0, rv = 0, linelen = 0;
+       char *cache = d->buf;
+       char *line = NULL;
+       FILE *f = NULL;
+
+       if (offset) {
+               if (offset > d->size)
+                       return -EINVAL;
+               if (!d->cached)
+                       return 0;
+               int left = d->size - offset;
+               total_len = left > size ? size: left;
+               memcpy(buf, cache + offset, total_len);
+               return total_len;
+       }
+
+       cg = get_pid_cgroup(fc->pid, "memory");
+
+       if (!cg)
+               return read_file("/proc/swaps", buf, size, d);
+
+       if (!cgfs_get_value("memory", cg, "memory.limit_in_bytes", 
&memlimit_str))
+               goto err;
+
+       if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", 
&memusage_str))
+               goto err;
+
+       memlimit = strtoul(memlimit_str, NULL, 10);
+       memusage = strtoul(memusage_str, NULL, 10);
+
+       if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", 
&memswusage_str) &&
+           cgfs_get_value("memory", cg, "memory.memsw.limit_in_bytes", 
&memswlimit_str)) {
+
+                /* If swap accounting is turned on, then default value is 
assumed to be that of cgroup / */
+                if (!cgfs_get_value("memory", "/", 
"memory.memsw.limit_in_bytes", &memswlimit_default_str))
+                    goto err;
+                if (!cgfs_get_value("memory", "/", 
"memory.memsw.usage_in_bytes", &memswusage_default_str))
+                    goto err;
+
+               memswlimit = strtoul(memswlimit_str, NULL, 10);
+               memswusage = strtoul(memswusage_str, NULL, 10);
+
+                if (!strcmp(memswlimit_str, memswlimit_default_str))
+                    memswlimit = 0;
+                if (!strcmp(memswusage_str, memswusage_default_str))
+                    memswusage = 0;
+
+               swap_total = (memswlimit - memlimit) / 1024;
+               swap_free = (memswusage - memusage) / 1024;
+       }
+
+       total_len = snprintf(d->buf, d->size, 
"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
+
+       /* When no mem + swap limit is specified or swapaccount=0*/
+       if (!memswlimit) {
+               f = fopen("/proc/meminfo", "r");
+               if (!f)
+                       goto err;
+
+               while (getline(&line, &linelen, f) != -1) {
+                       if (startswith(line, "SwapTotal:")) {
+                               sscanf(line, "SwapTotal:      %8lu kB", 
&swap_total);
+                       } else if (startswith(line, "SwapFree:")) {
+                               sscanf(line, "SwapFree:      %8lu kB", 
&swap_free);
+                       }
+               }
+       }
+
+       if (swap_total > 0) {
+               total_len += snprintf(d->buf + total_len, d->size,
+                                "none%*svirtual\t\t%lu\t%lu\t0\n", 36, " ",
+                                swap_total, swap_free);
+       }
+
+       if (total_len < 0) {
+               perror("Error writing to cache");
+               rv = 0;
+               goto err;
+       }
+
+       d->cached = 1;
+       d->size = (int)total_len;
+
+       if (total_len > size) total_len = size;
+       memcpy(buf, d->buf, total_len);
+       rv = total_len;
+
+err:
+       free(cg);
+       free(memswlimit_str);
+       free(memlimit_str);
+       free(memusage_str);
+       free(memswusage_str);
+       free(memswusage_default_str);
+       free(memswlimit_default_str);
+       return rv;
+}
+
 /*
  * Read the cpuset.cpus for cg
  * Return the answer in a newly allocated string which must be freed
@@ -2956,7 +3064,8 @@ static int proc_getattr(const char *path, struct stat *sb)
                        strcmp(path, "/proc/cpuinfo") == 0 ||
                        strcmp(path, "/proc/uptime") == 0 ||
                        strcmp(path, "/proc/stat") == 0 ||
-                       strcmp(path, "/proc/diskstats") == 0) {
+                       strcmp(path, "/proc/diskstats") == 0 ||
+                       strcmp(path, "/proc/swaps") == 0) {
                sb->st_size = 0;
                sb->st_mode = S_IFREG | 00444;
                sb->st_nlink = 1;
@@ -2973,7 +3082,8 @@ static int proc_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler, off
                                filler(buf, "meminfo", NULL, 0) != 0 ||
                                filler(buf, "stat", NULL, 0) != 0 ||
                                filler(buf, "uptime", NULL, 0) != 0 ||
-                               filler(buf, "diskstats", NULL, 0) != 0)
+                               filler(buf, "diskstats", NULL, 0) != 0 ||
+                               filler(buf, "swaps", NULL, 0) != 0)
                return -EINVAL;
        return 0;
 }
@@ -2993,6 +3103,8 @@ static int proc_open(const char *path, struct 
fuse_file_info *fi)
                type = LXC_TYPE_PROC_STAT;
        else if (strcmp(path, "/proc/diskstats") == 0)
                type = LXC_TYPE_PROC_DISKSTATS;
+       else if (strcmp(path, "/proc/swaps") == 0)
+               type = LXC_TYPE_PROC_SWAPS;
        if (type == -1)
                return -ENOENT;
 
@@ -3039,6 +3151,8 @@ static int proc_read(const char *path, char *buf, size_t 
size, off_t offset,
                return proc_stat_read(buf, size, offset, fi);
        case LXC_TYPE_PROC_DISKSTATS:
                return proc_diskstats_read(buf, size, offset, fi);
+       case LXC_TYPE_PROC_SWAPS:
+               return proc_swaps_read(buf, size, offset, fi);
        default:
                return -EINVAL;
        }
-- 
2.5.0

_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to