chrt: add fallback to be usable on kernels without sched_{get,set}attr
We have fallback for compilation with/without proper glibc and kernel headers, but it's not enough, because people can switch between kernels with and without the syscalls. (For example RT kernels for RHEL/CentOS). Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1353340 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
2cad2b32ff
commit
6f27e449a9
|
@ -58,11 +58,19 @@
|
|||
# define SCHED_FLAG_RESET_ON_FORK 0x01
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (__linux__) && !defined(HAVE_SCHED_SETATTR)
|
||||
# include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
/* usable kernel-headers, but old glibc-headers */
|
||||
#if defined (__linux__) && !defined(SYS_sched_setattr) && defined(__NR_sched_setattr)
|
||||
# define SYS_sched_setattr __NR_sched_setattr
|
||||
#endif
|
||||
|
||||
#if defined (__linux__) && !defined(SYS_sched_getattr) && defined(__NR_sched_getattr)
|
||||
# define SYS_sched_getattr __NR_sched_getattr
|
||||
#endif
|
||||
|
||||
#if defined (__linux__) && !defined(HAVE_SCHED_SETATTR) && defined(SYS_sched_setattr)
|
||||
# define HAVE_SCHED_SETATTR
|
||||
|
||||
|
@ -207,12 +215,20 @@ static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
|
|||
if (!pid)
|
||||
pid = getpid();
|
||||
|
||||
errno = 0;
|
||||
|
||||
/*
|
||||
* New way
|
||||
*/
|
||||
#ifdef HAVE_SCHED_SETATTR
|
||||
{
|
||||
struct sched_attr sa;
|
||||
|
||||
if (sched_getattr(pid, &sa, sizeof(sa), 0) != 0)
|
||||
if (sched_getattr(pid, &sa, sizeof(sa), 0) != 0) {
|
||||
if (errno == ENOSYS)
|
||||
goto fallback;
|
||||
err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
|
||||
}
|
||||
|
||||
policy = sa.sched_policy;
|
||||
prio = sa.sched_priority;
|
||||
|
@ -221,8 +237,13 @@ static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
|
|||
runtime = sa.sched_runtime;
|
||||
period = sa.sched_period;
|
||||
}
|
||||
#else /* !HAVE_SCHED_SETATTR */
|
||||
{
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Old way
|
||||
*/
|
||||
fallback:
|
||||
if (errno == ENOSYS) {
|
||||
struct sched_param sp;
|
||||
|
||||
policy = sched_getscheduler(pid);
|
||||
|
@ -238,7 +259,6 @@ static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
|
|||
reset_on_fork = 1;
|
||||
# endif
|
||||
}
|
||||
#endif /* !HAVE_SCHED_SETATTR */
|
||||
|
||||
if (ctl->altered)
|
||||
printf(_("pid %d's new scheduling policy: %s"), pid, get_policy_name(policy));
|
||||
|
@ -315,8 +335,7 @@ static void show_min_max(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef HAVE_SCHED_SETATTR
|
||||
static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
|
||||
static int set_sched_one_by_setscheduler(struct chrt_ctl *ctl, pid_t pid)
|
||||
{
|
||||
struct sched_param sp = { .sched_priority = ctl->priority };
|
||||
int policy = ctl->policy;
|
||||
|
@ -328,6 +347,13 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
|
|||
return sched_setscheduler(pid, policy, &sp);
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_SCHED_SETATTR
|
||||
static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
|
||||
{
|
||||
return set_sched_one_by_setscheduler(ctl, pid);
|
||||
}
|
||||
|
||||
#else /* !HAVE_SCHED_SETATTR */
|
||||
static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
|
||||
{
|
||||
|
@ -340,11 +366,20 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
|
|||
.sched_period = ctl->period,
|
||||
.sched_deadline = ctl->deadline
|
||||
};
|
||||
int rc;
|
||||
|
||||
# ifdef SCHED_RESET_ON_FORK
|
||||
if (ctl->reset_on_fork)
|
||||
sa.sched_flags |= SCHED_RESET_ON_FORK;
|
||||
# endif
|
||||
return sched_setattr(pid, &sa, 0);
|
||||
errno = 0;
|
||||
rc = sched_setattr(pid, &sa, 0);
|
||||
|
||||
if (rc != 0 && errno == ENOSYS && ctl->policy != SCHED_DEADLINE)
|
||||
/* fallback -- build with new kernel/libc, but executed on old kernels */
|
||||
rc = set_sched_one_by_setscheduler(ctl, pid);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* HAVE_SCHED_SETATTR */
|
||||
|
||||
|
|
Loading…
Reference in New Issue