(config *specs.Process)
| 220 | } |
| 221 | |
| 222 | func (r *runner) run(config *specs.Process) (int, error) { |
| 223 | var err error |
| 224 | defer func() { |
| 225 | if err != nil { |
| 226 | r.destroy() |
| 227 | } |
| 228 | }() |
| 229 | if err = r.checkTerminal(config); err != nil { |
| 230 | return -1, err |
| 231 | } |
| 232 | process, err := newProcess(config) |
| 233 | if err != nil { |
| 234 | return -1, err |
| 235 | } |
| 236 | process.LogLevel = strconv.Itoa(int(logrus.GetLevel())) |
| 237 | // Populate the fields that come from runner. |
| 238 | process.Init = r.init |
| 239 | process.SubCgroupPaths = r.subCgroupPaths |
| 240 | if len(r.listenFDs) > 0 { |
| 241 | process.Env = append(process.Env, "LISTEN_FDS="+strconv.Itoa(len(r.listenFDs)), "LISTEN_PID=1") |
| 242 | process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...) |
| 243 | } |
| 244 | baseFd := 3 + len(process.ExtraFiles) |
| 245 | procSelfFd, closer, err := pathrs.ProcThreadSelfOpen("fd/", unix.O_DIRECTORY|unix.O_CLOEXEC) |
| 246 | if err != nil { |
| 247 | return -1, err |
| 248 | } |
| 249 | defer closer() |
| 250 | defer procSelfFd.Close() |
| 251 | for i := baseFd; i < baseFd+r.preserveFDs; i++ { |
| 252 | err := unix.Faccessat(int(procSelfFd.Fd()), strconv.Itoa(i), unix.F_OK, 0) |
| 253 | if err != nil { |
| 254 | return -1, fmt.Errorf("unable to stat preserved-fd %d (of %d): %w", i-baseFd, r.preserveFDs, err) |
| 255 | } |
| 256 | process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(i))) |
| 257 | } |
| 258 | detach := r.detach || (r.action == CT_ACT_CREATE) |
| 259 | // Setting up IO is a two stage process. We need to modify process to deal |
| 260 | // with detaching containers, and then we get a tty after the container has |
| 261 | // started. |
| 262 | handlerCh := newSignalHandler(r.enableSubreaper, r.notifySocket) |
| 263 | tty, err := setupIO(process, r.container, config.Terminal, detach, r.consoleSocket) |
| 264 | if err != nil { |
| 265 | return -1, err |
| 266 | } |
| 267 | defer tty.Close() |
| 268 | |
| 269 | if r.pidfdSocket != "" { |
| 270 | connClose, err := setupPidfdSocket(process, r.pidfdSocket) |
| 271 | if err != nil { |
| 272 | return -1, err |
| 273 | } |
| 274 | defer connClose() |
| 275 | } |
| 276 | |
| 277 | switch r.action { |
| 278 | case CT_ACT_CREATE: |
| 279 | err = r.container.Start(process) |
no test coverage detected