解决chroot Linux中Upstart无法工作的问题

本文同步自(最佳显示效果请点击):https://zohead.com/archives/chroot-linux-upstart/

Upstart 是比较新的 Linux 中使用的 init 进程,用于替换原始的通过 /etc/inittab 控制的 /sbin/init 进程。原始的 /sbin/init 进程在系统启动时启动服务,在系统重启或关闭时关闭服务。而 Ubuntu 从 6.10 开始已经不再使用老的 init 进程方式,改为新的 Upstart 方式。Upstart 完全可以替代原始 init 进程(实际上 Upstart 就是新的 init 进程),而且还可以做到特定事件触发启动或停止服务等操作,相对于原始 init 进程是一大改善。

这里不打算对 Linux init 进程的作用和启动处理流程做太多介绍,有关 Upstart 的详细信息请参考 Ubuntu 网站上的介绍:

http://upstart.ubuntu.com/

笔者最近在使用一个 chroot 的 Ubuntu 12.04 系统(主系统为 Android 4.0.4,不是普通的 Linux 桌面或服务器发行版)时发现 Upstart 无法正常工作,具体表现为 service xxx start、invoke-rc.d 等服务控制的命令无法正常工作,启动或停止服务时会报下面的错误:

start: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused

即使直接通过运行:/etc/init.d/xxx start,这样也会报同样的错误。

由于 Upstart 需要使用 dbus 进行通讯,我就做进一步的检查,发现 dbus-daemon 是正常启动的,其它依赖 dbus 的程序看起来也能正常工作的。仔细想想之后差不多明白了,Upstart 需要新的 /sbin/init 进程和 dbus 通讯以进行服务控制,但现在我使用的主系统为 Android 系统,init 进程明显不是 Upstart。现在 Ubuntu 系统是通过 chroot 运行的,对于 Ubuntu 系统来说,其内置的 Upstart init 进程是不起作用的,所以所有服务的控制操作都不能正常运行,这是比较麻烦的。

再做搜寻之后发现国外一哥们 Péter Gy?ngy?si 写的这篇文章:

http://gyp.blogs.balabit.com/2011/01/using-upstart-in-a-chroot/

在这边文章里,作者写到他也遇到在 chroot 中 Upstart 无法正常工作的问题。他的解决方法不是像网上其它人说的那样修改 /sbin/initctl 指向 /bin/true 使某些程序不报错的方法(其实并没有解决问题),可以参考这里:

https://www.nesono.com/node/368

该作者通过自己写了一个 Python 脚本来替换 /sbin/initctl 程序来达到控制服务启动、停止等操作,这样运行 service xxx start 就可以工作正常。但这个 Python 脚本存在无法记录启动的服务的 PID 的问题,这样运行 service xxx stop 就无法正常停止服务了。为此,该作者通过修改系统内置的 start-stop-daemon 程序来达到记录 PID 的效果,这样就可以正常通过 service、invoke-rc.d 等命令启动和停止服务。

作者提供的 chroot Upstart 替换脚本可以在这里下载(直接将 /sbin/initctl 替换为 Python 脚本,其它相关文件也放在 /sbin 下):

http://git.balabit.hu/?p=gyp/upstart-dummy.git

start-stop-daemon 程序的 patch 在这里:

http://people.balabit.hu/gyp/blog/dpkg_start_stop_daemon_tracepid.diff

不过需要说明的是,上面的 patch 是针对老的 Ubuntu 系统的,在 Ubuntu 12.04 中无法使用,Ubuntu 12.04 系统中 start-stop-daemon 已经增加了 “-T” 参数与 patch 中的会有冲突,同时 patch 中还有别的问题。

我通过下载 Ubuntu 12.04 官方的 dpkg 程序源代码,然后在上面的 patch 基础上进一步做了修改,将 patch 中的 “-T” 参数改为 “-Z” 参数,并做了进一步的修正,成功编译出 Ubuntu 12.04 32 位系统中可以用的替换 start-stop-daemon 程序。经过测试,新的 Upstart 脚本和 start-stop-daemon 可以实现我的需求:在 chroot 运行的 Ubuntu 系统可以正常启动和停止服务。

这里是我编译出的 32 位 Ubuntu 12.04 系统中可以用的 start-stop-daemon 程序:

http://miseal.googlecode.com/files/start-stop-daemon_precise_i386.7z

此文章为我实际使用经验所写,特别感谢 Péter Gyöngyösi 的替换 Upstart 脚本,其中有任何问题欢迎提出指正哦~~~