Skip to content

Commit

Permalink
Merge pull request #557 from tych0/dont-mask-system-cpu
Browse files Browse the repository at this point in the history
sysfs: don't mask cpus in /sys/devices/system/cpu
  • Loading branch information
stgraber authored Jan 6, 2023
2 parents 935773f + 0a0948b commit 63c9b1d
Show file tree
Hide file tree
Showing 5 changed files with 3 additions and 256 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ such as:
/proc/swaps
/proc/uptime
/proc/slabinfo
/sys/devices/system/cpu
/sys/devices/system/cpu/online
```

Expand Down
207 changes: 3 additions & 204 deletions src/sysfs_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,160 +38,6 @@
#include "utils.h"

static off_t get_sysfile_size(const char *which);
/* Create cpumask from cpulist aka turn:
*
* 0,2-3
*
* into bit array
*
* 1 0 1 1
*/
static int lxc_cpumask(char *buf, __u32 **bitarr, __u32 *last_set_bit)
{
__do_free __u32 *arr_u32 = NULL;
__u32 cur_last_set_bit = 0, nbits = 256;
__u32 nr_u32;
char *token;

nr_u32 = BITS_TO_LONGS(nbits);
arr_u32 = zalloc(nr_u32 * sizeof(__u32));
if (!arr_u32)
return ret_errno(ENOMEM);

lxc_iterate_parts(token, buf, ",") {
__u32 last_bit, first_bit;
char *range;

errno = 0;
first_bit = strtoul(token, NULL, 0);
last_bit = first_bit;
range = strchr(token, '-');
if (range)
last_bit = strtoul(range + 1, NULL, 0);

if (!(first_bit <= last_bit))
return ret_errno(EINVAL);

if (last_bit >= nbits) {
__u32 add_bits = last_bit - nbits + 32;
__u32 new_nr_u32;
__u32 *p;

new_nr_u32 = BITS_TO_LONGS(nbits + add_bits);
p = realloc(arr_u32, new_nr_u32 * sizeof(uint32_t));
if (!p)
return ret_errno(ENOMEM);
arr_u32 = move_ptr(p);

memset(arr_u32 + nr_u32, 0,
(new_nr_u32 - nr_u32) * sizeof(uint32_t));
nbits += add_bits;
}

while (first_bit <= last_bit)
set_bit(first_bit++, arr_u32);

if (last_bit > cur_last_set_bit)
cur_last_set_bit = last_bit;
}

*last_set_bit = cur_last_set_bit;
*bitarr = move_ptr(arr_u32);
return 0;
}

static int lxc_cpumask_update(char *buf, __u32 *bitarr, __u32 last_set_bit,
bool clear)
{
bool flipped = false;
char *token;

lxc_iterate_parts(token, buf, ",") {
__u32 last_bit, first_bit;
char *range;

errno = 0;
first_bit = strtoul(token, NULL, 0);
last_bit = first_bit;
range = strchr(token, '-');
if (range)
last_bit = strtoul(range + 1, NULL, 0);

if (!(first_bit <= last_bit)) {
lxcfs_debug("The cup range seems to be inverted: %u-%u", first_bit, last_bit);
continue;
}

if (last_bit > last_set_bit)
continue;

while (first_bit <= last_bit) {
if (clear && is_set(first_bit, bitarr)) {
flipped = true;
clear_bit(first_bit, bitarr);
} else if (!clear && !is_set(first_bit, bitarr)) {
flipped = true;
set_bit(first_bit, bitarr);
}

first_bit++;
}
}

if (flipped)
return 1;

return 0;
}

#define __ISOL_CPUS "/sys/devices/system/cpu/isolated"
#define __OFFLINE_CPUS "/sys/devices/system/cpu/offline"
static int cpumask(char *posscpus, __u32 **bitarr, __u32 *last_set_bit)
{
__do_free char *isolcpus = NULL, *offlinecpus = NULL;
__do_free __u32 *possmask = NULL;
int ret;
__u32 poss_last_set_bit = 0;

if (file_exists(__ISOL_CPUS)) {
isolcpus = read_file_at(-EBADF, __ISOL_CPUS, PROTECT_OPEN);
if (!isolcpus)
return -1;

if (!isdigit(isolcpus[0]))
free_disarm(isolcpus);
} else {
lxcfs_debug("The path \""__ISOL_CPUS"\" to read isolated cpus from does not exist");
}

if (file_exists(__OFFLINE_CPUS)) {
offlinecpus = read_file_at(-EBADF, __OFFLINE_CPUS, PROTECT_OPEN);
if (!offlinecpus)
return -1;

if (!isdigit(offlinecpus[0]))
free_disarm(offlinecpus);
} else {
lxcfs_debug("The path \""__OFFLINE_CPUS"\" to read offline cpus from does not exist");
}

ret = lxc_cpumask(posscpus, &possmask, &poss_last_set_bit);
if (ret)
return ret;

if (isolcpus)
ret = lxc_cpumask_update(isolcpus, possmask, poss_last_set_bit, true);

if (offlinecpus)
ret |= lxc_cpumask_update(offlinecpus, possmask, poss_last_set_bit, true);
if (ret)
return ret;

*bitarr = move_ptr(possmask);
*last_set_bit = poss_last_set_bit;
return 0;
}

static int do_cpuset_read(char *cg, char *buf, size_t buflen)
{
__do_free char *cpuset = NULL;
Expand Down Expand Up @@ -299,61 +145,14 @@ static int sys_devices_system_cpu_online_getsize(const char *path)
static int filler_sys_devices_system_cpu(const char *path, void *buf,
fuse_fill_dir_t filler)
{
__do_free __u32 *bitarr = NULL;
__do_free char *cg = NULL, *cpuset = NULL;
__do_closedir DIR *dirp = NULL;
struct fuse_context *fc = fuse_get_context();
__u32 last_set_bit = 0;
int ret;
struct dirent *dirent;
pid_t initpid;

initpid = lookup_initpid_in_store(fc->pid);
if (initpid <= 1 || is_shared_pidns(initpid))
initpid = fc->pid;

cg = get_pid_cgroup(initpid, "cpuset");
if (!cg)
return 0;
prune_init_slice(cg);

cpuset = get_cpuset(cg);
if (!cpuset)
return 0;

ret = cpumask(cpuset, &bitarr, &last_set_bit);
if (ret)
return ret;

dirp = opendir(path);
if (!dirp)
return -ENOENT;

for (__u32 bit = 0; bit <= last_set_bit; bit++) {
char cpu[100];

if (!is_set(bit, bitarr))
continue;

ret = snprintf(cpu, sizeof(cpu), "cpu%u", bit);
if (ret < 0 || (size_t)ret >= sizeof(cpu))
continue;

if (dir_fillerat(filler, dirp, cpu, buf, 0) != 0)
return -ENOENT;
}

while ((dirent = readdir(dirp))) {
char *entry = dirent->d_name;

if (strlen(entry) > 3) {
entry += 3;

/* Don't emit entries we already filtered above. */
if (isdigit(*entry))
continue;
}

if (dirent_fillerat(filler, dirp, dirent, buf, 0) != 0)
return -ENOENT;
}
Expand Down Expand Up @@ -590,10 +389,10 @@ __lxcfs_fuse_ops int sys_readdir(const char *path, void *buf,
return -ENOENT;
return 0;
case LXC_TYPE_SYS_DEVICES_SYSTEM_CPU:
if (dir_filler(filler, buf, ".", 0) != 0 ||
dir_filler(filler, buf, "..", 0) != 0)
if (dir_filler(filler, buf, ".", 0) != 0 ||
dir_filler(filler, buf, "..", 0) != 0 ||
dirent_filler(filler, path, "online", buf, 0) != 0)
return -ENOENT;

return filler_sys_devices_system_cpu(path, buf, filler);
case LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_SUBDIR:
dirp = opendir_flags(path, O_CLOEXEC | O_NOFOLLOW);
Expand Down
2 changes: 0 additions & 2 deletions tests/main.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ TESTCASE="Stress readdir"
RUNTEST ${dirname}/test_readdir
TESTCASE="test_proc"
RUNTEST ${dirname}/test_proc
TESTCASE="test_sysfs"
RUNTEST ${dirname}/test_sysfs
TESTCASE="test_cgroup"
RUNTEST ${dirname}/test_cgroup
TESTCASE="test_read_proc.sh"
Expand Down
12 changes: 0 additions & 12 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,6 @@ test_programs += custom_target(
'@OUTPUT@',
])

test_programs += custom_target(
'test_sysfs',
build_by_default: want_tests != false,
input: 'test_sysfs.in',
output: 'test_sysfs',
command: [
meson_render_jinja2,
config_h,
'@INPUT@',
'@OUTPUT@',
])

test_programs += custom_target(
'test_read_proc.sh',
build_by_default: want_tests != false,
Expand Down
37 changes: 0 additions & 37 deletions tests/test_sysfs.in

This file was deleted.

0 comments on commit 63c9b1d

Please sign in to comment.