run.go#Action

前面代码和create都一样,只是在调用runner#run时传入的操作类型为run。

  1. case CT_ACT_CREATE:
  2. err = r.container.Start(process)
  3. case CT_ACT_RESTORE:
  4. err = r.container.Restore(process, r.criuOpts)
  5. case CT_ACT_RUN:
  6. err = r.container.Run(process)

1) libcontainer/container_linux.go#linuxContainer.Run

  1. BaseContainer
  2. // Start a process inside the container. Returns error if process fails to
  3. // start. You can track process lifecycle with passed Process structure.
  4. //
  5. // errors:
  6. // ContainerNotExists - Container no longer exists,
  7. // ConfigInvalid - config is invalid,
  8. // ContainerPaused - Container is paused,
  9. // SystemError - System error.
  10. Start(process *Process) (err error)
  11. // Run immediately starts the process inside the container. Returns error if process
  12. // fails to start. It does not block waiting for the exec fifo after start returns but
  13. // opens the fifo after start returns.
  14. //
  15. // errors:
  16. // ContainerNotExists - Container no longer exists,
  17. // ConfigInvalid - config is invalid,
  18. // ContainerPaused - Container is paused,
  19. // SystemError - System error.
  20. Run(process *Process) (err error)

不涉及exec.fifo文件的创建与删除。

  • 在Container.Start【容器CREATE】时,会在容器启动前创建exec.fifo,在容器启动完毕后删除exec.fifo,因为Start时不执行真正的命令,所以需要使用exec.fifo阻塞。
  • 在容器【START】时也会使用这个文件,只读方式打开该文件,向容器Init进程发送信号,执行真正的命令。
  • 在容器【RUN,即CREATE+START】时,会先执行【容器CREATE】操作,然后执行【容器RUN】操作。
    1. func (c *linuxContainer) Run(process *Process) error {
    2. if err := c.Start(process); err != nil {
    3. return err
    4. }
    5. if process.Init {
    6. return c.exec()
    7. }
    8. return nil
    9. }