In Virtuozzo containers we have access to sysfs prohibited for most of the files for security reasons. Running the code below in container I get false negative errno: /# ls /sys/devices/system/cpu/online ls: cannot access /sys/devices/system/cpu/online: No such file or directory /# rpm -qa glibc glibc-2.17-157.el7_3.2.x86_64 /# cat sysconf_nrproc_onln.c #include <stdio.h> #include <unistd.h> #include <errno.h> int main() { long nrproconln; printf("Before: errno=%d\n", errno); nrproconln = sysconf(_SC_NPROCESSORS_ONLN); printf("After: nrproc_onln=%ld errno=%d\n", nrproconln, errno); return 0; } /# gcc -o sysconf_nrproc_onln sysconf_nrproc_onln.c /# ./sysconf_nrproc_onln Before: errno=0 After: nrproc_onln=4 errno=2 In sysconf man we have: RETURN VALUE If name is invalid, -1 is returned, and errno is set to EINVAL. Otherwise, the value returned is the value of the system resource and errno is not changed. But in my case errno is 2 but should stay zero accoring to man. I can see with gdb: Breakpoint 3, __get_nprocs () at ../sysdeps/unix/sysv/linux/getsysstats.c:151 151 int fd = open_not_cancel_2 ("/sys/devices/system/cpu/online", flags); (gdb) p errno $10 = 0 (gdb) c Continuing. Breakpoint 4, __get_nprocs () at ../sysdeps/unix/sysv/linux/getsysstats.c:154 154 if (fd != -1) (gdb) p errno $11 = 2 (gdb) c Continuing. Breakpoint 6, __get_nprocs () at ../sysdeps/unix/sysv/linux/getsysstats.c:199 199 fd = open_not_cancel_2 ("/proc/stat", flags); (gdb) p errno $12 = 2 (gdb) c Continuing. Breakpoint 7, __get_nprocs () at ../sysdeps/unix/sysv/linux/getsysstats.c:200 200 if (fd != -1) (gdb) p errno $13 = 2 Function __get_nprocs tries to read nrprocesses from sysfs, fails and sets errno==2, fall-backs to read nrprocesses from proc, succeeds but never resets errno back. Our real problem is that docker(which we run in container) uses C.sysconf(C._SC_NPROCESSORS_ONLN) and checks error using errno!=0 as according to man it should not change from 0 by sysconf.
sysconf did not return -1, so the value of errno is undefined.
In sysconf man it is said completely the contrary, as I've already wrote in my previous message: "Otherwise, the value returned is the value of the system resource and errno is NOT CHANGED."
Please report that to the manpage project.
(In reply to Pavel Tikhomirov from comment #0) > Our real problem is that docker(which we run in container) uses > C.sysconf(C._SC_NPROCESSORS_ONLN) and checks error using errno!=0 as > according to man it should not change from 0 by sysconf. To elaborate, here is what POSIX says[1]: "If name is an invalid value, sysconf() shall return -1 and set errno to indicate the error. If the variable corresponding to name is described in <limits.h> as a maximum or minimum value and the variable has no limit, sysconf() shall return -1 without changing the value of errno." This means that the value of errno is defined only when sysconf() returns -1. This is reiterated further in the APPLICATION USAGE section where applications are advised as follows: "As -1 is a permissible return value in a successful situation, an application wishing to check for error situations should set errno to 0, then call sysconf(), and, if it returns -1, check to see if errno is non-zero." [1] http://pubs.opengroup.org/onlinepubs/9699919799//functions/sysconf.html