mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
cgroup: allow a cgroup subsystem to reject a fork
Add a new cgroup subsystem callback can_fork that conditionally states whether or not the fork is accepted or rejected by a cgroup policy. In addition, add a cancel_fork callback so that if an error occurs later in the forking process, any state modified by can_fork can be reverted. Allow for a private opaque pointer to be passed from cgroup_can_fork to cgroup_post_fork, allowing for the fork state to be stored by each subsystem separately. Also add a tagging system for cgroup_subsys.h to allow for CGROUP_<TAG> enumerations to be be defined and used. In addition, explicitly add a CGROUP_CANFORK_COUNT macro to make arrays easier to define. This is in preparation for implementing the pids cgroup subsystem. Signed-off-by: Aleksa Sarai <cyphar@cyphar.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
d770e558e2
commit
7e47682ea5
7 changed files with 133 additions and 9 deletions
|
@ -1239,6 +1239,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|||
{
|
||||
int retval;
|
||||
struct task_struct *p;
|
||||
void *cgrp_ss_priv[CGROUP_CANFORK_COUNT] = {};
|
||||
|
||||
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -1512,6 +1513,16 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|||
INIT_LIST_HEAD(&p->thread_group);
|
||||
p->task_works = NULL;
|
||||
|
||||
/*
|
||||
* Ensure that the cgroup subsystem policies allow the new process to be
|
||||
* forked. It should be noted the the new process's css_set can be changed
|
||||
* between here and cgroup_post_fork() if an organisation operation is in
|
||||
* progress.
|
||||
*/
|
||||
retval = cgroup_can_fork(p, cgrp_ss_priv);
|
||||
if (retval)
|
||||
goto bad_fork_free_pid;
|
||||
|
||||
/*
|
||||
* Make it visible to the rest of the system, but dont wake it up yet.
|
||||
* Need tasklist lock for parent etc handling!
|
||||
|
@ -1548,7 +1559,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|||
spin_unlock(¤t->sighand->siglock);
|
||||
write_unlock_irq(&tasklist_lock);
|
||||
retval = -ERESTARTNOINTR;
|
||||
goto bad_fork_free_pid;
|
||||
goto bad_fork_cancel_cgroup;
|
||||
}
|
||||
|
||||
if (likely(p->pid)) {
|
||||
|
@ -1590,7 +1601,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|||
write_unlock_irq(&tasklist_lock);
|
||||
|
||||
proc_fork_connector(p);
|
||||
cgroup_post_fork(p);
|
||||
cgroup_post_fork(p, cgrp_ss_priv);
|
||||
if (clone_flags & CLONE_THREAD)
|
||||
threadgroup_change_end(current);
|
||||
perf_event_fork(p);
|
||||
|
@ -1600,6 +1611,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|||
|
||||
return p;
|
||||
|
||||
bad_fork_cancel_cgroup:
|
||||
cgroup_cancel_fork(p, cgrp_ss_priv);
|
||||
bad_fork_free_pid:
|
||||
if (pid != &init_struct_pid)
|
||||
free_pid(pid);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue