Monday, January 19, 2009

VServer is not Xen, Part 2

Another oddity about VServer is that it does not have a true init process. Or rather, the whole start up is not as you are used to from other Linux systems.

While you can read about the different Init Styles there is one crucial issue: the startup scripts, usually located in /etc/rc.<n> are either executed outside of the VM or inside, so that you can either "see" the VM starting up from the master or not respectively. While this is OK and usable for most applications, it has a major problem. You cannot run DJB's daemontools.

This is because while the above startup styles execute the init scripts, it does not execute anything else from the inittab configuration files. Most importantly the last line in the following excerpt from /etc/inittab:
...
# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100

# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3

SV:123456:respawn:/command/svscanboot

The last line is what starts the root daemontools process that starts all services it maintains. In VServer is simply will not start.

The issue for me started a lot earlier, I should have seen this coming really. When I tried the initial setup I went down the usual (at least for me) get the daemontools-installer Debian package and build the binaries. I did this in the VM obviously, because that is where I wanted to install the daemontools. Here is what happened:
$ build-daemontools       

This script unpacks the daemontools source into a directory, and
compiles it to produce a binary daemontools*.deb file.
...
Press ENTER to continue...
Attempting to apply patches located in
/usr/src/daemontools-installer/patches...
/usr/src/daemontools-installer/patches/errno.patch
patching file src/error.h
/usr/src/daemontools-installer/patches/fileutils.patch
patching file src/rts.tests
dh_testdir
package/compile
Linking ./src/* into ./compile...
Compiling everything in ./compile...
make[1]: Entering directory `/tmp/daemontools/admin/daemontools-0.76/compile'
sh find-systype.sh > systype
rm -f compile
sh print-cc.sh > compile
chmod 555 compile
./compile byte_chr.c
./compile byte_copy.c
./compile byte_cr.c
./compile byte_diff.c
...
make[1]: Leaving directory `/tmp/daemontools/admin/daemontools-0.76/compile'
Copying commands into ./command...
touch build-stamp
dh_testdir
dh_testroot
dh_clean -k
dh_clean: Compatibility levels before 4 are deprecated.
dh_installdirs
dh_installdirs: Compatibility levels before 4 are deprecated.
mkdir -p debian/daemontools/package/admin/daemontools-0.76
mkdir -p debian/daemontools/command
mkdir -p debian/daemontools/usr/share/daemontools
mkdir -p debian/daemontools/service
cp -a command debian/daemontools/package/admin/daemontools-0.76
cp -a compile debian/daemontools/package/admin/daemontools-0.76
cp -a package debian/daemontools/package/admin/daemontools-0.76
cp -a src debian/daemontools/package/admin/daemontools-0.76
dh_link package/admin/daemontools-0.76/package usr/share/daemontools/package
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76 package/admin/daemontools
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/envdir command/envdir
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/envuidgid command/envuidgid
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/fghack command/fghack
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/multilog command/multilog
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/pgrphack command/pgrphack
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/readproctitle
command/readproctitle
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/setlock command/setlock
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/setuidgid command/setuidgid
dh_link: Compatibility levels before 4 are deprecated.
dh_link package/admin/daemontools-0.76/command/softlimit command/softlimit
...
dh_gencontrol
dh_gencontrol: Compatibility levels before 4 are deprecated.
dh_md5sums
dh_md5sums: Compatibility levels before 4 are deprecated.
dpkg-deb -b debian/daemontools ..
dpkg-deb: building package `daemontools' in `../daemontools_0.76-9_i386.deb'.

It seems that all went ok

Do you want to remove all files in /tmp/daemontools,
except daemontools_0.76-9_i386.deb now? [Yn]
Removing files... done

Do you want to install daemontools_0.76-9_i386.deb now? [Yn] n

Do you want to purge daemontools-installer now? [yN]

Good luck!

So the compile succeeded but the subsequent package compilation failed with "dh_link: Compatibility levels before 4 are deprecated." errors. The makefile was not built to handle these kinds of errors by the looks because at the end I got told all seems OK - which is of course not the case, the package is empty.

Well, I managed to build it somewhere else and install the binaries that way into the Virtual Machine. But then I noticed the issue above, in other words the services would not run because the root process was not started.

After searching around on the web I found - of course - a post outlining the same issue. As usual you go through the same steps and pain just to find out that someone else found the same problem and already fixed it.

The solution is to start the root daemontools process just like any other process. The post has a script that I include below (in case in gets lost in the Intertubes):
$ cat /etc/init.d/svscanboot 

#! /bin/sh
#
# daemontools for launching /etc/svscanboot from sysvinit instead of /sbin/init.
#
# author: dkg

set -e

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="daemontools"
NAME=svscanboot
DAEMON=/command/svscanboot

PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

#
# Function that starts the daemon/service.
#
d_start() {
start-stop-daemon --start --background --make-pidfile --quiet --pidfile $PIDFILE \
--exec $DAEMON
}

#
# Function that stops the daemon/service.
#
d_stop() {
start-stop-daemon --stop --quiet --pidfile $PIDFILE \
--name $NAME
echo "not cleaning up svscan and readproctitle subprocesses
appropriately. dkg is lazy."
}

#
# Function that sends a SIGHUP to the daemon/service.
#
d_reload() {
start-stop-daemon --stop --quiet --pidfile $PIDFILE \
--name $NAME --signal 1
}

case "$1" in
start)
echo -n "Starting $DESC: $NAME"
d_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
d_stop
echo "."
;;
restart|force-reload)
#
# If the "reload" option is implemented, move the "force-reload"
# option to the "reload" entry above. If not, "force-reload" is
# just the same as "restart".
#
echo -n "Restarting $DESC: $NAME"
d_stop
sleep 1
d_start
echo "."
;;
*)
# echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 1
;;
esac

exit 0

Now, other post mention that there is also a "fakeinit" style - but it did not work for me and I rather believe that this is the old name for "plain" mentioned in the Init Styles document I linked above.

Goes to show that a lot is unclear about VServer. But that is often the case with open-source tools and systems. It is up to us, the IT people, to help out and close those gaps while contributing to the community.

No comments:

Post a Comment