VirtualBox

From Segfault
Jump to navigation Jump to search

Installation

Installing VirtualBox is pretty easy these days, across all host operating systems. Apparently it wasn't always this easy so there are some (outdated) notes on the install process.

For Linux, the following repositories can be added:

deb http://download.virtualbox.org/virtualbox/debian jessie contrib                       # Debian
deb http://download.virtualbox.org/virtualbox/debian vivid contrib                        # Ubuntu

See Oracle Linux Yum Server for Yum based distributions.

Add the public key:

wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -      # Debian, Ubuntu
wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo rpm --import -     # Fedora

Usage

Let's create a virtual machine:

VDIR=/mnt/data/vm
NAME=fedora0
mkdir -p $VDIR/$NAME/snapshots

VBoxManage createhd --filename $VDIR/$NAME/"$NAME"_disk0.vdi --size 4096
VBoxManage createvm --name $NAME --ostype Fedora_64 --register --basefolder $VDIR

Note: use "VBoxManage list ostypes" to find out valid values for "ostype".

Before we can modify the VM to use briged networking[1], we have to find out the exact interface name of the host interface:

$ VBoxManage list bridgedifs | grep ^Name
Name:            en1: Wi-Fi (AirPort)
Name:            en0: Ethernet
Name:            p2p0

We want to use "en1":

VBoxManage modifyvm $NAME --memory 1024 --cpus 2 --boot1 dvd --boot2 disk --boot3 none --boot4 none \
           --chipset ich9 --nic1 bridged --nictype1 virtio --bridgeadapter1 "en1: Wi-Fi (AirPort)" \
           --macaddress1 080027123456 --audio none --vrde on --vrdeport 3139 --usb off \
           --snapshotfolder $VDIR/$NAME/snapshots

Note: you might have to adjust the values for bridgeadapterN and nictypeN and choose values according to your host-OS and your guest-OS.


We will need storage too:

VBoxManage storagectl $NAME --name sata0 --add sata --portcount 2 --hostiocache on

VBoxManage storageattach $NAME --storagectl sata0 --port 0 --device 0 --type hdd \
           --medium $VDIR/$NAME/"$NAME"_disk0.vdi --nonrotational on --discard on 

VBoxManage storageattach $NAME --storagectl sata0 --port 1 --device 0 --type dvddrive \
           --medium /mnt/data/install.iso

Note: add "--nonrotational on" and "--discard on" for SSD devices.

With that in place, the VM should be able to boot:

VBoxHeadless -startvm $NAME &

Change the boot order after installation:

vboxmanage modifyvm $NAME --boot1 disk --boot2 none

Poweroff/Reset the VM:

VBoxManage controlvm $NAME poweroff
VBoxManage controlvm $NAME reset

If we're done playing around with the VM, we can destroy it:

VBoxManage storagectl $NAME --name sata0 --remove
VBoxManage unregistervm $NAME --delete
VBoxManage closemedium disk $VDIR/$NAME/"$NAME"_disk0.vdi --delete

Install an extension pack:

VER=$(vboxmanage -v | cut -dr -f1)                                          # Should display somehing like 4.3.28
wget http://dlc-cdn.sun.com/virtualbox/$VER/Oracle_VM_VirtualBox_Extension_Pack-$VER.vbox-extpack
sudo vboxmanage extpack install --replace Oracle_VM_VirtualBox_Extension_Pack-$VER.vbox-extpack
sudo vboxmanage extpack cleanup

If installed properly:

$ vboxmanage list extpacks
Extension Packs: 1
Pack no. 0:   Oracle VM VirtualBox Extension Pack
Version:      4.3.28
Revision:     100309
Edition:      
Description:  USB 2.0 Host Controller, Host Webcam, VirtualBox RDP, PXE ROM with E1000 support.
VRDE Module:  VBoxVRDP
Usable:       true 
Why unusable:

Networking

There are several network modes available in VirtualBox. In short:

NAT

  • Guests are configured via DHCP, VirtualBox will act as DHCP server (10.0.2.0/24)
  • Guests can see each other
  • Incoming connections are only possible with portforwarding (in the VM settings)

Bridged Adapter

  • Guests will be connected to the hosts' network and will have the same connectivity as the host
  • Guests can see each other
  • Incoming connections are possible

Internal Network

  • Guests are in a private network (10.0.2.0/24), but will have to be configured manually, as VirtualBox will not act as an DHCP server
  • No incoming connections possible, as not even the host will have routes to this network

Host-only Adapter

  • Guests are in a private network (192.168.56.0/24), but will have to be configured manually, as VirtualBox will not act as an DHCP server
  • No incoming connections possible, as not even the host will have routes to this network

See also: VirtualBox and Networking – How you do it

Serial Console

The Serial Console can be enabled in the VM settings. Specify a socket for the taget with the following settings:

  • COM1
  • Host-pipe
  • create pipe
  • path to socket

Or, via the command line:

VBoxManage modifyvm VMNAME --uartmode1 server /virtualbox/VMNAME/serial.sock

Then we'll use socat to connect the socket to a network port:

socat -d tcp-listen:1234,bind=localhost,reuseaddr,fork ../serial.socket &
telnet localhost 1234

With newer versions[2] of VirtualBox, we can skip the socket file altogether and attach the serial port to a network port:

VBoxManage modifyvm VMNAME --uartmode1 tcpserver 2001

Virtual Disks

Overview

Virtual disks can have various formats[3] and variants [4] when creating a new disk:

$ vboxmanage createhd 
VBoxManage createmedium     [disk|dvd|floppy] --filename <filename>
                            [--size <megabytes>|--sizebyte <bytes>]
                            [--diffparent <uuid>|<filename>
                            [--format VDI|VMDK|VHD] (default: VDI)
                            [--variant Standard,Fixed,Split2G,Stream,ESX]
--format
VDI Virtualbox
VMDK VMware
VHD Microsoft Virtual PC
--variant
Standard sparse (dynamically allocated storage, resizable)
Fixed flat (fixed size, not resizable)
Split2G flat, split into 2GB chunks (for FAT16)
Stream optimized for streaming downloads, can be compressed
ESX ?

Several write modes[5] are supported:

$ vboxmanage modifymedium
VBoxManage modifymedium    [disk|dvd|floppy] <uuid|filename>
                           [--type normal|writethrough|immutable|shareable|
                                   readonly|multiattach]
                           [--autoreset on|off]
                           [--property <name=[value]>]
                           [--compact]
                           [--resize <megabytes>|--resizebyte <bytes>]
                           [--move <path]
                           [--description <description string>]
--type
normal can only be used by one running VM default
writethrough can only be used by one running VM unaffected by snapshots
immutable backing device will not be modified all writes from the guest are lost afterwards
shareable can be attached to more than one VM unaffected by snapshots -- Fixed disks only!
readonly can be attached to more than one VM readonly
multiattach can be attached to more than one VM writes are contained within each VM and preserved

Note: ideally we would use a Standard VDI disk (resizable) set to writethrough, to have it available (but not necessarily used) in different running VMs, but that's not possible. A shareable disk could do that, but only Fixed disks can be set to that type, which is not resizable.

Usage

Let's attach and detach an already existing disk to one of our VMs. Find the disk UUID:

$ vboxmanage list hdds
[...]
UUID:           57f89693-f7a5-4221-8483-c9daa6352a1a
Parent UUID:    base
State:          locked write
Type:           normal (base)
Location:       /data/vm/disk03.vdi
Storage format: VDI
Capacity:       10240 MBytes
Encryption:     disabled

Find out the controller name:

$ vboxmanage showvminfo vm3 | grep Storage
Storage Controller Name (0):            SATA
Storage Controller Type (0):            IntelAhci
Storage Controller Instance Number (0): 0
Storage Controller Max Port Count (0):  30
Storage Controller Port Count (0):      2
Storage Controller Bootable (0):        on


Attach the disk:

vboxmanage storageattach vm3 --storagectl SATA --device 0 --port 1 \
           --type hdd --medium 57f89693-f7a5-4221-8483-c9daa6352a1a --hotpluggable on --nonrotational on --mtype shareable

Warning: we used the shareable disk type here!

Detach with:

vboxmanage storageattach vm3 --storagectl SATA --device 0 --port 1 --medium none

Compacting disks

While shrinking VirtualBox disks is not supported, we can compact[6] disks somewhat[7], so that the image on the host's disk can be reduced in size.

For that to happen, we have to fill the unused space in our guest OS with zeros.

In a Linux guest, we can use zerofree to do just that on a read-only ext2 partition:

# echo s > /proc/sysrq-trigger
# echo u > /proc/sysrq-trigger
# touch /foo
touch: cannot touch '/foo': Read-only file system

# zerofree -v /dev/sda1
449623/461670/2048000

On an unmounted ext2 partition we can also discard unused space[8] with a current version of e2fsprogs, provided the block device is TRIM capable:

e2fsck -E discard /dev/sda1

Or, in Windows with SDelete:

WIN10$ sdelete -z c:
SDelete is set for 1 pass.
Free space cleaned on C:\
1 drive cleaned.

Now for the actual compaction:

$ df -h /
Filesystem   Size   Used  Avail Capacity  Mounted on
/dev/disk1  118Gi  105Gi   13Gi    90%    /

$ for d in $(vboxmanage list hdds | awk '/^Location/ {print $NF}'); do
   echo "D: $d"
   vboxmanage modifymedium $d compact
   echo
done
D: /opt/vm/vbox/jessie1/jessie1.vdi
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
[...]

$ df -h /
Filesystem   Size   Used  Avail Capacity  Mounted on
/dev/disk1  118Gi   80Gi   38Gi    68%    /

Mounting disk

Mounting disks[9] on a foreign system can be accomplished with the help of qemu-nbd:

sudo modprobe nbd
sudo qemu-nbd -c /dev/nbd0 disk.vdi
sudo kpartx -a /dev/nbd0                                                     # Only needed if partitions are present

sudo mount /dev/mapper/nbd0 /mnt

Unconfigure with:

sudo umount /mnt
sudo qemu-nbd -d /dev/nbd0

Snapshots

If we forgot to set the snapshot directory correctly, we can do this afterwards (if no snapshots have been created yet):

VM=`VBoxManage list vms | awk -F\" '{print $2}'`

for vm in $VM; do
   VBoxManage "$vm" --snapshotfolder /mnt/data/vm/"$vm"/snapshots
   VBoxManage showvminfo "$vm" | grep Snapshot\ folder
done

Troubleshooting

MAC address collision

If you allow VirtualBox to dynamically assign MAC addresses for its VNICs, but only sometimes assign a static MAC address to a few VMs, collisions may occur. Here's how to find MAC addresses assigned to more than one VM:

 $ for i in `awk '/enabled=\"true\" MAC/ {print $4}' ~/Library/VirtualBox/Machines/*/*.xml | \
            sort | uniq -c | sort -n | awk '!/ 1 / {print $2}'`; do
  echo $i
  grep -l $i ~/Library/VirtualBox/Machines/*/*.xml
  echo
done

MACAddress="0800275A8F2D"
/Users/bob/Library/VirtualBox/Machines/debian/debian-1.9-macosx.xml
/Users/bob/Library/VirtualBox/Machines/debian/debian.xml

MACAddress="080027B56361"
/Users/bob/Library/VirtualBox/Machines/opensolaris-0/opensolaris-0.xml
/Users/bob/Library/VirtualBox/Machines/opensolaris-1/opensolaris-1.xml

MACAddress="0800276E26A5"
/Users/bob/Library/VirtualBox/Machines/nt4/nt4.xml

SMBus base address uninitialized

This comes up when a Linux machine starts up:

piix4_smbus 0000:00:07.0: SMBus base address uninitialized - upgrade BIOS or use force_addr=0xaddr

The message occurs somewhere in drivers/i2c/busses/i2c-piix4.c.[10]

So, upgrading the BIOS won't be possible, as the BIOS is presented by VirtualBox too:

$ dmidecode | grep -A3 ^BIOS
BIOS Information
       Vendor: innotek GmbH
       Version: VirtualBox
       Release Date: 12/01/2006

And force_addr=0xaddr works only if we know what to provide for "0xaddr" - which we don't. And it's deemed dangerous too:

$ modinfo i2c-piix4  | grep force_addr
parm:   force_addr:Forcibly enable the PIIX4 at the given address. EXTREMELY DANGEROUS! (int)

The only viable solution[11][12] appears to be to disable the i2c_piix4 kernel module:

$ grep i2c /etc/modprobe.d/local.conf 
blacklist i2c_piix4

Update initrd.img via:

update-initramfs -u -k all

The message should be gone on the next reboot. If we were to load the module again, the message appears again:

$ modprobe i2c-piix4 
$ lsmod | grep i2c
i2c_piix4              20864  0 
i2c_core               46012  1 i2c_piix4

$ dmesg -t -l err
piix4_smbus 0000:00:07.0: SMBus base address uninitialized - upgrade BIOS or use force_addr=0xaddr

Timekeeping

Try different clocksources[13][14], if needed:

$ time ssh linux-vm sleep 5
real    0m14.956s
user    0m0.031s
sys     0m0.010s

So, in the VM:

$ grep . /sys/devices/system/clocksource/clocksource0/{a,c}*
/sys/devices/system/clocksource/clocksource0/available_clocksource:kvm-clock tsc acpi_pm
/sys/devices/system/clocksource/clocksource0/current_clocksource:tsc

The acpi_pm clocksource appears to be working well enough for the VM.

VNC

Under Linux, we'll be able to connect to the virtual machines via VNC, but we have to setup authentication for that:

vboxmanage modifyvm VM --vrdeauthlibrary null
vboxmanage modifyvm VM --vrdeport 1234
vboxmanage modifyvm VM --vrdeproperty VNCPassword="s3cr3t"

MacOS X

Virtualizing MacOS X isn't quite as simple and requires major surgery in some cases. Some URLs first:

TBC...

Links

References