Skip to content

Commit

Permalink
liblxcfs: handle broken upgrade gracefully
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
  • Loading branch information
Christian Brauner committed Mar 13, 2020
1 parent 2c7dd60 commit 920f887
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 11 deletions.
10 changes: 9 additions & 1 deletion src/bindings.c
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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__);
}

Expand Down
18 changes: 18 additions & 0 deletions src/bindings.h
Expand Up @@ -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 {
Expand All @@ -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 */
32 changes: 32 additions & 0 deletions src/cgroup_fuse.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
47 changes: 38 additions & 9 deletions src/proc_fuse.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion src/sysfs_fuse.c
Expand Up @@ -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:
Expand Down
25 changes: 25 additions & 0 deletions src/utils.c
Expand Up @@ -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)
{
Expand Down
2 changes: 2 additions & 0 deletions src/utils.h
Expand Up @@ -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);

Expand Down

0 comments on commit 920f887

Please sign in to comment.