()
| 775 | } |
| 776 | |
| 777 | func (p *initProcess) start() (retErr error) { |
| 778 | defer p.comm.closeParent() |
| 779 | err := p.cmd.Start() |
| 780 | p.process.ops = p |
| 781 | // close the child-side of the pipes (controlled by child) |
| 782 | p.comm.closeChild() |
| 783 | if err != nil { |
| 784 | p.process.ops = nil |
| 785 | return fmt.Errorf("unable to start init: %w", err) |
| 786 | } |
| 787 | |
| 788 | defer func() { |
| 789 | if retErr != nil { |
| 790 | // Find out if init is killed by the kernel's OOM killer. |
| 791 | // Get the count before killing init as otherwise cgroup |
| 792 | // might be removed by systemd. |
| 793 | oom, err := p.manager.OOMKillCount() |
| 794 | if err != nil { |
| 795 | logrus.WithError(err).Warn("unable to get oom kill count") |
| 796 | } else if oom > 0 { |
| 797 | // Does not matter what the particular error was, |
| 798 | // its cause is most probably OOM, so report that. |
| 799 | const oomError = "container init was OOM-killed (memory limit too low?)" |
| 800 | |
| 801 | if logrus.GetLevel() >= logrus.DebugLevel { |
| 802 | // Only show the original error if debug is set, |
| 803 | // as it is not generally very useful. |
| 804 | retErr = fmt.Errorf(oomError+": %w", retErr) |
| 805 | } else { |
| 806 | retErr = errors.New(oomError) |
| 807 | } |
| 808 | } |
| 809 | |
| 810 | // Terminate the process to ensure we can remove cgroups. |
| 811 | if err := ignoreTerminateErrors(p.terminate()); err != nil { |
| 812 | logrus.WithError(err).Warn("unable to terminate initProcess") |
| 813 | } |
| 814 | |
| 815 | _ = p.manager.Destroy() |
| 816 | if p.intelRdtManager != nil { |
| 817 | _ = p.intelRdtManager.Destroy() |
| 818 | } |
| 819 | } |
| 820 | }() |
| 821 | |
| 822 | // Do this before syncing with child so that no children can escape the |
| 823 | // cgroup. We don't need to worry about not doing this and not being root |
| 824 | // because we'd be using the rootless cgroup manager in that case. |
| 825 | if err := p.manager.Apply(p.pid()); err != nil { |
| 826 | if errors.Is(err, cgroups.ErrRootless) { |
| 827 | // ErrRootless is to be ignored except when |
| 828 | // the container doesn't have private pidns. |
| 829 | if !p.config.Config.Namespaces.IsPrivate(configs.NEWPID) { |
| 830 | // TODO: make this an error in runc 1.3. |
| 831 | logrus.Warn("Creating a rootless container with no cgroup and no private pid namespace. " + |
| 832 | "Such configuration is strongly discouraged (as it is impossible to properly kill all container's processes) " + |
| 833 | "and will result in an error in a future runc version.") |
| 834 | } |
nothing calls this directly
no test coverage detected