The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/365

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From 7689e7a469c85e227235bd57c6d2fcfeb70cbde2 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Fri, 13 Mar 2020 12:22:26 +0100
Subject: [PATCH 1/3] tree-wide: mark lxcfs fuse ops

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 src/cgroup_fuse.c | 33 +++++++++++++++++----------------
 src/macro.h       |  2 ++
 src/proc_fuse.c   | 17 +++++++++--------
 src/sysfs_fuse.c  | 19 ++++++++++---------
 4 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/src/cgroup_fuse.c b/src/cgroup_fuse.c
index 46a7a2f..2ca7139 100644
--- a/src/cgroup_fuse.c
+++ b/src/cgroup_fuse.c
@@ -499,7 +499,7 @@ static bool fc_may_access(struct fuse_context *fc, const 
char *contrl, const cha
        return ret;
 }
 
-int cg_getattr(const char *path, struct stat *sb)
+__lxcfs_fuse_ops int cg_getattr(const char *path, struct stat *sb)
 {
        struct timespec now;
        struct fuse_context *fc = fuse_get_context();
@@ -682,7 +682,7 @@ static int cgfs_create(const char *controller, const char 
*cg, uid_t uid, gid_t
        return 0;
 }
 
-int cg_mkdir(const char *path, mode_t mode)
+__lxcfs_fuse_ops int cg_mkdir(const char *path, mode_t mode)
 {
        struct fuse_context *fc = fuse_get_context();
        char *last = NULL, *path1, *cgdir = NULL, *controller, *next = NULL;
@@ -822,7 +822,7 @@ static bool cgfs_remove(const char *controller, const char 
*cg)
        return bret;
 }
 
-int cg_rmdir(const char *path)
+__lxcfs_fuse_ops int cg_rmdir(const char *path)
 {
        struct fuse_context *fc = fuse_get_context();
        char *last = NULL, *cgdir = NULL, *controller, *next = NULL;
@@ -904,7 +904,7 @@ static bool cgfs_chmod_file(const char *controller, const 
char *file, mode_t mod
        return true;
 }
 
-int cg_chmod(const char *path, mode_t mode)
+__lxcfs_fuse_ops int cg_chmod(const char *path, mode_t mode)
 {
        struct fuse_context *fc = fuse_get_context();
        char * cgdir = NULL, *last = NULL, *path1, *path2, *controller;
@@ -1024,7 +1024,7 @@ static int cgfs_chown_file(const char *controller, const 
char *file, uid_t uid,
        return 0;
 }
 
-int cg_chown(const char *path, uid_t uid, gid_t gid)
+__lxcfs_fuse_ops int cg_chown(const char *path, uid_t uid, gid_t gid)
 {
        struct fuse_context *fc = fuse_get_context();
        char *cgdir = NULL, *last = NULL, *path1, *path2, *controller;
@@ -1090,7 +1090,7 @@ int cg_chown(const char *path, uid_t uid, gid_t gid)
        return ret;
 }
 
-int cg_open(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int cg_open(const char *path, struct fuse_file_info *fi)
 {
        const char *cgroup;
        char *last = NULL, *path1, *path2, * cgdir = NULL, *controller;
@@ -1354,8 +1354,8 @@ static bool do_read_pids(pid_t tpid, const char *contrl, 
const char *cg,
        return answer;
 }
 
-int cg_read(const char *path, char *buf, size_t size, off_t offset,
-           struct fuse_file_info *fi)
+__lxcfs_fuse_ops int cg_read(const char *path, char *buf, size_t size,
+                            off_t offset, struct fuse_file_info *fi)
 {
        struct fuse_context *fc = fuse_get_context();
        struct file_info *f = INTTYPE_TO_PTR(fi->fh);
@@ -1421,7 +1421,7 @@ int cg_read(const char *path, char *buf, size_t size, 
off_t offset,
        return ret;
 }
 
-int cg_opendir(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int cg_opendir(const char *path, struct fuse_file_info *fi)
 {
        struct fuse_context *fc = fuse_get_context();
        const char *cgroup;
@@ -1472,13 +1472,13 @@ int cg_opendir(const char *path, struct fuse_file_info 
*fi)
        return 0;
 }
 
-int cg_release(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int cg_release(const char *path, struct fuse_file_info *fi)
 {
        do_release_file_info(fi);
        return 0;
 }
 
-int cg_releasedir(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int cg_releasedir(const char *path, struct fuse_file_info *fi)
 {
        do_release_file_info(fi);
        return 0;
@@ -1805,8 +1805,8 @@ static bool cgfs_set_value(const char *controller, const 
char *cgroup,
        return write_string(fnam, value, fd);
 }
 
-int cg_write(const char *path, const char *buf, size_t size, off_t offset,
-            struct fuse_file_info *fi)
+__lxcfs_fuse_ops int cg_write(const char *path, const char *buf, size_t size,
+                             off_t offset, struct fuse_file_info *fi)
 {
        struct fuse_context *fc = fuse_get_context();
        char *localbuf = NULL;
@@ -1974,8 +1974,9 @@ static void free_keys(struct cgfs_files **keys)
        free_disarm(keys);
 }
 
-int cg_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
-              off_t offset, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int cg_readdir(const char *path, void *buf,
+                               fuse_fill_dir_t filler, off_t offset,
+                               struct fuse_file_info *fi)
 {
        struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        struct cgfs_files **list = NULL;
@@ -2065,7 +2066,7 @@ int cg_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler,
        return ret;
 }
 
-int cg_access(const char *path, int mode)
+__lxcfs_fuse_ops int cg_access(const char *path, int mode)
 {
        int ret;
        const char *cgroup;
diff --git a/src/macro.h b/src/macro.h
index ce08510..29b5ed7 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -123,4 +123,6 @@
 
 #define __visible __attribute__((visibility("default")))
 
+#define __lxcfs_fuse_ops
+
 #endif /* __LXCFS_MACRO_H */
diff --git a/src/proc_fuse.c b/src/proc_fuse.c
index b62d6e4..ae557a9 100644
--- a/src/proc_fuse.c
+++ b/src/proc_fuse.c
@@ -72,7 +72,7 @@ struct memory_stat {
        uint64_t total_unevictable;
 };
 
-int proc_getattr(const char *path, struct stat *sb)
+__lxcfs_fuse_ops int proc_getattr(const char *path, struct stat *sb)
 {
        struct timespec now;
 
@@ -104,8 +104,9 @@ int proc_getattr(const char *path, struct stat *sb)
        return -ENOENT;
 }
 
-int proc_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
-                off_t offset, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int proc_readdir(const char *path, void *buf,
+                                 fuse_fill_dir_t filler, off_t offset,
+                                 struct fuse_file_info *fi)
 {
        if (filler(buf, ".",            NULL, 0) != 0 ||
            filler(buf, "..",           NULL, 0) != 0 ||
@@ -138,7 +139,7 @@ static off_t get_procfile_size(const char *path)
        return answer;
 }
 
-int proc_open(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int proc_open(const char *path, struct fuse_file_info *fi)
 {
        __do_free struct file_info *info = NULL;
        int type = -1;
@@ -181,7 +182,7 @@ int proc_open(const char *path, struct fuse_file_info *fi)
        return 0;
 }
 
-int proc_access(const char *path, int mask)
+__lxcfs_fuse_ops int proc_access(const char *path, int mask)
 {
        if (strcmp(path, "/proc") == 0 && access(path, R_OK) == 0)
                return 0;
@@ -193,7 +194,7 @@ int proc_access(const char *path, int mask)
        return 0;
 }
 
-int proc_release(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int proc_release(const char *path, struct fuse_file_info *fi)
 {
        do_release_file_info(fi);
        return 0;
@@ -1248,8 +1249,8 @@ static int proc_meminfo_read(char *buf, size_t size, 
off_t offset,
        return total_len;
 }
 
-int proc_read(const char *path, char *buf, size_t size, off_t offset,
-             struct fuse_file_info *fi)
+__lxcfs_fuse_ops int proc_read(const char *path, char *buf, size_t size,
+                              off_t offset, struct fuse_file_info *fi)
 {
        struct file_info *f = INTTYPE_TO_PTR(fi->fh);
 
diff --git a/src/sysfs_fuse.c b/src/sysfs_fuse.c
index 3114e4f..85bc12c 100644
--- a/src/sysfs_fuse.c
+++ b/src/sysfs_fuse.c
@@ -133,7 +133,7 @@ static off_t get_sysfile_size(const char *which)
        return answer;
 }
 
-int sys_getattr(const char *path, struct stat *sb)
+__lxcfs_fuse_ops int sys_getattr(const char *path, struct stat *sb)
 {
        struct timespec now;
 
@@ -177,8 +177,9 @@ int sys_getattr(const char *path, struct stat *sb)
        return -ENOENT;
 }
 
-int sys_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
-               off_t offset, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int sys_readdir(const char *path, void *buf,
+                                fuse_fill_dir_t filler, off_t offset,
+                                struct fuse_file_info *fi)
 {
        if (strcmp(path, "/sys") == 0) {
                if (filler(buf, ".",            NULL, 0) != 0 ||
@@ -216,7 +217,7 @@ int sys_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler,
        return 0;
 }
 
-int sys_open(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int sys_open(const char *path, struct fuse_file_info *fi)
 {
        __do_free struct file_info *info = NULL;
        int type = -1;
@@ -253,7 +254,7 @@ int sys_open(const char *path, struct fuse_file_info *fi)
        return 0;
 }
 
-int sys_access(const char *path, int mask)
+__lxcfs_fuse_ops int sys_access(const char *path, int mask)
 {
        if (strcmp(path, "/sys") == 0 && access(path, R_OK) == 0)
                return 0;
@@ -275,20 +276,20 @@ int sys_access(const char *path, int mask)
        return 0;
 }
 
-int sys_release(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int sys_release(const char *path, struct fuse_file_info *fi)
 {
        do_release_file_info(fi);
        return 0;
 }
 
-int sys_releasedir(const char *path, struct fuse_file_info *fi)
+__lxcfs_fuse_ops int sys_releasedir(const char *path, struct fuse_file_info 
*fi)
 {
        do_release_file_info(fi);
        return 0;
 }
 
-int sys_read(const char *path, char *buf, size_t size, off_t offset,
-            struct fuse_file_info *fi)
+__lxcfs_fuse_ops int sys_read(const char *path, char *buf, size_t size,
+                             off_t offset, struct fuse_file_info *fi)
 {
        struct file_info *f = INTTYPE_TO_PTR(fi->fh);
 

From 2c7dd60d9f08e7f33eb55dd70fbef31093426651 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Fri, 13 Mar 2020 12:24:41 +0100
Subject: [PATCH 2/3] bindings: make constructor failures non-fatal

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 src/bindings.c | 40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/bindings.c b/src/bindings.c
index 26ff9bf..28d252c 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -722,28 +722,38 @@ static void __attribute__((constructor)) lxcfs_init(void)
        int i = 0;
        pid_t pid;
 
-       lxcfs_info("Running constructor %s", __func__);
+       lxcfs_info("Running constructor %s to reload liblxcfs with count", 
__func__);
 
        cgroup_ops = cgroup_init();
-       if (!cgroup_ops)
-               log_exit("Failed to initialize cgroup support");
+       if (!cgroup_ops) {
+               lxcfs_info("Failed to initialize cgroup support");
+               goto broken_upgrade;
+       }
 
        /* Preserve initial namespace. */
        pid = getpid();
        init_ns = preserve_ns(pid, "mnt");
-       if (init_ns < 0)
-               log_exit("Failed to preserve initial mount namespace");
+       if (init_ns < 0) {
+               lxcfs_info("Failed to preserve initial mount namespace");
+               goto broken_upgrade;
+       }
 
        /* This function calls unshare(CLONE_NEWNS) our initial mount namespace
         * to privately mount lxcfs cgroups. */
-       if (!cgfs_setup_controllers())
+       if (!cgfs_setup_controllers()) {
                log_exit("Failed to setup private cgroup mounts for lxcfs");
+               goto broken_upgrade;
+       }
 
-       if (setns(init_ns, 0) < 0)
+       if (setns(init_ns, 0) < 0) {
                log_exit("%s - Failed to switch back to initial mount 
namespace", strerror(errno));
+               goto broken_upgrade;
+       }
 
-       if (!init_cpuview())
+       if (!init_cpuview()) {
                log_exit("Failed to init CPU view");
+               goto broken_upgrade;
+       }
 
        lxcfs_info("mount namespace: %d", cgroup_ops->mntns_fd);
        lxcfs_info("hierarchies:");
@@ -767,13 +777,15 @@ static void __attribute__((constructor)) lxcfs_init(void)
                lxcfs_info("- %s", api_extensions[i]);
 
        root_fd = open("/", O_PATH | O_CLOEXEC);
-       if (root_fd < 0) {
-               lxcfs_error("%s - Failed to open root directory", 
strerror(errno));
-               return;
-       }
+       if (root_fd < 0)
+               lxcfs_info("%s - Failed to open root directory", 
strerror(errno));
+       else if (fchdir(root_fd) < 0)
+               lxcfs_info("%s - Failed to change to root directory", 
strerror(errno));
+
+       return;
 
-       if (fchdir(root_fd) < 0)
-               lxcfs_error("%s - Failed to change to root directory", 
strerror(errno));
+broken_upgrade:
+       lxcfs_info("Failed to run constructor %s to reload liblxcfs", __func__);
 }
 
 static void __attribute__((destructor)) lxcfs_exit(void)

From 5f0c2794798625107aa9148bf5bfdc03053942d5 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Fri, 13 Mar 2020 13:24:59 +0100
Subject: [PATCH 3/3] liblxcfs: handle broken upgrade gracefully

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 src/bindings.c    | 10 +++++++++-
 src/bindings.h    | 18 ++++++++++++++++++
 src/cgroup_fuse.c | 32 ++++++++++++++++++++++++++++++++
 src/macro.h       | 10 ++++++++++
 src/proc_fuse.c   | 47 ++++++++++++++++++++++++++++++++++++++---------
 src/sysfs_fuse.c  |  6 +++++-
 src/utils.c       | 25 +++++++++++++++++++++++++
 src/utils.h       |  2 ++
 8 files changed, 139 insertions(+), 11 deletions(-)

diff --git a/src/bindings.c b/src/bindings.c
index 28d252c..bcee24c 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -50,6 +50,12 @@
 #include "utils.h"
 
 static bool can_use_pidfd;
+static bool reload_successful;
+
+bool liblxcfs_functional(void)
+{
+       return reload_successful;
+}
 
 /* Define pivot_root() if missing from the C library */
 #ifndef HAVE_PIVOT_ROOT
@@ -722,7 +728,7 @@ static void __attribute__((constructor)) lxcfs_init(void)
        int i = 0;
        pid_t pid;
 
-       lxcfs_info("Running constructor %s to reload liblxcfs with count", 
__func__);
+       lxcfs_info("Running constructor %s to reload liblxcfs", __func__);
 
        cgroup_ops = cgroup_init();
        if (!cgroup_ops) {
@@ -782,9 +788,11 @@ static void __attribute__((constructor)) lxcfs_init(void)
        else if (fchdir(root_fd) < 0)
                lxcfs_info("%s - Failed to change to root directory", 
strerror(errno));
 
+       reload_successful = true;
        return;
 
 broken_upgrade:
+       reload_successful = false;
        lxcfs_info("Failed to run constructor %s to reload liblxcfs", __func__);
 }
 
diff --git a/src/bindings.h b/src/bindings.h
index b4bc0e5..43dc258 100644
--- a/src/bindings.h
+++ b/src/bindings.h
@@ -39,17 +39,34 @@
 enum lxcfs_virt_t {
        LXC_TYPE_CGDIR,
        LXC_TYPE_CGFILE,
+
        LXC_TYPE_PROC_MEMINFO,
+#define LXC_TYPE_PROC_MEMINFO_PATH "/proc/meminfo"
+
        LXC_TYPE_PROC_CPUINFO,
+#define LXC_TYPE_PROC_CPUINFO_PATH "/proc/cpuinfo"
+
        LXC_TYPE_PROC_UPTIME,
+#define LXC_TYPE_PROC_UPTIME_PATH "/proc/uptime"
+
        LXC_TYPE_PROC_STAT,
+#define LXC_TYPE_PROC_STAT_PATH "/proc/stat"
+
        LXC_TYPE_PROC_DISKSTATS,
+#define LXC_TYPE_PROC_DISKSTATS_PATH "/proc/diskstats"
+
        LXC_TYPE_PROC_SWAPS,
+#define LXC_TYPE_PROC_SWAPS_PATH "/proc/swaps"
+
        LXC_TYPE_PROC_LOADAVG,
+#define LXC_TYPE_PROC_LOADAVG_PATH "/proc/loadavg"
+
        LXC_TYPE_SYS_DEVICES,
        LXC_TYPE_SYS_DEVICES_SYSTEM,
        LXC_TYPE_SYS_DEVICES_SYSTEM_CPU,
+
        LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE,
+#define LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE_PATH 
"/sys/devices/system/cpu/online"
 };
 
 struct file_info {
@@ -72,5 +89,6 @@ struct lxcfs_opts {
 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);
 
 #endif /* __LXCFS_BINDINGS_H */
diff --git a/src/cgroup_fuse.c b/src/cgroup_fuse.c
index 2ca7139..2130d7a 100644
--- a/src/cgroup_fuse.c
+++ b/src/cgroup_fuse.c
@@ -510,6 +510,8 @@ __lxcfs_fuse_ops int cg_getattr(const char *path, struct 
stat *sb)
        const char *controller = NULL;
        int ret = -ENOENT;
 
+       if (!liblxcfs_functional())
+               return -EIO;
 
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
@@ -689,6 +691,9 @@ __lxcfs_fuse_ops int cg_mkdir(const char *path, mode_t mode)
        const char *cgroup;
        int ret;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -829,6 +834,9 @@ __lxcfs_fuse_ops int cg_rmdir(const char *path)
        const char *cgroup;
        int ret;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -912,6 +920,9 @@ __lxcfs_fuse_ops int cg_chmod(const char *path, mode_t mode)
        const char *cgroup;
        int ret;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -1032,6 +1043,9 @@ __lxcfs_fuse_ops int cg_chown(const char *path, uid_t 
uid, gid_t gid)
        const char *cgroup;
        int ret;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -1099,6 +1113,9 @@ __lxcfs_fuse_ops int cg_open(const char *path, struct 
fuse_file_info *fi)
        struct fuse_context *fc = fuse_get_context();
        int ret;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -1364,6 +1381,9 @@ __lxcfs_fuse_ops int cg_read(const char *path, char *buf, 
size_t size,
        int ret, s;
        bool r;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -1428,6 +1448,9 @@ __lxcfs_fuse_ops int cg_opendir(const char *path, struct 
fuse_file_info *fi)
        struct file_info *dir_info;
        char *controller = NULL;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -1814,6 +1837,9 @@ __lxcfs_fuse_ops int cg_write(const char *path, const 
char *buf, size_t size,
        struct file_info *f = INTTYPE_TO_PTR(fi->fh);
        bool r;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -1985,6 +2011,9 @@ __lxcfs_fuse_ops int cg_readdir(const char *path, void 
*buf,
        struct fuse_context *fc = fuse_get_context();
        char **clist = NULL;
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
@@ -2075,6 +2104,9 @@ __lxcfs_fuse_ops int cg_access(const char *path, int mode)
        struct cgfs_files *k = NULL;
        struct fuse_context *fc = fuse_get_context();
 
+       if (!liblxcfs_functional())
+               return -EIO;
+
        if (!fc || !cgroup_ops || pure_unified_layout(cgroup_ops))
                return -EIO;
 
diff --git a/src/macro.h b/src/macro.h
index 29b5ed7..8ad7984 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -125,4 +125,14 @@
 
 #define __lxcfs_fuse_ops
 
+#ifndef thread_local
+#if __STDC_VERSION__ >= 201112L &&    \
+    !(defined(__STDC_NO_THREADS__) || \
+      (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
+#define thread_local _Thread_local
+#else
+#define thread_local __thread
+#endif
+#endif
+
 #endif /* __LXCFS_MACRO_H */
diff --git a/src/proc_fuse.c b/src/proc_fuse.c
index ae557a9..9652163 100644
--- a/src/proc_fuse.c
+++ b/src/proc_fuse.c
@@ -398,7 +398,7 @@ static int proc_diskstats_read(char *buf, size_t size, 
off_t offset,
        int ret;
        char dev_name[72];
 
-       if (offset){
+       if (offset) {
                int left;
 
                if (offset > d->size)
@@ -510,7 +510,8 @@ static int proc_diskstats_read(char *buf, size_t size, 
off_t offset,
 
        d->cached = 1;
        d->size = total_len;
-       if (total_len > size ) total_len = size;
+       if (total_len > size)
+               total_len = size;
        memcpy(buf, d->buf, total_len);
 
        return total_len;
@@ -1256,19 +1257,47 @@ __lxcfs_fuse_ops int proc_read(const char *path, char 
*buf, size_t size,
 
        switch (f->type) {
        case LXC_TYPE_PROC_MEMINFO:
-               return proc_meminfo_read(buf, size, offset, fi);
+               if (liblxcfs_functional())
+                       return proc_meminfo_read(buf, size, offset, fi);
+
+               return read_file_fuse_with_offset(LXC_TYPE_PROC_MEMINFO_PATH,
+                                                 buf, size, offset, f);
        case LXC_TYPE_PROC_CPUINFO:
-               return proc_cpuinfo_read(buf, size, offset, fi);
+               if (liblxcfs_functional())
+                       return proc_cpuinfo_read(buf, size, offset, fi);
+
+               return read_file_fuse_with_offset(LXC_TYPE_PROC_CPUINFO_PATH,
+                                                 buf, size, offset, f);
        case LXC_TYPE_PROC_UPTIME:
-               return proc_uptime_read(buf, size, offset, fi);
+               if (liblxcfs_functional())
+                       return proc_uptime_read(buf, size, offset, fi);
+
+               return read_file_fuse_with_offset(LXC_TYPE_PROC_UPTIME_PATH,
+                                                 buf, size, offset, f);
        case LXC_TYPE_PROC_STAT:
-               return proc_stat_read(buf, size, offset, fi);
+               if (liblxcfs_functional())
+                       return proc_stat_read(buf, size, offset, fi);
+
+               return read_file_fuse_with_offset(LXC_TYPE_PROC_STAT_PATH, buf,
+                                                 size, offset, f);
        case LXC_TYPE_PROC_DISKSTATS:
-               return proc_diskstats_read(buf, size, offset, fi);
+               if (liblxcfs_functional())
+                       return proc_diskstats_read(buf, size, offset, fi);
+
+               return read_file_fuse_with_offset(LXC_TYPE_PROC_DISKSTATS_PATH,
+                                                 buf, size, offset, f);
        case LXC_TYPE_PROC_SWAPS:
-               return proc_swaps_read(buf, size, offset, fi);
+               if (liblxcfs_functional())
+                       return proc_swaps_read(buf, size, offset, fi);
+
+               return read_file_fuse_with_offset(LXC_TYPE_PROC_SWAPS_PATH, buf,
+                                                 size, offset, f);
        case LXC_TYPE_PROC_LOADAVG:
-               return proc_loadavg_read(buf, size, offset, fi);
+               if (liblxcfs_functional())
+                       return proc_loadavg_read(buf, size, offset, fi);
+
+               return read_file_fuse_with_offset(LXC_TYPE_PROC_LOADAVG_PATH,
+                                                 buf, size, offset, f);
        }
 
        return -EINVAL;
diff --git a/src/sysfs_fuse.c b/src/sysfs_fuse.c
index 85bc12c..5bdb2ce 100644
--- a/src/sysfs_fuse.c
+++ b/src/sysfs_fuse.c
@@ -295,7 +295,11 @@ __lxcfs_fuse_ops int sys_read(const char *path, char *buf, 
size_t size,
 
        switch (f->type) {
        case LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE:
-               return sys_devices_system_cpu_online_read(buf, size, offset, 
fi);
+               if (liblxcfs_functional())
+                       return sys_devices_system_cpu_online_read(buf, size, 
offset, fi);
+
+               return 
read_file_fuse_with_offset(LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE_PATH,
+                                                 buf, size, offset, f);
        case LXC_TYPE_SYS_DEVICES:
                break;
        case LXC_TYPE_SYS_DEVICES_SYSTEM:
diff --git a/src/utils.c b/src/utils.c
index ccbb50b..5b5e076 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -344,9 +344,34 @@ int read_file_fuse(const char *path, char *buf, size_t 
size, struct file_info *d
 
        if (d->size > total_len)
                d->cached = d->size - total_len;
+
        return total_len;
 }
 
+int read_file_fuse_with_offset(const char *path, char *buf, size_t size,
+                              off_t offset, struct file_info *d)
+{
+       if (offset) {
+               ssize_t total_len = 0;
+               char *cache = d->buf;
+               int left;
+
+               if (offset > d->size)
+                       return -EINVAL;
+
+               if (!d->cached)
+                       return 0;
+
+               left = d->size - offset;
+               total_len = left > size ? size : left;
+               memcpy(buf, cache + offset, total_len);
+
+               return total_len;
+       }
+
+       return read_file_fuse(path, buf, size, d);
+}
+
 #define INITSCOPE "/init.scope"
 void prune_init_slice(char *cg)
 {
diff --git a/src/utils.h b/src/utils.h
index d1effc6..8ac6676 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -45,6 +45,8 @@ extern int send_creds(int sock, struct ucred *cred, char v, 
bool pingfirst);
 extern bool wait_for_sock(int sock, int timeout);
 extern int read_file_fuse(const char *path, char *buf, size_t size,
                          struct file_info *d);
+extern int read_file_fuse_with_offset(const char *path, char *buf, size_t size,
+                                     off_t offset, struct file_info *d);
 extern void prune_init_slice(char *cg);
 extern int wait_for_pid(pid_t pid);
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to