Difference between revisions of "Upstart issues"

From Linux-VServer

Jump to: navigation, search
(remove low level services inside the guest)
Line 41: Line 41:
 
         initctl emit filesystem
 
         initctl emit filesystem
 
  end script
 
  end script
 +
 +
=== Notes for older kernels ===
 +
If you encounter upstart errors like this:
 +
 +
$ vserver foo start
 +
init: missing runlevel
 +
Try `init --help' for more information.
 +
 +
or
 +
 +
$ vserver foo start
 +
telinit: Failed to connect to socket /com/ubuntu/upstart: Connection refused
 +
 +
then you're probably running the current stable version <code>2.6.22.19-vs2.2.0.7</code>.
 +
 +
Upstart's <code>/sbin/init</code> implementation requires to be PID 1. It is linked against NPTL (in contrast to sysvinit), which has a bug in it's caching <code>getpid(2)</code> wrapper. With this kernel version <code>getpid(2)</code> returns the cached PID to init, resulting in init replacing itself with telinit. You can fix this by upgrading to a <code>2.6.26+</code> kernel and a newer vserver patch, or by patching upstart:
 +
 +
diff --git a/init/main.c b/init/main.c
 +
index bfcd528..c6c9304 100644
 +
--- a/init/main.c
 +
+++ b/init/main.c
 +
@@ -37,6 +37,7 @@
 +
  #include <string.h>
 +
  #include <syslog.h>
 +
  #include <unistd.h>
 +
+#include <syscall.h>
 +
 
 +
  #include <linux/kd.h>
 +
 
 +
@@ -131,7 +132,7 @@ main (int  argc,
 +
  }
 +
 
 +
  /* Check we're process #1 */
 +
- if (getpid () > 1) {
 +
+ if (syscall(SYS_getpid) > 1) {
 +
  execv (TELINIT, argv);
 +
  /* Ignore failure, probably just that telinit doesn't exist */
 +
 +
For more information see the man pages of <code>getpid(2)</code> (NOTES) and <code>clone(2)</code> (BUGS).

Revision as of 03:11, 16 November 2009

Contents

running an upstart based guest

currently upstart based guests need some manual tweaking to make them work inside a vserver guest.

prepare the host

First of all you need to set the init style of your vserver to plain

# echo plain > /etc/vservers/<vservername>/apps/init/style

remove low level services inside the guest

Then you need to get rid of anything in /etc/init/ that tries to fiddle with your Server's Hardware or other low-level Stuff that's already handled by your host's kernel/system. Having one such scriptlet still enabled might cause the whole upstart system to fail (like not beeing able to open /dev/console or failing to start the udev system). Just remove these scriptlets, move them out of the way or rename them to something not ending in .conf. Be aware that upstart also parses subfolders of /etc/init/ for .conf files.

This is what I deleted on a basic Ubuntu 9.10 guest:

dmesg.conf
hostname.conf
hwclock-save.conf
hwclock.conf
mountall-net.conf
mountall-reboot.conf
mountall-shell.conf
mountall.conf
network-interface.conf
networking.conf
procps.conf
rsyslog-kmsg.conf
tty1.conf
tty2.conf
tty3.conf
tty4.conf
tty5.conf
tty6.conf
upstart-udev-bridge.conf

fake low level events inside the guest

Finally you need to fake emit the events that some of these scripts would do during regular boot. Probably the cleanest approach is to add a scriptlet vserver.conf to /etc/init/ with this content:

start on startup
script
       initctl emit virtual-filesystems
       initctl emit local-filesystems
       initctl emit remote-filesystems
       initctl emit filesystem
end script

Notes for older kernels

If you encounter upstart errors like this:

$ vserver foo start
init: missing runlevel
Try `init --help' for more information.

or

$ vserver foo start
telinit: Failed to connect to socket /com/ubuntu/upstart: Connection refused

then you're probably running the current stable version 2.6.22.19-vs2.2.0.7.

Upstart's /sbin/init implementation requires to be PID 1. It is linked against NPTL (in contrast to sysvinit), which has a bug in it's caching getpid(2) wrapper. With this kernel version getpid(2) returns the cached PID to init, resulting in init replacing itself with telinit. You can fix this by upgrading to a 2.6.26+ kernel and a newer vserver patch, or by patching upstart:

diff --git a/init/main.c b/init/main.c
index bfcd528..c6c9304 100644
--- a/init/main.c
+++ b/init/main.c
@@ -37,6 +37,7 @@
 #include <string.h>
 #include <syslog.h>
 #include <unistd.h>
+#include <syscall.h>
 
 #include <linux/kd.h>
 
@@ -131,7 +132,7 @@ main (int   argc,
 	}
 
 	/* Check we're process #1 */
-	if (getpid () > 1) {
+	if (syscall(SYS_getpid) > 1) {
 		execv (TELINIT, argv);
 		/* Ignore failure, probably just that telinit doesn't exist */

For more information see the man pages of getpid(2) (NOTES) and clone(2) (BUGS).

Personal tools