diff -uprN a/bindings.c b/bindings.c --- a/bindings.c 2019-01-07 15:52:33.206519758 +0800 +++ b/bindings.c 2019-01-07 16:11:20.021464817 +0800 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -3369,6 +3370,37 @@ static bool cpuline_in_cpuset(const char return cpu_in_cpuset(cpu, cpuset); } +static long get_cpulimit(const char *cgroup, const char *file) +{ + char *cpulimit_str = NULL; + long cpulimit = -1; + + if (cgfs_get_value("cpu", cgroup, file, &cpulimit_str)) + cpulimit = strtol(cpulimit_str, NULL, 10); + + free(cpulimit_str); + + return cpulimit; +} + +static long get_cpu_count(const char *cgroup) +{ + char *copy = strdupa(cgroup); + long double count = -1; + int period, quota; + + period = get_cpulimit(copy, "cpu.cfs_period_us"); + quota = get_cpulimit(copy, "cpu.cfs_quota_us"); + + if (quota != -1) + count = quota / period; + + if (quota > 0) { + return ceil(count); + } + + return -1; +} /* * check whether this is a '^processor" line in /proc/cpuinfo */ @@ -3387,11 +3419,13 @@ static int proc_cpuinfo_read(char *buf, struct fuse_context *fc = fuse_get_context(); struct file_info *d = (struct file_info *)fi->fh; char *cg = NULL; + char *ccg = NULL; char *cpuset = NULL; char *line = NULL; size_t linelen = 0, total_len = 0, rv = 0; bool am_printing = false, firstline = true, is_s390x = false; int curcpu = -1, cpu; + long total_cpus = -1; char *cache = d->buf; size_t cache_size = d->buflen; FILE *f = NULL; @@ -3419,6 +3453,12 @@ static int proc_cpuinfo_read(char *buf, if (!cpuset) goto err; + ccg = get_pid_cgroup(initpid, "cpu"); + if (ccg) { + prune_init_slice(ccg); + total_cpus = get_cpu_count(ccg); + } + f = fopen("/proc/cpuinfo", "r"); if (!f) goto err; @@ -3436,6 +3476,9 @@ static int proc_cpuinfo_read(char *buf, if (strncmp(line, "# processors:", 12) == 0) continue; if (is_processor_line(line)) { + if (total_cpus > 0 && curcpu >= (total_cpus-1)) { + break; + } am_printing = cpuline_in_cpuset(line, cpuset); if (am_printing) { curcpu ++; @@ -3457,6 +3500,10 @@ static int proc_cpuinfo_read(char *buf, continue; } else if (is_s390x && sscanf(line, "processor %d:", &cpu) == 1) { char *p = NULL; + + if (total_cpus > 0 && curcpu >= (total_cpus-1)) { + break; + } if (!cpu_in_cpuset(cpu, cpuset)) continue; curcpu ++; @@ -3509,7 +3556,7 @@ static int proc_cpuinfo_read(char *buf, } } - if (is_s390x) { + if ((is_s390x) && ((total_cpus < 0) || (total_cpus > 0 && curcpu < (total_cpus-1)))) { char *origcache = d->buf; ssize_t l; do { diff -uprN a/Makefile.am b/Makefile.am --- a/Makefile.am 2019-01-07 15:52:33.211519758 +0800 +++ b/Makefile.am 2019-01-07 16:09:21.713470585 +0800 @@ -13,7 +13,7 @@ AM_CFLAGS += -DRUNTIME_PATH=\"$(RUNTIME_ liblxcfs_la_SOURCES = macro.h bindings.c cpuset.c bindings.h liblxcfs_la_CFLAGS = $(AM_CFLAGS) -liblxcfs_la_LDFLAGS = $(AM_CFLAGS) -module -avoid-version -shared +liblxcfs_la_LDFLAGS = $(AM_CFLAGS) -module -avoid-version -shared -lm liblxcfstest_la_SOURCES = bindings.c cpuset.c bindings.h macro.h liblxcfstest_la_CFLAGS = $(AM_CFLAGS) -DRELOADTEST diff -uprN a/Makefile.in b/Makefile.in --- a/Makefile.in 2019-01-07 15:52:33.204519758 +0800 +++ b/Makefile.in 2019-01-07 16:09:21.714470585 +0800 @@ -427,7 +427,7 @@ AM_CFLAGS = -Wall -ggdb -D_GNU_SOURCE -D AM_LDFLAGS = $(FUSE_LIBS) -pthread liblxcfs_la_SOURCES = macro.h bindings.c cpuset.c bindings.h liblxcfs_la_CFLAGS = $(AM_CFLAGS) -liblxcfs_la_LDFLAGS = $(AM_CFLAGS) -module -avoid-version -shared +liblxcfs_la_LDFLAGS = $(AM_CFLAGS) -module -avoid-version -shared -lm liblxcfstest_la_SOURCES = bindings.c cpuset.c bindings.h macro.h liblxcfstest_la_CFLAGS = $(AM_CFLAGS) -DRELOADTEST liblxcfstest_la_LDFLAGS = $(AM_CFLAGS) -module -avoid-version -shared