Hallo,
hat jemand ein wenig Erfahrung, mit den ressource-limits, wo sie vereinbart werden, wann sie zutreffen etc?
Konkret: 1.) Gelten die per user und werden beim login festgelegt? 2.) Gelten die per process | thread? 3.) Werden die in /etc/security/limits vereinbart? 4.) Wie kommt ein "normaler" user da ran? (sched_setscheduler() gibt -ENOPERM zurück ...)
Jeder Hinweis ist willkommen ...
TIA!
Bernhard
Hi Bernhard,
On Mon, Oct 05, 2009 at 21:00:41 +0200, Bernhard Schiffner wrote:
Ohne Anspruch auf Vollstaendigkeit:
1.) Gelten die per user und werden beim login festgelegt?
Sie gelten mindestens per Prozess. Wenn die Limits beim Login festgelegt werden, dann meistens durch PAM. Siehe 3.)
2.) Gelten die per process | thread?
Per Prozess auf jeden Fall, siehe auch /proc/<PID>/limits. Bei Threads bin ich mir nicht sicher.
3.) Werden die in /etc/security/limits vereinbart?
/etc/security/limits.conf ist die Konfigurationsdatei von pam_limits.so. Wird dieses PAM-Modul waehrend einer Authentifizierung benutzt, setzt es Limits entsprechend der Konfigdatei.
4.) Wie kommt ein "normaler" user da ran?
getrlimit() und setrlimit() hast Du schon im Subject stehen. Was sind die Fragen dazu?
(sched_setscheduler() gibt -ENOPERM zurueck ...)
Disclaimer: Im Bereich Realtime kenne ich mich genau gar nicht aus. Laut Manpage kann man als non-root die sched_priority nur erhoehen, wenn RLIMIT_RTPRIO (Eintrag "Max realtime priority" in /proc/<PID>/limits) groesser Null ist und als Scheduler SCHED_RR bzw. SCHED_FIFO benutzt wird. Laeuft der Prozess mit der Capability CAP_SYS_NICE, kann die sched_priority ohne Beachtung der Limits erhoeht werden.
Gruss, Chris
On Tuesday 06 October 2009 10:26:00 Christian Perle wrote:
Hi Bernhard,
On Mon, Oct 05, 2009 at 21:00:41 +0200, Bernhard Schiffner wrote:
Ohne Anspruch auf Vollstaendigkeit:
1.) Gelten die per user und werden beim login festgelegt?
Sie gelten mindestens per Prozess. Wenn die Limits beim Login festgelegt werden, dann meistens durch PAM. Siehe 3.)
2.) Gelten die per process | thread?
Per Prozess auf jeden Fall, siehe auch /proc/<PID>/limits. Bei Threads bin ich mir nicht sicher.
3.) Werden die in /etc/security/limits vereinbart?
/etc/security/limits.conf ist die Konfigurationsdatei von pam_limits.so. Wird dieses PAM-Modul waehrend einer Authentifizierung benutzt, setzt es Limits entsprechend der Konfigdatei.
4.) Wie kommt ein "normaler" user da ran?
getrlimit() und setrlimit() hast Du schon im Subject stehen. Was sind die Fragen dazu?
(sched_setscheduler() gibt -ENOPERM zurueck ...)
Disclaimer: Im Bereich Realtime kenne ich mich genau gar nicht aus. Laut Manpage kann man als non-root die sched_priority nur erhoehen, wenn RLIMIT_RTPRIO (Eintrag "Max realtime priority" in /proc/<PID>/limits) groesser Null ist und als Scheduler SCHED_RR bzw. SCHED_FIFO benutzt wird. Laeuft der Prozess mit der Capability CAP_SYS_NICE, kann die sched_priority ohne Beachtung der Limits erhoeht werden.
Gruss, Chris
Danke für die Info, speziell den Hinweis auf /proc/<PID>.
Ein wenig Code hierzu liegt bei. (WIP) Ich bekomme als non-root bei getrlimit( RLIMIT_RTPRIO, ...) immer 0 zurück und will wissen, wie ich das für bestimmte Nutzer | Gruppen | Programme ändern kann. Ein erster Eintrag in /etc/security/limits half nicht weiter.
Ach so, das zeigt die Threads ps -C <name des exe> -mo pid,ppid,tid,pri,cmd (Die Angabe der Priorität ist bei mir unzuverlässig, vergleiche mit top / H!)
set_rtprio <TID, 80> setzt die Priorität bei bir auf -81.
Bernhard --------------------
#include <stdio.h> #include <sched.h> #include <stdlib.h>
// wegen getrlimit: #include <sys/time.h> #include <sys/resource.h>
int main(int argc, char **argv) { struct sched_param sched; struct rlimit limit;
int pid, prio;
getrlimit (RLIMIT_RTPRIO, &limit); printf ("Resource-Limits:\n"); printf ("RLIMIT_RTPRIO (soft): %d\n", limit.rlim_cur); printf ("RLIMIT_RTPRIO (hard): %d\n", limit.rlim_max);
if (argc == 1) { printf("set_rtprio <pid> <prio>\n"); printf("\n"); printf("Sets <pid>'s scheduling policy to SCHED_FIFO and\n"); printf(" <pid>'s priority to <prio>.\n"); printf("If <prio> is missing it displays <pid>'s policy and priority.\n"); printf("\n"); printf("Attention:\n"); printf("Priorities shown in ps (version 3.2.7) are FALSE! :\n"); printf("use top / H for check!\n"); printf("SCHED_FIFO-priorities are mapped [1..99] -> [-2..-100]\n"); printf("\n"); printf("Available policies and their range of priorities:\n"); printf(" SCHED_OTHER (0): %d until %d\n", sched_get_priority_min(SCHED_OTHER), sched_get_priority_max(SCHED_OTHER)); printf(" SCHED_FIFO (1): %d until %d\n", sched_get_priority_min(SCHED_FIFO), sched_get_priority_max(SCHED_FIFO)); printf(" SCHED_RR (2): %d until %d\n", sched_get_priority_min(SCHED_RR), sched_get_priority_max(SCHED_RR)); printf(" SCHED_BATCH (3): %d until %d\n", sched_get_priority_min(SCHED_BATCH), sched_get_priority_max(SCHED_BATCH)); // printf(" SCHED_ISO (4): %d until %d\n", sched_get_priority_min(SCHED_ISO), sched_get_priority_max(SCHED_ISO)); // printf(" SCHED_IDLE (5): %d until %d\n", sched_get_priority_min(SCHED_IDLE), sched_get_priority_max(SCHED_IDLE)); printf("\n"); getrlimit (RLIMIT_RTPRIO, &limit); printf ("Resource-Limits:\n"); printf ("(/etc/security/limits may be helpful to edit)\n"); printf ("RLIMIT_RTPRIO (soft): %d\n", limit.rlim_cur); printf ("RLIMIT_RTPRIO (hard): %d\n", limit.rlim_max); } if (argc == 2) { pid = atoi(argv[1]); if (sched_getparam(pid, &sched ) >= 0) { printf("Policy of pid %d = %d\n", pid, sched_getscheduler(pid)); printf("Priority of pid %d = %d\n", pid, sched.sched_priority); } else { perror(""); return -1; } } if (argc == 3) { pid = atoi(argv[1]); prio = atoi(argv[2]); printf("Request:\n"); printf("Policy of pid %d = %d\n", pid, SCHED_FIFO); printf("Priority of pid %d = %d\n", pid, prio); sched.sched_priority = prio; if (sched_setscheduler(pid, SCHED_FIFO, &sched)) { perror("sched_setscheduler :"); printf("Status:\n"); printf("Policy of pid %d = %d\n", pid, sched_getscheduler(pid)); printf("Priority of pid %d = %d\n", pid, sched.sched_priority); printf("\n"); return -1; } printf("Status:\n"); printf("Policy of pid %d = %d\n", pid, sched_getscheduler(pid)); printf("Priority of pid %d = %d\n", pid, sched.sched_priority); printf("\n"); } return 0; }
Hallo Bernhard,
On Tue, Oct 06, 2009 at 11:32:54 +0200, Bernhard Schiffner wrote:
Ich bekomme als non-root bei getrlimit( RLIMIT_RTPRIO, ...) immer 0 zurueck und will wissen, wie ich das fuer bestimmte Nutzer | Gruppen | Programme aendern kann. Ein erster Eintrag in /etc/security/limits half nicht weiter.
Die Datei heisst /etc/security/limits.conf, nicht /etc/security/limits.
Auf einem Testsystem (Ubuntu 8.04 mit selbstkompiliertem 2.6.27.10) hat es mit folgenden Zeilen in der /etc/security/limits.conf funktioniert:
ich soft rtprio 20 ich hard rtprio 20
Nachdem sich der User "ich" per ssh[*] neu eingeloggt hat, sitzt die real-time prio auf 20, zu sehen mit cat /proc/$$/limits bzw. ulimit -a in der Shell.
Danach kann ich mit Deinem Tool die Prio eines sleep-Prozesses auf 10 setzen:
$ sleep 1h & [1] 17011 $ ./rtlim 17011 10 Resource-Limits: RLIMIT_RTPRIO (soft): 20 RLIMIT_RTPRIO (hard): 20 Request: Policy of pid 17011 = 1 Priority of pid 17011 = 10 Status: Policy of pid 17011 = 1 Priority of pid 17011 = 10
Wenn ich stattdessen versuche, die Prio auf 50 zu setzen, geht es schief, weil damit das rlimit von 20 ueberschritten wird.
[*] Jede andere Login-Methode, die pam_limits.so in ihrer PAM-Konfiguration benutzt, sollte auch funktionieren.
Gruss, Chris
On Tuesday 06 October 2009 17:51:22 Christian Perle wrote:
Hallo Bernhard,
On Tue, Oct 06, 2009 at 11:32:54 +0200, Bernhard Schiffner wrote:
Ich bekomme als non-root bei getrlimit( RLIMIT_RTPRIO, ...) immer 0 zurueck und will wissen, wie ich das fuer bestimmte Nutzer | Gruppen | Programme aendern kann. Ein erster Eintrag in /etc/security/limits half nicht weiter.
Die Datei heisst /etc/security/limits.conf, nicht /etc/security/limits.
.-)
Auf einem Testsystem (Ubuntu 8.04 mit selbstkompiliertem 2.6.27.10) hat es mit folgenden Zeilen in der /etc/security/limits.conf funktioniert:
ich soft rtprio 20 ich hard rtprio 20
Debian dito. (Ich hatte nur hard eingetragen. Und nach der Zeile #End of File. Woran's wohl nur lag?)
Nachdem sich der User "ich" per ssh[*] neu eingeloggt hat, sitzt die real-time prio auf 20, zu sehen mit cat /proc/$$/limits bzw. ulimit -a in der Shell.
Geht bei mir auch. Danke für den Befehl ulimit, der war mir unbekannt.
Danach kann ich mit Deinem Tool die Prio eines sleep-Prozesses auf 10 setzen:
$ sleep 1h & [1] 17011 $ ./rtlim 17011 10 Resource-Limits: RLIMIT_RTPRIO (soft): 20 RLIMIT_RTPRIO (hard): 20 Request: Policy of pid 17011 = 1 Priority of pid 17011 = 10 Status: Policy of pid 17011 = 1 Priority of pid 17011 = 10
Damit bist Du Realtimer: GLÜCKWUNSCH!
Das mit den Prioritäten ist (gewollt) _die_ zentrale Steuerstelle. Der Rest ist checken, ob es auch klappt. Im negativen Fall sind die Hindernisse abzustellen. Das kann zwischen trivial (z.B. Powermanagement einstellen) und extrem anspruchsvoll (preempt RCU, (Jahre für ein paar Zeilen Code)) schwanken.
Wenn ich stattdessen versuche, die Prio auf 50 zu setzen, geht es schief, weil damit das rlimit von 20 ueberschritten wird.
Klar.
[*] Jede andere Login-Methode, die pam_limits.so in ihrer PAM-Konfiguration benutzt, sollte auch funktionieren.
Gruss, Chris
Danke sehr!
Bernhard
On Tuesday 06 October 2009 17:51:22 Christian Perle wrote: ...
[*] Jede andere Login-Methode, die pam_limits.so in ihrer PAM-Konfiguration benutzt, sollte auch funktionieren.
Gruss, Chris
Übrigens, vermutlich die Steuer-Variante, die sich zum Thema IMNSHO durchsetzen wird:
http://git.0pointer.de/?p=rtkit.git;a=blob;f=README
(Kommt aus der Audio-Ecke, Pulseaudio)
Bernhard
lug-dd@mailman.schlittermann.de