[Spice-commits] 31 commits - backends/baum.c backends/msmouse.c backends/rng-egd.c backends/testdev.c configure exec.c hw/core hw/i386 hw/net hw/virtio include/hw include/sysemu qemu-char.c rules.mak spice-qemu-char.c tests/Makefile tests/test-qdev-global-props.c ui/console.c ui/sdl2-keymap.h ui/sdl2.c ui/spice-core.c ui/vnc-tls.c ui/vnc.c util/qemu-sockets.c vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Sep 22 07:18:35 PDT 2014


 backends/baum.c                  |    2 
 backends/msmouse.c               |    2 
 backends/rng-egd.c               |    1 
 backends/testdev.c               |    2 
 configure                        |   11 +
 exec.c                           |    2 
 hw/core/machine.c                |    8 
 hw/core/qdev-properties-system.c |   18 -
 hw/core/qdev-properties.c        |   30 ++-
 hw/i386/pc.c                     |    6 
 hw/net/vhost_net.c               |    8 
 hw/net/virtio-net.c              |    2 
 hw/virtio/virtio-pci.c           |   45 +++-
 hw/virtio/virtio.c               |    9 
 include/hw/qdev-core.h           |   10 -
 include/hw/qdev-properties.h     |    2 
 include/sysemu/char.h            |    3 
 qemu-char.c                      |  353 ++++++++++++++++++---------------------
 rules.mak                        |    2 
 spice-qemu-char.c                |    8 
 tests/Makefile                   |    2 
 tests/test-qdev-global-props.c   |  159 ++++++++++++++++-
 ui/console.c                     |    3 
 ui/sdl2-keymap.h                 |    7 
 ui/sdl2.c                        |    1 
 ui/spice-core.c                  |    2 
 ui/vnc-tls.c                     |    2 
 ui/vnc.c                         |    1 
 util/qemu-sockets.c              |    3 
 vl.c                             |    2 
 30 files changed, 426 insertions(+), 280 deletions(-)

New commits:
commit 07e2863d0271ac6c05206d8ce9e4f4c39b25d3ea
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Sep 17 22:03:36 2014 -0700

    exec.c: fix setting 1-byte-long watchpoints
    
    With commit 05068c0dfb5b 'exec.c: Relax restrictions on watchpoint length
    and alignment' it's no longer possible to set 1-byte-long watchpoint
    because of incorrect address range check.
    Fix that by changing condition that checks for address wraparound.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1411016616-29879-1-git-send-email-jcmvbkbc at gmail.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/exec.c b/exec.c
index 2b24651..759055d 100644
--- a/exec.c
+++ b/exec.c
@@ -595,7 +595,7 @@ int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
     CPUWatchpoint *wp;
 
     /* forbid ranges which are empty or run off the end of the address space */
-    if (len == 0 || (addr + len - 1) <= addr) {
+    if (len == 0 || (addr + len - 1) < addr) {
         error_report("tried to set invalid watchpoint at %"
                      VADDR_PRIx ", len=%" VADDR_PRIu, addr, len);
         return -EINVAL;
commit 4852ee95f3a7ed8a02672b0fd0377167da5ed686
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Sep 18 21:55:08 2014 +0200

    Fix cross compilation (nm command)
    
    Commit c261d774fb9093d00e0938a19f502fb220f62718 added one more binutils
    tool: nm also needs a cross prefix.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1411070108-8954-1-git-send-email-sw at weilnetz.de
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/configure b/configure
index fb194fd..6c3d6cd 100755
--- a/configure
+++ b/configure
@@ -389,6 +389,7 @@ cpp="${CPP-$cc -E}"
 objcopy="${OBJCOPY-${cross_prefix}objcopy}"
 ld="${LD-${cross_prefix}ld}"
 libtool="${LIBTOOL-${cross_prefix}libtool}"
+nm="${NM-${cross_prefix}nm}"
 strip="${STRIP-${cross_prefix}strip}"
 windres="${WINDRES-${cross_prefix}windres}"
 pkg_config_exe="${PKG_CONFIG-${cross_prefix}pkg-config}"
@@ -4898,6 +4899,7 @@ echo "AS=$as" >> $config_host_mak
 echo "CPP=$cpp" >> $config_host_mak
 echo "OBJCOPY=$objcopy" >> $config_host_mak
 echo "LD=$ld" >> $config_host_mak
+echo "NM=$nm" >> $config_host_mak
 echo "WINDRES=$windres" >> $config_host_mak
 echo "LIBTOOL=$libtool" >> $config_host_mak
 echo "CFLAGS=$CFLAGS" >> $config_host_mak
diff --git a/rules.mak b/rules.mak
index 1d73293..cf76b88 100644
--- a/rules.mak
+++ b/rules.mak
@@ -23,7 +23,7 @@ QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d
 QEMU_INCLUDES += -I$(<D) -I$(@D)
 
 WL_U := -Wl,-u,
-find-symbols = $(if $1, $(sort $(shell nm -P -g $1 | $2)))
+find-symbols = $(if $1, $(sort $(shell $(NM) -P -g $1 | $2)))
 defined-symbols = $(call find-symbols,$1,awk '$$2!="U"{print $$1}')
 undefined-symbols = $(call find-symbols,$1,awk '$$2=="U"{print $$1}')
 
commit 10e11f4d2bf171f99c6b13883a510acfbc5dd585
Merge: bb26a1e 438f92e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Sep 18 20:02:00 2014 +0100

    Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
    
    pci, pc, virtio, misc bugfixes
    
    A bunch of bugfixes - some of these will make sense for 2.1.2
    I put Cc: qemu-stable included where appropriate.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    
    # gpg: Signature made Thu 18 Sep 2014 19:52:18 BST using RSA key ID D28D5469
    # gpg: Good signature from "Michael S. Tsirkin <mst at kernel.org>"
    # gpg:                 aka "Michael S. Tsirkin <mst at redhat.com>"
    
    * remotes/mst/tags/for_upstream:
      pc: leave more space for BIOS allocations
      virtio-pci: fix migration for pci bus master
      vhost-user: fix VIRTIO_NET_F_MRG_RXBUF negotiation
      virtio-pci: enable bus master for old guests
      Revert "virtio: don't call device on !vm_running"
      virtio-net: drop assert on vm stop
      Revert "rng-egd: remove redundant free"
      qdev: Move global validation to a single function
      qdev: Rename qdev_prop_check_global() to qdev_prop_check_globals()
      test-qdev-global-props: Test handling of hotpluggable and non-device types
      test-qdev-global-props: Initialize not_used=true for all props
      test-qdev-global-props: Run tests on subprocess
      tests: disable global props test for old glib
      test-qdev-global-props: Trivial comment fix
      hw/machine: Free old values of string properties
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 438f92ee9f6a4f78f8adcc399809e252b6da72a2
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Sep 18 16:32:07 2014 +0300

    pc: leave more space for BIOS allocations
    
    Since QEMU 2.1, we are allocating more space for ACPI tables, so no
    space is left after initrd for the BIOS to allocate memory.
    
    Besides ACPI tables, there are a few other uses of high memory in
    SeaBIOS: SMBIOS tables and USB drivers use it in particular.  These uses
    allocate a very small amount of memory.  Malloc metadata also lives
    there.  So we need _some_ extra padding there to avoid initrd breakage,
    but not much.
    
    John Snow found a case where RHEL5 was broken by the recent change to
    ACPI_TABLE_SIZE; in his case 4KB of extra padding are fine, but just to
    be safe I am adding 32KB, which is roughly the same amount of padding
    that was left by QEMU 2.0 and earlier.
    
    Move initrd to leave some space for the BIOS.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reported-by: John Snow <jsnow at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b6c9b61..9ac5bd2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -72,8 +72,10 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables.  */
-unsigned acpi_data_size = 0x20000;
+/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables
+ * (128K) and other BIOS datastructures (less than 4K reported to be used at
+ * the moment, 32K should be enough for a while).  */
+unsigned acpi_data_size = 0x20000 + 0x8000;
 void pc_set_legacy_acpi_data_size(void)
 {
     acpi_data_size = 0x10000;
commit 4d43d3f3c8147ade184df9a1e9e82826edd39e19
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Sep 11 18:34:29 2014 +0300

    virtio-pci: fix migration for pci bus master
    
    Current support for bus master (clearing OK bit)
    together with the need to support guests which do not
    enable PCI bus mastering, leads to extra state in
    VIRTIO_PCI_FLAG_BUS_MASTER_BUG bit, which isn't robust
    in case of cross-version migration for the case when
    guests use the device before setting DRIVER_OK.
    
    Rip out VIRTIO_PCI_FLAG_BUS_MASTER_BUG and implement a simpler
    work-around: treat clearing of PCI_COMMAND as a virtio reset.  Old
    guests never touch this bit so they will work.
    
    As reset clears device status, DRIVER and MASTER bits are
    now in sync, so we can fix up cross-version migration simply
    by synchronising them, without need to detect a buggy guest
    explicitly.
    
    Drop tracking VIRTIO_PCI_FLAG_BUS_MASTER_BUG completely.
    
    As reset makes the device quiescent, in the future we'll be able to drop
    checking OK bit in a bunch of places.
    
    Cc: Jason Wang <jasowang at redhat.com>
    Cc: Greg Kurz <gkurz at linux.vnet.ibm.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index a827cd4..f560814 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -86,9 +86,6 @@
  * 12 is historical, and due to x86 page size. */
 #define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
 
-/* Flags track per-device state like workarounds for quirks in older guests. */
-#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
-
 static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
                                VirtIOPCIProxy *dev);
 
@@ -323,14 +320,6 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
                                      proxy->pci_dev.config[PCI_COMMAND] |
                                      PCI_COMMAND_MASTER, 1);
         }
-
-        /* Linux before 2.6.34 sets the device as OK without enabling
-           the PCI device bus master bit. In this case we need to disable
-           some safety checks. */
-        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
-            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-        }
         break;
     case VIRTIO_MSI_CONFIG_VECTOR:
         msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
@@ -480,13 +469,18 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
+    uint8_t cmd = proxy->pci_dev.config[PCI_COMMAND];
+
     pci_default_write_config(pci_dev, address, val, len);
 
     if (range_covers_byte(address, len, PCI_COMMAND) &&
         !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
-        !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
+        (cmd & PCI_COMMAND_MASTER)) {
+        /* Bus driver disables bus mastering - make it act
+         * as a kind of reset to render the device quiescent. */
         virtio_pci_stop_ioeventfd(proxy);
-        virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
+        virtio_reset(vdev);
+        msix_unuse_all_vectors(&proxy->pci_dev);
     }
 }
 
@@ -895,11 +889,19 @@ static void virtio_pci_vmstate_change(DeviceState *d, bool running)
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
     if (running) {
-        /* Try to find out if the guest has bus master disabled, but is
-           in ready state. Then we have a buggy guest OS. */
-        if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
-            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
+        /* Linux before 2.6.34 drives the device without enabling
+           the PCI device bus master bit. Enable it automatically
+           for the guest. This is a PCI spec violation but so is
+           initiating DMA with bus master bit clear.
+           Note: this only makes a difference when migrating
+           across QEMU versions from an old QEMU, as for new QEMU
+           bus master and driver bits are always in sync.
+           TODO: consider enabling conditionally for compat machine types. */
+        if (vdev->status & (VIRTIO_CONFIG_S_ACKNOWLEDGE |
+                            VIRTIO_CONFIG_S_DRIVER)) {
+            pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
+                                     proxy->pci_dev.config[PCI_COMMAND] |
+                                     PCI_COMMAND_MASTER, 1);
         }
         virtio_pci_start_ioeventfd(proxy);
     } else {
@@ -1040,7 +1042,6 @@ static void virtio_pci_reset(DeviceState *qdev)
     virtio_pci_stop_ioeventfd(proxy);
     virtio_bus_reset(bus);
     msix_unuse_all_vectors(&proxy->pci_dev);
-    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 }
 
 static Property virtio_pci_properties[] = {
commit d8e80ae37a7acfea416ad9abbe76b453a73d9cc0
Author: Damjan Marion <damarion at cisco.com>
Date:   Thu Sep 11 14:55:48 2014 -0700

    vhost-user: fix VIRTIO_NET_F_MRG_RXBUF negotiation
    
    Header length check should happen only if backend is kernel. For user
    backend there is no reason to reset this bit.
    
    vhost-user code does not define .has_vnet_hdr_len so
    VIRTIO_NET_F_MRG_RXBUF cannot be negotiated even if both sides
    support it.
    
    Signed-off-by: Damjan Marion <damarion at cisco.com>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index b21e7a4..77bb93e 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -163,11 +163,11 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     if (r < 0) {
         goto fail;
     }
-    if (!qemu_has_vnet_hdr_len(options->net_backend,
-                               sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
-        net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
-    }
     if (backend_kernel) {
+        if (!qemu_has_vnet_hdr_len(options->net_backend,
+                               sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
+            net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
+        }
         if (~net->dev.features & net->dev.backend_features) {
             fprintf(stderr, "vhost lacks feature mask %" PRIu64
                    " for backend\n",
commit e43c0b2ea5574efb0bedebf6a7d05916eefeba52
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Sep 11 18:45:33 2014 +0200

    virtio-pci: enable bus master for old guests
    
    commit cc943c36faa192cd4b32af8fe5edb31894017d35
        pci: Use bus master address space for delivering MSI/MSI-X messages
    breaks virtio-net for rhel6.[56] x86 guests because they don't
    enable bus mastering for virtio PCI devices. For the same reason,
    rhel6.[56] ppc64 guests cannot boot on a virtio-blk disk anymore.
    
    Old guests forgot to enable bus mastering, enable it automatically on
    DRIVER (guests use some devices before DRIVER_OK).
    
    Reported-by: Greg Kurz <gkurz at linux.vnet.ibm.com>
    Reviewed-by: Greg Kurz <gkurz at linux.vnet.ibm.com>
    Tested-by: Greg Kurz <gkurz at linux.vnet.ibm.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index ddb5da1..a827cd4 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -314,6 +314,16 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             msix_unuse_all_vectors(&proxy->pci_dev);
         }
 
+        /* Linux before 2.6.34 drives the device without enabling
+           the PCI device bus master bit. Enable it automatically
+           for the guest. This is a PCI spec violation but so is
+           initiating DMA with bus master bit clear. */
+        if (val == (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER)) {
+            pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
+                                     proxy->pci_dev.config[PCI_COMMAND] |
+                                     PCI_COMMAND_MASTER, 1);
+        }
+
         /* Linux before 2.6.34 sets the device as OK without enabling
            the PCI device bus master bit. In this case we need to disable
            some safety checks. */
commit 9e8e8c48653471fa5fed447e388fdef57d4f6998
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Sep 11 18:42:02 2014 +0300

    Revert "virtio: don't call device on !vm_running"
    
    This reverts commit a1bc7b827e422e1ff065640d8ec5347c4aadfcd8.
        virtio: don't call device on !vm_running
    It turns out that virtio net assumes that vm_running
    is updated before device status callback in many places,
    so this change leads to asserts.
    Previous commit fixes the root issue that motivated
    a1bc7b827e422e1ff065640d8ec5347c4aadfcd8 differently,
    so there's no longer a need for this change.
    
    In the future, we might be able to drop checking vm_running
    completely, and check vm state directly.
    
    Reported-by: Dietmar Maurer <dietmar at proxmox.com>
    Cc: qemu-stable at nongnu.org
    Acked-by: Jason Wang <jasowang at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ac22238..5c98180 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1108,10 +1108,7 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
-
-    if (running) {
-        vdev->vm_running = running;
-    }
+    vdev->vm_running = running;
 
     if (backend_run) {
         virtio_set_status(vdev, vdev->status);
@@ -1124,10 +1121,6 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
     if (!backend_run) {
         virtio_set_status(vdev, vdev->status);
     }
-
-    if (!running) {
-        vdev->vm_running = running;
-    }
 }
 
 void virtio_init(VirtIODevice *vdev, const char *name,
commit 131c5221fe25a9547c4a388a3d26ff7fd14843e5
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Sep 11 18:32:51 2014 +0300

    virtio-net: drop assert on vm stop
    
    On vm stop, vm_running state set to stopped
    before device is notified, so callbacks can get envoked with
    vm_running = false; and this is not an error.
    
    Cc: qemu-stable at nongnu.org
    Acked-by: Jason Wang <jasowang at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 826a2a5..2040eac 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1125,8 +1125,6 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
         return num_packets;
     }
 
-    assert(vdev->vm_running);
-
     if (q->async_tx.elem.out_num) {
         virtio_queue_set_notification(q->tx_vq, 0);
         return num_packets;
commit abb4d5f2e2830b7a6dc4ddcc612dfab15e3a320d
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Thu Sep 4 19:10:47 2014 +0300

    Revert "rng-egd: remove redundant free"
    
    This reverts commit 5e490b6a504912225dff0e520e1c6af68295d238.
    
    Cc: qemu-stable at nongnu.org
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 25bb3b4..2962795 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -169,6 +169,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
     if (b->opened) {
         error_set(errp, QERR_PERMISSION_DENIED);
     } else {
+        g_free(s->chr_name);
         s->chr_name = g_strdup(value);
     }
 }
commit b3ce84fea466f3bca2ff85d158744f00c0f429bd
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Fri Aug 8 16:03:31 2014 -0300

    qdev: Move global validation to a single function
    
    Currently GlobalProperty.not_used=false has multiple meanings:
    
    * It may be a property for a hotpluggable device, which may or may not
      have been used by a device;
    * It may be a machine-type-provided property, which may or may not have
      been used by a device.
    * It may be a user-provided property that was actually not used by
      any device.
    
    Simplify the logic by having two separate fields: 'user_provided' and
    'used'. This allows the entire global property validation logic to be
    contained in a single function, and allows more specific error messages.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index ae0900f..84caa1d 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -388,28 +388,12 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 static int qdev_add_one_global(QemuOpts *opts, void *opaque)
 {
     GlobalProperty *g;
-    ObjectClass *oc;
 
     g = g_malloc0(sizeof(*g));
     g->driver   = qemu_opt_get(opts, "driver");
     g->property = qemu_opt_get(opts, "property");
     g->value    = qemu_opt_get(opts, "value");
-    oc = object_class_dynamic_cast(object_class_by_name(g->driver),
-                                   TYPE_DEVICE);
-    if (oc) {
-        DeviceClass *dc = DEVICE_CLASS(oc);
-
-        if (dc->hotpluggable) {
-            /* If hotpluggable then skip not_used checking. */
-            g->not_used = false;
-        } else {
-            /* Maybe a typo. */
-            g->not_used = true;
-        }
-    } else {
-        /* Maybe a typo. */
-        g->not_used = true;
-    }
+    g->user_provided = true;
     qdev_prop_register_global(g);
     return 0;
 }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 9075453..66556d3 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -961,13 +961,29 @@ int qdev_prop_check_globals(void)
     int ret = 0;
 
     QTAILQ_FOREACH(prop, &global_props, next) {
-        if (!prop->not_used) {
+        ObjectClass *oc;
+        DeviceClass *dc;
+        if (prop->used) {
+            continue;
+        }
+        if (!prop->user_provided) {
+            continue;
+        }
+        oc = object_class_by_name(prop->driver);
+        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
+        if (!oc) {
+            error_report("Warning: global %s.%s has invalid class name",
+                       prop->driver, prop->property);
+            ret = 1;
+            continue;
+        }
+        dc = DEVICE_CLASS(oc);
+        if (!dc->hotpluggable && !prop->used) {
+            error_report("Warning: global %s.%s=%s not used",
+                       prop->driver, prop->property, prop->value);
+            ret = 1;
             continue;
         }
-        ret = 1;
-        error_report("Warning: \"-global %s.%s=%s\" not used",
-                     prop->driver, prop->property, prop->value);
-
     }
     return ret;
 }
@@ -983,7 +999,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
         if (strcmp(typename, prop->driver) != 0) {
             continue;
         }
-        prop->not_used = false;
+        prop->used = true;
         object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
         if (err != NULL) {
             error_propagate(errp, err);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 0799ff2..178fee2 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -242,16 +242,16 @@ struct PropertyInfo {
 
 /**
  * GlobalProperty:
- * @not_used: Track use of a global property.  Defaults to false in all C99
- * struct initializations.
- *
- * This prevents reports of .compat_props when they are not used.
+ * @user_provided: Set to true if property comes from user-provided config
+ * (command-line or config file).
+ * @used: Set to true if property was used when initializing a device.
  */
 typedef struct GlobalProperty {
     const char *driver;
     const char *property;
     const char *value;
-    bool not_used;
+    bool user_provided;
+    bool used;
     QTAILQ_ENTRY(GlobalProperty) next;
 } GlobalProperty;
 
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index e1b008a..0be9835 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -209,8 +209,7 @@ static void test_dynamic_globalprop_subprocess(void)
         { TYPE_DYNAMIC_PROPS, "prop1", "101", true },
         { TYPE_DYNAMIC_PROPS, "prop2", "102", true },
         { TYPE_DYNAMIC_PROPS"-bad", "prop3", "103", true },
-        /* .not_used=false to emulate what qdev_add_one_global() does: */
-        { TYPE_UNUSED_HOTPLUG, "prop4", "104", false },
+        { TYPE_UNUSED_HOTPLUG, "prop4", "104", true },
         { TYPE_UNUSED_NOHOTPLUG, "prop5", "105", true },
         { TYPE_NONDEVICE, "prop6", "106", true },
         {}
@@ -226,12 +225,12 @@ static void test_dynamic_globalprop_subprocess(void)
     g_assert_cmpuint(mt->prop2, ==, 102);
     all_used = qdev_prop_check_globals();
     g_assert_cmpuint(all_used, ==, 1);
-    g_assert(!props[0].not_used);
-    g_assert(!props[1].not_used);
-    g_assert(props[2].not_used);
-    g_assert(!props[3].not_used);
-    g_assert(props[4].not_used);
-    g_assert(props[5].not_used);
+    g_assert(props[0].used);
+    g_assert(props[1].used);
+    g_assert(!props[2].used);
+    g_assert(!props[3].used);
+    g_assert(!props[4].used);
+    g_assert(!props[5].used);
 }
 
 static void test_dynamic_globalprop(void)
@@ -240,10 +239,50 @@ static void test_dynamic_globalprop(void)
     g_test_trap_assert_passed();
     g_test_trap_assert_stderr_unmatched("*prop1*");
     g_test_trap_assert_stderr_unmatched("*prop2*");
-    g_test_trap_assert_stderr("*Warning: \"-global dynamic-prop-type-bad.prop3=103\" not used\n*");
+    g_test_trap_assert_stderr("*Warning: global dynamic-prop-type-bad.prop3 has invalid class name\n*");
     g_test_trap_assert_stderr_unmatched("*prop4*");
-    g_test_trap_assert_stderr("*Warning: \"-global nohotplug-type.prop5=105\" not used\n*");
-    g_test_trap_assert_stderr("*Warning: \"-global nondevice-type.prop6=106\" not used\n*");
+    g_test_trap_assert_stderr("*Warning: global nohotplug-type.prop5=105 not used\n*");
+    g_test_trap_assert_stderr("*Warning: global nondevice-type.prop6 has invalid class name\n*");
+    g_test_trap_assert_stdout("");
+}
+
+/* Test setting of dynamic properties using user_provided=false properties */
+static void test_dynamic_globalprop_nouser_subprocess(void)
+{
+    MyType *mt;
+    static GlobalProperty props[] = {
+        { TYPE_DYNAMIC_PROPS, "prop1", "101" },
+        { TYPE_DYNAMIC_PROPS, "prop2", "102" },
+        { TYPE_DYNAMIC_PROPS"-bad", "prop3", "103" },
+        { TYPE_UNUSED_HOTPLUG, "prop4", "104" },
+        { TYPE_UNUSED_NOHOTPLUG, "prop5", "105" },
+        { TYPE_NONDEVICE, "prop6", "106" },
+        {}
+    };
+    int all_used;
+
+    qdev_prop_register_global_list(props);
+
+    mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 101);
+    g_assert_cmpuint(mt->prop2, ==, 102);
+    all_used = qdev_prop_check_globals();
+    g_assert_cmpuint(all_used, ==, 0);
+    g_assert(props[0].used);
+    g_assert(props[1].used);
+    g_assert(!props[2].used);
+    g_assert(!props[3].used);
+    g_assert(!props[4].used);
+    g_assert(!props[5].used);
+}
+
+static void test_dynamic_globalprop_nouser(void)
+{
+    g_test_trap_subprocess("/qdev/properties/dynamic/global/nouser/subprocess", 0, 0);
+    g_test_trap_assert_passed();
+    g_test_trap_assert_stderr("");
     g_test_trap_assert_stdout("");
 }
 
@@ -273,6 +312,11 @@ int main(int argc, char **argv)
     g_test_add_func("/qdev/properties/dynamic/global",
                     test_dynamic_globalprop);
 
+    g_test_add_func("/qdev/properties/dynamic/global/nouser/subprocess",
+                    test_dynamic_globalprop_nouser_subprocess);
+    g_test_add_func("/qdev/properties/dynamic/global/nouser",
+                    test_dynamic_globalprop_nouser);
+
     g_test_run();
 
     return 0;
commit d828c430eb7dd481d6399f8b56e9641e47a40cea
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Fri Aug 8 16:03:30 2014 -0300

    qdev: Rename qdev_prop_check_global() to qdev_prop_check_globals()
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3d12560..9075453 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -955,7 +955,7 @@ void qdev_prop_register_global_list(GlobalProperty *props)
     }
 }
 
-int qdev_prop_check_global(void)
+int qdev_prop_check_globals(void)
 {
     GlobalProperty *prop;
     int ret = 0;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 77fe3a1..ae56ee5 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -177,7 +177,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
 
 void qdev_prop_register_global(GlobalProperty *prop);
 void qdev_prop_register_global_list(GlobalProperty *props);
-int qdev_prop_check_global(void);
+int qdev_prop_check_globals(void);
 void qdev_prop_set_globals(DeviceState *dev, Error **errp);
 void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
                                     Error **errp);
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 26d8cb2..e1b008a 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -224,7 +224,7 @@ static void test_dynamic_globalprop_subprocess(void)
 
     g_assert_cmpuint(mt->prop1, ==, 101);
     g_assert_cmpuint(mt->prop2, ==, 102);
-    all_used = qdev_prop_check_global();
+    all_used = qdev_prop_check_globals();
     g_assert_cmpuint(all_used, ==, 1);
     g_assert(!props[0].not_used);
     g_assert(!props[1].not_used);
diff --git a/vl.c b/vl.c
index 9c9acf5..2aaa558 100644
--- a/vl.c
+++ b/vl.c
@@ -4541,7 +4541,7 @@ int main(int argc, char **argv, char **envp)
         }
     }
 
-    qdev_prop_check_global();
+    qdev_prop_check_globals();
     if (vmstate_dump_file) {
         /* dump and exit */
         dump_vmstate_json_to_file(vmstate_dump_file);
commit 08ac80cd614ca4c81cc8799749977d5ff02d4ea5
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Fri Aug 8 16:03:29 2014 -0300

    test-qdev-global-props: Test handling of hotpluggable and non-device types
    
    Ensure no warning will be printed for hotpluggable types, and warnings
    will be printed for non-device types.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 5488937..26d8cb2 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -113,6 +113,9 @@ static void test_static_globalprop(void)
 #define DYNAMIC_TYPE(obj) \
     OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
 
+#define TYPE_UNUSED_HOTPLUG   "hotplug-type"
+#define TYPE_UNUSED_NOHOTPLUG "nohotplug-type"
+
 static void prop1_accessor(Object *obj,
                            Visitor *v,
                            void *opaque,
@@ -159,6 +162,45 @@ static const TypeInfo dynamic_prop_type = {
     .class_init = dynamic_class_init,
 };
 
+static void hotplug_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = NULL;
+    dc->hotpluggable = true;
+}
+
+static const TypeInfo hotplug_type = {
+    .name = TYPE_UNUSED_HOTPLUG,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .instance_init = dynamic_instance_init,
+    .class_init = hotplug_class_init,
+};
+
+static void nohotplug_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = NULL;
+    dc->hotpluggable = false;
+}
+
+static const TypeInfo nohotplug_type = {
+    .name = TYPE_UNUSED_NOHOTPLUG,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .instance_init = dynamic_instance_init,
+    .class_init = nohotplug_class_init,
+};
+
+#define TYPE_NONDEVICE "nondevice-type"
+
+static const TypeInfo nondevice_type = {
+    .name = TYPE_NONDEVICE,
+    .parent = TYPE_OBJECT,
+};
+
 /* Test setting of dynamic properties using global properties */
 static void test_dynamic_globalprop_subprocess(void)
 {
@@ -167,6 +209,10 @@ static void test_dynamic_globalprop_subprocess(void)
         { TYPE_DYNAMIC_PROPS, "prop1", "101", true },
         { TYPE_DYNAMIC_PROPS, "prop2", "102", true },
         { TYPE_DYNAMIC_PROPS"-bad", "prop3", "103", true },
+        /* .not_used=false to emulate what qdev_add_one_global() does: */
+        { TYPE_UNUSED_HOTPLUG, "prop4", "104", false },
+        { TYPE_UNUSED_NOHOTPLUG, "prop5", "105", true },
+        { TYPE_NONDEVICE, "prop6", "106", true },
         {}
     };
     int all_used;
@@ -183,6 +229,9 @@ static void test_dynamic_globalprop_subprocess(void)
     g_assert(!props[0].not_used);
     g_assert(!props[1].not_used);
     g_assert(props[2].not_used);
+    g_assert(!props[3].not_used);
+    g_assert(props[4].not_used);
+    g_assert(props[5].not_used);
 }
 
 static void test_dynamic_globalprop(void)
@@ -192,6 +241,9 @@ static void test_dynamic_globalprop(void)
     g_test_trap_assert_stderr_unmatched("*prop1*");
     g_test_trap_assert_stderr_unmatched("*prop2*");
     g_test_trap_assert_stderr("*Warning: \"-global dynamic-prop-type-bad.prop3=103\" not used\n*");
+    g_test_trap_assert_stderr_unmatched("*prop4*");
+    g_test_trap_assert_stderr("*Warning: \"-global nohotplug-type.prop5=105\" not used\n*");
+    g_test_trap_assert_stderr("*Warning: \"-global nondevice-type.prop6=106\" not used\n*");
     g_test_trap_assert_stdout("");
 }
 
@@ -202,6 +254,9 @@ int main(int argc, char **argv)
     module_call_init(MODULE_INIT_QOM);
     type_register_static(&static_prop_type);
     type_register_static(&dynamic_prop_type);
+    type_register_static(&hotplug_type);
+    type_register_static(&nohotplug_type);
+    type_register_static(&nondevice_type);
 
     g_test_add_func("/qdev/properties/static/default/subprocess",
                     test_static_prop_subprocess);
commit 45de81735b01b59fbc45803b2c1c8ca37cb55ead
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Fri Aug 8 16:03:28 2014 -0300

    test-qdev-global-props: Initialize not_used=true for all props
    
    This will ensure we are actually testing the code which sets
    not_used=false when the property is used.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 34223a7..5488937 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -164,8 +164,8 @@ static void test_dynamic_globalprop_subprocess(void)
 {
     MyType *mt;
     static GlobalProperty props[] = {
-        { TYPE_DYNAMIC_PROPS, "prop1", "101" },
-        { TYPE_DYNAMIC_PROPS, "prop2", "102" },
+        { TYPE_DYNAMIC_PROPS, "prop1", "101", true },
+        { TYPE_DYNAMIC_PROPS, "prop2", "102", true },
         { TYPE_DYNAMIC_PROPS"-bad", "prop3", "103", true },
         {}
     };
@@ -180,6 +180,9 @@ static void test_dynamic_globalprop_subprocess(void)
     g_assert_cmpuint(mt->prop2, ==, 102);
     all_used = qdev_prop_check_global();
     g_assert_cmpuint(all_used, ==, 1);
+    g_assert(!props[0].not_used);
+    g_assert(!props[1].not_used);
+    g_assert(props[2].not_used);
 }
 
 static void test_dynamic_globalprop(void)
commit 2177801a4899bf29108b3d471417a5b4d701ec29
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Fri Aug 8 16:03:27 2014 -0300

    test-qdev-global-props: Run tests on subprocess
    
    There are multiple reasons for running the global property tests on a
    subprocess:
    
    * We need the global_props lists to be empty for each test case, so
      global properties from the previous test won't affect the next one;
    * We don't want the qdev_prop_check_global() warnings to pollute test
      output;
    * With a subprocess, we can ensure qdev_prop_check_global() is printing
      the warning messages it should.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index e1a1317..34223a7 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -65,7 +65,7 @@ static const TypeInfo static_prop_type = {
 };
 
 /* Test simple static property setting to default value */
-static void test_static_prop(void)
+static void test_static_prop_subprocess(void)
 {
     MyType *mt;
 
@@ -75,8 +75,16 @@ static void test_static_prop(void)
     g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
 }
 
+static void test_static_prop(void)
+{
+    g_test_trap_subprocess("/qdev/properties/static/default/subprocess", 0, 0);
+    g_test_trap_assert_passed();
+    g_test_trap_assert_stderr("");
+    g_test_trap_assert_stdout("");
+}
+
 /* Test setting of static property using global properties */
-static void test_static_globalprop(void)
+static void test_static_globalprop_subprocess(void)
 {
     MyType *mt;
     static GlobalProperty props[] = {
@@ -93,6 +101,14 @@ static void test_static_globalprop(void)
     g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
 }
 
+static void test_static_globalprop(void)
+{
+    g_test_trap_subprocess("/qdev/properties/static/global/subprocess", 0, 0);
+    g_test_trap_assert_passed();
+    g_test_trap_assert_stderr("");
+    g_test_trap_assert_stdout("");
+}
+
 #define TYPE_DYNAMIC_PROPS "dynamic-prop-type"
 #define DYNAMIC_TYPE(obj) \
     OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
@@ -144,7 +160,7 @@ static const TypeInfo dynamic_prop_type = {
 };
 
 /* Test setting of dynamic properties using global properties */
-static void test_dynamic_globalprop(void)
+static void test_dynamic_globalprop_subprocess(void)
 {
     MyType *mt;
     static GlobalProperty props[] = {
@@ -166,6 +182,16 @@ static void test_dynamic_globalprop(void)
     g_assert_cmpuint(all_used, ==, 1);
 }
 
+static void test_dynamic_globalprop(void)
+{
+    g_test_trap_subprocess("/qdev/properties/dynamic/global/subprocess", 0, 0);
+    g_test_trap_assert_passed();
+    g_test_trap_assert_stderr_unmatched("*prop1*");
+    g_test_trap_assert_stderr_unmatched("*prop2*");
+    g_test_trap_assert_stderr("*Warning: \"-global dynamic-prop-type-bad.prop3=103\" not used\n*");
+    g_test_trap_assert_stdout("");
+}
+
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
@@ -174,9 +200,20 @@ int main(int argc, char **argv)
     type_register_static(&static_prop_type);
     type_register_static(&dynamic_prop_type);
 
-    g_test_add_func("/qdev/properties/static/default", test_static_prop);
-    g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
-    g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop);
+    g_test_add_func("/qdev/properties/static/default/subprocess",
+                    test_static_prop_subprocess);
+    g_test_add_func("/qdev/properties/static/default",
+                    test_static_prop);
+
+    g_test_add_func("/qdev/properties/static/global/subprocess",
+                    test_static_globalprop_subprocess);
+    g_test_add_func("/qdev/properties/static/global",
+                    test_static_globalprop);
+
+    g_test_add_func("/qdev/properties/dynamic/global/subprocess",
+                    test_dynamic_globalprop_subprocess);
+    g_test_add_func("/qdev/properties/dynamic/global",
+                    test_dynamic_globalprop);
 
     g_test_run();
 
commit 9d41401b90fa10b335d2e739149d36437cfbf622
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Sep 18 20:46:45 2014 +0300

    tests: disable global props test for old glib
    
    follow-up patch moves global property tests to subprocesses.
    Unfortunately with old glib this causes:
    
    tests/test-qdev-global-props.c: In function
    ‘test_static_prop’:
    tests/test-qdev-global-props.c:80:5: error: implicit
    declaration of function ‘g_test_trap_subprocess’
    [-Werror=implicit-function-declaration]
    tests/test-qdev-global-props.c:80:5: error: nested extern
    declaration of ‘g_test_trap_subprocess’ [-Werror=nested-externs]
    
    This function was only added in glib 2.38, and our
    minimum version is 2.12.
    
    To fix, disable the test for glib < 2.38.
    
    Apply before that patch to avoid breaking bisect.
    
    Reported-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/configure b/configure
index 961bf6f..6f1284a 100755
--- a/configure
+++ b/configure
@@ -2716,6 +2716,12 @@ for i in $glib_modules; do
     fi
 done
 
+# g_test_trap_subprocess added in 2.38. Used by some tests.
+glib_subprocess=yes
+if ! $pkg_config --atleast-version=2.38 glib-2.0; then
+    glib_subprocess=no
+fi
+
 ##########################################
 # SHA command probe for modules
 if test "$modules" = yes; then
@@ -4585,6 +4591,9 @@ if test "$bluez" = "yes" ; then
   echo "CONFIG_BLUEZ=y" >> $config_host_mak
   echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak
 fi
+if test "glib_subprocess" = "yes" ; then
+  echo "CONFIG_HAS_GLIB_SUBPROCESS_TESTS=y" >> $config_host_mak
+fi
 echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
 if test "$gtk" = "yes" ; then
   echo "CONFIG_GTK=y" >> $config_host_mak
diff --git a/tests/Makefile b/tests/Makefile
index d5db97b..a5e3d0c 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -58,7 +58,7 @@ check-unit-y += tests/test-int128$(EXESUF)
 # all code tested by test-int128 is inside int128.h
 gcov-files-test-int128-y =
 check-unit-y += tests/test-bitops$(EXESUF)
-check-unit-y += tests/test-qdev-global-props$(EXESUF)
+check-unit-$(CONFIG_HAS_GLIB_SUBPROCESS_TESTS) += tests/test-qdev-global-props$(EXESUF)
 check-unit-y += tests/check-qom-interface$(EXESUF)
 gcov-files-check-qom-interface-y = qom/object.c
 check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
commit bb26a1e80b5639d71119ff58e0ef598708993fc0
Merge: e4d50d4 9d64fab
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Sep 18 17:00:38 2014 +0100

    Merge remote-tracking branch 'remotes/kraxel/tags/pull-vnc-20140918-1' into staging
    
    vnc: set TCP_NODELAY, cleanup in tlc code
    
    # gpg: Signature made Thu 18 Sep 2014 07:02:37 BST using RSA key ID D3E87138
    # gpg: Good signature from "Gerd Hoffmann (work) <kraxel at redhat.com>"
    # gpg:                 aka "Gerd Hoffmann <gerd at kraxel.org>"
    # gpg:                 aka "Gerd Hoffmann (private) <kraxel at gmail.com>"
    
    * remotes/kraxel/tags/pull-vnc-20140918-1:
      vnc-tls: Clean up dead store in vnc_set_x509_credential()
      ui/vnc: set TCP_NODELAY
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 9d64fab42274fb50a39bab184f79d0239596ba4a
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Sep 17 09:33:15 2014 +0200

    vnc-tls: Clean up dead store in vnc_set_x509_credential()
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c
index 6392326..0f59f9b 100644
--- a/ui/vnc-tls.c
+++ b/ui/vnc-tls.c
@@ -444,8 +444,6 @@ static int vnc_set_x509_credential(VncDisplay *vd,
     struct stat sb;
 
     g_free(*cred);
-    *cred = NULL;
-
     *cred = g_malloc(strlen(certdir) + strlen(filename) + 2);
 
     strcpy(*cred, certdir);
commit 86152436eb06a76e495425c1aa862833576fbc71
Author: Peter Lieven <pl at kamp.de>
Date:   Fri Sep 5 22:07:41 2014 +0200

    ui/vnc: set TCP_NODELAY
    
    we currently have the Nagle algorithm enabled for all outgoing VNC updates.
    This may delay sensitive updates as mouse movements or typing in the console.
    As we currently prepare all data in a buffer and then send as much as we can
    disabling the Nagle algorithm should not cause big trouble. Well established
    VNC servers like TightVNC set TCP_NODELAY as well.
    A regular framebuffer update request generates exactly one framebuffer update
    which should be pushed out as fast as possible.
    
    Signed-off-by: Peter Lieven <pl at kamp.de>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/vnc.c b/ui/vnc.c
index f8d9b7d..0fe6eff 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2914,6 +2914,7 @@ static void vnc_listen_read(void *opaque, bool websocket)
     }
 
     if (csock != -1) {
+        socket_set_nodelay(csock);
         vnc_connect(vs, csock, false, websocket);
     }
 }
commit e4d50d47a9eb15f42bdd561803a29a4d7c3eb8ec
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Sep 2 11:24:17 2014 +0100

    qemu-char: Rename register_char_driver_qapi() to register_char_driver()
    
    Now we have removed the legacy register_char_driver() we can
    rename register_char_driver_qapi() to the more obvious and
    shorter name.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1409653457-27863-6-git-send-email-peter.maydell at linaro.org

diff --git a/backends/baum.c b/backends/baum.c
index 796512d..a69aaff 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -629,7 +629,7 @@ fail_handle:
 
 static void register_types(void)
 {
-    register_char_driver_qapi("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL);
+    register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL);
 }
 
 type_init(register_types);
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 650a531..0119110 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -79,7 +79,7 @@ CharDriverState *qemu_chr_open_msmouse(void)
 
 static void register_types(void)
 {
-    register_char_driver_qapi("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL);
+    register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL);
 }
 
 type_init(register_types);
diff --git a/backends/testdev.c b/backends/testdev.c
index 70d63b3..eba396a 100644
--- a/backends/testdev.c
+++ b/backends/testdev.c
@@ -125,7 +125,7 @@ CharDriverState *chr_testdev_init(void)
 
 static void register_types(void)
 {
-    register_char_driver_qapi("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL);
+    register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL);
 }
 
 type_init(register_types);
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index dbfd4e6..832b7fe 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -344,7 +344,7 @@ bool chr_is_ringbuf(const CharDriverState *chr);
 
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 
-void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
+void register_char_driver(const char *name, ChardevBackendKind kind,
         void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
 
 /* add an eventfd to the qemu devices that are polled */
diff --git a/qemu-char.c b/qemu-char.c
index 317e45c..2a3cb9f 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3495,7 +3495,7 @@ typedef struct CharDriver {
 
 static GSList *backends;
 
-void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
+void register_char_driver(const char *name, ChardevBackendKind kind,
         void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
 {
     CharDriver *s;
@@ -4124,34 +4124,32 @@ void qmp_chardev_remove(const char *id, Error **errp)
 
 static void register_types(void)
 {
-    register_char_driver_qapi("null", CHARDEV_BACKEND_KIND_NULL, NULL);
-    register_char_driver_qapi("socket", CHARDEV_BACKEND_KIND_SOCKET,
-                              qemu_chr_parse_socket);
-    register_char_driver_qapi("udp", CHARDEV_BACKEND_KIND_UDP,
-                              qemu_chr_parse_udp);
-    register_char_driver_qapi("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
-                              qemu_chr_parse_ringbuf);
-    register_char_driver_qapi("file", CHARDEV_BACKEND_KIND_FILE,
-                              qemu_chr_parse_file_out);
-    register_char_driver_qapi("stdio", CHARDEV_BACKEND_KIND_STDIO,
-                              qemu_chr_parse_stdio);
-    register_char_driver_qapi("serial", CHARDEV_BACKEND_KIND_SERIAL,
-                              qemu_chr_parse_serial);
-    register_char_driver_qapi("tty", CHARDEV_BACKEND_KIND_SERIAL,
-                              qemu_chr_parse_serial);
-    register_char_driver_qapi("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
-                              qemu_chr_parse_parallel);
-    register_char_driver_qapi("parport", CHARDEV_BACKEND_KIND_PARALLEL,
-                              qemu_chr_parse_parallel);
-    register_char_driver_qapi("pty", CHARDEV_BACKEND_KIND_PTY, NULL);
-    register_char_driver_qapi("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
-    register_char_driver_qapi("pipe", CHARDEV_BACKEND_KIND_PIPE,
-                              qemu_chr_parse_pipe);
-    register_char_driver_qapi("mux", CHARDEV_BACKEND_KIND_MUX,
-                              qemu_chr_parse_mux);
+    register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL);
+    register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET,
+                         qemu_chr_parse_socket);
+    register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp);
+    register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
+                         qemu_chr_parse_ringbuf);
+    register_char_driver("file", CHARDEV_BACKEND_KIND_FILE,
+                         qemu_chr_parse_file_out);
+    register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO,
+                         qemu_chr_parse_stdio);
+    register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL,
+                         qemu_chr_parse_serial);
+    register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL,
+                         qemu_chr_parse_serial);
+    register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
+                         qemu_chr_parse_parallel);
+    register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL,
+                         qemu_chr_parse_parallel);
+    register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL);
+    register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
+    register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE,
+                         qemu_chr_parse_pipe);
+    register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux);
     /* Bug-compatibility: */
-    register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY,
-                              qemu_chr_parse_ringbuf);
+    register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY,
+                         qemu_chr_parse_ringbuf);
     /* this must be done after machine init, since we register FEs with muxes
      * as part of realize functions like serial_isa_realizefn when -nographic
      * is specified
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 4518a4d..8106e06 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -368,10 +368,10 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
 
 static void register_types(void)
 {
-    register_char_driver_qapi("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC,
-                              qemu_chr_parse_spice_vmc);
-    register_char_driver_qapi("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT,
-                              qemu_chr_parse_spice_port);
+    register_char_driver("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC,
+                         qemu_chr_parse_spice_vmc);
+    register_char_driver("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT,
+                         qemu_chr_parse_spice_port);
 }
 
 type_init(register_types);
diff --git a/ui/console.c b/ui/console.c
index 5d73d81..f819382 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -2035,8 +2035,7 @@ static const TypeInfo qemu_console_info = {
 static void register_types(void)
 {
     type_register_static(&qemu_console_info);
-    register_char_driver_qapi("vc", CHARDEV_BACKEND_KIND_VC,
-                              qemu_chr_parse_vc);
+    register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc);
 }
 
 type_init(register_types);
commit a61ae7f88ce5c4c781d89b789118bf19a17b028f
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Sep 2 11:24:16 2014 +0100

    qemu-char: Remove register_char_driver() machinery
    
    Now that all the char backends have been converted to the QAPI
    framework we can remove the machinery for handling old style
    backends.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1409653457-27863-5-git-send-email-peter.maydell at linaro.org

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 98cd4c9..dbfd4e6 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -344,7 +344,6 @@ bool chr_is_ringbuf(const CharDriverState *chr);
 
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 
-void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *));
 void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
         void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
 
diff --git a/qemu-char.c b/qemu-char.c
index 48c3801..317e45c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3489,26 +3489,12 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
 
 typedef struct CharDriver {
     const char *name;
-    /* old, pre qapi */
-    CharDriverState *(*open)(QemuOpts *opts);
-    /* new, qapi-based */
     ChardevBackendKind kind;
     void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
 } CharDriver;
 
 static GSList *backends;
 
-void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *))
-{
-    CharDriver *s;
-
-    s = g_malloc0(sizeof(*s));
-    s->name = g_strdup(name);
-    s->open = open;
-
-    backends = g_slist_append(backends, s);
-}
-
 void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
         void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
 {
@@ -3530,8 +3516,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
     CharDriver *cd;
     CharDriverState *chr;
     GSList *i;
+    ChardevReturn *ret = NULL;
+    ChardevBackend *backend;
+    const char *id = qemu_opts_id(opts);
+    char *bid = NULL;
 
-    if (qemu_opts_id(opts) == NULL) {
+    if (id == NULL) {
         error_setg(errp, "chardev: no id specified");
         goto err;
     }
@@ -3554,89 +3544,49 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
         goto err;
     }
 
-    if (!cd->open) {
-        /* using new, qapi init */
-        ChardevBackend *backend = g_new0(ChardevBackend, 1);
-        ChardevReturn *ret = NULL;
-        const char *id = qemu_opts_id(opts);
-        char *bid = NULL;
+    backend = g_new0(ChardevBackend, 1);
 
-        if (qemu_opt_get_bool(opts, "mux", 0)) {
-            bid = g_strdup_printf("%s-base", id);
-        }
+    if (qemu_opt_get_bool(opts, "mux", 0)) {
+        bid = g_strdup_printf("%s-base", id);
+    }
 
-        chr = NULL;
-        backend->kind = cd->kind;
-        if (cd->parse) {
-            cd->parse(opts, backend, &local_err);
-            if (local_err) {
-                error_propagate(errp, local_err);
-                goto qapi_out;
-            }
-        }
-        ret = qmp_chardev_add(bid ? bid : id, backend, errp);
-        if (!ret) {
+    chr = NULL;
+    backend->kind = cd->kind;
+    if (cd->parse) {
+        cd->parse(opts, backend, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
             goto qapi_out;
         }
-
-        if (bid) {
-            qapi_free_ChardevBackend(backend);
-            qapi_free_ChardevReturn(ret);
-            backend = g_new0(ChardevBackend, 1);
-            backend->mux = g_new0(ChardevMux, 1);
-            backend->kind = CHARDEV_BACKEND_KIND_MUX;
-            backend->mux->chardev = g_strdup(bid);
-            ret = qmp_chardev_add(id, backend, errp);
-            if (!ret) {
-                chr = qemu_chr_find(bid);
-                qemu_chr_delete(chr);
-                chr = NULL;
-                goto qapi_out;
-            }
-        }
-
-        chr = qemu_chr_find(id);
-        chr->opts = opts;
-
-    qapi_out:
-        qapi_free_ChardevBackend(backend);
-        qapi_free_ChardevReturn(ret);
-        g_free(bid);
-        return chr;
     }
-
-    chr = cd->open(opts);
-    if (!chr) {
-        error_setg(errp, "chardev: opening backend \"%s\" failed",
-                   qemu_opt_get(opts, "backend"));
-        goto err;
+    ret = qmp_chardev_add(bid ? bid : id, backend, errp);
+    if (!ret) {
+        goto qapi_out;
     }
 
-    if (!chr->filename)
-        chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
-    chr->init = init;
-    /* if we didn't create the chardev via qmp_chardev_add, we
-     * need to send the OPENED event here
-     */
-    if (!chr->explicit_be_open) {
-        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    if (bid) {
+        qapi_free_ChardevBackend(backend);
+        qapi_free_ChardevReturn(ret);
+        backend = g_new0(ChardevBackend, 1);
+        backend->mux = g_new0(ChardevMux, 1);
+        backend->kind = CHARDEV_BACKEND_KIND_MUX;
+        backend->mux->chardev = g_strdup(bid);
+        ret = qmp_chardev_add(id, backend, errp);
+        if (!ret) {
+            chr = qemu_chr_find(bid);
+            qemu_chr_delete(chr);
+            chr = NULL;
+            goto qapi_out;
+        }
     }
-    QTAILQ_INSERT_TAIL(&chardevs, chr, next);
 
-    if (qemu_opt_get_bool(opts, "mux", 0)) {
-        CharDriverState *base = chr;
-        int len = strlen(qemu_opts_id(opts)) + 6;
-        base->label = g_malloc(len);
-        snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
-        chr = qemu_chr_open_mux(base);
-        chr->filename = base->filename;
-        chr->avail_connections = MAX_MUX;
-        QTAILQ_INSERT_TAIL(&chardevs, chr, next);
-    } else {
-        chr->avail_connections = 1;
-    }
-    chr->label = g_strdup(qemu_opts_id(opts));
+    chr = qemu_chr_find(id);
     chr->opts = opts;
+
+qapi_out:
+    qapi_free_ChardevBackend(backend);
+    qapi_free_ChardevReturn(ret);
+    g_free(bid);
     return chr;
 
 err:
commit 90a14bfe52166e5a85fff4e20532a22ae21dc6a7
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Sep 2 11:24:15 2014 +0100

    qemu-char: Convert udp backend to QAPI
    
    Convert the udp char backend to the new style QAPI framework.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1409653457-27863-4-git-send-email-peter.maydell at linaro.org

diff --git a/qemu-char.c b/qemu-char.c
index 1cff09e..48c3801 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2385,20 +2385,6 @@ static CharDriverState *qemu_chr_open_udp_fd(int fd)
     return chr;
 }
 
-static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
-{
-    Error *local_err = NULL;
-    int fd = -1;
-
-    fd = inet_dgram_opts(opts, &local_err);
-    if (fd < 0) {
-        qerror_report_err(local_err);
-        error_free(local_err);
-        return NULL;
-    }
-    return qemu_chr_open_udp_fd(fd);
-}
-
 /***********************************************************/
 /* TCP Net console */
 
@@ -3449,6 +3435,58 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
     backend->socket->addr = addr;
 }
 
+static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
+                               Error **errp)
+{
+    const char *host = qemu_opt_get(opts, "host");
+    const char *port = qemu_opt_get(opts, "port");
+    const char *localaddr = qemu_opt_get(opts, "localaddr");
+    const char *localport = qemu_opt_get(opts, "localport");
+    bool has_local = false;
+    SocketAddress *addr;
+
+    if (host == NULL || strlen(host) == 0) {
+        host = "localhost";
+    }
+    if (port == NULL || strlen(port) == 0) {
+        error_setg(errp, "chardev: udp: remote port not specified");
+        return;
+    }
+    if (localport == NULL || strlen(localport) == 0) {
+        localport = "0";
+    } else {
+        has_local = true;
+    }
+    if (localaddr == NULL || strlen(localaddr) == 0) {
+        localaddr = "";
+    } else {
+        has_local = true;
+    }
+
+    backend->udp = g_new0(ChardevUdp, 1);
+
+    addr = g_new0(SocketAddress, 1);
+    addr->kind = SOCKET_ADDRESS_KIND_INET;
+    addr->inet = g_new0(InetSocketAddress, 1);
+    addr->inet->host = g_strdup(host);
+    addr->inet->port = g_strdup(port);
+    addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
+    addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
+    addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
+    addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
+    backend->udp->remote = addr;
+
+    if (has_local) {
+        backend->udp->has_local = true;
+        addr = g_new0(SocketAddress, 1);
+        addr->kind = SOCKET_ADDRESS_KIND_INET;
+        addr->inet = g_new0(InetSocketAddress, 1);
+        addr->inet->host = g_strdup(localaddr);
+        addr->inet->port = g_strdup(localport);
+        backend->udp->local = addr;
+    }
+}
+
 typedef struct CharDriver {
     const char *name;
     /* old, pre qapi */
@@ -4139,7 +4177,8 @@ static void register_types(void)
     register_char_driver_qapi("null", CHARDEV_BACKEND_KIND_NULL, NULL);
     register_char_driver_qapi("socket", CHARDEV_BACKEND_KIND_SOCKET,
                               qemu_chr_parse_socket);
-    register_char_driver("udp", qemu_chr_open_udp);
+    register_char_driver_qapi("udp", CHARDEV_BACKEND_KIND_UDP,
+                              qemu_chr_parse_udp);
     register_char_driver_qapi("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
                               qemu_chr_parse_ringbuf);
     register_char_driver_qapi("file", CHARDEV_BACKEND_KIND_FILE,
commit 8287fea321882b01d30cd7bfc85d1a043935d525
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Sep 2 11:24:14 2014 +0100

    util/qemu-sockets.c: Support specifying IPv4 or IPv6 in socket_dgram()
    
    Currently you can specify whether you want a UDP chardev backend
    to be IPv4 or IPv6 using the ipv4 or ipv6 options if you use the
    QemuOpts parsing code in inet_dgram_opts(). However the QMP struct
    parsing code in socket_dgram() doesn't provide this flexibility
    (which in turn prevents us from converting the UDP backend handling
    to the new style QAPI framework).
    
    Use the existing inet_addr_to_opts() function to convert the
    remote->inet address to option strings; this handles ipv4 and
    ipv6 flags as well as host and port. (It will also convert any
    'to' specification, which is harmless as it is ignored in this
    context.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1409653457-27863-3-git-send-email-peter.maydell at linaro.org

diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 5d38395..4a25585 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -966,8 +966,7 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
     switch (remote->kind) {
     case SOCKET_ADDRESS_KIND_INET:
-        qemu_opt_set(opts, "host", remote->inet->host);
-        qemu_opt_set(opts, "port", remote->inet->port);
+        inet_addr_to_opts(opts, remote->inet);
         if (local) {
             qemu_opt_set(opts, "localaddr", local->inet->host);
             qemu_opt_set(opts, "localport", local->inet->port);
commit dafd325dbbf6053e15f256b53942cb44103058dd
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Sep 2 11:24:13 2014 +0100

    qemu-char: Convert socket backend to QAPI
    
    Convert the socket char backend to the new style QAPI framework;
    this allows it to return an Error ** to callers who might not
    want it to print directly about socket failures.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1409653457-27863-2-git-send-email-peter.maydell at linaro.org

diff --git a/qemu-char.c b/qemu-char.c
index 1a8d9aa..1cff09e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2985,61 +2985,6 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
     return chr;
 }
 
-static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
-{
-    CharDriverState *chr = NULL;
-    Error *local_err = NULL;
-    int fd = -1;
-
-    bool is_listen      = qemu_opt_get_bool(opts, "server", false);
-    bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
-    bool is_telnet      = qemu_opt_get_bool(opts, "telnet", false);
-    bool do_nodelay     = !qemu_opt_get_bool(opts, "delay", true);
-    bool is_unix        = qemu_opt_get(opts, "path") != NULL;
-
-    if (is_unix) {
-        if (is_listen) {
-            fd = unix_listen_opts(opts, &local_err);
-        } else {
-            fd = unix_connect_opts(opts, &local_err, NULL, NULL);
-        }
-    } else {
-        if (is_listen) {
-            fd = inet_listen_opts(opts, 0, &local_err);
-        } else {
-            fd = inet_connect_opts(opts, &local_err, NULL, NULL);
-        }
-    }
-    if (fd < 0) {
-        goto fail;
-    }
-
-    if (!is_waitconnect)
-        qemu_set_nonblock(fd);
-
-    chr = qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, is_telnet,
-                                  is_waitconnect, &local_err);
-    if (local_err) {
-        goto fail;
-    }
-    return chr;
-
-
- fail:
-    if (local_err) {
-        qerror_report_err(local_err);
-        error_free(local_err);
-    }
-    if (fd >= 0) {
-        closesocket(fd);
-    }
-    if (chr) {
-        g_free(chr->opaque);
-        g_free(chr);
-    }
-    return NULL;
-}
-
 /*********************************************************/
 /* Ring buffer chardev */
 
@@ -3450,6 +3395,60 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
     backend->mux->chardev = g_strdup(chardev);
 }
 
+static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
+                                  Error **errp)
+{
+    bool is_listen      = qemu_opt_get_bool(opts, "server", false);
+    bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
+    bool is_telnet      = qemu_opt_get_bool(opts, "telnet", false);
+    bool do_nodelay     = !qemu_opt_get_bool(opts, "delay", true);
+    const char *path = qemu_opt_get(opts, "path");
+    const char *host = qemu_opt_get(opts, "host");
+    const char *port = qemu_opt_get(opts, "port");
+    SocketAddress *addr;
+
+    if (!path) {
+        if (!host) {
+            error_setg(errp, "chardev: socket: no host given");
+            return;
+        }
+        if (!port) {
+            error_setg(errp, "chardev: socket: no port given");
+            return;
+        }
+    }
+
+    backend->socket = g_new0(ChardevSocket, 1);
+
+    backend->socket->has_nodelay = true;
+    backend->socket->nodelay = do_nodelay;
+    backend->socket->has_server = true;
+    backend->socket->server = is_listen;
+    backend->socket->has_telnet = true;
+    backend->socket->telnet = is_telnet;
+    backend->socket->has_wait = true;
+    backend->socket->wait = is_waitconnect;
+
+    addr = g_new0(SocketAddress, 1);
+    if (path) {
+        addr->kind = SOCKET_ADDRESS_KIND_UNIX;
+        addr->q_unix = g_new0(UnixSocketAddress, 1);
+        addr->q_unix->path = g_strdup(path);
+    } else {
+        addr->kind = SOCKET_ADDRESS_KIND_INET;
+        addr->inet = g_new0(InetSocketAddress, 1);
+        addr->inet->host = g_strdup(host);
+        addr->inet->port = g_strdup(port);
+        addr->inet->has_to = qemu_opt_get(opts, "to");
+        addr->inet->to = qemu_opt_get_number(opts, "to", 0);
+        addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
+        addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
+        addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
+        addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
+    }
+    backend->socket->addr = addr;
+}
+
 typedef struct CharDriver {
     const char *name;
     /* old, pre qapi */
@@ -4138,7 +4137,8 @@ void qmp_chardev_remove(const char *id, Error **errp)
 static void register_types(void)
 {
     register_char_driver_qapi("null", CHARDEV_BACKEND_KIND_NULL, NULL);
-    register_char_driver("socket", qemu_chr_open_socket);
+    register_char_driver_qapi("socket", CHARDEV_BACKEND_KIND_SOCKET,
+                              qemu_chr_parse_socket);
     register_char_driver("udp", qemu_chr_open_udp);
     register_char_driver_qapi("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
                               qemu_chr_parse_ringbuf);
commit 8af47027eb51d2d2afd15cff3ab7236a0211b8a0
Merge: 5f3fb5a 0d61f7d
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Sep 16 18:29:40 2014 +0100

    Merge remote-tracking branch 'remotes/kraxel/tags/pull-sdl-20140916-1' into staging
    
    Two minor sdl2 fixes.
    
    # gpg: Signature made Tue 16 Sep 2014 07:20:37 BST using RSA key ID D3E87138
    # gpg: Good signature from "Gerd Hoffmann (work) <kraxel at redhat.com>"
    # gpg:                 aka "Gerd Hoffmann <gerd at kraxel.org>"
    # gpg:                 aka "Gerd Hoffmann (private) <kraxel at gmail.com>"
    
    * remotes/kraxel/tags/pull-sdl-20140916-1:
      sdl2: keymap fixups
      sdl2: drop sdl_zoom.h
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 5f3fb5a2e259322d50d289f180ac7e452ad1b6f8
Merge: cc35a44 07d49a5
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Sep 16 18:28:31 2014 +0100

    Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20140916-2' into staging
    
    spice: call qemu_spice_set_passwd() during init
    
    # gpg: Signature made Tue 16 Sep 2014 07:11:22 BST using RSA key ID D3E87138
    # gpg: Good signature from "Gerd Hoffmann (work) <kraxel at redhat.com>"
    # gpg:                 aka "Gerd Hoffmann <gerd at kraxel.org>"
    # gpg:                 aka "Gerd Hoffmann (private) <kraxel at gmail.com>"
    
    * remotes/spice/tags/pull-spice-20140916-2:
      spice: call qemu_spice_set_passwd() during init
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 07d49a53b6394941ed833486a3acb5c480d87db2
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Fri Sep 5 14:08:48 2014 +0200

    spice: call qemu_spice_set_passwd() during init
    
    Don't call SPICE API directly to set password given in command line, but
    use the internal API, saving password for later calls.
    
    This solves losing password when changing expiration in qemu monitor.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1138639
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/spice-core.c b/ui/spice-core.c
index 17a2ed3..6467fa4 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -733,7 +733,7 @@ void qemu_spice_init(void)
                              tls_ciphers);
     }
     if (password) {
-        spice_server_set_ticket(spice_server, password, 0, 0, 0);
+        qemu_spice_set_passwd(password, false, false);
     }
     if (qemu_opt_get_bool(opts, "sasl", 0)) {
         if (spice_server_set_sasl_appname(spice_server, "qemu") == -1 ||
commit 0d61f7dcc6c04e7e825417c74e50362d990330bf
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Jul 29 13:52:27 2014 +0200

    sdl2: keymap fixups
    
    Make a few keys works correctly in SDL2.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/sdl2-keymap.h b/ui/sdl2-keymap.h
index 5a12f45..cbedaa4 100644
--- a/ui/sdl2-keymap.h
+++ b/ui/sdl2-keymap.h
@@ -105,9 +105,10 @@ static const int sdl2_scancode_to_qcode[SDL_NUM_SCANCODES] = {
     [SDL_SCANCODE_KP_9]              = Q_KEY_CODE_KP_9,
     [SDL_SCANCODE_KP_0]              = Q_KEY_CODE_KP_0,
     [SDL_SCANCODE_KP_PERIOD]         = Q_KEY_CODE_KP_DECIMAL,
+
+    [SDL_SCANCODE_NONUSBACKSLASH]    = Q_KEY_CODE_LESS,
+    [SDL_SCANCODE_APPLICATION]       = Q_KEY_CODE_MENU,
 #if 0
-    [SDL_SCANCODE_NONUSBACKSLASH]    = Q_KEY_CODE_NONUSBACKSLASH,
-    [SDL_SCANCODE_APPLICATION]       = Q_KEY_CODE_APPLICATION,
     [SDL_SCANCODE_POWER]             = Q_KEY_CODE_POWER,
     [SDL_SCANCODE_KP_EQUALS]         = Q_KEY_CODE_KP_EQUALS,
 
@@ -231,7 +232,7 @@ static const int sdl2_scancode_to_qcode[SDL_NUM_SCANCODES] = {
     [SDL_SCANCODE_LGUI]              = Q_KEY_CODE_META_L,
     [SDL_SCANCODE_RCTRL]             = Q_KEY_CODE_CTRL_R,
     [SDL_SCANCODE_RSHIFT]            = Q_KEY_CODE_SHIFT_R,
-    [SDL_SCANCODE_RALT]              = Q_KEY_CODE_ALTGR,
+    [SDL_SCANCODE_RALT]              = Q_KEY_CODE_ALT_R,
     [SDL_SCANCODE_RGUI]              = Q_KEY_CODE_META_R,
 #if 0
     [SDL_SCANCODE_MODE]              = Q_KEY_CODE_MODE,
commit 4f36e42ee9334c56f0ea8048ccdbe8ae8372346e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Jul 24 13:45:38 2014 +0200

    sdl2: drop sdl_zoom.h
    
    It isn't used.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/sdl2.c b/ui/sdl2.c
index fcac87b..1ad74ba 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -35,7 +35,6 @@
 #include "ui/console.h"
 #include "ui/input.h"
 #include "sysemu/sysemu.h"
-#include "sdl_zoom.h"
 
 #include "sdl2-keymap.h"
 
commit 70e98b230fa58d7da22bd6c45b206fc58e9908c2
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Fri Aug 8 16:03:26 2014 -0300

    test-qdev-global-props: Trivial comment fix
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 2bef04c..e1a1317 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -143,7 +143,7 @@ static const TypeInfo dynamic_prop_type = {
     .class_init = dynamic_class_init,
 };
 
-/* Test setting of static property using global properties */
+/* Test setting of dynamic properties using global properties */
 static void test_dynamic_globalprop(void)
 {
     MyType *mt;
commit 556068eed04b7f11187aabd89b981552d8d0c30e
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Aug 6 15:18:21 2014 -0300

    hw/machine: Free old values of string properties
    
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Marcel Apfelbaum <marcel.a at redhat.com>
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Cc: qemu-stable at nongnu.org

diff --git a/hw/core/machine.c b/hw/core/machine.c
index f0046d6..7f3418c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -24,6 +24,7 @@ static void machine_set_accel(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->accel);
     ms->accel = g_strdup(value);
 }
 
@@ -79,6 +80,7 @@ static void machine_set_kernel(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->kernel_filename);
     ms->kernel_filename = g_strdup(value);
 }
 
@@ -93,6 +95,7 @@ static void machine_set_initrd(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->initrd_filename);
     ms->initrd_filename = g_strdup(value);
 }
 
@@ -107,6 +110,7 @@ static void machine_set_append(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->kernel_cmdline);
     ms->kernel_cmdline = g_strdup(value);
 }
 
@@ -121,6 +125,7 @@ static void machine_set_dtb(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->dtb);
     ms->dtb = g_strdup(value);
 }
 
@@ -135,6 +140,7 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->dumpdtb);
     ms->dumpdtb = g_strdup(value);
 }
 
@@ -176,6 +182,7 @@ static void machine_set_dt_compatible(Object *obj, const char *value, Error **er
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->dt_compatible);
     ms->dt_compatible = g_strdup(value);
 }
 
@@ -232,6 +239,7 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    g_free(ms->firmware);
     ms->firmware = g_strdup(value);
 }
 


More information about the Spice-commits mailing list