1
0
mirror of https://github.com/lxc/lxcfs.git synced 2026-02-06 03:46:14 +01:00

cpuview: paththrough personality when reading cpuinfo

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).

https://github.com/lxc/lxcfs/issues/553

Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
This commit is contained in:
Alexander Mikhalitsyn
2022-11-28 14:54:56 +01:00
parent 474491c40b
commit 096972f7a9
3 changed files with 54 additions and 1 deletions

View File

@@ -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;
@@ -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)
@@ -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;

View File

@@ -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)
{

View File

@@ -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>
@@ -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)
{
@@ -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);