runc的detach, console, tty等相关问题
runc 端解析:
1、 runc/utils_linux.go
func (r *runner) run(config *specs.Process) (int , error)
在该函数中第一次对容器的IO进行了处理,首先调用tty, err := setupIO(process, rootuid, rootgid, r.console, config.Terminal, r.detach, || r.create),创建并返回了一个结构tty,tty的具体类型如下所示:
type tty struct {
console libcontainer.Console
state *term.State
closers []io.Closer
postStart []io.Closer
wg sync.WaitGroup
}
之后又有handler := newSignalHandler(tty, r.enableSubreaper)以及tty.ClosePostStart(), status, err := handler.forward(process)对tty进行处理(主要是针对winsize)。同时,我们可以发现在handler.forward函数之前有对r.detach进行判断,若r.detach为true则直接返回了。
2、runc/utils_linux.go
// setupIO sets the proper IO on the process depending on the configuration
// detach and createTTy will not work unless a console path is passed --->即detach 和createTty不能同时为true,除非console不为空
func setupIO(process *libcontainer.Process, rootuid, rootgid int, console string, createTTY, detach bool) (*tty, error)
(1)当createTTy为true时,调用 return createTty(process, rootuid, rootgid, console) ---> 要求tty,则优先创建tty
(2)当detach为true时,调用dupStdio(process, rootuid, rootgid), 最后再返回一个空的tty, return &tty{}
(3)当createTTy和detach都为false时,则return createStdioPipes(process, rootuid, rootgid)
------------------------------------------------------------ tty方式 ----------------------------------------------------
3、runc/tty.go
func createTty(p *libcontainer.Process, rootuid, rootgid int, consolePath string) (*tty, error)
(1)当用户指定了consolePath的时候,则直接调用p.consoleFromPath(consolePath),再返回一个空的tty, return &tty{}
(2)当用户未指定consolePath时,则调用console, err := p.NewConsole(rootuid, rootgid)创建一个新的console,并且将标准输入输出与console相连。接着调用state, err := term.SetRawTerminal(os.Stdin.Fd())函数将标准输入设置为raw mode。最后返回:
return &tty {
console: console,
state: state,
closers: []io.Closer{
console,
},
}
4、runc/libcontainer/process.go
// ConsoleFromPath sets the process's console with the path provided
func (p *Process) ConsoleFromPath(path string) error
仅仅只是将path赋值给p.consolePath
5、runc/libcontainer/console_linux.go
// NewConsole returns an initialized console that can be used within a container by copying bytes
// from the master side to the slave that is attached as the tty for the container's init process
func NewConsole(uid, gid int) (Console, error)
首先调用master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR | syscall.O_NOCTTY|syscall.O_CLOEXEC, 0),打开主设备,接着调用console, err := ptsname(master)获取从设备的设备名,之后再对主从设备进行一系列的操作。最后,return &linuxConsole{ slavePath: console, master: master}
------------------------------------------------------------------------ detach 模式---------------------------------------------------------------
6、runc/utils_linux.go
func dupStdio(process *libcontainer.Process, rootuid, rootgid int) error
该函数的操作很简单,就是直接将标准IO,os.Stdin, os.Stdout, os.Stderr和process的Stdin, Stdout, Stderr相连,然后改变这几个文件描述符的uid和gid即可。
--------------------------------------------------------------------------- 不分配terminal,不detach ------------------------------------------
7、runc/tty.go
// setup standard pipes so that the TTY of the calling runc process is not inherited by the container
func createStdioPipes(p *libcontainer.Process, rootuid, rootuid int) (*tty, error)
首先调用i, err := p.InitializeIO(rootuid, rootgid),其中函数InitializeIO函数做的工作其实就是创建了三个管道,并将一端连接process的STDIO,再将另一端返回给i。接着对tty 结构进行填充,主要将STDIO赋值给tty.Closers和tty.postStart。最后将i和os.StdIO相连。
容器内解析:
1、runc/libcontainer/standard_init_linux.go
func (l *linuxStandardInit) Init() error
该函数先判断从runc端传来的配置中l.config.Console是否为空,如果不为空,则调用console = newConsoleFromPath(l.config.Console),获取一个linuxConsole的实例,其中只将slavePath字段设置为l.config.Console。之后,再调用console.dupStdio(),在dupStdio中打开SlaveConsole文件,并且将fds 复制到当前进程的stdio。如果console不为空,则调用system.Setctty()。在Setctty()中,只是简单地调用了函数,syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0)
2、runc/libcontainer/console_linux.go
// newConsoleFromPath is an internal function returning an initialized console for use inside a container's MNT namespace
func newConsoleFromPath(slavePath) *linuxConsole
只是简单地返回 return &linuxConsole{ slavePath: slavePath}
3、 runc/libcontainer/console_linux.go
// dupStdio opens the slavePath for the console and dups the fds to the current processes stdio, fd 0, 1, 2
func (c *linuxConsole) dupStdio() error
(1)、首先打开console: slave, err := c.open(syscall.O_RDWR),再调用fd := int(slave.Fd())转换为文件描述符
(2)、最后,调用syscall.Dup3()将STDIO绑定到console上
4、runc/libcontainer/system/linux.go
func Setctty() error
该函数只是简单地调用了syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0)
runc的detach, console, tty等相关问题的更多相关文章
- tty/pts 相关指令
http://unix.stackexchange.com/questions/136662/how-can-we-know-whos-at-the-other-end-of-a-pseudo-ter ...
- Linux TTY介绍
1. TTY介绍 TTY(TeleType)指Linux中的一类终端(Terminal)设备, 是一种字符设备 在Linux中, tty可分为如下几类- 串行端口终端(serial port term ...
- console对象
今天无意中看到console.info()的时候不自觉的楞了一下,对于console.info()确实不是十分的了解,平时就是用console.log(),既然不太明白就去网上看了一下关于consol ...
- Chrome开发者工具详解(1)-Elements、Console、Sources面板
Chrome开发者工具详解(1)-Elements.Console.Sources面板 Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Netwo ...
- Chrome开发者工具详解(1):Elements、Console、Sources面板
Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Network面板. Timeline面板.Profiles面板.Application面板.Se ...
- Node.js小白开路(一)-- console篇
在所有内容的学习之中我们经常首先要接受到的常常很大一部分为命令行或是工具的内容展示,console内容为node.js在命令行中答应数据内容的一个途径. Console是nodejs中的元老级模块了. ...
- BOM相关知识点
1.BOM概念:Browser Object Model 浏览器对象模型作用:提供了使用JS操作浏览器的接口 2.BOM包含了许多对象信息,包括如下这些:(1)screen 屏幕信息(2)locati ...
- linux 终端下敲ctrl-c时,到底发生了什么?(转)
通过telnet登录到单板,然后按ctrl-c会发生什么情况,流程是怎么样的? 在分析之前,先介绍tty的相关知识.我们可以认为,所有跟输入输出相关的操作,最终都由tty来接管.举例来说,当我们敲 l ...
- Openstack Basic
html,body { } .CodeMirror { height: auto } .CodeMirror-scroll { } .CodeMirror-lines { padding: 4px 0 ...
随机推荐
- 35 Gallery – Ajax Slide
http://html5up.net/overflow (PC,Mobile,Table) http://bridge.net/ https://github.com/bridgedotnet/Bri ...
- 解决死锁SQL
USE [master]GO/****** Object: StoredProcedure [dbo].[p_lockinfo] Script Date: 04/03/2014 15:12:40 ** ...
- springMVC图片文件上传功能的实现
在工程依赖库下添加文件上传jar包 commons-fileupload-1.2.2.jar commons-io-2.4.jar 2.jsp页面设置form表单属性enctype 在表单中上传图片时 ...
- 关于setInterval和setTImeout中的this指向问题
前些天在练习写一个小例子的时候用到了定时器,发现在setInterval和setTimeout中传入函数时,函数中的this会指向window对象,如下例: var num = 0; function ...
- 数码管问题(c++实现)
描述:液晶数码管用七笔阿拉数字表示的十个数字,把横和竖的一 个短划都称为一笔,即7有3笔,8有7笔等.对于十个数字一种排列,要做到 两相邻数字都可以由另一个数字加上几笔或减去几笔组成,但不能又加又减. ...
- javascript --- 子对象访问父对象的方式
在传统面向对象的编程语言里,都会提供一种子类访问父类的特殊语法,引文我们在实现子类方法往往需要父类方法的额外辅助.在这种情况下,子类通常会调用父类中的同名方法,最终以便完成工作. javascript ...
- css三角形的实现
实底三角形: <html> <head> <title></title> <style type="text/css"> ...
- Microsoft Dynamics CRM 2013 安装过程 图解
在安装前,先持一下SQL配置管理,将相关的服务打开.(由于在虚拟机里,许多服务需要时才会打开,像Reporting Services需要处理报表时才打开) 注:Analysis Services 登录 ...
- 解决虚拟机linux端mysql数据库无法远程访问
解决虚拟机linux端mysql数据库无法远程访问 1. 在控制台执行 mysql -u root -p mysql,CentOS系统提示输入数据库root用户的密码,输入完成后即进入mysql控制台 ...
- 【原】iOS动态性(一):动态添加属性的方法——关联(e.g. 向Category添加属性)
想到要如何为所有的对象增加实例变量吗?我们知道,使用Category可以很方便地为现有的类增加方法,但却无法直接增加实例变量.不过从Mac OS X v10.6开始,系统提供了Associative ...