Question

What's the best way to grant a process/thread the right to lower its own nice value, without running it with full privileges? Solution can be external to the process itself (ulimit or setcap for example).

I'm looking for something portable at least across modern Linux and Mac OS X (and this is why I didn't reply myself with ulimit or setcap).

Was it helpful?

Solution

You'll need extra privileges to decrease the nice value (increase the logical priority). In Linux, this means either being run by root or having the CAP_SYS_NICE capability. Both can be set for the binary executable (either setuid root via chown and chmod, or setcap). The former will work on all Unix-like systems (but will require root privileges when installed), but the latter is Linux-specific.

The most acceptable portable way is probably to write a wrapper program, that can be installed setuid root. It will be very simple, just a couple of dozen lines of C. It simply calls sched_get_priority_min(), sched_get_priority_max(), sched_setscheduler(), and sched_setparam() to lower the nice value (getting it more CPU time), then calls seteuid(0); setregid(getgid(), getgid); setreuid(getuid(), getuid()); to drop the extra privileges, and finally execv() the actual program. Note: you most definitely want to hardcode the path to the actual program at install time. This should work without modifications on all Linux and Unix-like systems.

In your actual program, you simply increase the niceness of the threads that are not so important. In other words, you do not try to lower the niceness of any threads in your program, but increase the niceness of all other threads. The setuid root wrapper program is the portable way to reduce the minimum niceness level. You can obviously check the current niceness and scheduler details first to see if there is enough range to adjust. Perhaps your wrapper program can set command-line parameters or environment variables that tell the actual program which priority levels to use.

OTHER TIPS

Any process can make itself nicer using setpriority() or sched_setscheduler(), and any thread using pthread_setchedparam() and pthread_setschedprio(). Both are defined in POSIX.1-2001, so should be available in basically all non-Windows systems. For details on the scheduler types and priorities available, see man 2 sched_setscheduler.

Note that higher numerical priority values indicate nicer process; lower logical priority. The larger the value, the less CPU time it gets. To find out the minimum and maximum values for a given scheduling policy, you must use sched_get_priority_min() and sched_get_priority_max().

Normally a process or thread should always be able to lower its priority (making it nicer), and use any scheduling policy that does not make it less nice. However, Linux kernels prior to 2.6.12 did not allow that for normal users, so your program should probably just try to make it or some of its threads nicer, but not mind too much if it happens to not be allowed on some rarer architectures. Most importantly, your algorithmic design should not rely on scheduling; strive for more robust code than that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top