Index: virtualization/chapter.sgml
===================================================================
RCS file: /home/dcvs/doc/en_US.ISO8859-1/books/handbook/virtualization/chapter.sgml,v
retrieving revision 1.17
diff -u -p -r1.17 chapter.sgml
--- virtualization/chapter.sgml	28 Jul 2008 14:33:51 -0000	1.17
+++ virtualization/chapter.sgml	18 Aug 2008 17:36:31 -0000
@@ -54,6 +54,11 @@
 	  virtualization.</para>
       </listitem>
 
+      <listitem>
+	<para>How to run FreeBSD as guest in <application>qemu</application>
+	  and as a qemu host.</para>
+      </listitem>
+
     </itemizedlist>
 
     <para>Before reading this chapter, you should:</para>
@@ -958,6 +963,211 @@ xenbr1          8000.feffffffffff   no  
 
       </sect3>
     </sect2>
+
+    <sect2 id="virtualization-qemu-intro">
+      <title>What you should know about qemu</title>
+      <para>qemu's homepage is <ulink
+	url="http://bellard.org/qemu/">
+	http://bellard.org/qemu/</ulink>, documentation gets
+	installed (on &os;) as
+	<filename>/usr/local/share/doc/qemu/qemu-doc.html</filename> and
+	<filename>/usr/local/share/doc/qemu/qemu-tech.html</filename>, and
+	there also is a manpage.</para>
+      <para>Places to check other than the official documentation:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>The <filename>pkg-message</filename> of the relevant &os;
+	    port (can also be displayed via
+	    <screen>&prompt.user; <userinput>pkg_info -D qemu\* |less</userinput></screen>
+	    if a qemu port is installed.)</para>
+	</listitem>
+	<listitem>
+	  <para>The <ulink
+	    url="http://qemu.kidsquid.com/moin.cgi/FrequentlyAskedQuestions">
+	    unofficial #qemu FAQ</ulink> (many of the Linux-related notes
+	    there also apply to &os; hosts.).</para>
+        </listitem>
+	<listitem>
+	  <para>The <ulink
+	    url="http://qemu-forum.ipi.fi/">
+	    qemu forum</ulink> that also has howtos/patches/svn snapshots.
+	    (actually at the time of writing the snapshots are apparently
+	    still checked out from cvs and are old as such, you can go
+	    to a <ulink
+	    url="http://repo.or.cz/w/qemu.git">
+	    git mirror of the qemu svn</ulink> to get snapshots, note
+	    however that upstream qemu sources don't build on &os; without
+	    changes.)</para>
+	</listitem>
+	<listitem>
+	  <para>The <ulink
+	    url="http://lists.gnu.org/archive/html/qemu-devel/">
+	    qemu-devel mailing list archive</ulink>.</para>
+	</listitem>
+	<listitem>
+	  <para>The <ulink
+	    url="http://lists.freebsd.org/pipermail/freebsd-emulation/">
+	    freebsd-emulation mailing list archive</ulink>.</para>
+	</listitem>
+      </itemizedlist>
+      <para>If you still have a question after checking the above you can
+	join the official qemu irc channel
+	<ulink url="irc://irc.freenode.net/#qemu">
+	&#35;qemu on freenode irc</ulink> (see maybe the
+	<ulink url="http://en.wikipedia.org/wiki/Irc">
+	Wikipedia article on irc</ulink> and 
+	<ulink url="http://freenode.net/using_the_network.shtml">
+	http://freenode.net/using_the_network.shtml</ulink>
+	if you are new to irc), or post a question on the <ulink
+	url="http://lists.freebsd.org/mailman/listinfo/freebsd-emulation">
+	freebsd-emulation mailing list</ulink> if the question is
+	&os;-specific, or on the <ulink
+	url="http://lists.gnu.org/mailman/listinfo/qemu-devel">
+	qemu-devel mailing list</ulink> if it concerns qemu in general.
+	Or you can join the mentioned <ulink
+	url="http://qemu-forum.ipi.fi/">
+	qemu webforum</ulink> and post the question there.</para>
+      <para>General things you should know:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>For best results always try the latest version
+	    (0.9.1 as of this writing)
+	    or even an svn checkout or on &os; the
+	    <filename role="package">emulators/qemu-devel</filename>
+	    port.</para>
+	</listitem>
+	<listitem>
+	  <para>qemu's userland networking (<command>-net user</command>,
+	    also called slirp,
+	    which is the default) is not really stable on 64 bit hosts,
+	    so you probably need to use tuntap there (see also
+	    <xref linkend="virtualization-host-qemu-tuntap">
+	    if this is for a &os; host.)</para>
+	</listitem>
+	<listitem>
+	  <para>You need to use <command>qemu-system-x86_64</command>
+	    if you want to emulate
+	    amd64 guests, or if you want to use kqemu on amd64 hosts.
+	    (actually the latter is no longer true for qemu svn and the 
+	    <filename role="package">emulators/qemu-devel</filename>
+	    port at the time of writing.)</para>
+	</listitem>
+	<listitem>
+	  <para>You can try <command>pcnet</command>,
+	    <command>i82557b</command> or <command>e1000</command>
+	    (the latter not yet
+	    in 0.9.1), especially with BSD/Linux guests as alternate
+	    emulated nics in place of the default
+	    ne2kpci, they should be a little faster/use less guest cpu.</para>
+	</listitem>
+	<listitem>
+	  <para>You can also try <command>-drive if=scsi,file=..</command>
+	    instead of <command>-hdb ...</command>
+	    to specify additional image files (qemu's bios can't boot
+	    from SCSI yet at the time of writing), SCSI should perform
+	    better than IDE (especially with Linux guests, less
+	    with &os;.)</para>
+	</listitem>
+	<listitem>
+	  <para>And you can try <command>-vnc ...</command> if the host
+	    or qemu build lacks X and
+	    <command>-nographic</command> or <command>-curses</command>
+	    (the latter not yet in 0.9.1) isn't enough
+	    (<command>-nographic</command> needs the guest configured for
+	    serial console.)
+	    <command>-vnc</command> works best with an en-us keymap on the host.
+	    You can
+	    use e.g. the &os; <filename role="package">net/tightvnc</filename>
+	    port with qemu.  The X keymap on the host can be changed
+	    temporarily using
+	    <command>setxkbmap</command>, see its manpage for details.</para>
+	</listitem>
+	<listitem>
+	  <para>iso images are faster than physical CD/DVD drives.</para>
+	</listitem>
+      </itemizedlist>
+    </sect2>
+
+    <sect2 id="virtualization-guest-qemu">
+      <title>&os; as a qemu guest</title>
+
+      <para>First a few things you should know:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>&os;/amd64 guests may need a patch to qemu: <ulink
+	    url="http://www.nabble.com/-PATCH--i386-hard-interrupt-generation-bug-fix-p14921171.html">
+	    i386-hard-interrupt-generation-bug-fix</ulink>
+	    (unfortunately not yet committed to mainline qemu, or
+	    I missed it...  the &os;
+	    <filename role="package">emulators/qemu-devel</filename> port
+	    has it tho.)</para>
+	</listitem>
+	<listitem>
+	  <para>Debian/Ubuntu (and their offsprings) have a record of
+	    shipping partially broken
+	    qemu bioses, so if you have problems using a packaged qemu on
+	    these distros also try using the bios found in that qemu
+	    version's(!) source tarball (<filename>pc-bios/bios.bin</filename>
+	    in there) instead of the one installed by your distro
+	    package.</para>
+	</listitem>
+      </itemizedlist>
+
+      <sect3 id="virtualization-guest-qemu-example">
+        <title>An example how to install &os; 7.0 as a qemu guest</title>
+        <para>First, we create an empty raw 5 GB image:
+	  <screen>&prompt.user; <userinput>qemu-img create 7.0.img 5G</userinput></screen>
+	  (You may want <command>-f qcow2</command> for qcow2 format
+	  if you have to/want to avoid sparse files on the host -
+	  some backup apps like &man.bsdtar.1;
+	  don't support them properly, others like gtar or star do if passed
+	  appropriate flags - qcow2 might be slower than raw.)</para>
+        <para>Next, we boot sysinstall with the image:
+	  <screen>&prompt.user; <userinput>qemu -m 256 -cdrom 7.0-RELEASE-i386-disc1.iso -hda 7.0.img -boot d -monitor stdio</userinput></screen>
+	  Now follow the instructions in <xref linkend="install"> like
+	  as if you would install a real machine using CD media...
+	  Click into the guest window to access the guest mouse pointer
+	  and hit <keycombo action="simul"><keycap>Alt</keycap>
+	  <keycap>Ctrl</keycap></keycombo> to leave the guest window
+	  mouse grab.  If you use the default usermode networking (aka slirp)
+	  like in the above example the guest should have network if you
+	  configure it to use DHCP, so if you want you could probably
+	  also use a bootonly iso instead of disc1 and do a network install.
+	  (&man.ping.8 doesn't work with slirp tho.)</para>
+	<para>When finished, select `exit install' in sysinstall to reboot,
+	  and when you see the guest booting the iso again, type
+	  <command>q</command> in qemu's monitor (or
+	  <command>killall qemu</command> on another host shell if you are
+	  using <command>-curses</command>, like
+	  when you have no X on the host.)</para>
+        <para>Now, we should be able to boot the installed image:
+	  <screen>&prompt.user; <userinput>qemu -m 256 -cdrom 7.0-RELEASE-i386-disc1.iso -hda 7.0.img -boot c -monitor stdio</userinput></screen>
+	  (You can omit <command>-cdrom</command> if you don't plan to
+	  access the install iso from the installed guest.)</para>
+        <para>Now you should see a normal boot like on a freshly installed
+	  box, all the way up to your first login: prompt.  If you plan to
+	  use this guest with <command>-nographic</command> later on,
+	  now is the time to configure it for a serial console:
+	  (both in the guest:)
+	  <screen>&prompt.root; <userinput>echo console=\"comconsole\" >>/boot/loader.conf</userinput></screen>
+	  <screen>&prompt.root; <userinput>sed -i -e '/^ttyd0/s/off/on/' /etc/ttys</userinput></screen>
+	  As always with virtualization, lowering <option>kern.hz</option>
+	  helps performance also with qemu, so you might want to do that too:
+	  (in the guest:)
+	  <screen>&prompt.root; <userinput>echo kern.hz=100 >>/boot/loader.conf</userinput></screen>
+	  When you are finished with the guest, shut it down, this should
+	  make qemu quit gracefully (in the guest:)
+	  <screen>&prompt.root; <userinput>shutdown -p now</userinput></screen>
+	  If you just configured for serial console, you can now boot the
+	  guest with <command>-nographic</command>:
+	  <screen>&prompt.user; <userinput>qemu -m 256 -hda 7.0.img -boot c -nographic</userinput></screen>
+	  With <command>-nographic</command>, the guest console and qemu's
+	  monitor are multiplexed on qemu's tty, hit
+	  <keycombo action="simul"><keycap>Ctrl</keycap>
+	  <keycap>a</keycap></keycombo> and then <keycap>h</keycap>
+	  to show a small help.</para>
+      </sect3>
+    </sect2>
   </sect1>
 
   <sect1 id="virtualization-host">
@@ -968,7 +1178,149 @@ xenbr1          8000.feffffffffff   no  
       use older versions of <application>VMware</application> in this capacity.
       Work is also ongoing in getting <application>&xen;</application> to
       work as a host environment on FreeBSD.</para>
+    <para><application>qemu</application> also often works, although some guests
+      work better than others, and the kqemu accellerator kernel module
+      still works better (i.e. with more guests) on i386 hosts than
+      on amd64 - although the latter has improved with qemu svn at the time of
+      writing, a snapshot of which is available as the
+      <filename role="package">emulators/qemu-devel</filename> port.
+      (But it is still slower than <application>VMware</application>.)
+      Also kqemu was broken for a long time on amd64 SMP, so
+      be sure to use recent qemu and kqemu ports if your host is such.</para>
+    <sect2 id="virtualization-host-qemu">
+      <title>&os; as a qemu Host</title>
+
+      <para>Notes about the current state of affairs re. qemu on &os; hosts
+	can always be found in the <filename>pkg-message</filename>
+	of the relevant qemu port (there are two at the moment,
+	<filename role="package">emulators/qemu</filename> and
+	<filename role="package">emulators/qemu-devel</filename>,
+	the first is usually the latest release and the latter is an
+	svn snapshot).  If you already have a qemu port installed you can
+	also view those notes via:
+	<screen>&prompt.user; <userinput>pkg_info -D qemu\* |less</userinput></screen>
+	Here are a few facts that are noted there which are unlikely to
+	change:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>If you want to use qemu with <command>-m 512</command>
+	    or larger on i386 &os; 6.x hosts you need to increase the
+	    <command>kern.maxdsiz</command>
+	    tunable in the host's &man.loader.conf.5 since the default
+	    is 512 MB, and qemu needs memory for itself also.
+	    (&os; 7.0 and up use jemalloc which uses &man.mmap.2 and
+	    isn't affected by <command>kern.maxdsiz</command> anymore.)</para>
+	</listitem>
+	<listitem>
+	  <para>If you use kqemu make sure your <filename>kqemu.ko</filename>
+	    is always in sync
+	    with the kernel (like with any kld installed outside of base),
+	    i.e. rebuild the
+	    <filename role="package">emulators/kqemu-kmod</filename>
+	    port (or
+	    <filename role="package">emulators/kqemu-kmod-devel</filename>
+	    depending on which qemu port you use) whenever you update
+	    the kernel - especially
+	    if you are switching branches or are following a -stable or even
+	    -current branch!</para>
+	</listitem>
+	<listitem>
+	  <para>qemu now uses &man.aio.4 at least for ide dma, so if you get
+	    `Invalid system call' crashes that is because aio is not
+	    (kld)loaded.</para>
+	</listitem>
+	<listitem>
+	  <para>You can enable autoloading of kqemu (and aio) at boot by
+	    adding a line
+	    <literal>kqemu_enable=YES</literal>
+	    to <filename>/etc/rc.conf</filename> (assuming you have built
+	    the qemu port with the kqemu knob enabled of course).</para>
+	</listitem>
+      </itemizedlist>
+      <sect3 id="virtualization-host-qemu-linuxguest">
+	<title>Simple Linux guest examples</title>
+	<para>As an example, we run the well known <ulink
+	  url="http://knoppix.net">Knoppix</ulink> Linux live-CD/DVD in qemu:
+	  <screen>&prompt.user; <userinput>qemu -m 256 -cdrom KNOPPIX_V5.3.1DVD-2008-03-26-EN.iso -boot d -monitor stdio -soundhw es1370</userinput></screen>
+	  (Omit <command>-soundhw es1370</command> if you don't have sound
+	  configured on the host.)
+	  If you want a smaller download you can also try <ulink
+	  url="http://www.damnsmalllinux.org">Damn Small Linux</ulink>
+	  (around 50 MB):
+	  <screen>&prompt.user; <userinput>qemu -m 256 -cdrom dsl-4.3.iso -boot d -monitor stdio -soundhw es1370</userinput></screen>
+	  Again, click into the guest window to access the guest
+	  mouse pointer and
+	  hit <keycombo action="simul"><keycap>Alt</keycap>
+	  <keycap>Ctrl</keycap></keycombo> to leave the guest window
+	  mouse grab.</para>
 
+      </sect3>
+      <sect3 id="virtualization-host-qemu-tuntap">
+	<title>Simple Example for using qemu tuntap networking on
+	  &os; Hosts</title>
+	<para>In cases where you want a qemu guest to appear as a seperate
+	  (virtual) host on your network, or when you are on an amd64 host
+	  where the default usermode networking doesn't quite work, or
+	  when you are simply concerned about virtual network performance,
+	  you may want to use tuntap networking.</para>
+	<para>The idea here is to have qemu talk to a &man.tap.4; interface,
+	  which you (usually) bridge with your host's physical interface,
+	  and that qemu then passes the traffic of the emulated nic that
+	  the guest uses on.  Since you (usually) don't want to run qemu
+	  as root you first need to setup permissions on the tap device in
+	  &man.devfs.conf.5; so that qemu running as your user can acess it.
+	  For example add:
+	  <programlisting>        own     tap0    <replaceable>&lt;username or uid&gt;</replaceable></programlisting>
+	  Next you figure out two IPs in an unused sub-subnet of your
+	  host's network, one for the tap interface and the other for the
+	  guest (this is important so the host itself can talk to the guest's
+	  emulated nic properly), and then edit qemu's tuntap setup script
+	  that gets executed after qemu opens a tap device,
+	  <filename>/usr/local/etc/qemu-ifup</filename> to read something
+	  like this:
+	  <programlisting>#!/bin/sh
+sudo /sbin/ifconfig $1 <replaceable>&lt;IP for the tap interface&gt;</replaceable> netmask <replaceable>&lt;sub-subnet's netmask&gt;</replaceable>
+case "`/sbin/ifconfig bridge0`" in
+    *" $1 "*) ;;      # already in the bridge 
+    *) sudo /sbin/ifconfig bridge0 addm $1 ;;
+esac</programlisting>
+	  (sudo is in ports as 
+	  <filename role="package">security/sudo</filename>, if your user
+	  is in the wheel group you can add a line
+	  <programlisting>%wheel  ALL=/sbin/ifconfig</programlisting>
+	  to <filename>/usr/local/etc/sudoers</filename> for this to work.)
+	  Then you load the if_tap and if_bridge klds, restart devfs, set the
+	  <varname>net.link.tap.user_open</varname> sysctl, create
+	  the bridge and add your host's physical interface to it:
+	  <screen>&prompt.root; <userinput>kldload if_tap if_bridge</userinput></screen>
+	  <screen>&prompt.root; <userinput>/etc/rc.d/devfs restart</userinput></screen>
+	  <screen>&prompt.root; <userinput>sysctl net.link.tap.user_open=1</userinput></screen>
+	  <screen>&prompt.root; <userinput>ifconfig bridge0 create</userinput></screen>
+	  <screen>&prompt.root; <userinput>ifconfig bridge0 addm <replaceable>&lt;host's physical interface&gt;</replaceable> up</userinput></screen>
+	  Now you should be ready to start qemu:
+	  <screen>&prompt.user; <userinput>qemu -m 256 -hda guest.img -boot c -net nic -net tap,ifname=tap0</userinput></screen>
+	  In the guest configure the emulated nic with the IP you selected
+	  above (different than the tap interface's IP) and the netmask of
+	  your host's physical interface, and the rest (gateway, dns) like you
+	  would configure any other host on your physical network.
+	  (Note that if you have more than one qemu guest on a network
+	  you need to make sure they each use a different macaddress,
+	  the macaddress can be set via
+	  <command>-net nic,macaddr=...</command>.)</para>
+	<para>If you would like to make these settings permanent, add
+	  the following to
+	  &man.loader.conf.5; to load <filename>if_tap.ko</filename> and
+	  <filename>if_bridge.ko</filename> at boot:
+	  <programlisting>if_tap_load=YES
+if_bridge_load=YES</programlisting>
+	  (or put them in your kernel config), add
+	  <programlisting>net.link.tap.user_open=1</programlisting>
+	  to &man.sysctl.conf.5;, and add the bridge configuration to
+	  &man.rc.conf.5;:
+	  <programlisting>cloned_interfaces="bridge0"
+ifconfig_bridge0="addm <replaceable>&lt;host's physical interface&gt;</replaceable> up"</programlisting>
+      </sect3>
+    </sect2>
   </sect1>
 
 </chapter>
