execSetns runs the process that executes C code to perform the setns calls because setns support requires the C process to fork off a child and perform the setns before the go runtime boots, we wait on the process to die and receive the child's pid over the provided pipe.
()
| 596 | // before the go runtime boots, we wait on the process to die and receive the child's pid |
| 597 | // over the provided pipe. |
| 598 | func (p *setnsProcess) execSetns() error { |
| 599 | status, err := p.cmd.Process.Wait() |
| 600 | if err != nil { |
| 601 | _ = p.cmd.Wait() |
| 602 | return fmt.Errorf("error waiting on setns process to finish: %w", err) |
| 603 | } |
| 604 | if !status.Success() { |
| 605 | _ = p.cmd.Wait() |
| 606 | return &exec.ExitError{ProcessState: status} |
| 607 | } |
| 608 | var pid *pid |
| 609 | if err := json.NewDecoder(p.comm.initSockParent).Decode(&pid); err != nil { |
| 610 | _ = p.cmd.Wait() |
| 611 | return fmt.Errorf("error reading pid from init pipe: %w", err) |
| 612 | } |
| 613 | |
| 614 | // Clean up the zombie parent process |
| 615 | // On Unix systems FindProcess always succeeds. |
| 616 | firstChildProcess, _ := os.FindProcess(pid.PidFirstChild) |
| 617 | |
| 618 | // Ignore the error in case the child has already been reaped for any reason |
| 619 | _, _ = firstChildProcess.Wait() |
| 620 | |
| 621 | process, err := os.FindProcess(pid.Pid) |
| 622 | if err != nil { |
| 623 | return err |
| 624 | } |
| 625 | p.cmd.Process = process |
| 626 | p.process.ops = p |
| 627 | return nil |
| 628 | } |
| 629 | |
| 630 | type initProcess struct { |
| 631 | containerProcess |