Fedora GNOME desktop on top of Debian KDE desktop
Would you like to try running the latest release of PCBSD? Or perhaps you want to check out systemd in the latest Fedora-ARM release? Or maybe you need a clean build environment for packaging? Perhaps you want to learn to use gparted to repartition a disk, but don't want to practice on your real disk? Qemu is a simple and safe way to run a different operating system for your host architecture (with the KVM hypervisor) or for a different one (plain Qemu without KVM). In the first case, Qemu environments allow a much richer experience than live-booting a USB stick or CD. In the cross-architecture case, Qemu is one of few open-source emulator alternatives.
Right now, Docker is all the rage, but Docker is based on Linux's lxc containers. Lxc containers share a kernel and thus do not allow cross-arch testing. On the other hand, Qemu virtual machines running a different kernel are much slower than containers.
Host's physical CPU and guest's virtual one differ, as the "model name" strings from /proc/cpuinfo show. Here the virtual CPU is single-core, unlike the quad core that the laptop possesses. The vCPU can also have a different architecture than the host.
There are probably better ways to perform the following steps than I outline here, and I'm happy to receive corrections or suggestions. These instructions have worked for me, and are distilled from a large amount of sometimes confusing and lengthy documentation.
Note: in what appears below, "hildesheim" is my laptop and "localhost" is the QEMU-encapsulated guest.
>Install needed software packages
On Debian Testing,
apt-get install dnsmasq-utils dnmasq resolvconf libvirt0 qemu qemu-kvm qemu-system-arm qemu-user bridge-utils libvirt-bin libvirt0
Install the guest OS on a virtual disk
Virtual machines are big fun! But they can be space hogs. I recommend installing them on an old spare drive mounted in a USB enclosure.
Example: here's a bash script that uses an ISO image downloaded from fedoraproject.org to install Fedora 21 in a Qemu-kvm VM. The "--enable-kvm" switch will work only if the host and image architectures are the same. Similarly, qemu-system-x86_64 is for x86-on-x86 guests.
#!/bin/bash #run with "sudo -u alison ~alison/bin/install_Ubuntu_IVI_Qemu" #Without -u, xauth error: #"Could not initialize SDL(No available video device) - exiting" ROOTDIR=/mnt/VMs/ ISO=Fedora-Live-Desktop-x86_64-20-1.iso HDNAME=fedora-x86_64-bldr sudo qemu-img create -f raw ${ROOTDIR}/${HDNAME}.raw 100G sudo chown alison ${ROOTDIR}/${HDNAME}.raw #installs from "cdrom" onto "hard disk a" qemu-system-x86_64 --enable-kvm --cdrom ${ROOTDIR}/${ISO} -boot d -hda ${ROOTDIR}/${HDNAME}.raw -m 2048 -net nic,model=e1000 -net user,hostfwd=tcp:127.0.0.1:6666-:22 -name ${HDNAME} -localtime -no-reboot
The ROOTDIR is where the virtual disk of the VM is located. Note that the script specifies a "raw" image of size 100 GB. See the man page for qemu-img for more information.
Mounting virtual disk on host and examining its contents. Note the offset number 1048576 = (* 2048 512) to mount /boot and 2672820224 = (* 5220352 512) to mount /.
The figure above shows the default partition table and filesystems created by the Fedora installer. Loop-mounting the .raw disk allows the user to create a different partition table before installation, or to directly copy files in and out of the VM without booting it. Loop mounts are therefore useful for VM backup or cloning.
The "chown" is necessary if you want to be able to boot the VM without root permission. The "m" switch allocates memory from your host to the VM. The "-no-reboot" allows switching from installer script above to the normal starter one below.
Run the guest OS
#!/bin/bash ROOTDIR=/mnt/VMs/ HDNAME=fedora-x86_64-bldr qemu-system-x86_64 --enable-kvm -boot c -hda ${ROOTDIR}/${HDNAME}.raw -m 4096 -net nic,model=e1000 -net user,hostfwd=tcp:127.0.0.1:6666-:22 -name ${HDNAME} -localtime
Note that this script specifies 4 GB of virtual RAM while the one above specified 2 GB. In fact these parameters are freely specifiable at boot time. Similarly, features like audio or network can be changed at every boot.
Also see OpenEmbedded's fine Testing with QEMU page, especially the runqemu command.
Set up networking
Reference: libvirt.org.
The option "-net user,hostfwd=tcp:127.0.0.1:6666-:22" means that port 22 on the guest is forwarded to port 6666 on the host. Thus it is possible to remotely login to the guest from the host via sessions like:
ssh -p 6666 username@127.0.0.1 username@127.0.0.1's password:or from the guest to the host with
ssh username@10.0.2.2
I don't know where "10.0.2.2" configuration is specified.
Start by configuring the host machine to allow bridge networking. Begin by installing the packages listed at the top of this page.
[alison@localhost ~]$ sudo virsh net-define /etc/libvirt/qemu/networks/default.xml error: Failed to define network from /etc/libvirt/qemu/networks/default.xml error: operation failed: network 'default' already exists with uuid a3f2e4f4-661c-41e9-9735-11866e62d29b [alison@localhost ~]$ sudo virsh net-autostart default Network default marked as autostarted [alison@localhost ~]$ sudo virsh net-start default Network default started
Now the virbr0 network interface is available from the host:
[alison@@hildesheim ~]$ ip addr list 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default [ . . . ] 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 [ . . . ] 3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 [ . . . ] 5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 82:7c:ac:76:38:75 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever [alison@@hildesheim ~] brctl show bridge name bridge id STP enabled interfaces virbr0 8000.000000000000 yes
Fedora guest interfaces and "yum update"
Then set up packet-forwarding to the guest via the host:
[alison@hildesheim ~]$ sudo emacs -nw /etc/sysctl.conf # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1
And set up the dnsmasq DNS server on host by changing the global /etc/dnsmasq.conf as follows:
Either:
interface=eth0
or
listen-address=192.168.0.1
(Replace interface or listen-address with the interfaces or addresses on which you want your global dnsmasq to answer.) Uncomment the following line to tell dnsmasq to only bind specific interfaces, not try to bind all interfaces:
bind-interfaces