sched_get/setaffinity(): try to be more compatible with Linux
in handling the cpuset sizes different from sizeof(cpuset_t). For both cases, cpuset size shorter than sizeof(cpuset_t) results in EINVAL on Linux. For sched_getaffinity(), be more permissive and accept cpuset size larger than our cpuset_t, by clipping the syscall argument and zeroing the rest of the output buffer. For sched_setaffinity(), we should allow shorter cpusets than current ABI size, again zeroing the rest of the bits. With this change, python os.sched_get/setaffinity functions work. Reported by: se Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
9026652101
commit
d9cacbf4b0
@ -26,11 +26,31 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
sched_getaffinity(pid_t pid, size_t cpusetsz, cpuset_t *cpuset)
|
||||
{
|
||||
/*
|
||||
* Be more Linux-compatible:
|
||||
* - return EINVAL in passed size is less than size of cpuset_t
|
||||
* in advance, instead of ERANGE from the syscall
|
||||
* - if passed size is larger than the size of cpuset_t, be
|
||||
* permissive by claming it back to sizeof(cpuset_t) and
|
||||
* zeroing the rest.
|
||||
*/
|
||||
if (cpusetsz < sizeof(cpuset_t)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
if (cpusetsz > sizeof(cpuset_t)) {
|
||||
memset((char *)cpuset + sizeof(cpuset_t), 0,
|
||||
cpusetsz - sizeof(cpuset_t));
|
||||
cpusetsz = sizeof(cpuset_t);
|
||||
}
|
||||
|
||||
return (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
|
||||
pid == 0 ? -1 : pid, cpusetsz, cpuset));
|
||||
}
|
||||
|
@ -26,11 +26,22 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
sched_setaffinity(pid_t pid, size_t cpusetsz, const cpuset_t *cpuset)
|
||||
{
|
||||
cpuset_t c;
|
||||
|
||||
if (cpusetsz > sizeof(cpuset_t)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
} else {
|
||||
memset(&c, 0, sizeof(c));
|
||||
memcpy(&c, cpuset, cpusetsz);
|
||||
}
|
||||
return (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
|
||||
pid == 0 ? -1 : pid, cpusetsz, cpuset));
|
||||
pid == 0 ? -1 : pid, sizeof(cpuset_t), &c));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user