newTask is a helper for TaskSet.NewTask that only takes ownership of parts of cfg if it succeeds.
(ctx context.Context, cfg *TaskConfig)
| 174 | // newTask is a helper for TaskSet.NewTask that only takes ownership of parts |
| 175 | // of cfg if it succeeds. |
| 176 | func (ts *TaskSet) newTask(ctx context.Context, cfg *TaskConfig) (*Task, int32, error) { |
| 177 | srcT := TaskFromContext(ctx) |
| 178 | tg := cfg.ThreadGroup |
| 179 | image := cfg.TaskImage |
| 180 | t := &Task{ |
| 181 | taskNode: taskNode{ |
| 182 | tg: tg, |
| 183 | parent: cfg.Parent, |
| 184 | children: make(map[*Task]struct{}), |
| 185 | }, |
| 186 | runState: (*runApp)(nil), |
| 187 | interruptChan: make(chan struct{}, 1), |
| 188 | signalMask: atomicbitops.FromUint64(uint64(cfg.SignalMask)), |
| 189 | signalStack: linux.SignalStack{Flags: linux.SS_DISABLE}, |
| 190 | image: *image, |
| 191 | fdTable: cfg.FDTable, |
| 192 | k: cfg.Kernel, |
| 193 | ptraceTracees: make(map[*Task]struct{}), |
| 194 | allowedCPUMask: cfg.AllowedCPUMask.Copy(), |
| 195 | ioUsage: &usage.IO{}, |
| 196 | niceness: cfg.Niceness, |
| 197 | utsns: cfg.UTSNamespace, |
| 198 | ipcns: cfg.IPCNamespace, |
| 199 | mountNamespace: cfg.MountNamespace, |
| 200 | rseqCPU: -1, |
| 201 | rseqAddr: cfg.RSeqAddr, |
| 202 | rseqSignature: cfg.RSeqSignature, |
| 203 | futexWaiter: futex.NewWaiter(), |
| 204 | containerID: cfg.ContainerID, |
| 205 | cgroups: make(map[Cgroup]struct{}), |
| 206 | userCounters: cfg.UserCounters, |
| 207 | sessionKeyring: cfg.SessionKeyring, |
| 208 | personality: atomicbitops.FromUint32(cfg.Personality), |
| 209 | Origin: cfg.Origin, |
| 210 | onDestroyAction: make(map[TaskDestroyAction]struct{}), |
| 211 | noNewPrivs: cfg.NoNewPrivs, |
| 212 | } |
| 213 | t.netns = cfg.NetworkNamespace |
| 214 | t.creds.Store(cfg.Credentials) |
| 215 | t.fsContext.Store(cfg.FSContext) |
| 216 | t.endStopCond.L = &t.tg.signalHandlers.mu |
| 217 | // We don't construct t.blockingTimer until Task.run(); see that function |
| 218 | // for justification. |
| 219 | |
| 220 | var cu cleanup.Cleanup |
| 221 | defer cu.Clean() |
| 222 | |
| 223 | pidFD := int32(-1) |
| 224 | |
| 225 | if cfg.pidFDMode != dontMakePIDFD { |
| 226 | isThread := cfg.pidFDMode == makeThreadedPIDFD |
| 227 | t.pid = &pid{} |
| 228 | t.pid.t.Store(t) |
| 229 | |
| 230 | vfsfd, err := srcT.pidFDOpen(t.pid, isThread, false /*nonblock*/) |
| 231 | if err != nil { |
| 232 | return nil, -1, err |
| 233 | } |
no test coverage detected