• runc kill 和 delete流程分析


    runc kill

    // kill sends the specified signal (default: SIGTERM) to the container's init process

    1、runc/kill.go

    Action: func(context *cli.Context) error

    首先和大多数命令类似,调用container, err := getContainer(context)获取容器实例。之后再调用sigstr := context.Args().Get(1)和signal, err := parseSignal(sigstr)获取信号,最后调用container.Signal(signal)将信号传递给容器的init process。

    2、runc/libcontainer/container_linux.go

    func (c *linuxContainer) Signal(s os.Signal) error

    这个函数很简单,直接调用c.initProcess.signal(s)

    3、runc/libcontainer/process_linux.go

    func (p *initProcess) signal(sig os.Signal)

    这个函数也很简单,直接调用syscall.Kill(p.pid(), s)即可

    runc delete

    // delete any resources held by one container or more containers often used with detached containers

    1、runc/delete.go

    Action: func(context *cli.Context) error

    首先调用factory, err := factory.Args().Present()获取工厂实例,因为runc delete后面可以添加多个容器id,因此我们需要遍历参数,对每个容器进行操作。对于每个容器,我们先调用container, err := factory.Load(id)获取容器实例。当err不为nil且err为libcontainer.Error的时候,说明这是一个启动过程中abort的容器,它的容器目录依旧存在,但是因为没有state.json文件,所以我们并不能看到它。这时,我们只需要将它的容器目录删除即可。若为正常的容器,那么我们先调用s, err := container.Status获取容器的状态,接着根据状态的不同,分别进行操作:

    (1)、若s为libcontainer.Stopped时,调用destroy(container)即可

    (2)、若s为libcontainer.Created时,则调用killContainer(container)

    (3)、若为其他情况,当force被置位时,则调用killContainer(container),否则报错

    2、runc/delete.go

    func killContainer(container libcontainer.Container) error

    首先调用container.Signal(syscall.SIGKILL)给容器的init进程发送KILL信号,接着再进入一个for循环,不断调用container.Signal(syscall.Signal(0)),测试容器是否还活着,当确认容器已经stop的时候, 调用destroy(container)。注:一般用给一个进程发送signal 0,来检测进程是否存在

    3、runc/utils_linux.go

    func destory(container libcontainer.Container)

    这个函数很简单,直接调用container.Destory()

    4、runc/libcontainer/container_linux.go

    该函数先调用c.m.Lock()上个锁,接着调用return c.state.destroy()

    5、runc/libcontainer/state_linux.go

    如果c.config.Namespaces.Contains(configs.NEWPID)为false的话,则调用killCgroupProcesses(c.cgroupManager)。接着调用c.cgroupManager.Destroy()摧毁容器的cgroup。接着设置c.initProcess = nil, 然后调用runPoststopHooks(c),最后设置c.state为&stoppedState{c: c}

  • 相关阅读:
    【转】linux清屏的几种方法
    【转】Ubuntu 64位系统安装交叉编译环境一直提醒 没有那个文件或目录
    【转】无法获得锁 /var/lib/dpkg/lock
    层级原理图设计方法
    【转】gcc 编译使用动态链接库和静态链接库
    【转】设置 vim 显示行号永久有效
    【转】VMware 全屏显示
    emwin之自绘制 BUTTON 图形的一些问题
    使用 sizeof 获取字符串数组的大小
    emwin之2D图形流位图显示的方法
  • 原文地址:https://www.cnblogs.com/YaoDD/p/5981393.html
Copyright © 2020-2023  润新知