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