| #include <pronix.de> |
|
|
3.3. Erstellen von eigenen Dämon - Prozessen
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Resource | Standard | 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 Sie die Ressourcen gleich bis auf die Hard-Limits ändern. Sollten die beiden Struktur-Variablen rlim_cur oder/und rlim_max den Wert RLIM_INFINITY haben, so bedeutet dies, dass überhaupt kein Limit gesetzt (unbegrenzt) ist. Nun wollen wir mal anhand eines Beispiels sehen wie Sie die Ressourcen-Limits des aktuellen Prozesses auslesen können ...
#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 den Code Ihren Bedürfnissen anpassen. Falls das Programm portabel gehalten werden soll muss natürlich bedingt compiliert werden ...
#ifdef RLIMIT_OFILE read_limit(RLIMIT_OFILE,"RLIMIT_OFILE"); #endif #ifdef RLIMIT_NPROC read_limit(RLIMIT_NPROC,"RLIMIT_NPROC"); #endif
Man muss auch noch dazu anmerken, das dieses Kapitel nicht dem POSIX.1-Standard entspricht.
Jetzt haben Sie eine Funktion zum Auslesen der Ressourcen geschrieben. Jetzt benötigen Sie noch eine zum Ändern der Ressourcen. Dabei gibt es folgende Regeln zu beachten ...
Hier nun das 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 ...
#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;
...folgendes schreiben....
limit.rlim_max=neuer_wert;
Ich wiederhole es nochmals, auch wenn Sie das Limit ändern, gilt dies nur für den aktuell laufenden Prozess. Wird das Programm beendet und wieder neu gestartet, sind alle Limits wieder im Urzustand.