mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
exec: add ControlGroupModify= switch to allow changing access mode to cgroups fs
This commit is contained in:
parent
8585357a0e
commit
64747e2d4b
@ -629,6 +629,18 @@
|
||||
for details.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ControlGroupModify=</varname></term>
|
||||
<listitem><para>Takes a boolean
|
||||
argument. If true, the control groups
|
||||
created for this unit will be owned by
|
||||
ther user specified with
|
||||
<varname>User=</varname> (and the
|
||||
configured group), and he can create
|
||||
subgroups as well as add processes to
|
||||
the group.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>CapabilityBoundingSet=</varname></term>
|
||||
|
||||
|
44
src/cgroup.c
44
src/cgroup.c
@ -140,6 +140,50 @@ int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) {
|
||||
assert(b);
|
||||
|
||||
if (!b->realized)
|
||||
return -EINVAL;
|
||||
|
||||
return cg_set_group_access(b->controller, b->path, mode, uid, gid);
|
||||
}
|
||||
|
||||
int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) {
|
||||
CGroupBonding *b;
|
||||
int r;
|
||||
|
||||
LIST_FOREACH(by_unit, b, first) {
|
||||
r = cgroup_bonding_set_group_access(b, mode, uid, gid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) {
|
||||
assert(b);
|
||||
|
||||
if (!b->realized)
|
||||
return -EINVAL;
|
||||
|
||||
return cg_set_task_access(b->controller, b->path, mode, uid, gid);
|
||||
}
|
||||
|
||||
int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) {
|
||||
CGroupBonding *b;
|
||||
int r;
|
||||
|
||||
LIST_FOREACH(by_unit, b, first) {
|
||||
r = cgroup_bonding_set_task_access(b, mode, uid, gid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) {
|
||||
assert(b);
|
||||
assert(sig >= 0);
|
||||
|
@ -59,6 +59,12 @@ void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim);
|
||||
int cgroup_bonding_install(CGroupBonding *b, pid_t pid);
|
||||
int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid);
|
||||
|
||||
int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
|
||||
int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
|
||||
|
||||
int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
|
||||
int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
|
||||
|
||||
int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s);
|
||||
int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s);
|
||||
|
||||
|
@ -91,7 +91,8 @@
|
||||
" <property name=\"SameProcessGroup\" type=\"b\" access=\"read\"/>\n" \
|
||||
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
|
||||
" <property name=\"KillSignal\" type=\"i\" access=\"read\"/>\n" \
|
||||
" <property name=\"UtmpIdentifier\" type=\"s\" access=\"read\"/>\n"
|
||||
" <property name=\"UtmpIdentifier\" type=\"s\" access=\"read\"/>\n" \
|
||||
" <property name=\"ControlGroupModify\" type=\"b\" access=\"read\"/>\n"
|
||||
|
||||
#define BUS_EXEC_COMMAND_INTERFACE(name) \
|
||||
" <property name=\"" name "\" type=\"a(sasbttuii)\" access=\"read\"/>\n"
|
||||
@ -153,7 +154,8 @@
|
||||
{ interface, "SameProcessGroup", bus_property_append_bool, "b", &(context).same_pgrp }, \
|
||||
{ interface, "KillMode", bus_execute_append_kill_mode, "s", &(context).kill_mode }, \
|
||||
{ interface, "KillSignal", bus_property_append_int, "i", &(context).kill_signal }, \
|
||||
{ interface, "UtmpIdentifier", bus_property_append_string, "s", (context).utmp_id }
|
||||
{ interface, "UtmpIdentifier", bus_property_append_string, "s", (context).utmp_id }, \
|
||||
{ interface, "ControlGroupModify", bus_property_append_bool, "b", &(context).control_group_modify }
|
||||
|
||||
#define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix) \
|
||||
{ interface, prefix "StartTimestamp", bus_property_append_usec, "t", &(estatus).start_timestamp.realtime }, \
|
||||
|
@ -1246,6 +1246,13 @@ int exec_spawn(ExecCommand *command,
|
||||
r = EXIT_STDIN;
|
||||
goto fail_child;
|
||||
}
|
||||
|
||||
if (cgroup_bondings && context->control_group_modify)
|
||||
if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 ||
|
||||
cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) {
|
||||
r = EXIT_CGROUP;
|
||||
goto fail_child;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_PAM
|
||||
@ -1649,12 +1656,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
|
||||
"%sWorkingDirectory: %s\n"
|
||||
"%sRootDirectory: %s\n"
|
||||
"%sNonBlocking: %s\n"
|
||||
"%sPrivateTmp: %s\n",
|
||||
"%sPrivateTmp: %s\n"
|
||||
"%sControlGroupModify: %s\n",
|
||||
prefix, c->umask,
|
||||
prefix, c->working_directory ? c->working_directory : "/",
|
||||
prefix, c->root_directory ? c->root_directory : "/",
|
||||
prefix, yes_no(c->non_blocking),
|
||||
prefix, yes_no(c->private_tmp));
|
||||
prefix, yes_no(c->private_tmp),
|
||||
prefix, yes_no(c->control_group_modify));
|
||||
|
||||
STRV_FOREACH(e, c->environment)
|
||||
fprintf(f, "%sEnvironment: %s\n", prefix, *e);
|
||||
|
@ -160,6 +160,8 @@ struct ExecContext {
|
||||
bool non_blocking;
|
||||
bool private_tmp;
|
||||
|
||||
bool control_group_modify;
|
||||
|
||||
/* This is not exposed to the user but available
|
||||
* internally. We need it to make sure that whenever we spawn
|
||||
* /bin/mount it is run in the same process group as us so
|
||||
|
@ -1911,7 +1911,8 @@ static int load_from_path(Unit *u, const char *path) {
|
||||
{ "KillMode", config_parse_kill_mode, 0, &(context).kill_mode, section }, \
|
||||
{ "KillSignal", config_parse_kill_signal, 0, &(context).kill_signal, section }, \
|
||||
{ "SendSIGKILL", config_parse_bool, 0, &(context).send_sigkill, section }, \
|
||||
{ "UtmpIdentifier", config_parse_string_printf, 0, &(context).utmp_id, section }
|
||||
{ "UtmpIdentifier", config_parse_string_printf, 0, &(context).utmp_id, section }, \
|
||||
{ "ControlGroupModify", config_parse_bool, 0, &(context).control_group_modify, section }
|
||||
|
||||
const ConfigItem items[] = {
|
||||
{ "Names", config_parse_names, 0, u, "Unit" },
|
||||
|
Loading…
Reference in New Issue
Block a user