mirror of
https://github.com/troglobit/finit.git
synced 2026-10-24 11:54:36 +00:00
conf: make cgroup delegate and leaf name first-class keys
parse_cgroup() takes two arguments that are not cgroupfs files: the
leaf directory to place the service in, and whether to hand the subtree
over to it. The block format could express neither. 'name' happened
to work, because a free-form key is emitted as name:VALUE and that is
what the parser looks for, but 'delegate' came out as delegate:true and
was filed as a cgroup setting, so it silently did nothing.
Declare both, and emit delegate as the bare flag the parser expects.
Neither means anything on a top-level group definition, so say so there
rather than emitting something that would be written to cgroupfs.
service podman {
cgroup containers { name = "podman" delegate = true }
...
}
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
2 files changed
+46
-3
No files matched your search
+29
-3
@@ -136,6 +136,14 @@ static TAILQ_HEAD(, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_
|
|||||||
* cfg_error_cb() buffers it and only a failed parse is reported.
|
* cfg_error_cb() buffers it and only a failed parse is reported.
|
||||||
*/
|
*/
|
||||||
static cfg_opt_t cgroup_opts[] = {
|
static cfg_opt_t cgroup_opts[] = {
|
||||||
|
/*
|
||||||
|
* Not cgroupfs files but arguments to parse_cgroup(): the leaf
|
||||||
|
* directory to place the service in, and whether to hand the
|
||||||
|
* subtree over to it. Only meaningful inside a service block.
|
||||||
|
*/
|
||||||
|
CFG_STR ("name", NULL, CFGF_NODEFAULT),
|
||||||
|
CFG_BOOL("delegate", cfg_false, CFGF_NODEFAULT),
|
||||||
|
|
||||||
CFG_STR("cpu.weight", NULL, CFGF_NODEFAULT),
|
CFG_STR("cpu.weight", NULL, CFGF_NODEFAULT),
|
||||||
CFG_STR("cpu.weight.nice", NULL, CFGF_NODEFAULT),
|
CFG_STR("cpu.weight.nice", NULL, CFGF_NODEFAULT),
|
||||||
CFG_STR("cpu.max", NULL, CFGF_NODEFAULT),
|
CFG_STR("cpu.max", NULL, CFGF_NODEFAULT),
|
||||||
@@ -1079,11 +1087,27 @@ static void addopt(char *line, size_t len, const char *opt, const char *val)
|
|||||||
* cgroup NAME { key = val ... } -> "NAME" + "key:val,key:val"
|
* cgroup NAME { key = val ... } -> "NAME" + "key:val,key:val"
|
||||||
* Free-form (KEYSTRVAL) and declared options enumerate the same way.
|
* Free-form (KEYSTRVAL) and declared options enumerate the same way.
|
||||||
*/
|
*/
|
||||||
static char *cgroup_settings(cfg_t *cg, char *buf, size_t len)
|
static char *cgroup_settings(cfg_t *cg, char *buf, size_t len, char *file, int svc)
|
||||||
{
|
{
|
||||||
cfg_opt_t *opt;
|
cfg_opt_t *opt;
|
||||||
|
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* delegate is a flag, so it carries no value, and a top-level
|
||||||
|
* group has nothing to delegate to.
|
||||||
|
*/
|
||||||
|
if (cfg_size(cg, "delegate")) {
|
||||||
|
if (!svc)
|
||||||
|
logit(LOG_WARNING, "%s: cgroup %s: delegate only applies"
|
||||||
|
" inside a service, ignoring", file, cfg_title(cg));
|
||||||
|
else if (cfg_getbool(cg, "delegate") == cfg_true)
|
||||||
|
strlcat(buf, "delegate", len);
|
||||||
|
}
|
||||||
|
if (!svc && cfg_size(cg, "name"))
|
||||||
|
logit(LOG_WARNING, "%s: cgroup %s: name only applies inside a"
|
||||||
|
" service, ignoring", file, cfg_title(cg));
|
||||||
|
|
||||||
for (opt = cg->opts; opt && opt->name; opt++) {
|
for (opt = cg->opts; opt && opt->name; opt++) {
|
||||||
const char *val;
|
const char *val;
|
||||||
|
|
||||||
@@ -1093,6 +1117,8 @@ static char *cgroup_settings(cfg_t *cg, char *buf, size_t len)
|
|||||||
val = cfg_opt_getnstr(opt, 0);
|
val = cfg_opt_getnstr(opt, 0);
|
||||||
if (!val)
|
if (!val)
|
||||||
continue;
|
continue;
|
||||||
|
if (!svc && !strcmp(opt->name, "name"))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (buf[0])
|
if (buf[0])
|
||||||
strlcat(buf, ",", len);
|
strlcat(buf, ",", len);
|
||||||
@@ -1394,7 +1420,7 @@ static void svc_translate(cfg_t *sec, int type, struct rlimit rlimit[], char *fi
|
|||||||
" using '%s'", file, cfg_title(sec), cnt,
|
" using '%s'", file, cfg_title(sec), cnt,
|
||||||
cfg_title(cg));
|
cfg_title(cg));
|
||||||
|
|
||||||
cgroup_settings(cg, buf, sizeof(buf));
|
cgroup_settings(cg, buf, sizeof(buf), file, 1);
|
||||||
if (buf[0])
|
if (buf[0])
|
||||||
addtok(line, sizeof(line), "cgroup.%s,%s", cfg_title(cg), buf);
|
addtok(line, sizeof(line), "cgroup.%s,%s", cfg_title(cg), buf);
|
||||||
else
|
else
|
||||||
@@ -1666,7 +1692,7 @@ static int conf_parse_cfg(cfg_t *cfg, char *file, int is_rcsd)
|
|||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
||||||
cgroup_add((char *)cfg_title(cg),
|
cgroup_add((char *)cfg_title(cg),
|
||||||
cgroup_settings(cg, buf, sizeof(buf)), 0);
|
cgroup_settings(cg, buf, sizeof(buf), file, 0), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* file-scope resource limits, applies to all services in file */
|
/* file-scope resource limits, applies to all services in file */
|
||||||
|
|||||||
@@ -257,3 +257,20 @@ for key in manual-start manual; do
|
|||||||
run "initctl stop service.sh"
|
run "initctl stop service.sh"
|
||||||
retry 'assert_num_children 0 service.sh'
|
retry 'assert_num_children 0 service.sh'
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# delegate is a flag to parse_cgroup(), not a cgroupfs file, and the
|
||||||
|
# cgroup leaf name is an argument too. Both must come out of the
|
||||||
|
# translator in the comma-separated form that parser expects.
|
||||||
|
say 'cgroup delegate and name translate as parse_cgroup arguments'
|
||||||
|
run "echo 'service service.sh {' > $FINIT_CONF"
|
||||||
|
run "echo ' description = \"Delegated\"' >> $FINIT_CONF"
|
||||||
|
run "echo ' cgroup system {' >> $FINIT_CONF"
|
||||||
|
run "echo ' name = \"mysvc\"' >> $FINIT_CONF"
|
||||||
|
run "echo ' delegate = true' >> $FINIT_CONF"
|
||||||
|
run "echo ' cpu.weight = 250' >> $FINIT_CONF"
|
||||||
|
run "echo ' }' >> $FINIT_CONF"
|
||||||
|
run "echo ' command = \"service.sh\"' >> $FINIT_CONF"
|
||||||
|
run "echo '}' >> $FINIT_CONF"
|
||||||
|
run "initctl reload"
|
||||||
|
|
||||||
|
retry 'assert_desc "Delegated" service.sh'
|
||||||
Reference in new issue
Block a user