解决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 脚本,其中有任何问题欢迎提出指正哦~~~

3 条评论 在此博文.
  1. Arline Goff:

    Upstart uses job definition files in /etc/init to define on what events a service should be started. So, while the system is booting, upstart processes various events, and then can start multiple services in parallel. This allows them to fully utilize the resources of the system, for instance, by starting a disk-bound service up while another CPU-bound service runs, or while the network is waiting for a dynamic IP address to be assigned.

  2. felonwan:

    很好,我也是遇到这个问题,难得能认真思考和自己动手,喜欢你的文章。

    希望能多把遇到的问题用中文表述,虽然也能看英文,还是比较喜欢看中文。

  3. admin:

    博客是中英双语的,除了给老外看的文章会中英文两个版本都写,其它一般就写个中文的咯~~~
    PS:你也折腾过Android上的Linux哈~~~

发表评论





*