]> git.proxmox.com Git - pve-qemu-kvm.git/commitdiff
imported from svn 'pve-qemu-kvm/pve2'
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 23 Aug 2011 05:41:36 +0000 (07:41 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 23 Aug 2011 05:41:36 +0000 (07:41 +0200)
31 files changed:
Makefile [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/kvm-ifdown [new file with mode: 0755]
debian/kvm-ifup [new file with mode: 0755]
debian/patches-0.12.1/adjust-path.diff [new file with mode: 0644]
debian/patches-0.12.1/cpuid-fix.diff [new file with mode: 0644]
debian/patches-0.12.1/enable-ksm.diff [new file with mode: 0644]
debian/patches-0.12.1/fairsched.diff [new file with mode: 0644]
debian/patches-0.12.1/keymap.diff [new file with mode: 0644]
debian/patches-0.12.1/live-migration-fixes.diff [new file with mode: 0644]
debian/patches-0.12.1/multicore.diff [new file with mode: 0644]
debian/patches-0.12.1/ps2-queue-size.diff [new file with mode: 0644]
debian/patches-0.12.1/series [new file with mode: 0644]
debian/patches-0.12.1/vncticket.diff [new file with mode: 0644]
debian/patches/adjust-path.diff [new file with mode: 0644]
debian/patches/cpuid-fix.diff [new file with mode: 0644]
debian/patches/fairsched.diff [new file with mode: 0644]
debian/patches/fr-ca-keymap-corrections.diff [new file with mode: 0644]
debian/patches/keymap.diff [new file with mode: 0644]
debian/patches/live-migration-fixes.diff [new file with mode: 0644]
debian/patches/multicore.diff [new file with mode: 0644]
debian/patches/ps2-queue-size.diff [new file with mode: 0644]
debian/patches/pve-auth.patch [new file with mode: 0644]
debian/patches/series [new file with mode: 0644]
debian/patches/set-max-nics.patch [new file with mode: 0644]
debian/patches/use-local-linux-kvm-h.diff [new file with mode: 0644]
debian/patches/vncticket.diff [new file with mode: 0644]
debian/rules [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..ee61e54
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,56 @@
+RELEASE=2.0
+
+# also update debian/changelog
+KVMVER=0.15.0
+KVMPKGREL=1
+
+KVMPACKAGE=pve-qemu-kvm
+KVMDIR=qemu-kvm
+
+ARCH=amd64
+
+KVM_DEB=${KVMPACKAGE}_${KVMVER}-${KVMPKGREL}_${ARCH}.deb
+
+all: ${KVM_DEB} ${KVMDIR}-src.tar.gz
+
+${KVMDIR}.org/README:
+       rm -rf ${KVMDIR}.org
+       git clone git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git ${KVMDIR}.org
+       cd ${KVMDIR}.org; git checkout -b local qemu-kvm-${KVMVER}
+       touch $@
+
+${KVMDIR}-src.tar.gz: ${KVMDIR}.org/README
+       tar czf $@ ${KVMDIR}.org
+
+${KVM_DEB} kvm: ${KVMDIR}.org/README
+       rm -rf ${KVMDIR}
+       cp -a ${KVMDIR}.org ${KVMDIR}
+       cp -a debian ${KVMDIR}/debian
+       cd ${KVMDIR}; dpkg-buildpackage -rfakeroot -us -uc
+       lintian ${KVM_DEB} || true
+
+.PHONY: upload
+upload: ${KVM_DEB} ${KVMDIR}-src.tar.gz
+       umount /pve/${RELEASE}; mount /pve/${RELEASE} -o rw 
+       mkdir -p /pve/${RELEASE}/extra
+       mkdir -p /pve/${RELEASE}/install
+       rm -rf /pve/${RELEASE}/extra/Packages*
+       rm -rf /pve/${RELEASE}/extra/${KVMPACKAGE}_*.deb
+       rm -rf /pve/${RELEASE}/install/${KVMDIR}-src.tar.gz
+       cp ${KVM_DEB} /pve/${RELEASE}/extra
+       cp  ${KVMDIR}-src.tar.gz /pve/${RELEASE}/install
+       cd /pve/${RELEASE}/extra; dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
+       umount /pve/${RELEASE}; mount /pve/${RELEASE} -o ro
+
+.PHONY: distclean
+distclean: clean
+       rm -rf ${KVMDIR}.org ${KVMDIR}-src.tar.gz
+
+
+.PHONY: clean
+clean:
+       rm -rf *~ ${KVMDIR} ${KVMPACKAGE}_*
+
+.PHONY: dinstall
+dinstall: ${KVM_DEB}
+       dpkg -i ${KVM_DEB}
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..845f320
--- /dev/null
@@ -0,0 +1,171 @@
+pve-qemu-kvm (0.15.0-1) unstable; urgency=low
+
+  * update to upstream 0.15.0
+
+  * depend on libaio1 (--enable-linux-aio)
+
+  * depend on libuuid1 (--enable-uuid)
+  
+  * use pxe roms from upstream qemu-kvm
+  
+  * do not use --disable-blobs (let qemu-kvm install files, and we remove
+    what we do not need)
+
+ -- Proxmox Support Team <support@proxmox.com>  Thu, 11 Aug 2011 10:00:44 +0200
+
+pve-qemu-kvm (0.14.1-1) unstable; urgency=low
+
+  * update to upstream 0.14.1
+  
+  * remove enable-ksm.diff patch (newer libc already have those
+    definitions)
+  
+  * also install vgabios-qxl.bin vgabios-stdvga.bin vgabios-vmware.bin
+
+ -- Proxmox Support Team <support@proxmox.com>  Tue, 21 Jun 2011 06:30:29 +0200
+
+pve-qemu-kvm (0.14.0-1) unstable; urgency=low
+
+  * update to 0.14.0
+
+  * removed kvmtrace (removed from upstream?)
+  
+  * add vnc keyboard fixes for fr-ca (reported by Pierre-Yves)
+
+ -- Proxmox Support Team <support@proxmox.com>  Fri, 25 Feb 2011 08:17:56 +0100
+
+pve-qemu-kvm (0.13.0-3) unstable; urgency=low
+
+  * fix vnc keyboard altgr/shift emulation
+
+ -- Proxmox Support Team <support@proxmox.com>  Tue, 07 Dec 2010 12:45:16 +0100
+
+pve-qemu-kvm (0.13.0-2) unstable; urgency=low
+
+  * do not install unnecessary blobs (manually install blobs, use
+    --disable-blobs)
+
+  * update migration and vnc keymap patches for 0.13.0
+  
+ -- Proxmox Support Team <support@proxmox.com>  Mon, 25 Oct 2010 13:46:03 +0200
+
+pve-qemu-kvm (0.13.0-1) unstable; urgency=low
+
+  * update to qemu-kvm-0.13.0
+
+ -- Proxmox Support Team <support@proxmox.com>  Thu, 21 Oct 2010 13:38:14 +0200
+
+pve-qemu-kvm (0.12.5-2) unstable; urgency=low
+
+  * enable up to 32 NICs (as suggested in the forum)
+
+ -- Proxmox Support Team <support@proxmox.com>  Wed, 06 Oct 2010 08:23:07 +0200
+
+pve-qemu-kvm (0.12.5-1) unstable; urgency=low
+
+  * update to qemu-kvm-0.12.5
+
+ -- Proxmox Support Team <support@proxmox.com>  Thu, 05 Aug 2010 11:01:56 +0200
+
+pve-qemu-kvm (0.12.4-1) unstable; urgency=low
+
+  * update to qemu-kvm-0.12.4
+
+ -- Proxmox Support Team <support@proxmox.com>  Tue, 11 May 2010 08:14:29 +0200
+
+pve-qemu-kvm (0.12.3-1) unstable; urgency=low
+
+  * update to qemu-kvm-0.12.3
+  
+  * include gPXE 1.0 network boot
+  
+  * remove multicore.diff patch
+  
+  * do not install ppc and sparc bios files
+
+ -- Proxmox Support Team <support@proxmox.com>  Wed, 14 Apr 2010 13:30:23 +0200
+
+pve-qemu-kvm (0.11.1-2) unstable; urgency=low
+
+  * Use/Include PXE boot ROMs from the Etherboot package
+
+ -- Proxmox Support Team <support@proxmox.com>  Tue, 26 Jan 2010 13:28:19 +0100
+
+pve-qemu-kvm (0.11.1-1) unstable; urgency=low
+
+  * update to qemu-kvm-0.11.1
+
+  * cleanup debian rules file
+  
+  * install kvmtrace kvmtrace_format and kvm_stat
+  
+  * configure with --disable-xen --with-kvm-trace 
+  
+  * depend on python for scripts
+  
+ -- Proxmox Support Team <support@proxmox.com>  Mon, 14 Dec 2009 14:44:56 +0100
+
+pve-qemu-kvm (0.11.0-2) stable; urgency=low
+
+  * fix live migration (live-migration-fxes.diff)
+
+ -- Proxmox Support Team <support@proxmox.com>  Wed, 30 Sep 2009 11:07:23 +0200
+
+pve-qemu-kvm (0.11.0-1) stable; urgency=low
+
+  * update to stable branch
+
+  * rename packare to pve-qemu-kvm
+       
+ -- Proxmox Support Team <support@proxmox.com>  Mon, 28 Sep 2009 10:35:05 +0200
+
+pve-kvm (86-4) unstable; urgency=low
+
+  * include multicore patch from amd
+
+ -- Proxmox Support Team <support@proxmox.com>  Mon, 14 Sep 2009 10:40:00 +0200
+
+pve-kvm (86-3) unstable; urgency=low
+
+  * fix "i8042.c: No controller found" problem
+
+ -- Proxmox Support Team <support@proxmox.com>  Mon, 15 Jun 2009 13:35:57 +0200
+
+pve-kvm (86-2) unstable; urgency=low
+
+  * add CPUID fix: http://git.kernel.org/?p=virt/kvm/qemu-kvm.git;a=commitdiff_plain;h=8fa3b3ce6e
+
+ -- Proxmox Support Team <support@proxmox.com>  Tue, 09 Jun 2009 09:50:28 +0200
+
+pve-kvm (86-1) unstable; urgency=low
+
+  *  New upstream release
+
+ -- Proxmox Support Team <support@proxmox.com>  Fri, 22 May 2009 09:16:27 +0200
+
+pve-kvm (85-1) unstable; urgency=low
+
+  *  New upstream release
+
+ -- Proxmox Support Team <support@proxmox.com>  Tue, 28 Apr 2009 07:41:21 +0200
+
+pve-kvm (83-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Proxmox Support Team <support@proxmox.com>  Wed,  7 Jan 2009 12:57:02 +0100
+
+pve-kvm (75-1) unstable; urgency=low
+
+  *  New upstream release
+
+ -- Proxmox Support Team <support@proxmox.com>  Thu, 11 Sep 2008 10:03:51 +0200
+
+pve-kvm (74-1) unstable; urgency=low
+
+  * New upstream release
+  
+  * added fairsched options
+
+ -- Proxmox Support Team <support@proxmox.com>  Thu, 28 Aug 2008 12:40:32 +0200
+
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..09d6b36
--- /dev/null
@@ -0,0 +1,16 @@
+Source: pve-qemu-kvm
+Section: admin
+Priority: extra
+Maintainer: Proxmox Support Team <support@proxmox.com>
+Build-Depends: debhelper (>= 5), autotools-dev, libpci-dev, quilt, texinfo, texi2html, libgnutls-dev, libsdl1.2-dev, check, libaio-dev, uuid-dev
+Standards-Version: 3.7.2
+
+Package: pve-qemu-kvm
+Architecture: any
+Depends: iproute, bridge-utils, python, libsdl1.2debian, libaio1, libuuid1, ${shlibs:Depends}, ${misc:Depends}
+Conflicts: qemu, qemu-kvm, kvm, pve-kvm, pve-qemu-kvm-2.6.18
+Replaces: pve-kvm, pve-qemu-kvm-2.6.18
+Description: Full virtualization on x86 hardware
+ Using KVM, one can run multiple virtual PCs, each running unmodified Linux or
+ Windows images. Each virtual machine has private virtualized hardware: a
+ network card, disk, graphics adapter, etc. 
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..e861e42
--- /dev/null
@@ -0,0 +1,66 @@
+This package was debianized by the proxmox support team <support@proxmox.com>
+
+
+It was downloaded from
+
+git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git
+
+Upstream Author: Fabrice Bellard <fabrice.bellard@free.fr>
+
+Upstream Maintainers: Avi Kivity <avi@redhat.com>
+                      Anthony Liguori <aliguori@us.ibm.com>
+
+Copyright: Copyright (C) 2006 Qumranet, Inc.
+           Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008  Fabrice Bellard
+
+License:
+
+    QEMU as a whole is released under the GNU General Public License version 2.
+    On Debian systems, the complete text of the GNU General Public License
+    version 2 can be found in the file /usr/share/common-licenses/GPL-2.
+
+    Parts of QEMU have specific licenses which are compatible with the
+    GNU General Public License. Hence each source file contains its own
+    licensing information.
+
+    In particular, the QEMU virtual CPU core library (libqemu.a) is
+    released under the GNU Lesser General Public License version 2 or later.
+    On Debian systems, the complete text of the GNU Lesser General Public 
+    License can be found in the file /usr/share/common-licenses/LGPL.
+
+    Some hardware device emulation sources and other QEMU functionality are
+    released under the BSD license, including:
+     * aes, bsd-user, sd, slirp, sys-queue
+
+    On Debian systems, the complete text of the BSD license be found in the
+    file /usr/share/common-licenses/BSD.
+
+    Some hardware device emulation sources and other QEMU functionality are
+    released under the MIT/X11 (BSD-like) license, including:
+     * sdl, host-utils, vnc, keymaps, ioport, usb, hw/*, net, acl, block,
+       kqemu, monitor, curses, readline, vl, savevm, osdep, audio, tcg,
+       qemu-malloc, qemu-img
+
+    The following points clarify the QEMU license:
+     1) QEMU as a whole is released under the GNU General Public License
+     2) Parts of QEMU have specific licenses which are compatible with the
+        GNU General Public License. Hence each source file contains its own
+        licensing information.
+        In particular, the QEMU virtual CPU core library (libqemu.a) is
+        released under the GNU Lesser General Public License. Many hardware
+        device emulation sources are released under the BSD license.
+     3) The Tiny Code Generator (TCG) is released under the BSD license
+        (see license headers in files).
+     4) QEMU is a trademark of Fabrice Bellard.
+     -- Fabrice Bellard.
+
+    BIOS sources in QEMU:
+       bios.bin: Copyright (C) 2002 MandrakeSoft S.A. and others.  This file
+       is licensed under the GNU LGPL, version 2, or (at your option) any later
+       version.
+       Homepage: http://sourceforge.net/projects/bochs
+
+       vgabios.bin and vgabios-cirrus.bin: (C) 2003 the LGPL VGABios
+       developers Team. These files are licensed under the GNU LGPL, version 2,
+       or (at your option) any later version.
+       Homepage: http://savannah.nongnu.org/projects/vgabios
diff --git a/debian/kvm-ifdown b/debian/kvm-ifdown
new file mode 100755 (executable)
index 0000000..92b94c4
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exit 0
\ No newline at end of file
diff --git a/debian/kvm-ifup b/debian/kvm-ifup
new file mode 100755 (executable)
index 0000000..2d39ddc
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+switch=$(/sbin/ip route list | awk '/^default / { print $NF }')
+/sbin/ifconfig $1 0.0.0.0 promisc up
+/usr/sbin/brctl addif ${switch} $1
diff --git a/debian/patches-0.12.1/adjust-path.diff b/debian/patches-0.12.1/adjust-path.diff
new file mode 100644 (file)
index 0000000..07c63e6
--- /dev/null
@@ -0,0 +1,30 @@
+Index: kvm-86/configure
+===================================================================
+--- kvm-86.orig/configure      2009-05-22 09:47:55.000000000 +0200
++++ kvm-86/configure   2009-05-22 09:48:26.000000000 +0200
+@@ -1393,8 +1393,8 @@
+       prefix="/usr/local"
+   fi
+   mansuffix="/share/man"
+-  datasuffix="/share/qemu"
+-  docsuffix="/share/doc/qemu"
++  datasuffix="/share/kvm"
++  docsuffix="/share/doc/pve-qemu-kvm"
+   binsuffix="/bin"
+ fi
+Index: kvm-86/net.h
+===================================================================
+--- kvm-86.orig/net.h  2009-05-22 09:47:48.000000000 +0200
++++ kvm-86/net.h       2009-05-22 09:48:26.000000000 +0200
+@@ -124,8 +124,8 @@
+ void net_host_device_add(Monitor *mon, const char *device, const char *opts);
+ void net_host_device_remove(Monitor *mon, int vlan_id, const char *device);
+-#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
+-#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
++#define DEFAULT_NETWORK_SCRIPT "/etc/kvm/kvm-ifup"
++#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/kvm/kvm-ifdown"
+ #ifdef __sun__
+ #define SMBD_COMMAND "/usr/sfw/sbin/smbd"
+ #else
diff --git a/debian/patches-0.12.1/cpuid-fix.diff b/debian/patches-0.12.1/cpuid-fix.diff
new file mode 100644 (file)
index 0000000..1052ad5
--- /dev/null
@@ -0,0 +1,18 @@
+see http://git.kernel.org/?p=virt/kvm/qemu-kvm.git;a=commitdiff;h=8fa3b3ce6e#patch1
+
+KVM_GET_SUPPORTED_CPUID has been known to fail to return -E2BIG
+when it runs out of entries. Detect this by always trying again
+with a bigger table if the ioctl() fills the table.
+
+--- a/kvm/libkvm/libkvm-x86.c
++++ b/kvm/libkvm/libkvm-x86.c
+@@ -575,6 +575,8 @@ static struct kvm_cpuid2 *try_get_cpuid(kvm_context_t kvm, int max)
+       r = ioctl(kvm->fd, KVM_GET_SUPPORTED_CPUID, cpuid);
+       if (r == -1)
+               r = -errno;
++      else if (r == 0 && cpuid->nent >= max)
++              r = -E2BIG;
+       if (r < 0) {
+               if (r == -E2BIG) {
+                       free(cpuid);
+
diff --git a/debian/patches-0.12.1/enable-ksm.diff b/debian/patches-0.12.1/enable-ksm.diff
new file mode 100644 (file)
index 0000000..3ecd434
--- /dev/null
@@ -0,0 +1,33 @@
+From: Izik Eidus <ieidus@redhat.com>
+Date: Thu, 8 Oct 2009 14:39:39 +0000 (+0200)
+Subject: ksm support
+X-Git-Url: http://git.kernel.org/?p=virt%2Fkvm%2Fqemu-kvm.git;a=commitdiff_plain;h=ccb167e9d7d460a7cd09fdabd848efd3606dd27e
+
+ksm support
+
+patch is slighly modified by <support@proxmox.com> for old libc 
+
+Call MADV_MERGEABLE on guest memory allocations.  MADV_MERGABLE will be
+available starting in Linux 2.6.32.  This system call registers a region of
+virtual address space with Linux as a candidate for transparent memory
+sharing.
+
+Patchworks-ID: 35447
+Signed-off-by: Izik Eidus <ieidus@redhat.com>
+Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
+---
+
+Index: qemu-kvm/exec.c
+===================================================================
+--- qemu-kvm.orig/exec.c       2009-12-21 10:37:57.000000000 +0100
++++ qemu-kvm/exec.c    2009-12-21 11:22:34.000000000 +0100
+@@ -48,6 +48,9 @@
+ #include <qemu.h>
+ #endif
++/* our libc does not define it */
++#define MADV_MERGEABLE   12
++
+ //#define DEBUG_TB_INVALIDATE
+ //#define DEBUG_FLUSH
+ //#define DEBUG_TLB
diff --git a/debian/patches-0.12.1/fairsched.diff b/debian/patches-0.12.1/fairsched.diff
new file mode 100644 (file)
index 0000000..51e8de1
--- /dev/null
@@ -0,0 +1,167 @@
+Index: qemu-kvm/qemu-options.hx
+===================================================================
+--- qemu-kvm.orig/qemu-options.hx      2009-12-21 10:37:57.000000000 +0100
++++ qemu-kvm/qemu-options.hx   2009-12-21 10:41:25.000000000 +0100
+@@ -66,6 +66,12 @@
+ are split equally.
+ ETEXI
++DEF("id", HAS_ARG, QEMU_OPTION_id,
++    "-id n         set the faisched ID\n")
++
++DEF("cpuunits",  HAS_ARG, QEMU_OPTION_cpuunits,
++    "-cpuuinits n    set fairsched cpu units\n")
++
+ DEF("fda", HAS_ARG, QEMU_OPTION_fda,
+     "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n")
+ DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "")
+Index: qemu-kvm/vl.c
+===================================================================
+--- qemu-kvm.orig/vl.c 2009-12-21 10:37:58.000000000 +0100
++++ qemu-kvm/vl.c      2009-12-21 10:42:50.000000000 +0100
+@@ -159,6 +159,7 @@
+ #include "qemu-objects.h"
+ #include "qemu-kvm.h"
+ #include "hw/device-assignment.h"
++#include "vzsyscalls.h"
+ #include "disas.h"
+@@ -224,6 +225,7 @@
+ int max_cpus = 0;
+ int smp_cores = 1;
+ int smp_threads = 1;
++int fairsched_id = 0;
+ const char *vnc_display;
+ int acpi_enabled = 1;
+ #ifdef TARGET_I386
+@@ -363,7 +365,7 @@
+     prctl(PR_SET_NAME, name);
+ #endif        
+ }
+- 
++
+ /***************/
+ /* ballooning */
+@@ -4897,6 +4899,7 @@
+     const char *gdbstub_dev = NULL;
+     uint32_t boot_devices_bitmap = 0;
+     int i;
++    int cpuunits = 0;
+     int snapshot, linux_boot, net_boot;
+     const char *initrd_filename;
+     const char *kernel_filename, *kernel_cmdline;
+@@ -5550,6 +5553,20 @@
+                     exit(1);
+                 }
+                 break;
++            case QEMU_OPTION_id:
++                fairsched_id = atoi(optarg);
++              if (fairsched_id < 100 || fairsched_id >= 1000000) {
++                  fprintf(stderr, "Invalid ID\n");
++                  exit(1);
++              }
++                break;
++            case QEMU_OPTION_cpuunits:
++                cpuunits = atoi(optarg);
++              if (cpuunits < 8 || cpuunits > 500000) {
++                  fprintf(stderr, "Invalid value for cpuunits\n");
++                    exit(1);
++                }
++                break;
+           case QEMU_OPTION_vnc:
+                 display_type = DT_VNC;
+               vnc_display = optarg;
+@@ -5947,6 +5964,39 @@
+     if (ram_size == 0)
+         ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
++    if (cpuunits && !fairsched_id) {
++      fprintf(stderr, "cpuunits specified without -id");
++      exit (1);
++    }
++
++    if (fairsched_id) {
++      int ret;
++      int weight = cpuunits ? 500000/cpuunits : 500;
++      pid_t cpid = getpid();
++
++      ret = syscall(__NR_fairsched_rmnod, fairsched_id);
++      if (ret == -EBUSY) {
++      fprintf (stderr, "unable to create fairsched node - still in use\n");
++      exit(1);
++      }
++
++      ret = syscall(__NR_fairsched_mknod, 0, weight, fairsched_id);
++      if (ret != fairsched_id) {
++      fprintf (stderr, "unable to create fairsched node\n");
++      exit(1);
++      }
++
++      ret = syscall(__NR_fairsched_mvpr, cpid, fairsched_id);
++      if (ret != 0) {
++      fprintf (stderr, "unable to move procces to fairsched group");
++      exit (1);
++      }
++
++      /* note: we can never remove ourself from the group, so the empty group
++       will exist after we finish
++      */
++    }
++
+     /* init the dynamic translator */
+     cpu_exec_init_all(tb_size * 1024 * 1024);
+Index: qemu-kvm/vzsyscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ qemu-kvm/vzsyscalls.h      2009-12-21 10:41:25.000000000 +0100
+@@ -0,0 +1,47 @@
++/*
++ *  Copyright (C) 2000-2008, Parallels, Inc. All rights reserved.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation; either version 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++#ifndef _VZSYSCALLS_H_
++#define _VZSYSCALLS_H_
++
++#include <sys/syscall.h>
++
++#ifdef __x86_64__
++#define __NR_fairsched_vcpus  499
++#define __NR_setluid          501
++#define __NR_setublimit               502
++#define __NR_fairsched_mknod    504
++#define __NR_fairsched_rmnod    505
++#define __NR_fairsched_chwt   506
++#define __NR_fairsched_mvpr     507
++#define __NR_fairsched_rate   508
++#define __NR_ioprio_set               251
++#elif defined(__i386__)
++#define __NR_fairsched_mknod    500
++#define __NR_fairsched_rmnod    501
++#define __NR_fairsched_chwt   502
++#define __NR_fairsched_mvpr     503
++#define __NR_fairsched_rate   504
++#define __NR_fairsched_vcpus  505
++#define __NR_setluid          511
++#define __NR_setublimit               512
++#define __NR_ioprio_set               289
++#else
++#error "no syscall for this arch"
++#endif
++
++#endif
diff --git a/debian/patches-0.12.1/keymap.diff b/debian/patches-0.12.1/keymap.diff
new file mode 100644 (file)
index 0000000..ac4904d
--- /dev/null
@@ -0,0 +1,468 @@
+Index: kvm-86/curses.c
+===================================================================
+--- kvm-86.orig/curses.c       2009-05-22 10:09:19.000000000 +0200
++++ kvm-86/curses.c    2009-05-22 10:10:38.000000000 +0200
+@@ -238,7 +238,11 @@
+                 keysym = chr;
+             keycode &= ~KEY_MASK;
+-            keycode |= keysym2scancode(kbd_layout, keysym);
++
++          keydata_t *kd = find_keysym(kbd_layout, keysym);
++          if (kd) {
++              keycode |= kd->keycode;
++          }
+         }
+         if (is_graphic_console()) {
+Index: kvm-86/keymaps.c
+===================================================================
+--- kvm-86.orig/keymaps.c      2009-05-22 10:09:24.000000000 +0200
++++ kvm-86/keymaps.c   2009-05-22 10:10:38.000000000 +0200
+@@ -67,6 +67,7 @@
+     char file_name[1024];
+     char line[1024];
+     int len;
++    int upper;
+     snprintf(file_name, sizeof(file_name),
+              "%s/keymaps/%s", bios_dir, language);
+@@ -97,25 +98,66 @@
+           if (*end_of_keysym) {
+               int keysym;
+               *end_of_keysym = 0;
++                uint8_t keymod;
++                int deadsym;
++
++                keymod = 0;
++                deadsym = 0;
++              upper = 0;
++redo:
++                if (upper==1){
++                    char *c;
++                    for(c=line;*c;c++)
++                        *c=toupper(*c);
++                    keymod |= KEYMOD_SHIFT;
++                    upper++;
++                }
++
+               keysym = get_keysym(table, line);
+               if (keysym == 0) {
+                     //                    fprintf(stderr, "Warning: unknown keysym %s\n", line);
+               } else {
+                   const char *rest = end_of_keysym + 1;
+                   char *rest2;
++                  char *modifier;
+                   int keycode = strtol(rest, &rest2, 0);
+-                  if (rest && strstr(rest, "numlock")) {
+-                      add_to_key_range(&k->keypad_range, keycode);
+-                      add_to_key_range(&k->numlock_range, keysym);
+-                      //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
++                    modifier = strtok (rest2, " ");
++                    while (modifier != NULL) {
++                        if (!strcmp(modifier, "shift")) {
++                            keymod |= KEYMOD_SHIFT;
++                        } else
++                      if (!strcmp(modifier, "addupper")) {
++                          upper++;
++                      } else
++                        if (!strcmp(modifier, "ctrl")) {
++                            keymod |= KEYMOD_CTRL;
++                        } else
++                        if (!strcmp(modifier, "alt")) {
++                            keymod |= KEYMOD_ALT;
++                        } else
++                        if (!strcmp(modifier, "altgr")) {
++                            keymod |= KEYMOD_ALTGR;
++                        } else
++                        if (!strncmp(modifier, "dead_",5)) {
++                            keymod |= KEYMOD_DEAD;
++                            deadsym = get_keysym(table, modifier);
++                        } else
++                        if (!strcmp(modifier, "numlock")) {
++                          add_to_key_range(&k->keypad_range, keycode);
++                          add_to_key_range(&k->numlock_range, keysym);
++                          //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
++                      }
++                      modifier = strtok (NULL," ");
+                   }
+                   /* if(keycode&0x80)
+                      keycode=(keycode<<8)^0x80e0; */
+                   if (keysym < MAX_NORMAL_KEYCODE) {
+                       //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
+-                      k->keysym2keycode[keysym] = keycode;
++                        k->keysym2keycode[keysym].keycode = keycode;
++                        k->keysym2keycode[keysym].keymod = keymod;
++                        k->keysym2keycode[keysym].deadsym = deadsym;
+                   } else {
+                       if (k->extra_count >= MAX_EXTRA_COUNT) {
+                           fprintf(stderr,
+@@ -128,11 +170,18 @@
+ #endif
+                           k->keysym2keycode_extra[k->extra_count].
+                               keysym = keysym;
+-                          k->keysym2keycode_extra[k->extra_count].
+-                              keycode = keycode;
++                          k->keysym2keycode_extra[k->extra_count].kdata.
++                              keycode = keycode;
++                          k->keysym2keycode_extra[k->extra_count].kdata.
++                              keymod = keymod;
++                            k->keysym2keycode_extra[k->extra_count].kdata.
++                              deadsym = deadsym;
++
+                           k->extra_count++;
+                       }
+                   }
++                    if (upper==1)
++                        goto redo;
+               }
+           }
+       }
+@@ -148,14 +197,11 @@
+ }
+-int keysym2scancode(void *kbd_layout, int keysym)
++keydata_t *find_keysym(void *kbd_layout, int keysym)
+ {
+     kbd_layout_t *k = kbd_layout;
+     if (keysym < MAX_NORMAL_KEYCODE) {
+-      if (k->keysym2keycode[keysym] == 0)
+-          fprintf(stderr, "Warning: no scancode found for keysym %d\n",
+-                  keysym);
+-      return k->keysym2keycode[keysym];
++        return &k->keysym2keycode[keysym];
+     } else {
+       int i;
+ #ifdef XK_ISO_Left_Tab
+@@ -163,10 +209,10 @@
+           keysym = XK_Tab;
+ #endif
+       for (i = 0; i < k->extra_count; i++)
+-          if (k->keysym2keycode_extra[i].keysym == keysym)
+-              return k->keysym2keycode_extra[i].keycode;
++            if (k->keysym2keycode_extra[i].keysym == keysym)
++                return &k->keysym2keycode_extra[i].kdata;
+     }
+-    return 0;
++    return NULL;
+ }
+ int keycode_is_keypad(void *kbd_layout, int keycode)
+Index: kvm-86/keymaps.h
+===================================================================
+--- kvm-86.orig/keymaps.h      2009-05-22 10:09:32.000000000 +0200
++++ kvm-86/keymaps.h   2009-05-22 10:10:38.000000000 +0200
+@@ -38,13 +38,26 @@
+     struct key_range *next;
+ };
++#define KEYMOD_SHIFT 0x01
++#define KEYMOD_CTRL  0x02
++#define KEYMOD_ALT   0x04
++#define KEYMOD_DEAD  0x08
++#define KEYMOD_ALTGR 0x10
++
+ #define MAX_NORMAL_KEYCODE 512
+ #define MAX_EXTRA_COUNT 256
++
++typedef struct {
++    uint16_t keycode;
++    uint8_t keymod;
++    int deadsym;
++} keydata_t;
++
+ typedef struct {
+-    uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
++    keydata_t keysym2keycode[MAX_NORMAL_KEYCODE];
+     struct {
+       int keysym;
+-      uint16_t keycode;
++        keydata_t kdata;
+     } keysym2keycode_extra[MAX_EXTRA_COUNT];
+     int extra_count;
+     struct key_range *keypad_range;
+@@ -53,7 +66,7 @@
+ void *init_keyboard_layout(const name2keysym_t *table, const char *language);
+-int keysym2scancode(void *kbd_layout, int keysym);
++keydata_t *find_keysym(void *kbd_layout, int keysym);
+ int keycode_is_keypad(void *kbd_layout, int keycode);
+ int keysym_is_numlock(void *kbd_layout, int keysym);
+Index: kvm-86/sdl.c
+===================================================================
+--- kvm-86.orig/sdl.c  2009-05-22 10:09:43.000000000 +0200
++++ kvm-86/sdl.c       2009-05-22 10:10:38.000000000 +0200
+@@ -214,7 +214,11 @@
+     if (keysym == 92 && ev->keysym.scancode == 133) {
+         keysym = 0xa5;
+     }
+-    return keysym2scancode(kbd_layout, keysym);
++    keydata_t *kd = find_keysym(kbd_layout, keysym);
++    if (kd==NULL)
++        return 0;
++    else
++        return kd->keycode;
+ }
+ /* specific keyboard conversions from scan codes */
+Index: kvm-86/vnc.c
+===================================================================
+--- kvm-86.orig/vnc.c  2009-05-22 10:09:54.000000000 +0200
++++ kvm-86/vnc.c       2009-05-22 10:10:38.000000000 +0200
+@@ -1257,27 +1257,85 @@
+     check_pointer_type_change(vs, kbd_mouse_is_absolute());
+ }
++static void do_keycode(int keycode, int down)
++{
++    // fprintf (stderr, "KEY: %04x %d\n", keycode, down);
++    if (keycode & 0x80)
++        kbd_put_keycode(0xe0);
++    if (down)
++        kbd_put_keycode(keycode & 0x7f);
++    else
++        kbd_put_keycode(keycode | 0x80);
++}
++
++static void do_modifier(VncState *vs, int keycode, int down, int level)
++{
++    do_keycode(keycode, down);
++    vs->modifiers_state[level][keycode] = down;
++    if (level==0) {
++        vs->modifiers_state[1][keycode] = down;
++    }
++}
++
+ static void reset_keys(VncState *vs)
+ {
+     int i;
+     for(i = 0; i < 256; i++) {
+-        if (vs->modifiers_state[i]) {
+-            if (i & 0x80)
+-                kbd_put_keycode(0xe0);
+-            kbd_put_keycode(i | 0x80);
+-            vs->modifiers_state[i] = 0;
++        if (vs->modifiers_state[0][i]) {
++          do_modifier (vs, i, 0, 0);
++        }
++    }
++}
++
++static void set_modifiers(VncState *vs, uint8_t reqstate, int down, int full)
++{
++    modifier_t *m;
++    for(m=test_modifier; m->bit; m++) {
++        int requested = reqstate & m->bit;
++        /* Release unwanted modifiers */
++        if (!down || full) {
++            if (vs->modifiers_state[1][m->keycode] && !requested)
++                do_modifier(vs, m->keycode, 0, 1);
++        }
++        /* Press desired modifiers */
++        if (down || full) {
++            int already_set = vs->modifiers_state[1][m->keycode];
++            if (!already_set && requested)
++                do_modifier(vs, m->keycode, 1, 1);
+         }
+     }
+ }
++static void restore_modifiers(VncState *vs)
++{
++    /* Restore modifiers from reference */
++    modifier_t *m;
++    for(m=test_modifier; m->bit; m++) {
++        if (vs->modifiers_state[0][m->keycode] !=
++          vs->modifiers_state[1][m->keycode])
++            do_modifier(vs, m->keycode, vs->modifiers_state[0][m->keycode], 0);
++    }
++}
+ static void press_key(VncState *vs, int keysym)
+ {
+-    kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
+-    kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
++    keydata_t *kd = find_keysym(vs->vd->kbd_layout, keysym & 0xFFFF);
++    if (kd==NULL)
++        return;
++
++    kbd_put_keycode(kd->keycode & 0x7f);
++    kbd_put_keycode(kd->keycode | 0x80);
+ }
+-static void do_key_event(VncState *vs, int down, int keycode, int sym)
++static void do_key_event(VncState *vs, int down, keydata_t *kd, int sym)
+ {
++    if (kd==NULL)
++        return;
++
++    int keycode = kd->keycode;
++    //fprintf (stderr, "SYM: %04x SCANCODE: %04x MOD %04x\n",
++    //             sym, keycode, kd->keymod);
++
++
+     /* QEMU console switch */
+     switch(keycode) {
+     case 0x2a:                          /* Left Shift */
+@@ -1286,23 +1344,24 @@
+     case 0x9d:                          /* Right CTRL */
+     case 0x38:                          /* Left ALT */
+     case 0xb8:                          /* Right ALT */
+-        if (down)
+-            vs->modifiers_state[keycode] = 1;
+-        else
+-            vs->modifiers_state[keycode] = 0;
+-        break;
++        do_modifier(vs, keycode, down, 0);
++        return;
+     case 0x02 ... 0x0a: /* '1' to '9' keys */
+-        if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
++        if (down && vs->modifiers_state[0][0x1d] && vs->modifiers_state[0][0x38]) {
+             /* Reset the modifiers sent to the current console */
+             reset_keys(vs);
+             console_select(keycode - 0x02);
+             return;
+         }
+         break;
+-    case 0x3a:                        /* CapsLock */
+-    case 0x45:                        /* NumLock */
+-        if (!down)
+-            vs->modifiers_state[keycode] ^= 1;
++    case 0x3a:                        /* CapsLock */
++    case 0x45:                        /* NumLock */
++        if (!down) {
++          if (vs->modifiers_state[0][0x45])
++              do_modifier(vs, keycode, 0, 0);
++          else
++              do_modifier(vs, keycode, 1, 0);
++      }
+         break;
+     }
+@@ -1312,25 +1371,42 @@
+            toggles numlock away from the VNC window.
+         */
+         if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
+-            if (!vs->modifiers_state[0x45]) {
+-                vs->modifiers_state[0x45] = 1;
++          if (!vs->modifiers_state[0][0x45]) {
++              do_modifier(vs, 0x45, 1, 0);
+                 press_key(vs, 0xff7f);
+             }
+         } else {
+-            if (vs->modifiers_state[0x45]) {
+-                vs->modifiers_state[0x45] = 0;
+-                press_key(vs, 0xff7f);
++            if (vs->modifiers_state[0][0x45]) {
++              do_modifier(vs, 0x45, 0, 0);
++              press_key(vs, 0xff7f);
+             }
+         }
+     }
+     if (is_graphic_console()) {
+-        if (keycode & 0x80)
+-            kbd_put_keycode(0xe0);
+-        if (down)
+-            kbd_put_keycode(keycode & 0x7f);
+-        else
+-            kbd_put_keycode(keycode | 0x80);
++        if (down) {
++          /* Send deadkey */
++          if (kd->keymod & KEYMOD_DEAD) {
++            keydata_t *deaddata;
++            deaddata = find_keysym(vs->vd->kbd_layout, kd->deadsym);
++            if (deaddata != NULL) {
++                set_modifiers(vs, deaddata->keymod, 0, 1);
++                do_keycode(deaddata->keycode, 1);
++                do_keycode(deaddata->keycode, 0);
++                restore_modifiers(vs);
++            }
++          }
++          set_modifiers(vs, kd->keymod, 1, 0);
++      } else
++          restore_modifiers(vs);
++
++        do_keycode (keycode, down);
++
++      /* vnc never sends ALTGR, so we create an artificial up event */
++      if (down && (kd->keymod & KEYMOD_ALTGR)) {
++          set_modifiers(vs, kd->keymod, 0, 0);
++      }
++
+     } else {
+         /* QEMU console emulation */
+         if (down) {
+@@ -1388,13 +1464,9 @@
+ static void key_event(VncState *vs, int down, uint32_t sym)
+ {
+-    int keycode;
+-
+-    if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
+-        sym = sym - 'A' + 'a';
++    keydata_t *kd = find_keysym(vs->vd->kbd_layout, sym & 0xFFFF);
+-    keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
+-    do_key_event(vs, down, keycode, sym);
++    do_key_event(vs, down, kd, sym & 0xFFFF);
+ }
+ static void ext_key_event(VncState *vs, int down,
+@@ -1403,8 +1475,15 @@
+     /* if the user specifies a keyboard layout, always use it */
+     if (keyboard_layout)
+         key_event(vs, down, sym);
+-    else
+-        do_key_event(vs, down, keycode, sym);
++    else {
++        keydata_t kd;
++
++        kd.keycode = keycode;
++      kd.keymod = 0;
++      kd.deadsym = 0;
++
++      do_key_event(vs, down, &kd, sym & 0xFFFF);
++    }
+ }
+ static void framebuffer_update_request(VncState *vs, int incremental,
+Index: kvm-86/vnc.h
+===================================================================
+--- kvm-86.orig/vnc.h  2009-05-22 10:10:08.000000000 +0200
++++ kvm-86/vnc.h       2009-05-22 10:10:38.000000000 +0200
+@@ -49,6 +49,21 @@
+  *
+  *****************************************************************************/
++typedef struct {
++    int keycode;
++    int bit;
++} modifier_t;
++
++static modifier_t test_modifier[]={
++    {0x2a, KEYMOD_SHIFT},
++    {0x36, KEYMOD_SHIFT},
++    {0x1d, KEYMOD_CTRL},
++    {0x9d, KEYMOD_CTRL},
++    {0x38, KEYMOD_ALT},
++    {0xb8, KEYMOD_ALTGR},
++    {0,0},
++};
++
+ typedef struct Buffer
+ {
+     size_t capacity;
+@@ -156,7 +171,7 @@
+     VncReadEvent *read_handler;
+     size_t read_handler_expect;
+     /* input */
+-    uint8_t modifiers_state[256];
++    uint8_t modifiers_state[2][256];
+     Buffer zlib;
+     Buffer zlib_tmp;
diff --git a/debian/patches-0.12.1/live-migration-fixes.diff b/debian/patches-0.12.1/live-migration-fixes.diff
new file mode 100644 (file)
index 0000000..1cb3a71
--- /dev/null
@@ -0,0 +1,51 @@
+Index: qemu-kvm/vl.c
+===================================================================
+--- qemu-kvm.orig/vl.c 2009-09-30 10:35:45.000000000 +0200
++++ qemu-kvm/vl.c      2009-09-30 10:47:05.000000000 +0200
+@@ -3175,9 +3175,10 @@
+ static int ram_save_live(QEMUFile *f, int stage, void *opaque)
+ {
+     ram_addr_t addr;
+-    uint64_t bytes_transferred_last;
+     double bwidth = 0;
+     uint64_t expected_time = 0;
++    static int64_t starttime = 0;
++    double timediff;
+     if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
+         qemu_file_set_error(f);
+@@ -3195,10 +3196,9 @@
+         cpu_physical_memory_set_dirty_tracking(1);
+         qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
+-    }
+-    bytes_transferred_last = bytes_transferred;
+-    bwidth = get_clock();
++      starttime = get_clock();
++    }
+     while (!qemu_file_rate_limit(f)) {
+         int ret;
+@@ -3209,8 +3209,8 @@
+             break;
+     }
+-    bwidth = get_clock() - bwidth;
+-    bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
++    timediff = get_clock() - starttime;
++    bwidth = bytes_transferred / timediff;
+     /* if we haven't transferred anything this round, force expected_time to a
+      * a very high value, but without crashing */
+@@ -3230,6 +3230,10 @@
+     qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
++    if ((stage == 2) && (bytes_transferred > 2*ram_bytes_total())) {
++        return 1;
++    }
++
+     expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
+     return (stage == 2) && (expected_time <= migrate_max_downtime());
diff --git a/debian/patches-0.12.1/multicore.diff b/debian/patches-0.12.1/multicore.diff
new file mode 100644 (file)
index 0000000..f4a4674
--- /dev/null
@@ -0,0 +1,201 @@
+Index: kvm-86/cpu-defs.h
+===================================================================
+--- kvm-86.orig/cpu-defs.h     2009-09-24 14:19:14.000000000 +0200
++++ kvm-86/cpu-defs.h  2009-09-24 14:47:00.000000000 +0200
+@@ -194,6 +194,8 @@
+     int cpu_index; /* CPU index (informative) */                        \
+     uint32_t host_tid; /* host thread ID */                             \
+     int numa_node; /* NUMA node this cpu is belonging to  */            \
++    int nr_cores;  /* number of cores within this CPU package */        \
++    int nr_threads;/* number of threads within this CPU */              \
+     int running; /* Nonzero if cpu is currently running(usermode).  */  \
+     int thread_id;                                                    \
+     /* user data */                                                     \
+Index: kvm-86/target-i386/helper.c
+===================================================================
+--- kvm-86.orig/target-i386/helper.c   2009-09-24 14:19:14.000000000 +0200
++++ kvm-86/target-i386/helper.c        2009-09-24 14:50:18.000000000 +0200
+@@ -121,7 +121,7 @@
+ #ifdef TARGET_X86_64
+     {
+         .name = "qemu64",
+-        .level = 2,
++        .level = 4,
+         .vendor1 = CPUID_VENDOR_AMD_1,
+         .vendor2 = CPUID_VENDOR_AMD_2,
+         .vendor3 = CPUID_VENDOR_AMD_3,
+@@ -192,7 +192,7 @@
+ #endif
+     {
+         .name = "qemu32",
+-        .level = 2,
++        .level = 4,
+         .family = 6,
+         .model = 3,
+         .stepping = 3,
+@@ -1638,6 +1638,12 @@
+         *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+         *ecx = env->cpuid_ext_features;
+         *edx = env->cpuid_features;
++
++        if (env->nr_cores * env->nr_threads > 1) {
++          *ebx |= (env->nr_cores * env->nr_threads) << 16;
++          *edx |= 1 << 28;    /* HTT bit */
++        }
++
+         break;
+     case 2:
+         /* cache info: needed for Pentium Pro compatibility */
+@@ -1648,21 +1654,29 @@
+         break;
+     case 4:
+         /* cache info: needed for Core compatibility */
++        if (env->nr_cores > 1) {
++              *eax = (env->nr_cores - 1) << 26;
++        } else {
++              *eax = 0;
++        }
+         switch (count) {
+             case 0: /* L1 dcache info */
+-                *eax = 0x0000121;
++                *eax |= 0x0000121;
+                 *ebx = 0x1c0003f;
+                 *ecx = 0x000003f;
+                 *edx = 0x0000001;
+                 break;
+             case 1: /* L1 icache info */
+-                *eax = 0x0000122;
++                *eax |= 0x0000122;
+                 *ebx = 0x1c0003f;
+                 *ecx = 0x000003f;
+                 *edx = 0x0000001;
+                 break;
+             case 2: /* L2 cache info */
+-                *eax = 0x0000143;
++                *eax |= 0x0000143;
++                if (env->nr_threads > 1) {
++                    *eax |= (env->nr_threads - 1) << 14;
++                }
+                 *ebx = 0x3c0003f;
+                 *ecx = 0x0000fff;
+                 *edx = 0x0000001;
+@@ -1715,6 +1729,16 @@
+         *ecx = env->cpuid_ext3_features;
+         *edx = env->cpuid_ext2_features;
++        if (env->nr_cores * env->nr_threads > 1) {
++            uint32_t teax, tebx, tecx, tedx;
++            cpu_x86_cpuid(env, 0, 0, &teax, &tebx, &tecx, &tedx);
++            if ( tebx == CPUID_VENDOR_AMD_1 &&
++                tedx == CPUID_VENDOR_AMD_2 &&
++                tecx == CPUID_VENDOR_AMD_3) {
++                *ecx |= 1 << 1;    /* CmpLegacy bit */
++            }
++      }
++
+         if (kvm_enabled()) {
+             uint32_t h_eax, h_edx;
+@@ -1790,6 +1814,9 @@
+         *ebx = 0;
+         *ecx = 0;
+         *edx = 0;
++        if (env->nr_cores * env->nr_threads > 1) {
++            *ecx |= (env->nr_cores * env->nr_threads) - 1;
++        }
+         break;
+     case 0x8000000A:
+         *eax = 0x00000001; /* SVM Revision */
+Index: kvm-86/vl.c
+===================================================================
+--- kvm-86.orig/vl.c   2009-09-24 14:30:14.000000000 +0200
++++ kvm-86/vl.c        2009-09-24 14:47:00.000000000 +0200
+@@ -230,6 +230,8 @@
+ const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
+ int assigned_devices_index;
+ int smp_cpus = 1;
++int smp_cores = 1;
++int smp_threads = 1;
+ int fairsched_id = 0;
+ const char *vnc_display;
+ int acpi_enabled = 1;
+@@ -2499,6 +2501,52 @@
+     return;
+ }
++static void smp_parse(const char *optarg)
++{
++    int smp, sockets = 0, threads = 0, cores = 0;
++    char *endptr;
++    char option[128];
++
++    smp = strtoul(optarg, &endptr, 10);
++    if (endptr != optarg) {
++        if (*endptr == ',') {
++            endptr++;
++        }
++    }
++    if (get_param_value(option, 128, "sockets", endptr) != 0)
++        sockets = strtoull(option, NULL, 10);
++    if (get_param_value(option, 128, "cores", endptr) != 0)
++        cores = strtoull(option, NULL, 10);
++    if (get_param_value(option, 128, "threads", endptr) != 0)
++        threads = strtoull(option, NULL, 10);
++
++    /* compute missing values, prefer sockets over cores over threads */
++    if (smp == 0 || sockets == 0) {
++        sockets = sockets > 0 ? sockets : 1;
++        cores = cores > 0 ? cores : 1;
++        threads = threads > 0 ? threads : 1;
++        if (smp == 0) {
++            smp = cores * threads * sockets;
++        } else {
++            sockets = smp / (cores * threads);
++        }
++    } else {
++        if (cores == 0) {
++            threads = threads > 0 ? threads : 1;
++            cores = smp / (sockets * threads);
++        } else {
++            if (sockets == 0) {
++                sockets = smp / (cores * threads);
++            } else {
++                threads = smp / (cores * sockets);
++            }
++        }
++    }
++    smp_cpus = smp;
++    smp_cores = cores > 0 ? cores : 1;
++    smp_threads = threads > 0 ? threads : 1;
++}
++
+ /***********************************************************/
+ /* USB devices */
+@@ -3727,6 +3775,8 @@
+     if (kvm_enabled())
+         kvm_init_vcpu(env);
++    env->nr_cores = smp_cores;
++    env->nr_threads = smp_threads;
+     return;
+ }
+@@ -4060,6 +4110,8 @@
+         kvm_start_vcpu(env);
+     else
+         tcg_init_vcpu(env);
++    env->nr_cores = smp_cores;
++    env->nr_threads = smp_threads;
+ }
+ void qemu_notify_event(void)
+@@ -5560,7 +5612,7 @@
+                 usb_devices_index++;
+                 break;
+             case QEMU_OPTION_smp:
+-                smp_cpus = atoi(optarg);
++                smp_parse(optarg);
+                 if (smp_cpus < 1) {
+                     fprintf(stderr, "Invalid number of CPUs\n");
+                     exit(1);
diff --git a/debian/patches-0.12.1/ps2-queue-size.diff b/debian/patches-0.12.1/ps2-queue-size.diff
new file mode 100644 (file)
index 0000000..58564bc
--- /dev/null
@@ -0,0 +1,20 @@
+
+bug description: boot a guest, open VNC console, and when it's still in BIOS / bootloader sequence, type as many keys as you can, move your mouse as much as you can. If needed, just reboot the guest.
+
+Linux guest will boot with "i8042.c: No controller found" and no keyboard.
+
+Further discussion seem to lead to a conclusion that there is some obscure bug in Qemu BIOS which makes this problem visible.
+
+Index: kvm-86/hw/ps2.c
+===================================================================
+--- kvm-86.orig/hw/ps2.c       2009-06-15 13:31:24.000000000 +0200
++++ kvm-86/hw/ps2.c    2009-06-15 13:31:50.000000000 +0200
+@@ -70,7 +70,7 @@
+ #define MOUSE_STATUS_ENABLED    0x20
+ #define MOUSE_STATUS_SCALE21    0x10
+-#define PS2_QUEUE_SIZE 256
++#define PS2_QUEUE_SIZE 15
+ typedef struct {
+     uint8_t data[PS2_QUEUE_SIZE];
diff --git a/debian/patches-0.12.1/series b/debian/patches-0.12.1/series
new file mode 100644 (file)
index 0000000..902ebc9
--- /dev/null
@@ -0,0 +1,7 @@
+adjust-path.diff
+fairsched.diff
+vncticket.diff
+#keymap.diff
+#multicore.diff
+live-migration-fixes.diff
+enable-ksm.diff
diff --git a/debian/patches-0.12.1/vncticket.diff b/debian/patches-0.12.1/vncticket.diff
new file mode 100644 (file)
index 0000000..5bf4102
--- /dev/null
@@ -0,0 +1,126 @@
+Index: qemu-kvm/console.h
+===================================================================
+--- qemu-kvm.orig/console.h    2009-12-21 10:37:57.000000000 +0100
++++ qemu-kvm/console.h 2009-12-21 10:45:29.000000000 +0100
+@@ -322,7 +322,7 @@
+ void vnc_display_init(DisplayState *ds);
+ void vnc_display_close(DisplayState *ds);
+ int vnc_display_open(DisplayState *ds, const char *display);
+-int vnc_display_password(DisplayState *ds, const char *password);
++int vnc_display_password(DisplayState *ds, const char *password, int limit);
+ void do_info_vnc_print(Monitor *mon, const QObject *data);
+ void do_info_vnc(Monitor *mon, QObject **ret_data);
+ char *vnc_display_local_addr(DisplayState *ds);
+Index: qemu-kvm/monitor.c
+===================================================================
+--- qemu-kvm.orig/monitor.c    2009-12-21 10:37:58.000000000 +0100
++++ qemu-kvm/monitor.c 2009-12-21 11:03:40.000000000 +0100
+@@ -949,9 +949,9 @@
+     monitor_read_bdrv_key_start(mon, bs, NULL, NULL);
+ }
+-static void change_vnc_password(const char *password)
++static void change_vnc_password(const char *password, int limit)
+ {
+-    if (vnc_display_password(NULL, password) < 0)
++    if (vnc_display_password(NULL, password, limit) < 0)
+         qemu_error_new(QERR_SET_PASSWD_FAILED);
+ }
+@@ -959,19 +959,30 @@
+ static void change_vnc_password_cb(Monitor *mon, const char *password,
+                                    void *opaque)
+ {
+-    change_vnc_password(password);
++    change_vnc_password(password, 0);
++    monitor_read_command(mon, 1);
++}
++
++static void change_vnc_ticket_cb(Monitor *mon, const char *password,
++                               void *opaque)
++{
++    change_vnc_password(password, 1);
+     monitor_read_command(mon, 1);
+ }
+ static void do_change_vnc(Monitor *mon, const char *target, const char *arg)
+ {
+     if (strcmp(target, "passwd") == 0 ||
+-        strcmp(target, "password") == 0) {
++        strcmp(target, "password") == 0 ||
++      strcmp(target, "ticket") == 0) {
+         if (arg) {
+             char password[9];
+             strncpy(password, arg, sizeof(password));
+             password[sizeof(password) - 1] = '\0';
+-            change_vnc_password(password);
++          if (strcmp(target, "ticket") == 0)
++            change_vnc_ticket_cb(mon, password, NULL);
++          else 
++            change_vnc_password_cb(mon, password, NULL);
+         } else {
+             monitor_read_password(mon, change_vnc_password_cb, NULL);
+         }
+Index: qemu-kvm/vnc.c
+===================================================================
+--- qemu-kvm.orig/vnc.c        2009-12-21 10:37:57.000000000 +0100
++++ qemu-kvm/vnc.c     2009-12-21 10:44:13.000000000 +0100
+@@ -1763,7 +1763,7 @@
+ static void set_pixel_conversion(VncState *vs)
+ {
+     if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
+-        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && 
++        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
+         !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
+         vs->write_pixels = vnc_write_pixels_copy;
+         switch (vs->ds->surface->pf.bits_per_pixel) {
+@@ -1871,7 +1871,7 @@
+         vnc_write_u8(vs, 0);  /* msg id */
+         vnc_write_u8(vs, 0);
+         vnc_write_u16(vs, 1); /* number of rects */
+-        vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), 
++        vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
+                                ds_get_height(vs->ds), VNC_ENCODING_WMVi);
+         pixel_format_message(vs);
+         vnc_flush(vs);
+@@ -2068,7 +2068,10 @@
+     int i, j, pwlen;
+     unsigned char key[8];
+-    if (!vs->vd->password || !vs->vd->password[0]) {
++    if (vs->vd->retries >= 0)
++        vs->vd->retries++;
++
++    if (!vs->vd->password || !vs->vd->password[0] || vs->vd->retries > 3) {
+         VNC_DEBUG("No password configured on server");
+         vnc_write_u32(vs, 1); /* Reject auth */
+         if (vs->minor >= 8) {
+@@ -2438,7 +2441,7 @@
+ #endif
+ }
+-int vnc_display_password(DisplayState *ds, const char *password)
++int vnc_display_password(DisplayState *ds, const char *password, int limit)
+ {
+     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+@@ -2453,6 +2456,7 @@
+     if (password && password[0]) {
+         if (!(vs->password = qemu_strdup(password)))
+             return -1;
++      vs->retries = limit ? 0 : -1;
+         if (vs->auth == VNC_AUTH_NONE) {
+             vs->auth = VNC_AUTH_VNC;
+         }
+Index: qemu-kvm/vnc.h
+===================================================================
+--- qemu-kvm.orig/vnc.h        2009-12-21 10:37:57.000000000 +0100
++++ qemu-kvm/vnc.h     2009-12-21 10:44:13.000000000 +0100
+@@ -104,6 +104,7 @@
+     char *display;
+     char *password;
++    int retries;
+     int auth;
+ #ifdef CONFIG_VNC_TLS
+     int subauth; /* Used by VeNCrypt */
diff --git a/debian/patches/adjust-path.diff b/debian/patches/adjust-path.diff
new file mode 100644 (file)
index 0000000..3545a09
--- /dev/null
@@ -0,0 +1,41 @@
+Index: new/net.h
+===================================================================
+--- new.orig/net.h     2011-08-11 10:04:51.000000000 +0200
++++ new/net.h  2011-08-11 10:09:49.000000000 +0200
+@@ -172,8 +172,8 @@
+ int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
+ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
+-#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
+-#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
++#define DEFAULT_NETWORK_SCRIPT "/etc/kvm/kvm-ifup"
++#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/kvm/kvm-ifdown"
+ #ifdef __sun__
+ #define SMBD_COMMAND "/usr/sfw/sbin/smbd"
+ #else
+Index: new/configure
+===================================================================
+--- new.orig/configure 2011-08-11 10:04:51.000000000 +0200
++++ new/configure      2011-08-11 10:09:49.000000000 +0200
+@@ -157,7 +157,7 @@
+ bindir="\${prefix}/bin"
+ libdir="\${prefix}/lib"
+ sysconfdir="\${prefix}/etc"
+-confsuffix="/qemu"
++confsuffix="/kvm"
+ slirp="yes"
+ fmod_lib=""
+ fmod_inc=""
+Index: new/net/tap.h
+===================================================================
+--- new.orig/net/tap.h 2011-08-11 10:04:51.000000000 +0200
++++ new/net/tap.h      2011-08-11 10:09:49.000000000 +0200
+@@ -29,8 +29,6 @@
+ #include "qemu-common.h"
+ #include "qemu-option.h"
+-#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
+-#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
+ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan);
diff --git a/debian/patches/cpuid-fix.diff b/debian/patches/cpuid-fix.diff
new file mode 100644 (file)
index 0000000..1052ad5
--- /dev/null
@@ -0,0 +1,18 @@
+see http://git.kernel.org/?p=virt/kvm/qemu-kvm.git;a=commitdiff;h=8fa3b3ce6e#patch1
+
+KVM_GET_SUPPORTED_CPUID has been known to fail to return -E2BIG
+when it runs out of entries. Detect this by always trying again
+with a bigger table if the ioctl() fills the table.
+
+--- a/kvm/libkvm/libkvm-x86.c
++++ b/kvm/libkvm/libkvm-x86.c
+@@ -575,6 +575,8 @@ static struct kvm_cpuid2 *try_get_cpuid(kvm_context_t kvm, int max)
+       r = ioctl(kvm->fd, KVM_GET_SUPPORTED_CPUID, cpuid);
+       if (r == -1)
+               r = -errno;
++      else if (r == 0 && cpuid->nent >= max)
++              r = -E2BIG;
+       if (r < 0) {
+               if (r == -E2BIG) {
+                       free(cpuid);
+
diff --git a/debian/patches/fairsched.diff b/debian/patches/fairsched.diff
new file mode 100644 (file)
index 0000000..7a57ada
--- /dev/null
@@ -0,0 +1,159 @@
+Index: new/qemu-options.hx
+===================================================================
+--- new.orig/qemu-options.hx   2011-08-11 10:04:51.000000000 +0200
++++ new/qemu-options.hx        2011-08-11 10:09:56.000000000 +0200
+@@ -89,6 +89,12 @@
+ are split equally.
+ ETEXI
++DEF("id", HAS_ARG, QEMU_OPTION_id,
++    "-id n         set the faisched ID\n", QEMU_ARCH_ALL)
++
++DEF("cpuunits",  HAS_ARG, QEMU_OPTION_cpuunits,
++    "-cpuuinits n    set fairsched cpu units\n", QEMU_ARCH_ALL)
++
+ DEF("fda", HAS_ARG, QEMU_OPTION_fda,
+     "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
+ DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
+Index: new/vl.c
+===================================================================
+--- new.orig/vl.c      2011-08-11 10:04:51.000000000 +0200
++++ new/vl.c   2011-08-11 10:09:56.000000000 +0200
+@@ -150,6 +150,8 @@
+ #include "fsdev/qemu-fsdev.h"
+ #endif
++#include "vzsyscalls.h"
++
+ #include "disas.h"
+ #include "qemu_socket.h"
+@@ -203,6 +205,7 @@
+ int rtc_td_hack = 0;
+ int usb_enabled = 0;
+ int singlestep = 0;
++int fairsched_id = 0;
+ int smp_cpus = 1;
+ int max_cpus = 0;
+ int smp_cores = 1;
+@@ -2074,6 +2077,7 @@
+ {
+     const char *gdbstub_dev = NULL;
+     int i;
++    int cpuunits = 0;
+     int snapshot, linux_boot;
+     const char *icount_option = NULL;
+     const char *initrd_filename;
+@@ -2768,6 +2772,20 @@
+                     exit(1);
+                 }
+                 break;
++            case QEMU_OPTION_id:
++                fairsched_id = atoi(optarg);
++              if (fairsched_id < 100 || fairsched_id >= 1000000) {
++                  fprintf(stderr, "Invalid ID\n");
++                  exit(1);
++              }
++                break;
++            case QEMU_OPTION_cpuunits:
++                cpuunits = atoi(optarg);
++              if (cpuunits < 8 || cpuunits > 500000) {
++                  fprintf(stderr, "Invalid value for cpuunits\n");
++                    exit(1);
++                }
++                break;
+           case QEMU_OPTION_vnc:
+ #ifdef CONFIG_VNC
+                 display_remote++;
+@@ -3141,6 +3159,39 @@
+     if (ram_size == 0)
+         ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
++    if (cpuunits && !fairsched_id) {
++      fprintf(stderr, "cpuunits specified without -id");
++      exit (1);
++    }
++
++    if (fairsched_id && cpuunits) {
++      int ret;
++      int weight = cpuunits ? 500000/cpuunits : 500;
++      pid_t cpid = getpid();
++
++      ret = syscall(__NR_fairsched_rmnod, fairsched_id);
++      if (ret == -EBUSY) {
++      fprintf (stderr, "unable to create fairsched node - still in use\n");
++      exit(1);
++      }
++
++      ret = syscall(__NR_fairsched_mknod, 0, weight, fairsched_id);
++      if (ret != fairsched_id) {
++      fprintf (stderr, "unable to create fairsched node\n");
++      exit(1);
++      }
++
++      ret = syscall(__NR_fairsched_mvpr, cpid, fairsched_id);
++      if (ret != 0) {
++      fprintf (stderr, "unable to move procces to fairsched group");
++      exit (1);
++      }
++
++      /* note: we can never remove ourself from the group, so the empty group
++       will exist after we finish
++      */
++    }
++
+     /* init the dynamic translator */
+     cpu_exec_init_all(tb_size * 1024 * 1024);
+Index: new/vzsyscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ new/vzsyscalls.h   2011-08-11 10:09:56.000000000 +0200
+@@ -0,0 +1,47 @@
++/*
++ *  Copyright (C) 2000-2008, Parallels, Inc. All rights reserved.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation; either version 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++#ifndef _VZSYSCALLS_H_
++#define _VZSYSCALLS_H_
++
++#include <sys/syscall.h>
++
++#ifdef __x86_64__
++#define __NR_fairsched_vcpus  499
++#define __NR_setluid          501
++#define __NR_setublimit               502
++#define __NR_fairsched_mknod    504
++#define __NR_fairsched_rmnod    505
++#define __NR_fairsched_chwt   506
++#define __NR_fairsched_mvpr     507
++#define __NR_fairsched_rate   508
++#define __NR_ioprio_set               251
++#elif defined(__i386__)
++#define __NR_fairsched_mknod    500
++#define __NR_fairsched_rmnod    501
++#define __NR_fairsched_chwt   502
++#define __NR_fairsched_mvpr     503
++#define __NR_fairsched_rate   504
++#define __NR_fairsched_vcpus  505
++#define __NR_setluid          511
++#define __NR_setublimit               512
++#define __NR_ioprio_set               289
++#else
++#error "no syscall for this arch"
++#endif
++
++#endif
diff --git a/debian/patches/fr-ca-keymap-corrections.diff b/debian/patches/fr-ca-keymap-corrections.diff
new file mode 100644 (file)
index 0000000..89dcc27
--- /dev/null
@@ -0,0 +1,36 @@
+Index: new/pc-bios/keymaps/fr-ca
+===================================================================
+--- new.orig/pc-bios/keymaps/fr-ca     2011-08-11 10:04:51.000000000 +0200
++++ new/pc-bios/keymaps/fr-ca  2011-08-11 10:09:38.000000000 +0200
+@@ -14,22 +14,31 @@
+ twosuperior 0x9 altgr
+ threesuperior 0xa altgr
+ onequarter 0xb altgr
++minus 0x0c
+ onehalf 0xc altgr
++equal 0xd
+ threequarters 0xd altgr
+ section 0x18 altgr
+ paragraph 0x19 altgr
+ bracketleft 0x1a altgr
+ bracketright 0x1b altgr
++semicolon 0x27
++colon 0x27 shift
+ asciitilde 0x27 altgr
+ braceleft 0x28 altgr
++numbersign 0x29
+ braceright 0x2b altgr
+ less 0x2b
+ greater 0x2b shift
+ guillemotleft 0x56
+ guillemotright 0x56 shift
+ degree 0x56 altgr
++comma 0x33
+ mu 0x32 altgr
++apostrophe 0x33 shift
++period 0x34 shift
+ eacute 0x35
++Eacute 0x35 shift
+ dead_acute 0x35 altgr
+ dead_grave 0x28
+ dead_circumflex 0x1a
diff --git a/debian/patches/keymap.diff b/debian/patches/keymap.diff
new file mode 100644 (file)
index 0000000..e4c16db
--- /dev/null
@@ -0,0 +1,68 @@
+Index: new/ui/vnc.c
+===================================================================
+--- new.orig/ui/vnc.c  2011-08-11 10:04:51.000000000 +0200
++++ new/ui/vnc.c       2011-08-11 10:10:00.000000000 +0200
+@@ -1444,6 +1444,10 @@
+ static void do_key_event(VncState *vs, int down, int keycode, int sym)
+ {
++    int mods =  keycode & 0xf00;
++
++    keycode &= SCANCODE_KEYMASK;
++
+     /* QEMU console switch */
+     switch(keycode) {
+     case 0x2a:                          /* Left Shift */
+@@ -1514,12 +1518,42 @@
+     }
+     if (is_graphic_console()) {
++
++      /* our java vnc client never sends ALTGR, so we create
++         an artificial up/down event */
++
++      int emul_altgr = (mods & SCANCODE_ALTGR) &&
++          !vs->modifiers_state[0xb8];
++
++      if (emul_altgr) {
++              reset_keys(vs);
++              kbd_put_keycode(SCANCODE_EMUL0);
++              kbd_put_keycode(0xb8 & SCANCODE_KEYCODEMASK);
++      }
++
++      int emul_shift = (mods & SCANCODE_SHIFT) &&
++          !vs->modifiers_state[0x2a];
++
++      if (emul_shift) {
++          kbd_put_keycode(0x2a & SCANCODE_KEYCODEMASK);
++      }
++
+         if (keycode & SCANCODE_GREY)
+             kbd_put_keycode(SCANCODE_EMUL0);
+         if (down)
+             kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK);
+         else
+             kbd_put_keycode(keycode | SCANCODE_UP);
++
++      if (emul_shift) {
++          kbd_put_keycode(0x2a | SCANCODE_UP);
++      }
++
++      if (emul_altgr) {
++          kbd_put_keycode(SCANCODE_EMUL0);
++          kbd_put_keycode(0xb8 | SCANCODE_UP);
++      }
++
+     } else {
+         /* QEMU console emulation */
+         if (down) {
+@@ -1627,7 +1661,8 @@
+         lsym = lsym - 'A' + 'a';
+     }
+-    keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
++    keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF);
++
+     do_key_event(vs, down, keycode, sym);
+ }
diff --git a/debian/patches/live-migration-fixes.diff b/debian/patches/live-migration-fixes.diff
new file mode 100644 (file)
index 0000000..38dd6e4
--- /dev/null
@@ -0,0 +1,51 @@
+Index: new/arch_init.c
+===================================================================
+--- new.orig/arch_init.c       2011-08-11 10:04:51.000000000 +0200
++++ new/arch_init.c    2011-08-11 10:10:04.000000000 +0200
+@@ -251,9 +251,10 @@
+ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
+ {
+     ram_addr_t addr;
+-    uint64_t bytes_transferred_last;
+     double bwidth = 0;
+     uint64_t expected_time = 0;
++    static int64_t starttime = 0;
++    double timediff;
+     if (stage < 0) {
+         cpu_physical_memory_set_dirty_tracking(0);
+@@ -293,10 +294,10 @@
+             qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
+             qemu_put_be64(f, block->length);
+         }
++
++      starttime = qemu_get_clock_ns(rt_clock);
+     }
+-    bytes_transferred_last = bytes_transferred;
+-    bwidth = qemu_get_clock_ns(rt_clock);
+     while (!qemu_file_rate_limit(f)) {
+         int bytes_sent;
+@@ -308,8 +309,8 @@
+         }
+     }
+-    bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
+-    bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
++    timediff = qemu_get_clock_ns(rt_clock) - starttime;
++    bwidth = bytes_transferred / timediff;
+     /* if we haven't transferred anything this round, force expected_time to a
+      * a very high value, but without crashing */
+@@ -330,6 +331,10 @@
+     qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
++    if ((stage == 2) && (bytes_transferred > 2*ram_bytes_total())) {
++        return 1;
++    }
++
+     expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
+     return (stage == 2) && (expected_time <= migrate_max_downtime());
diff --git a/debian/patches/multicore.diff b/debian/patches/multicore.diff
new file mode 100644 (file)
index 0000000..f4a4674
--- /dev/null
@@ -0,0 +1,201 @@
+Index: kvm-86/cpu-defs.h
+===================================================================
+--- kvm-86.orig/cpu-defs.h     2009-09-24 14:19:14.000000000 +0200
++++ kvm-86/cpu-defs.h  2009-09-24 14:47:00.000000000 +0200
+@@ -194,6 +194,8 @@
+     int cpu_index; /* CPU index (informative) */                        \
+     uint32_t host_tid; /* host thread ID */                             \
+     int numa_node; /* NUMA node this cpu is belonging to  */            \
++    int nr_cores;  /* number of cores within this CPU package */        \
++    int nr_threads;/* number of threads within this CPU */              \
+     int running; /* Nonzero if cpu is currently running(usermode).  */  \
+     int thread_id;                                                    \
+     /* user data */                                                     \
+Index: kvm-86/target-i386/helper.c
+===================================================================
+--- kvm-86.orig/target-i386/helper.c   2009-09-24 14:19:14.000000000 +0200
++++ kvm-86/target-i386/helper.c        2009-09-24 14:50:18.000000000 +0200
+@@ -121,7 +121,7 @@
+ #ifdef TARGET_X86_64
+     {
+         .name = "qemu64",
+-        .level = 2,
++        .level = 4,
+         .vendor1 = CPUID_VENDOR_AMD_1,
+         .vendor2 = CPUID_VENDOR_AMD_2,
+         .vendor3 = CPUID_VENDOR_AMD_3,
+@@ -192,7 +192,7 @@
+ #endif
+     {
+         .name = "qemu32",
+-        .level = 2,
++        .level = 4,
+         .family = 6,
+         .model = 3,
+         .stepping = 3,
+@@ -1638,6 +1638,12 @@
+         *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+         *ecx = env->cpuid_ext_features;
+         *edx = env->cpuid_features;
++
++        if (env->nr_cores * env->nr_threads > 1) {
++          *ebx |= (env->nr_cores * env->nr_threads) << 16;
++          *edx |= 1 << 28;    /* HTT bit */
++        }
++
+         break;
+     case 2:
+         /* cache info: needed for Pentium Pro compatibility */
+@@ -1648,21 +1654,29 @@
+         break;
+     case 4:
+         /* cache info: needed for Core compatibility */
++        if (env->nr_cores > 1) {
++              *eax = (env->nr_cores - 1) << 26;
++        } else {
++              *eax = 0;
++        }
+         switch (count) {
+             case 0: /* L1 dcache info */
+-                *eax = 0x0000121;
++                *eax |= 0x0000121;
+                 *ebx = 0x1c0003f;
+                 *ecx = 0x000003f;
+                 *edx = 0x0000001;
+                 break;
+             case 1: /* L1 icache info */
+-                *eax = 0x0000122;
++                *eax |= 0x0000122;
+                 *ebx = 0x1c0003f;
+                 *ecx = 0x000003f;
+                 *edx = 0x0000001;
+                 break;
+             case 2: /* L2 cache info */
+-                *eax = 0x0000143;
++                *eax |= 0x0000143;
++                if (env->nr_threads > 1) {
++                    *eax |= (env->nr_threads - 1) << 14;
++                }
+                 *ebx = 0x3c0003f;
+                 *ecx = 0x0000fff;
+                 *edx = 0x0000001;
+@@ -1715,6 +1729,16 @@
+         *ecx = env->cpuid_ext3_features;
+         *edx = env->cpuid_ext2_features;
++        if (env->nr_cores * env->nr_threads > 1) {
++            uint32_t teax, tebx, tecx, tedx;
++            cpu_x86_cpuid(env, 0, 0, &teax, &tebx, &tecx, &tedx);
++            if ( tebx == CPUID_VENDOR_AMD_1 &&
++                tedx == CPUID_VENDOR_AMD_2 &&
++                tecx == CPUID_VENDOR_AMD_3) {
++                *ecx |= 1 << 1;    /* CmpLegacy bit */
++            }
++      }
++
+         if (kvm_enabled()) {
+             uint32_t h_eax, h_edx;
+@@ -1790,6 +1814,9 @@
+         *ebx = 0;
+         *ecx = 0;
+         *edx = 0;
++        if (env->nr_cores * env->nr_threads > 1) {
++            *ecx |= (env->nr_cores * env->nr_threads) - 1;
++        }
+         break;
+     case 0x8000000A:
+         *eax = 0x00000001; /* SVM Revision */
+Index: kvm-86/vl.c
+===================================================================
+--- kvm-86.orig/vl.c   2009-09-24 14:30:14.000000000 +0200
++++ kvm-86/vl.c        2009-09-24 14:47:00.000000000 +0200
+@@ -230,6 +230,8 @@
+ const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
+ int assigned_devices_index;
+ int smp_cpus = 1;
++int smp_cores = 1;
++int smp_threads = 1;
+ int fairsched_id = 0;
+ const char *vnc_display;
+ int acpi_enabled = 1;
+@@ -2499,6 +2501,52 @@
+     return;
+ }
++static void smp_parse(const char *optarg)
++{
++    int smp, sockets = 0, threads = 0, cores = 0;
++    char *endptr;
++    char option[128];
++
++    smp = strtoul(optarg, &endptr, 10);
++    if (endptr != optarg) {
++        if (*endptr == ',') {
++            endptr++;
++        }
++    }
++    if (get_param_value(option, 128, "sockets", endptr) != 0)
++        sockets = strtoull(option, NULL, 10);
++    if (get_param_value(option, 128, "cores", endptr) != 0)
++        cores = strtoull(option, NULL, 10);
++    if (get_param_value(option, 128, "threads", endptr) != 0)
++        threads = strtoull(option, NULL, 10);
++
++    /* compute missing values, prefer sockets over cores over threads */
++    if (smp == 0 || sockets == 0) {
++        sockets = sockets > 0 ? sockets : 1;
++        cores = cores > 0 ? cores : 1;
++        threads = threads > 0 ? threads : 1;
++        if (smp == 0) {
++            smp = cores * threads * sockets;
++        } else {
++            sockets = smp / (cores * threads);
++        }
++    } else {
++        if (cores == 0) {
++            threads = threads > 0 ? threads : 1;
++            cores = smp / (sockets * threads);
++        } else {
++            if (sockets == 0) {
++                sockets = smp / (cores * threads);
++            } else {
++                threads = smp / (cores * sockets);
++            }
++        }
++    }
++    smp_cpus = smp;
++    smp_cores = cores > 0 ? cores : 1;
++    smp_threads = threads > 0 ? threads : 1;
++}
++
+ /***********************************************************/
+ /* USB devices */
+@@ -3727,6 +3775,8 @@
+     if (kvm_enabled())
+         kvm_init_vcpu(env);
++    env->nr_cores = smp_cores;
++    env->nr_threads = smp_threads;
+     return;
+ }
+@@ -4060,6 +4110,8 @@
+         kvm_start_vcpu(env);
+     else
+         tcg_init_vcpu(env);
++    env->nr_cores = smp_cores;
++    env->nr_threads = smp_threads;
+ }
+ void qemu_notify_event(void)
+@@ -5560,7 +5612,7 @@
+                 usb_devices_index++;
+                 break;
+             case QEMU_OPTION_smp:
+-                smp_cpus = atoi(optarg);
++                smp_parse(optarg);
+                 if (smp_cpus < 1) {
+                     fprintf(stderr, "Invalid number of CPUs\n");
+                     exit(1);
diff --git a/debian/patches/ps2-queue-size.diff b/debian/patches/ps2-queue-size.diff
new file mode 100644 (file)
index 0000000..58564bc
--- /dev/null
@@ -0,0 +1,20 @@
+
+bug description: boot a guest, open VNC console, and when it's still in BIOS / bootloader sequence, type as many keys as you can, move your mouse as much as you can. If needed, just reboot the guest.
+
+Linux guest will boot with "i8042.c: No controller found" and no keyboard.
+
+Further discussion seem to lead to a conclusion that there is some obscure bug in Qemu BIOS which makes this problem visible.
+
+Index: kvm-86/hw/ps2.c
+===================================================================
+--- kvm-86.orig/hw/ps2.c       2009-06-15 13:31:24.000000000 +0200
++++ kvm-86/hw/ps2.c    2009-06-15 13:31:50.000000000 +0200
+@@ -70,7 +70,7 @@
+ #define MOUSE_STATUS_ENABLED    0x20
+ #define MOUSE_STATUS_SCALE21    0x10
+-#define PS2_QUEUE_SIZE 256
++#define PS2_QUEUE_SIZE 15
+ typedef struct {
+     uint8_t data[PS2_QUEUE_SIZE];
diff --git a/debian/patches/pve-auth.patch b/debian/patches/pve-auth.patch
new file mode 100644 (file)
index 0000000..5921d00
--- /dev/null
@@ -0,0 +1,425 @@
+Index: new/ui/vnc.c
+===================================================================
+--- new.orig/ui/vnc.c  2011-08-11 10:10:00.000000000 +0200
++++ new/ui/vnc.c       2011-08-11 10:10:30.000000000 +0200
+@@ -31,6 +31,8 @@
+ #include "qemu-timer.h"
+ #include "acl.h"
+ #include "qemu-objects.h"
++#include <signal.h>
++#include <sys/wait.h>
+ #define VNC_REFRESH_INTERVAL_BASE 30
+ #define VNC_REFRESH_INTERVAL_INC  50
+@@ -41,6 +43,125 @@
+ #include "vnc_keysym.h"
+ #include "d3des.h"
++static int pve_vmid = 0;
++
++void pve_auth_setup(int vmid) {
++      pve_vmid = vmid;
++}
++
++static char *
++urlencode(char *buf, const char *value)
++{
++      static const char *hexchar = "0123456789abcdef";
++      char *p = buf;
++      int i;
++      int l = strlen(value);
++      for (i = 0; i < l; i++) {
++              char c = value[i];
++              if (('a' <= c && c <= 'z') ||
++                  ('A' <= c && c <= 'Z') ||
++                  ('0' <= c && c <= '9')) {
++                      *p++ = c;
++              } else if (c == 32) {
++                      *p++ = '+';
++              } else {
++                      *p++ = '%';
++                      *p++ = hexchar[c >> 4];
++                      *p++ = hexchar[c & 15];
++              }
++      }
++      *p = 0;
++
++      return p;
++}
++
++int
++pve_auth_verify(const char *clientip, const char *username, const char *passwd)
++{
++      struct sockaddr_in server;
++
++      int sfd = socket(AF_INET, SOCK_STREAM, 0);
++      if (sfd == -1) {
++              perror("pve_auth_verify: socket failed");
++              return -1;
++      }
++
++      struct hostent *he;
++      if ((he = gethostbyname("localhost")) == NULL) {
++              fprintf(stderr, "pve_auth_verify: error resolving hostname\n");
++              goto err;
++      }
++
++      memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
++      server.sin_family = AF_INET;
++      server.sin_port = htons(85);
++
++      if (connect(sfd, (struct sockaddr *)&server, sizeof(server))) {
++              perror("pve_auth_verify: error connecting to server");
++              goto err;
++      }
++
++      char buf[8192];
++      char form[8192];
++
++      char *p = form;
++      p = urlencode(p, "username");
++      *p++ = '=';
++      p = urlencode(p, username);
++
++      *p++ = '&';
++      p = urlencode(p, "password");
++      *p++ = '=';
++      p = urlencode(p, passwd);
++
++      *p++ = '&';
++      p = urlencode(p, "path");
++      *p++ = '=';
++      char authpath[256];
++      sprintf(authpath, "/vms/%d", pve_vmid);
++      p = urlencode(p, authpath);
++
++      *p++ = '&';
++      p = urlencode(p, "privs");
++      *p++ = '=';
++      p = urlencode(p, "VM.Console");
++
++      sprintf(buf, "POST /api2/json/access/ticket HTTP/1.1\n"
++              "Host: localhost:85\n"
++              "Connection: close\n"
++              "PVEClientIP: %s\n"
++              "Content-Type: application/x-www-form-urlencoded\n"
++              "Content-Length: %zd\n\n%s\n", clientip, strlen(form), form);
++      ssize_t len = strlen(buf);
++      ssize_t sb = send(sfd, buf, len, 0);
++      if (sb < 0) {
++              perror("pve_auth_verify: send failed");
++              goto err;
++      }
++      if (sb != len) {
++              fprintf(stderr, "pve_auth_verify: partial send error\n");
++              goto err;
++      }
++
++      len = recv(sfd, buf, sizeof(buf) - 1, 0);
++      if (len < 0) {
++              perror("pve_auth_verify: recv failed");
++              goto err;
++      }
++
++      buf[len] = 0;
++
++      //printf("DATA:%s\n", buf);
++
++      shutdown(sfd, SHUT_RDWR);
++
++      return strncmp(buf, "HTTP/1.1 200 OK", 15);
++
++err:
++      shutdown(sfd, SHUT_RDWR);
++      return -1;
++}
++
+ static VncDisplay *vnc_display; /* needed for info vnc */
+ static DisplayChangeListener *dcl;
+@@ -1810,7 +1931,7 @@
+ static void set_pixel_conversion(VncState *vs)
+ {
+     if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
+-        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && 
++        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
+         !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
+         vs->write_pixels = vnc_write_pixels_copy;
+         vnc_hextile_set_pixel_conversion(vs, 0);
+@@ -1896,7 +2017,7 @@
+         vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
+         vnc_write_u8(vs, 0);
+         vnc_write_u16(vs, 1); /* number of rects */
+-        vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), 
++        vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
+                                ds_get_height(vs->ds), VNC_ENCODING_WMVi);
+         pixel_format_message(vs);
+         vnc_unlock_output(vs);
+@@ -2729,7 +2850,7 @@
+ char *vnc_display_local_addr(DisplayState *ds)
+ {
+     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+-    
++
+     return vnc_socket_local_addr("%s:%s", vs->lsock);
+ }
+@@ -2778,6 +2899,7 @@
+             tls = 1; /* Require TLS */
+         } else if (strncmp(options, "x509", 4) == 0) {
+             char *start, *end;
++            tls = 1; /* Require TLS */
+             x509 = 1; /* Require x509 certificates */
+             if (strncmp(options, "x509verify", 10) == 0)
+                 vs->tls.x509verify = 1; /* ...and verify client certs */
+@@ -2800,10 +2922,12 @@
+                 }
+                 qemu_free(path);
+             } else {
+-                fprintf(stderr, "No certificate path provided\n");
+-                qemu_free(vs->display);
+-                vs->display = NULL;
+-                return -1;
++                if (pve_tls_set_x509_creds_dir(vs) < 0) {
++                      fprintf(stderr, "No certificate path provided\n");
++                      qemu_free(vs->display);
++                      vs->display = NULL;
++                      return -1;
++              }
+             }
+ #endif
+ #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
+@@ -2856,10 +2980,10 @@
+             vs->auth = VNC_AUTH_VENCRYPT;
+             if (x509) {
+                 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
+-                vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
++                vs->subauth = VNC_AUTH_VENCRYPT_X509PLAIN;
+             } else {
+                 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
+-                vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
++                vs->subauth = VNC_AUTH_VENCRYPT_TLSPLAIN;
+             }
+         } else {
+ #endif /* CONFIG_VNC_TLS */
+Index: new/ui/vnc-auth-vencrypt.c
+===================================================================
+--- new.orig/ui/vnc-auth-vencrypt.c    2011-08-11 10:04:51.000000000 +0200
++++ new/ui/vnc-auth-vencrypt.c 2011-08-11 10:10:30.000000000 +0200
+@@ -25,7 +25,107 @@
+  */
+ #include "vnc.h"
++#include "qemu_socket.h"
++static int protocol_client_auth_plain(VncState *vs, uint8_t *data, size_t len)
++{
++      const char *err = NULL;
++      char username[256];
++      char passwd[512];
++
++      char clientip[256];
++      clientip[0] = 0;
++      struct sockaddr_in client;
++      socklen_t addrlen = sizeof(client);
++      if (getpeername(vs->csock, &client, &addrlen) == 0) {
++              inet_ntop(client.sin_family, &client.sin_addr, 
++                        clientip, sizeof(clientip));
++      }
++
++      if ((len != (vs->username_len + vs->password_len)) ||
++          (vs->username_len >= (sizeof(username)-1)) ||
++          (vs->password_len >= (sizeof(passwd)-1))    ) {
++              err = "Got unexpected data length";
++              goto err;
++      }
++
++      strncpy(username, (char *)data, vs->username_len);
++      username[vs->username_len] = 0;
++      strncpy(passwd, (char *)data + vs->username_len, vs->password_len);
++      passwd[vs->password_len] = 0;
++
++      VNC_DEBUG("AUTH PLAIN username: %s pw: %s\n", username, passwd);
++
++      if (pve_auth_verify(clientip, username, passwd) == 0) {
++              vnc_write_u32(vs, 0); /* Accept auth completion */
++              start_client_init(vs);
++              return 0;
++      }
++
++      err =  "Authentication failed";
++err:
++       if (err) {
++             VNC_DEBUG("AUTH PLAIN ERROR: %s\n", err);
++             vnc_write_u32(vs, 1); /* Reject auth */
++             if (vs->minor >= 8) {
++                     int elen = strlen(err);
++                     vnc_write_u32(vs, elen);
++                     vnc_write(vs, err, elen);
++             }
++       }
++       vnc_flush(vs);
++       vnc_client_error(vs);
++
++       return 0;
++
++}
++
++static int protocol_client_auth_plain_start(VncState *vs, uint8_t *data, size_t len)
++{
++      uint32_t ulen = read_u32(data, 0);
++      uint32_t pwlen = read_u32(data, 4);
++      const char *err = NULL;
++
++      VNC_DEBUG("AUTH PLAIN START %u %u\n", ulen, pwlen);
++
++       if (!ulen) {
++             err = "No User name.";
++             goto err;
++       }
++       if (ulen >= 255) {
++             err = "User name too long.";
++             goto err;
++       }
++       if (!pwlen) {
++             err = "Password too short";
++             goto err;
++       }
++       if (pwlen >= 511) {
++             err = "Password too long.";
++             goto err;
++       }
++
++       vs->username_len = ulen;
++       vs->password_len = pwlen;
++
++       vnc_read_when(vs, protocol_client_auth_plain, ulen + pwlen);
++
++       return 0;
++err:
++       if (err) {
++             VNC_DEBUG("AUTH PLAIN ERROR: %s\n", err);
++             vnc_write_u32(vs, 1); /* Reject auth */
++             if (vs->minor >= 8) {
++                     int elen = strlen(err);
++                     vnc_write_u32(vs, elen);
++                     vnc_write(vs, err, elen);
++             }
++       }
++       vnc_flush(vs);
++       vnc_client_error(vs);
++
++       return 0;
++}
+ static void start_auth_vencrypt_subauth(VncState *vs)
+ {
+@@ -37,6 +137,12 @@
+        start_client_init(vs);
+        break;
++    case VNC_AUTH_VENCRYPT_TLSPLAIN:
++    case VNC_AUTH_VENCRYPT_X509PLAIN:
++       VNC_DEBUG("Start TLS auth PLAIN\n");
++       vnc_read_when(vs, protocol_client_auth_plain_start, 8);
++       break;
++
+     case VNC_AUTH_VENCRYPT_TLSVNC:
+     case VNC_AUTH_VENCRYPT_X509VNC:
+        VNC_DEBUG("Start TLS auth VNC\n");
+Index: new/ui/vnc.h
+===================================================================
+--- new.orig/ui/vnc.h  2011-08-11 10:04:51.000000000 +0200
++++ new/ui/vnc.h       2011-08-11 10:12:42.000000000 +0200
+@@ -260,6 +260,8 @@
+     char challenge[VNC_AUTH_CHALLENGE_SIZE];
+ #ifdef CONFIG_VNC_TLS
+     int subauth; /* Used by VeNCrypt */
++    int username_len;
++    int password_len;
+     VncStateTLS tls;
+ #endif
+ #ifdef CONFIG_VNC_SASL
+Index: new/ui/vnc-tls.c
+===================================================================
+--- new.orig/ui/vnc-tls.c      2011-08-11 10:04:51.000000000 +0200
++++ new/ui/vnc-tls.c   2011-08-11 10:10:30.000000000 +0200
+@@ -291,6 +291,14 @@
+     static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
+     static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
++    /* optimize for speed */
++    static const int ciphers[] = {
++          GNUTLS_CIPHER_ARCFOUR_128,
++          GNUTLS_CIPHER_AES_128_CBC,
++          GNUTLS_CIPHER_3DES_CBC,
++          0
++    };
++
+     VNC_DEBUG("Do TLS setup\n");
+     if (vnc_tls_initialize() < 0) {
+         VNC_DEBUG("Failed to init TLS\n");
+@@ -310,6 +318,13 @@
+             return -1;
+         }
++      if ((gnutls_cipher_set_priority(vs->tls.session, ciphers)) < 0) {
++          gnutls_deinit(vs->tls.session);
++            vs->tls.session = NULL;
++            vnc_client_error(vs);
++            return -1;
++      }
++
+         if (gnutls_kx_set_priority(vs->tls.session, needX509Creds ? kx_x509 : kx_anon) < 0) {
+             gnutls_deinit(vs->tls.session);
+             vs->tls.session = NULL;
+@@ -419,6 +434,24 @@
+     return 0;
+ }
++int pve_tls_set_x509_creds_dir(VncDisplay *vd)
++{
++    if (vnc_set_x509_credential(vd, "/etc/pve", "pve-root-ca.pem", &vd->tls.x509cacert, 0) < 0)
++        goto cleanup;
++    if (vnc_set_x509_credential(vd, "/etc/pve/local", "pve-ssl.pem", &vd->tls.x509cert, 0) < 0)
++        goto cleanup;
++    if (vnc_set_x509_credential(vd, "/etc/pve/local", "pve-ssl.key", &vd->tls.x509key, 0) < 0)
++        goto cleanup;
++
++    return 0;
++
++ cleanup:
++    qemu_free(vd->tls.x509cacert);
++    qemu_free(vd->tls.x509cert);
++    qemu_free(vd->tls.x509key);
++    vd->tls.x509cacert = vd->tls.x509cacrl = vd->tls.x509cert = vd->tls.x509key = NULL;
++    return -1;
++}
+ int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
+                                const char *certdir)
+Index: new/ui/vnc-tls.h
+===================================================================
+--- new.orig/ui/vnc-tls.h      2011-08-11 10:04:51.000000000 +0200
++++ new/ui/vnc-tls.h   2011-08-11 10:10:30.000000000 +0200
+@@ -68,6 +68,8 @@
+ int vnc_tls_validate_certificate(VncState *vs);
++int pve_tls_set_x509_creds_dir(VncDisplay *vd);
++
+ int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
+                              const char *path);
+Index: new/vl.c
+===================================================================
+--- new.orig/vl.c      2011-08-11 10:09:56.000000000 +0200
++++ new/vl.c   2011-08-11 10:10:30.000000000 +0200
+@@ -2774,6 +2774,7 @@
+                 break;
+             case QEMU_OPTION_id:
+                 fairsched_id = atoi(optarg);
++              pve_auth_setup(fairsched_id);
+               if (fairsched_id < 100 || fairsched_id >= 1000000) {
+                   fprintf(stderr, "Invalid ID\n");
+                   exit(1);
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644 (file)
index 0000000..1d64f4b
--- /dev/null
@@ -0,0 +1,9 @@
+fr-ca-keymap-corrections.diff
+adjust-path.diff
+fairsched.diff
+keymap.diff
+live-migration-fixes.diff
+set-max-nics.patch
+use-local-linux-kvm-h.diff
+pve-auth.patch
+
diff --git a/debian/patches/set-max-nics.patch b/debian/patches/set-max-nics.patch
new file mode 100644 (file)
index 0000000..67c871a
--- /dev/null
@@ -0,0 +1,13 @@
+Index: new/net.h
+===================================================================
+--- new.orig/net.h     2011-08-11 10:09:49.000000000 +0200
++++ new/net.h  2011-08-11 10:10:08.000000000 +0200
+@@ -126,7 +126,7 @@
+ /* NIC info */
+-#define MAX_NICS 8
++#define MAX_NICS 32
+ struct NICInfo {
+     MACAddr macaddr;
diff --git a/debian/patches/use-local-linux-kvm-h.diff b/debian/patches/use-local-linux-kvm-h.diff
new file mode 100644 (file)
index 0000000..6990382
--- /dev/null
@@ -0,0 +1,16 @@
+
+Alway use our own version.
+
+Index: new/kvm/libkvm/libkvm.h
+===================================================================
+--- new.orig/kvm/libkvm/libkvm.h       2011-08-11 10:04:51.000000000 +0200
++++ new/kvm/libkvm/libkvm.h    2011-08-11 10:10:13.000000000 +0200
+@@ -15,7 +15,7 @@
+ #define __user /* temporary, until installed via make headers_install */
+ #endif
+-#include <linux/kvm.h>
++#include "linux/kvm.h"
+ #include <signal.h>
diff --git a/debian/patches/vncticket.diff b/debian/patches/vncticket.diff
new file mode 100644 (file)
index 0000000..fa1474d
--- /dev/null
@@ -0,0 +1,149 @@
+Index: qemu-kvm/console.h
+===================================================================
+--- qemu-kvm.orig/console.h    2010-10-21 13:40:20.000000000 +0200
++++ qemu-kvm/console.h 2010-10-21 14:06:21.000000000 +0200
+@@ -368,7 +368,7 @@
+ void vnc_display_init(DisplayState *ds);
+ void vnc_display_close(DisplayState *ds);
+ int vnc_display_open(DisplayState *ds, const char *display);
+-int vnc_display_password(DisplayState *ds, const char *password);
++int vnc_display_password(DisplayState *ds, const char *password, int limit);
+ void do_info_vnc_print(Monitor *mon, const QObject *data);
+ void do_info_vnc(Monitor *mon, QObject **ret_data);
+ char *vnc_display_local_addr(DisplayState *ds);
+Index: qemu-kvm/ui/vnc.c
+===================================================================
+--- qemu-kvm.orig/ui/vnc.c     2010-10-21 13:40:21.000000000 +0200
++++ qemu-kvm/ui/vnc.c  2010-10-21 14:06:21.000000000 +0200
+@@ -1790,7 +1790,7 @@
+ static void set_pixel_conversion(VncState *vs)
+ {
+     if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
+-        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && 
++        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
+         !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
+         vs->write_pixels = vnc_write_pixels_copy;
+         vnc_hextile_set_pixel_conversion(vs, 0);
+@@ -1876,7 +1876,7 @@
+         vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
+         vnc_write_u8(vs, 0);
+         vnc_write_u16(vs, 1); /* number of rects */
+-        vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), 
++        vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
+                                ds_get_height(vs->ds), VNC_ENCODING_WMVi);
+         pixel_format_message(vs);
+         vnc_unlock_output(vs);
+@@ -2079,7 +2079,10 @@
+     int i, j, pwlen;
+     unsigned char key[8];
+-    if (!vs->vd->password || !vs->vd->password[0]) {
++    if (vs->vd->retries >= 0)
++        vs->vd->retries++;
++
++    if (!vs->vd->password || !vs->vd->password[0] || vs->vd->retries > 3) {
+         VNC_DEBUG("No password configured on server");
+         vnc_write_u32(vs, 1); /* Reject auth */
+         if (vs->minor >= 8) {
+@@ -2478,7 +2481,7 @@
+ #endif
+ }
+-int vnc_display_password(DisplayState *ds, const char *password)
++int vnc_display_password(DisplayState *ds, const char *password, int limit)
+ {
+     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+@@ -2493,6 +2496,7 @@
+     if (password && password[0]) {
+         if (!(vs->password = qemu_strdup(password)))
+             return -1;
++      vs->retries = limit ? 0 : -1;
+         if (vs->auth == VNC_AUTH_NONE) {
+             vs->auth = VNC_AUTH_VNC;
+         }
+Index: qemu-kvm/ui/vnc.h
+===================================================================
+--- qemu-kvm.orig/ui/vnc.h     2010-10-21 13:40:20.000000000 +0200
++++ qemu-kvm/ui/vnc.h  2010-10-21 14:06:21.000000000 +0200
+@@ -120,6 +120,7 @@
+     char *display;
+     char *password;
++    int retries;
+     int auth;
+     bool lossy;
+ #ifdef CONFIG_VNC_TLS
+Index: qemu-kvm/monitor.c
+===================================================================
+--- qemu-kvm.orig/monitor.c    2010-10-21 13:40:21.000000000 +0200
++++ qemu-kvm/monitor.c 2010-10-21 14:14:38.000000000 +0200
+@@ -978,7 +978,7 @@
+ static int change_vnc_password(const char *password)
+ {
+-    if (vnc_display_password(NULL, password) < 0) {
++    if (vnc_display_password(NULL, password, 0) < 0) {
+         qerror_report(QERR_SET_PASSWD_FAILED);
+         return -1;
+     }
+@@ -986,6 +986,17 @@
+     return 0;
+ }
++static int change_vnc_ticket(const char *password)
++{
++    if (vnc_display_password(NULL, password, 1) < 0) {
++      qerror_report(QERR_SET_PASSWD_FAILED);
++      return -1;
++    }
++
++    return 0;
++}
++
++
+ static void change_vnc_password_cb(Monitor *mon, const char *password,
+                                    void *opaque)
+ {
+@@ -996,12 +1007,16 @@
+ static int do_change_vnc(Monitor *mon, const char *target, const char *arg)
+ {
+     if (strcmp(target, "passwd") == 0 ||
+-        strcmp(target, "password") == 0) {
++        strcmp(target, "password") == 0 ||
++      strcmp(target, "ticket") == 0) {
+         if (arg) {
+             char password[9];
+             strncpy(password, arg, sizeof(password));
+             password[sizeof(password) - 1] = '\0';
+-            return change_vnc_password(password);
++          if (strcmp(target, "ticket") == 0)
++              return change_vnc_ticket(password);
++          else
++              return change_vnc_password(password);
+         } else {
+             return monitor_read_password(mon, change_vnc_password_cb, NULL);
+         }
+@@ -3324,11 +3339,11 @@
+ static int is_valid_option(const char *c, const char *typestr)
+ {
+     char option[3];
+-  
++
+     option[0] = '-';
+     option[1] = *c;
+     option[2] = '\0';
+-  
++
+     typestr = strstr(typestr, option);
+     return (typestr != NULL);
+ }
+@@ -3640,7 +3655,7 @@
+                     p++;
+                     if(c != *p) {
+                         if(!is_valid_option(p, typestr)) {
+-                  
++
+                             monitor_printf(mon, "%s: unsupported option -%c\n",
+                                            cmdname, *p);
+                             goto fail;
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..ea7cc5e
--- /dev/null
@@ -0,0 +1,137 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+PACKAGE=pve-qemu-kvm
+destdir := $(CURDIR)/debian/$(PACKAGE)
+
+ifneq "$(wildcard /usr/share/quilt/quilt.make)" ""
+include /usr/share/quilt/quilt.make
+endif
+
+CFLAGS = -Wall
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+
+config.status: configure
+       dh_testdir
+       # Add here commands to configure the package.
+       ./configure --prefix=/usr --datadir=/usr/share/kvm --docdir=/usr/share/doc/pve-qemu-kvm --sysconfdir=/etc --disable-xen --enable-vnc-tls --enable-sdl --enable-uuid --enable-linux-aio
+
+build: patch build-stamp
+
+build-stamp:  config.status
+       dh_testdir
+
+       # Add here commands to compile the package.
+       $(MAKE) V=1
+
+       #docbook-to-man debian/kvm.sgml > kvm.1
+
+       touch $@
+
+clean: unpatch
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp 
+
+       # Add here commands to clean up after the build process.
+       -$(MAKE) distclean
+ifneq "$(wildcard /usr/share/misc/config.sub)" ""
+       cp -f /usr/share/misc/config.sub config.sub
+endif
+ifneq "$(wildcard /usr/share/misc/config.guess)" ""
+       cp -f /usr/share/misc/config.guess config.guess
+endif
+
+
+       dh_clean 
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k 
+       dh_installdirs
+
+       # Add here commands to install the package into debian/pve-kvm.
+       $(MAKE) DESTDIR=$(destdir) install
+
+       mv $(destdir)/usr/bin/qemu-system-x86_64 $(destdir)/usr/bin/kvm
+       mv $(destdir)/usr/share/man/man1/qemu.1 $(destdir)/usr/share/man/man1/kvm.1
+
+       # Install the userspace utilities
+       install -m 0755 kvm/kvm_stat $(destdir)/usr/bin/
+
+       install -D -m 0755 $(CURDIR)/debian/kvm-ifup $(destdir)/etc/kvm/kvm-ifup
+       install -D -m 0755 $(CURDIR)/debian/kvm-ifdown $(destdir)/etc/kvm/kvm-ifdown
+       # we do not need openbios files (sparc/ppc)
+       rm -rf $(destdir)/usr/share/kvm/openbios-*
+       # remove ppc files
+       rm $(destdir)/usr/share/kvm/*.dtb
+       rm $(destdir)/usr/share/kvm/ppc_rom.bin
+       rm $(destdir)/usr/share/kvm/s390-zipl.rom
+       rm $(destdir)/usr/share/kvm/slof.bin
+       rm $(destdir)/usr/share/kvm/spapr-rtas.bin
+
+        # remove guest agent (that is only required for a guest)
+       rm $(destdir)/usr/bin/qemu-ga
+
+       # Remove things we don't package at all, would be a "kvm-dev" package
+       rm -Rf $(destdir)/usr/include/linux/
+       rm -Rf $(destdir)/usr/include
+       rm -Rf $(destdir)/usr/lib*
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs 
+       dh_installdocs
+       dh_installexamples
+#      dh_install
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_python
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_perl
+#      dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install