由lxc-checkpoint想到的 …

May 12th, 2015 by JasonLe's Tech Leave a reply »

在 LXC 1.1版本以后,lxc整合了criu的功能,使得可以checkpoint一个正在运行的容器。但是有时候我们会出现lxc.tty must be 0的文字,这个就意味着我们必须在lxc 的config中加入特定的选项

cat | sudo tee -a /var/lib/lxc/u1/config << EOF
# hax for criu
lxc.console = none
lxc.tty = 0
lxc.cgroup.devices.deny = c 5:1 rwm
EOF

但是我发现了一个问题:到底什么是tty,他是由什么管理的?

我们都知道在unix下有非常多的终端:bash、zsh、sh、ssh等,这些终端程序就是我们输入命令的窗口,至于配置用户的终端,当然是在/etc/passwd下面。

但是是哪个程序调用了/bin/bash呢?使用strace跟踪这个/bin/login(strace -f -o /tmp/strace.log /bin/login),可以发现里面存在execve系统调用,这个调用执行了 /bin/login程序。而login又是谁调用的呢?经过查看是getty。getty是在自己的主进程里头直接执行了/bin/login,这样/bin/login将把getty的进程空间替换掉。

而init需要读取/etc/inittab来做,inittab,目前不再被systemd使用,这里就有/etc/rc.d/一系列脚本完成。
根据系统启动原理,我们可以发现调用过程:

init –> init –> /sbin/getty –> /bin/login –> /bin/login –> /bin/bash

这里的execve调用以后,后者将直接替换前者,我们要知道一点:因为终端程序之间有父子关系的存在,当子进程exit之后,父进程要进行处理,否则就是zombie进程。因此当我们键入exit退出/bin/bash以后,也就相当于/sbin/getty都已经结束了, 因此最前面的init程序判断/sbin/getty退出了,又会创建一个子进程把/sbin/getty启动,进而又启动了/bin/login,又看 到了那个”XXX login:”

一般情况下,系统内置程序会比自己编写的更加优先被执行,按照系统内置规则,一般首先是程序别名,然后是shell function,之后是系统内置函数(builtin ),最后才是自己编写的函数(program )!

总的来说:先    alias –> shell function –> builtin –> program   后 

 

参考:

[1] man boot-scripts Linux启动过程
[2] man bootparam  Linux内核启动参数
[3] man 5 passwd
[4] man shadow