mirror of
https://github.com/troglobit/finit.git
synced 2026-11-09 16:21:24 +00:00
Resource limit manipulation (setrlimit)
Add support for changing the initial hard and soft resource limits for finit and any processes it launches. See /etc/finit.conf section in README.md for more information.
This commit is contained in:
1 parent
f29dff691f
commit
6d84fd010e
2 files changed
+105
No files matched your search
@@ -133,6 +133,24 @@ Syntax:
|
|||||||
* `network <PATH>`
|
* `network <PATH>`
|
||||||
Script or program to bring up networking, with optional arguments
|
Script or program to bring up networking, with optional arguments
|
||||||
|
|
||||||
|
* `rlimit <hard|soft> RESOURCE <LIMIT|infinity>`
|
||||||
|
Modify the specified resource's hard or soft limit to be the
|
||||||
|
specifed limit. `RESOURCE` is a lower-case string matching the
|
||||||
|
constants in `setrlimit(2)` with the `RLIMIT_` prefix
|
||||||
|
removed. E.g. to select `RLIMIT_CPU`, `RESOURCE` would be
|
||||||
|
`cpu`. `LIMIT` is an integer whose unit depends on the resource
|
||||||
|
being modified, see `setrlimit(2)` for more information. The special
|
||||||
|
limit `infinity` means the there should be no limit on the resource,
|
||||||
|
i.e. `RLIM_INFINITY` is passed to `setrlimit(2)`.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# No process is allowed more than 8MB of address space
|
||||||
|
rlimit hard as 8388608
|
||||||
|
|
||||||
|
# Core dumps may be arbitrarily large
|
||||||
|
rlimit soft core infinity
|
||||||
|
```
|
||||||
|
|
||||||
* `runlevel <N>`
|
* `runlevel <N>`
|
||||||
N is the runlevel number 1-9, where 6 is reserved for reboot.
|
N is the runlevel number 1-9, where 6 is reserved for reboot.
|
||||||
Default is 2.
|
Default is 2.
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
@@ -150,6 +152,86 @@ void conf_parse_cond(svc_t *svc, char *cond)
|
|||||||
strlcpy(svc->cond, ptr, sizeof(svc->cond));
|
strlcpy(svc->cond, ptr, sizeof(svc->cond));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rlimit_name {
|
||||||
|
char *name;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rlimit_name rlimit_names[] = {
|
||||||
|
{ "as", RLIMIT_AS },
|
||||||
|
{ "core", RLIMIT_CORE },
|
||||||
|
{ "cpu", RLIMIT_CPU },
|
||||||
|
{ "data", RLIMIT_DATA },
|
||||||
|
{ "fsize", RLIMIT_FSIZE },
|
||||||
|
{ "locks", RLIMIT_LOCKS },
|
||||||
|
{ "memlock", RLIMIT_MEMLOCK },
|
||||||
|
{ "msgqueue", RLIMIT_MSGQUEUE },
|
||||||
|
{ "nice", RLIMIT_NICE },
|
||||||
|
{ "nofile", RLIMIT_NOFILE },
|
||||||
|
{ "nproc", RLIMIT_NPROC },
|
||||||
|
{ "rss", RLIMIT_RSS },
|
||||||
|
{ "rtprio", RLIMIT_RTPRIO },
|
||||||
|
{ "rttime", RLIMIT_RTTIME },
|
||||||
|
{ "sigpending", RLIMIT_SIGPENDING },
|
||||||
|
{ "stack", RLIMIT_STACK },
|
||||||
|
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
void conf_parse_rlimit(char *line)
|
||||||
|
{
|
||||||
|
struct rlimit rlim;
|
||||||
|
rlim_t new, *set;
|
||||||
|
const struct rlimit_name *name;
|
||||||
|
int resource = -1;
|
||||||
|
|
||||||
|
char *tok = strtok(line, " \t");
|
||||||
|
|
||||||
|
if (tok && !strcmp(tok, "soft"))
|
||||||
|
set = &rlim.rlim_cur;
|
||||||
|
else if (tok && !strcmp(tok, "hard"))
|
||||||
|
set = &rlim.rlim_max;
|
||||||
|
else
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
tok = strtok(NULL, " \t");
|
||||||
|
if (!tok)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (name = rlimit_names; name->name; name++)
|
||||||
|
if (!strcmp(tok, name->name))
|
||||||
|
resource = name->val;
|
||||||
|
|
||||||
|
if (resource < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
tok = strtok(NULL, " \t");
|
||||||
|
if (!tok)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!strcmp(tok, "infinity"))
|
||||||
|
new = RLIM_INFINITY;
|
||||||
|
else {
|
||||||
|
const char *err = NULL;
|
||||||
|
|
||||||
|
new = strtonum(tok, 0, 2 << 31, &err);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getrlimit(resource, &rlim))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*set = new;
|
||||||
|
if (setrlimit(resource, &rlim))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
FLOG_WARN("Failed parsing/setting %s rlimit", name->name ? : "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_static(char *line)
|
static void parse_static(char *line)
|
||||||
{
|
{
|
||||||
char *x;
|
char *x;
|
||||||
@@ -302,6 +384,11 @@ static void parse_dynamic(char *line, time_t mtime)
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MATCH_CMD(line, "rlimit ", x)) {
|
||||||
|
conf_parse_rlimit(x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_conf_dynamic(char *file, time_t mtime)
|
static int parse_conf_dynamic(char *file, time_t mtime)
|
||||||
|
|||||||
Reference in new issue
Block a user