Re: [Regression] 2.6.24-git9: RT sched mishandles artswrapper (bisected)

Rafael J. Wysocki
2008-02-06T01:24:00Z

On Tuesday, 5 of February 2008, Dmitry Adamushko wrote:
> Rafael, any progress with this issue? (a few questions below).
>
> > >
> > > Does this artsmessage thing also run with RT priority?
> >
> > Well, it's in a strange state (after it's broken). From top:
> >
> > PR = -51
> > NI = 0
> > S = R
> > %CPU = 0.0
> > %MEM = 0.0
>
> cat /proc/$PID/stat ; sleep 3; cat /proc/$PID/stat ?
> cat /proc/sched_debug; sleep 3 ; cat /proc/sched_debug

Well, instead please find appended a test program that allows me to trigger
the issue.

To reproduce it do:

$ gcc -o break_scheduler break_scheduler.c
$ su -
[...]
# chown root.root $PATH_TO_BINARY/break_scheduler
# chmod u+s $PATH_TO_BINARY/break_scheduler
^D
$ ./break_scheduler

It behaves normally if run directly by root and it also behaves normally if
the execv() at the end is removed.

Hope that helps to understand what the problem is.

Thanks,
Rafael

---
#include <stdio.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <sched.h>

#define EXECUTE "/bin/ls"

void adjust_priority()
{
int sched = sched_getscheduler(0);

if(sched == SCHED_FIFO || sched == SCHED_RR) {
puts(">> non-standard scheduling policy");
} else {
struct sched_param sp;
long int priority = (sched_get_priority_max(SCHED_FIFO) +
sched_get_priority_min(SCHED_FIFO))/2;

sp.sched_priority = priority;

if (sched_setscheduler(0, SCHED_FIFO, &sp) != -1) {
printf(">> running as realtime process now "
"(priority %ld)\n", priority);
} else {
/* can't set realtime priority */
puts(">> could not set realtime priority");
}
}
}

int main(int argc, char **argv)
{
adjust_priority();

/* drop root privileges if running setuid root
(due to realtime priority stuff) */
if (geteuid() != getuid()) {
seteuid(getuid());
if (geteuid() != getuid()) {
perror("setuid()");
return 2;
}
}

puts("OK");

if(argc == 0)
return 1;

argv[0] = EXECUTE;
execv(EXECUTE, argv);
perror(EXECUTE);

return 0;
}