diff options
author | Fabricio Voznika <fvoznika@google.com> | 2018-09-27 15:00:03 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-09-27 15:00:58 -0700 |
commit | 491faac03b2815ca1bc9b5425c1b3f6291468e20 (patch) | |
tree | 0a8f0c1ad99c3d8660f36802132ecd9386c54518 /pkg/sentry/kernel | |
parent | 68ac2ad1e1f16e65d9d1318d6827edf8487578d0 (diff) |
Implement 'runsc kill --all'
In order to implement kill --all correctly, the Sentry needs
to track all tasks that belong to a given container. This change
introduces ContainerID to the task, that gets inherited by all
children. 'kill --all' then iterates over all tasks comparing the
ContainerID field to find all processes that need to be signalled.
PiperOrigin-RevId: 214841768
Change-Id: I693b2374be8692d88cc441ef13a0ae34abf73ac6
Diffstat (limited to 'pkg/sentry/kernel')
-rw-r--r-- | pkg/sentry/kernel/kernel.go | 25 | ||||
-rw-r--r-- | pkg/sentry/kernel/task.go | 12 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_clone.go | 1 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_start.go | 4 |
4 files changed, 42 insertions, 0 deletions
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index f71e32ac9..1ace0b501 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -524,6 +524,9 @@ type CreateProcessArgs struct { // Anyone setting Root must donate a reference (i.e. increment it) to // keep it alive until it is decremented by CreateProcess. Root *fs.Dirent + + // ContainerID is the container that the process belongs to. + ContainerID string } // NewContext returns a context.Context that represents the task that will be @@ -660,6 +663,7 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID, UTSNamespace: args.UTSNamespace, IPCNamespace: args.IPCNamespace, AbstractSocketNamespace: args.AbstractSocketNamespace, + ContainerID: args.ContainerID, } t, err := k.tasks.NewTask(config) if err != nil { @@ -818,6 +822,27 @@ func (k *Kernel) SendExternalSignal(info *arch.SignalInfo, context string) { k.sendExternalSignal(info, context) } +// SendContainerSignal sends the given signal to all processes inside the +// namespace that match the given container ID. +func (k *Kernel) SendContainerSignal(cid string, info *arch.SignalInfo) error { + k.extMu.Lock() + defer k.extMu.Unlock() + k.tasks.mu.RLock() + defer k.tasks.mu.RUnlock() + + for t := range k.tasks.Root.tids { + if t == t.tg.leader && t.ContainerID() == cid { + t.tg.signalHandlers.mu.Lock() + defer t.tg.signalHandlers.mu.Unlock() + infoCopy := *info + if err := t.sendSignalLocked(&infoCopy, true /*group*/); err != nil { + return err + } + } + } + return nil +} + // FeatureSet returns the FeatureSet. func (k *Kernel) FeatureSet() *cpuid.FeatureSet { return k.featureSet diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index 2f6f825ac..07ad1614c 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -205,6 +205,13 @@ type Task struct { // k is the Kernel that this task belongs to. The k pointer is immutable. k *Kernel + // containerID has no equivalent in Linux; it's used by runsc to track all + // tasks that belong to a given containers since cgroups aren't implemented. + // It's inherited by the children, is immutable, and may be empty. + // + // NOTE: cgroups can be used to track this when implemented. + containerID string + // mu protects some of the following fields. mu sync.Mutex `state:"nosave"` @@ -678,3 +685,8 @@ func (t *Task) MountNamespace() *fs.MountNamespace { func (t *Task) AbstractSockets() *AbstractSocketNamespace { return t.abstractSockets } + +// ContainerID returns t's container ID. +func (t *Task) ContainerID() string { + return t.containerID +} diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index 46c688b20..130bd652b 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -258,6 +258,7 @@ func (t *Task) Clone(opts *CloneOptions) (ThreadID, *SyscallControl, error) { UTSNamespace: utsns, IPCNamespace: ipcns, AbstractSocketNamespace: t.abstractSockets, + ContainerID: t.ContainerID(), } if opts.NewThreadGroup { cfg.Parent = t diff --git a/pkg/sentry/kernel/task_start.go b/pkg/sentry/kernel/task_start.go index 6ce99d268..6c8d7d316 100644 --- a/pkg/sentry/kernel/task_start.go +++ b/pkg/sentry/kernel/task_start.go @@ -77,6 +77,9 @@ type TaskConfig struct { // AbstractSocketNamespace is the AbstractSocketNamespace of the new task. AbstractSocketNamespace *AbstractSocketNamespace + + // ContainerID is the container the new task belongs to. + ContainerID string } // NewTask creates a new task defined by cfg. @@ -124,6 +127,7 @@ func (ts *TaskSet) newTask(cfg *TaskConfig) (*Task, error) { abstractSockets: cfg.AbstractSocketNamespace, rseqCPU: -1, futexWaiter: futex.NewWaiter(), + containerID: cfg.ContainerID, } t.endStopCond.L = &t.tg.signalHandlers.mu t.ptraceTracer.Store((*Task)(nil)) |