Skip to content

Commit

Permalink
cpuview: paththrough personality when reading cpuinfo
Browse files Browse the repository at this point in the history
Let's change processing thread personality if caller personality
is different. It allows to read /proc/cpuinfo properly in
some cases (arm64 rely on current->personality inside Linux kernel).

#553

Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
  • Loading branch information
mihalicyn committed Nov 30, 2022
1 parent 474491c commit 096972f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static bool can_use_swap;
static bool can_use_sys_cpu;
static bool has_versioned_opts;
static bool memory_is_cgroupv2;
static __u32 host_personality;

static volatile sig_atomic_t reload_successful;

Expand Down Expand Up @@ -73,6 +74,11 @@ bool liblxcfs_memory_is_cgroupv2(void)
return memory_is_cgroupv2;
}

__u32 liblxcfs_personality(void)
{
return host_personality;
}

/* Define pivot_root() if missing from the C library */
#ifndef HAVE_PIVOT_ROOT
static int pivot_root(const char *new_root, const char *put_old)
Expand Down Expand Up @@ -919,6 +925,11 @@ static void __attribute__((constructor)) lxcfs_init(void)
goto broken_upgrade;
}

if (get_task_personality(getpid(), &host_personality) < 0) {
lxcfs_info("Failed to retrieve host personality");
goto broken_upgrade;
}

reload_successful = 1;
return;

Expand Down
1 change: 1 addition & 0 deletions src/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ extern bool liblxcfs_can_use_swap(void);
extern bool liblxcfs_memory_is_cgroupv2(void);
extern bool liblxcfs_can_use_sys_cpu(void);
extern bool liblxcfs_has_versioned_opts(void);
extern __u32 liblxcfs_personality(void);

static inline bool lxcfs_has_opt(struct lxcfs_opts *opts, lxcfs_opt_t opt)
{
Expand Down
43 changes: 42 additions & 1 deletion src/proc_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/personality.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
Expand Down Expand Up @@ -1500,6 +1501,46 @@ static int proc_slabinfo_read(char *buf, size_t size, off_t offset,
return total_len;
}

static int proc_read_with_personality(int (*do_proc_read)(char *, size_t, off_t,
struct fuse_file_info *), char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
struct fuse_context *fc = fuse_get_context();
__u32 host_personality = liblxcfs_personality(), caller_personality;
bool change_personality;
int ret, read_ret;

if (get_task_personality(fc->pid, &caller_personality) < 0)
return log_error(0, "Failed to get caller process (pid: %d) personality", fc->pid);

/* do we need to change thread personality? */
change_personality = host_personality != caller_personality;

if (change_personality) {
ret = personality(caller_personality);
if (ret == -1)
return log_error(0, "Call to personality(%d) failed: %s\n",
caller_personality, strerror(errno));

lxcfs_debug("task (tid: %d) personality was changed %d -> %d\n",
(int)syscall(SYS_gettid), ret, caller_personality);
}

read_ret = do_proc_read(buf, size, offset, fi);

if (change_personality) {
ret = personality(host_personality);
if (ret == -1)
return log_error(0, "Call to personality(%d) failed: %s\n",
host_personality, strerror(errno));

lxcfs_debug("task (tid: %d) personality was restored %d -> %d\n",
(int)syscall(SYS_gettid), ret, host_personality);
}

return read_ret;
}

__lxcfs_fuse_ops int proc_read(const char *path, char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
Expand All @@ -1514,7 +1555,7 @@ __lxcfs_fuse_ops int proc_read(const char *path, char *buf, size_t size,
buf, size, offset, f);
case LXC_TYPE_PROC_CPUINFO:
if (liblxcfs_functional())
return proc_cpuinfo_read(buf, size, offset, fi);
return proc_read_with_personality(&proc_cpuinfo_read, buf, size, offset, fi);

return read_file_fuse_with_offset(LXC_TYPE_PROC_CPUINFO_PATH,
buf, size, offset, f);
Expand Down

0 comments on commit 096972f

Please sign in to comment.