ein Kapitel zurück                                           ein Kapitel weiter

Sie werden die Limits der Resourcen wahrscheinlich nie verändern müssen. Falls doch, dann dient diese Kapitel dazu, damit sie wenigstens wissen wie. Bedenken sie aber bitte, falls sie die Resourcen eines Prozesses verändern, und sie eh schon am Limit sind, ob überhaupt noch ein Sinnvolles Arbeiten Möglich ist. Dies ist Abhängig vom System. Diese Funktionen dienen aber 'nur' für das Verändern des Prozesses der gerade läuft. Alle anderen bleiben davon unberührt. Wollen sie die in diesem Kapitel gezeigten Resourcen dauerhaft ändern, kommen um das Neukompilieren des Kernels nicht herum. Natürlich müssen sie erst mal einige Konstanten verändern. Diese vielleicht zu einem anderen Zeitpunkt.

Um unter Linux/Unix geltende Ressourcen eines Prozesses abzufragen oder zu ändern gibt es die beiden Funktionen....

#include <sys/time.h>
#include <sys/resource.h>

int getrlimit(int resource, struct rlimit *limit_zeiger);

int setrlimit(int resource, struct rlimit *limit_zeiger);  

Folgende vordefinierten Konstanten stehen dabei für die int-Variable ressource zur Verfügung (Systemabhängig)......

Resource Standart Bedeutung
RLIMIT_CORE SVR4,BSD Maximal Grösse der core-Datei in Bytes. Der Wert 0 bedeutet das keine core-Datei angelegt wird.
RLIMIT_CPU SVR4,BSD Limit für CPU-Zeit in Sekunden. Liefert Signal SIGXCPU, wenn das Soft-Limit überschritten wurde, an den Prozess.
RLIMIT_DATA SVR4, BSD Maximale Grösse des Gesamten Datensegmentes (Datensegment,BSS - Segment und Heap)
RLIMIT_FSIZE SVR4, BSD Maximale Grösse einer Datei die beschrieben werden kann in Bytes. Wird das Soft-Limit überschritten wird das Signal SIGXFSZ ausgelöst.
RLIMIT_MEMLOCK BSD, LINUX Max. Speichergrösse die mit unlock gesperrt werden kann.
RLIMIT_NOFILE SVR4 Max. Anzahl von gleichzeitig geöffnete Dateien.
RLIMIT_NPROC BSD Max. Anzahl von Kindprozessen pro User-ID.
RLIMIT_OFILE BSD Max. Anzahl von gleichzeitig geöffnete Dateien.
RLIMIT_RSS BSD Maximale resident set size in Byte. Bei Speicherengpässen entzieht der Kern den Prozessen, die den resident set size überschreiten, den zuviel angeforderten Speicher.
RLIMIT_STACK SVR4, BSD Max Grösse des Stacks in Byte
RLIMIT_VMEM SVR4 Max. Grösse des Memory Mapped-Adressraums.


Die Struktur rlimit hat folgendes Aussehen.....

struct rlimit {
          rlim_t rlim_cur;   //Soft-Limit == aktuelles Limit
          rlim_t rlim_max;   //Hard-Limit == maximaler Wert für rlim_cur
               };  

Mit den Soft-Limits können also unsere Resourcen bis gleich bis auf die Hard-Limits ändern. Sollten die beiden Strukur-Variablen rlim_cur oder/und rlim_max den Wert RLIM_INFINITY haben, so Bedeutet dies das überhaupt kein Limit gesetzt (unbegrenzt) ist. Nun wollen wir mal anhand eines Beispiels sehen wie wir die Resourcen-Limits des aktuellen Prozesses auslesen können......

/*Download:limit1.c*/
#include <stdio.h> #include <sys/time.h> #include <sys/resource.h> /*keinerlei Limits (unbegrenzt)*/ #define NO_LIMIT RLIM_INFINITY enum{ERROR=-1, SUCCESS}; int limit_wert[] = {RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_MEMLOCK, RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_OFILE, RLIMIT_RSS, RLIMIT_STACK, /*RLIMIT_VMEM*/}; char *limit_name[] = {"RLIMIT_CORE","RLIMIT_CPU","RLIMIT_DATA","RLIMIT_FSIZE", "RLIMIT_MEMLOCK","RLIMIT_NOFILE","RLIMIT_NPROC","RLIMIT_OFILE", "RLIMIT_RSS","RLIMIT_STACK",/*"RLIMIT_VMEM",*/NULL}; void read_limit(int resource, char *name) { struct rlimit limit; /*Wir Erfragen nach dem Limit 'resource'*/ if(getrlimit(resource, &limit) == ERROR) { printf("Fehler bei getrlimit...\n"); exit(0); } printf("%15s | Soft-Limit : ",name); if(limit.rlim_cur == NO_LIMIT) printf("unbegrenzt |"); else printf("%12ld |",limit.rlim_cur); printf("Hard-Limit : "); if(limit.rlim_max == NO_LIMIT) printf("unbegrenzt |"); else printf("%12ld|",limit.rlim_max); if(limit.rlim_cur == limit.rlim_max) printf("(Soft-Limit = maximal)\n"); else printf("(Soft-Limt = erweiterbar\n"); } int main() { int i; for(i=0; limit_name[i]!= NULL; i++) read_limit(limit_wert[i], limit_name[i]); return 0; }

Da ich auf Linux programmiere und mir somit die meisten dieser Ressourcen-Konstanten zur Verfügung stehen müssen sie eben den Code anpassen. Falls das Programm portabel gehalten werden soll muss natürlich Bedient compiliert werden.....

#ifdef RLIMIT_OFILE
   read_limit(RLIMIT_OFILE,"RLIMIT_OFILE");
#endif
#ifdef RLIMIT_NPROC
   read_limit(RLIMIT_NPROC,"RLIMIT_NPROC");
#endif
........usw.  

Dies muss nicht so aussehen! Man muss auch noch dazu anmerken, das dieses Kapitel nicht dem POSIX.1 - Standart entspricht.

Jetzt haben wir eine Funktion zum Auslesen der Ressourcen geschrieben. Jetzt benötigen wir noch eine zum Ändern der Ressourcen. Dabei gibt es folgende Regeln zu beachten....

  • Einen Soft-Limit können sie von jedem Prozess verändern. Es muss nur darauf geachtet werden das der Wert des Hard-Limit nicht überschritten wird.
  • Den Hard-Limit können ebenfalls jederzeit heruntersetzen soweit dieser noch größer oder gleich dem Soft-Limit ist. Erhöhen können sie aber als normaler User den Prozess anschließend nicht mehr.
  • Nur Superuser kann das Hard-Limit erhöhen.

Hier nun unser Programm mit setrlimit. Auch hier gilt wieder, wenn sie das Programm portabel halten wollen müssen sie die einzelnen Limits bedingt Compilieren, da nicht alle Limtits auf jedem System vorhanden sind......

/*Download:limit2.c*/
#include <stdio.h> #include <sys/time.h> #include <sys/resource.h> /*keinerlei Limits (unbegrenzt)*/ #define NO_LIMIT RLIM_INFINITY enum{ERROR=-1, SUCCESS}; int limit_wert[] = {RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_MEMLOCK, RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_OFILE, RLIMIT_RSS, RLIMIT_STACK, /*RLIMIT_VMEM*/}; char *limit_name[] = {"RLIMIT_CORE","RLIMIT_CPU","RLIMIT_DATA","RLIMIT_FSIZE", "RLIMIT_MEMLOCK","RLIMIT_NOFILE","RLIMIT_NPROC","RLIMIT_OFILE", "RLIMIT_RSS","RLIMIT_STACK",/*"RLIMIT_VMEM",*/NULL}; void read_limit(int resource, char *name) { struct rlimit limit; /*Wir Erfragen nach dem Limit 'resource'*/ if(getrlimit(resource, &limit) == ERROR) { printf("Fehler bei getrlimit...\n"); exit(0); } printf("%15s | Soft-Limit : ",name); if(limit.rlim_cur == NO_LIMIT) printf("unbegrenzt |"); else printf("%12ld |",limit.rlim_cur); printf("Hard-Limit : "); if(limit.rlim_max == NO_LIMIT) printf("unbegrenzt |"); else printf("%12ld|",limit.rlim_max); if(limit.rlim_cur == limit.rlim_max) printf("(Soft-Limit = maximal)\n"); else printf("(Soft-Limt = erweiterbar\n"); } /*Funktion zum setzen eines Limits. Ist beschränkt auf Soft-Limits*/ void set_limit(int resource, char *name) { struct rlimit limit; long neuer_wert; printf("\nWir verändern nur Soft-Limits!!\n\n"); printf("Welchen Wert soll der Soft-Limit von %s bekommen : ",name); scanf("%ld",&neuer_wert); if(getrlimit(resource, &limit) == ERROR) { printf("Fehler bei getrlimit...\n"); exit(0); } limit.rlim_cur=neuer_wert; if(setrlimit(resource, &limit) == ERROR) { printf("Fehler bei setrlimit...\n"); exit(0); } printf("\nLese das Soft-Limit von %s nochmals....\n",name); read_limit(resource, name); printf("\n\n"); } int main() { int i,x; printf("\n"); while(1) { for(i=0; limit_name[i] != NULL; i++) { printf("%2d - %-15s ",i,limit_name[i]); if(!(i%3)) printf("\n"); } printf("\n\nWelches Limit wollen sie verändern (99=ENDE): "); scanf("%d",&x); if(x==99) break; read_limit(limit_wert[x], limit_name[x]); set_limit(limit_wert[x], limit_name[x]); } return 0; }

Sollten sie die Hard-Limits ändern wollen so müssen sie im Programm anstatt....

limit.rlim_cur=neuer_wert;  

...schreiben....

limit.rlim_max=neuer_wert;  

Ich wiederhole es nochmals, auch wenn sie das Limit ändern, gilt dies nur für den aktuell laufenden Prozeß. Wird das Programm beendet und wieder neu gestartet, sind alle Limits wieder im Uhrzustand.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf