[Spice-commits] 70 commits - Makefile.objs accel.c arch_init.c block.c block/qcow2.c block/ssh.c block/vmdk.c blockdev.c gdbstub.c hw/alpha hw/i386 hw/ide hw/mips hw/ppc hw/s390x hw/scsi hw/sparc64 include/exec include/hw include/qemu include/qemu-common.h include/qom include/sysemu kvm-all.c kvm-stub.c linux-headers/asm-mips linux-headers/asm-powerpc linux-headers/asm-x86 linux-headers/linux linux-user/arm linux-user/elfload.c linux-user/ioctls.h linux-user/syscall.c linux-user/syscall_types.h migration-tcp.c migration-unix.c pc-bios/linuxboot.bin pc-bios/optionrom qapi-schema.json qapi/block-core.json qemu-char.c qemu-img.c qemu-nbd.c qemu-options.hx qtest.c savevm.c target-arm/cpu.c target-cris/cpu.c target-lm32/cpu.c target-mips/cpu.c target-s390x/Makefile.objs target-s390x/cpu-qom.h target-s390x/cpu.c target-s390x/cpu.h target-s390x/helper.c target-s390x/kvm.c target-s390x/machine.c target-xtensa/cpu.c tests/Makefile tests/bios-tables-test.c tests/blockdev-test.c tests/drive_del-test.c tests/qdev-monitor-test.c tests/qemu-iotests tests/qemu-iotests-quick.sh trace-events translate-all.c util/Makefile.objs util/id.c util/qemu-error.c util/qemu-option.c util/qemu-sockets.c vl.c xen-common-stub.c xen-common.c
Gerd Hoffmann
kraxel at kemper.freedesktop.org
Wed Oct 15 03:49:33 PDT 2014
Makefile.objs | 1
accel.c | 157 ++++++++++++++++
arch_init.c | 5
block.c | 9
block/qcow2.c | 3
block/ssh.c | 10 +
block/vmdk.c | 2
blockdev.c | 72 +++++++
gdbstub.c | 32 ++-
hw/alpha/dp264.c | 2
hw/i386/pc.c | 1
hw/i386/pc_piix.c | 2
hw/i386/pc_q35.c | 7
hw/ide/ahci.c | 15 +
hw/ide/ahci.h | 2
hw/ide/core.c | 22 +-
hw/mips/mips_fulong2e.c | 2
hw/mips/mips_malta.c | 2
hw/mips/mips_r4k.c | 2
hw/ppc/mac_newworld.c | 2
hw/ppc/mac_oldworld.c | 2
hw/ppc/prep.c | 2
hw/s390x/ipl.c | 2
hw/s390x/s390-virtio.c | 32 ---
hw/s390x/virtio-ccw.c | 2
hw/scsi/virtio-scsi.c | 9
hw/sparc64/sun4u.c | 2
include/exec/cpu-all.h | 4
include/hw/boards.h | 6
include/hw/xen/xen.h | 1
include/qemu-common.h | 3
include/qemu/error-report.h | 1
include/qemu/option.h | 1
include/qemu/sockets.h | 2
include/qemu/typedefs.h | 1
include/qom/cpu.h | 3
include/sysemu/accel.h | 62 ++++++
include/sysemu/arch_init.h | 1
include/sysemu/blockdev.h | 5
include/sysemu/kvm.h | 2
include/sysemu/qtest.h | 1
kvm-all.c | 36 +++
kvm-stub.c | 5
linux-headers/asm-mips/kvm_para.h | 6
linux-headers/asm-powerpc/kvm.h | 2
linux-headers/asm-x86/kvm.h | 3
linux-headers/linux/kvm.h | 13 +
linux-headers/linux/kvm_para.h | 3
linux-headers/linux/vfio.h | 34 +++
linux-headers/linux/vhost.h | 2
linux-user/arm/syscall_nr.h | 2
linux-user/elfload.c | 18 -
linux-user/ioctls.h | 3
linux-user/syscall.c | 87 +++++++--
linux-user/syscall_types.h | 2
migration-tcp.c | 4
migration-unix.c | 4
pc-bios/linuxboot.bin |binary
pc-bios/optionrom/linuxboot.S | 47 ++++
pc-bios/optionrom/optionrom.h | 21 +-
qapi-schema.json | 15 +
qapi/block-core.json | 6
qemu-char.c | 359 ++++++++++++++++++++++++++++----------
qemu-img.c | 4
qemu-nbd.c | 4
qemu-options.hx | 20 +-
qtest.c | 27 ++
savevm.c | 11 -
target-arm/cpu.c | 1
target-cris/cpu.c | 1
target-lm32/cpu.c | 1
target-mips/cpu.c | 1
target-s390x/Makefile.objs | 2
target-s390x/cpu-qom.h | 4
target-s390x/cpu.c | 114 +++++++++---
target-s390x/cpu.h | 41 +++-
target-s390x/helper.c | 19 --
target-s390x/kvm.c | 58 +++++-
target-s390x/machine.c | 76 ++++++++
target-xtensa/cpu.c | 1
tests/Makefile | 5
tests/bios-tables-test.c | 10 -
tests/blockdev-test.c | 59 ------
tests/drive_del-test.c | 137 ++++++++++++++
tests/qdev-monitor-test.c | 77 --------
tests/qemu-iotests-quick.sh | 2
tests/qemu-iotests/052 | 5
tests/qemu-iotests/060 | 3
tests/qemu-iotests/060.out | 9
tests/qemu-iotests/065 | 12 -
tests/qemu-iotests/067.out | 10 -
tests/qemu-iotests/070 | 2
tests/qemu-iotests/070.out | 5
tests/qemu-iotests/082 | 12 -
tests/qemu-iotests/082.out | 62 +-----
tests/qemu-iotests/089.out | 2
tests/qemu-iotests/095 | 4
tests/qemu-iotests/095.out | 16 -
tests/qemu-iotests/105 | 70 +++++++
tests/qemu-iotests/105.out | 21 ++
tests/qemu-iotests/group | 1
trace-events | 6
translate-all.c | 33 +--
util/Makefile.objs | 1
util/id.c | 28 ++
util/qemu-error.c | 23 +-
util/qemu-option.c | 17 -
util/qemu-sockets.c | 20 +-
vl.c | 101 ++--------
xen-common-stub.c | 6
xen-common.c | 25 ++
111 files changed, 1667 insertions(+), 668 deletions(-)
New commits:
commit b1d28ec6a7dbdaadda39d29322f0de694aeb0b74
Merge: 9d1c35d 4b7757b
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Fri Oct 10 14:55:29 2014 +0100
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20141010' into staging
various s390x updates:
- cpu state handling in qemu and migration
- vhost-scsi-ccw bugfix
# gpg: Signature made Fri 10 Oct 2014 14:01:34 BST using RSA key ID C6F02FAF
# gpg: Can't check signature: public key not found
* remotes/cohuck/tags/s390x-20141010:
s390x/virtio-ccw: fix vhost-scsi intialization
s390x/migration: migrate CPU state
s390x/kvm: synchronize the cpu state after SIGP (INITIAL) CPU RESET
s390x/kvm: reuse kvm_s390_reset_vcpu() to get rid of ifdefs
s390x/kvm: propagate s390 cpu state to kvm
s390x/kvm: proper use of the cpu states OPERATING and STOPPED
s390x/kvm: introduce proper states for s390 cpus
linux-headers: update to 3.17-rc7
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
commit 9d1c35dfc9940e4afa604a25f62b9dc197c513b6
Author: Paolo Bonzini <pbonzini at redhat.com>
Date: Fri Oct 10 12:23:35 2014 +0200
kvm fix compilation with GCC 4.3.4
As usual, SLES11's GCC complained about double typedefs:
/home/cohuck/git/qemu/kvm-all.c:110: error: redefinition of typedef âKVMStateâ
/home/cohuck/git/qemu/include/sysemu/kvm.h:161: error: previous declaration of âKVMStateâ was here
Reported-by: Cornelia Huck <cornelia.huck at de.ibm.com>
Tested-by: Cornelia Huck <cornelia.huck at de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
diff --git a/kvm-all.c b/kvm-all.c
index e98a7c7..44a5e72 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -71,7 +71,7 @@ typedef struct KVMSlot
typedef struct kvm_dirty_log KVMDirtyLog;
-typedef struct KVMState
+struct KVMState
{
AccelState parent_obj;
@@ -107,7 +107,7 @@ typedef struct KVMState
QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
bool direct_msi;
#endif
-} KVMState;
+};
#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
commit 4b7757bae7c94f980969031119db12d540cf2b61
Author: Cornelia Huck <cornelia.huck at de.ibm.com>
Date: Tue Sep 30 13:55:04 2014 +0200
s390x/virtio-ccw: fix vhost-scsi intialization
The vhost-scsi-ccw backend is of type VHostSCSICcw, not VirtIOSCSICcw.
This fixes a segfault when invoking
qemu-system-s390x -device vhost-scsi-ccw,?
Reviewed-by: Thomas Huth <thuth at linux.vnet.ibm.com>
Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index e7d3ea1..18ba29f 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1528,7 +1528,7 @@ static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
static const TypeInfo vhost_ccw_scsi = {
.name = TYPE_VHOST_SCSI_CCW,
.parent = TYPE_VIRTIO_CCW_DEVICE,
- .instance_size = sizeof(VirtIOSCSICcw),
+ .instance_size = sizeof(VHostSCSICcw),
.instance_init = vhost_ccw_scsi_instance_init,
.class_init = vhost_ccw_scsi_class_init,
};
commit ef1df13087768c0ab4010355595b0e3dd91bbd3c
Author: Thomas Huth <thuth at linux.vnet.ibm.com>
Date: Tue Sep 30 10:58:42 2014 +0200
s390x/migration: migrate CPU state
This patch provides the cpu save information for dumps and later life
migration and enables migration of the CPU state. The code is based on
earlier work from Christian Borntraeger and Jason Herne.
Signed-off-by: Thomas Huth <thuth at linux.vnet.ibm.com>
Signed-off-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
[provide cpu_post_load()]
Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
CC: Andreas Faerber <afaerber at suse.de>
CC: Christian Borntraeger <borntraeger at de.ibm.com>
CC: Jason J. Herne <jjherne at us.ibm.com>
Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>
[Cornelia Huck: tweaked cpu_post_load() comment]
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index f873146..2c57494 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,5 @@
obj-y += translate.o helper.o cpu.o interrupt.o
obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += ioinst.o arch_dump.o
+obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o
obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 4f7d4cb..8b376df 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -77,6 +77,10 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
#define ENV_OFFSET offsetof(S390CPU, env)
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_s390_cpu;
+#endif
+
void s390_cpu_do_interrupt(CPUState *cpu);
bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index ec7df90..d2f6312 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -292,11 +292,6 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
}
#endif
-static const VMStateDescription vmstate_s390_cpu = {
- .name = "cpu",
- .unmigratable = 1,
-};
-
static void s390_cpu_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *scc = S390_CPU_CLASS(oc);
@@ -323,11 +318,11 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->handle_mmu_fault = s390_cpu_handle_mmu_fault;
#else
cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
+ cc->vmsd = &vmstate_s390_cpu;
cc->write_elf64_note = s390_cpu_write_elf64_note;
cc->write_elf64_qemunote = s390_cpu_write_elf64_qemunote;
cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
#endif
- dc->vmsd = &vmstate_s390_cpu;
cc->gdb_num_core_regs = S390_NUM_CORE_REGS;
cc->gdb_core_xml_file = "s390x-core64.xml";
}
diff --git a/target-s390x/machine.c b/target-s390x/machine.c
new file mode 100644
index 0000000..fbcb0d0
--- /dev/null
+++ b/target-s390x/machine.c
@@ -0,0 +1,76 @@
+/*
+ * S390x machine definitions and functions
+ *
+ * Copyright IBM Corp. 2014
+ *
+ * Authors:
+ * Thomas Huth <thuth at linux.vnet.ibm.com>
+ * Christian Borntraeger <borntraeger at de.ibm.com>
+ * Jason J. Herne <jjherne at us.ibm.com>
+ *
+ * This work 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.
+ */
+
+#include "hw/hw.h"
+#include "cpu.h"
+#include "sysemu/kvm.h"
+
+static int cpu_post_load(void *opaque, int version_id)
+{
+ S390CPU *cpu = opaque;
+
+ /*
+ * As the cpu state is pushed to kvm via kvm_set_mp_state rather
+ * than via cpu_synchronize_state, we need update kvm here.
+ */
+ if (kvm_enabled()) {
+ kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state);
+ }
+
+ return 0;
+}
+
+const VMStateDescription vmstate_s390_cpu = {
+ .name = "cpu",
+ .post_load = cpu_post_load,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(env.fregs[0].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[1].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[2].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[3].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[4].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[5].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[6].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[7].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[8].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[9].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[10].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[11].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[12].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[13].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[14].ll, S390CPU),
+ VMSTATE_UINT64(env.fregs[15].ll, S390CPU),
+ VMSTATE_UINT64_ARRAY(env.regs, S390CPU, 16),
+ VMSTATE_UINT64(env.psw.mask, S390CPU),
+ VMSTATE_UINT64(env.psw.addr, S390CPU),
+ VMSTATE_UINT64(env.psa, S390CPU),
+ VMSTATE_UINT32(env.fpc, S390CPU),
+ VMSTATE_UINT32(env.todpr, S390CPU),
+ VMSTATE_UINT64(env.pfault_token, S390CPU),
+ VMSTATE_UINT64(env.pfault_compare, S390CPU),
+ VMSTATE_UINT64(env.pfault_select, S390CPU),
+ VMSTATE_UINT64(env.cputm, S390CPU),
+ VMSTATE_UINT64(env.ckc, S390CPU),
+ VMSTATE_UINT64(env.gbea, S390CPU),
+ VMSTATE_UINT64(env.pp, S390CPU),
+ VMSTATE_UINT32_ARRAY(env.aregs, S390CPU, 16),
+ VMSTATE_UINT64_ARRAY(env.cregs, S390CPU, 16),
+ VMSTATE_UINT8(env.cpu_state, S390CPU),
+ VMSTATE_END_OF_LIST()
+ },
+};
commit 71dd7e69b30dc5024a8d891e7011173a81fe7a72
Author: David Hildenbrand <dahi at linux.vnet.ibm.com>
Date: Tue Sep 30 10:57:32 2014 +0200
s390x/kvm: synchronize the cpu state after SIGP (INITIAL) CPU RESET
We need to synchronize registers after a reset has been performed. The
current code does that in qemu_system_reset(), load_normal_reset() and
modified_clear_reset() for all vcpus. After SIGP (INITIAL) CPU RESET,
this needs to be done for the targeted vcpu as well, so let's call
cpu_synchronize_post_reset() in the respective handlers.
Signed-off-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
CC: Andreas Faerber <afaerber at suse.de>
Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index e4c4c8d..5b10a25 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -952,6 +952,7 @@ static void sigp_initial_cpu_reset(void *arg)
cpu_synchronize_state(cpu);
scc->initial_cpu_reset(cpu);
+ cpu_synchronize_post_reset(cpu);
}
static void sigp_cpu_reset(void *arg)
@@ -961,6 +962,7 @@ static void sigp_cpu_reset(void *arg)
cpu_synchronize_state(cpu);
scc->cpu_reset(cpu);
+ cpu_synchronize_post_reset(cpu);
}
#define SIGP_ORDER_MASK 0x000000ff
commit 99607144a423dd2cd3113587e36bc4dc65c4ddf1
Author: David Hildenbrand <dahi at linux.vnet.ibm.com>
Date: Tue Sep 30 10:57:31 2014 +0200
s390x/kvm: reuse kvm_s390_reset_vcpu() to get rid of ifdefs
This patch reuses kvm_s390_reset_vcpu() to get rid of some CONFIG_KVM and
CONFIG_USER_ONLY ifdefs in cpu.c.
In order to get rid of CONFIG_USER_ONLY, kvm_s390_reset_vcpu() has to provide a
dummy implementation - the two definitions are moved to the proper section in
cpu.h.
Signed-off-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
CC: Andreas Faerber <afaerber at suse.de>
Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 9dbb0df..ec7df90 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -117,14 +117,10 @@ static void s390_cpu_initial_reset(CPUState *s)
env->pfault_token = -1UL;
-#if defined(CONFIG_KVM)
/* Reset state inside the kernel that we cannot access yet from QEMU. */
if (kvm_enabled()) {
- if (kvm_vcpu_ioctl(s, KVM_S390_INITIAL_RESET, NULL)) {
- perror("Initial CPU reset failed");
- }
+ kvm_s390_reset_vcpu(cpu);
}
-#endif
}
/* CPUClass:reset() */
@@ -145,11 +141,10 @@ static void s390_cpu_full_reset(CPUState *s)
env->pfault_token = -1UL;
-#if !defined(CONFIG_USER_ONLY)
+ /* Reset state inside the kernel that we cannot access yet from QEMU. */
if (kvm_enabled()) {
kvm_s390_reset_vcpu(cpu);
}
-#endif
tlb_flush(s, 1);
}
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 6b3aaed..fe2f95d 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -389,16 +389,12 @@ int s390_virtio_hypercall(CPUS390XState *env);
void s390_virtio_irq(int config_change, uint64_t token);
#ifdef CONFIG_KVM
-void kvm_s390_reset_vcpu(S390CPU *cpu);
void kvm_s390_virtio_irq(int config_change, uint64_t token);
void kvm_s390_service_interrupt(uint32_t parm);
void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq);
int kvm_s390_inject_flic(struct kvm_s390_irq *irq);
#else
-static inline void kvm_s390_reset_vcpu(S390CPU *cpu)
-{
-}
static inline void kvm_s390_virtio_irq(int config_change, uint64_t token)
{
}
@@ -1073,6 +1069,7 @@ int kvm_s390_cpu_restart(S390CPU *cpu);
int kvm_s390_get_memslot_count(KVMState *s);
void kvm_s390_clear_cmma_callback(void *opaque);
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
+void kvm_s390_reset_vcpu(S390CPU *cpu);
#else
static inline void kvm_s390_io_interrupt(uint16_t subchannel_id,
uint16_t subchannel_nr,
@@ -1107,6 +1104,9 @@ static inline int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
{
return -ENOSYS;
}
+static inline void kvm_s390_reset_vcpu(S390CPU *cpu)
+{
+}
#endif
static inline void cmma_reset(S390CPU *cpu)
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 7c90b18..e4c4c8d 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -198,7 +198,7 @@ void kvm_s390_reset_vcpu(S390CPU *cpu)
* Before this ioctl cpu_synchronize_state() is called in common kvm
* code (kvm-all) */
if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) {
- perror("Can't reset vcpu\n");
+ error_report("Initial CPU reset failed on CPU %i\n", cs->cpu_index);
}
}
commit c9e659c9ee75d33ff11a8573cea738ad26bb6f86
Author: David Hildenbrand <dahi at linux.vnet.ibm.com>
Date: Tue Sep 30 10:57:30 2014 +0200
s390x/kvm: propagate s390 cpu state to kvm
Let QEMU propagate the cpu state to kvm. If kvm doesn't yet support it, it is
silently ignored as kvm will still handle the cpu state itself in that case.
The state is not synced back, thus kvm won't have a chance to actively modify
the cpu state. To do so, control has to be given back to QEMU (which is already
done so in all relevant cases).
Setting of the cpu state can fail either because kvm doesn't support the
interface yet, or because the state is invalid/not supported. Failed attempts
will be traced
Signed-off-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth at linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
CC: Andreas Faerber <afaerber at suse.de>
Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index dc89eb3..9dbb0df 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -288,6 +288,9 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
cpu_state);
exit(1);
}
+ if (kvm_enabled() && cpu->env.cpu_state != cpu_state) {
+ kvm_s390_set_cpu_state(cpu, cpu_state);
+ }
cpu->env.cpu_state = cpu_state;
return s390_count_running_cpus();
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 7b9300e..6b3aaed 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1072,6 +1072,7 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
int kvm_s390_cpu_restart(S390CPU *cpu);
int kvm_s390_get_memslot_count(KVMState *s);
void kvm_s390_clear_cmma_callback(void *opaque);
+int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
#else
static inline void kvm_s390_io_interrupt(uint16_t subchannel_id,
uint16_t subchannel_nr,
@@ -1102,6 +1103,10 @@ static inline int kvm_s390_get_memslot_count(KVMState *s)
{
return MAX_AVAIL_SLOTS;
}
+static inline int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
+{
+ return -ENOSYS;
+}
#endif
static inline void cmma_reset(S390CPU *cpu)
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 415baea..7c90b18 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -181,9 +181,10 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
return cpu->cpu_index;
}
-int kvm_arch_init_vcpu(CPUState *cpu)
+int kvm_arch_init_vcpu(CPUState *cs)
{
- /* nothing todo yet */
+ S390CPU *cpu = S390_CPU(cs);
+ kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state);
return 0;
}
@@ -1321,3 +1322,41 @@ int kvm_s390_get_memslot_count(KVMState *s)
{
return kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
}
+
+int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
+{
+ struct kvm_mp_state mp_state = {};
+ int ret;
+
+ /* the kvm part might not have been initialized yet */
+ if (CPU(cpu)->kvm_state == NULL) {
+ return 0;
+ }
+
+ switch (cpu_state) {
+ case CPU_STATE_STOPPED:
+ mp_state.mp_state = KVM_MP_STATE_STOPPED;
+ break;
+ case CPU_STATE_CHECK_STOP:
+ mp_state.mp_state = KVM_MP_STATE_CHECK_STOP;
+ break;
+ case CPU_STATE_OPERATING:
+ mp_state.mp_state = KVM_MP_STATE_OPERATING;
+ break;
+ case CPU_STATE_LOAD:
+ mp_state.mp_state = KVM_MP_STATE_LOAD;
+ break;
+ default:
+ error_report("Requested CPU state is not a valid S390 CPU state: %u",
+ cpu_state);
+ exit(1);
+ }
+
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MP_STATE, &mp_state);
+ if (ret) {
+ trace_kvm_failed_cpu_state_set(CPU(cpu)->cpu_index, cpu_state,
+ strerror(-ret));
+ }
+
+ return ret;
+}
diff --git a/trace-events b/trace-events
index 5202f20..5290806 100644
--- a/trace-events
+++ b/trace-events
@@ -1369,6 +1369,7 @@ mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
# target-s390x/kvm.c
kvm_enable_cmma(int rc) "CMMA: enabling with result code %d"
kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
+kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s"
# hw/dma/i8257.c
i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
commit eb24f7c6896e93047f2c58ffd3ba4f453e88280b
Author: David Hildenbrand <dahi at linux.vnet.ibm.com>
Date: Tue Sep 30 10:57:29 2014 +0200
s390x/kvm: proper use of the cpu states OPERATING and STOPPED
This patch makes sure that halting a cpu and stopping a cpu are two different
things. Stopping a cpu will also set the cpu halted - this is needed for common
infrastructure to work (note that the stop and stopped flag cannot be used for
our purpose because they are already used by other mechanisms).
A cpu can be halted ("waiting") when it is operating. If interrupts are
disabled, this is called a "disabled wait", as it can't be woken up anymore. A
stopped cpu is treated like a "disabled wait" cpu, but in order to prepare for a
proper cpu state synchronization with the kvm part, we need to track the real
logical state of a cpu.
Signed-off-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger at de.ibm.com>
CC: Andreas Faerber <afaerber at suse.de>
Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 4fa9cff..3b77c9a 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -176,7 +176,7 @@ static void s390_ipl_reset(DeviceState *dev)
}
}
- s390_add_running_cpu(cpu);
+ s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
}
static void s390_ipl_class_init(ObjectClass *klass, void *data)
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 03cab74..dc89eb3 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -26,7 +26,9 @@
#include "cpu.h"
#include "qemu-common.h"
#include "qemu/timer.h"
+#include "qemu/error-report.h"
#include "hw/hw.h"
+#include "trace.h"
#ifndef CONFIG_USER_ONLY
#include "sysemu/arch_init.h"
#endif
@@ -81,7 +83,7 @@ static void s390_cpu_load_normal(CPUState *s)
S390CPU *cpu = S390_CPU(s);
cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR;
cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64;
- s390_add_running_cpu(cpu);
+ s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
}
#endif
@@ -93,11 +95,8 @@ static void s390_cpu_reset(CPUState *s)
CPUS390XState *env = &cpu->env;
env->pfault_token = -1UL;
- s390_del_running_cpu(cpu);
scc->parent_reset(s);
-#if !defined(CONFIG_USER_ONLY)
- s->halted = 1;
-#endif
+ s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
tlb_flush(s, 1);
}
@@ -135,9 +134,8 @@ static void s390_cpu_full_reset(CPUState *s)
S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
CPUS390XState *env = &cpu->env;
- s390_del_running_cpu(cpu);
-
scc->parent_reset(s);
+ s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
memset(env, 0, offsetof(CPUS390XState, cpu_num));
@@ -147,12 +145,7 @@ static void s390_cpu_full_reset(CPUState *s)
env->pfault_token = -1UL;
- /* set halted to 1 to make sure we can add the cpu in
- * s390_ipl_cpu code, where CPUState::halted is set back to 0
- * after incrementing the cpu counter */
#if !defined(CONFIG_USER_ONLY)
- s->halted = 1;
-
if (kvm_enabled()) {
kvm_s390_reset_vcpu(cpu);
}
@@ -206,10 +199,7 @@ static void s390_cpu_initfn(Object *obj)
env->tod_basetime = 0;
env->tod_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
env->cpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
- /* set CPUState::halted state to 1 to avoid decrementing the running
- * cpu counter in s390_cpu_reset to a negative number at
- * initial ipl */
- cs->halted = 1;
+ s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
#endif
env->cpu_num = cpu_num++;
env->ext_index = -1;
@@ -230,6 +220,12 @@ static void s390_cpu_finalize(Object *obj)
}
#if !defined(CONFIG_USER_ONLY)
+static bool disabled_wait(CPUState *cpu)
+{
+ return cpu->halted && !(S390_CPU(cpu)->env.psw.mask &
+ (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK));
+}
+
static unsigned s390_count_running_cpus(void)
{
CPUState *cpu;
@@ -239,34 +235,60 @@ static unsigned s390_count_running_cpus(void)
uint8_t state = S390_CPU(cpu)->env.cpu_state;
if (state == CPU_STATE_OPERATING ||
state == CPU_STATE_LOAD) {
- nr_running++;
+ if (!disabled_wait(cpu)) {
+ nr_running++;
+ }
}
}
return nr_running;
}
-void s390_add_running_cpu(S390CPU *cpu)
+unsigned int s390_cpu_halt(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
+ trace_cpu_halt(cs->cpu_index);
- if (cs->halted) {
- cpu->env.cpu_state = CPU_STATE_OPERATING;
- cs->halted = 0;
- cs->exception_index = -1;
+ if (!cs->halted) {
+ cs->halted = 1;
+ cs->exception_index = EXCP_HLT;
}
+
+ return s390_count_running_cpus();
}
-unsigned s390_del_running_cpu(S390CPU *cpu)
+void s390_cpu_unhalt(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
+ trace_cpu_unhalt(cs->cpu_index);
- if (cs->halted == 0) {
- assert(s390_count_running_cpus() >= 1);
- cpu->env.cpu_state = CPU_STATE_STOPPED;
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
+ if (cs->halted) {
+ cs->halted = 0;
+ cs->exception_index = -1;
+ }
+}
+
+unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
+ {
+ trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state);
+
+ switch (cpu_state) {
+ case CPU_STATE_STOPPED:
+ case CPU_STATE_CHECK_STOP:
+ /* halt the cpu for common infrastructure */
+ s390_cpu_halt(cpu);
+ break;
+ case CPU_STATE_OPERATING:
+ case CPU_STATE_LOAD:
+ /* unhalt the cpu for common infrastructure */
+ s390_cpu_unhalt(cpu);
+ break;
+ default:
+ error_report("Requested CPU state is not a valid S390 CPU state: %u",
+ cpu_state);
+ exit(1);
}
+ cpu->env.cpu_state = cpu_state;
return s390_count_running_cpus();
}
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index f1a3ad2..7b9300e 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -407,8 +407,9 @@ static inline void kvm_s390_service_interrupt(uint32_t parm)
}
#endif
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
-void s390_add_running_cpu(S390CPU *cpu);
-unsigned s390_del_running_cpu(S390CPU *cpu);
+unsigned int s390_cpu_halt(S390CPU *cpu);
+void s390_cpu_unhalt(S390CPU *cpu);
+unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu);
/* service interrupts are floating therefore we must not pass an cpustate */
void s390_sclp_extint(uint32_t parm);
@@ -417,11 +418,16 @@ void s390_sclp_extint(uint32_t parm);
extern const hwaddr virtio_size;
#else
-static inline void s390_add_running_cpu(S390CPU *cpu)
+static inline unsigned int s390_cpu_halt(S390CPU *cpu)
+{
+ return 0;
+}
+
+static inline void s390_cpu_unhalt(S390CPU *cpu)
{
}
-static inline unsigned s390_del_running_cpu(S390CPU *cpu)
+static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
{
return 0;
}
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index e21afe6..09aec7b 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -504,23 +504,18 @@ hwaddr s390_cpu_get_phys_addr_debug(CPUState *cs, vaddr vaddr)
void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
{
+ env->psw.addr = addr;
+ env->psw.mask = mask;
+ env->cc_op = (mask >> 44) & 3;
+
if (mask & PSW_MASK_WAIT) {
S390CPU *cpu = s390_env_get_cpu(env);
- CPUState *cs = CPU(cpu);
- if (!(mask & (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK))) {
- if (s390_del_running_cpu(cpu) == 0) {
+ if (s390_cpu_halt(cpu) == 0) {
#ifndef CONFIG_USER_ONLY
- qemu_system_shutdown_request();
+ qemu_system_shutdown_request();
#endif
- }
}
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
}
-
- env->psw.addr = addr;
- env->psw.mask = mask;
- env->cc_op = (mask >> 44) & 3;
}
static uint64_t get_psw_mask(CPUS390XState *env)
@@ -818,7 +813,7 @@ void s390_cpu_do_interrupt(CPUState *cs)
qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n",
__func__, cs->exception_index, env->psw.addr);
- s390_add_running_cpu(cpu);
+ s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
/* handle machine checks */
if ((env->psw.mask & PSW_MASK_MCHECK) &&
(cs->exception_index == -1)) {
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a85a480..415baea 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -921,7 +921,7 @@ static void sigp_cpu_start(void *arg)
CPUState *cs = arg;
S390CPU *cpu = S390_CPU(cs);
- s390_add_running_cpu(cpu);
+ s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
DPRINTF("DONE: KVM cpu start: %p\n", &cpu->env);
}
@@ -934,7 +934,7 @@ static void sigp_cpu_restart(void *arg)
};
kvm_s390_vcpu_interrupt(cpu, &irq);
- s390_add_running_cpu(cpu);
+ s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
}
int kvm_s390_cpu_restart(S390CPU *cpu)
@@ -1074,7 +1074,7 @@ static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswoffset)
error_report("Unmanageable %s! CPU%i new PSW: 0x%016lx:%016lx",
str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswoffset),
ldq_phys(cs->as, cpu->env.psa + pswoffset + 8));
- s390_del_running_cpu(cpu);
+ s390_cpu_halt(cpu);
guest_panicked();
}
@@ -1103,7 +1103,8 @@ static int handle_intercept(S390CPU *cpu)
break;
case ICPT_WAITPSW:
/* disabled wait, since enabled wait is handled in kernel */
- if (s390_del_running_cpu(cpu) == 0) {
+ cpu_synchronize_state(cs);
+ if (s390_cpu_halt(cpu) == 0) {
if (is_special_wait_psw(cs)) {
qemu_system_shutdown_request();
} else {
@@ -1113,7 +1114,7 @@ static int handle_intercept(S390CPU *cpu)
r = EXCP_HALTED;
break;
case ICPT_CPU_STOP:
- if (s390_del_running_cpu(cpu) == 0) {
+ if (s390_cpu_set_state(CPU_STATE_STOPPED, cpu) == 0) {
qemu_system_shutdown_request();
}
r = EXCP_HALTED;
diff --git a/trace-events b/trace-events
index 011d105..5202f20 100644
--- a/trace-events
+++ b/trace-events
@@ -1372,3 +1372,8 @@ kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
# hw/dma/i8257.c
i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
+
+# target-s390x/cpu.c
+cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8
+cpu_halt(int cpu_index) "halting cpu %d"
+cpu_unhalt(int cpu_index) "unhalting cpu %d"
commit 75973bfe415774babe7c1e18fa682c050fdce73b
Author: David Hildenbrand <dahi at linux.vnet.ibm.com>
Date: Tue Sep 30 10:57:28 2014 +0200
s390x/kvm: introduce proper states for s390 cpus
Until now, when a s390 cpu was stopped or halted, the number of running
CPUs was tracked in a global variable. This was problematic for migration,
so Jason came up with a per-cpu running state.
As it turns out, we want to track the full logical state of a target vcpu,
so we need real s390 cpu states.
This patch is based on an initial patch by Jason Herne, but was heavily
rewritten when adding the cpu states STOPPED and OPERATING. On the way we
move add_del_running to cpu.c (the declaration is already in cpu.h) and
modify the users where appropriate.
Please note that the cpu is still set to be stopped when it is
halted, which is wrong. This will be fixed in the next patch. The LOAD and
CHECK-STOP state will not be used in the first step.
Signed-off-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
[folded Jason's patch into David's patch to avoid add/remove same lines]
Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger at de.ibm.com>
CC: Andreas Faerber <afaerber at suse.de>
Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 9c61246..af0004a 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -125,38 +125,6 @@ static void s390_virtio_register_hcalls(void)
s390_virtio_hcall_set_status);
}
-/*
- * The number of running CPUs. On s390 a shutdown is the state of all CPUs
- * being either stopped or disabled (for interrupts) waiting. We have to
- * track this number to call the shutdown sequence accordingly. This
- * number is modified either on startup or while holding the big qemu lock.
- */
-static unsigned s390_running_cpus;
-
-void s390_add_running_cpu(S390CPU *cpu)
-{
- CPUState *cs = CPU(cpu);
-
- if (cs->halted) {
- s390_running_cpus++;
- cs->halted = 0;
- cs->exception_index = -1;
- }
-}
-
-unsigned s390_del_running_cpu(S390CPU *cpu)
-{
- CPUState *cs = CPU(cpu);
-
- if (cs->halted == 0) {
- assert(s390_running_cpus >= 1);
- s390_running_cpus--;
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
- }
- return s390_running_cpus;
-}
-
void s390_init_ipl_dev(const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 2cfeb82..03cab74 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -229,6 +229,49 @@ static void s390_cpu_finalize(Object *obj)
#endif
}
+#if !defined(CONFIG_USER_ONLY)
+static unsigned s390_count_running_cpus(void)
+{
+ CPUState *cpu;
+ int nr_running = 0;
+
+ CPU_FOREACH(cpu) {
+ uint8_t state = S390_CPU(cpu)->env.cpu_state;
+ if (state == CPU_STATE_OPERATING ||
+ state == CPU_STATE_LOAD) {
+ nr_running++;
+ }
+ }
+
+ return nr_running;
+}
+
+void s390_add_running_cpu(S390CPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+
+ if (cs->halted) {
+ cpu->env.cpu_state = CPU_STATE_OPERATING;
+ cs->halted = 0;
+ cs->exception_index = -1;
+ }
+}
+
+unsigned s390_del_running_cpu(S390CPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+
+ if (cs->halted == 0) {
+ assert(s390_count_running_cpus() >= 1);
+ cpu->env.cpu_state = CPU_STATE_STOPPED;
+ cs->halted = 1;
+ cs->exception_index = EXCP_HLT;
+ }
+
+ return s390_count_running_cpus();
+}
+#endif
+
static const VMStateDescription vmstate_s390_cpu = {
.name = "cpu",
.unmigratable = 1,
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 62940c3..f1a3ad2 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -141,6 +141,20 @@ typedef struct CPUS390XState {
QEMUTimer *tod_timer;
QEMUTimer *cpu_timer;
+
+ /*
+ * The cpu state represents the logical state of a cpu. In contrast to other
+ * architectures, there is a difference between a halt and a stop on s390.
+ * If all cpus are either stopped (including check stop) or in the disabled
+ * wait state, the vm can be shut down.
+ */
+#define CPU_STATE_UNINITIALIZED 0x00
+#define CPU_STATE_STOPPED 0x01
+#define CPU_STATE_CHECK_STOP 0x02
+#define CPU_STATE_OPERATING 0x03
+#define CPU_STATE_LOAD 0x04
+ uint8_t cpu_state;
+
} CPUS390XState;
#include "cpu-qom.h"
commit a9fd16544dd3cdc50902ff652e2f57982f113497
Author: Jens Freimann <jfrei at linux.vnet.ibm.com>
Date: Tue Sep 30 10:57:27 2014 +0200
linux-headers: update to 3.17-rc7
Sync headers with 3.17-rc7
Acked-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
diff --git a/linux-headers/asm-mips/kvm_para.h b/linux-headers/asm-mips/kvm_para.h
index 14fab8f..dbb2464 100644
--- a/linux-headers/asm-mips/kvm_para.h
+++ b/linux-headers/asm-mips/kvm_para.h
@@ -1 +1,5 @@
-#include <asm-generic/kvm_para.h>
+#ifndef _ASM_MIPS_KVM_PARA_H
+#define _ASM_MIPS_KVM_PARA_H
+
+
+#endif /* _ASM_MIPS_KVM_PARA_H */
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 2bc4a94..e0e49db 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -548,6 +548,7 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4)
#define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5)
+#define KVM_REG_PPC_LPCR_64 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb5)
#define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6)
/* Architecture compatibility level */
@@ -555,6 +556,7 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_DABRX (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb8)
#define KVM_REG_PPC_WORT (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb9)
+#define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba)
/* Transactional Memory checkpointed state:
* This is all GPRs, all VSX regs and a subset of SPRs
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
index d3a8778..d7dcef5 100644
--- a/linux-headers/asm-x86/kvm.h
+++ b/linux-headers/asm-x86/kvm.h
@@ -23,7 +23,10 @@
#define GP_VECTOR 13
#define PF_VECTOR 14
#define MF_VECTOR 16
+#define AC_VECTOR 17
#define MC_VECTOR 18
+#define XM_VECTOR 19
+#define VE_VECTOR 20
/* Select x86 specific features in <linux/kvm.h> */
#define __KVM_HAVE_PIT
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index f5d2c38..2669938 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -162,7 +162,7 @@ struct kvm_pit_config {
#define KVM_EXIT_TPR_ACCESS 12
#define KVM_EXIT_S390_SIEIC 13
#define KVM_EXIT_S390_RESET 14
-#define KVM_EXIT_DCR 15
+#define KVM_EXIT_DCR 15 /* deprecated */
#define KVM_EXIT_NMI 16
#define KVM_EXIT_INTERNAL_ERROR 17
#define KVM_EXIT_OSI 18
@@ -268,7 +268,7 @@ struct kvm_run {
__u64 trans_exc_code;
__u32 pgm_code;
} s390_ucontrol;
- /* KVM_EXIT_DCR */
+ /* KVM_EXIT_DCR (deprecated) */
struct {
__u32 dcrn;
__u32 data;
@@ -399,13 +399,18 @@ struct kvm_vapic_addr {
__u64 vapic_addr;
};
-/* for KVM_SET_MPSTATE */
+/* for KVM_SET_MP_STATE */
+/* not all states are valid on all architectures */
#define KVM_MP_STATE_RUNNABLE 0
#define KVM_MP_STATE_UNINITIALIZED 1
#define KVM_MP_STATE_INIT_RECEIVED 2
#define KVM_MP_STATE_HALTED 3
#define KVM_MP_STATE_SIPI_RECEIVED 4
+#define KVM_MP_STATE_STOPPED 5
+#define KVM_MP_STATE_CHECK_STOP 6
+#define KVM_MP_STATE_OPERATING 7
+#define KVM_MP_STATE_LOAD 8
struct kvm_mp_state {
__u32 mp_state;
@@ -758,6 +763,8 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_VM_ATTRIBUTES 101
#define KVM_CAP_ARM_PSCI_0_2 102
#define KVM_CAP_PPC_FIXUP_HCALL 103
+#define KVM_CAP_PPC_ENABLE_HCALL 104
+#define KVM_CAP_CHECK_EXTENSION_VM 105
#ifdef KVM_CAP_IRQ_ROUTING
diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h
index 2dff783..e61661e 100644
--- a/linux-headers/linux/kvm_para.h
+++ b/linux-headers/linux/kvm_para.h
@@ -20,6 +20,9 @@
#define KVM_HC_FEATURES 3
#define KVM_HC_PPC_MAP_MAGIC_PAGE 4
#define KVM_HC_KICK_CPU 5
+#define KVM_HC_MIPS_GET_CLOCK_FREQ 6
+#define KVM_HC_MIPS_EXIT_VM 7
+#define KVM_HC_MIPS_CONSOLE_OUTPUT 8
/*
* hypercalls use architecture specific
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 26c218e..95b591b 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -30,6 +30,9 @@
*/
#define VFIO_DMA_CC_IOMMU 4
+/* Check if EEH is supported */
+#define VFIO_EEH 5
+
/*
* The IOCTL interface is designed for extensibility by embedding the
* structure length (argsz) and flags into structures passed between
@@ -455,6 +458,37 @@ struct vfio_iommu_spapr_tce_info {
#define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
+/*
+ * EEH PE operation struct provides ways to:
+ * - enable/disable EEH functionality;
+ * - unfreeze IO/DMA for frozen PE;
+ * - read PE state;
+ * - reset PE;
+ * - configure PE.
+ */
+struct vfio_eeh_pe_op {
+ __u32 argsz;
+ __u32 flags;
+ __u32 op;
+};
+
+#define VFIO_EEH_PE_DISABLE 0 /* Disable EEH functionality */
+#define VFIO_EEH_PE_ENABLE 1 /* Enable EEH functionality */
+#define VFIO_EEH_PE_UNFREEZE_IO 2 /* Enable IO for frozen PE */
+#define VFIO_EEH_PE_UNFREEZE_DMA 3 /* Enable DMA for frozen PE */
+#define VFIO_EEH_PE_GET_STATE 4 /* PE state retrieval */
+#define VFIO_EEH_PE_STATE_NORMAL 0 /* PE in functional state */
+#define VFIO_EEH_PE_STATE_RESET 1 /* PE reset in progress */
+#define VFIO_EEH_PE_STATE_STOPPED 2 /* Stopped DMA and IO */
+#define VFIO_EEH_PE_STATE_STOPPED_DMA 4 /* Stopped DMA only */
+#define VFIO_EEH_PE_STATE_UNAVAIL 5 /* State unavailable */
+#define VFIO_EEH_PE_RESET_DEACTIVATE 5 /* Deassert PE reset */
+#define VFIO_EEH_PE_RESET_HOT 6 /* Assert hot reset */
+#define VFIO_EEH_PE_RESET_FUNDAMENTAL 7 /* Assert fundamental reset */
+#define VFIO_EEH_PE_CONFIGURE 8 /* PE configuration */
+
+#define VFIO_EEH_PE_OP _IO(VFIO_TYPE, VFIO_BASE + 21)
+
/* ***************************************************************** */
#endif /* VFIO_H */
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index bb5df43..c656f61 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -14,7 +14,7 @@
#include <linux/ioctl.h>
#include <linux/virtio_config.h>
-#include "hw/virtio/virtio_ring.h"
+#include <linux/virtio_ring.h>
struct vhost_vring_state {
unsigned int index;
commit fcb2cd928f5519b8241e22411a696be1a7272b1c
Merge: b6011bd 5008e5b
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Thu Oct 9 15:09:05 2014 +0100
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Four changes here. Polling for reconnection of character devices,
the QOMification of accelerators, a fix for -kernel support on x86, and one
for a recently-introduced virtio-scsi optimization.
# gpg: Signature made Thu 09 Oct 2014 14:36:50 BST using RSA key ID 4E6B09D7
# gpg: Good signature from "Paolo Bonzini <pbonzini at redhat.com>"
# gpg: aka "Paolo Bonzini <bonzini at gnu.org>"
* remotes/bonzini/tags/for-upstream: (28 commits)
qemu-char: Fix reconnect socket error reporting
qemu-sockets: Add error to non-blocking connect handler
qemu-error: Add error_vreport()
virtio-scsi: fix use-after-free of VirtIOSCSIReq
linuxboot: compute initrd loading address
kvm: Make KVMState be the TYPE_KVM_ACCEL instance struct
accel: Create accel object when initializing machine
accel: Pass MachineState object to accel init functions
accel: Rename 'init' method to 'init_machine'
accel: Move accel init/allowed code to separate function
accel: Remove tcg_available() function
accel: Move qtest accel registration to qtest.c
accel: Move Xen registration code to xen-common.c
accel: Move KVM accel registration to kvm-all.c
accel: Report unknown accelerator as "not found" instead of "does not exist"
accel: Make AccelClass.available() optional
accel: Use QOM classes for accel types
accel: Move accel name lookup to separate function
accel: Simplify configure_accelerator() using AccelType *acc variable
accel: Create AccelType typedef
...
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
commit 5008e5b7b817b5ea2b788203122cd50e7c16e599
Author: Corey Minyard <cminyard at mvista.com>
Date: Wed Oct 8 07:11:55 2014 -0500
qemu-char: Fix reconnect socket error reporting
If reconnect was set, errors wouldn't always be reported.
Fix that and also only report a connect error once until a
connection has been made.
The primary purpose of this is to tell the user that a
connection failed so they can know they need to figure out
what went wrong. So we don't want to spew too much
out here, just enough so they know.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/qemu-char.c b/qemu-char.c
index c71805a..bd0709b 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2509,6 +2509,7 @@ typedef struct {
guint reconnect_timer;
int64_t reconnect_time;
+ bool connect_err_reported;
} TCPCharDriver;
static gboolean socket_reconnect_timeout(gpointer opaque);
@@ -2521,6 +2522,19 @@ static void qemu_chr_socket_restart_timer(CharDriverState *chr)
socket_reconnect_timeout, chr);
}
+static void check_report_connect_error(CharDriverState *chr,
+ Error *err)
+{
+ TCPCharDriver *s = chr->opaque;
+
+ if (!s->connect_err_reported) {
+ error_report("Unable to connect character device %s: %s",
+ chr->label, error_get_pretty(err));
+ s->connect_err_reported = true;
+ }
+ qemu_chr_socket_restart_timer(chr);
+}
+
static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
#ifndef _WIN32
@@ -3045,14 +3059,14 @@ static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd)
static void qemu_chr_socket_connected(int fd, Error *err, void *opaque)
{
CharDriverState *chr = opaque;
+ TCPCharDriver *s = chr->opaque;
if (fd < 0) {
- error_report("Unable to connect to char device %s: %s",
- chr->label, error_get_pretty(err));
- qemu_chr_socket_restart_timer(chr);
+ check_report_connect_error(chr, err);
return;
}
+ s->connect_err_reported = false;
qemu_chr_finish_socket_connection(chr, fd);
}
@@ -4068,11 +4082,19 @@ static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
#endif /* WIN32 */
+static void socket_try_connect(CharDriverState *chr)
+{
+ Error *err = NULL;
+
+ if (!qemu_chr_open_socket_fd(chr, &err)) {
+ check_report_connect_error(chr, err);
+ }
+}
+
static gboolean socket_reconnect_timeout(gpointer opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
- Error *err;
s->reconnect_timer = 0;
@@ -4080,11 +4102,7 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
return false;
}
- if (!qemu_chr_open_socket_fd(chr, &err)) {
- error_report("Unable to connect to char device %s: %s\n",
- chr->label, error_get_pretty(err));
- qemu_chr_socket_restart_timer(chr);
- }
+ socket_try_connect(chr);
return false;
}
@@ -4136,15 +4154,13 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
s->reconnect_time = reconnect;
}
- if (!qemu_chr_open_socket_fd(chr, errp)) {
- if (s->reconnect_time) {
- qemu_chr_socket_restart_timer(chr);
- } else {
- g_free(s);
- g_free(chr->filename);
- g_free(chr);
- return NULL;
- }
+ if (s->reconnect_time) {
+ socket_try_connect(chr);
+ } else if (!qemu_chr_open_socket_fd(chr, errp)) {
+ g_free(s);
+ g_free(chr->filename);
+ g_free(chr);
+ return NULL;
}
if (is_listen && is_waitconnect) {
commit 5179502918d0c230afb50d8b95247de440fccdd5
Author: Corey Minyard <cminyard at mvista.com>
Date: Wed Oct 8 07:11:56 2014 -0500
qemu-sockets: Add error to non-blocking connect handler
An error value here would be quite handy and more consistent
with the rest of the code.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
[Make sure SO_ERROR value is passed to error_setg_errno. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index fdbb196..f47dae6 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -47,7 +47,7 @@ int recv_all(int fd, void *buf, int len1, bool single_read);
/* callback function for nonblocking connect
* valid fd on success, negative error code on failure
*/
-typedef void NonBlockingConnectHandler(int fd, void *opaque);
+typedef void NonBlockingConnectHandler(int fd, Error *errp, void *opaque);
InetSocketAddress *inet_parse(const char *str, Error **errp);
int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
diff --git a/migration-tcp.c b/migration-tcp.c
index 2e34517..91c9cf3 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -33,12 +33,12 @@
do { } while (0)
#endif
-static void tcp_wait_for_connect(int fd, void *opaque)
+static void tcp_wait_for_connect(int fd, Error *err, void *opaque)
{
MigrationState *s = opaque;
if (fd < 0) {
- DPRINTF("migrate connect error\n");
+ DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
s->file = NULL;
migrate_fd_error(s);
} else {
diff --git a/migration-unix.c b/migration-unix.c
index 0a5f8a1..1cdadfb 100644
--- a/migration-unix.c
+++ b/migration-unix.c
@@ -33,12 +33,12 @@
do { } while (0)
#endif
-static void unix_wait_for_connect(int fd, void *opaque)
+static void unix_wait_for_connect(int fd, Error *err, void *opaque)
{
MigrationState *s = opaque;
if (fd < 0) {
- DPRINTF("migrate connect error\n");
+ DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
s->file = NULL;
migrate_fd_error(s);
} else {
diff --git a/qemu-char.c b/qemu-char.c
index 62af0ef..c71805a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3042,11 +3042,13 @@ static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd)
}
}
-static void qemu_chr_socket_connected(int fd, void *opaque)
+static void qemu_chr_socket_connected(int fd, Error *err, void *opaque)
{
CharDriverState *chr = opaque;
if (fd < 0) {
+ error_report("Unable to connect to char device %s: %s",
+ chr->label, error_get_pretty(err));
qemu_chr_socket_restart_timer(chr);
return;
}
@@ -4079,7 +4081,8 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
}
if (!qemu_chr_open_socket_fd(chr, &err)) {
- error_report("Unable to connect to char device %s\n", chr->label);
+ error_report("Unable to connect to char device %s: %s\n",
+ chr->label, error_get_pretty(err));
qemu_chr_socket_restart_timer(chr);
}
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 1eef590..a76bb3c 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -234,6 +234,7 @@ static void wait_for_connect(void *opaque)
int val = 0, rc = 0;
socklen_t valsize = sizeof(val);
bool in_progress;
+ Error *err = NULL;
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
@@ -244,10 +245,12 @@ static void wait_for_connect(void *opaque)
/* update rc to contain error */
if (!rc && val) {
rc = -1;
+ errno = val;
}
/* connect error */
if (rc < 0) {
+ error_setg_errno(&err, errno, "Error connecting to socket");
closesocket(s->fd);
s->fd = rc;
}
@@ -257,9 +260,14 @@ static void wait_for_connect(void *opaque)
while (s->current_addr->ai_next != NULL && s->fd < 0) {
s->current_addr = s->current_addr->ai_next;
s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL);
+ if (s->fd < 0) {
+ error_free(err);
+ err = NULL;
+ error_setg_errno(&err, errno, "Unable to start socket connect");
+ }
/* connect in progress */
if (in_progress) {
- return;
+ goto out;
}
}
@@ -267,9 +275,11 @@ static void wait_for_connect(void *opaque)
}
if (s->callback) {
- s->callback(s->fd, s->opaque);
+ s->callback(s->fd, err, s->opaque);
}
g_free(s);
+out:
+ error_free(err);
}
static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
@@ -401,7 +411,7 @@ int inet_connect_opts(QemuOpts *opts, Error **errp,
return sock;
} else {
if (callback) {
- callback(sock, opaque);
+ callback(sock, NULL, opaque);
}
}
g_free(connect_state);
@@ -769,7 +779,7 @@ int unix_connect_opts(QemuOpts *opts, Error **errp,
} else if (rc >= 0) {
/* non blocking socket immediate success, call callback */
if (callback != NULL) {
- callback(sock, opaque);
+ callback(sock, NULL, opaque);
}
}
@@ -919,7 +929,7 @@ int socket_connect(SocketAddress *addr, Error **errp,
fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
if (fd >= 0 && callback) {
qemu_set_nonblock(fd);
- callback(fd, opaque);
+ callback(fd, NULL, opaque);
}
break;
commit 5748e4c2be4f5c24c691f91328be02a9c4cb3063
Author: Corey Minyard <cminyard at mvista.com>
Date: Wed Oct 8 07:11:54 2014 -0500
qemu-error: Add error_vreport()
Needed to nicely print socket error reports.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index 000eae3..7ab2355 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -38,6 +38,7 @@ void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void error_set_progname(const char *argv0);
+void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
const char *error_get_progname(void);
extern bool enable_timestamp_msg;
diff --git a/util/qemu-error.c b/util/qemu-error.c
index 7b167fd..9bba5f5 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -199,14 +199,13 @@ static void error_print_loc(void)
bool enable_timestamp_msg;
/*
* Print an error message to current monitor if we have one, else to stderr.
- * Format arguments like sprintf(). The result should not contain
+ * Format arguments like vsprintf(). The result should not contain
* newlines.
* Prepend the current location and append a newline.
* It's wrong to call this in a QMP monitor. Use qerror_report() there.
*/
-void error_report(const char *fmt, ...)
+void error_vreport(const char *fmt, va_list ap)
{
- va_list ap;
GTimeVal tv;
gchar *timestr;
@@ -218,8 +217,22 @@ void error_report(const char *fmt, ...)
}
error_print_loc();
- va_start(ap, fmt);
error_vprintf(fmt, ap);
- va_end(ap);
error_printf("\n");
}
+
+/*
+ * Print an error message to current monitor if we have one, else to stderr.
+ * Format arguments like sprintf(). The result should not contain
+ * newlines.
+ * Prepend the current location and append a newline.
+ * It's wrong to call this in a QMP monitor. Use qerror_report() there.
+ */
+void error_report(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ error_vreport(fmt, ap);
+ va_end(ap);
+}
commit 35e4e96c4d5bfcf8a22930d8e99f7c8c44420062
Author: Paolo Bonzini <pbonzini at redhat.com>
Date: Wed Oct 8 01:19:00 2014 +0200
virtio-scsi: fix use-after-free of VirtIOSCSIReq
scsi_req_continue can complete the request and cause the VirtIOSCSIReq
to be freed. Fetch req->sreq just once to avoid the bug.
Reported-by: Richard Jones <rjones at redhat.com>
Tested-by: Richard Jones <rjones at redhat.com>
Reviewed-by: Fam Zheng <famz at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 203e624..6c02fe2 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -545,11 +545,12 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
{
- if (scsi_req_enqueue(req->sreq)) {
- scsi_req_continue(req->sreq);
+ SCSIRequest *sreq = req->sreq;
+ if (scsi_req_enqueue(sreq)) {
+ scsi_req_continue(sreq);
}
- bdrv_io_unplug(req->sreq->dev->conf.bs);
- scsi_req_unref(req->sreq);
+ bdrv_io_unplug(sreq->dev->conf.bs);
+ scsi_req_unref(sreq);
}
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
commit cdebec5e40bd0af82da0659f37af85ee2aa2c9d1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date: Mon Oct 6 16:49:57 2014 +0200
linuxboot: compute initrd loading address
Even though hw/i386/pc.c tries to compute a valid loading address for the
initrd, close to the top of RAM, this does not take into account other
data that is malloced into that memory by SeaBIOS.
Luckily we can easily look at the memory map to find out how much memory is
used up there. This patch places the initrd in the first four gigabytes,
below the first hole (as returned by INT 15h, AX=e801h).
Without this patch:
[ 0.000000] init_memory_mapping: [mem 0x07000000-0x07fdffff]
[ 0.000000] RAMDISK: [mem 0x0710a000-0x07fd7fff]
With this patch:
[ 0.000000] init_memory_mapping: [mem 0x07000000-0x07fdffff]
[ 0.000000] RAMDISK: [mem 0x07112000-0x07fdffff]
So linuxboot is able to use the 64k that were added as padding for
QEMU <= 2.1.
Acked-by: Michael S. Tsirkin <mst at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/pc-bios/linuxboot.bin b/pc-bios/linuxboot.bin
index e7c3669..130103f 100644
Binary files a/pc-bios/linuxboot.bin and b/pc-bios/linuxboot.bin differ
diff --git a/pc-bios/optionrom/linuxboot.S b/pc-bios/optionrom/linuxboot.S
index 748c831..5bc0af0 100644
--- a/pc-bios/optionrom/linuxboot.S
+++ b/pc-bios/optionrom/linuxboot.S
@@ -76,14 +76,45 @@ boot_kernel:
copy_kernel:
+ /* Compute initrd address */
+ mov $0xe801, %ax
+ xor %cx, %cx
+ xor %dx, %dx
+ int $0x15
+
+ /* Output could be in AX/BX or CX/DX */
+ or %cx, %cx
+ jnz 1f
+ or %dx, %dx
+ jnz 1f
+ mov %ax, %cx
+ mov %bx, %dx
+1:
+
+ or %dx, %dx
+ jnz 2f
+ addw $1024, %cx /* add 1 MB */
+ movzwl %cx, %edi
+ shll $10, %edi /* convert to bytes */
+ jmp 3f
+
+2:
+ addw $16777216 >> 16, %dx /* add 16 MB */
+ movzwl %dx, %edi
+ shll $16, %edi /* convert to bytes */
+
+3:
+ read_fw FW_CFG_INITRD_SIZE
+ subl %eax, %edi
+ andl $-4096, %edi /* EDI = start of initrd */
/* We need to load the kernel into memory we can't access in 16 bit
mode, so let's get into 32 bit mode, write the kernel and jump
back again. */
/* Reserve space on the stack for our GDT descriptor. */
- mov %esp, %ebp
- sub $16, %esp
+ mov %esp, %ebp
+ sub $16, %esp
/* Now create the GDT descriptor */
movw $((3 * 8) - 1), -16(%bp)
@@ -108,10 +139,18 @@ copy_kernel:
/* We're now running in 16-bit CS, but 32-bit ES! */
/* Load kernel and initrd */
+ pushl %edi
+ read_fw_blob_addr32_edi(FW_CFG_INITRD)
read_fw_blob_addr32(FW_CFG_KERNEL)
- read_fw_blob_addr32(FW_CFG_INITRD)
read_fw_blob_addr32(FW_CFG_CMDLINE)
- read_fw_blob_addr32(FW_CFG_SETUP)
+
+ read_fw FW_CFG_SETUP_ADDR
+ mov %eax, %edi
+ mov %eax, %ebx
+ read_fw_blob_addr32_edi(FW_CFG_SETUP)
+
+ /* Update the header with the initrd address we chose above */
+ popl %es:0x218(%ebx)
/* And now jump into Linux! */
mov $0, %eax
diff --git a/pc-bios/optionrom/optionrom.h b/pc-bios/optionrom/optionrom.h
index ce43608..f1a9021 100644
--- a/pc-bios/optionrom/optionrom.h
+++ b/pc-bios/optionrom/optionrom.h
@@ -51,8 +51,6 @@
.endm
#define read_fw_blob_pre(var) \
- read_fw var ## _ADDR; \
- mov %eax, %edi; \
read_fw var ## _SIZE; \
mov %eax, %ecx; \
mov $var ## _DATA, %ax; \
@@ -68,6 +66,8 @@
* Clobbers: %eax, %edx, %es, %ecx, %edi
*/
#define read_fw_blob(var) \
+ read_fw var ## _ADDR; \
+ mov %eax, %edi; \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
rep insb (%dx), %es:(%edi); \
@@ -80,7 +80,22 @@
*
* Clobbers: %eax, %edx, %es, %ecx, %edi
*/
-#define read_fw_blob_addr32(var) \
+#define read_fw_blob_addr32(var) \
+ read_fw var ## _ADDR; \
+ mov %eax, %edi; \
+ read_fw_blob_pre(var); \
+ /* old as(1) doesn't like this insn so emit the bytes instead: \
+ addr32 rep insb (%dx), %es:(%edi); \
+ */ \
+ .dc.b 0x67,0xf3,0x6c
+
+/*
+ * Read a blob from the fw_cfg device in forced addr32 mode, address is in %edi.
+ * Requires _SIZE and _DATA values for the parameter.
+ *
+ * Clobbers: %eax, %edx, %edi, %es, %ecx
+ */
+#define read_fw_blob_addr32_edi(var) \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
addr32 rep insb (%dx), %es:(%edi); \
commit fc02086b5ab8de50ce8234cf8f42b254de9e5d91
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:32 2014 -0300
kvm: Make KVMState be the TYPE_KVM_ACCEL instance struct
Now that we create an accel object before calling machine_init, we can
simply use the accel object to save all KVMState data, instead of
allocationg KVMState manually.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/kvm-all.c b/kvm-all.c
index 0a9de92..e98a7c7 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -71,8 +71,10 @@ typedef struct KVMSlot
typedef struct kvm_dirty_log KVMDirtyLog;
-struct KVMState
+typedef struct KVMState
{
+ AccelState parent_obj;
+
KVMSlot *slots;
int nr_slots;
int fd;
@@ -105,10 +107,13 @@ struct KVMState
QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
bool direct_msi;
#endif
-};
+} KVMState;
#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
+#define KVM_STATE(obj) \
+ OBJECT_CHECK(KVMState, (obj), TYPE_KVM_ACCEL)
+
KVMState *kvm_state;
bool kvm_kernel_irqchip;
bool kvm_async_interrupts_allowed;
@@ -1401,7 +1406,7 @@ static int kvm_init(MachineState *ms)
int i, type = 0;
const char *kvm_type;
- s = g_malloc0(sizeof(KVMState));
+ s = KVM_STATE(ms->accelerator);
/*
* On systems where the kernel can support different base page
@@ -1590,7 +1595,6 @@ err:
close(s->fd);
}
g_free(s->slots);
- g_free(s);
return ret;
}
@@ -2242,6 +2246,7 @@ static const TypeInfo kvm_accel_type = {
.name = TYPE_KVM_ACCEL,
.parent = TYPE_ACCEL,
.class_init = kvm_accel_class_init,
+ .instance_size = sizeof(KVMState),
};
static void kvm_type_init(void)
commit ac2da55e01b1a84e6bba32768211201dec230232
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:31 2014 -0300
accel: Create accel object when initializing machine
Create an actual TYPE_ACCEL object when initializing a machine. This
will allow accelerator classes to implement some initialization on
instance_init, and to save state on the TYPE_ACCEL object.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 6087ab3..74e41da 100644
--- a/accel.c
+++ b/accel.c
@@ -32,6 +32,7 @@
#include "sysemu/qtest.h"
#include "hw/xen/xen.h"
#include "qom/object.h"
+#include "hw/boards.h"
int tcg_tb_size;
static bool tcg_allowed = true;
@@ -60,11 +61,17 @@ static AccelClass *accel_find(const char *opt_name)
static int accel_init_machine(AccelClass *acc, MachineState *ms)
{
+ ObjectClass *oc = OBJECT_CLASS(acc);
+ const char *cname = object_class_get_name(oc);
+ AccelState *accel = ACCEL(object_new(cname));
int ret;
+ ms->accelerator = accel;
*(acc->allowed) = true;
ret = acc->init_machine(ms);
if (ret < 0) {
+ ms->accelerator = NULL;
*(acc->allowed) = false;
+ object_unref(OBJECT(accel));
}
return ret;
}
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 0058c49..6a60c3c 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -5,6 +5,7 @@
#include "qemu/typedefs.h"
#include "sysemu/blockdev.h"
+#include "sysemu/accel.h"
#include "hw/qdev.h"
#include "qom/object.h"
@@ -131,6 +132,7 @@ struct MachineState {
char *kernel_cmdline;
char *initrd_filename;
const char *cpu_model;
+ AccelState *accelerator;
};
#endif
commit f6a1ef64408a5f7f52601589fef2a850b93d817e
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:30 2014 -0300
accel: Pass MachineState object to accel init functions
Most of the machine options and machine state information is in the
MachineState object, not on the MachineClass. This will allow init
functions to use the MachineState object directly instead of
qemu_get_machine_opts() or the current_machine global.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index b151d55..6087ab3 100644
--- a/accel.c
+++ b/accel.c
@@ -24,6 +24,7 @@
*/
#include "sysemu/accel.h"
+#include "hw/boards.h"
#include "qemu-common.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
@@ -35,7 +36,7 @@
int tcg_tb_size;
static bool tcg_allowed = true;
-static int tcg_init(MachineClass *mc)
+static int tcg_init(MachineState *ms)
{
tcg_exec_init(tcg_tb_size * 1024 * 1024);
return 0;
@@ -57,18 +58,18 @@ static AccelClass *accel_find(const char *opt_name)
return ac;
}
-static int accel_init_machine(AccelClass *acc, MachineClass *mc)
+static int accel_init_machine(AccelClass *acc, MachineState *ms)
{
int ret;
*(acc->allowed) = true;
- ret = acc->init_machine(mc);
+ ret = acc->init_machine(ms);
if (ret < 0) {
*(acc->allowed) = false;
}
return ret;
}
-int configure_accelerator(MachineClass *mc)
+int configure_accelerator(MachineState *ms)
{
const char *p;
char buf[10];
@@ -98,7 +99,7 @@ int configure_accelerator(MachineClass *mc)
acc->name);
continue;
}
- ret = accel_init_machine(acc, mc);
+ ret = accel_init_machine(acc, ms);
if (ret < 0) {
init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n",
diff --git a/include/hw/boards.h b/include/hw/boards.h
index dfb6718..0058c49 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -9,8 +9,6 @@
#include "qom/object.h"
-typedef struct MachineState MachineState;
-
typedef void QEMUMachineInitFunc(MachineState *ms);
typedef void QEMUMachineResetFunc(void);
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 5f20b0e..04df51b 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -32,6 +32,7 @@ typedef struct MemoryMappingList MemoryMappingList;
typedef struct QEMUMachine QEMUMachine;
typedef struct MachineClass MachineClass;
+typedef struct MachineState MachineState;
typedef struct NICInfo NICInfo;
typedef struct HCIInfo HCIInfo;
typedef struct AudioState AudioState;
diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
index 8812cda..997720f 100644
--- a/include/sysemu/accel.h
+++ b/include/sysemu/accel.h
@@ -39,7 +39,7 @@ typedef struct AccelClass {
const char *opt_name;
const char *name;
int (*available)(void);
- int (*init_machine)(MachineClass *mc);
+ int (*init_machine)(MachineState *ms);
bool *allowed;
} AccelClass;
@@ -57,6 +57,6 @@ typedef struct AccelClass {
extern int tcg_tb_size;
-int configure_accelerator(MachineClass *mc);
+int configure_accelerator(MachineState *ms);
#endif
diff --git a/kvm-all.c b/kvm-all.c
index ce0e4c7..0a9de92 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1380,8 +1380,9 @@ static int kvm_max_vcpus(KVMState *s)
return (ret) ? ret : kvm_recommended_vcpus(s);
}
-static int kvm_init(MachineClass *mc)
+static int kvm_init(MachineState *ms)
{
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
static const char upgrade_note[] =
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
"(see http://sourceforge.net/projects/kvm).\n";
diff --git a/qtest.c b/qtest.c
index 18e26fc..4b85995 100644
--- a/qtest.c
+++ b/qtest.c
@@ -520,7 +520,7 @@ static void configure_qtest_icount(const char *options)
qemu_opts_del(opts);
}
-static int qtest_init_accel(MachineClass *mc)
+static int qtest_init_accel(MachineState *ms)
{
configure_qtest_icount("0");
return 0;
diff --git a/vl.c b/vl.c
index c3def21..020b7c3 100644
--- a/vl.c
+++ b/vl.c
@@ -4179,7 +4179,7 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
- configure_accelerator(machine_class);
+ configure_accelerator(current_machine);
if (qtest_chrdev) {
Error *local_err = NULL;
diff --git a/xen-common.c b/xen-common.c
index acb738f..56359ca 100644
--- a/xen-common.c
+++ b/xen-common.c
@@ -110,7 +110,7 @@ static void xen_change_state_handler(void *opaque, int running,
}
}
-static int xen_init(MachineClass *mc)
+static int xen_init(MachineState *ms)
{
xen_xc = xen_xc_interface_open(0, 0, 0);
if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
commit b6011bd8a57c1eda81a857d21adeb9b66e58b1b0
Merge: 2472b6c 1a1c4db
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Tue Oct 7 10:41:48 2014 +0100
Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20141006-2' into staging
linux-user pull for 2.2
Clearest linux-user patches sent to the list since august,
Apart from Mikhails patch, the rest are quite trivial.
v2: check for CONFIG_TIMERFD only after it has been defined
# gpg: Signature made Mon 06 Oct 2014 20:08:10 BST using RSA key ID DE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio at iki.fi>"
# gpg: aka "Riku Voipio <riku.voipio at linaro.org>"
* remotes/riku/tags/pull-linux-user-20141006-2:
translate-all.c: memory walker initial address miscalculation
linux-user: don't include timerfd if not needed
linux-user: Simplify timerid checks on g_posix_timers range
linux-user: Convert blkpg to use a special subop handler
linux-user: Enable epoll_pwait syscall for ARM
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
commit 1a1c4db9b298956e89caf53b09b6a7a960d55d66
Author: Mikhail Ilyin <m.ilin at samsung.com>
Date: Mon Sep 8 17:28:56 2014 +0400
translate-all.c: memory walker initial address miscalculation
The initial base address is miscalculated in walk_memory_regions().
It has to be shifted TARGET_PAGE_BITS more. Holder variables are
extended to target_ulong size otherwise they don't fit for MIPS N32
(a 32-bit ABI with a 64-bit address space) and qemu won't compile.
The issue led to incorrect debug output of memory maps and a
mis-formed coredumped file.
Signed-off-by: Mikhail Ilyin <m.ilin at samsung.com>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index f9d132f..c085804 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -232,8 +232,8 @@ extern uintptr_t qemu_host_page_mask;
#if defined(CONFIG_USER_ONLY)
void page_dump(FILE *f);
-typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
- abi_ulong, unsigned long);
+typedef int (*walk_memory_regions_fn)(void *, target_ulong,
+ target_ulong, unsigned long);
int walk_memory_regions(void *, walk_memory_regions_fn);
int page_get_flags(target_ulong address);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index bea803b..1c04fcf 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2355,9 +2355,9 @@ struct elf_note_info {
};
struct vm_area_struct {
- abi_ulong vma_start; /* start vaddr of memory region */
- abi_ulong vma_end; /* end vaddr of memory region */
- abi_ulong vma_flags; /* protection etc. flags for the region */
+ target_ulong vma_start; /* start vaddr of memory region */
+ target_ulong vma_end; /* end vaddr of memory region */
+ abi_ulong vma_flags; /* protection etc. flags for the region */
QTAILQ_ENTRY(vm_area_struct) vma_link;
};
@@ -2368,13 +2368,13 @@ struct mm_struct {
static struct mm_struct *vma_init(void);
static void vma_delete(struct mm_struct *);
-static int vma_add_mapping(struct mm_struct *, abi_ulong,
- abi_ulong, abi_ulong);
+static int vma_add_mapping(struct mm_struct *, target_ulong,
+ target_ulong, abi_ulong);
static int vma_get_mapping_count(const struct mm_struct *);
static struct vm_area_struct *vma_first(const struct mm_struct *);
static struct vm_area_struct *vma_next(struct vm_area_struct *);
static abi_ulong vma_dump_size(const struct vm_area_struct *);
-static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
+static int vma_walker(void *priv, target_ulong start, target_ulong end,
unsigned long flags);
static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
@@ -2466,8 +2466,8 @@ static void vma_delete(struct mm_struct *mm)
g_free(mm);
}
-static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
- abi_ulong end, abi_ulong flags)
+static int vma_add_mapping(struct mm_struct *mm, target_ulong start,
+ target_ulong end, abi_ulong flags)
{
struct vm_area_struct *vma;
@@ -2535,7 +2535,7 @@ static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
return (vma->vma_end - vma->vma_start);
}
-static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
+static int vma_walker(void *priv, target_ulong start, target_ulong end,
unsigned long flags)
{
struct mm_struct *mm = (struct mm_struct *)priv;
diff --git a/translate-all.c b/translate-all.c
index 2e0265a..ba5c840 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1660,30 +1660,30 @@ void cpu_interrupt(CPUState *cpu, int mask)
struct walk_memory_regions_data {
walk_memory_regions_fn fn;
void *priv;
- uintptr_t start;
+ target_ulong start;
int prot;
};
static int walk_memory_regions_end(struct walk_memory_regions_data *data,
- abi_ulong end, int new_prot)
+ target_ulong end, int new_prot)
{
- if (data->start != -1ul) {
+ if (data->start != -1u) {
int rc = data->fn(data->priv, data->start, end, data->prot);
if (rc != 0) {
return rc;
}
}
- data->start = (new_prot ? end : -1ul);
+ data->start = (new_prot ? end : -1u);
data->prot = new_prot;
return 0;
}
static int walk_memory_regions_1(struct walk_memory_regions_data *data,
- abi_ulong base, int level, void **lp)
+ target_ulong base, int level, void **lp)
{
- abi_ulong pa;
+ target_ulong pa;
int i, rc;
if (*lp == NULL) {
@@ -1708,7 +1708,7 @@ static int walk_memory_regions_1(struct walk_memory_regions_data *data,
void **pp = *lp;
for (i = 0; i < V_L2_SIZE; ++i) {
- pa = base | ((abi_ulong)i <<
+ pa = base | ((target_ulong)i <<
(TARGET_PAGE_BITS + V_L2_BITS * level));
rc = walk_memory_regions_1(data, pa, level - 1, pp + i);
if (rc != 0) {
@@ -1727,13 +1727,12 @@ int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
data.fn = fn;
data.priv = priv;
- data.start = -1ul;
+ data.start = -1u;
data.prot = 0;
for (i = 0; i < V_L1_SIZE; i++) {
- int rc = walk_memory_regions_1(&data, (abi_ulong)i << V_L1_SHIFT,
+ int rc = walk_memory_regions_1(&data, (target_ulong)i << (V_L1_SHIFT + TARGET_PAGE_BITS),
V_L1_SHIFT / V_L2_BITS - 1, l1_map + i);
-
if (rc != 0) {
return rc;
}
@@ -1742,13 +1741,13 @@ int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
return walk_memory_regions_end(&data, 0, 0);
}
-static int dump_region(void *priv, abi_ulong start,
- abi_ulong end, unsigned long prot)
+static int dump_region(void *priv, target_ulong start,
+ target_ulong end, unsigned long prot)
{
FILE *f = (FILE *)priv;
- (void) fprintf(f, TARGET_ABI_FMT_lx"-"TARGET_ABI_FMT_lx
- " "TARGET_ABI_FMT_lx" %c%c%c\n",
+ (void) fprintf(f, TARGET_FMT_lx"-"TARGET_FMT_lx
+ " "TARGET_FMT_lx" %c%c%c\n",
start, end, end - start,
((prot & PAGE_READ) ? 'r' : '-'),
((prot & PAGE_WRITE) ? 'w' : '-'),
@@ -1760,7 +1759,7 @@ static int dump_region(void *priv, abi_ulong start,
/* dump memory mappings */
void page_dump(FILE *f)
{
- const int length = sizeof(abi_ulong) * 2;
+ const int length = sizeof(target_ulong) * 2;
(void) fprintf(f, "%-*s %-*s %-*s %s\n",
length, "start", length, "end", length, "size", "prot");
walk_memory_regions(f, dump_region);
@@ -1788,7 +1787,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
- assert(end < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+ assert(end < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif
assert(start < end);
@@ -1825,7 +1824,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
- assert(start < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+ assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif
if (len == 0) {
commit d80a1905942afecafc04dba4bf51103cd30d37a1
Author: Riku Voipio <riku.voipio at linaro.org>
Date: Wed Oct 1 16:05:46 2014 +0300
linux-user: don't include timerfd if not needed
Without this, builds on older systems fail with:
qemu/linux-user/syscall.c:61:25: warning: sys/timerfd.h: No such file or directory
v2: fix the usual case where CONFIG_TIMERFD is enabled..
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7087a56..a175cc1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -58,7 +58,6 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/statfs.h>
-#include <sys/timerfd.h>
#include <utime.h>
#include <sys/sysinfo.h>
//#include <sys/user.h>
@@ -67,6 +66,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/wireless.h>
#include <linux/icmp.h>
#include "qemu-common.h"
+#ifdef CONFIG_TIMERFD
+#include <sys/timerfd.h>
+#endif
#ifdef TARGET_GPROF
#include <sys/gmon.h>
#endif
commit e52a99f756eff14935edd1893dc9ec7660078f82
Author: Alexander Graf <agraf at suse.de>
Date: Fri Aug 22 13:56:18 2014 +0200
linux-user: Simplify timerid checks on g_posix_timers range
We check whether the passed in timer id is negative on all calls
that involve g_posix_timers.
However, these checks are bogus. First off we limit the timer_id to
16 bits which is not what Linux does. Then we check whether it's negative
which it can't be because we masked it.
We can safely remove the masking. For the negativity check we can just
treat the timerid as unsigned and only check for upper boundaries.
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dcb9df9..7087a56 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9615,11 +9615,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
{
/* args: timer_t timerid, int flags, const struct itimerspec *new_value,
* struct itimerspec * old_value */
- arg1 &= 0xffff;
- if (arg3 == 0 || arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+ target_ulong timerid = arg1;
+
+ if (arg3 == 0 || timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
- timer_t htimer = g_posix_timers[arg1];
+ timer_t htimer = g_posix_timers[timerid];
struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
target_to_host_itimerspec(&hspec_new, arg3);
@@ -9635,13 +9636,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_gettime:
{
/* args: timer_t timerid, struct itimerspec *curr_value */
- arg1 &= 0xffff;
+ target_ulong timerid = arg1;
+
if (!arg2) {
return -TARGET_EFAULT;
- } else if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+ } else if (timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
- timer_t htimer = g_posix_timers[arg1];
+ timer_t htimer = g_posix_timers[timerid];
struct itimerspec hspec;
ret = get_errno(timer_gettime(htimer, &hspec));
@@ -9657,11 +9659,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_getoverrun:
{
/* args: timer_t timerid */
- arg1 &= 0xffff;
- if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+ target_ulong timerid = arg1;
+
+ if (timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
- timer_t htimer = g_posix_timers[arg1];
+ timer_t htimer = g_posix_timers[timerid];
ret = get_errno(timer_getoverrun(htimer));
}
break;
@@ -9672,13 +9675,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_delete:
{
/* args: timer_t timerid */
- arg1 &= 0xffff;
- if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+ target_ulong timerid = arg1;
+
+ if (timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
- timer_t htimer = g_posix_timers[arg1];
+ timer_t htimer = g_posix_timers[timerid];
ret = get_errno(timer_delete(htimer));
- g_posix_timers[arg1] = 0;
+ g_posix_timers[timerid] = 0;
}
break;
}
commit a59b5e35d181599bc4114ceff3547ef47e713689
Author: Alexander Graf <agraf at suse.de>
Date: Fri Aug 22 13:15:50 2014 +0200
linux-user: Convert blkpg to use a special subop handler
The blkpg ioctl can take different payloads depending on the opcode in
its payload structure. Create a new special ioctl handler that can only
deal with partition style ones for now.
This patch fixes running parted for me.
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 609b27c..e672655 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -78,7 +78,8 @@
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
- IOCTL(BLKPG, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
+ IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
+ MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
#ifdef FIBMAP
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8fe9df7..dcb9df9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3696,6 +3696,59 @@ out:
return ret;
}
+static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
+ abi_long cmd, abi_long arg)
+{
+ void *argptr;
+ int target_size;
+ const argtype *arg_type = ie->arg_type;
+ const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
+ abi_long ret;
+
+ struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
+ struct blkpg_partition host_part;
+
+ /* Read and convert blkpg */
+ arg_type++;
+ target_size = thunk_type_size(arg_type, 0);
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr) {
+ ret = -TARGET_EFAULT;
+ goto out;
+ }
+ thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+ unlock_user(argptr, arg, 0);
+
+ switch (host_blkpg->op) {
+ case BLKPG_ADD_PARTITION:
+ case BLKPG_DEL_PARTITION:
+ /* payload is struct blkpg_partition */
+ break;
+ default:
+ /* Unknown opcode */
+ ret = -TARGET_EINVAL;
+ goto out;
+ }
+
+ /* Read and convert blkpg->data */
+ arg = (abi_long)(uintptr_t)host_blkpg->data;
+ target_size = thunk_type_size(part_arg_type, 0);
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr) {
+ ret = -TARGET_EFAULT;
+ goto out;
+ }
+ thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
+ unlock_user(argptr, arg, 0);
+
+ /* Swizzle the data pointer to our local copy and call! */
+ host_blkpg->data = &host_part;
+ ret = get_errno(ioctl(fd, ie->host_cmd, host_blkpg));
+
+out:
+ return ret;
+}
+
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
int fd, abi_long cmd, abi_long arg)
{
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 9d0c92d..1fd4ee0 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -252,4 +252,4 @@ STRUCT(blkpg_ioctl_arg,
TYPE_INT, /* op */
TYPE_INT, /* flags */
TYPE_INT, /* datalen */
- MK_PTR(MK_STRUCT(STRUCT_blkpg_partition))) /* data */
+ TYPE_PTRVOID) /* data */
commit 40645c7bfd7c4d45381927e1e80081fa827c368a
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Fri Sep 19 02:35:20 2014 +0100
linux-user: Enable epoll_pwait syscall for ARM
We have support for the epoll_pwait syscall, but it wasn't enabled for
ARM guests because we hadn't defined the syscall number; correct this
deficiency.
Reported-by: Dave Flogeras <dflogeras2 at gmail.com>
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index bef847c..7d7be7c 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -350,7 +350,7 @@
#define TARGET_NR_vmsplice (343)
#define TARGET_NR_move_pages (344)
#define TARGET_NR_getcpu (345)
- /* 346 for epoll_pwait */
+#define TARGET_NR_epoll_pwait (346)
#define TARGET_NR_kexec_load (347)
#define TARGET_NR_utimensat (348)
#define TARGET_NR_signalfd (349)
commit 2472b6c07bb50179019589af1c22f43935ab7f5c
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Fri Sep 12 19:04:17 2014 +0100
gdbstub: Allow target CPUs to specify watchpoint STOP_BEFORE_ACCESS flag
GDB assumes that watchpoint set via the gdbstub remote protocol will
behave in the same way as hardware watchpoints for the target. In
particular, whether the CPU stops with the PC before or after the insn
which triggers the watchpoint is target dependent. Allow guest CPU
code to specify which behaviour to use. This fixes a bug where with
guest CPUs which stop before the accessing insn GDB would manually
step forward over what it thought was the insn and end up one insn
further forward than it should be.
We set this flag for the CPU architectures which set
gdbarch_have_nonsteppable_watchpoint in gdb 7.7:
ARM, CRIS, LM32, MIPS and Xtensa.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias at xilinx.com>
Tested-by: Max Filippov <jcmvbkbc at gmail.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias at xilinx.com>
Tested-by: Michael Walle <michael at walle.cc> (for lm32)
Message-id: 1410545057-14014-1-git-send-email-peter.maydell at linaro.org
diff --git a/gdbstub.c b/gdbstub.c
index 71aaa23..d1b5afd 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -625,11 +625,23 @@ void gdb_register_coprocessor(CPUState *cpu,
}
#ifndef CONFIG_USER_ONLY
-static const int xlat_gdb_type[] = {
- [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
- [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
- [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
-};
+/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
+static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
+{
+ static const int xlat[] = {
+ [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
+ [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
+ [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
+ };
+
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+ int cputype = xlat[gdbtype];
+
+ if (cc->gdb_stop_before_watchpoint) {
+ cputype |= BP_STOP_BEFORE_ACCESS;
+ }
+ return cputype;
+}
#endif
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
@@ -656,10 +668,11 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
- err = cpu_watchpoint_insert(cpu, addr, len, xlat_gdb_type[type],
- NULL);
- if (err)
+ err = cpu_watchpoint_insert(cpu, addr, len,
+ xlat_gdb_type(cpu, type), NULL);
+ if (err) {
break;
+ }
}
return err;
#endif
@@ -692,7 +705,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
- err = cpu_watchpoint_remove(cpu, addr, len, xlat_gdb_type[type]);
+ err = cpu_watchpoint_remove(cpu, addr, len,
+ xlat_gdb_type(cpu, type));
if (err)
break;
}
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index f576b47..2098f1c 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -99,6 +99,8 @@ struct TranslationBlock;
* @vmsd: State description for migration.
* @gdb_num_core_regs: Number of core registers accessible to GDB.
* @gdb_core_xml_file: File name for core registers GDB XML description.
+ * @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop
+ * before the insn which triggers a watchpoint rather than after it.
* @cpu_exec_enter: Callback for cpu_exec preparation.
* @cpu_exec_exit: Callback for cpu_exec cleanup.
* @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
@@ -152,6 +154,7 @@ typedef struct CPUClass {
const struct VMStateDescription *vmsd;
int gdb_num_core_regs;
const char *gdb_core_xml_file;
+ bool gdb_stop_before_watchpoint;
void (*cpu_exec_enter)(CPUState *cpu);
void (*cpu_exec_exit)(CPUState *cpu);
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 8ab6d95..edfd586 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -1117,6 +1117,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->gdb_num_core_regs = 26;
cc->gdb_core_xml_file = "arm-core.xml";
+ cc->gdb_stop_before_watchpoint = true;
cc->debug_excp_handler = arm_debug_excp_handler;
}
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 528e458..16cfba9 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -291,6 +291,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->gdb_num_core_regs = 49;
+ cc->gdb_stop_before_watchpoint = true;
}
static const TypeInfo cris_cpu_type_info = {
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 6c5de66..f8081f5 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -273,6 +273,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
cc->vmsd = &vmstate_lm32_cpu;
#endif
cc->gdb_num_core_regs = 32 + 7;
+ cc->gdb_stop_before_watchpoint = true;
cc->debug_excp_handler = lm32_debug_excp_handler;
}
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 5ed60f7..98dc94e 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -151,6 +151,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
#endif
cc->gdb_num_core_regs = 73;
+ cc->gdb_stop_before_watchpoint = true;
}
static const TypeInfo mips_cpu_type_info = {
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 51c41d5..6a5414f 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -147,6 +147,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = xtensa_cpu_set_pc;
cc->gdb_read_register = xtensa_cpu_gdb_read_register;
cc->gdb_write_register = xtensa_cpu_gdb_write_register;
+ cc->gdb_stop_before_watchpoint = true;
#ifndef CONFIG_USER_ONLY
cc->do_unaligned_access = xtensa_cpu_do_unaligned_access;
cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
commit 507ef2f9fab3e67ac6fefda4e20db7fc5f2bc186
Merge: b00a0dd 767c86d
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Mon Oct 6 10:59:55 2014 +0100
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
# gpg: Signature made Sat 04 Oct 2014 21:24:46 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha at redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha at gmail.com>"
* remotes/stefanha/tags/block-pull-request: (23 commits)
blockdev-test: Test device_del after drive_del
blockdev-test: Factor out some common code into helpers
blockdev-test: Simplify by using g_assert_cmpstr()
blockdev-test: Clean up bogus drive_add argument
blockdev-test: Use single rather than double quotes in QMP
drive_del-test: Merge of qdev-monitor-test, blockdev-test
iotests: qemu-img info output for corrupt image
qapi: Add corrupt field to ImageInfoSpecificQCow2
iotests: Use _img_info
util: Emancipate id_wellformed() from QemuOpts
q35/ahci: Pick up -cdrom and -hda options
qtest/bios-tables: Correct Q35 command line
ide: Update ide_drive_get to be HBA agnostic
pc/vl: Add units-per-default-bus property
blockdev: Allow overriding if_max_dev property
blockdev: Orphaned drive search
qemu-iotests: Fix supported cache modes for 052
make check-block: Use default cache modes
Modify qemu_opt_rename to realize renaming all items in opts
vmdk: Fix integer overflow in offset calculation
...
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
commit 767c86d3e752dfc68ff5d018c3b0b63b333371b2
Author: Markus Armbruster <armbru at redhat.com>
Date: Thu Oct 2 16:51:36 2014 +0200
blockdev-test: Test device_del after drive_del
Executed in this order, drive_del and device_del's automatic drive
deletion take notoriously tricky special paths.
[Fixed "an device" -> "a device" typo as requested by Eric Blake.
--Stefan]
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412261496-24455-7-git-send-email-armbru at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 38f8229..53fa969 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -40,6 +40,19 @@ static void drive_del(void)
QDECREF(response);
}
+static void device_del(void)
+{
+ QDict *response;
+
+ /* Complication: ignore DEVICE_DELETED event */
+ qmp_discard_response("{'execute': 'device_del',"
+ " 'arguments': { 'id': 'dev0' } }");
+ response = qmp_receive();
+ g_assert(response);
+ g_assert(qdict_haskey(response, "return"));
+ QDECREF(response);
+}
+
static void test_drive_without_dev(void)
{
/* Start with an empty drive */
@@ -87,6 +100,23 @@ static void test_after_failed_device_add(void)
qtest_end();
}
+static void test_drive_del_device_del(void)
+{
+ /* Start with a drive used by a device that unplugs instantaneously */
+ qtest_start("-drive if=none,id=drive0,file=/dev/null"
+ " -device virtio-scsi-pci"
+ " -device scsi-hd,drive=drive0,id=dev0");
+
+ /*
+ * Delete the drive, and then the device
+ * Doing it in this order takes notoriously tricky special paths
+ */
+ drive_del();
+ device_del();
+
+ qtest_end();
+}
+
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();
@@ -99,6 +129,8 @@ int main(int argc, char **argv)
if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) {
qtest_add_func("/drive_del/after_failed_device_add",
test_after_failed_device_add);
+ qtest_add_func("/blockdev/drive_del_device_del",
+ test_drive_del_device_del);
}
return g_test_run();
commit 2eea5cd452592ac9b31ed498555f36273b3e0a94
Author: Markus Armbruster <armbru at redhat.com>
Date: Thu Oct 2 16:51:35 2014 +0200
blockdev-test: Factor out some common code into helpers
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412261496-24455-6-git-send-email-armbru at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 80917ad..38f8229 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -14,14 +14,23 @@
#include <string.h>
#include "libqtest.h"
-static void test_drive_without_dev(void)
+static void drive_add(void)
{
QDict *response;
- /* Start with an empty drive */
- qtest_start("-drive if=none,id=drive0");
+ response = qmp("{'execute': 'human-monitor-command',"
+ " 'arguments': {"
+ " 'command-line': 'drive_add 0 if=none,id=drive0'"
+ "}}");
+ g_assert(response);
+ g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
+ QDECREF(response);
+}
+
+static void drive_del(void)
+{
+ QDict *response;
- /* Delete the drive */
response = qmp("{'execute': 'human-monitor-command',"
" 'arguments': {"
" 'command-line': 'drive_del drive0'"
@@ -29,17 +38,20 @@ static void test_drive_without_dev(void)
g_assert(response);
g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
QDECREF(response);
+}
+
+static void test_drive_without_dev(void)
+{
+ /* Start with an empty drive */
+ qtest_start("-drive if=none,id=drive0");
+
+ /* Delete the drive */
+ drive_del();
/* Ensure re-adding the drive works - there should be no duplicate ID error
* because the old drive must be gone.
*/
- response = qmp("{'execute': 'human-monitor-command',"
- " 'arguments': {"
- " 'command-line': 'drive_add 0 if=none,id=drive0'"
- "}}");
- g_assert(response);
- g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
- QDECREF(response);
+ drive_add();
qtest_end();
}
@@ -65,24 +77,12 @@ static void test_after_failed_device_add(void)
QDECREF(response);
/* Delete the drive */
- response = qmp("{'execute': 'human-monitor-command',"
- " 'arguments': {"
- " 'command-line': 'drive_del drive0'"
- "}}");
- g_assert(response);
- g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
- QDECREF(response);
+ drive_del();
/* Try to re-add the drive. This fails with duplicate IDs if a leaked
* virtio-blk-pci exists that holds a reference to the old drive0.
*/
- response = qmp("{'execute': 'human-monitor-command',"
- " 'arguments': {"
- " 'command-line': 'drive_add 0 if=none,id=drive0'"
- "}}");
- g_assert(response);
- g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
- QDECREF(response);
+ drive_add();
qtest_end();
}
commit 37e153fe45020c38229a113adc1eda05757e2c37
Author: Markus Armbruster <armbru at redhat.com>
Date: Thu Oct 2 16:51:34 2014 +0200
blockdev-test: Simplify by using g_assert_cmpstr()
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412261496-24455-5-git-send-email-armbru at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 32516a2..80917ad 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -17,7 +17,6 @@
static void test_drive_without_dev(void)
{
QDict *response;
- const char *response_return;
/* Start with an empty drive */
qtest_start("-drive if=none,id=drive0");
@@ -28,9 +27,7 @@ static void test_drive_without_dev(void)
" 'command-line': 'drive_del drive0'"
"}}");
g_assert(response);
- response_return = qdict_get_try_str(response, "return");
- g_assert(response_return);
- g_assert(strcmp(response_return, "") == 0);
+ g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
QDECREF(response);
/* Ensure re-adding the drive works - there should be no duplicate ID error
@@ -41,9 +38,7 @@ static void test_drive_without_dev(void)
" 'command-line': 'drive_add 0 if=none,id=drive0'"
"}}");
g_assert(response);
- response_return = qdict_get_try_str(response, "return");
- g_assert(response_return);
- g_assert(strcmp(response_return, "OK\r\n") == 0);
+ g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
QDECREF(response);
qtest_end();
commit e319df669da92f6ba56595e486637108256da08f
Author: Markus Armbruster <armbru at redhat.com>
Date: Thu Oct 2 16:51:33 2014 +0200
blockdev-test: Clean up bogus drive_add argument
The first argument should be a PCI address, which pci-addr=auto isn't.
Doesn't really matter, as drive_add ignores its first argument when
its second argument has if=none. Clean it up anyway.
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412261496-24455-4-git-send-email-armbru at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index a5de239..32516a2 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -83,7 +83,7 @@ static void test_after_failed_device_add(void)
*/
response = qmp("{'execute': 'human-monitor-command',"
" 'arguments': {"
- " 'command-line': 'drive_add pci-addr=auto if=none,id=drive0'"
+ " 'command-line': 'drive_add 0 if=none,id=drive0'"
"}}");
g_assert(response);
g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
commit d0e386683779f09afe5bf198b957a780c960204b
Author: Markus Armbruster <armbru at redhat.com>
Date: Thu Oct 2 16:51:32 2014 +0200
blockdev-test: Use single rather than double quotes in QMP
QMP accepts both single and double quotes. This is the only test
using double quotes. They need to be quoted in C strings. Replace
them by single quotes.
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412261496-24455-3-git-send-email-armbru at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 39c56fc..a5de239 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -23,9 +23,9 @@ static void test_drive_without_dev(void)
qtest_start("-drive if=none,id=drive0");
/* Delete the drive */
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_del drive0\""
+ response = qmp("{'execute': 'human-monitor-command',"
+ " 'arguments': {"
+ " 'command-line': 'drive_del drive0'"
"}}");
g_assert(response);
response_return = qdict_get_try_str(response, "return");
@@ -36,9 +36,9 @@ static void test_drive_without_dev(void)
/* Ensure re-adding the drive works - there should be no duplicate ID error
* because the old drive must be gone.
*/
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_add 0 if=none,id=drive0\""
+ response = qmp("{'execute': 'human-monitor-command',"
+ " 'arguments': {"
+ " 'command-line': 'drive_add 0 if=none,id=drive0'"
"}}");
g_assert(response);
response_return = qdict_get_try_str(response, "return");
@@ -59,10 +59,10 @@ static void test_after_failed_device_add(void)
/* Make device_add fail. If this leaks the virtio-blk-pci device then a
* reference to drive0 will also be held (via qdev properties).
*/
- response = qmp("{\"execute\": \"device_add\","
- " \"arguments\": {"
- " \"driver\": \"virtio-blk-pci\","
- " \"drive\": \"drive0\""
+ response = qmp("{'execute': 'device_add',"
+ " 'arguments': {"
+ " 'driver': 'virtio-blk-pci',"
+ " 'drive': 'drive0'"
"}}");
g_assert(response);
error = qdict_get_qdict(response, "error");
@@ -70,9 +70,9 @@ static void test_after_failed_device_add(void)
QDECREF(response);
/* Delete the drive */
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_del drive0\""
+ response = qmp("{'execute': 'human-monitor-command',"
+ " 'arguments': {"
+ " 'command-line': 'drive_del drive0'"
"}}");
g_assert(response);
g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
@@ -81,9 +81,9 @@ static void test_after_failed_device_add(void)
/* Try to re-add the drive. This fails with duplicate IDs if a leaked
* virtio-blk-pci exists that holds a reference to the old drive0.
*/
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_add pci-addr=auto if=none,id=drive0\""
+ response = qmp("{'execute': 'human-monitor-command',"
+ " 'arguments': {"
+ " 'command-line': 'drive_add pci-addr=auto if=none,id=drive0'"
"}}");
g_assert(response);
g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
commit e2f3f221885a90de766ce9a38b87badeb658635a
Author: Markus Armbruster <armbru at redhat.com>
Date: Thu Oct 2 16:51:31 2014 +0200
drive_del-test: Merge of qdev-monitor-test, blockdev-test
Each of qdev-monitor-test and blockdev-test has just one test case,
and both are about drive_del.
[Extended copyright from 2013 to 2013-2014 as requested by Eric Blake.
--Stefan]
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412261496-24455-2-git-send-email-armbru at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/Makefile b/tests/Makefile
index 834279c..ffa8312 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -140,8 +140,7 @@ check-qtest-i386-y += tests/bios-tables-test$(EXESUF)
check-qtest-i386-y += tests/rtc-test$(EXESUF)
check-qtest-i386-y += tests/i440fx-test$(EXESUF)
check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
-check-qtest-i386-y += tests/blockdev-test$(EXESUF)
-check-qtest-i386-y += tests/qdev-monitor-test$(EXESUF)
+check-qtest-i386-y += tests/drive_del-test$(EXESUF)
check-qtest-i386-y += tests/wdt_ib700-test$(EXESUF)
gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c
check-qtest-i386-y += $(check-qtest-pci-y)
@@ -335,7 +334,7 @@ tests/tpci200-test$(EXESUF): tests/tpci200-test.o
tests/display-vga-test$(EXESUF): tests/display-vga-test.o
tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
tests/qom-test$(EXESUF): tests/qom-test.o
-tests/blockdev-test$(EXESUF): tests/blockdev-test.o $(libqos-pc-obj-y)
+tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-pc-obj-y)
tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
tests/nvme-test$(EXESUF): tests/nvme-test.o
tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o
diff --git a/tests/blockdev-test.c b/tests/blockdev-test.c
deleted file mode 100644
index c940e00..0000000
--- a/tests/blockdev-test.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * blockdev.c test cases
- *
- * Copyright (C) 2013 Red Hat Inc.
- *
- * Authors:
- * Stefan Hajnoczi <stefanha at redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include <glib.h>
-#include <string.h>
-#include "libqtest.h"
-
-static void test_drive_add_empty(void)
-{
- QDict *response;
- const char *response_return;
-
- /* Start with an empty drive */
- qtest_start("-drive if=none,id=drive0");
-
- /* Delete the drive */
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_del drive0\""
- "}}");
- g_assert(response);
- response_return = qdict_get_try_str(response, "return");
- g_assert(response_return);
- g_assert(strcmp(response_return, "") == 0);
- QDECREF(response);
-
- /* Ensure re-adding the drive works - there should be no duplicate ID error
- * because the old drive must be gone.
- */
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_add 0 if=none,id=drive0\""
- "}}");
- g_assert(response);
- response_return = qdict_get_try_str(response, "return");
- g_assert(response_return);
- g_assert(strcmp(response_return, "OK\r\n") == 0);
- QDECREF(response);
-
- qtest_end();
-}
-
-int main(int argc, char **argv)
-{
- g_test_init(&argc, &argv, NULL);
-
- qtest_add_func("/qmp/drive_add_empty", test_drive_add_empty);
-
- return g_test_run();
-}
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
new file mode 100644
index 0000000..39c56fc
--- /dev/null
+++ b/tests/drive_del-test.c
@@ -0,0 +1,110 @@
+/*
+ * blockdev.c test cases
+ *
+ * Copyright (C) 2013-2014 Red Hat Inc.
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha at redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+
+static void test_drive_without_dev(void)
+{
+ QDict *response;
+ const char *response_return;
+
+ /* Start with an empty drive */
+ qtest_start("-drive if=none,id=drive0");
+
+ /* Delete the drive */
+ response = qmp("{\"execute\": \"human-monitor-command\","
+ " \"arguments\": {"
+ " \"command-line\": \"drive_del drive0\""
+ "}}");
+ g_assert(response);
+ response_return = qdict_get_try_str(response, "return");
+ g_assert(response_return);
+ g_assert(strcmp(response_return, "") == 0);
+ QDECREF(response);
+
+ /* Ensure re-adding the drive works - there should be no duplicate ID error
+ * because the old drive must be gone.
+ */
+ response = qmp("{\"execute\": \"human-monitor-command\","
+ " \"arguments\": {"
+ " \"command-line\": \"drive_add 0 if=none,id=drive0\""
+ "}}");
+ g_assert(response);
+ response_return = qdict_get_try_str(response, "return");
+ g_assert(response_return);
+ g_assert(strcmp(response_return, "OK\r\n") == 0);
+ QDECREF(response);
+
+ qtest_end();
+}
+
+static void test_after_failed_device_add(void)
+{
+ QDict *response;
+ QDict *error;
+
+ qtest_start("-drive if=none,id=drive0");
+
+ /* Make device_add fail. If this leaks the virtio-blk-pci device then a
+ * reference to drive0 will also be held (via qdev properties).
+ */
+ response = qmp("{\"execute\": \"device_add\","
+ " \"arguments\": {"
+ " \"driver\": \"virtio-blk-pci\","
+ " \"drive\": \"drive0\""
+ "}}");
+ g_assert(response);
+ error = qdict_get_qdict(response, "error");
+ g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, "GenericError");
+ QDECREF(response);
+
+ /* Delete the drive */
+ response = qmp("{\"execute\": \"human-monitor-command\","
+ " \"arguments\": {"
+ " \"command-line\": \"drive_del drive0\""
+ "}}");
+ g_assert(response);
+ g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
+ QDECREF(response);
+
+ /* Try to re-add the drive. This fails with duplicate IDs if a leaked
+ * virtio-blk-pci exists that holds a reference to the old drive0.
+ */
+ response = qmp("{\"execute\": \"human-monitor-command\","
+ " \"arguments\": {"
+ " \"command-line\": \"drive_add pci-addr=auto if=none,id=drive0\""
+ "}}");
+ g_assert(response);
+ g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
+ QDECREF(response);
+
+ qtest_end();
+}
+
+int main(int argc, char **argv)
+{
+ const char *arch = qtest_get_arch();
+
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_func("/drive_del/without-dev", test_drive_without_dev);
+
+ /* TODO I guess any arch with PCI would do */
+ if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) {
+ qtest_add_func("/drive_del/after_failed_device_add",
+ test_after_failed_device_add);
+ }
+
+ return g_test_run();
+}
diff --git a/tests/qdev-monitor-test.c b/tests/qdev-monitor-test.c
deleted file mode 100644
index e20ffd6..0000000
--- a/tests/qdev-monitor-test.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * qdev-monitor.c test cases
- *
- * Copyright (C) 2013 Red Hat Inc.
- *
- * Authors:
- * Stefan Hajnoczi <stefanha at redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include <string.h>
-#include <glib.h>
-#include "libqtest.h"
-#include "qapi/qmp/qjson.h"
-
-static void test_device_add(void)
-{
- QDict *response;
- QDict *error;
-
- qtest_start("-drive if=none,id=drive0");
-
- /* Make device_add fail. If this leaks the virtio-blk-pci device then a
- * reference to drive0 will also be held (via qdev properties).
- */
- response = qmp("{\"execute\": \"device_add\","
- " \"arguments\": {"
- " \"driver\": \"virtio-blk-pci\","
- " \"drive\": \"drive0\""
- "}}");
- g_assert(response);
- error = qdict_get_qdict(response, "error");
- g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, "GenericError");
- QDECREF(response);
-
- /* Delete the drive */
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_del drive0\""
- "}}");
- g_assert(response);
- g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
- QDECREF(response);
-
- /* Try to re-add the drive. This fails with duplicate IDs if a leaked
- * virtio-blk-pci exists that holds a reference to the old drive0.
- */
- response = qmp("{\"execute\": \"human-monitor-command\","
- " \"arguments\": {"
- " \"command-line\": \"drive_add pci-addr=auto if=none,id=drive0\""
- "}}");
- g_assert(response);
- g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
- QDECREF(response);
-
- qtest_end();
-}
-
-int main(int argc, char **argv)
-{
- const char *arch = qtest_get_arch();
-
- /* Check architecture */
- if (strcmp(arch, "i386") && strcmp(arch, "x86_64")) {
- g_test_message("Skipping test for non-x86\n");
- return 0;
- }
-
- /* Run the tests */
- g_test_init(&argc, &argv, NULL);
-
- qtest_add_func("/qmp/device_add", test_device_add);
-
- return g_test_run();
-}
commit f383611a0a464e0bd06da9d98ab0d63f987cb885
Author: Max Reitz <mreitz at redhat.com>
Date: Tue Sep 30 21:31:29 2014 +0200
iotests: qemu-img info output for corrupt image
The "corrupt" entry in the format-specific information section should be
"true".
Signed-off-by: Max Reitz <mreitz at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412105489-7681-4-git-send-email-mreitz at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
index 2355567..9772d36 100755
--- a/tests/qemu-iotests/060
+++ b/tests/qemu-iotests/060
@@ -76,6 +76,9 @@ $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
# The corrupt bit must now be set
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+# This information should be available through qemu-img info
+$QEMU_IMG info "$TEST_IMG" | _filter_testdir
+
# Try to open the image R/W (which should fail)
$QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \
| _filter_testdir \
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
index 4f0c6d0..cd679f9 100644
--- a/tests/qemu-iotests/060.out
+++ b/tests/qemu-iotests/060.out
@@ -11,6 +11,15 @@ incompatible_features 0x0
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L1 table); further corruption events will be suppressed
write failed: Input/output error
incompatible_features 0x2
+image: TEST_DIR/t.qcow2
+file format: qcow2
+virtual size: 64M (67108864 bytes)
+disk size: 196K
+cluster_size: 65536
+Format specific information:
+ compat: 1.1
+ lazy refcounts: false
+ corrupt: true
qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
commit 9009b1963c5ed9bb826c8116e8b1d3aa94d47f85
Author: Max Reitz <mreitz at redhat.com>
Date: Tue Sep 30 21:31:28 2014 +0200
qapi: Add corrupt field to ImageInfoSpecificQCow2
Just like lazy-refcounts, this field will be present iff the qcow2
compat level is 1.1 (or probably any future revision).
As expected, this breaks some tests due to the new field present in
qemu-img info output; so fix their output accordingly.
Suggested-by: Eric Blake <eblake at redhat.com>
Signed-off-by: Max Reitz <mreitz at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412105489-7681-3-git-send-email-mreitz at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/block/qcow2.c b/block/qcow2.c
index 778fc1e..fb28493 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2282,6 +2282,9 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
.lazy_refcounts = s->compatible_features &
QCOW2_COMPAT_LAZY_REFCOUNTS,
.has_lazy_refcounts = true,
+ .corrupt = s->incompatible_features &
+ QCOW2_INCOMPAT_CORRUPT,
+ .has_corrupt = true,
};
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index fa2d1b7..8f7089e 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -38,12 +38,16 @@
#
# @lazy-refcounts: #optional on or off; only valid for compat >= 1.1
#
+# @corrupt: #optional true if the image has been marked corrupt; only valid for
+# compat >= 1.1 (since 2.2)
+#
# Since: 1.7
##
{ 'type': 'ImageInfoSpecificQCow2',
'data': {
'compat': 'str',
- '*lazy-refcounts': 'bool'
+ '*lazy-refcounts': 'bool',
+ '*corrupt': 'bool'
} }
##
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
index e89b61d..8d3a9c9 100755
--- a/tests/qemu-iotests/065
+++ b/tests/qemu-iotests/065
@@ -94,28 +94,28 @@ class TestQCow2(TestQemuImgInfo):
class TestQCow3NotLazy(TestQemuImgInfo):
'''Testing a qcow2 version 3 image with lazy refcounts disabled'''
img_options = 'compat=1.1,lazy_refcounts=off'
- json_compare = { 'compat': '1.1', 'lazy-refcounts': False }
- human_compare = [ 'compat: 1.1', 'lazy refcounts: false' ]
+ json_compare = { 'compat': '1.1', 'lazy-refcounts': False, 'corrupt': False }
+ human_compare = [ 'compat: 1.1', 'lazy refcounts: false', 'corrupt: false' ]
class TestQCow3Lazy(TestQemuImgInfo):
'''Testing a qcow2 version 3 image with lazy refcounts enabled'''
img_options = 'compat=1.1,lazy_refcounts=on'
- json_compare = { 'compat': '1.1', 'lazy-refcounts': True }
- human_compare = [ 'compat: 1.1', 'lazy refcounts: true' ]
+ json_compare = { 'compat': '1.1', 'lazy-refcounts': True, 'corrupt': False }
+ human_compare = [ 'compat: 1.1', 'lazy refcounts: true', 'corrupt: false' ]
class TestQCow3NotLazyQMP(TestQMP):
'''Testing a qcow2 version 3 image with lazy refcounts disabled, opening
with lazy refcounts enabled'''
img_options = 'compat=1.1,lazy_refcounts=off'
qemu_options = 'lazy-refcounts=on'
- compare = { 'compat': '1.1', 'lazy-refcounts': False }
+ compare = { 'compat': '1.1', 'lazy-refcounts': False, 'corrupt': False }
class TestQCow3LazyQMP(TestQMP):
'''Testing a qcow2 version 3 image with lazy refcounts enabled, opening
with lazy refcounts disabled'''
img_options = 'compat=1.1,lazy_refcounts=on'
qemu_options = 'lazy-refcounts=off'
- compare = { 'compat': '1.1', 'lazy-refcounts': True }
+ compare = { 'compat': '1.1', 'lazy-refcounts': True, 'corrupt': False }
TestImageInfoSpecific = None
TestQemuImgInfo = None
diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out
index 7e090b9..0f72dcf 100644
--- a/tests/qemu-iotests/067.out
+++ b/tests/qemu-iotests/067.out
@@ -6,7 +6,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virtio-blk-pci,drive=disk,id=virtio0
QMP_VERSION
{"return": {}}
-{"return": [{"io-status": "ok", "device": "disk", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
+{"return": [{"io-status": "ok", "device": "disk", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}}
@@ -24,7 +24,7 @@ QMP_VERSION
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
QMP_VERSION
{"return": {}}
-{"return": [{"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
+{"return": [{"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
{"return": {}}
{"return": {}}
{"return": {}}
@@ -44,7 +44,7 @@ Testing:
QMP_VERSION
{"return": {}}
{"return": "OK\r\n"}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
+{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
{"return": {}}
{"return": {}}
{"return": {}}
@@ -64,14 +64,14 @@ Testing:
QMP_VERSION
{"return": {}}
{"return": {}}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
+{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
{"return": {}}
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
+{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
index 249c5e4..0a3ab5a 100644
--- a/tests/qemu-iotests/082.out
+++ b/tests/qemu-iotests/082.out
@@ -21,6 +21,7 @@ cluster_size: 4096
Format specific information:
compat: 1.1
lazy refcounts: true
+ corrupt: false
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=on
@@ -34,6 +35,7 @@ cluster_size: 8192
Format specific information:
compat: 1.1
lazy refcounts: true
+ corrupt: false
Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=off
@@ -197,6 +199,7 @@ cluster_size: 4096
Format specific information:
compat: 1.1
lazy refcounts: true
+ corrupt: false
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
@@ -209,6 +212,7 @@ cluster_size: 8192
Format specific information:
compat: 1.1
lazy refcounts: true
+ corrupt: false
Testing: convert -O qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
image: TEST_DIR/t.IMGFMT.base
@@ -357,6 +361,7 @@ cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: true
+ corrupt: false
Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2
@@ -369,6 +374,7 @@ cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
+ corrupt: false
Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2
@@ -381,6 +387,7 @@ cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: true
+ corrupt: false
Testing: amend -f qcow2 -o size=4M,size=148M TEST_DIR/t.qcow2
image: TEST_DIR/t.IMGFMT
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
index 4ca2f88..b2b0390 100644
--- a/tests/qemu-iotests/089.out
+++ b/tests/qemu-iotests/089.out
@@ -41,10 +41,12 @@ vm state offset: 512 MiB
Format specific information:
compat: 1.1
lazy refcounts: false
+ corrupt: false
format name: IMGFMT
cluster size: 64 KiB
vm state offset: 512 MiB
Format specific information:
compat: 1.1
lazy refcounts: false
+ corrupt: false
*** done
commit 1b53eab270ee08e61e21c3fcc77e34c4b5484c30
Author: Max Reitz <mreitz at redhat.com>
Date: Tue Sep 30 21:31:27 2014 +0200
iotests: Use _img_info
qemu-img info should only be used directly if the format-specific
information or the name of the format is relevant (some tests explicitly
test format-specific information; test 082 uses qcow2-specific settings
to test the qemu-img interface); otherwise, tests should always use
_img_info instead.
Test 082 was touched only partially. It does test the qemu-img
interface; however, its invocations of qemu-img info are not real tests
but rather verifications, so if format-specific information is not
important for the test, there is no reason not to use _img_info. In
contrast to directly invoking qemu-img info, "qcow2" is replaced by
"IMGFMT"; but as "qcow2" is only mentioned once in test 082 (in
_supported_fmt), I consider this an improvement.
Signed-off-by: Max Reitz <mreitz at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1412105489-7681-2-git-send-email-mreitz at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/qemu-iotests/070 b/tests/qemu-iotests/070
index ea0dae7..d649ddf 100755
--- a/tests/qemu-iotests/070
+++ b/tests/qemu-iotests/070
@@ -77,7 +77,7 @@ _use_sample_img test-disk2vhd.vhdx.bz2
echo
echo "=== Verify image created by Disk2VHD can be opened ==="
-$QEMU_IMG info "$TEST_IMG" 2>&1 | _filter_testdir | _filter_qemu
+_img_info
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/070.out b/tests/qemu-iotests/070.out
index 15f1fc1..ca74383 100644
--- a/tests/qemu-iotests/070.out
+++ b/tests/qemu-iotests/070.out
@@ -20,9 +20,8 @@ read 18874368/18874368 bytes at offset 0
18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
=== Verify image created by Disk2VHD can be opened ===
-image: TEST_DIR/test-disk2vhd.vhdx
-file format: vhdx
+image: TEST_DIR/test-disk2vhd.IMGFMT
+file format: IMGFMT
virtual size: 256M (268435456 bytes)
-disk size: 260M
cluster_size: 2097152
*** done
diff --git a/tests/qemu-iotests/082 b/tests/qemu-iotests/082
index f6eb75f..910b13e 100755
--- a/tests/qemu-iotests/082
+++ b/tests/qemu-iotests/082
@@ -56,7 +56,7 @@ echo === create: Options specified more than once ===
# Last -f should win
run_qemu_img create -f foo -f $IMGFMT "$TEST_IMG" $size
-run_qemu_img info "$TEST_IMG"
+_img_info
# Multiple -o should be merged
run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" $size
@@ -66,7 +66,7 @@ run_qemu_img info "$TEST_IMG"
run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" $size
run_qemu_img info "$TEST_IMG"
run_qemu_img create -f $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" $size
-run_qemu_img info "$TEST_IMG"
+_img_info
echo
echo === create: help for -o ===
@@ -106,11 +106,11 @@ run_qemu_img create -f $IMGFMT "$TEST_IMG" $size
# Last -f should win
run_qemu_img convert -f foo -f $IMGFMT "$TEST_IMG" "$TEST_IMG".base
-run_qemu_img info "$TEST_IMG".base
+TEST_IMG="${TEST_IMG}.base" _img_info
# Last -O should win
run_qemu_img convert -O foo -O $IMGFMT "$TEST_IMG" "$TEST_IMG".base
-run_qemu_img info "$TEST_IMG".base
+TEST_IMG="${TEST_IMG}.base" _img_info
# Multiple -o should be merged
run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" "$TEST_IMG".base
@@ -120,7 +120,7 @@ run_qemu_img info "$TEST_IMG".base
run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" "$TEST_IMG".base
run_qemu_img info "$TEST_IMG".base
run_qemu_img convert -O $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" "$TEST_IMG".base
-run_qemu_img info "$TEST_IMG".base
+TEST_IMG="${TEST_IMG}.base" _img_info
echo
echo === convert: help for -o ===
@@ -167,7 +167,7 @@ run_qemu_img info "$TEST_IMG"
run_qemu_img amend -f $IMGFMT -o size=8M -o lazy_refcounts=on -o size=132M "$TEST_IMG"
run_qemu_img info "$TEST_IMG"
run_qemu_img amend -f $IMGFMT -o size=4M,size=148M "$TEST_IMG"
-run_qemu_img info "$TEST_IMG"
+_img_info
echo
echo === amend: help for -o ===
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
index 90c21c8..249c5e4 100644
--- a/tests/qemu-iotests/082.out
+++ b/tests/qemu-iotests/082.out
@@ -4,16 +4,10 @@ QA output created by 082
Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 196K
cluster_size: 65536
-Format specific information:
- compat: 1.1
- lazy refcounts: false
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=4096 lazy_refcounts=on
@@ -43,16 +37,10 @@ Format specific information:
Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=off
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 28K
cluster_size: 8192
-Format specific information:
- compat: 1.1
- lazy refcounts: false
=== create: help for -o ===
@@ -188,24 +176,15 @@ Testing: create -f qcow2 TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
-
-Testing: info TEST_DIR/t.qcow2.base
-image: TEST_DIR/t.qcow2.base
+image: TEST_DIR/t.IMGFMT.base
file format: raw
virtual size: 128M (134217728 bytes)
-disk size: 0
Testing: convert -O foo -O qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
-
-Testing: info TEST_DIR/t.qcow2.base
-image: TEST_DIR/t.qcow2.base
-file format: qcow2
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 196K
cluster_size: 65536
-Format specific information:
- compat: 1.1
- lazy refcounts: false
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
@@ -232,16 +211,10 @@ Format specific information:
lazy refcounts: true
Testing: convert -O qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
-
-Testing: info TEST_DIR/t.qcow2.base
-image: TEST_DIR/t.qcow2.base
-file format: qcow2
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 28K
cluster_size: 8192
-Format specific information:
- compat: 1.1
- lazy refcounts: false
=== convert: help for -o ===
@@ -410,16 +383,10 @@ Format specific information:
lazy refcounts: true
Testing: amend -f qcow2 -o size=4M,size=148M TEST_DIR/t.qcow2
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 148M (155189248 bytes)
-disk size: 196K
cluster_size: 65536
-Format specific information:
- compat: 1.1
- lazy refcounts: true
=== amend: help for -o ===
diff --git a/tests/qemu-iotests/095 b/tests/qemu-iotests/095
index acc7dbf..6630181 100755
--- a/tests/qemu-iotests/095
+++ b/tests/qemu-iotests/095
@@ -60,7 +60,7 @@ _make_test_img -b "${TEST_IMG}.snp1" $size_larger
echo
echo "=== Base image info before commit and resize ==="
-$QEMU_IMG info "${TEST_IMG}.base" | _filter_testdir
+TEST_IMG="${TEST_IMG}.base" _img_info
echo
echo === Running QEMU Live Commit Test ===
@@ -78,7 +78,7 @@ _send_qemu_cmd $h "{ 'execute': 'block-commit',
echo
echo "=== Base image info after commit and resize ==="
-$QEMU_IMG info "${TEST_IMG}.base" | _filter_testdir
+TEST_IMG="${TEST_IMG}.base" _img_info
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/095.out b/tests/qemu-iotests/095.out
index 5864dda..cc86efa 100644
--- a/tests/qemu-iotests/095.out
+++ b/tests/qemu-iotests/095.out
@@ -4,14 +4,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR/t.IMGFMT.snp1'
=== Base image info before commit and resize ===
-image: TEST_DIR/t.qcow2.base
-file format: qcow2
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
virtual size: 5.0M (5242880 bytes)
-disk size: 196K
cluster_size: 65536
-Format specific information:
- compat: 1.1
- lazy refcounts: false
=== Running QEMU Live Commit Test ===
@@ -20,12 +16,8 @@ Format specific information:
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "test", "len": 104857600, "offset": 104857600, "speed": 0, "type": "commit"}}
=== Base image info after commit and resize ===
-image: TEST_DIR/t.qcow2.base
-file format: qcow2
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
virtual size: 100M (104857600 bytes)
-disk size: 196K
cluster_size: 65536
-Format specific information:
- compat: 1.1
- lazy refcounts: false
*** done
commit 0d15da8e6fc3cbcd088476c561dcc88b9aae493a
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:29 2014 -0300
accel: Rename 'init' method to 'init_machine'
Today, all accelerator init functions affect some global state:
* tcg_init() calls tcg_exec_init() and affects globals such as tcg_tcx,
page size globals, and possibly others;
* kvm_init() changes the kvm_state global, cpu_interrupt_handler, and possibly
others;
* xen_init() changes the xen_xc global, and registers a change state handler.
With the new accelerator QOM classes, initialization may now be split in two
steps:
* instance_init() will do basic initialization that doesn't affect any global
state and don't need MachineState or MachineClass data. This will allow
probing code to safely create multiple accelerator objects on the fly just
for reporting host/accelerator capabilities, for example.
* accel_init_machine()/init_machine() will save the accelerator object in
MachineState, and do initialization steps which still affect global state,
machine state, or that need data from MachineClass or MachineState.
To clarify the difference between those two steps, rename init() to
init_machine().
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 9241967..b151d55 100644
--- a/accel.c
+++ b/accel.c
@@ -57,11 +57,11 @@ static AccelClass *accel_find(const char *opt_name)
return ac;
}
-static int accel_init(AccelClass *acc, MachineClass *mc)
+static int accel_init_machine(AccelClass *acc, MachineClass *mc)
{
int ret;
*(acc->allowed) = true;
- ret = acc->init(mc);
+ ret = acc->init_machine(mc);
if (ret < 0) {
*(acc->allowed) = false;
}
@@ -98,7 +98,7 @@ int configure_accelerator(MachineClass *mc)
acc->name);
continue;
}
- ret = accel_init(acc, mc);
+ ret = accel_init_machine(acc, mc);
if (ret < 0) {
init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n",
@@ -128,7 +128,7 @@ static void tcg_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "tcg";
- ac->init = tcg_init;
+ ac->init_machine = tcg_init;
ac->allowed = &tcg_allowed;
}
diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
index 120ca0e..8812cda 100644
--- a/include/sysemu/accel.h
+++ b/include/sysemu/accel.h
@@ -39,7 +39,7 @@ typedef struct AccelClass {
const char *opt_name;
const char *name;
int (*available)(void);
- int (*init)(MachineClass *mc);
+ int (*init_machine)(MachineClass *mc);
bool *allowed;
} AccelClass;
diff --git a/kvm-all.c b/kvm-all.c
index 18dcd45..ce0e4c7 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -2233,7 +2233,7 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "KVM";
- ac->init = kvm_init;
+ ac->init_machine = kvm_init;
ac->allowed = &kvm_allowed;
}
diff --git a/qtest.c b/qtest.c
index 0af8b74..18e26fc 100644
--- a/qtest.c
+++ b/qtest.c
@@ -564,7 +564,7 @@ static void qtest_accel_class_init(ObjectClass *oc, void *data)
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "QTest";
ac->available = qtest_available;
- ac->init = qtest_init_accel;
+ ac->init_machine = qtest_init_accel;
ac->allowed = &qtest_allowed;
}
diff --git a/xen-common.c b/xen-common.c
index acc64d5..acb738f 100644
--- a/xen-common.c
+++ b/xen-common.c
@@ -126,7 +126,7 @@ static void xen_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "Xen";
- ac->init = xen_init;
+ ac->init_machine = xen_init;
ac->allowed = &xen_allowed;
}
commit d95c8527e9662a54a8f98c2ced35736604b1b253
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:28 2014 -0300
accel: Move accel init/allowed code to separate function
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 0f3fcee..9241967 100644
--- a/accel.c
+++ b/accel.c
@@ -57,6 +57,17 @@ static AccelClass *accel_find(const char *opt_name)
return ac;
}
+static int accel_init(AccelClass *acc, MachineClass *mc)
+{
+ int ret;
+ *(acc->allowed) = true;
+ ret = acc->init(mc);
+ if (ret < 0) {
+ *(acc->allowed) = false;
+ }
+ return ret;
+}
+
int configure_accelerator(MachineClass *mc)
{
const char *p;
@@ -87,14 +98,12 @@ int configure_accelerator(MachineClass *mc)
acc->name);
continue;
}
- *(acc->allowed) = true;
- ret = acc->init(mc);
+ ret = accel_init(acc, mc);
if (ret < 0) {
init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n",
acc->name,
strerror(-ret));
- *(acc->allowed) = false;
} else {
accel_initialised = true;
}
commit 32592e112fc9da1e4f6b48896e6473c49043d5dd
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:27 2014 -0300
accel: Remove tcg_available() function
As the function always return 1, it is not needed anymore.
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 2cf47337..0f3fcee 100644
--- a/accel.c
+++ b/accel.c
@@ -119,7 +119,6 @@ static void tcg_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "tcg";
- ac->available = tcg_available;
ac->init = tcg_init;
ac->allowed = &tcg_allowed;
}
diff --git a/arch_init.c b/arch_init.c
index c974f3f..9b3e25d 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1337,11 +1337,6 @@ void cpudef_init(void)
#endif
}
-int tcg_available(void)
-{
- return 1;
-}
-
int kvm_available(void)
{
#ifdef CONFIG_KVM
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 769ec06..54b36c1 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -33,7 +33,6 @@ void do_smbios_option(QemuOpts *opts);
void ram_mig_init(void);
void cpudef_init(void);
void audio_init(void);
-int tcg_available(void);
int kvm_available(void);
int xen_available(void);
commit 3a6ce5147f1273a5eec6a82fac9c8e6d085c1247
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:26 2014 -0300
accel: Move qtest accel registration to qtest.c
As qtest_availble() returns 1 only when CONFIG_POSIX is set, keep
setting AccelClass.available to keep current behavior (this is different
from what we did for KVM and Xen).
This also allows us to make qtest_init_accel() static.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 2cefbb0..2cf47337 100644
--- a/accel.c
+++ b/accel.c
@@ -132,28 +132,10 @@ static const TypeInfo tcg_accel_type = {
.class_init = tcg_accel_class_init,
};
-static void qtest_accel_class_init(ObjectClass *oc, void *data)
-{
- AccelClass *ac = ACCEL_CLASS(oc);
- ac->name = "QTest";
- ac->available = qtest_available;
- ac->init = qtest_init_accel;
- ac->allowed = &qtest_allowed;
-}
-
-#define TYPE_QTEST_ACCEL ACCEL_CLASS_NAME("qtest")
-
-static const TypeInfo qtest_accel_type = {
- .name = TYPE_QTEST_ACCEL,
- .parent = TYPE_ACCEL,
- .class_init = qtest_accel_class_init,
-};
-
static void register_accel_types(void)
{
type_register_static(&accel_type);
type_register_static(&tcg_accel_type);
- type_register_static(&qtest_accel_type);
}
type_init(register_accel_types);
diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index 95c9ade..05473b7 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -26,7 +26,6 @@ static inline bool qtest_enabled(void)
bool qtest_driver(void);
-int qtest_init_accel(MachineClass *mc);
void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
static inline int qtest_available(void)
diff --git a/qtest.c b/qtest.c
index ef0d991..0af8b74 100644
--- a/qtest.c
+++ b/qtest.c
@@ -17,6 +17,7 @@
#include "exec/ioport.h"
#include "exec/memory.h"
#include "hw/irq.h"
+#include "sysemu/accel.h"
#include "sysemu/sysemu.h"
#include "sysemu/cpus.h"
#include "qemu/config-file.h"
@@ -519,7 +520,7 @@ static void configure_qtest_icount(const char *options)
qemu_opts_del(opts);
}
-int qtest_init_accel(MachineClass *mc)
+static int qtest_init_accel(MachineClass *mc)
{
configure_qtest_icount("0");
return 0;
@@ -557,3 +558,27 @@ bool qtest_driver(void)
{
return qtest_chr;
}
+
+static void qtest_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelClass *ac = ACCEL_CLASS(oc);
+ ac->name = "QTest";
+ ac->available = qtest_available;
+ ac->init = qtest_init_accel;
+ ac->allowed = &qtest_allowed;
+}
+
+#define TYPE_QTEST_ACCEL ACCEL_CLASS_NAME("qtest")
+
+static const TypeInfo qtest_accel_type = {
+ .name = TYPE_QTEST_ACCEL,
+ .parent = TYPE_ACCEL,
+ .class_init = qtest_accel_class_init,
+};
+
+static void qtest_type_init(void)
+{
+ type_register_static(&qtest_accel_type);
+}
+
+type_init(qtest_type_init);
commit b152b05a35acc0ff3da5648fd5cb97136853838c
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:25 2014 -0300
accel: Move Xen registration code to xen-common.c
Note that this has an user-visible side-effect: instead of reporting
"Xen is not supported for this target", QEMU binaries not supporting Xen
will report "xen accelerator does not exist".
As xen_available() always return 1 when CONFIG_XEN is enabled, we don't
need to set AccelClass.available anymore. xen_enabled() is not being
removed yet, but only because vl.c is still using it.
This also allows us to make xen_init() static.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index a20e427..2cefbb0 100644
--- a/accel.c
+++ b/accel.c
@@ -132,23 +132,6 @@ static const TypeInfo tcg_accel_type = {
.class_init = tcg_accel_class_init,
};
-static void xen_accel_class_init(ObjectClass *oc, void *data)
-{
- AccelClass *ac = ACCEL_CLASS(oc);
- ac->name = "Xen";
- ac->available = xen_available;
- ac->init = xen_init;
- ac->allowed = &xen_allowed;
-}
-
-#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
-
-static const TypeInfo xen_accel_type = {
- .name = TYPE_XEN_ACCEL,
- .parent = TYPE_ACCEL,
- .class_init = xen_accel_class_init,
-};
-
static void qtest_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
@@ -170,7 +153,6 @@ static void register_accel_types(void)
{
type_register_static(&accel_type);
type_register_static(&tcg_accel_type);
- type_register_static(&xen_accel_type);
type_register_static(&qtest_accel_type);
}
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index f71f2d8..b0ed04c 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -36,7 +36,6 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
qemu_irq *xen_interrupt_controller_init(void);
-int xen_init(MachineClass *mc);
void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
diff --git a/xen-common-stub.c b/xen-common-stub.c
index bd56ca2..906f991 100644
--- a/xen-common-stub.c
+++ b/xen-common-stub.c
@@ -11,9 +11,3 @@
void xenstore_store_pv_console_info(int i, CharDriverState *chr)
{
}
-
-int xen_init(MachineClass *mc)
-{
- return -ENOSYS;
-}
-
diff --git a/xen-common.c b/xen-common.c
index f07b35e..acc64d5 100644
--- a/xen-common.c
+++ b/xen-common.c
@@ -11,6 +11,7 @@
#include "hw/xen/xen_backend.h"
#include "qmp-commands.h"
#include "sysemu/char.h"
+#include "sysemu/accel.h"
//#define DEBUG_XEN
@@ -109,7 +110,7 @@ static void xen_change_state_handler(void *opaque, int running,
}
}
-int xen_init(MachineClass *mc)
+static int xen_init(MachineClass *mc)
{
xen_xc = xen_xc_interface_open(0, 0, 0);
if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
@@ -121,3 +122,25 @@ int xen_init(MachineClass *mc)
return 0;
}
+static void xen_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelClass *ac = ACCEL_CLASS(oc);
+ ac->name = "Xen";
+ ac->init = xen_init;
+ ac->allowed = &xen_allowed;
+}
+
+#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
+
+static const TypeInfo xen_accel_type = {
+ .name = TYPE_XEN_ACCEL,
+ .parent = TYPE_ACCEL,
+ .class_init = xen_accel_class_init,
+};
+
+static void xen_type_init(void)
+{
+ type_register_static(&xen_accel_type);
+}
+
+type_init(xen_type_init);
commit 782c3f2939a8faefa4c5a324dfb472a534048510
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:24 2014 -0300
accel: Move KVM accel registration to kvm-all.c
Note that this has an user-visible side-effect: instead of reporting
"KVM is not supported for this target", QEMU binaries not supporting KVM
will report "kvm accelerator does not exist".
As kvm_availble() always return 1 when CONFIG_KVM is enabled, we don't
need to set AccelClass.available anymore. kvm_enabled() is not being
completely removed yet only because qmp_query_kvm() still uses it.
This also allows us to make kvm_init() static.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index fce6eab..a20e427 100644
--- a/accel.c
+++ b/accel.c
@@ -149,23 +149,6 @@ static const TypeInfo xen_accel_type = {
.class_init = xen_accel_class_init,
};
-static void kvm_accel_class_init(ObjectClass *oc, void *data)
-{
- AccelClass *ac = ACCEL_CLASS(oc);
- ac->name = "KVM";
- ac->available = kvm_available;
- ac->init = kvm_init;
- ac->allowed = &kvm_allowed;
-}
-
-#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
-
-static const TypeInfo kvm_accel_type = {
- .name = TYPE_KVM_ACCEL,
- .parent = TYPE_ACCEL,
- .class_init = kvm_accel_class_init,
-};
-
static void qtest_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
@@ -188,7 +171,6 @@ static void register_accel_types(void)
type_register_static(&accel_type);
type_register_static(&tcg_accel_type);
type_register_static(&xen_accel_type);
- type_register_static(&kvm_accel_type);
type_register_static(&qtest_accel_type);
}
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 77ee240..b0cd657 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -163,8 +163,6 @@ extern KVMState *kvm_state;
/* external API */
-int kvm_init(MachineClass *mc);
-
int kvm_has_sync_mmu(void);
int kvm_has_vcpu_events(void);
int kvm_has_robust_singlestep(void);
diff --git a/kvm-all.c b/kvm-all.c
index 4afcd05..18dcd45 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -25,6 +25,7 @@
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "sysemu/sysemu.h"
+#include "sysemu/accel.h"
#include "hw/hw.h"
#include "hw/pci/msi.h"
#include "hw/s390x/adapter.h"
@@ -106,6 +107,8 @@ struct KVMState
#endif
};
+#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
+
KVMState *kvm_state;
bool kvm_kernel_irqchip;
bool kvm_async_interrupts_allowed;
@@ -1377,7 +1380,7 @@ static int kvm_max_vcpus(KVMState *s)
return (ret) ? ret : kvm_recommended_vcpus(s);
}
-int kvm_init(MachineClass *mc)
+static int kvm_init(MachineClass *mc)
{
static const char upgrade_note[] =
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
@@ -2225,3 +2228,24 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target)
}
return r;
}
+
+static void kvm_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelClass *ac = ACCEL_CLASS(oc);
+ ac->name = "KVM";
+ ac->init = kvm_init;
+ ac->allowed = &kvm_allowed;
+}
+
+static const TypeInfo kvm_accel_type = {
+ .name = TYPE_KVM_ACCEL,
+ .parent = TYPE_ACCEL,
+ .class_init = kvm_accel_class_init,
+};
+
+static void kvm_type_init(void)
+{
+ type_register_static(&kvm_accel_type);
+}
+
+type_init(kvm_type_init);
diff --git a/kvm-stub.c b/kvm-stub.c
index 8e7737c..43fc0dd 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -35,11 +35,6 @@ int kvm_init_vcpu(CPUState *cpu)
return -ENOSYS;
}
-int kvm_init(MachineClass *mc)
-{
- return -ENOSYS;
-}
-
void kvm_flush_coalesced_mmio_buffer(void)
{
}
commit b31f9acaaa9ddc5d0725efc2994b0d802d67ea38
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:23 2014 -0300
accel: Report unknown accelerator as "not found" instead of "does not exist"
As the accelerator classes won't be registered anymore if they are not
enabled at compile time, saying "does not exist" may be misleading, as
the accelerator may be simply disabled. Change the wording to just say
"not found".
Suggested-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 85177f1..fce6eab 100644
--- a/accel.c
+++ b/accel.c
@@ -79,7 +79,7 @@ int configure_accelerator(MachineClass *mc)
p = get_opt_name(buf, sizeof(buf), p, ':');
acc = accel_find(buf);
if (!acc) {
- fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
+ fprintf(stderr, "\"%s\" accelerator not found.\n", buf);
continue;
}
if (acc->available && !acc->available()) {
commit f6dfb83547d0cf5aa938cce391ba33c32a97bed9
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:22 2014 -0300
accel: Make AccelClass.available() optional
When we move accel classes outside accel.c, the available() function
won't be necessary anymore, because the classes will be registered only
if the accelerator code is really enabled at build time.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index a3e2fd9..85177f1 100644
--- a/accel.c
+++ b/accel.c
@@ -82,7 +82,7 @@ int configure_accelerator(MachineClass *mc)
fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
continue;
}
- if (!acc->available()) {
+ if (acc->available && !acc->available()) {
printf("%s not supported for this target\n",
acc->name);
continue;
commit b14a0b7469fa3e6c26d18438531d26138c55b67e
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:21 2014 -0300
accel: Use QOM classes for accel types
Instead of having a static AccelType array, register a class for each
accelerator type, and use class name lookup to find accelerator
information.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index c752fcc..a3e2fd9 100644
--- a/accel.c
+++ b/accel.c
@@ -30,6 +30,7 @@
#include "sysemu/kvm.h"
#include "sysemu/qtest.h"
#include "hw/xen/xen.h"
+#include "qom/object.h"
int tcg_tb_size;
static bool tcg_allowed = true;
@@ -40,32 +41,20 @@ static int tcg_init(MachineClass *mc)
return 0;
}
-typedef struct AccelType {
- const char *opt_name;
- const char *name;
- int (*available)(void);
- int (*init)(MachineClass *mc);
- bool *allowed;
-} AccelType;
-
-static AccelType accel_list[] = {
- { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
- { "xen", "Xen", xen_available, xen_init, &xen_allowed },
- { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
- { "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
+static const TypeInfo accel_type = {
+ .name = TYPE_ACCEL,
+ .parent = TYPE_OBJECT,
+ .class_size = sizeof(AccelClass),
+ .instance_size = sizeof(AccelState),
};
-/* Lookup AccelType from opt_name. Returns NULL if not found */
-static AccelType *accel_find(const char *opt_name)
+/* Lookup AccelClass from opt_name. Returns NULL if not found */
+static AccelClass *accel_find(const char *opt_name)
{
- int i;
- for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
- AccelType *acc = &accel_list[i];
- if (acc->opt_name && strcmp(acc->opt_name, opt_name) == 0) {
- return acc;
- }
- }
- return NULL;
+ char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
+ AccelClass *ac = ACCEL_CLASS(object_class_by_name(class_name));
+ g_free(class_name);
+ return ac;
}
int configure_accelerator(MachineClass *mc)
@@ -75,7 +64,7 @@ int configure_accelerator(MachineClass *mc)
int ret;
bool accel_initialised = false;
bool init_failed = false;
- AccelType *acc = NULL;
+ AccelClass *acc = NULL;
p = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (p == NULL) {
@@ -124,3 +113,83 @@ int configure_accelerator(MachineClass *mc)
return !accel_initialised;
}
+
+
+static void tcg_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelClass *ac = ACCEL_CLASS(oc);
+ ac->name = "tcg";
+ ac->available = tcg_available;
+ ac->init = tcg_init;
+ ac->allowed = &tcg_allowed;
+}
+
+#define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg")
+
+static const TypeInfo tcg_accel_type = {
+ .name = TYPE_TCG_ACCEL,
+ .parent = TYPE_ACCEL,
+ .class_init = tcg_accel_class_init,
+};
+
+static void xen_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelClass *ac = ACCEL_CLASS(oc);
+ ac->name = "Xen";
+ ac->available = xen_available;
+ ac->init = xen_init;
+ ac->allowed = &xen_allowed;
+}
+
+#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
+
+static const TypeInfo xen_accel_type = {
+ .name = TYPE_XEN_ACCEL,
+ .parent = TYPE_ACCEL,
+ .class_init = xen_accel_class_init,
+};
+
+static void kvm_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelClass *ac = ACCEL_CLASS(oc);
+ ac->name = "KVM";
+ ac->available = kvm_available;
+ ac->init = kvm_init;
+ ac->allowed = &kvm_allowed;
+}
+
+#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
+
+static const TypeInfo kvm_accel_type = {
+ .name = TYPE_KVM_ACCEL,
+ .parent = TYPE_ACCEL,
+ .class_init = kvm_accel_class_init,
+};
+
+static void qtest_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelClass *ac = ACCEL_CLASS(oc);
+ ac->name = "QTest";
+ ac->available = qtest_available;
+ ac->init = qtest_init_accel;
+ ac->allowed = &qtest_allowed;
+}
+
+#define TYPE_QTEST_ACCEL ACCEL_CLASS_NAME("qtest")
+
+static const TypeInfo qtest_accel_type = {
+ .name = TYPE_QTEST_ACCEL,
+ .parent = TYPE_ACCEL,
+ .class_init = qtest_accel_class_init,
+};
+
+static void register_accel_types(void)
+{
+ type_register_static(&accel_type);
+ type_register_static(&tcg_accel_type);
+ type_register_static(&xen_accel_type);
+ type_register_static(&kvm_accel_type);
+ type_register_static(&qtest_accel_type);
+}
+
+type_init(register_accel_types);
diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
index 5537d74..120ca0e 100644
--- a/include/sysemu/accel.h
+++ b/include/sysemu/accel.h
@@ -24,6 +24,36 @@
#define HW_ACCEL_H
#include "qemu/typedefs.h"
+#include "qom/object.h"
+
+typedef struct AccelState {
+ /*< private >*/
+ Object parent_obj;
+} AccelState;
+
+typedef struct AccelClass {
+ /*< private >*/
+ ObjectClass parent_class;
+ /*< public >*/
+
+ const char *opt_name;
+ const char *name;
+ int (*available)(void);
+ int (*init)(MachineClass *mc);
+ bool *allowed;
+} AccelClass;
+
+#define TYPE_ACCEL "accel"
+
+#define ACCEL_CLASS_SUFFIX "-" TYPE_ACCEL
+#define ACCEL_CLASS_NAME(a) (a ACCEL_CLASS_SUFFIX)
+
+#define ACCEL_CLASS(klass) \
+ OBJECT_CLASS_CHECK(AccelClass, (klass), TYPE_ACCEL)
+#define ACCEL(obj) \
+ OBJECT_CHECK(AccelState, (obj), TYPE_ACCEL)
+#define ACCEL_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(AccelClass, (obj), TYPE_ACCEL)
extern int tcg_tb_size;
commit a22465520060951e70124729521318a559a3fe88
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:20 2014 -0300
accel: Move accel name lookup to separate function
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index fc8c551..c752fcc 100644
--- a/accel.c
+++ b/accel.c
@@ -55,11 +55,24 @@ static AccelType accel_list[] = {
{ "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
};
+/* Lookup AccelType from opt_name. Returns NULL if not found */
+static AccelType *accel_find(const char *opt_name)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
+ AccelType *acc = &accel_list[i];
+ if (acc->opt_name && strcmp(acc->opt_name, opt_name) == 0) {
+ return acc;
+ }
+ }
+ return NULL;
+}
+
int configure_accelerator(MachineClass *mc)
{
const char *p;
char buf[10];
- int i, ret;
+ int ret;
bool accel_initialised = false;
bool init_failed = false;
AccelType *acc = NULL;
@@ -75,30 +88,26 @@ int configure_accelerator(MachineClass *mc)
p++;
}
p = get_opt_name(buf, sizeof(buf), p, ':');
- for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
- acc = &accel_list[i];
- if (strcmp(acc->opt_name, buf) == 0) {
- if (!acc->available()) {
- printf("%s not supported for this target\n",
- acc->name);
- break;
- }
- *(acc->allowed) = true;
- ret = acc->init(mc);
- if (ret < 0) {
- init_failed = true;
- fprintf(stderr, "failed to initialize %s: %s\n",
- acc->name,
- strerror(-ret));
- *(acc->allowed) = false;
- } else {
- accel_initialised = true;
- }
- break;
- }
- }
- if (i == ARRAY_SIZE(accel_list)) {
+ acc = accel_find(buf);
+ if (!acc) {
fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
+ continue;
+ }
+ if (!acc->available()) {
+ printf("%s not supported for this target\n",
+ acc->name);
+ continue;
+ }
+ *(acc->allowed) = true;
+ ret = acc->init(mc);
+ if (ret < 0) {
+ init_failed = true;
+ fprintf(stderr, "failed to initialize %s: %s\n",
+ acc->name,
+ strerror(-ret));
+ *(acc->allowed) = false;
+ } else {
+ accel_initialised = true;
}
}
commit e8b466ef95637e083b8c962476e38dd640f360f1
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:19 2014 -0300
accel: Simplify configure_accelerator() using AccelType *acc variable
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 3cefd74..fc8c551 100644
--- a/accel.c
+++ b/accel.c
@@ -62,6 +62,7 @@ int configure_accelerator(MachineClass *mc)
int i, ret;
bool accel_initialised = false;
bool init_failed = false;
+ AccelType *acc = NULL;
p = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (p == NULL) {
@@ -75,20 +76,21 @@ int configure_accelerator(MachineClass *mc)
}
p = get_opt_name(buf, sizeof(buf), p, ':');
for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
- if (strcmp(accel_list[i].opt_name, buf) == 0) {
- if (!accel_list[i].available()) {
+ acc = &accel_list[i];
+ if (strcmp(acc->opt_name, buf) == 0) {
+ if (!acc->available()) {
printf("%s not supported for this target\n",
- accel_list[i].name);
+ acc->name);
break;
}
- *(accel_list[i].allowed) = true;
- ret = accel_list[i].init(mc);
+ *(acc->allowed) = true;
+ ret = acc->init(mc);
if (ret < 0) {
init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n",
- accel_list[i].name,
+ acc->name,
strerror(-ret));
- *(accel_list[i].allowed) = false;
+ *(acc->allowed) = false;
} else {
accel_initialised = true;
}
@@ -108,7 +110,7 @@ int configure_accelerator(MachineClass *mc)
}
if (init_failed) {
- fprintf(stderr, "Back to %s accelerator.\n", accel_list[i].name);
+ fprintf(stderr, "Back to %s accelerator.\n", acc->name);
}
return !accel_initialised;
commit e54adde6154fc86e52abb911e7c0604c9dc7a58a
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:18 2014 -0300
accel: Create AccelType typedef
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/accel.c b/accel.c
index 9424796..3cefd74 100644
--- a/accel.c
+++ b/accel.c
@@ -40,13 +40,15 @@ static int tcg_init(MachineClass *mc)
return 0;
}
-static struct {
+typedef struct AccelType {
const char *opt_name;
const char *name;
int (*available)(void);
int (*init)(MachineClass *mc);
bool *allowed;
-} accel_list[] = {
+} AccelType;
+
+static AccelType accel_list[] = {
{ "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
{ "xen", "Xen", xen_available, xen_init, &xen_allowed },
{ "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
commit a1a9cb0ccd9aa6f0afcf151006fd981ec39ffa15
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:17 2014 -0300
accel: Move accel code to accel.c
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/Makefile.objs b/Makefile.objs
index 97db978..add8375 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -62,6 +62,7 @@ common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
common-obj-y += audio/
common-obj-y += hw/
+common-obj-y += accel.o
common-obj-y += ui/
common-obj-y += bt-host.o bt-vhci.o
diff --git a/accel.c b/accel.c
new file mode 100644
index 0000000..9424796
--- /dev/null
+++ b/accel.c
@@ -0,0 +1,113 @@
+/*
+ * QEMU System Emulator, accelerator interfaces
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2014 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "sysemu/accel.h"
+#include "qemu-common.h"
+#include "sysemu/arch_init.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
+#include "sysemu/qtest.h"
+#include "hw/xen/xen.h"
+
+int tcg_tb_size;
+static bool tcg_allowed = true;
+
+static int tcg_init(MachineClass *mc)
+{
+ tcg_exec_init(tcg_tb_size * 1024 * 1024);
+ return 0;
+}
+
+static struct {
+ const char *opt_name;
+ const char *name;
+ int (*available)(void);
+ int (*init)(MachineClass *mc);
+ bool *allowed;
+} accel_list[] = {
+ { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
+ { "xen", "Xen", xen_available, xen_init, &xen_allowed },
+ { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
+ { "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
+};
+
+int configure_accelerator(MachineClass *mc)
+{
+ const char *p;
+ char buf[10];
+ int i, ret;
+ bool accel_initialised = false;
+ bool init_failed = false;
+
+ p = qemu_opt_get(qemu_get_machine_opts(), "accel");
+ if (p == NULL) {
+ /* Use the default "accelerator", tcg */
+ p = "tcg";
+ }
+
+ while (!accel_initialised && *p != '\0') {
+ if (*p == ':') {
+ p++;
+ }
+ p = get_opt_name(buf, sizeof(buf), p, ':');
+ for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
+ if (strcmp(accel_list[i].opt_name, buf) == 0) {
+ if (!accel_list[i].available()) {
+ printf("%s not supported for this target\n",
+ accel_list[i].name);
+ break;
+ }
+ *(accel_list[i].allowed) = true;
+ ret = accel_list[i].init(mc);
+ if (ret < 0) {
+ init_failed = true;
+ fprintf(stderr, "failed to initialize %s: %s\n",
+ accel_list[i].name,
+ strerror(-ret));
+ *(accel_list[i].allowed) = false;
+ } else {
+ accel_initialised = true;
+ }
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(accel_list)) {
+ fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
+ }
+ }
+
+ if (!accel_initialised) {
+ if (!init_failed) {
+ fprintf(stderr, "No accelerator found!\n");
+ }
+ exit(1);
+ }
+
+ if (init_failed) {
+ fprintf(stderr, "Back to %s accelerator.\n", accel_list[i].name);
+ }
+
+ return !accel_initialised;
+}
diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
new file mode 100644
index 0000000..5537d74
--- /dev/null
+++ b/include/sysemu/accel.h
@@ -0,0 +1,32 @@
+/* QEMU accelerator interfaces
+ *
+ * Copyright (c) 2014 Red Hat Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef HW_ACCEL_H
+#define HW_ACCEL_H
+
+#include "qemu/typedefs.h"
+
+extern int tcg_tb_size;
+
+int configure_accelerator(MachineClass *mc);
+
+#endif
diff --git a/vl.c b/vl.c
index 72436cd..c3def21 100644
--- a/vl.c
+++ b/vl.c
@@ -61,6 +61,7 @@ int main(int argc, char **argv)
#include "qemu/sockets.h"
#include "hw/hw.h"
#include "hw/boards.h"
+#include "sysemu/accel.h"
#include "hw/usb.h"
#include "hw/pcmcia.h"
#include "hw/i386/pc.h"
@@ -213,11 +214,9 @@ static NotifierList exit_notifiers =
static NotifierList machine_init_done_notifiers =
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
-static bool tcg_allowed = true;
bool xen_allowed;
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
-static int tcg_tb_size;
static int has_defaults = 1;
static int default_serial = 1;
@@ -2675,84 +2674,6 @@ static MachineClass *machine_parse(const char *name)
exit(!name || !is_help_option(name));
}
-static int tcg_init(MachineClass *mc)
-{
- tcg_exec_init(tcg_tb_size * 1024 * 1024);
- return 0;
-}
-
-static struct {
- const char *opt_name;
- const char *name;
- int (*available)(void);
- int (*init)(MachineClass *mc);
- bool *allowed;
-} accel_list[] = {
- { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
- { "xen", "Xen", xen_available, xen_init, &xen_allowed },
- { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
- { "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
-};
-
-static int configure_accelerator(MachineClass *mc)
-{
- const char *p;
- char buf[10];
- int i, ret;
- bool accel_initialised = false;
- bool init_failed = false;
-
- p = qemu_opt_get(qemu_get_machine_opts(), "accel");
- if (p == NULL) {
- /* Use the default "accelerator", tcg */
- p = "tcg";
- }
-
- while (!accel_initialised && *p != '\0') {
- if (*p == ':') {
- p++;
- }
- p = get_opt_name(buf, sizeof(buf), p, ':');
- for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
- if (strcmp(accel_list[i].opt_name, buf) == 0) {
- if (!accel_list[i].available()) {
- printf("%s not supported for this target\n",
- accel_list[i].name);
- break;
- }
- *(accel_list[i].allowed) = true;
- ret = accel_list[i].init(mc);
- if (ret < 0) {
- init_failed = true;
- fprintf(stderr, "failed to initialize %s: %s\n",
- accel_list[i].name,
- strerror(-ret));
- *(accel_list[i].allowed) = false;
- } else {
- accel_initialised = true;
- }
- break;
- }
- }
- if (i == ARRAY_SIZE(accel_list)) {
- fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
- }
- }
-
- if (!accel_initialised) {
- if (!init_failed) {
- fprintf(stderr, "No accelerator found!\n");
- }
- exit(1);
- }
-
- if (init_failed) {
- fprintf(stderr, "Back to %s accelerator.\n", accel_list[i].name);
- }
-
- return !accel_initialised;
-}
-
void qemu_add_exit_notifier(Notifier *notify)
{
notifier_list_add(&exit_notifiers, notify);
commit 20674449453924ac808a82619456f68bb14df007
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Fri Sep 26 17:45:16 2014 -0300
vl.c: Small coding style fix
Just to make checkpatch.pl happy when moving the code.
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/vl.c b/vl.c
index 9d2aaaf..72436cd 100644
--- a/vl.c
+++ b/vl.c
@@ -2712,7 +2712,7 @@ static int configure_accelerator(MachineClass *mc)
if (*p == ':') {
p++;
}
- p = get_opt_name(buf, sizeof (buf), p, ':');
+ p = get_opt_name(buf, sizeof(buf), p, ':');
for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
if (strcmp(accel_list[i].opt_name, buf) == 0) {
if (!accel_list[i].available()) {
commit 01ca519f24d6eb8afdfaa971c930d1b67235dfca
Author: Corey Minyard <cminyard at mvista.com>
Date: Thu Oct 2 11:17:38 2014 -0500
qemu-char: Print the remote and local addresses for a socket
It seems that it might be a good idea to know what is at the remote
end of a socket for tracking down issues. So add that to the
socket filename.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/qemu-char.c b/qemu-char.c
index aa15bd3..62af0ef 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -142,9 +142,11 @@ static int SocketAddress_to_str(char *dest, int max_len,
static int sockaddr_to_str(char *dest, int max_len,
struct sockaddr_storage *ss, socklen_t ss_len,
+ struct sockaddr_storage *ps, socklen_t ps_len,
bool is_listen, bool is_telnet)
{
- char host[NI_MAXHOST], serv[NI_MAXSERV];
+ char shost[NI_MAXHOST], sserv[NI_MAXSERV];
+ char phost[NI_MAXHOST], pserv[NI_MAXSERV];
const char *left = "", *right = "";
switch (ss->ss_family) {
@@ -159,12 +161,15 @@ static int sockaddr_to_str(char *dest, int max_len,
right = "]";
/* fall through */
case AF_INET:
- getnameinfo((struct sockaddr *) ss, ss_len, host, sizeof(host),
- serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
- return snprintf(dest, max_len, "%s:%s%s%s:%s%s",
+ getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
+ sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
+ getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
+ pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
+ return snprintf(dest, max_len, "%s:%s%s%s:%s%s <-> %s%s%s:%s",
is_telnet ? "telnet" : "tcp",
- left, host, right, serv,
- is_listen ? ",server" : "");
+ left, shost, right, sserv,
+ is_listen ? ",server" : "",
+ left, phost, right, pserv);
default:
return snprintf(dest, max_len, "unknown");
@@ -2870,15 +2875,19 @@ static void tcp_chr_connect(void *opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
- struct sockaddr_storage ss;
- socklen_t ss_len = sizeof(ss);
+ struct sockaddr_storage ss, ps;
+ socklen_t ss_len = sizeof(ss), ps_len = sizeof(ps);
memset(&ss, 0, ss_len);
if (getsockname(s->fd, (struct sockaddr *) &ss, &ss_len) != 0) {
snprintf(chr->filename, CHR_MAX_FILENAME_SIZE,
"Error in getsockname: %s\n", strerror(errno));
+ } else if (getpeername(s->fd, (struct sockaddr *) &ps, &ps_len) != 0) {
+ snprintf(chr->filename, CHR_MAX_FILENAME_SIZE,
+ "Error in getpeername: %s\n", strerror(errno));
} else {
- sockaddr_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, &ss, ss_len,
+ sockaddr_to_str(chr->filename, CHR_MAX_FILENAME_SIZE,
+ &ss, ss_len, &ps, ps_len,
s->is_listen, s->is_telnet);
}
commit 5dd1f02b4bc2f2c2ef3a2adfd8a412c8c8769085
Author: Corey Minyard <cminyard at mvista.com>
Date: Thu Oct 2 11:17:37 2014 -0500
qemu-char: Add reconnecting to client sockets
Adds a "reconnect" option to socket backends that gives a reconnect
timeout. This only applies to client sockets. If the other end
of a socket closes the connection, qemu will attempt to reconnect
after the given number of seconds.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/qapi-schema.json b/qapi-schema.json
index 4bfaf20..148097b 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2651,14 +2651,19 @@
# @nodelay: #optional set TCP_NODELAY socket option (default: false)
# @telnet: #optional enable telnet protocol on server
# sockets (default: false)
+# @reconnect: #optional For a client socket, if a socket is disconnected,
+# then attempt a reconnect after the given number of seconds.
+# Setting this to zero disables this function. (default: 0)
+# (Since: 2.2)
#
# Since: 1.4
##
-{ 'type': 'ChardevSocket', 'data': { 'addr' : 'SocketAddress',
- '*server' : 'bool',
- '*wait' : 'bool',
- '*nodelay' : 'bool',
- '*telnet' : 'bool' } }
+{ 'type': 'ChardevSocket', 'data': { 'addr' : 'SocketAddress',
+ '*server' : 'bool',
+ '*wait' : 'bool',
+ '*nodelay' : 'bool',
+ '*telnet' : 'bool',
+ '*reconnect' : 'int' } }
##
# @ChardevUdp:
diff --git a/qemu-char.c b/qemu-char.c
index 549ebd8..aa15bd3 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2501,8 +2501,21 @@ typedef struct {
SocketAddress *addr;
bool is_listen;
bool is_telnet;
+
+ guint reconnect_timer;
+ int64_t reconnect_time;
} TCPCharDriver;
+static gboolean socket_reconnect_timeout(gpointer opaque);
+
+static void qemu_chr_socket_restart_timer(CharDriverState *chr)
+{
+ TCPCharDriver *s = chr->opaque;
+ assert(s->connected == 0);
+ s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
+ socket_reconnect_timeout, chr);
+}
+
static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
#ifndef _WIN32
@@ -2784,6 +2797,9 @@ static void tcp_chr_disconnect(CharDriverState *chr)
SocketAddress_to_str(chr->filename, CHR_MAX_FILENAME_SIZE,
"disconnected:", s->addr, s->is_listen, s->is_telnet);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
+ if (s->reconnect_time) {
+ qemu_chr_socket_restart_timer(chr);
+ }
}
static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
@@ -2964,6 +2980,10 @@ static void tcp_chr_close(CharDriverState *chr)
TCPCharDriver *s = chr->opaque;
int i;
+ if (s->reconnect_timer) {
+ g_source_remove(s->reconnect_timer);
+ s->reconnect_timer = 0;
+ }
qapi_free_SocketAddress(s->addr);
if (s->fd >= 0) {
remove_fd_in_watch(chr);
@@ -3013,6 +3033,18 @@ static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd)
}
}
+static void qemu_chr_socket_connected(int fd, void *opaque)
+{
+ CharDriverState *chr = opaque;
+
+ if (fd < 0) {
+ qemu_chr_socket_restart_timer(chr);
+ return;
+ }
+
+ qemu_chr_finish_socket_connection(chr, fd);
+}
+
static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp)
{
TCPCharDriver *s = chr->opaque;
@@ -3020,7 +3052,10 @@ static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp)
if (s->is_listen) {
fd = socket_listen(s->addr, errp);
- } else {
+ } else if (s->reconnect_time) {
+ fd = socket_connect(s->addr, errp, qemu_chr_socket_connected, chr);
+ return fd >= 0;
+ } else {
fd = socket_connect(s->addr, errp, NULL, NULL);
}
if (fd < 0) {
@@ -3448,6 +3483,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
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);
+ int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0);
const char *path = qemu_opt_get(opts, "path");
const char *host = qemu_opt_get(opts, "host");
const char *port = qemu_opt_get(opts, "port");
@@ -3474,6 +3510,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
backend->socket->telnet = is_telnet;
backend->socket->has_wait = true;
backend->socket->wait = is_waitconnect;
+ backend->socket->has_reconnect = true;
+ backend->socket->reconnect = reconnect;
addr = g_new0(SocketAddress, 1);
if (path) {
@@ -3873,6 +3911,9 @@ QemuOptsList qemu_chardev_opts = {
.name = "delay",
.type = QEMU_OPT_BOOL,
},{
+ .name = "reconnect",
+ .type = QEMU_OPT_NUMBER,
+ },{
.name = "telnet",
.type = QEMU_OPT_BOOL,
},{
@@ -4016,6 +4057,26 @@ static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
#endif /* WIN32 */
+static gboolean socket_reconnect_timeout(gpointer opaque)
+{
+ CharDriverState *chr = opaque;
+ TCPCharDriver *s = chr->opaque;
+ Error *err;
+
+ s->reconnect_timer = 0;
+
+ if (chr->be_open) {
+ return false;
+ }
+
+ if (!qemu_chr_open_socket_fd(chr, &err)) {
+ error_report("Unable to connect to char device %s\n", chr->label);
+ qemu_chr_socket_restart_timer(chr);
+ }
+
+ return false;
+}
+
static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
Error **errp)
{
@@ -4026,6 +4087,7 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
bool is_listen = sock->has_server ? sock->server : true;
bool is_telnet = sock->has_telnet ? sock->telnet : false;
bool is_waitconnect = sock->has_wait ? sock->wait : false;
+ int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0;
chr = qemu_chr_alloc();
s = g_malloc0(sizeof(TCPCharDriver));
@@ -4058,13 +4120,19 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
if (is_telnet) {
s->do_telnetopt = 1;
}
+ } else if (reconnect > 0) {
+ s->reconnect_time = reconnect;
}
if (!qemu_chr_open_socket_fd(chr, errp)) {
- g_free(s);
- g_free(chr->filename);
- g_free(chr);
- return NULL;
+ if (s->reconnect_time) {
+ qemu_chr_socket_restart_timer(chr);
+ } else {
+ g_free(s);
+ g_free(chr->filename);
+ g_free(chr);
+ return NULL;
+ }
}
if (is_listen && is_waitconnect) {
diff --git a/qemu-options.hx b/qemu-options.hx
index 365b56c..22cf3b9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1930,9 +1930,9 @@ ETEXI
DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
"-chardev null,id=id[,mux=on|off]\n"
- "-chardev socket,id=id[,host=host],port=port[,to=to][,ipv4][,ipv6][,nodelay]\n"
- " [,server][,nowait][,telnet][,mux=on|off] (tcp)\n"
- "-chardev socket,id=id,path=path[,server][,nowait][,telnet],[mux=on|off] (unix)\n"
+ "-chardev socket,id=id[,host=host],port=port[,to=to][,ipv4][,ipv6][,nodelay][,reconnect=seconds]\n"
+ " [,server][,nowait][,telnet][,reconnect=seconds][,mux=on|off] (tcp)\n"
+ "-chardev socket,id=id,path=path[,server][,nowait][,telnet][,reconnect=seconds][,mux=on|off] (unix)\n"
"-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr]\n"
" [,localport=localport][,ipv4][,ipv6][,mux=on|off]\n"
"-chardev msmouse,id=id[,mux=on|off]\n"
@@ -2004,7 +2004,7 @@ Options to each backend are described below.
A void device. This device will not emit any data, and will drop any data it
receives. The null backend does not take any options.
- at item -chardev socket ,id=@var{id} [@var{TCP options} or @var{unix options}] [,server] [,nowait] [,telnet]
+ at item -chardev socket ,id=@var{id} [@var{TCP options} or @var{unix options}] [,server] [,nowait] [,telnet] [,reconnect=@var{seconds}]
Create a two-way stream socket, which can be either a TCP or a unix socket. A
unix socket will be created if @option{path} is specified. Behaviour is
@@ -2018,6 +2018,10 @@ connect to a listening socket.
@option{telnet} specifies that traffic on the socket should interpret telnet
escape sequences.
+ at option{reconnect} sets the timeout for reconnecting on non-server sockets when
+the remote end goes away. qemu will delay this many seconds and then attempt
+to reconnect. Zero disables reconnecting, and is the default.
+
TCP and unix socket options are given below:
@table @option
@@ -2687,14 +2691,16 @@ telnet on port 5555 to access the QEMU port.
localhost 5555
@end table
- at item tcp:[@var{host}]:@var{port}[, at var{server}][,nowait][,nodelay]
+ at item tcp:[@var{host}]:@var{port}[, at var{server}][,nowait][,nodelay][,reconnect=@var{seconds}]
The TCP Net Console has two modes of operation. It can send the serial
I/O to a location or wait for a connection from a location. By default
the TCP Net Console is sent to @var{host} at the @var{port}. If you use
the @var{server} option QEMU will wait for a client socket application
to connect to the port before continuing, unless the @code{nowait}
option was specified. The @code{nodelay} option disables the Nagle buffering
-algorithm. If @var{host} is omitted, 0.0.0.0 is assumed. Only
+algorithm. The @code{reconnect} option only applies if @var{noserver} is
+set, if the connection goes down it will attempt to reconnect at the
+given interval. If @var{host} is omitted, 0.0.0.0 is assumed. Only
one TCP connection at a time is accepted. You can use @code{telnet} to
connect to the corresponding character device.
@table @code
@@ -2715,7 +2721,7 @@ MAGIC_SYSRQ sequence if you use a telnet that supports sending the break
sequence. Typically in unix telnet you do it with Control-] and then
type "send break" followed by pressing the enter key.
- at item unix:@var{path}[,server][,nowait]
+ at item unix:@var{path}[,server][,nowait][,reconnect=@var{seconds}]
A unix domain socket is used instead of a tcp socket. The option works the
same as if you had specified @code{-serial tcp} except the unix domain socket
@var{path} is used for connections.
commit 16cc4ffe34f3fd6d0626ed459fb241304786a04b
Author: Corey Minyard <cminyard at mvista.com>
Date: Thu Oct 2 11:17:36 2014 -0500
qemu-char: set socket filename to disconnected when not connected
This way we can tell if the socket is connected or not. It also splits
the string conversions out into separate functions to make this more
convenient.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/qemu-char.c b/qemu-char.c
index a671d6b..549ebd8 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -117,6 +117,60 @@ static void qapi_copy_SocketAddress(SocketAddress **p_dest,
qobject_decref(obj);
}
+static int SocketAddress_to_str(char *dest, int max_len,
+ const char *prefix, SocketAddress *addr,
+ bool is_listen, bool is_telnet)
+{
+ switch (addr->kind) {
+ case SOCKET_ADDRESS_KIND_INET:
+ return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix,
+ is_telnet ? "telnet" : "tcp", addr->inet->host,
+ addr->inet->port, is_listen ? ",server" : "");
+ break;
+ case SOCKET_ADDRESS_KIND_UNIX:
+ return snprintf(dest, max_len, "%sunix:%s%s", prefix,
+ addr->q_unix->path, is_listen ? ",server" : "");
+ break;
+ case SOCKET_ADDRESS_KIND_FD:
+ return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->fd->str,
+ is_listen ? ",server" : "");
+ break;
+ default:
+ abort();
+ }
+}
+
+static int sockaddr_to_str(char *dest, int max_len,
+ struct sockaddr_storage *ss, socklen_t ss_len,
+ bool is_listen, bool is_telnet)
+{
+ char host[NI_MAXHOST], serv[NI_MAXSERV];
+ const char *left = "", *right = "";
+
+ switch (ss->ss_family) {
+#ifndef _WIN32
+ case AF_UNIX:
+ return snprintf(dest, max_len, "unix:%s%s",
+ ((struct sockaddr_un *)(ss))->sun_path,
+ is_listen ? ",server" : "");
+#endif
+ case AF_INET6:
+ left = "[";
+ right = "]";
+ /* fall through */
+ case AF_INET:
+ getnameinfo((struct sockaddr *) ss, ss_len, host, sizeof(host),
+ serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
+ return snprintf(dest, max_len, "%s:%s%s%s:%s%s",
+ is_telnet ? "telnet" : "tcp",
+ left, host, right, serv,
+ is_listen ? ",server" : "");
+
+ default:
+ return snprintf(dest, max_len, "unknown");
+ }
+}
+
/***********************************************************/
/* character device */
@@ -2727,6 +2781,8 @@ static void tcp_chr_disconnect(CharDriverState *chr)
s->chan = NULL;
closesocket(s->fd);
s->fd = -1;
+ SocketAddress_to_str(chr->filename, CHR_MAX_FILENAME_SIZE,
+ "disconnected:", s->addr, s->is_listen, s->is_telnet);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
@@ -2798,6 +2854,17 @@ static void tcp_chr_connect(void *opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
+
+ memset(&ss, 0, ss_len);
+ if (getsockname(s->fd, (struct sockaddr *) &ss, &ss_len) != 0) {
+ snprintf(chr->filename, CHR_MAX_FILENAME_SIZE,
+ "Error in getsockname: %s\n", strerror(errno));
+ } else {
+ sockaddr_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, &ss, ss_len,
+ s->is_listen, s->is_telnet);
+ }
s->connected = 1;
if (s->chan) {
@@ -2928,43 +2995,9 @@ static void tcp_chr_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
-static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
- Error **errp)
+static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd)
{
TCPCharDriver *s = chr->opaque;
- char host[NI_MAXHOST], serv[NI_MAXSERV];
- const char *left = "", *right = "";
- struct sockaddr_storage ss;
- socklen_t ss_len = sizeof(ss);
-
- memset(&ss, 0, ss_len);
- if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
- closesocket(fd);
- error_setg_errno(errp, errno, "getsockname");
- return false;
- }
-
- switch (ss.ss_family) {
-#ifndef _WIN32
- case AF_UNIX:
- snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "unix:%s%s",
- ((struct sockaddr_un *)(&ss))->sun_path,
- s->is_listen ? ",server" : "");
- break;
-#endif
- case AF_INET6:
- left = "[";
- right = "]";
- /* fall through */
- case AF_INET:
- getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
- serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
- snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "%s:%s%s%s:%s%s",
- s->is_telnet ? "telnet" : "tcp",
- left, host, right, serv,
- s->is_listen ? ",server" : "");
- break;
- }
if (s->is_listen) {
s->listen_fd = fd;
@@ -2978,8 +3011,6 @@ static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
s->chan = io_channel_from_socket(s->fd);
tcp_chr_connect(chr);
}
-
- return true;
}
static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp)
@@ -2996,7 +3027,8 @@ static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp)
return false;
}
- return qemu_chr_finish_socket_connection(chr, fd, errp);
+ qemu_chr_finish_socket_connection(chr, fd);
+ return true;
}
/*********************************************************/
@@ -4019,6 +4051,8 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
chr->explicit_be_open = true;
chr->filename = g_malloc(CHR_MAX_FILENAME_SIZE);
+ SocketAddress_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, "disconnected:",
+ addr, is_listen, is_telnet);
if (is_listen) {
if (is_telnet) {
commit cfb429cb1acef4925812e3361ce56884043e84f7
Author: Corey Minyard <cminyard at mvista.com>
Date: Thu Oct 2 11:17:35 2014 -0500
qemu-char: Move some items into TCPCharDriver
This keeps them from having to be passed around and makes them
available for later functions, like printing and reconnecting.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/qemu-char.c b/qemu-char.c
index dcfeb73..a671d6b 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -28,6 +28,9 @@
#include "sysemu/char.h"
#include "hw/usb.h"
#include "qmp-commands.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi-visit.h"
#include <unistd.h>
#include <fcntl.h>
@@ -87,6 +90,34 @@
#define CHR_MAX_FILENAME_SIZE 256
/***********************************************************/
+/* Socket address helpers */
+static void qapi_copy_SocketAddress(SocketAddress **p_dest,
+ SocketAddress *src)
+{
+ QmpOutputVisitor *qov;
+ QmpInputVisitor *qiv;
+ Visitor *ov, *iv;
+ QObject *obj;
+
+ *p_dest = NULL;
+
+ qov = qmp_output_visitor_new();
+ ov = qmp_output_get_visitor(qov);
+ visit_type_SocketAddress(ov, &src, NULL, &error_abort);
+ obj = qmp_output_get_qobject(qov);
+ qmp_output_visitor_cleanup(qov);
+ if (!obj) {
+ return;
+ }
+
+ qiv = qmp_input_visitor_new(obj);
+ iv = qmp_input_get_visitor(qiv);
+ visit_type_SocketAddress(iv, p_dest, NULL, &error_abort);
+ qmp_input_visitor_cleanup(qiv);
+ qobject_decref(obj);
+}
+
+/***********************************************************/
/* character device */
static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
@@ -2412,6 +2443,10 @@ typedef struct {
int read_msgfds_num;
int *write_msgfds;
int write_msgfds_num;
+
+ SocketAddress *addr;
+ bool is_listen;
+ bool is_telnet;
} TCPCharDriver;
static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
@@ -2861,6 +2896,8 @@ static void tcp_chr_close(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
int i;
+
+ qapi_free_SocketAddress(s->addr);
if (s->fd >= 0) {
remove_fd_in_watch(chr);
if (s->chan) {
@@ -2892,7 +2929,6 @@ static void tcp_chr_close(CharDriverState *chr)
}
static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
- bool is_listen, bool is_telnet,
Error **errp)
{
TCPCharDriver *s = chr->opaque;
@@ -2913,7 +2949,7 @@ static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
case AF_UNIX:
snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "unix:%s%s",
((struct sockaddr_un *)(&ss))->sun_path,
- is_listen ? ",server" : "");
+ s->is_listen ? ",server" : "");
break;
#endif
case AF_INET6:
@@ -2924,13 +2960,13 @@ static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "%s:%s%s%s:%s%s",
- is_telnet ? "telnet" : "tcp",
+ s->is_telnet ? "telnet" : "tcp",
left, host, right, serv,
- is_listen ? ",server" : "");
+ s->is_listen ? ",server" : "");
break;
}
- if (is_listen) {
+ if (s->is_listen) {
s->listen_fd = fd;
s->listen_chan = io_channel_from_socket(s->listen_fd);
s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN,
@@ -2946,23 +2982,21 @@ static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
return true;
}
-static bool qemu_chr_open_socket_fd(CharDriverState *chr, SocketAddress *addr,
- bool is_listen, bool is_telnet,
- Error **errp)
+static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp)
{
+ TCPCharDriver *s = chr->opaque;
int fd;
- if (is_listen) {
- fd = socket_listen(addr, errp);
+ if (s->is_listen) {
+ fd = socket_listen(s->addr, errp);
} else {
- fd = socket_connect(addr, errp, NULL, NULL);
+ fd = socket_connect(s->addr, errp, NULL, NULL);
}
if (fd < 0) {
return false;
}
- return qemu_chr_finish_socket_connection(chr, fd, is_listen, is_telnet,
- errp);
+ return qemu_chr_finish_socket_connection(chr, fd, errp);
}
/*********************************************************/
@@ -3967,7 +4001,10 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
s->fd = -1;
s->listen_fd = -1;
s->is_unix = addr->kind == SOCKET_ADDRESS_KIND_UNIX;
+ s->is_listen = is_listen;
+ s->is_telnet = is_telnet;
s->do_nodelay = do_nodelay;
+ qapi_copy_SocketAddress(&s->addr, sock->addr);
chr->opaque = s;
chr->chr_write = tcp_chr_write;
@@ -3989,7 +4026,7 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
}
}
- if (!qemu_chr_open_socket_fd(chr, addr, is_listen, is_telnet, errp)) {
+ if (!qemu_chr_open_socket_fd(chr, errp)) {
g_free(s);
g_free(chr->filename);
g_free(chr);
commit 43ded1a0d2381e65f0fff28269b7d02d4ead6aac
Author: Corey Minyard <cminyard at mvista.com>
Date: Thu Oct 2 11:17:34 2014 -0500
qemu-char: Rework qemu_chr_open_socket() for reconnect
Move all socket configuration to qmp_chardev_open_socket().
qemu_chr_open_socket_fd() just opens the socket. This is getting ready
for the reconnect code, which will call open_sock_fd() on a reconnect
attempt.
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/qemu-char.c b/qemu-char.c
index f9d2a02..dcfeb73 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2891,13 +2891,11 @@ static void tcp_chr_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
- bool is_listen, bool is_telnet,
- bool is_waitconnect,
- Error **errp)
+static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
+ bool is_listen, bool is_telnet,
+ Error **errp)
{
- CharDriverState *chr = NULL;
- TCPCharDriver *s = NULL;
+ TCPCharDriver *s = chr->opaque;
char host[NI_MAXHOST], serv[NI_MAXSERV];
const char *left = "", *right = "";
struct sockaddr_storage ss;
@@ -2905,26 +2903,14 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
memset(&ss, 0, ss_len);
if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
+ closesocket(fd);
error_setg_errno(errp, errno, "getsockname");
- return NULL;
+ return false;
}
- chr = qemu_chr_alloc();
- s = g_malloc0(sizeof(TCPCharDriver));
-
- s->connected = 0;
- s->fd = -1;
- s->listen_fd = -1;
- s->read_msgfds = 0;
- s->read_msgfds_num = 0;
- s->write_msgfds = 0;
- s->write_msgfds_num = 0;
-
- chr->filename = g_malloc(CHR_MAX_FILENAME_SIZE);
switch (ss.ss_family) {
#ifndef _WIN32
case AF_UNIX:
- s->is_unix = 1;
snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "unix:%s%s",
((struct sockaddr_un *)(&ss))->sun_path,
is_listen ? ",server" : "");
@@ -2935,7 +2921,6 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
right = "]";
/* fall through */
case AF_INET:
- s->do_nodelay = do_nodelay;
getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "%s:%s%s%s:%s%s",
@@ -2945,25 +2930,11 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
break;
}
- chr->opaque = s;
- chr->chr_write = tcp_chr_write;
- chr->chr_sync_read = tcp_chr_sync_read;
- chr->chr_close = tcp_chr_close;
- chr->get_msgfds = tcp_get_msgfds;
- chr->set_msgfds = tcp_set_msgfds;
- chr->chr_add_client = tcp_chr_add_client;
- chr->chr_add_watch = tcp_chr_add_watch;
- chr->chr_update_read_handler = tcp_chr_update_read_handler;
- /* be isn't opened until we get a connection */
- chr->explicit_be_open = true;
-
if (is_listen) {
s->listen_fd = fd;
s->listen_chan = io_channel_from_socket(s->listen_fd);
- s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
- if (is_telnet) {
- s->do_telnetopt = 1;
- }
+ s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN,
+ tcp_chr_accept, chr);
} else {
s->connected = 1;
s->fd = fd;
@@ -2972,13 +2943,26 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
tcp_chr_connect(chr);
}
- if (is_listen && is_waitconnect) {
- fprintf(stderr, "QEMU waiting for connection on: %s\n",
- chr->filename);
- tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
- qemu_set_nonblock(s->listen_fd);
+ return true;
+}
+
+static bool qemu_chr_open_socket_fd(CharDriverState *chr, SocketAddress *addr,
+ bool is_listen, bool is_telnet,
+ Error **errp)
+{
+ int fd;
+
+ if (is_listen) {
+ fd = socket_listen(addr, errp);
+ } else {
+ fd = socket_connect(addr, errp, NULL, NULL);
}
- return chr;
+ if (fd < 0) {
+ return false;
+ }
+
+ return qemu_chr_finish_socket_connection(chr, fd, is_listen, is_telnet,
+ errp);
}
/*********************************************************/
@@ -3969,23 +3953,57 @@ static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
Error **errp)
{
+ CharDriverState *chr;
+ TCPCharDriver *s;
SocketAddress *addr = sock->addr;
bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
bool is_listen = sock->has_server ? sock->server : true;
bool is_telnet = sock->has_telnet ? sock->telnet : false;
bool is_waitconnect = sock->has_wait ? sock->wait : false;
- int fd;
+
+ chr = qemu_chr_alloc();
+ s = g_malloc0(sizeof(TCPCharDriver));
+
+ s->fd = -1;
+ s->listen_fd = -1;
+ s->is_unix = addr->kind == SOCKET_ADDRESS_KIND_UNIX;
+ s->do_nodelay = do_nodelay;
+
+ chr->opaque = s;
+ chr->chr_write = tcp_chr_write;
+ chr->chr_sync_read = tcp_chr_sync_read;
+ chr->chr_close = tcp_chr_close;
+ chr->get_msgfds = tcp_get_msgfds;
+ chr->set_msgfds = tcp_set_msgfds;
+ chr->chr_add_client = tcp_chr_add_client;
+ chr->chr_add_watch = tcp_chr_add_watch;
+ chr->chr_update_read_handler = tcp_chr_update_read_handler;
+ /* be isn't opened until we get a connection */
+ chr->explicit_be_open = true;
+
+ chr->filename = g_malloc(CHR_MAX_FILENAME_SIZE);
if (is_listen) {
- fd = socket_listen(addr, errp);
- } else {
- fd = socket_connect(addr, errp, NULL, NULL);
+ if (is_telnet) {
+ s->do_telnetopt = 1;
+ }
}
- if (fd < 0) {
+
+ if (!qemu_chr_open_socket_fd(chr, addr, is_listen, is_telnet, errp)) {
+ g_free(s);
+ g_free(chr->filename);
+ g_free(chr);
return NULL;
}
- return qemu_chr_open_socket_fd(fd, do_nodelay, is_listen,
- is_telnet, is_waitconnect, errp);
+
+ if (is_listen && is_waitconnect) {
+ fprintf(stderr, "QEMU waiting for connection on: %s\n",
+ chr->filename);
+ tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
+ qemu_set_nonblock(s->listen_fd);
+ }
+
+ return chr;
}
static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp,
commit 9f781168c5d4d2640be89b53a41443d4f368f489
Author: Corey Minyard <cminyard at mvista.com>
Date: Thu Oct 2 11:17:33 2014 -0500
qemu-char: Make the filename size for a chardev a #define
Signed-off-by: Corey Minyard <cminyard at mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
diff --git a/qemu-char.c b/qemu-char.c
index 8623c70..f9d2a02 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -84,6 +84,7 @@
#define READ_BUF_LEN 4096
#define READ_RETRIES 10
+#define CHR_MAX_FILENAME_SIZE 256
/***********************************************************/
/* character device */
@@ -989,7 +990,8 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
{
int fd_in, fd_out;
- char filename_in[256], filename_out[256];
+ char filename_in[CHR_MAX_FILENAME_SIZE];
+ char filename_out[CHR_MAX_FILENAME_SIZE];
const char *filename = opts->device;
if (filename == NULL) {
@@ -997,8 +999,8 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
return NULL;
}
- snprintf(filename_in, 256, "%s.in", filename);
- snprintf(filename_out, 256, "%s.out", filename);
+ snprintf(filename_in, CHR_MAX_FILENAME_SIZE, "%s.in", filename);
+ snprintf(filename_out, CHR_MAX_FILENAME_SIZE, "%s.out", filename);
TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
if (fd_in < 0 || fd_out < 0) {
@@ -1976,7 +1978,7 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
OVERLAPPED ov;
int ret;
DWORD size;
- char openname[256];
+ char openname[CHR_MAX_FILENAME_SIZE];
s->fpipe = TRUE;
@@ -2918,12 +2920,12 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
s->write_msgfds = 0;
s->write_msgfds_num = 0;
- chr->filename = g_malloc(256);
+ chr->filename = g_malloc(CHR_MAX_FILENAME_SIZE);
switch (ss.ss_family) {
#ifndef _WIN32
case AF_UNIX:
s->is_unix = 1;
- snprintf(chr->filename, 256, "unix:%s%s",
+ snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "unix:%s%s",
((struct sockaddr_un *)(&ss))->sun_path,
is_listen ? ",server" : "");
break;
@@ -2936,7 +2938,7 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
s->do_nodelay = do_nodelay;
getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
- snprintf(chr->filename, 256, "%s:%s%s%s:%s%s",
+ snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "%s:%s%s%s:%s%s",
is_telnet ? "telnet" : "tcp",
left, host, right, serv,
is_listen ? ",server" : "");
commit f5bebbbb28dc7a149a891f0f1e112fb50bb72664
Author: Markus Armbruster <armbru at redhat.com>
Date: Tue Sep 30 13:59:30 2014 +0200
util: Emancipate id_wellformed() from QemuOpts
IDs have long spread beyond QemuOpts: not everything with an ID
necessarily goes through QemuOpts. Commit 9aebf3b is about such a
case: block layer names are meant to be well-formed IDs, but some of
them don't go through QemuOpts, and thus weren't checked. The commit
fixed that the straightforward way: rename the internal QemuOpts
helper id_wellformed() to qemu_opts_id_wellformed() and give it
external linkage.
Instead of using it directly in block.c, the commit adds wrapper
bdrv_is_valid_name(), probably to hide the connection to QemuOpts.
Go one logical step further: emancipate IDs from QemuOpts. Rename the
function back to id_wellformed(), and put it in another file. While
there, clean up its value to bool. Peel off the bdrv_is_valid_name()
wrapper.
[Replaced stray return 0 with return false to match bool returns used
elsewhere in id_wellformed().
--Stefan]
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/block.c b/block.c
index c5a251c..d3aebeb 100644
--- a/block.c
+++ b/block.c
@@ -335,18 +335,13 @@ void bdrv_register(BlockDriver *bdrv)
QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
}
-static bool bdrv_is_valid_name(const char *name)
-{
- return qemu_opts_id_wellformed(name);
-}
-
/* create a new block device (by default it is empty) */
BlockDriverState *bdrv_new(const char *device_name, Error **errp)
{
BlockDriverState *bs;
int i;
- if (*device_name && !bdrv_is_valid_name(device_name)) {
+ if (*device_name && !id_wellformed(device_name)) {
error_setg(errp, "Invalid device name");
return NULL;
}
@@ -874,7 +869,7 @@ static void bdrv_assign_node_name(BlockDriverState *bs,
}
/* Check for empty string or invalid characters */
- if (!bdrv_is_valid_name(node_name)) {
+ if (!id_wellformed(node_name)) {
error_setg(errp, "Invalid node name");
return;
}
diff --git a/include/qemu-common.h b/include/qemu-common.h
index dcb57ab..b87e9c2 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -190,6 +190,9 @@ int64_t strtosz_suffix_unit(const char *nptr, char **end,
/* used to print char* safely */
#define STR_OR_NULL(str) ((str) ? (str) : "null")
+/* id.c */
+bool id_wellformed(const char *id);
+
/* path.c */
void init_paths(const char *prefix);
const char *path(const char *pathname);
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 945347c..59bea75 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -103,7 +103,6 @@ typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaq
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
int abort_on_failure);
-int qemu_opts_id_wellformed(const char *id);
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);
diff --git a/util/Makefile.objs b/util/Makefile.objs
index cb8862b..93007e2 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -8,6 +8,7 @@ util-obj-y += fifo8.o
util-obj-y += acl.o
util-obj-y += error.o qemu-error.o
util-obj-$(CONFIG_POSIX) += compatfd.o
+util-obj-y += id.o
util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o
util-obj-y += qemu-option.o qemu-progress.o
util-obj-y += hexdump.o
diff --git a/util/id.c b/util/id.c
new file mode 100644
index 0000000..09b22fb
--- /dev/null
+++ b/util/id.c
@@ -0,0 +1,28 @@
+/*
+ * Dealing with identifiers
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru at redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+
+bool id_wellformed(const char *id)
+{
+ int i;
+
+ if (!qemu_isalpha(id[0])) {
+ return false;
+ }
+ for (i = 1; id[i]; i++) {
+ if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 0cf9960..5d10695 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -641,28 +641,13 @@ QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
return NULL;
}
-int qemu_opts_id_wellformed(const char *id)
-{
- int i;
-
- if (!qemu_isalpha(id[0])) {
- return 0;
- }
- for (i = 1; id[i]; i++) {
- if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
- return 0;
- }
- }
- return 1;
-}
-
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp)
{
QemuOpts *opts = NULL;
if (id) {
- if (!qemu_opts_id_wellformed(id)) {
+ if (!id_wellformed(id)) {
error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
#if 0 /* conversion from qerror_report() to error_set() broke this: */
error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
commit d93162e13c1f4a5b2a4de6b1997f32e3fca19e67
Author: John Snow <jsnow at redhat.com>
Date: Wed Oct 1 14:19:29 2014 -0400
q35/ahci: Pick up -cdrom and -hda options
This patch implements the backend for the Q35 board
for us to be able to pick up and use drives defined
by the -cdrom, -hda, or -drive if=ide shorthand options.
Signed-off-by: John Snow <jsnow at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
Message-id: 1412187569-23452-7-git-send-email-jsnow at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index b28ddbb..bb0dc8e 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -86,6 +86,7 @@ static void pc_q35_init(MachineState *machine)
DeviceState *icc_bridge;
PcGuestInfo *guest_info;
ram_addr_t lowmem;
+ DriveInfo *hd[MAX_SATA_PORTS];
/* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
* and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
@@ -253,6 +254,9 @@ static void pc_q35_init(MachineState *machine)
true, "ich9-ahci");
idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0");
idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1");
+ g_assert_cmpint(MAX_SATA_PORTS, ==, ICH_AHCI(ahci)->ahci.ports);
+ ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
+ ahci_ide_create_devs(ahci, hd);
if (usb_enabled(false)) {
/* Should we create 6 UHCI according to ich9 spec? */
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 8978643..063730e 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1419,3 +1419,18 @@ static void sysbus_ahci_register_types(void)
}
type_init(sysbus_ahci_register_types)
+
+void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd)
+{
+ AHCIPCIState *d = ICH_AHCI(dev);
+ AHCIState *ahci = &d->ahci;
+ int i;
+
+ for (i = 0; i < ahci->ports; i++) {
+ if (hd[i] == NULL) {
+ continue;
+ }
+ ide_create_drive(&ahci->dev[i].port, 0, hd[i]);
+ }
+
+}
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 1543df7..e223258 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -332,4 +332,6 @@ void ahci_uninit(AHCIState *s);
void ahci_reset(AHCIState *s);
+void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd);
+
#endif /* HW_IDE_AHCI_H */
commit 6b9e03a4e7598765a6cebb7618f2eeb22e928f6e
Author: John Snow <jsnow at redhat.com>
Date: Wed Oct 1 14:19:28 2014 -0400
qtest/bios-tables: Correct Q35 command line
If the Q35 board types are to begin recognizing
and decoding syntactic sugar for drive/device
declarations, then workarounds found within
the qtests suite need to be adjusted to prevent
any test failures after the fix.
bios-tables-test improperly uses this cli:
-drive file=etc,id=hd -device ide-hd,drive=hd
Which will create a drive and device due to
the lack of specifying if=none. Then, it will
attempt to create a second device and fail.
This patch corrects this test to always use
the full, non-sugared -device/-drive syntax
for both PC and Q35.
Signed-off-by: John Snow <jsnow at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
Message-id: 1412187569-23452-6-git-send-email-jsnow at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 602932b..9e4d205 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -714,14 +714,12 @@ static void test_acpi_one(const char *params, test_data *data)
uint8_t signature_high;
uint16_t signature;
int i;
- const char *device = "";
- if (!g_strcmp0(data->machine, MACHINE_Q35)) {
- device = ",id=hd -device ide-hd,drive=hd";
- }
+ args = g_strdup_printf("-net none -display none %s "
+ "-drive id=hd0,if=none,file=%s "
+ "-device ide-hd,drive=hd0 ",
+ params ? params : "", disk);
- args = g_strdup_printf("-net none -display none %s -drive file=%s%s,",
- params ? params : "", disk, device);
qtest_start(args);
/* Wait at most 1 minute */
commit d8f94e1bb275ab6a14a15220fd6afd0d04324aeb
Author: John Snow <jsnow at redhat.com>
Date: Wed Oct 1 14:19:27 2014 -0400
ide: Update ide_drive_get to be HBA agnostic
Instead of duplicating the logic for the if_ide
(bus,unit) mappings, rely on the blockdev layer
for managing those mappings for us, and use the
drive_get_by_index call instead.
This allows ide_drive_get to work for AHCI HBAs
as well, and can be used in the Q35 initialization.
Lastly, change the nature of the argument to
ide_drive_get so that represents the number of
total drives we can support, and not the total
number of buses. This will prevent array overflows
if the units-per-default-bus property ever needs
to be adjusted for compatibility reasons.
Signed-off-by: John Snow <jsnow at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
Message-id: 1412187569-23452-5-git-send-email-jsnow at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/blockdev.c b/blockdev.c
index 1780d77..e595910 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -135,6 +135,23 @@ void blockdev_auto_del(BlockDriverState *bs)
}
}
+/**
+ * Returns the current mapping of how many units per bus
+ * a particular interface can support.
+ *
+ * A positive integer indicates n units per bus.
+ * 0 implies the mapping has not been established.
+ * -1 indicates an invalid BlockInterfaceType was given.
+ */
+int drive_get_max_devs(BlockInterfaceType type)
+{
+ if (type >= IF_IDE && type < IF_COUNT) {
+ return if_max_devs[type];
+ }
+
+ return -1;
+}
+
static int drive_index_to_bus_id(BlockInterfaceType type, int index)
{
int max_devs = if_max_devs[type];
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index b178a03..84a55e4 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -97,7 +97,7 @@ static void clipper_init(MachineState *machine)
/* IDE disk setup. */
{
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
pci_cmd646_ide_init(pci_bus, hd, 0);
}
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 103d756..4384633 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -239,7 +239,7 @@ static void pc_init1(MachineState *machine,
pc_nic_init(isa_bus, pci_bus);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
if (pci_enabled) {
PCIDevice *dev;
if (xen_enabled()) {
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 190700a..ae85428 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2558,16 +2558,28 @@ const VMStateDescription vmstate_ide_bus = {
}
};
-void ide_drive_get(DriveInfo **hd, int max_bus)
+void ide_drive_get(DriveInfo **hd, int n)
{
int i;
+ int highest_bus = drive_get_max_bus(IF_IDE) + 1;
+ int max_devs = drive_get_max_devs(IF_IDE);
+ int n_buses = max_devs ? (n / max_devs) : n;
- if (drive_get_max_bus(IF_IDE) >= max_bus) {
- fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus);
+ /*
+ * Note: The number of actual buses available is not known.
+ * We compute this based on the size of the DriveInfo* array, n.
+ * If it is less than max_devs * <num_real_buses>,
+ * We will stop looking for drives prematurely instead of overfilling
+ * the array.
+ */
+
+ if (highest_bus > n_buses) {
+ error_report("Too many IDE buses defined (%d > %d)",
+ highest_bus, n_buses);
exit(1);
}
- for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) {
- hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+ for (i = 0; i < n; i++) {
+ hd[i] = drive_get_by_index(IF_IDE, i);
}
}
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index be286da..29cd708 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -350,7 +350,7 @@ static void mips_fulong2e_init(MachineState *machine)
pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
/* South bridge */
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0));
if (!isa_bus) {
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 2d87de9..b20807c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1147,7 +1147,7 @@ void mips_malta_init(MachineState *machine)
pci_bus = gt64120_register(isa_irq);
/* Southbridge */
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index e219766..93606a4 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -294,7 +294,7 @@ void mips_r4k_init(MachineState *machine)
if (nd_table[0].used)
isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
for(i = 0; i < MAX_IDE_BUS; i++)
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[MAX_IDE_DEVS * i],
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 1626db4..4094beb 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -400,7 +400,7 @@ static void ppc_core99_init(MachineState *machine)
macio_init(macio, pic_mem, escc_bar);
/* We only emulate 2 out of 3 IDE controllers for now */
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
"ide[0]"));
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index be9a194..ebd87fb 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -278,7 +278,7 @@ static void ppc_heathrow_init(MachineState *machine)
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
dev = DEVICE(macio);
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f0ef1af..9f484cd 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -519,7 +519,7 @@ static void ppc_prep_init(MachineState *machine)
}
}
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
for(i = 0; i < MAX_IDE_BUS; i++) {
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[2 * i],
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 9c77e18..871a0ea 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -864,7 +864,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
for(i = 0; i < nb_nics; i++)
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
pci_cmd646_ide_init(pci_bus, hd, 1);
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index a4033d4..09716de 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -52,6 +52,7 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
bool drive_check_orphaned(void);
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
int drive_get_max_bus(BlockInterfaceType type);
+int drive_get_max_devs(BlockInterfaceType type);
DriveInfo *drive_get_next(BlockInterfaceType type);
DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);
commit 1602651833c081e32366c9e534ad72e4287840c5
Author: John Snow <jsnow at redhat.com>
Date: Wed Oct 1 14:19:26 2014 -0400
pc/vl: Add units-per-default-bus property
This patch adds the 'units_per_default_bus' property which
allows individual boards to declare their desired
index => (bus,unit) mapping for their default HBA, so that
boards such as Q35 can specify that its default if_ide HBA,
AHCI, only accepts one unit per bus.
This property only overrides the mapping for drives matching
the block_default_type interface.
This patch also adds this property to *all* past and present
Q35 machine types. This retroactive addition is justified
because the previous erroneous index=>(bus,unit) mappings
caused by lack of such a property were not utilized due to
lack of initialization code in the Q35 init routine.
Further, semantically, the Q35 board type has always had the
property that its default HBA, AHCI, only accepts one unit per
bus. The new code added to add devices to drives relies upon
the accuracy of this mapping. Thus, the property is applied
retroactively to reduce complexity of allowing IDE HBAs with
different units per bus.
Examples:
Prior to this patch, all IDE HBAs were assumed to use 2 units
per bus (Master, Slave). When using Q35 and AHCI, however, we
only allow one unit per bus.
-hdb foo.qcow2 would become index=1, or bus=0,unit=1.
-hdd foo.qcow2 would become index=3, or bus=1,unit=1.
-drive file=foo.qcow2,index=5 becomes bus=2,unit=1.
These are invalid for AHCI. They now become, under Q35 only:
-hdb foo.qcow2 --> index=1, bus=1, unit=0.
-hdd foo.qcow2 --> index=3, bus=3, unit=0.
-drive file=foo.qcow2,index=5 --> bus=5,unit=0.
The mapping is adjusted based on the fact that the default IF
for the Q35 machine type is IF_IDE, and units-per-default-bus
overrides the IDE mapping from its default of 2 units per bus
to just 1 unit per bus.
Signed-off-by: John Snow <jsnow at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
Message-id: 1412187569-23452-4-git-send-email-jsnow at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 82a7daa..d045e8b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1524,6 +1524,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data)
mc->hot_add_cpu = qm->hot_add_cpu;
mc->kvm_type = qm->kvm_type;
mc->block_default_type = qm->block_default_type;
+ mc->units_per_default_bus = qm->units_per_default_bus;
mc->max_cpus = qm->max_cpus;
mc->no_serial = qm->no_serial;
mc->no_parallel = qm->no_parallel;
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index d4a907c..b28ddbb 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -344,7 +344,8 @@ static void pc_q35_init_1_4(MachineState *machine)
#define PC_Q35_MACHINE_OPTIONS \
PC_DEFAULT_MACHINE_OPTIONS, \
.desc = "Standard PC (Q35 + ICH9, 2009)", \
- .hot_add_cpu = pc_hot_add_cpu
+ .hot_add_cpu = pc_hot_add_cpu, \
+ .units_per_default_bus = 1
#define PC_Q35_2_2_MACHINE_OPTIONS \
PC_Q35_MACHINE_OPTIONS, \
diff --git a/include/hw/boards.h b/include/hw/boards.h
index dfb6718..663f16a 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -28,6 +28,7 @@ struct QEMUMachine {
QEMUMachineHotAddCPUFunc *hot_add_cpu;
QEMUMachineGetKvmtypeFunc *kvm_type;
BlockInterfaceType block_default_type;
+ int units_per_default_bus;
int max_cpus;
unsigned int no_serial:1,
no_parallel:1,
@@ -86,6 +87,7 @@ struct MachineClass {
int (*kvm_type)(const char *arg);
BlockInterfaceType block_default_type;
+ int units_per_default_bus;
int max_cpus;
unsigned int no_serial:1,
no_parallel:1,
diff --git a/vl.c b/vl.c
index 4bc8f97..debcbcc 100644
--- a/vl.c
+++ b/vl.c
@@ -1585,6 +1585,7 @@ static void machine_class_init(ObjectClass *oc, void *data)
mc->hot_add_cpu = qm->hot_add_cpu;
mc->kvm_type = qm->kvm_type;
mc->block_default_type = qm->block_default_type;
+ mc->units_per_default_bus = qm->units_per_default_bus;
mc->max_cpus = qm->max_cpus;
mc->no_serial = qm->no_serial;
mc->no_parallel = qm->no_parallel;
@@ -4375,6 +4376,13 @@ int main(int argc, char **argv, char **envp)
blk_mig_init();
ram_mig_init();
+ /* If the currently selected machine wishes to override the units-per-bus
+ * property of its default HBA interface type, do so now. */
+ if (machine_class->units_per_default_bus) {
+ override_max_devs(machine_class->block_default_type,
+ machine_class->units_per_default_bus);
+ }
+
/* open the virtual block devices */
if (snapshot)
qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
commit 21dff8cf38d311a917ab33f19d5cea7696f0c354
Author: John Snow <jsnow at redhat.com>
Date: Wed Oct 1 14:19:25 2014 -0400
blockdev: Allow overriding if_max_dev property
The if_max_devs table as in the past been an immutable
default that controls the mapping of index => (bus,unit)
for all boards and all HBAs for each interface type.
Since adding this mapping information to the HBA device
itself is currently unwieldly from the perspective of
retrieving this information at option parsing time
(e.g, within drive_new), we consider the alternative
of marking the if_max_devs table mutable so that
later configuration and initialization can adjust the
mapping at will, but only up until a drive is added,
at which point the mapping is finalized.
Signed-off-by: John Snow <jsnow at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Message-id: 1412187569-23452-3-git-send-email-jsnow at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/blockdev.c b/blockdev.c
index 48da1a7..1780d77 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -60,7 +60,7 @@ static const char *const if_name[IF_COUNT] = {
[IF_XEN] = "xen",
};
-static const int if_max_devs[IF_COUNT] = {
+static int if_max_devs[IF_COUNT] = {
/*
* Do not change these numbers! They govern how drive option
* index maps to unit and bus. That mapping is ABI.
@@ -79,6 +79,30 @@ static const int if_max_devs[IF_COUNT] = {
[IF_SCSI] = 7,
};
+/**
+ * Boards may call this to offer board-by-board overrides
+ * of the default, global values.
+ */
+void override_max_devs(BlockInterfaceType type, int max_devs)
+{
+ DriveInfo *dinfo;
+
+ if (max_devs <= 0) {
+ return;
+ }
+
+ QTAILQ_FOREACH(dinfo, &drives, next) {
+ if (dinfo->type == type) {
+ fprintf(stderr, "Cannot override units-per-bus property of"
+ " the %s interface, because a drive of that type has"
+ " already been added.\n", if_name[type]);
+ g_assert_not_reached();
+ }
+ }
+
+ if_max_devs[type] = max_devs;
+}
+
/*
* We automatically delete the drive when a device using it gets
* unplugged. Questionable feature, but we can't just drop it.
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 3040286..a4033d4 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -46,6 +46,8 @@ struct DriveInfo {
QTAILQ_ENTRY(DriveInfo) next;
};
+void override_max_devs(BlockInterfaceType type, int max_devs);
+
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
bool drive_check_orphaned(void);
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
commit a66c9dc734fb30de1e18e9dc217f2d37e16c492a
Author: John Snow <jsnow at redhat.com>
Date: Wed Oct 1 14:19:24 2014 -0400
blockdev: Orphaned drive search
When users use command line options like -hda, -cdrom,
or even -drive if=ide, it is up to the board initialization
routines to pick up these drives and create backing
devices for them.
Some boards, like Q35, have not been doing this.
However, there is no warning explaining why certain
drive specifications are just silently ignored,
so this function adds a check to print some warnings
to assist users in debugging these sorts of issues
in the future.
This patch will not warn about drives added with if_none,
for which it is not possible to tell in advance if
the omission of a backing device is an issue.
A warning in these cases is considered appropriate.
Signed-off-by: John Snow <jsnow at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Message-id: 1412187569-23452-2-git-send-email-jsnow at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/blockdev.c b/blockdev.c
index dc94ad3..48da1a7 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -166,6 +166,27 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
return NULL;
}
+bool drive_check_orphaned(void)
+{
+ DriveInfo *dinfo;
+ bool rs = false;
+
+ QTAILQ_FOREACH(dinfo, &drives, next) {
+ /* If dinfo->bdrv->dev is NULL, it has no device attached. */
+ /* Unless this is a default drive, this may be an oversight. */
+ if (!dinfo->bdrv->dev && !dinfo->is_default &&
+ dinfo->type != IF_NONE) {
+ fprintf(stderr, "Warning: Orphaned drive without device: "
+ "id=%s,file=%s,if=%s,bus=%d,unit=%d\n",
+ dinfo->id, dinfo->bdrv->filename, if_name[dinfo->type],
+ dinfo->bus, dinfo->unit);
+ rs = true;
+ }
+ }
+
+ return rs;
+}
+
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index)
{
return drive_get(type,
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index abec381..3040286 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -38,6 +38,7 @@ struct DriveInfo {
int unit;
int auto_del; /* see blockdev_mark_auto_del() */
bool enable_auto_del; /* Only for legacy drive_new() */
+ bool is_default; /* Added by default_drive() ? */
int media_cd;
int cyls, heads, secs, trans;
QemuOpts *opts;
@@ -46,6 +47,7 @@ struct DriveInfo {
};
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
+bool drive_check_orphaned(void);
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
int drive_get_max_bus(BlockInterfaceType type);
DriveInfo *drive_get_next(BlockInterfaceType type);
diff --git a/vl.c b/vl.c
index 9d2aaaf..4bc8f97 100644
--- a/vl.c
+++ b/vl.c
@@ -1169,6 +1169,7 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type,
int index, const char *optstr)
{
QemuOpts *opts;
+ DriveInfo *dinfo;
if (!enable || drive_get_by_index(type, index)) {
return;
@@ -1178,9 +1179,13 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type,
if (snapshot) {
drive_enable_snapshot(opts, NULL);
}
- if (!drive_new(opts, type)) {
+
+ dinfo = drive_new(opts, type);
+ if (!dinfo) {
exit(1);
}
+ dinfo->is_default = true;
+
}
void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
@@ -4457,6 +4462,9 @@ int main(int argc, char **argv, char **envp)
if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0)
exit(1);
+ /* Did we create any drives that we failed to create a device for? */
+ drive_check_orphaned();
+
net_check_clients();
ds = init_displaystate();
commit cf77b2d25eeabe268412cf41d4ea38ec5de8c611
Author: Kevin Wolf <kwolf at redhat.com>
Date: Tue Sep 30 13:27:10 2014 +0200
qemu-iotests: Fix supported cache modes for 052
The requirement for this test case is really "no O_DIRECT", because the
temporary snapshot for BDRV_O_SNAPSHOT is created in /tmp, which often
is a tmpfs.
Commit f210a83c ('qemu-iotests: Add _default_cache_mode and
_supported_cache_modes') turned the restriction into writethrough-only,
but that's not really necessary.
Allow to run the test for any non-O_DIRECT cache modes, and use the
global default of writeback if no cache mode is specified.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Message-id: 1412076430-11623-3-git-send-email-kwolf at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
index 6bdae92..61959e2 100755
--- a/tests/qemu-iotests/052
+++ b/tests/qemu-iotests/052
@@ -41,8 +41,9 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt generic
_supported_proto file
_supported_os Linux
-_default_cache_mode "writethrough"
-_supported_cache_modes "writethrough"
+
+# Don't do O_DIRECT on tmpfs
+_supported_cache_modes "writeback" "writethrough" "unsafe"
size=128M
_make_test_img $size
commit d9323e9b20b1a74720f17e81387cffe013d9cf0b
Author: Kevin Wolf <kwolf at redhat.com>
Date: Tue Sep 30 13:27:09 2014 +0200
make check-block: Use default cache modes
When qemu-iotests only gave a choice between cache=none and
cache=writethrough, we picked cache=none because it was the option that
would complete the test in finite time. Some tests could only work for
one of the two options and would be skipped with cache=none, but that
was an acceptable trade-off at the time.
Today, however, qemu-iotests is a bit more flexible than that and you
can specify any of the cache modes supported by qemu. The default is
writeback, like in qemu, which is fast and (unlike cache=none) compatible
with any host filesystem. Test cases that have specific requirements for
the cache mode can also specify a different default.
In order to get a fast test run that works everywhere and doesn't skip
tests that need a different cache mode, not specifying any cache mode
and instead relying on the default is the best we can do today.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Message-id: 1412076430-11623-2-git-send-email-kwolf at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/tests/qemu-iotests-quick.sh b/tests/qemu-iotests-quick.sh
index 8a9a4c6..12af731 100755
--- a/tests/qemu-iotests-quick.sh
+++ b/tests/qemu-iotests-quick.sh
@@ -3,6 +3,6 @@
cd tests/qemu-iotests
ret=0
-./check -T -nocache -qcow2 -g quick || ret=1
+./check -T -qcow2 -g quick || ret=1
exit $ret
commit 20d6cd47d0459bdc6a8b64e7abe8f713e0d4718e
Author: Jun Li <junmuzi at gmail.com>
Date: Wed Sep 24 13:45:27 2014 +0800
Modify qemu_opt_rename to realize renaming all items in opts
Add realization of rename all items in opts for qemu_opt_rename.
e.g:
When add bps twice in command line, need to rename all bps to
throttling.bps-total.
This patch solved following bug:
Bug 1145586 - qemu-kvm will give strange hint when add bps twice for a drive
ref:https://bugzilla.redhat.com/show_bug.cgi?id=1145586
[Resolved conflict with commit 5abbf0ee4d87c695deb1c3fca9bb994b93a3e3be
("block: Catch simultaneous usage of options and their aliases"). Check
for simultaneous use first, and then loop over all options.
--Stefan]
Signed-off-by: Jun Li <junmuzi at gmail.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1411537527-16715-1-git-send-email-junmuzi at gmail.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/blockdev.c b/blockdev.c
index 2f441c5..dc94ad3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -548,6 +548,10 @@ static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
"same time", to, from);
return;
}
+ }
+
+ /* rename all items in opts */
+ while ((value = qemu_opt_get(opts, from))) {
qemu_opt_set(opts, to, value);
qemu_opt_unset(opts, from);
}
commit d1319b077a4bd980ca1b8a167b02b519330dd26b
Author: Fam Zheng <famz at redhat.com>
Date: Tue Sep 23 09:56:21 2014 +0800
vmdk: Fix integer overflow in offset calculation
This fixes the bug introduced by commit c6ac36e (vmdk: Optimize cluster
allocation).
$ ~/build/master/qemu-io /stor/vm/arch.vmdk -c 'write 2G 1k'
write failed: Invalid argument
Reported-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
Reviewed-by: Max Reitz <mreitz at redhat.com>
Signed-off-by: Fam Zheng <famz at redhat.com>
Message-id: 1411437381-11234-1-git-send-email-famz at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/block/vmdk.c b/block/vmdk.c
index afdea1a..4ae6c75 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1113,7 +1113,7 @@ static int get_cluster_offset(BlockDriverState *bs,
uint32_t min_count, *l2_table;
bool zeroed = false;
int64_t ret;
- int32_t cluster_sector;
+ int64_t cluster_sector;
if (m_data) {
m_data->valid = 0;
diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105
new file mode 100755
index 0000000..9bae49e
--- /dev/null
+++ b/tests/qemu-iotests/105
@@ -0,0 +1,70 @@
+#!/bin/bash
+#
+# Create, read, write big image
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=famz at redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2 vmdk vhdx qed
+_supported_proto generic
+_supported_os Linux
+_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
+ "subformat=twoGbMaxExtentSparse"
+
+echo
+echo "creating large image"
+_make_test_img 16T
+
+echo
+echo "small read"
+$QEMU_IO -c "read 1024 4096" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "small write"
+$QEMU_IO -c "write 8192 4096" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "small read at high offset"
+$QEMU_IO -c "read 14T 4096" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "small write at high offset"
+$QEMU_IO -c "write 14T 4096" "$TEST_IMG" | _filter_qemu_io
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/105.out b/tests/qemu-iotests/105.out
new file mode 100644
index 0000000..13ffcb5
--- /dev/null
+++ b/tests/qemu-iotests/105.out
@@ -0,0 +1,21 @@
+QA output created by 105
+
+creating large image
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=17592186044416
+
+small read
+read 4096/4096 bytes at offset 1024
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+small write
+wrote 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+small read at high offset
+read 4096/4096 bytes at offset 15393162788864
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+small write at high offset
+wrote 4096/4096 bytes at offset 15393162788864
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 622685e..b230996 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -105,3 +105,4 @@
101 rw auto quick
103 rw auto quick
104 rw auto
+105 rw auto quick
commit fbf28a4328123b3259d100eedc0e6f5b7f8bf186
Author: Markus Armbruster <armbru at redhat.com>
Date: Mon Sep 29 16:07:55 2014 +0200
block: Drop superfluous conditionals around qemu_opts_del()
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Reviewed-by: Eric Blake <eblake at redhat.com>
Message-id: 1411999675-14533-1-git-send-email-armbru at redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/blockdev.c b/blockdev.c
index ad43648..2f441c5 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -224,9 +224,7 @@ void drive_info_del(DriveInfo *dinfo)
if (!dinfo) {
return;
}
- if (dinfo->opts) {
- qemu_opts_del(dinfo->opts);
- }
+ qemu_opts_del(dinfo->opts);
g_free(dinfo->id);
QTAILQ_REMOVE(&drives, dinfo, next);
g_free(dinfo->serial);
diff --git a/qemu-img.c b/qemu-img.c
index ea4bbae..27b85db 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1736,9 +1736,7 @@ out:
qemu_opts_del(opts);
qemu_opts_free(create_opts);
qemu_vfree(buf);
- if (sn_opts) {
- qemu_opts_del(sn_opts);
- }
+ qemu_opts_del(sn_opts);
if (out_bs) {
bdrv_unref(out_bs);
}
diff --git a/qemu-nbd.c b/qemu-nbd.c
index fa60338..b524b34 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -778,9 +778,7 @@ int main(int argc, char **argv)
unlink(sockpath);
}
- if (sn_opts) {
- qemu_opts_del(sn_opts);
- }
+ qemu_opts_del(sn_opts);
if (device) {
void *ret;
commit 18fe46d79a6de61cb2c379fb610d834ef658d84b
Author: Richard W.M. Jones <rjones at redhat.com>
Date: Mon Sep 29 09:06:22 2014 +0100
ssh: Don't crash if either host or path is not specified.
$ ./qemu-img create -f qcow2 overlay \
-b 'json: { "file.driver":"ssh",
"file.host":"localhost",
"file.host_key_check":"no" }'
qemu-img: qobject/qdict.c:193: qdict_get_obj: Assertion `obj != ((void *)0)' failed.
Aborted
A similar crash also happens if the file.host field is omitted.
https://bugzilla.redhat.com/show_bug.cgi?id=1147343
Bug found and reported by Jun Li.
Signed-off-by: Richard W.M. Jones <rjones at redhat.com>
Reviewed-by: Gonglei <arei.gonglei at huawei.com>
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/block/ssh.c b/block/ssh.c
index cf43bc0..f466cbf 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -517,6 +517,11 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
const char *host, *user, *path, *host_key_check;
int port;
+ if (!qdict_haskey(options, "host")) {
+ ret = -EINVAL;
+ error_setg(errp, "No hostname was specified");
+ goto err;
+ }
host = qdict_get_str(options, "host");
if (qdict_haskey(options, "port")) {
@@ -525,6 +530,11 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
port = 22;
}
+ if (!qdict_haskey(options, "path")) {
+ ret = -EINVAL;
+ error_setg(errp, "No path was specified");
+ goto err;
+ }
path = qdict_get_str(options, "path");
if (qdict_haskey(options, "user")) {
commit af957387547b05ed6dc4d84c10cca42700a7aeda
Author: Zhang Haoyu <zhanghy at sangfor.com>
Date: Mon Sep 29 16:38:02 2014 +0800
snapshot: fix referencing wrong variable in while loop in do_delvm
The while loop variabal is "bs1",
but "bs" is always passed to bdrv_snapshot_delete_by_id_or_name.
Broken in commit a89d89d, v1.7.0.
Signed-off-by: Zhang Haoyu <zhanghy at sangfor.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
diff --git a/savevm.c b/savevm.c
index e19ae0a..2d8eb96 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1245,19 +1245,18 @@ int load_vmstate(const char *name)
void do_delvm(Monitor *mon, const QDict *qdict)
{
- BlockDriverState *bs, *bs1;
+ BlockDriverState *bs;
Error *err = NULL;
const char *name = qdict_get_str(qdict, "name");
- bs = find_vmstate_bs();
- if (!bs) {
+ if (!find_vmstate_bs()) {
monitor_printf(mon, "No block device supports snapshots\n");
return;
}
- bs1 = NULL;
- while ((bs1 = bdrv_next(bs1))) {
- if (bdrv_can_snapshot(bs1)) {
+ bs = NULL;
+ while ((bs = bdrv_next(bs))) {
+ if (bdrv_can_snapshot(bs)) {
bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
if (err) {
monitor_printf(mon,
More information about the Spice-commits
mailing list