kata + docker run & star

 

 

 

func (r *runner) run(config *specs.Process) (int, error) {
    if err := r.checkTerminal(config); err != nil {
        r.destroy()
        return -1, err
    }
    process, err := newProcess(*config)
    if err != nil {
        r.destroy()
        return -1, err
    }
    if len(r.listenFDs) > 0 {
        process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(r.listenFDs)), "LISTEN_PID=1")
        process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...)
    }
    baseFd := 3 + len(process.ExtraFiles)
    for i := baseFd; i < baseFd+r.preserveFDs; i++ {
        process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(i)))
    }
    rootuid, err := r.container.Config().HostRootUID()
    if err != nil {
        r.destroy()
        return -1, err
    }
    rootgid, err := r.container.Config().HostRootGID()
    if err != nil {
        r.destroy()
        return -1, err
    }
    var (
        detach = r.detach || (r.action == CT_ACT_CREATE)
    )
    // Setting up IO is a two stage process. We need to modify process to deal
    // with detaching containers, and then we get a tty after the container has
    // started.
    handler := newSignalHandler(r.enableSubreaper, r.notifySocket)
    tty, err := setupIO(process, rootuid, rootgid, config.Terminal, detach, r.consoleSocket)
    if err != nil {
        r.destroy()
        return -1, err
    }
    defer tty.Close()
    switch r.action {
    case CT_ACT_CREATE:
        err = r.container.Start(process)
    case CT_ACT_RESTORE:
        err = r.container.Restore(process, r.criuOpts)
    case CT_ACT_RUN:
        err = r.container.Run(process)
    default:
        panic("Unknown action")
    }
    if err != nil {
        r.destroy()
        return -1, err
    }
    if err := tty.waitConsole(); err != nil {
        r.terminate(process)
        r.destroy()
        return -1, err
    }
    if err = tty.ClosePostStart(); err != nil {
        r.terminate(process)
        r.destroy()
        return -1, err
    }
    if r.pidFile != "" {
        if err = createPidFile(r.pidFile, process); err != nil {
            r.terminate(process)
            r.destroy()
            return -1, err
        }
    }
    status, err := handler.forward(process, tty, detach)
    if err != nil {
        r.terminate(process)
    }
    if detach {
        return 0, nil
    }
    r.destroy()
    return status, err
}

 

 

func (c *linuxContainer) Start(process *Process) error {
        c.m.Lock()
        defer c.m.Unlock()
        if process.Init {
                if err := c.createExecFifo(); err != nil {
                        return err
                }
        }
        if err := c.start(process); err != nil {
                if process.Init {
                        c.deleteExecFifo()
                }
                return err
        }
        return nil
}

func (c *linuxContainer) Run(process *Process) error {
        if err := c.Start(process); err != nil {
                return err
        }
        if process.Init {
                return c.exec()
        }
        return nil
}

 

 

func (s *sandbox) getContainer(id string) (*container, error)

 ctr, err := a.sandbox.getContainer(req.ContainerId)

// Shared function between CreateContainer and ExecProcess, because those expect
// a process to be run.
func (a *agentGRPC) execProcess(ctr *container, proc *process, createContainer bool) (err error) {
        if ctr == nil {
                return grpcStatus.Error(codes.InvalidArgument, "Container cannot be nil")
        }

        if proc == nil {
                return grpcStatus.Error(codes.InvalidArgument, "Process cannot be nil")
        }

        // This lock is very important to avoid any race with reaper.reap().
        // Indeed, if we don't lock this here, we could potentially get the
        // SIGCHLD signal before the channel has been created, meaning we will
        // miss the opportunity to get the exit code, leading WaitProcess() to
        // wait forever on the new channel.
        // This lock has to be taken before we run the new process.
        a.sandbox.subreaper.lock()
        defer a.sandbox.subreaper.unlock()

        if createContainer {
                err = ctr.container.Start(&proc.process)
        } else {
                err = ctr.container.Run(&(proc.process))
        }
        if err != nil {
                return grpcStatus.Errorf(codes.Internal, "Could not run process: %v", err)
        }

        // Get process PID
        pid, err := proc.process.Pid()
        if err != nil {
                return err
        }

        proc.exitCodeCh = make(chan int, 1)

        // Create process channel to allow WaitProcess to wait on it.
        // This channel is buffered so that reaper.reap() will not
        // block until WaitProcess listen onto this channel.
        a.sandbox.subreaper.setExitCodeCh(pid, proc.exitCodeCh)

        return nil
}

 

posted on 2020-11-24 20:34  tycoon3  阅读(222)  评论(0编辑  收藏  举报

导航