Index.
- Introduction.
- Install VirtualBox.
- Create the Virtual Machine.
- Add init scripts.
- Special hardware.
- Download.
17-Jun-2011: initial release. 25-Aug-2011: update special hardware advice. 29-Aug-2011: replaced VDE network with host-only network. 06-Sep-2011: withdrawn special hardware advice. 06-Nov-2011: changed host-only network setup. 29-Dec-2011: removed host-only script parts.
Introduction.
In the article Home Server Planning you could see how a virtual server fits into our home server design. This article will show how to add a virtual server and it shows how to make it start and stop automatic when your Home Server starts and stops. The virtualization solution is VirtualBox by Oracle.
We need to reserve two new networks, we take the ranges from the whole reserved network space, see the updated table below. The network between the server and gateway will be a VirtualBox host-only network, the network between the gateway and the web server will be an internal Virtualbox network.
| IPv4 | Remark |
|---|---|
| 10.126.160.0/24 | Workstations LAN |
| 10.126.161.0/24 | Server/Gateway vboxnet0 LAN |
| 10.126.162.0/24 | DMZ LAN |
| 10.126.163.0/24 | Spare |
| 10.126.164.0/24 | Spare |
| 10.126.165.0/24 | Spare |
| 10.126.166.0/24 | Spare |
| 10.126.167.0/24 | Spare |
First, a reminder of what the configuration will look like in the future. In this article the network between the host and the Gateway server will be added.
Install VirtualBox.
Install the needed packages with with the command: pacman -S –needed virtualbox. Next we must create the account that will be used to run on virtual servers. You first need to get the group GID number so that you can use the same number for UID. The home directory of the new user will be set on the special partition that we have created during LVM setup.
[root@homsrv ~]# grep vboxusers /etc/group
vboxusers:x:108:
[root@homsrv ~]# adduser
Login name for new user []: vboxhost
User ID ('UID') [ defaults to next available ]: 108
Initial group [ users ]: vboxusers
Additional groups (comma separated) []:
Home directory [ /home/vboxhost ] /mnt/vserver/virtualbox
Shell [ /bin/bash ] /bin/bash
Expiry date (YYYY-MM-DD) []:
New account will be created as follows:
---------------------------------------
Login name.......: vboxhost
UID..............: 108
Initial group....: vboxusers
Additional groups: [ None ]
Home directory...: /var/lib/virtualbox
Shell............: /bin/bash
Expiry date......: [ Never ]
This is it... if you want to bail out, hit Control-C. Otherwise, press
ENTER to go ahead and make the account.
Creating new account...
Changing the user information for vboxhost
Enter the new value, or press ENTER for the default
Full Name []: VirtualBox Headless
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Account setup complete.
[root@homsrv ~]#
Create the Virtual Machine.
I assume that you don’t have X installed on your home server, so we will use another Linux workstation with X to do the virtualbox configuration using the graphic tool. You need to enable X forwarding on your Home Server to get that to work. In /etc/ssh/sshd_config find the line #X11Forwarding no and change it to X11Forwarding yes. On your workstation in /etc/ssh/ssh_config you need the lines:
Host * ForwardX11 yes
The VM VirtualBox Extension pack is not distributed by Arch Linux, you need to download that yourself. The extension pack is needed so that you can use RDP to access the virtual machines consoles over the network. Copy the downloaded file to your Home Server in the new vboxhost user home directory. Issue the following commands on your workstation to show the Home Server virtualbox GUI:
mbroek@seaport:~$ xhost + access control disabled, clients can connect from any host mbroek@seaport:~$ ssh homsrv -l vboxhost vboxhost@homsrv's password: Last login: Wed Jun 8 15:42:54 2011 from seaport.wpl.ym Welcome at localhost.localdomain - DISPLAY on localhost:10.0 Wed Jun 8 15:46:56 CEST 2011 [vboxhost@homsrv ~]$ virtualbox Qt WARNING: X Error: BadAccess (attempt to access private resource denied) 10 Major opcode: 2 (X_ChangeWindowAttributes) Resource id: 0x15c Xlib: extension "SYNC" missing on display "localhost:10.0".
If you do have X installed on your Home Server, login as user vboxhost and start the VirtualBox GUI.
First select File->Preferences->Extensions and install the VM Virtualbox Extension pack.Next in File->Preferences->Network create or edit the first Host-Only network. No DHCP and set the address to 10.126.161.1 and netmask 255.255.255.0. This would be vboxnet0.
Then you can create the first virtual machine, for example the gateway server. Create the machine with the following settings:
- Linux, type Arch Linux.
- 256 MB Ram, we will lower that later.
- 8 GB Expandable harddisk.
- Settings->System->Motherboard no floppy.
- Settings->System->Motherboard no UTC time.
- settings->Display->Remote Display set Enable Server on and port to 5000 or so.
- Settings->Storage->IDE point CD to the Arch install iso.
- Settings->Audio off.
- Settings->Network->Adapter 1 set to Host-only adapter ‘vboxnet0′.
- Settings->Network->Adapter 2 set to Bridged eth1.
- Settings->Network->Adapter 3 set to Internal Network ‘WPL-DMZ’.
It is a good idea to note the network adapter MAC addresses while you set the Network settings. It is always possible that the network cards get switched during installation of the OS.
In this example you see a bridged network card and two network cards that are connected to two VDE networks. Today the VDE networks are replaced by VirtualBox networks.
Now you should be able to start the machine and install Arch Linux. Just do a base install only.
Add init scripts.
Next we will make it so that our new virtual machine will start and stop automatic when the home server starts or stops. There are no scripts for a headless solution, so we must make our own scripts. First create /etc/vbox/autorun.cfg:
# /etc/vbox/autorun.cfg
#
# Configuration of machines that should run headless in the background.
# These machines must be present in the home directory of the "vboxhost"
# account.
# This file is sourced by /etc/rc.d/rc.virtualbox
# Account to use.
VBOXHOST="vboxhost"
i=0
# Machine definitions, add them in the order to start. They will be stopped
# in the reverse order. Remmember to add a line to increase $i after each
# machine.
VBOX_NAME[$i]="MBSE Gateway" # name of the machine
VBOX_UUID[$i]="02117c0e-9fe0-492a-8ff2-b4ffe0f94960" # uuid of the machine
VBOX_AUTO[$i]="true" # true to start this
# machine
VBOX_STOP[$i]="acpipowerbutton" # or acpibutton
VBOX_PORT[$i]=5000 # RDP port
i=$(($i+1)) # next
Then create /etc/rc.d/vboxhost:
#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions
. /etc/vbox/vbox.cfg
. /etc/vbox/autorun.cfg
DEVICE=/dev/vboxdrv
GROUPNAME=vboxusers
MODPROBE=/sbin/modprobe
# Should be a bit longer then the slowest machine needs.
# This script kills machines after this timeout.
STOPTIME=60
running()
{
lsmod | grep -q "$1[^_-]"
}
start_kernel()
{
if ! running vboxdrv; then
stat_busy "Starting VirtualBox kernel modules"
if ! $MODPROBE vboxdrv > /dev/null 2>&1; then
stat_fail
return
fi
sleep .2
if ! running vboxnetflt; then
if ! $MODPROBE vboxnetflt > /dev/null 2>&1; then
stat_fail
return
fi
fi
if ! running vboxnetadp; then
if ! $MODPROBE vboxnetadp > /dev/null 2>&1; then
stat_fail
return
fi
fi
add_daemon vboxhost
stat_done
fi
}
run_machine()
{
# Don't start a running machine
su $VBOXHOST -c "VBoxManage showvminfo ${VBOX_UUID[$1]} |grep '^State:' \
|grep 'running' >/dev/null" && {
return
}
# Start the machine
stat_busy "Starting VirtualBox machine \"${VBOX_NAME[$i]}\""
su $VBOXHOST -c "VBoxHeadless --startvm ${VBOX_UUID[$1]} --vrdeproperty \
TCP/Ports=${VBOX_PORT[$1]} 1>/dev/null 2>/dev/null" &
if [ $? -gt 0 ]; then
stat_fail
else
add_daemon vboxhost
stat_done
fi
sleep .5
}
start_autorun()
{
i=0
export VBOX_IPC_SOCKETID="$VBOXHOST"
while [ true ]; do
[ "${VBOX_UUID[$i]}" = "" ] && break;
if [ "${VBOX_AUTO[$i]}" = "true" ]; then
run_machine $i
fi
i=$(($i+1))
done
}
stop_autorun()
{
# See how many machines are defined
i=0
while [ true ]; do
[ "${VBOX_UUID[$i]}" = "" ] && break;
i=$(($i+1))
done
j=$i
# Stop the machines
s=0
export VBOX_IPC_SOCKETID="$VBOXHOST"
while [ $i -gt 0 ]; do
i=$(($i-1))
if [ "${VBOX_AUTO[$i]}" = "true" ]; then
su $VBOXHOST -c "VBoxManage --nologo showvminfo ${VBOX_UUID[$i]} \
|grep '^State:' |grep 'running' >/dev/null" && {
stat_busy "Shutdown VirtualBox machine \"${VBOX_NAME[$i]}\""
s=1
su $VBOXHOST -c "VBoxManage --nologo controlvm ${VBOX_UUID[$i]} \
${VBOX_STOP[$i]}" 1>/dev/null
if [ $? -gt 0 ]; then
stat_fail
else
stat_done
fi
}
fi
done
if [ $s -gt 0 ]; then
stat_busy "Waiting until all machines are stopped"
# If we stopped some machines using the power button, we must wait until
# the shutdown is completed before we can continue. At least one second
# is wasted here else module unloading will fail.
i=0
while [ $i -lt $STOPTIME ]; do
sleep 1
VMS=$(su $VBOXHOST -c "VBoxManage --nologo list runningvms 2>/dev/null")
[ -z "$VMS" ] && break;
i=$(($i+1))
done
if [ $i -ge $STOPTIME ]; then
# Still some machines running, do it the hard way...
i=$j
while [ $i -gt 0 ]; do
i=$(($i-1))
if [ "${VBOX_AUTO[$i]}" = "true" ]; then
su $VBOXHOST -c "VBoxManage --nologo showvminfo ${VBOX_UUID[$i]} \
|grep '^State:' |grep 'running' >/dev/null" && {
su $VBOXHOST -c "VBoxManage --nologo controlvm ${VBOX_UUID[$i]} \
poweroff" 1>/dev/null 2>/dev/null
}
fi
done
stat_fail
else
stat_done
fi
fi
}
dmnstatus()
{
if running vboxdrv; then
if running vboxnetflt; then
if running vboxnetadp; then
echo "VirtualBox kernel modules (vboxdrv, vboxnetflt and \
vboxnetadp) are loaded."
else
echo "VirtualBox kernel modules (vboxdrv and vboxnetflt) are loaded."
fi
else
echo "VirtualBox kernel module is loaded."
fi
for i in $SHUTDOWN_USERS; do
# don't create the ipcd directory with wrong permissions!
if [ -d /tmp/.vbox-$i-ipc ]; then
export VBOX_IPC_SOCKETID="$i"
VMS=$(su $i -c "/usr/bin/VBoxManage --nologo list runningvms 2>/dev/null")
if [ -n "$VMS" ]; then
echo
echo "The following VMs are for user '$i' are currently running:"
echo "$VMS"
fi
fi
done
# Now list system wide autorun machines
export VBOX_IPC_SOCKETID="$VBOXHOST"
VMS=$(su $VBOXHOST -c "VBoxManage --nologo list runningvms 2>/dev/null")
if [ -n "$VMS" ]; then
echo
echo "The following system wide VMs are currently running:"
echo "$VMS"
fi
else
echo "VirtualBox kernel module is not loaded."
fi
}
case "$1" in
start)
start_kernel
start_autorun
;;
stop)
stop_autorun
;;
status)
dmnstatus
;;
restart)
stop_autorun
sleep 1
start_autorun
;;
*)
echo "usage: $0 {start|stop|status|restart}"
esac
exit 0
Now add vboxhost in the DAEMONS=() line in /etc/rc.conf right before the network entry. It needs to start before the rest of the network because the host-only network for the virtual gateway needs to be configured when the network starts so that the default route can be set. When you now reboot your Home Server you should see that the virtual machine is automatic stopped and started.
Special hardware.
The standard Arch Linux kernels contain the virtio network adapters. I have used them for a couple of days, and they have a speed increase over the standard Intel PRO/1000 driver. But they have serious problems too. On the web server under heavy load a lot of kernel errors were logged which pointed to memory corruption. Between other machines network traffic could be stalled. So I leave this text here as a reminder, the current virtio driver from kernel 3.0.4 (at the time of this writing) are not usable.
Download.
The needed scripts and configuration files upto this article can be downloaded from the following archive. The Firewall Builder configuration files are included, see the examples/homsrc/etc/iptables directory. Just unpack this archive in your home directory to see what you can use.


