Difference between revisions of "Arch VServer"

From ArchWiki
Jump to: navigation, search
m
(Current status / Next steps: Remove old info.)
(32 intermediate revisions by 11 users not shown)
Line 1: Line 1:
[[Category:Emulators (English)]][[Category: Tutorial (English)]]
+
[[Category:Virtualization]]
{{ stub }}
+
This article aims to provide all necessary information regarding the creation of a vserver host as well as vserver guests running Arch Linux. This will enable you to setup virtual servers that provide different services as if they were on different machines, with a very little overhead. You can get more information about virtual servers [http://en.wikipedia.org/wiki/Virtual_private_server here].
{{ translateme }}
+
  
=Introduction=
+
=Preparing the Host=
  
This article aims to provide all necessary information about setting virtual servers on Arch Linux. You can setup virtual servers to provide different services on just one machine as if they were on different machines with a very little power loss. You can get more information about virtual servers [http://en.wikipedia.org/wiki/Virtual_private_server here].
+
To prepare the vserver host environment, you will need to install both a vserver patched kernel, the vserver utilities and their dependencies which are located in the [[AUR]]. The required packages are {{AUR|dietlibc}}, {{AUR|beecrypt}}, {{AUR|kernel26-vserver}} (not found or {{AUR|linux-vserver}} orphan), and {{AUR|util-vserver}}
  
=Installation=
+
=Paths of Interest=
  
For more secure chroots and compatibility you need '''''dietlibc''''' and '''''beecrypt'''''.
+
'''/etc/vservers''' : configuration root ( [http://www.nongnu.org/util-vserver/doc/conf/configuration.html ''reference''] )
 +
: '''/etc/vservers/.defaults''' : configuration skeleton used when building new guests
 +
:: '''/etc/vservers/.defaults/vdirbase''' : symlink to the folder containing vserver guests. This defaults to /vservers.
 +
: '''/etc/vservers/<guest name>''' : guest specific configurations
  
dietlibc is available in [community] repository, therefore you can manually download and install it or you can comment out [community] in your pacman.conf and install it via pacman:
+
=Preparing the Guests=
  
pacman -Sy dietlibc
+
Vserver will launch guests from subfolders of ''/etc/vservers/.defaults/vdirbase''. As such, creating a new guest system is as simple as installing the required packages in a folder of the host. Furthermore, there's nothing stopping you ( and quite a few things encouraging you ) to mount filesystems to the subfolders of ''vdirbase'' and installing your guest in there.
  
beecrypt is available in [http://aur.archlinux.org/packages.php?ID=16387 AUR].
+
If you plan on doing this often, I highly recommend that you write yourself a little batch script since most of these steps can be automated quite easily.
  
Next, you need util-vserver to administer the guests. (creating aur package//adopting it..)
+
==Preparing the guest installation media==
  
=Configuration=
+
'''NOTE''' : This is all heavily inspired from [https://wiki.archlinux.org/index.php/Install_From_Existing_Linux wiki:Install From Existing Linux] and will therefore be quite brief when not mentioning Vserver specific steps.
 +
 
 +
===Optional: Base variables to follow along with the steps===
 +
GuestName= # Name of the guest
 +
GuestRoot=/etc/vservers/.defaults/vdirbase/$GuestName
 +
GuestPackages= # Listing of packages to install via pacman
 +
GuestDisk= # Installation target device
 +
GuestNetDevice= # ex.: eth0, dummy0, etc...
 +
GuestIP= # I think you get it
 +
GuestContext= # Unique identifier for the guest, I go with the last part of the IP
 +
 
 +
===Optional: Preparing the guest disk===
 +
# Create a LVM Physical Volume, a Volume Group and a Logical Volume ( [https://wiki.archlinux.org/index.php/Lvm#Create_Logical_Volumes wiki:LVM] )
 +
# Create a filesystem on the lvm volume
 +
# mkdir $GuestRoot
 +
# mount /dev/$GuestDisk $GuestRoot
 +
 
 +
===Optional: Link the host and guest pacman cache===
 +
# mkdir $GuestRoot/var/cache/pacman/pkg
 +
# mount -o bind /var/cache/pacman/pkg $GuestRoot/var/cache/pacman/pkg
 +
 
 +
===Prepare Vserver===
 +
# vserver $GuestName -m skeleton --context $GuestContext --interface $GuestNetDevice:$GuestIP --flags lock,virt_mem,virt_uptime,virt_cpu,virt_load,sched_hard,hide_netif --initstyle plain
 +
# (optional) cd /etc/vservers/$GuestName/interfaces
 +
# (optional) cp -r 0 1
 +
# (optional) echo 'lo' > dev
 +
# (optional) echo '127.0.0.$GuestContext' > ip
 +
 
 +
===Prepare the guest's filesystem===
 +
# Prepare guest filesystem for the pacman db
 +
## mkdir -p /newarch/var/lib/pacman
 +
 
 +
===Install the base system===
 +
'''NOTE : ''' To save some time, it's probably a good idea to create a text file containing all the packages to install and call it via "pacman -S `cat $GuestPackages` -r $GuestRoot" instead of the following :
 +
# pacman -S base -r $GuestRoot
 +
# Optional: If you want to chroot into the newly created guest so as to install new packages, it might be a good idea to mount a few filesystems required by some packages.
 +
## Bind /dev, /proc, /sys to the corresponding directories in $GuestRoot
 +
# Modify guest configuration files to enable a smoother boot process
 +
## Modify '''/etc/inittab''' by deleting all lines that create the consoles ( agetty )
 +
## Modify '''/etc/rc.shutdown''' by removing anything hardware/clock/mount related. This includes most everything under ''Saving Random Seed'.
 +
## Modify '''/etc/rc.sysinit''' by anything hardware/clock/mount related.
 +
## Create '''/etc/init.d/rc'''
 +
## Modify '''/etc/syslog-ng.conf''' by removing file("/proc/kmsg")
 +
## Modify '''/etc/rc.conf''' by removing the networks Daemon.
 +
# Ensure '''/etc/rc.*''' can be executed: "chmod +x /etc/rc.*"
 +
 
 +
===Annexe : Configuration files modified===
 +
'''/etc/init.d/rc'''
 +
if [ $1 -eq 3 ]; then
 +
echo "entering runlevel 3:multi";
 +
/etc/rc.multi
 +
fi
 +
if [ $1 -eq 6 ]; then
 +
echo "entering runlevel 6:reboot";
 +
/etc/rc.shutdown
 +
fi
 +
if [ $1 -eq 0 ]; then
 +
echo "entering runlevel 0: shutdown";
 +
/etc/rc.shutdown
 +
fi
 +
if [ $1 -eq 4 ]; then
 +
echo "entering runlevel 4";
 +
fi
 +
if [ $1 -eq 5 ]; then
 +
echo "entering runlevel 5";
 +
fi
 +
if [ $1 -eq 1 ]; then
 +
echo "entering runlevel 1:single";
 +
/etc/rc.single
 +
fi
 +
if [ $1 -eq 2 ]; then
 +
echo "entering runlevel 2:multi";
 +
/etc/rc.multi
 +
fi
 +
 
 +
====/etc/rc.sysinit====
 +
#!/bin/bash
 +
#
 +
# /etc/rc.sysinit
 +
#
 +
 +
. /etc/rc.conf
 +
. /etc/rc.d/functions
 +
 +
echo " "
 +
printhl "Arch Linux\n"
 +
printhl "${C_H2}https://www.archlinux.org"
 +
printhl "Copyright 2002-2007 Judd Vinet"
 +
printhl "Copyright 2007-2009 Aaron Griffin"
 +
printhl "Distributed under the GNU General Public License (GPL)"
 +
printsep
 +
 +
 +
# start up our mini logger until syslog takes over
 +
/sbin/minilogd
 +
 +
if [ -x /sbin/udevadm ]; then
 +
stat_busy "Starting UDev Daemon"
 +
/sbin/udevd --daemon
 +
stat_done
 +
else
 +
# Static /dev, our last resort
 +
status "Using static /dev filesystem" true
 +
fi
 +
 +
# Trigger udev uevents
 +
if /bin/pidof -o %PPID /sbin/udevd >/dev/null; then
 +
  stat_busy "Triggering UDev uevents"
 +
  /sbin/udevadm trigger
 +
  stat_done
 +
fi
 +
  NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk,noglusterfs"
 +
 +
stat_busy "Mounting Local Filesystems"
 +
/bin/rm -f /etc/mtab*
 +
# Write /proc, /sys and /dev to /etc/mtab
 +
if [ -e /proc/mounts ]; then
 +
/bin/grep -e "rootfs" -e "/proc " -e "/sys " -e "/dev " /proc/mounts >>    /etc/mtab
 +
fi
 +
stat_done
 +
 
 +
stat_busy "Configuring System Clock"
 +
if [ ! -f /var/lib/hwclock/adjtime ]; then
 +
echo "0.0 0 0.0" > /var/lib/hwclock/adjtime
 +
fi
 +
if [ "$TIMEZONE" != "" -a -e "/usr/share/zoneinfo/$TIMEZONE" ]; then
 +
/bin/rm -f /etc/localtime
 +
/bin/cp "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
 +
fi
 +
 +
if [ -n "$HWCLOCK_PARAMS" ]; then
 +
/sbin/hwclock --adjust #Adjust for system drift
 +
/sbin/hwclock $HWCLOCK_PARAMS
 +
fi
 +
stat_done
 +
 +
RANDOM_SEED=/var/lib/misc/random-seed
 +
if [ -f $RANDOM_SEED ]; then
 +
stat_busy "Initializing Random Seed"
 +
/bin/cat $RANDOM_SEED > /dev/urandom
 +
stat_done
 +
fi
 +
 +
stat_busy "Removing Leftover Files"
 +
/bin/rm -f /etc/nologin &>/dev/null
 +
/bin/rm -f /etc/shutdownpid &>/dev/null
 +
/bin/rm -f /var/lock/* &>/dev/null
 +
/bin/rm -rf /tmp/* /tmp/.* &>/dev/null
 +
/bin/rm -f /forcefsck &>/dev/null
 +
(cd /var/run && /usr/bin/find . ! -type d -exec /bin/rm -f -- {} \; )
 +
: > /var/run/utmp
 +
/bin/chmod 0664 /var/run/utmp
 +
# Keep {x,k,g}dm happy with xorg
 +
/bin/mkdir /tmp/.ICE-unix && /bin/chmod 1777 /tmp/.ICE-unix
 +
/bin/mkdir /tmp/.X11-unix && /bin/chmod 1777 /tmp/.X11-unix
 +
stat_done
 +
 +
#status "Updating Shared Library Links" /sbin/ldconfig
 +
 +
if [ "$HOSTNAME" != "" ]; then
 +
status "Setting Hostname: $HOSTNAME" /bin/hostname $HOSTNAME
 +
fi
 +
 +
# Set the NIS domain name, if necessary
 +
[ -f /etc/conf.d/nisdomainname ] && . /etc/conf.d/nisdomainname
 +
if [ "$NISDOMAINNAME" != "" ]; then
 +
status "Setting NIS Domain Name: $NISDOMAINNAME" /bin/nisdomainname  $NISDOMAINNAME
 +
fi
 +
 +
status "Updating Module Dependencies" /sbin/depmod -A
 +
 +
# Flush old locale settings
 +
: >/etc/profile.d/locale.sh
 +
/bin/chmod 755 /etc/profile.d/locale.sh
 +
# Set user defined locale
 +
[ -z "$LOCALE" ] && LOCALE="en_US"
 +
stat_busy "Setting Locale: $LOCALE"
 +
echo "export LANG=$LOCALE" >>/etc/profile.d/locale.sh
 +
stat_done
 +
 +
# Adding persistent network/cdrom generated rules
 +
if [ -f "/dev/.udev/tmp-rules--70-persistent-cd.rules" ]; then
 +
stat_busy "Adding persistent cdrom udev rules"
 +
/bin/cat /dev/.udev/tmp-rules--70-persistent-cd.rules >> /etc/udev/rules.d/70-persistent-cd.rules
 +
stat_done
 +
fi
 +
if [ -f "/dev/.udev/tmp-rules--70-persistent-net.rules" ]; then
 +
stat_busy "Adding persistent network udev rules"
 +
/bin/cat /dev/.udev/tmp-rules--70-persistent-net.rules >> /etc/udev/rules.d /70-persistent-net.rules
 +
stat_done
 +
fi
 +
 +
/bin/dmesg >| /var/log/dmesg.log
 +
 +
# End of file
 +
# vim: set ts=2 noet:
 +
 
 +
====/etc/rc.shutdown====
 +
#!/bin/bash
 +
#
 +
# /etc/rc.shutdown
 +
#
 +
 +
. /etc/rc.conf
 +
. /etc/rc.d/functions
 +
 +
# avoid staircase effect
 +
/bin/stty onlcr
 +
 +
echo " "
 +
printhl "Initiating Shutdown..."
 +
echo " "
 +
 +
# avoid NIS hanging syslog-ng on shutdown by unsetting the domainname
 +
if [ -x /bin/domainname ]; then
 +
/bin/domainname ""
 +
fi
 +
 +
if [ -x /etc/rc.local.shutdown ]; then
 +
/etc/rc.local.shutdown
 +
fi
 +
 +
if [ "$PREVLEVEL" = "3" -o "$PREVLEVEL" = "5" ]; then
 +
# Find daemons NOT in the DAEMONS array. Shut these down first
 +
if [ -d /var/run/daemons ]; then
 +
for daemon in $(/bin/ls -1t /var/run/daemons); do
 +
  if ! in_array $daemon ${DAEMONS[@]}; then
 +
stop_daemon $daemon
 +
  fi
 +
done
 +
fi
 +
# Shutdown daemons in reverse order
 +
let i=${#DAEMONS[@]}-1
 +
while [ $i -ge 0 ]; do
 +
if [ "${DAEMONS[$i]:0:1}" != '!' ]; then
 +
ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@}
 +
fi
 +
        let i=i-1
 +
    done
 +
fi
 +
 +
# Terminate all processes
 +
stat_busy "Sending SIGTERM To Processes"
 +
/sbin/killall5 -15 &> /dev/null
 +
/bin/sleep 5
 +
stat_done
 +
 +
stat_busy "Sending SIGKILL To Processes"
 +
/sbin/killall5 -9 &> /dev/null
 +
/bin/sleep 1
 +
stat_done
 +
 +
# Write to wtmp file before unmounting
 +
/sbin/halt -w
 +
 +
# Power off or reboot
 +
if [ "$RUNLEVEL" = "0" ]; then
 +
printsep
 +
    printhl "${C_H2}POWER OFF"
 +
/sbin/poweroff -d -f -h -i
 +
else
 +
printsep
 +
printhl "${C_H2}REBOOTING"
 +
# if kexec is installed and a kernel is loaded, use it
 +
[ -x /sbin/kexec ] && /sbin/kexec -e > /dev/null 2>&1
 +
/sbin/reboot -d -f -i
 +
fi
 +
 +
# End of file
 +
# vim: set ts=2 sw=2 noet:
  
 
=Troubleshooting=
 
=Troubleshooting=
 +
==Viewing output from vserver $GuestName start / stop==
 +
 +
'''NOTE : ''' For me, this only worked in the actual consoles, not in X.
 +
 +
# Make sure that the device /dev/console exists in the guest
 +
## If it does not, cp -a /dev/console $GuestRoot/dev/
 +
 +
==SSH will not start==
 +
I noticed that /dev/null did not always get created properly in my first experimentations. Therefore I did a quick :
 +
# cp -a /dev/null $GuestRoot/dev
 +
# cp -a /dev/zero $GuestRoot/dev
 +
 +
Furthermore, if you're not using the dummy network driver and are attaching to the host's network interface, you'll want to configure the ListenAddress statement of /etc/ssh/sshd_config so that it binds only to the guest's IP address as opposed to 127.0.0.1.
 +
 +
==SSH immediately terminates the connection==
 +
On my machine, SSH used to authenticate me correctly and log me in, but then immediately drop the connection without an explanation. Consulting /var/log/auth.log revealed the following:
 +
 +
sshd[17899]: pam_limits(sshd:session): Could not set limit for 'nice': Operation not permitted
 +
 +
This is easily fixed by commenting all '''nice''' related lines in /etc/security/limits.conf.
 +
 +
=Tips & Trick=
 +
==Network via dummy adapters==
 +
Here, you're either using the dummy module to create virtual network adapters or created interface aliases via /usr/sbin/ip or /usr/sbin/ifconfig. I went for the former and configured the host as such :
 +
# ''/etc/sysctl.conf'' : net.ipv4.ip_forward=1<br>
 +
Modify or add that statement to enable routing on the host
 +
# ''/etc/rc.local''<br>
 +
modprobe dummy numdummies=$NumberOfGuests<br>
 +
ip link set dev dummy$GuestContext name $GuestName
  
=Tips & Tricks=
+
This provides me with dummy interfaces that I can route / firewall that are all named the same as my guests... yay.
  
 
=More Resources=
 
=More Resources=
 +
[http://linux-vserver.org/Problematic_Programs Problematic Programs]<br>
 +
[http://linux-vserver.org/Howto_make_bsd-style_init_sysv-compatible Make BSD style init SYSV compatible]<br>
 +
[http://www.cedarcreeksoftware.com/an-even-easier-linux-vserver-tutorial.html Vserver tutorial]<br>
 +
[http://linux-vserver.org/Installation_on_ArchLinux linux-vserver.org's Installation on ArchLinux]<br>
 +
[http://wiki.linux-vserver.org/Networking_vserver_guests linux-verserver.org's networking tutorial]<br>
 +
<!-- vim: set ft=Wikipedia: -->

Revision as of 09:37, 8 March 2013

This article aims to provide all necessary information regarding the creation of a vserver host as well as vserver guests running Arch Linux. This will enable you to setup virtual servers that provide different services as if they were on different machines, with a very little overhead. You can get more information about virtual servers here.

Preparing the Host

To prepare the vserver host environment, you will need to install both a vserver patched kernel, the vserver utilities and their dependencies which are located in the AUR. The required packages are dietlibcAUR, beecryptAUR, kernel26-vserverAUR (not found or linux-vserverAUR orphan), and util-vserverAUR

Paths of Interest

/etc/vservers : configuration root ( reference )

/etc/vservers/.defaults : configuration skeleton used when building new guests
/etc/vservers/.defaults/vdirbase : symlink to the folder containing vserver guests. This defaults to /vservers.
/etc/vservers/<guest name> : guest specific configurations

Preparing the Guests

Vserver will launch guests from subfolders of /etc/vservers/.defaults/vdirbase. As such, creating a new guest system is as simple as installing the required packages in a folder of the host. Furthermore, there's nothing stopping you ( and quite a few things encouraging you ) to mount filesystems to the subfolders of vdirbase and installing your guest in there.

If you plan on doing this often, I highly recommend that you write yourself a little batch script since most of these steps can be automated quite easily.

Preparing the guest installation media

NOTE : This is all heavily inspired from wiki:Install From Existing Linux and will therefore be quite brief when not mentioning Vserver specific steps.

Optional: Base variables to follow along with the steps

GuestName= # Name of the guest
GuestRoot=/etc/vservers/.defaults/vdirbase/$GuestName
GuestPackages= # Listing of packages to install via pacman
GuestDisk= # Installation target device
GuestNetDevice= # ex.: eth0, dummy0, etc...
GuestIP= # I think you get it
GuestContext= # Unique identifier for the guest, I go with the last part of the IP

Optional: Preparing the guest disk

  1. Create a LVM Physical Volume, a Volume Group and a Logical Volume ( wiki:LVM )
  2. Create a filesystem on the lvm volume
  3. mkdir $GuestRoot
  4. mount /dev/$GuestDisk $GuestRoot

Optional: Link the host and guest pacman cache

  1. mkdir $GuestRoot/var/cache/pacman/pkg
  2. mount -o bind /var/cache/pacman/pkg $GuestRoot/var/cache/pacman/pkg

Prepare Vserver

  1. vserver $GuestName -m skeleton --context $GuestContext --interface $GuestNetDevice:$GuestIP --flags lock,virt_mem,virt_uptime,virt_cpu,virt_load,sched_hard,hide_netif --initstyle plain
  2. (optional) cd /etc/vservers/$GuestName/interfaces
  3. (optional) cp -r 0 1
  4. (optional) echo 'lo' > dev
  5. (optional) echo '127.0.0.$GuestContext' > ip

Prepare the guest's filesystem

  1. Prepare guest filesystem for the pacman db
    1. mkdir -p /newarch/var/lib/pacman

Install the base system

NOTE : To save some time, it's probably a good idea to create a text file containing all the packages to install and call it via "pacman -S `cat $GuestPackages` -r $GuestRoot" instead of the following :

  1. pacman -S base -r $GuestRoot
  2. Optional: If you want to chroot into the newly created guest so as to install new packages, it might be a good idea to mount a few filesystems required by some packages.
    1. Bind /dev, /proc, /sys to the corresponding directories in $GuestRoot
  3. Modify guest configuration files to enable a smoother boot process
    1. Modify /etc/inittab by deleting all lines that create the consoles ( agetty )
    2. Modify /etc/rc.shutdown by removing anything hardware/clock/mount related. This includes most everything under Saving Random Seed'.
    3. Modify /etc/rc.sysinit by anything hardware/clock/mount related.
    4. Create /etc/init.d/rc
    5. Modify /etc/syslog-ng.conf by removing file("/proc/kmsg")
    6. Modify /etc/rc.conf by removing the networks Daemon.
  4. Ensure /etc/rc.* can be executed: "chmod +x /etc/rc.*"

Annexe : Configuration files modified

/etc/init.d/rc

if [ $1 -eq 3 ]; then
echo "entering runlevel 3:multi";
/etc/rc.multi
fi
if [ $1 -eq 6 ]; then
echo "entering runlevel 6:reboot";
/etc/rc.shutdown
fi
if [ $1 -eq 0 ]; then
echo "entering runlevel 0: shutdown";
/etc/rc.shutdown
fi
if [ $1 -eq 4 ]; then
echo "entering runlevel 4";
fi
if [ $1 -eq 5 ]; then
echo "entering runlevel 5";
fi
if [ $1 -eq 1 ]; then
echo "entering runlevel 1:single";
/etc/rc.single
fi
if [ $1 -eq 2 ]; then
echo "entering runlevel 2:multi";
/etc/rc.multi
fi

/etc/rc.sysinit

#!/bin/bash
#
# /etc/rc.sysinit
#

. /etc/rc.conf
. /etc/rc.d/functions

echo " "
printhl "Arch Linux\n"
printhl "${C_H2}https://www.archlinux.org"
printhl "Copyright 2002-2007 Judd Vinet"
printhl "Copyright 2007-2009 Aaron Griffin"
printhl "Distributed under the GNU General Public License (GPL)"
printsep


# start up our mini logger until syslog takes over
/sbin/minilogd

if [ -x /sbin/udevadm ]; then
	stat_busy "Starting UDev Daemon"
	/sbin/udevd --daemon
	stat_done
else
	# Static /dev, our last resort
	status "Using static /dev filesystem" true
fi

# Trigger udev uevents
if /bin/pidof -o %PPID /sbin/udevd >/dev/null; then
  stat_busy "Triggering UDev uevents"
  /sbin/udevadm trigger
  stat_done
fi
  NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk,noglusterfs"

stat_busy "Mounting Local Filesystems"
/bin/rm -f /etc/mtab*
# Write /proc, /sys and /dev to /etc/mtab
if [ -e /proc/mounts ]; then
	/bin/grep -e "rootfs" -e "/proc " -e "/sys " -e "/dev " /proc/mounts >>    /etc/mtab
fi
stat_done
 
stat_busy "Configuring System Clock"
if [ ! -f /var/lib/hwclock/adjtime ]; then
	echo "0.0 0 0.0" > /var/lib/hwclock/adjtime
fi
if [ "$TIMEZONE" != "" -a -e "/usr/share/zoneinfo/$TIMEZONE" ]; then
	/bin/rm -f /etc/localtime
	/bin/cp "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
fi

if [ -n "$HWCLOCK_PARAMS" ]; then
	/sbin/hwclock --adjust #Adjust for system drift
	/sbin/hwclock $HWCLOCK_PARAMS
fi
stat_done

RANDOM_SEED=/var/lib/misc/random-seed
if [ -f $RANDOM_SEED ]; then
	stat_busy "Initializing Random Seed"
	/bin/cat $RANDOM_SEED > /dev/urandom
	stat_done
fi

stat_busy "Removing Leftover Files"
/bin/rm -f /etc/nologin &>/dev/null
/bin/rm -f /etc/shutdownpid &>/dev/null
/bin/rm -f /var/lock/* &>/dev/null
/bin/rm -rf /tmp/* /tmp/.* &>/dev/null
/bin/rm -f /forcefsck &>/dev/null
(cd /var/run && /usr/bin/find . ! -type d -exec /bin/rm -f -- {} \; )
: > /var/run/utmp
/bin/chmod 0664 /var/run/utmp
# Keep {x,k,g}dm happy with xorg
/bin/mkdir /tmp/.ICE-unix && /bin/chmod 1777 /tmp/.ICE-unix
/bin/mkdir /tmp/.X11-unix && /bin/chmod 1777 /tmp/.X11-unix
stat_done

#status "Updating Shared Library Links" /sbin/ldconfig

if [ "$HOSTNAME" != "" ]; then
	status "Setting Hostname: $HOSTNAME" /bin/hostname $HOSTNAME
fi

# Set the NIS domain name, if necessary
[ -f /etc/conf.d/nisdomainname ] && . /etc/conf.d/nisdomainname
if [ "$NISDOMAINNAME" != "" ]; then
	status "Setting NIS Domain Name: $NISDOMAINNAME" /bin/nisdomainname  $NISDOMAINNAME
fi

status "Updating Module Dependencies" /sbin/depmod -A

# Flush old locale settings
: >/etc/profile.d/locale.sh
/bin/chmod 755 /etc/profile.d/locale.sh
# Set user defined locale
[ -z "$LOCALE" ] && LOCALE="en_US"
stat_busy "Setting Locale: $LOCALE"
echo "export LANG=$LOCALE" >>/etc/profile.d/locale.sh
stat_done

# Adding persistent network/cdrom generated rules
if [ -f "/dev/.udev/tmp-rules--70-persistent-cd.rules" ]; then
	stat_busy "Adding persistent cdrom udev rules"
	/bin/cat /dev/.udev/tmp-rules--70-persistent-cd.rules >> /etc/udev/rules.d/70-persistent-cd.rules
	stat_done
fi
if [ -f "/dev/.udev/tmp-rules--70-persistent-net.rules" ]; then
	stat_busy "Adding persistent network udev rules"
	/bin/cat /dev/.udev/tmp-rules--70-persistent-net.rules >> /etc/udev/rules.d /70-persistent-net.rules
	stat_done
fi

/bin/dmesg >| /var/log/dmesg.log

# End of file
# vim: set ts=2 noet:

/etc/rc.shutdown

#!/bin/bash
#
# /etc/rc.shutdown
#

. /etc/rc.conf
. /etc/rc.d/functions

# avoid staircase effect
/bin/stty onlcr

echo " "
printhl "Initiating Shutdown..."
echo " "

# avoid NIS hanging syslog-ng on shutdown by unsetting the domainname
if [ -x /bin/domainname ]; then
	/bin/domainname ""
fi

if [ -x /etc/rc.local.shutdown ]; then
	/etc/rc.local.shutdown
fi

if [ "$PREVLEVEL" = "3" -o "$PREVLEVEL" = "5" ]; then
	# Find daemons NOT in the DAEMONS array. Shut these down first
	if [ -d /var/run/daemons ]; then
		for daemon in $(/bin/ls -1t /var/run/daemons); do
		  if ! in_array $daemon ${DAEMONS[@]}; then
				stop_daemon $daemon
		  fi
		done
	fi
	# Shutdown daemons in reverse order
	let i=${#DAEMONS[@]}-1
	while [ $i -ge 0 ]; do
		if [ "${DAEMONS[$i]:0:1}" != '!' ]; then
			ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@}
		fi
        let i=i-1
    done
fi

# Terminate all processes
stat_busy "Sending SIGTERM To Processes"
/sbin/killall5 -15 &> /dev/null
/bin/sleep 5
stat_done

stat_busy "Sending SIGKILL To Processes"
/sbin/killall5 -9 &> /dev/null
/bin/sleep 1
stat_done

# Write to wtmp file before unmounting
/sbin/halt -w

# Power off or reboot
if [ "$RUNLEVEL" = "0" ]; then
	printsep
    printhl "${C_H2}POWER OFF"
	/sbin/poweroff -d -f -h -i
else
	printsep
	printhl "${C_H2}REBOOTING"
	# if kexec is installed and a kernel is loaded, use it
	[ -x /sbin/kexec ] && /sbin/kexec -e > /dev/null 2>&1
	/sbin/reboot -d -f -i
fi

# End of file
# vim: set ts=2 sw=2 noet:

Troubleshooting

Viewing output from vserver $GuestName start / stop

NOTE : For me, this only worked in the actual consoles, not in X.

  1. Make sure that the device /dev/console exists in the guest
    1. If it does not, cp -a /dev/console $GuestRoot/dev/

SSH will not start

I noticed that /dev/null did not always get created properly in my first experimentations. Therefore I did a quick :

  1. cp -a /dev/null $GuestRoot/dev
  2. cp -a /dev/zero $GuestRoot/dev

Furthermore, if you're not using the dummy network driver and are attaching to the host's network interface, you'll want to configure the ListenAddress statement of /etc/ssh/sshd_config so that it binds only to the guest's IP address as opposed to 127.0.0.1.

SSH immediately terminates the connection

On my machine, SSH used to authenticate me correctly and log me in, but then immediately drop the connection without an explanation. Consulting /var/log/auth.log revealed the following:

sshd[17899]: pam_limits(sshd:session): Could not set limit for 'nice': Operation not permitted

This is easily fixed by commenting all nice related lines in /etc/security/limits.conf.

Tips & Trick

Network via dummy adapters

Here, you're either using the dummy module to create virtual network adapters or created interface aliases via /usr/sbin/ip or /usr/sbin/ifconfig. I went for the former and configured the host as such :

  1. /etc/sysctl.conf : net.ipv4.ip_forward=1

Modify or add that statement to enable routing on the host

  1. /etc/rc.local
modprobe dummy numdummies=$NumberOfGuests
ip link set dev dummy$GuestContext name $GuestName

This provides me with dummy interfaces that I can route / firewall that are all named the same as my guests... yay.

More Resources

Problematic Programs
Make BSD style init SYSV compatible
Vserver tutorial
linux-vserver.org's Installation on ArchLinux
linux-verserver.org's networking tutorial