私はLinuxのSCHED_FIFO
リアルタイムクラスの下でプログラムを実行したいと思います。 RTPRIO
のユーザーのハードリミットを0に設定し、1つのプロセスだけのハードリミットをプログラムで上げることをお勧めします。私がプロセスにCAP_SYS_RESOURCE
を許可すると、それがハード限界を上げることを可能にすることが広く言及されている。 、man setrlimit 2:setuidまたはケイパビリティCAP_SYS_RESOURCEを使用してulimitハード制限をリアルタイムで優先的に発生させるにはどうすればよいですか?
ソフトリミットは、カーネルが対応するリソースに対して強制する値です。ハードリミットは、ソフトリミットの上限として機能します。特権のないプロセスは、ソフトリミットを0からハードリミットまでの値に設定し、ハードリミットを(不可逆的に)下げます。特権プロセス(LinuxではCAP_SYS_RESOURCE機能を持つプロセス)は、いずれかの制限値に任意の変更を加えることができます。
しかし、私はこれを私のために働かせることはできません。ここではテストコードは次のとおりです。99のハードリミットとの特別な権限なしで期待通り
#include <stdio.h>
#include <sched.h>
#include <errno.h>
#include <string.h>
#include <sys/resource.h>
#define PRIORITY (50)
int main(int argc, char **argv) {
struct sched_param param;
struct rlimit rl;
int e, min_fifo, max_fifo;
min_fifo = sched_get_priority_min(SCHED_FIFO);
max_fifo = sched_get_priority_max(SCHED_FIFO);
printf("For policy SCHED_FIFO min priority is %d, max is %d.\n",
min_fifo, max_fifo);
if ((min_fifo>PRIORITY)||(max_fifo<PRIORITY)) {
printf("Desired priority of %d is out of range.\n", PRIORITY);
return 1;
}
if (getrlimit(RLIMIT_RTPRIO, &rl) != 0) {
e = errno;
printf("Failed to getrlimit(): %s.\n", strerror(e));
return 1;
}
printf("RTPRIO soft limit is %d, hard is %d.\n",
(int) rl.rlim_cur, (int) rl.rlim_max);
// Adjust hard limit if necessary
if (rl.rlim_max < PRIORITY) {
rl.rlim_max = PRIORITY;
if (setrlimit(RLIMIT_RTPRIO, &rl) != 0) {
e = errno;
printf("Failed to raise hard limit for RTPRIO to %d: %s.\n",
(int) rl.rlim_max, strerror(e));
return 1;
}
printf("Raised hard limit for RTPRIO to %d.\n", (int) rl.rlim_max);
}
// Adjust soft limit if necessary
if (rl.rlim_cur < PRIORITY) {
rl.rlim_cur = PRIORITY;
if (setrlimit(RLIMIT_RTPRIO, &rl) != 0) {
e = errno;
printf("Failed to raise soft limit for RTPRIO to %d: %s.\n",
(int) rl.rlim_cur, strerror(e));
return 1;
}
printf("Raised soft limit for RTPRIO to %d.\n", (int) rl.rlim_cur);
}
// Set desired priority with class SCHED_FIFO
param.sched_priority = PRIORITY;
if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
e = errno;
printf("Setting policy failed: %s.\n", strerror(e));
return 1;
} else {
printf("Set policy SCHED_FIFO, priority %d.\n", param.sched_priority);
}
return 0;
}
これは動作します:
$ ./rtprio
For policy SCHED_FIFO min priority is 1, max is 99.
RTPRIO soft limit is 0, hard is 99.
Raised soft limit for RTPRIO to 50.
Set policy SCHED_FIFO, priority 50.
$
0のハードリミットと予想通りそれはsudoを使用して動作します:
$ sudo ./rtprio
For policy SCHED_FIFO min priority is 1, max is 99.
RTPRIO soft limit is 0, hard is 0.
Raised hard limit for RTPRIO to 50.
Raised soft limit for RTPRIO to 50.
Set policy SCHED_FIFO, priority 50.
$
しかし、setuidルートの場合は期待どおりに動作しません。
$ sudo chown root ./rtprio
$ sudo chgrp root ./rtprio
$ sudo chmod ug+s ./rtprio
$ ls -l ./rtprio
-rwsrwsr-x 1 root root 8948 11月 28 12:04 ./rtprio
$ ./rtprio
For policy SCHED_FIFO min priority is 1, max is 99.
RTPRIO soft limit is 0, hard is 0.
Failed to raise hard limit for RTPRIO to 50: Operation not permitted.
はまた、予想外にすべて機能を持つだけでなく、能力CAP_SYS_RESOURCEで失敗します。私はここで何をしないのです
$ sudo setcap cap_sys_resource=eip ./rtprio
$ getcap ./rtprio
./rtprio = cap_sys_resource+eip
$ ./rtprio
For policy SCHED_FIFO min priority is 1, max is 99.
RTPRIO soft limit is 0, hard is 0.
Failed to raise hard limit for RTPRIO to 50: Operation not permitted.
$ sudo setcap all=eip ./rtprio
$ getcap ./rtprio
./rtprio =eip
$ ./rtprio
For policy SCHED_FIFO min priority is 1, max is 99.
RTPRIO soft limit is 0, hard is 0.
Failed to raise hard limit for RTPRIO to 50: Operation not permitted.
?
$ uname -srv
Linux 3.13.0-100-generiC#147-Ubuntu SMP Tue Oct 18 16:48:51 UTC 2016
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
$ bash --version | head -1
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)