mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 10:12:32 +00:00
Compare commits
1
Commits
4.x
...
cgroup-config
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44137806e4 |
@@ -98,6 +98,54 @@ 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
|
||||||
|
|
||||||
|
* `cgroup <NAME> cpuset:SPEC cpu:SPEC mem:SPEC`
|
||||||
|
Create a control group for resource limiting services using cgroups.
|
||||||
|
Unlike `rlimit` this setting defines a common group to be selected for
|
||||||
|
any set of run/task/services using the `group` directive (below).
|
||||||
|
|
||||||
|
A cpuset for a cgroup can be the traditional list of CPU cores to
|
||||||
|
assign to the group, or a range that Finit will use to dynamically
|
||||||
|
allocate cores based on the amount available. The range values can be
|
||||||
|
either in absolute form or percent.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cgroup first cpuset:1
|
||||||
|
```
|
||||||
|
|
||||||
|
To create a cgroup with one exclusive CPU:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cgroup single cpuset:[1,1]
|
||||||
|
```
|
||||||
|
|
||||||
|
To create cgroup that uses at most two shared CPUs:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cgroup uptotwo cpuset:[,2]
|
||||||
|
```
|
||||||
|
|
||||||
|
To create cgroup with at least two shared CPUs:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cgroup dual cpuset:[2,]
|
||||||
|
```
|
||||||
|
|
||||||
|
To create cgroup with at least one CPU and at most half of all
|
||||||
|
available CPUs:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cgroup greedy cpuset:[1,50%]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
* `group <NAME>`
|
||||||
|
All subsequent `service`, `task`, or `run` directives are executed in the
|
||||||
|
given control group `NAME`, which must be defined prior to this line. If
|
||||||
|
`NAME` does not yet exist the default group `default` is used.
|
||||||
|
|
||||||
|
When separate Finit `.conf` files are used for services the default group
|
||||||
|
is reset for each `.conf` file read.
|
||||||
|
|
||||||
* `rlimit [hard|soft] RESOURCE <LIMIT|unlimited>` Set the hard or soft
|
* `rlimit [hard|soft] RESOURCE <LIMIT|unlimited>` Set the hard or soft
|
||||||
limit for a resource, or both if that argument is omitted. `RESOURCE`
|
limit for a resource, or both if that argument is omitted. `RESOURCE`
|
||||||
is the lower-case `RLIMIT_` string constants from `setrlimit(2)`,
|
is the lower-case `RLIMIT_` string constants from `setrlimit(2)`,
|
||||||
|
|||||||
+77
-1
@@ -30,7 +30,15 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int active;
|
||||||
|
char cgroup[16];
|
||||||
|
char path[32];
|
||||||
|
} cg_avail[200];
|
||||||
|
|
||||||
static int cg_init = 0;
|
static int cg_init = 0;
|
||||||
|
static int cg_num = 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by Finit at early boot to mount initial cgroups
|
* Called by Finit at early boot to mount initial cgroups
|
||||||
@@ -64,8 +72,19 @@ void cgroup_init(void)
|
|||||||
|
|
||||||
snprintf(rc, sizeof(rc), "/sys/fs/cgroup/%s", cgroup);
|
snprintf(rc, sizeof(rc), "/sys/fs/cgroup/%s", cgroup);
|
||||||
mkdir(rc, 0755);
|
mkdir(rc, 0755);
|
||||||
if (mount("cgroup", rc, "cgroup", opts, cgroup))
|
if (mount("cgroup", rc, "cgroup", opts, cgroup)) {
|
||||||
_d("Failed mounting %s cgroup on %s", cgroup, rc);
|
_d("Failed mounting %s cgroup on %s", cgroup, rc);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cg_avail[cg_num].active = 1;
|
||||||
|
strlcpy(cg_avail[cg_num].cgroup, cgroup, sizeof(cg_avail[cg_num].cgroup));
|
||||||
|
strlcpy(cg_avail[cg_num].path, rc, sizeof(cg_avail[cg_num].path));
|
||||||
|
cg_num++;
|
||||||
|
|
||||||
|
/* Create default group in all available cgroups */
|
||||||
|
strlcat(rc, "/default", sizeof(rc));
|
||||||
|
mkdir(rc, 0755);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default cgroups for process monitoring */
|
/* Default cgroups for process monitoring */
|
||||||
@@ -93,6 +112,49 @@ fail:
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cgroup_add(char *name, void (*cb)(char *, void *), void *arg)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < cg_num; i++) {
|
||||||
|
char path[80];
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "%s/%s", cg_avail[i].path, name);
|
||||||
|
if (mkdir(path, 0755) && EEXIST != errno) {
|
||||||
|
rc++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: Add to cache of added groups, for cgroup_find() */
|
||||||
|
if (cb)
|
||||||
|
cb(path, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: Temporary hackish implementation */
|
||||||
|
int cgroup_find(char *name, char *group, size_t len)
|
||||||
|
{
|
||||||
|
char path[80];
|
||||||
|
|
||||||
|
if (cg_num <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "%s/%s", cg_avail[0].path, name);
|
||||||
|
if (access(path, F_OK))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
strlcpy(group, name, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int cgroup_cpuset_range(char *group, int min, int max) */
|
||||||
|
/* { */
|
||||||
|
/* } */
|
||||||
|
|
||||||
static int move_pid(char *group, char *name, int pid)
|
static int move_pid(char *group, char *name, int pid)
|
||||||
{
|
{
|
||||||
char path[256];
|
char path[256];
|
||||||
@@ -135,6 +197,20 @@ int cgroup_service(char *cmd, int pid)
|
|||||||
return move_pid("finit/system", nm, pid);
|
return move_pid("finit/system", nm, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cgroup_assign(char *name, int pid)
|
||||||
|
{
|
||||||
|
char path[120];
|
||||||
|
int i, rc = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < cg_num; i++) {
|
||||||
|
snprintf(path, sizeof(path), "%s/%s/cgroup.procs",
|
||||||
|
cg_avail[i].path, name);
|
||||||
|
rc += echo(path, 0, "%d", pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
|
|||||||
@@ -26,7 +26,11 @@
|
|||||||
|
|
||||||
void cgroup_init (void);
|
void cgroup_init (void);
|
||||||
|
|
||||||
|
int cgroup_add (char *name, void (*cb)(char *, void *), void *arg);
|
||||||
|
int cgroup_find (char *name, char *group, size_t len);
|
||||||
|
|
||||||
int cgroup_user (char *name);
|
int cgroup_user (char *name);
|
||||||
int cgroup_service (char *cmd, int pid);
|
int cgroup_service (char *cmd, int pid);
|
||||||
|
int cgroup_assign (char *name, int pid);
|
||||||
|
|
||||||
#endif /* FINIT_CGROUP_H_ */
|
#endif /* FINIT_CGROUP_H_ */
|
||||||
|
|||||||
+62
-7
@@ -33,6 +33,7 @@
|
|||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
|
#include "cgroup.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
@@ -53,6 +54,7 @@ struct conf_change {
|
|||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char cgroup[32];
|
||||||
static uev_t w1, w2, w3, w4;
|
static uev_t w1, w2, w3, w4;
|
||||||
static TAILQ_HEAD(head, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_change_list);
|
static TAILQ_HEAD(head, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_change_list);
|
||||||
|
|
||||||
@@ -342,6 +344,45 @@ error:
|
|||||||
logit(LOG_WARNING, "rlimit: parse error");
|
logit(LOG_WARNING, "rlimit: parse error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpuset_cb(char *grp, void *arg)
|
||||||
|
{
|
||||||
|
int cpuset = *(int *)arg;
|
||||||
|
char path[128];
|
||||||
|
|
||||||
|
if (!strstr(grp, "cpuset"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Both .cpus and .mems are mandatory settings */
|
||||||
|
snprintf(path, sizeof(path), "%s/cpuset.cpus", grp);
|
||||||
|
echo(path, 0, "%d", cpuset);
|
||||||
|
snprintf(path, sizeof(path), "%s/cpuset.mems", grp);
|
||||||
|
echo(path, 0, "0");
|
||||||
|
|
||||||
|
/* XXX: HACK for now, fix proper CPU allocation */
|
||||||
|
snprintf(path, sizeof(path), "%s/cpuset.cpu_exclusive", grp);
|
||||||
|
echo(path, 0, "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_cgroup(char *line)
|
||||||
|
{
|
||||||
|
char *group, *token;
|
||||||
|
int cpuset = -1;
|
||||||
|
|
||||||
|
group = strtok(line, " ");
|
||||||
|
if (!group)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while ((token = strtok(NULL, " "))) {
|
||||||
|
if (!strncmp(token, "cpuset:", 7)) {
|
||||||
|
token += 7;
|
||||||
|
cpuset = atoi(token); /* XXX: fixme */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpuset >= 0)
|
||||||
|
cgroup_add(group, cpuset_cb, &cpuset);
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_static(char *line)
|
static void parse_static(char *line)
|
||||||
{
|
{
|
||||||
char *x;
|
char *x;
|
||||||
@@ -430,6 +471,11 @@ static void parse_static(char *line)
|
|||||||
cfglevel = 2; /* Fallback */
|
cfglevel = 2; /* Fallback */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MATCH_CMD(line, "cgroup ", x)) {
|
||||||
|
parse_cgroup(strip_line(x));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
||||||
@@ -448,26 +494,26 @@ static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
|||||||
|
|
||||||
/* Monitored daemon, will be respawned on exit */
|
/* Monitored daemon, will be respawned on exit */
|
||||||
if (MATCH_CMD(line, "service ", x)) {
|
if (MATCH_CMD(line, "service ", x)) {
|
||||||
service_register(SVC_TYPE_SERVICE, x, rlimit, file);
|
service_register(SVC_TYPE_SERVICE, x, rlimit, cgroup, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One-shot task, will not be respawned */
|
/* One-shot task, will not be respawned */
|
||||||
if (MATCH_CMD(line, "task ", x)) {
|
if (MATCH_CMD(line, "task ", x)) {
|
||||||
service_register(SVC_TYPE_TASK, x, rlimit, file);
|
service_register(SVC_TYPE_TASK, x, rlimit, cgroup, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like task but waits for completion, useful w/ [S] */
|
/* Like task but waits for completion, useful w/ [S] */
|
||||||
if (MATCH_CMD(line, "run ", x)) {
|
if (MATCH_CMD(line, "run ", x)) {
|
||||||
service_register(SVC_TYPE_RUN, x, rlimit, file);
|
service_register(SVC_TYPE_RUN, x, rlimit, cgroup, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Classic inetd service */
|
/* Classic inetd service */
|
||||||
if (MATCH_CMD(line, "inetd ", x)) {
|
if (MATCH_CMD(line, "inetd ", x)) {
|
||||||
#ifdef INETD_ENABLED
|
#ifdef INETD_ENABLED
|
||||||
service_register(SVC_TYPE_INETD, x, rlimit, file);
|
service_register(SVC_TYPE_INETD, x, rlimit, cgroup, file);
|
||||||
#else
|
#else
|
||||||
_e("Finit built with inetd support disabled, cannot register service inetd %s!", x);
|
_e("Finit built with inetd support disabled, cannot register service inetd %s!", x);
|
||||||
#endif
|
#endif
|
||||||
@@ -480,9 +526,15 @@ static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* All subsequent run/task/service/tty/etc. directives to use this cgroup */
|
||||||
|
if (MATCH_CMD(line, "group ", x)) {
|
||||||
|
cgroup_find(x, cgroup, sizeof(cgroup));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Regular or serial TTYs to run getty */
|
/* Regular or serial TTYs to run getty */
|
||||||
if (MATCH_CMD(line, "tty ", x)) {
|
if (MATCH_CMD(line, "tty ", x)) {
|
||||||
tty_register(strip_line(x), rlimit, file);
|
tty_register(strip_line(x), rlimit, cgroup, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -500,8 +552,8 @@ static void tabstospaces(char *line)
|
|||||||
|
|
||||||
static int parse_conf_dynamic(char *file)
|
static int parse_conf_dynamic(char *file)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
|
||||||
struct rlimit rlimit[RLIMIT_NLIMITS];
|
struct rlimit rlimit[RLIMIT_NLIMITS];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
fp = fopen(file, "r");
|
fp = fopen(file, "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
@@ -512,6 +564,9 @@ static int parse_conf_dynamic(char *file)
|
|||||||
/* Prepare default limits for each service */
|
/* Prepare default limits for each service */
|
||||||
memcpy(rlimit, global_rlimit, sizeof(rlimit));
|
memcpy(rlimit, global_rlimit, sizeof(rlimit));
|
||||||
|
|
||||||
|
/* Prepare default cgroup for each service */
|
||||||
|
strlcpy(cgroup, "default", sizeof(cgroup));
|
||||||
|
|
||||||
_d("Parsing %s <<<<<<", file);
|
_d("Parsing %s <<<<<<", file);
|
||||||
while (!feof(fp)) {
|
while (!feof(fp)) {
|
||||||
char line[LINE_SIZE] = "";
|
char line[LINE_SIZE] = "";
|
||||||
@@ -592,7 +647,7 @@ int conf_reload(void)
|
|||||||
/* If rescue.conf is missing, fall back to a root shell */
|
/* If rescue.conf is missing, fall back to a root shell */
|
||||||
rc = parse_conf(RESCUE_CONF);
|
rc = parse_conf(RESCUE_CONF);
|
||||||
if (rc)
|
if (rc)
|
||||||
tty_register(line, global_rlimit, NULL);
|
tty_register(line, global_rlimit, cgroup, NULL);
|
||||||
|
|
||||||
print(rc, "Entering rescue mode");
|
print(rc, "Entering rescue mode");
|
||||||
goto done;
|
goto done;
|
||||||
|
|||||||
+4
-4
@@ -450,19 +450,19 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
/* Register udevd as a monitored service */
|
/* Register udevd as a monitored service */
|
||||||
snprintf(cmd, sizeof(cmd), "[S12345789] pid:udevd %s -- Device event managing daemon", path);
|
snprintf(cmd, sizeof(cmd), "[S12345789] pid:udevd %s -- Device event managing daemon", path);
|
||||||
if (service_register(SVC_TYPE_SERVICE, cmd, global_rlimit, NULL)) {
|
if (service_register(SVC_TYPE_SERVICE, cmd, global_rlimit, "default", NULL)) {
|
||||||
_pe("Failed registering %s", path);
|
_pe("Failed registering %s", path);
|
||||||
udev = 0;
|
udev = 0;
|
||||||
} else {
|
} else {
|
||||||
snprintf(cmd, sizeof(cmd), ":1 [S] <svc%s> "
|
snprintf(cmd, sizeof(cmd), ":1 [S] <svc%s> "
|
||||||
"udevadm trigger -c add -t devices "
|
"udevadm trigger -c add -t devices "
|
||||||
"-- Requesting device events", path);
|
"-- Requesting device events", path);
|
||||||
service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);
|
service_register(SVC_TYPE_RUN, cmd, global_rlimit, "default", NULL);
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), ":2 [S] <svc%s> "
|
snprintf(cmd, sizeof(cmd), ":2 [S] <svc%s> "
|
||||||
"udevadm trigger -c add -t subsystems "
|
"udevadm trigger -c add -t subsystems "
|
||||||
"-- Requesting subsystem events", path);
|
"-- Requesting subsystem events", path);
|
||||||
service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);
|
service_register(SVC_TYPE_RUN, cmd, global_rlimit, "default", NULL);
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
} else {
|
} else {
|
||||||
@@ -483,7 +483,7 @@ int main(int argc, char* argv[])
|
|||||||
* Start bundled watchdogd as soon as possible, if enabled
|
* Start bundled watchdogd as soon as possible, if enabled
|
||||||
*/
|
*/
|
||||||
if (which(FINIT_LIBPATH_ "/watchdogd"))
|
if (which(FINIT_LIBPATH_ "/watchdogd"))
|
||||||
service_register(SVC_TYPE_SERVICE, FINIT_LIBPATH_ "/watchdogd", global_rlimit, NULL);
|
service_register(SVC_TYPE_SERVICE, FINIT_LIBPATH_ "/watchdogd", global_rlimit, "default", NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mount filesystems
|
* Mount filesystems
|
||||||
|
|||||||
+10
-2
@@ -186,7 +186,11 @@ static int service_start(svc_t *svc)
|
|||||||
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
cgroup_service(svc->cmd, pid);
|
|
||||||
|
if (pid > 0) {
|
||||||
|
cgroup_service(svc->cmd, pid);
|
||||||
|
cgroup_assign(svc->cgroup, pid);
|
||||||
|
}
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
int status;
|
int status;
|
||||||
@@ -626,6 +630,7 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
|||||||
* @type: %SVC_TYPE_SERVICE(0), %SVC_TYPE_TASK(1), %SVC_TYPE_RUN(2)
|
* @type: %SVC_TYPE_SERVICE(0), %SVC_TYPE_TASK(1), %SVC_TYPE_RUN(2)
|
||||||
* @cfg: Configuration, complete command, with -- for description text
|
* @cfg: Configuration, complete command, with -- for description text
|
||||||
* @rlimit: Limits for this service/task/run/inetd, may be global limits
|
* @rlimit: Limits for this service/task/run/inetd, may be global limits
|
||||||
|
* @cgroup: Control group, may be default
|
||||||
* @file: The file name service was loaded from
|
* @file: The file name service was loaded from
|
||||||
*
|
*
|
||||||
* This function is used to register commands to be run on different
|
* This function is used to register commands to be run on different
|
||||||
@@ -673,7 +678,7 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
|||||||
* Returns:
|
* Returns:
|
||||||
* POSIX OK(0) on success, or non-zero errno exit status on failure.
|
* POSIX OK(0) on success, or non-zero errno exit status on failure.
|
||||||
*/
|
*/
|
||||||
int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
int service_register(int type, char *cfg, struct rlimit rlimit[], char *cgroup, char *file)
|
||||||
{
|
{
|
||||||
char id_str[MAX_ID_LEN];
|
char id_str[MAX_ID_LEN];
|
||||||
#ifdef INETD_ENABLED
|
#ifdef INETD_ENABLED
|
||||||
@@ -912,6 +917,9 @@ recreate:
|
|||||||
/* Set configured limits */
|
/* Set configured limits */
|
||||||
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
|
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
|
||||||
|
|
||||||
|
/* Register desired control group */
|
||||||
|
strlcpy(svc->cgroup, cgroup, sizeof(svc->cgroup));
|
||||||
|
|
||||||
/* New, recently modified or unchanged ... used on reload. */
|
/* New, recently modified or unchanged ... used on reload. */
|
||||||
if (file && conf_changed(file))
|
if (file && conf_changed(file))
|
||||||
svc_mark_dirty(svc);
|
svc_mark_dirty(svc);
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@
|
|||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
|
|
||||||
void service_runlevel (int newlevel);
|
void service_runlevel (int newlevel);
|
||||||
int service_register (int type, char *line, struct rlimit rlimit[], char *file);
|
int service_register (int type, char *line, struct rlimit rlimit[], char *cgroup, char *file);
|
||||||
void service_unregister (svc_t *svc);
|
void service_unregister (svc_t *svc);
|
||||||
|
|
||||||
void service_runtask_clean (void);
|
void service_runtask_clean (void);
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ typedef struct svc {
|
|||||||
/* Limits and scoping */
|
/* Limits and scoping */
|
||||||
struct rlimit rlimit[RLIMIT_NLIMITS];
|
struct rlimit rlimit[RLIMIT_NLIMITS];
|
||||||
|
|
||||||
|
/* Control group */
|
||||||
|
char cgroup[32];
|
||||||
|
|
||||||
/* Service details */
|
/* Service details */
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char pidfile[MAX_ARG_LEN];
|
char pidfile[MAX_ARG_LEN];
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h" /* Generated by configure script */
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
|
#include "cgroup.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
@@ -100,6 +101,7 @@ void tty_sweep(void)
|
|||||||
* tty_register - Register a getty on a device
|
* tty_register - Register a getty on a device
|
||||||
* @line: Configuration, text after initial "tty"
|
* @line: Configuration, text after initial "tty"
|
||||||
* @rlimit: Limits for this service/task/run/inetd, may be global limits
|
* @rlimit: Limits for this service/task/run/inetd, may be global limits
|
||||||
|
* @cgroup: Control group, may be default
|
||||||
* @file: The file name TTY was loaded from
|
* @file: The file name TTY was loaded from
|
||||||
*
|
*
|
||||||
* A Finit tty line can use the internal getty implementation or an
|
* A Finit tty line can use the internal getty implementation or an
|
||||||
@@ -118,7 +120,7 @@ void tty_sweep(void)
|
|||||||
* Different getty implementations prefer the TTY device argument in
|
* Different getty implementations prefer the TTY device argument in
|
||||||
* different order, so take care to investigate this first.
|
* different order, so take care to investigate this first.
|
||||||
*/
|
*/
|
||||||
int tty_register(char *line, struct rlimit rlimit[], char *file)
|
int tty_register(char *line, struct rlimit rlimit[], char *cgroup, char *file)
|
||||||
{
|
{
|
||||||
struct tty *entry;
|
struct tty *entry;
|
||||||
size_t i, num = 0;
|
size_t i, num = 0;
|
||||||
@@ -274,6 +276,9 @@ again:
|
|||||||
/* Register configured limits */
|
/* Register configured limits */
|
||||||
memcpy(entry->rlimit, rlimit, sizeof(entry->rlimit));
|
memcpy(entry->rlimit, rlimit, sizeof(entry->rlimit));
|
||||||
|
|
||||||
|
/* Register desired control group */
|
||||||
|
strlcpy(entry->cgroup, cgroup, sizeof(entry->cgroup));
|
||||||
|
|
||||||
if (file && conf_changed(file))
|
if (file && conf_changed(file))
|
||||||
entry->dirty = 1; /* Modified, restart */
|
entry->dirty = 1; /* Modified, restart */
|
||||||
else
|
else
|
||||||
@@ -410,6 +415,8 @@ void tty_start(struct tty *tty)
|
|||||||
tty->pid = run_getty(dev, tty->baud, tty->term, tty->noclear, tty->nowait, tty->rlimit);
|
tty->pid = run_getty(dev, tty->baud, tty->term, tty->noclear, tty->nowait, tty->rlimit);
|
||||||
else
|
else
|
||||||
tty->pid = run_getty2(dev, tty->cmd, tty->args, tty->noclear, tty->nowait, tty->rlimit);
|
tty->pid = run_getty2(dev, tty->cmd, tty->args, tty->noclear, tty->nowait, tty->rlimit);
|
||||||
|
|
||||||
|
cgroup_assign(tty->cgroup, tty->pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_stop(struct tty *tty)
|
void tty_stop(struct tty *tty)
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ struct tty {
|
|||||||
/* Limits and scoping */
|
/* Limits and scoping */
|
||||||
struct rlimit rlimit[RLIMIT_NLIMITS];
|
struct rlimit rlimit[RLIMIT_NLIMITS];
|
||||||
|
|
||||||
|
/* Control group */
|
||||||
|
char cgroup[32];
|
||||||
|
|
||||||
/* Set if modified => reloaded, or -1 when marked for removal */
|
/* Set if modified => reloaded, or -1 when marked for removal */
|
||||||
int dirty;
|
int dirty;
|
||||||
};
|
};
|
||||||
@@ -58,7 +61,7 @@ struct tty {
|
|||||||
void tty_mark (void);
|
void tty_mark (void);
|
||||||
void tty_sweep (void);
|
void tty_sweep (void);
|
||||||
|
|
||||||
int tty_register (char *line, struct rlimit rlimit[], char *file);
|
int tty_register (char *line, struct rlimit rlimit[], char *cgroup, char *file);
|
||||||
int tty_unregister (struct tty *tty);
|
int tty_unregister (struct tty *tty);
|
||||||
|
|
||||||
struct tty *tty_find (char *dev);
|
struct tty *tty_find (char *dev);
|
||||||
|
|||||||
Reference in New Issue
Block a user