Compare commits

..

50 Commits

Author SHA1 Message Date
Michael Roth
a58047f7fb Update version for 2.5.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-29 15:47:56 -05:00
Denis V. Lunev
5f409b108f hyperv: cpu hotplug fix with HyperV enabled
With Hyper-V enabled CPU hotplug stops working. The CPU appears
in device manager on Windows but does not appear in peformance
monitor and control panel.

The root of the problem is the following. Windows checks
HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE bit in CPUID. The
presence of this bit is enough to cure the situation.

The bit should be set when CPU hotplug is allowed for HyperV VM.
The check that hot_add_cpu callback is defined is enough from the
protocol point of view. Though this callback is defined almost
always thus there is no need to export that knowledge in the
other way.

Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Richard Henderson <rth@twiddle.net>
CC: Eduardo Habkost <ehabkost@redhat.com>
CC: "Andreas Färber" <afaerber@suse.de>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 4467c6c118)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 18:02:30 -05:00
Fam Zheng
078de11898 vmdk: Fix converting to streamOptimized
Commit d62d9dc4b8 lifted streamOptimized images's version to 3, but we
now refuse to open version 3 images read-write.  We need to make
streamOptimized an exception to allow converting to it. This fixes the
accidentally broken iotests case 059 for the same reason.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 3db1d98a20)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:41:10 -05:00
Fam Zheng
acea76c162 vmdk: Create streamOptimized as version 3
VMware products accept only version 3 for streamOptimized, let's bump
the version.

Reported-by: Radoslav Gerganov <rgerganov@vmware.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d62d9dc4b8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:41:04 -05:00
Prasad J Pandit
80b6e5723f usb: check USB configuration descriptor object
When processing remote NDIS control message packets, the USB Net
device emulator checks to see if the USB configuration descriptor
object is of RNDIS type(2). But it does not check if it is null,
which leads to a null dereference error. Add check to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455188480-14688-1-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 80eecda8e5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:56 -05:00
Prasad J Pandit
9bddb45dbc usb: check RNDIS message length
When processing remote NDIS control message packets, the USB Net
device emulator uses a fixed length(4096) data buffer. The incoming
packet length could exceed this limit. Add a check to avoid it.

Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455648821-17340-2-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 64c9bc181f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:52 -05:00
Prasad J Pandit
e3a2cdfcb5 usb: check RNDIS buffer offsets & length
When processing remote NDIS control message packets,
the USB Net device emulator uses a fixed length(4096) data buffer.
The incoming informationBufferOffset & Length combination could
overflow and cross that range. Check control message buffer
offsets and length to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455648821-17340-3-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fe3c546c5f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:46 -05:00
Prasad J Pandit
4dcd2f13b1 usb: check page select value while processing iTD
While processing isochronous transfer descriptors(iTD), the page
select(PG) field value could lead to an OOB read access. Add
check to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1453233406-12165-1-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 49d925ce50)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:40 -05:00
Prasad J Pandit
38e09211b6 net: ne2000: fix bounds check in ioport operations
While doing ioport r/w operations, ne2000 device emulation suffers
from OOB r/w errors. Update respective array bounds check to avoid
OOB access.

Reported-by: Ling Liu <liuling-it@360.cn>
Cc: qemu-stable@nongnu.org
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit aa7f9966df)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:34 -05:00
Prasad J Pandit
d0ee85b4e4 net: check packet payload length
While computing IP checksum, 'net_checksum_calculate' reads
payload length from the packet. It could exceed the given 'data'
buffer size. Add a check to avoid it.

Reported-by: Liu Ling <liuling-it@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 362786f14a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:27 -05:00
Prasad J Pandit
4f046a6ba1 ide: ahci: reset ncq object to unused on error
When processing NCQ commands, AHCI device emulation prepares a
NCQ transfer object; To which an aio control block(aiocb) object
is assigned in 'execute_ncq_command'. In case, when the NCQ
command is invalid, the 'aiocb' object is not assigned, and NCQ
transfer object is left as 'used'. This leads to a use after
free kind of error in 'bdrv_aio_cancel_async' via 'ahci_reset_port'.
Reset NCQ transfer object to 'unused' to avoid it.

[Maintainer edit: s/ACHI/AHCI/ in the commit message. --js]

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1452282511-4116-1-git-send-email-ppandit@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 4ab0359a8a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:20 -05:00
P J P
b47809c6b3 i386: avoid null pointer dereference
Hello,

A null pointer dereference issue was reported by Mr Ling Liu, CC'd here. It
occurs while doing I/O port write operations via hmp interface. In that,
'current_cpu' remains null as it is not called from cpu_exec loop, which
results in the said issue.

Below is a proposed (tested)patch to fix this issue; Does it look okay?

===
From ae88a4947fab9a148cd794f8ad2d812e7f5a1d0f Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Fri, 18 Dec 2015 11:16:07 +0530
Subject: [PATCH] i386: avoid null pointer dereference

When I/O port write operation is called from hmp interface,
'current_cpu' remains null, as it is not called from cpu_exec()
loop. This leads to a null pointer dereference in vapic_write
routine. Add check to avoid it.

Reported-by: Ling Liu <liuling-it@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <alpine.LFD.2.20.1512181129320.9805@wniryva>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: P J P <ppandit@redhat.com>
(cherry picked from commit 4c1396cb57)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:39:27 -05:00
Wolfgang Bumiller
24fe899c3c hmp: fix sendkey out of bounds write (CVE-2015-8619)
When processing 'sendkey' command, hmp_sendkey routine null
terminates the 'keyname_buf' array. This results in an OOB
write issue, if 'keyname_len' was to fall outside of
'keyname_buf' array.

Since the keyname's length is known the keyname_buf can be
removed altogether by adding a length parameter to
index_from_key() and using it for the error output as well.

Reported-by: Ling Liu <liuling-it@360.cn>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Message-Id: <20160113080958.GA18934@olga>
[Comparison with "<" dumbed down, test for junk after strtoul()
tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>

(cherry picked from commit 64ffbe04ea)

Conflicts:
	hmp.c

*removed dependency on 7fb1cf16

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:38:16 -05:00
John Snow
aaf4fb6afb ahci: Do not unmap NULL addresses
Definitely don't try to unmap a garbage address.

Reported-by: Zuozhi fzz <zuozhi.fzz@alibaba-inc.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1454103689-13042-2-git-send-email-jsnow@redhat.com
(cherry picked from commit 99b4cb7106)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:35:36 -05:00
Greg Kurz
a2ae168821 migration: allow machine to enforce configuration section migration
Migration of pseries-2.3 doesn't have configuration section. Unfortunately,
QEMU 2.4/2.4.1/2.5 are buggy and always stream and expect the configuration
section, and break migration both ways.

This patch introduces a property which allows to enforce a configuration
section for machines who don't have one.

It can be set at startup:

-machine enforce-config-section=on

or later from the QEMU monitor:

qom-set /machine enforce-config-section on

It is up to the tooling to set or unset this property according to the
version of the QEMU at the other end of the pipe.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 902c053d83)

Conflicts:
	qemu-options.hx

* removed context dependency on 87252e1b
* added to provide 2.5<->2.5.1 migration compat option for
  pseries-2.3 machines

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:20:12 -05:00
Marcel Apfelbaum
bad094d524 vl.c: Fix regression in machine error message
Commit e1ce0c3cb (vl.c: fix regression when reading machine type
from config file) fixed the error message when the machine type
was supplied inside the config file. However now the option name
is not displayed correctly if the error happens when the machine
is specified at command line.

Running
    ./x86_64-softmmu/qemu-system-x86_64 -M q35-1.5 -redir tcp:8022::22
will result in the error message:
    qemu-system-x86_64: -redir tcp:8022::22: unsupported machine type
    Use -machine help to list supported machines

Fixed it by restoring the error location and also extracted the code
dealing with machine options into a separate function.

Reported-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <1455303747-19776-2-git-send-email-ehabkost@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 34f405ae6d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 18:21:32 -05:00
Alberto Garcia
4b0b1ec8e0 quorum: Fix crash in quorum_aio_cb()
quorum_aio_cb() emits the QUORUM_REPORT_BAD event if there's
an I/O error in a Quorum child. However sacb->aiocb must be
correctly initialized for this to happen. read_quorum_children() and
read_fifo_child() are not doing this, which results in a QEMU crash.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 8138570d071ba7e25db3736979234a1fd71dbd05.1457610443.git.berto@igalia.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit b9c600d207)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 18:18:19 -05:00
Peter Maydell
cab1cc7245 target-arm: Make reserved ranges in ID_AA64* spaces RAZ, not UNDEF
The v8 ARM ARM defines that unused spaces in the ID_AA64* system
register ranges are Reserved and must RAZ, rather than being UNDEF.
Implement this.

In particular, ARM v8.2 adds a new feature register ID_AA64MMFR2,
and newer versions of the Linux kernel will attempt to read this,
which causes them not to boot up on versions of QEMU missing this fix.

Since the encoding .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6
is actually defined in ARMv8 (as ID_MMFR4), we give it an entry in
the ARMCPU struct so CPUs can override it, though since none do
this too will just RAZ.

Cc: qemu-stable@nongnu.org
Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1455890863-11203-1-git-send-email-peter.maydell@linaro.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
(cherry picked from commit e20d84c140)

Conflicts:
	target-arm/helper.c

* remove context dep on 4054bfa9

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:48:45 -05:00
Michael S. Tsirkin
9ae02175b4 vhost-user: don't merge regions with different fds
vhost currently merges regions with contiguious virtual and physical
addresses.  This breaks for vhost-user since that also needs fds to
match.

Add a vhost_ops entry to compare the fds for vhost-user only.

Cc: qemu-stable@nongnu.org
Cc: Victor Kaplansky <victork@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit ffe42cc14c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:36:07 -05:00
Laszlo Ersek
30929793b0 fw_cfg: unbreak migration compatibility for 2.4 and earlier machines
When I reviewed Marc's fw_cfg DMA patches, I completely missed that the
way we set dma_enabled would break migration.

Gerd explained the right way (see reference below): dma_enabled should be
set to true by default, and only true->false transitions should be
possible:

- when the user requests that with

    -global fw_cfg_mem.dma_enabled=off

  or

   -global fw_cfg_io.dma_enabled=off

  as appropriate for the platform,

- when HW_COMPAT_2_4 dictates it,

- when board code initializes fw_cfg without requesting DMA support.

Cc: Marc Marí <markmb@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Alexandre DERUMIER <aderumier@odiso.com>
Cc: qemu-stable@nongnu.org
Ref: http://thread.gmane.org/gmane.comp.emulators.qemu/390272/focus=391042
Ref: https://bugs.launchpad.net/qemu/+bug/1536487
Suggested-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 1455823860-22268-1-git-send-email-lersek@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e6915b5f3a)

Conflicts:
	include/hw/compat.h

* remove cosmetic dep on c9c0afbb

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:33:59 -05:00
Marcel Apfelbaum
c5c9841ce8 hw/virtio: group virtio flags into an enum
Minimizes the possibility to assign
the same bit to different features.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit fc1769b758)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:25:13 -05:00
Marcel Apfelbaum
6b62303eb8 hw/virtio: fix double use of a virtio flag
Commits 1811e64c and a6df8adf use the same virtio feature bit 4
for different features.

Fix it by using different bits.

Reported-by: Laurent Vivier <lvivier@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 631a438755)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:24:57 -05:00
Greg Kurz
c06f342009 spapr: skip configuration section during migration of older machines
Since QEMU 2.4, we have a configuration section in the migration stream.
This must be skipped for older machines, like it is already done for x86.

This patch fixes the migration of pseries-2.3 from/to QEMU 2.3, but it
breaks migration of the same machine from/to QEMU 2.4/2.4.1/2.5. We do
that anyway because QEMU 2.3 is likely to be more widely deployed than
newer QEMU versions.

Fixes: 61964c23e5
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 09b5e30da5)

Conflicts:
	hw/ppc/spapr.c

*remove dep on 5013c5474

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:17:33 -05:00
Laszlo Ersek
cb873eaa6d e1000: eliminate infinite loops on out-of-bounds transfer start
The start_xmit() and e1000_receive_iov() functions implement DMA transfers
iterating over a set of descriptors that the guest's e1000 driver
prepares:

- the TDLEN and RDLEN registers store the total size of the descriptor
  area,

- while the TDH and RDH registers store the offset (in whole tx / rx
  descriptors) into the area where the transfer is supposed to start.

Each time a descriptor is processed, the TDH and RDH register is bumped
(as appropriate for the transfer direction).

QEMU already contains logic to deal with bogus transfers submitted by the
guest:

- Normally, the transmit case wants to increase TDH from its initial value
  to TDT. (TDT is allowed to be numerically smaller than the initial TDH
  value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
  that QEMU currently has here is a check against reaching the original
  TDH value again -- a complete wraparound, which should never happen.

- In the receive case RDH is increased from its initial value until
  "total_size" bytes have been received; preferably in a single step, or
  in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
  RX descriptors are skipped without receiving data, while RDH is
  incremented just the same. QEMU tries to prevent an infinite loop
  (processing only null RX descriptors) by detecting whether RDH assumes
  its original value during the loop. (Again, wrapping from RDLEN to 0 is
  normal.)

What both directions miss is that the guest could program TDLEN and RDLEN
so low, and the initial TDH and RDH so high, that these registers will
immediately be truncated to zero, and then never reassume their initial
values in the loop -- a full wraparound will never occur.

The condition that expresses this is:

  xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)

i.e., TDH or RDH start out after the last whole rx or tx descriptor that
fits into the TDLEN or RDLEN sized area.

This condition could be checked before we enter the loops, but
pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
bogus DMA addresses, so we just extend the existing failsafes with the
above condition.

This is CVE-2016-1981.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Petr Matousek <pmatouse@redhat.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Prasad Pandit <ppandit@redhat.com>
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: qemu-stable@nongnu.org
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit dd793a7488)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:55:27 -05:00
Jeff Cody
4853a5a80f block: qemu-iotests - add test for snapshot, commit, snapshot bug
Signed-off-by: Jeff Cody <jcody@redhat.com>
Message-id: 2dbc05efba2f683cb3aaf71aaa9b776ebf7ec57c.1454376655.git.jcody@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[Moved test number from 143 to 144]
Signed-off-by: Max Reitz <mreitz@redhat.com>

(cherry picked from commit 8983b670f6)

Conflicts:
	tests/qemu-iotests/group

*removed context dependencies on newer test groups

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:53:35 -05:00
Jeff Cody
a375e0b03e block: set device_list.tqe_prev to NULL on BDS removal
This fixes a regression introduced with commit 3f09bfbc7.  Multiple
bugs arise in conjunction with live snapshots and mirroring operations
(which include active layer commit).

After a live snapshot occurs, the active layer and the base layer both
have a non-NULL tqe_prev field in the device_list, although the base
node's tqe_prev field points to a NULL entry.  This non-NULL tqe_prev
field occurs after the bdrv_append() in the external snapshot calls
change_parent_backing_link().

In change_parent_backing_link(), when the previous active layer is
removed from device_list, the device_list.tqe_prev pointer is not
set to NULL.

The operating scheme in the block layer is to indicate that a BDS belongs
in the bdrv_states device_list iff the device_list.tqe_prev pointer
is non-NULL.

This patch does two things:

1.) Introduces a new block layer helper bdrv_device_remove() to remove a
    BDS from the device_list, and
2.) uses that new API, which also fixes the regression once used in
    change_parent_backing_link().

Signed-off-by: Jeff Cody <jcody@redhat.com>
Message-id: 0cd51e11c0666c04ddb7c05293fe94afeb551e89.1454376655.git.jcody@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit f8aa905a4f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:51:48 -05:00
Eric Blake
a38a283fc7 qmp: Fix reference-counting of qnull on empty output visit
Commit 6c2f9a15 ensured that we would not return NULL when the
caller used an output visitor but had nothing to visit. But
in doing so, it added a FIXME about a reference count leak
that could abort qemu in the (unlikely) case of SIZE_MAX such
visits (more plausible on 32-bit).  (Although that commit
suggested we might fix it in time for 2.5, we ran out of time;
fortunately, it is unlikely enough to bite that it was not
worth worrying about during the 2.5 release.)

This fixes things by documenting the internal contracts, and
explaining why the internal function can return NULL and only
the public facing interface needs to worry about qnull(),
thus avoiding over-referencing the qnull_ global object.

It does not, however, fix the stupidity of the stack mixing
up two separate pieces of information; add a FIXME to explain
that issue, which will be fixed shortly in a future patch.

Signed-off-by: Eric Blake <eblake@redhat.com>
Cc: qemu-stable@nongnu.org
Message-Id: <1454075341-13658-25-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit a861564015)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:50:34 -05:00
Dr. David Alan Gilbert
225d50fbb1 cpus: use broadcast on qemu_pause_cond
Jiri saw a hang on pause_all_vcpus called from postcopy_start,
where the cpus are all apparently stopped ('stopped' flag set)
but pause_all_vcpus is still stuck on a cond_wait on qemu_paused_cond.
We suspect this is happening if a qmp_stop is called at about the
same time as the postcopy code calls that pause_all_vcpus;
although they both should have the main lock held, Paolo spotted
the cond_wait unlocks the global lock so perhaps they both
could end up waiting at the same time?

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reported-by: Jiri Denemark <jdenemar@redhat.com>
Message-Id: <1453716498-27238-1-git-send-email-dgilbert@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 96bce6831b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:47:04 -05:00
Gabriel L. Somlo
020282d3e6 fw_cfg: avoid calculating invalid current entry pointer
When calculating a pointer to the currently selected fw_cfg item, the
following is used:

  FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];

When s->cur_entry is FW_CFG_INVALID, we are calculating the address of
a non-existent element in s->entries[arch][...], which is undefined.

This patch ensures the resulting entry pointer is set to NULL whenever
s->cur_entry is FW_CFG_INVALID.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Message-id: 1446733972-1602-5-git-send-email-somlo@cmu.edu
Cc: Marc Marí <markmb@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 66f8fd9dda)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:45:24 -05:00
Halil Pasic
091af18104 s390x/css: fix control flags during csch
From the beginning, css support contained an error in csch handling:
instead of setting the clear bit in the function control bits twice, we
need to set the clear pending bit in the activity control bits. Let's
fix this.

Cc: qemu-stable@nongnu.org
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit 4c6bf79a22)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:42:26 -05:00
Pierre Morel
d98392379a s390x/ioinst: set type and len for SEI response
If no event information is pending, the return code
is set to 0x0005 and the length of the response is
set to 8 bytes.

Signed-off-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Song Shan Gong <gongss@linux.vnet.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit f70202be53)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:42:13 -05:00
Christian Borntraeger
643c8d8ec1 block/raw-posix: avoid bogus fixup for cylinders on DASD disks
large volume DASD that have > 64k cylinders do claim to have
0xFFFE cylinders as special value in the old 16 bit field. We
want to pass this "token" along to the guest, instead of
calculating the real number. Otherwise qemu might fail with
"cyls must be between 1 and 65535"

Cc: qemu-stable@nongnu.org
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 972b543c6b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:41:43 -05:00
Gerd Hoffmann
3ede27db32 ehci: update irq on reset
After clearing the status register we also have to update the irq line
status.  Otherwise a irq which happends to be pending at reset time
causes a interrupt storm.  And the guest can't stop as the status
register doesn't indicate any pending interrupt.

Both NetBSD and FreeBSD hang on shutdown because of that.

Cc: qemu-stable@nongnu.org
Reported-by: Andrey Korolyov <andrey@xdel.ru>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1453203884-4125-1-git-send-email-kraxel@redhat.com
(cherry picked from commit 5a8660741a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:41:14 -05:00
Laurent Vivier
9849b1912f net: set endianness on all backend devices
commit 5be7d9f1b1
       vhost-net: tell tap backend about the vnet endianness

makes vhost net to set the endianness of the device, but only for
the first device.

In case of multiqueue, we have multiple devices... This patch sets the
endianness for all the devices of the interface.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit a407644079)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:36:19 -05:00
Prasad J Pandit
fe90bdc25b net: ne2000: check ring buffer control registers
Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152)
bytes to process network packets. Registers PSTART & PSTOP
define ring buffer size & location. Setting these registers
to invalid values could lead to infinite loop or OOB r/w
access issues. Add check to avoid it.

Reported-by: Yang Hongke <yanghongke@huawei.com>
Tested-by: Yang Hongke <yanghongke@huawei.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 415ab35a44)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:34:56 -05:00
Li Zhijian
aaa5271327 net/filter: fix nf->netdev_id leak
Cc: Jason Wang <jasowang@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 671f66f87f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:34:23 -05:00
Li Zhijian
abda95cb01 net/dump: fix nfds->filename leak
Cc: Jason Wang <jasowang@redhat.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit b50c7d452f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:34:15 -05:00
Max Reitz
6a49a71cc6 blockdev: Fix 'change' for slot devices
'change' and related operations did not work when used on guest devices
featuring removable media but no actual tray, because
blk_dev_is_tray_open() always returned false for them and the
blockdev-{insert,remove}-medium commands required it to return true.

Fix this by making blockdev-{insert,remove}-medium work on tray-less
devices. Also, blockdev-{open,close}-tray are now explicitly no-ops when
invoked on such devices, and blk_dev_change_media_cb() is instead
called by blockdev-{insert,remove}-medium (for tray-less devices only).

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1454096953-31773-3-git-send-email-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 12c7ec87a7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:23:54 -05:00
Max Reitz
e1a8a09124 block: Add blk_dev_has_tray()
Pull out the check whether a block device has a tray from
blk_dev_is_tray_open() into its own function so both attributes (whether
there is a tray vs. whether that tray is open) can be queried
independently.

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1454096953-31773-2-git-send-email-mreitz@redhat.com
(cherry picked from commit 8f3a73bc57)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:23:28 -05:00
Prasad J Pandit
7a2c1c8e66 net: rocker: fix an incorrect array bounds check
While processing transmit(tx) descriptors in 'tx_consume' routine
the switch emulator suffers from an off-by-one error, if a
descriptor was to have more than allowed(ROCKER_TX_FRAGS_MAX=16)
fragments. Fix an incorrect bounds check to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 007cd223de)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:39:32 -05:00
Marc-André Lureau
702a8d165c ivshmem: remove redundant assignment, fix crash with msi=off
Fix crash when msi=false introduced in 660c97ee (msi_vectors is NULL in
this case)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 47213eb110)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:35:51 -05:00
Marc-André Lureau
3e96d5dcf2 ivshmem: no need for opaque argument
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 2c64846972)
*context dependency for 47213eb
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:35:25 -05:00
P J P
16a2875735 scsi: initialise info object with appropriate size
While processing controller 'CTRL_GET_INFO' command, the routine
'megasas_ctrl_get_info' overflows the '&info' object size. Use its
appropriate size to null initialise it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <alpine.LFD.2.20.1512211501420.22471@wniryva>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: P J P <ppandit@redhat.com>
(cherry picked from commit 36fef36b91)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:21:11 -05:00
Greg Kurz
4588b0d856 virtio-9p: use accessor to get thread_pool
The aio_context_new() function does not allocate a thread pool. This is
deferred to the first call to the aio_get_thread_pool() accessor. It is
hence forbidden to access the thread_pool field directly, as it may be
NULL. The accessor *must* be used always.

Fixes: ebac1202c9
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: qemu-stable@nongnu.org
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
(cherry picked from commit 4b3a4f2d45)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:20:55 -05:00
Stefano Stabellini
ff083d3c3b xenfb: avoid reading twice the same fields from the shared page
Reading twice the same field could give the guest an attack of
opportunity. In the case of event->type, gcc could compile the switch
statement into a jump table, effectively ending up reading the type
field multiple times.

This is part of XSA-155.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
(cherry picked from commit 7ea11bf376)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:20:35 -05:00
Stefano Stabellini
4d59e78dfe xen/blkif: Avoid double access to src->nr_segments
src is stored in shared memory and src->nr_segments is dereferenced
twice at the end of the function.  If a compiler decides to compile this
into two separate memory accesses then the size limitation could be
bypassed.

Fix it by removing the double access to src->nr_segments.

This is part of XSA-155.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
(cherry picked from commit f9e98e5d7a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:20:17 -05:00
Peter Maydell
52a7b27947 configure: Fix shell syntax to placate OpenBSD's pdksh
Unfortunately the OpenBSD pdksh does not like brackets inside
the right part of a ${variable+word} parameter expansion:

  $ echo "${a+($b)}"
  ksh: ${a+($b)}": bad substitution

though both bash and dash accept them. In any case this line
was causing odd output in the case where nettle is not present:
  nettle    no ()

(because if nettle is not present then $nettle will be "no",
not a null string or unset).

Rewrite it to just use an if.

This bug was originally introduced in becaeb726 and was present
in the 2.4.0 release.

Fixes: https://bugs.launchpad.net/qemu/+bug/1525682
Reported-by: Dmitrij D. Czarkoff
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1450105357-8516-1-git-send-email-peter.maydell@linaro.org
(cherry picked from commit 18f49881cf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:19:47 -05:00
Greg Kurz
d4aed70099 target-ppc: kvm: fix floating point registers sync on little-endian hosts
On VSX capable CPUs, the 32 FP registers are mapped to the high-bits
of the 32 first VSX registers. So if you have:

VSR31 = (uint128) 0x0102030405060708090a0b0c0d0e0f00

then

FPR31 = (uint64) 0x0102030405060708

The kernel stores the VSX registers in the fp_state struct following the
host endian element ordering.

On big-endian:

fp_state.fpr[31][0] = 0x0102030405060708
fp_state.fpr[31][1] = 0x090a0b0c0d0e0f00

On little-endian:

fp_state.fpr[31][0] = 0x090a0b0c0d0e0f00
fp_state.fpr[31][1] = 0x0102030405060708

The KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctls preserve this ordering, but
QEMU considers it as big-endian and always copies element [0] to the
fpr[] array and element [1] to the vsr[] array. This does not work with
little-endian hosts, and you will get:

(qemu) p $f31
0x90a0b0c0d0e0f00

instead of:

(qemu) p $f31
0x102030405060708

This patch fixes the element ordering for little-endian hosts.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 3a4b791b4c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:10:47 -05:00
P J P
42ae4a3c61 net: vmxnet3: avoid memory leakage in activate_device
Vmxnet3 device emulator does not check if the device is active
before activating it, also it did not free the transmit & receive
buffers while deactivating the device, thus resulting in memory
leakage on the host. This patch fixes both these issues to avoid
host memory leakage.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit aa4a3dce1c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:08:24 -05:00
Gerd Hoffmann
0d335804e3 ehci: make idt processing more robust
Make ehci_process_itd return an error in case we didn't do any actual
iso transfer because we've found no active transaction.  That'll avoid
ehci happily run in circles forever if the guest builds a loop out of
idts.

This is CVE-2015-8558.

Cc: qemu-stable@nongnu.org
Reported-by: Qinghao Tang <luodalongde@gmail.com>
Tested-by: P J P <ppandit@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 156a2e4dbf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:07:11 -05:00
1480 changed files with 31916 additions and 51754 deletions

View File

@@ -273,12 +273,9 @@ F: */xen*
F: hw/char/xen_console.c
F: hw/display/xenfb.c
F: hw/net/xen_nic.c
F: hw/block/xen_*
F: hw/xen/
F: hw/xenpv/
F: hw/i386/xen/
F: include/hw/xen/
F: include/sysemu/xen-mapcache.h
Hosts:
------
@@ -590,7 +587,7 @@ F: hw/ppc/prep.c
F: hw/pci-host/prep.[hc]
F: hw/isa/pc87312.[hc]
sPAPR
sPAPR (pseries)
M: David Gibson <david@gibson.dropbear.id.au>
M: Alexander Graf <agraf@suse.de>
L: qemu-ppc@nongnu.org
@@ -944,13 +941,6 @@ M: Jiri Pirko <jiri@resnulli.us>
S: Maintained
F: hw/net/rocker/
NVDIMM
M: Xiao Guangrong <guangrong.xiao@linux.intel.com>
S: Maintained
F: hw/acpi/nvdimm.c
F: hw/mem/nvdimm.c
F: include/hw/mem/nvdimm.h
Subsystems
----------
Audio
@@ -1039,8 +1029,7 @@ Device Tree
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
M: Alexander Graf <agraf@suse.de>
S: Maintained
F: device_tree.c
F: include/sysemu/device_tree.h
F: device_tree.[ch]
Error reporting
M: Markus Armbruster <armbru@redhat.com>
@@ -1119,9 +1108,8 @@ F: net/netmap.c
Network Block Device (NBD)
M: Paolo Bonzini <pbonzini@redhat.com>
S: Odd Fixes
F: block/nbd*
F: nbd/
F: include/block/nbd*
F: block/nbd.c
F: nbd.*
F: qemu-nbd.c
T: git git://github.com/bonzini/qemu.git nbd-next
@@ -1204,7 +1192,6 @@ SLIRP
M: Jan Kiszka <jan.kiszka@siemens.com>
S: Maintained
F: slirp/
F: net/slirp.c
T: git git://git.kiszka.org/qemu.git queues/slirp
Tracing
@@ -1256,21 +1243,6 @@ S: Odd fixes
F: util/buffer.c
F: include/qemu/buffer.h
I/O Channels
M: Daniel P. Berrange <berrange@redhat.com>
S: Maintained
F: io/
F: include/io/
F: tests/test-io-*
Sockets
M: Daniel P. Berrange <berrange@redhat.com>
M: Gerd Hoffmann <kraxel@redhat.com>
M: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: include/qemu/sockets.h
F: util/qemu-sockets.c
Usermode Emulation
------------------
Overall
@@ -1511,7 +1483,6 @@ M: Denis V. Lunev <den@openvz.org>
L: qemu-block@nongnu.org
S: Supported
F: block/parallels.c
F: docs/specs/parallels.txt
qed
M: Stefan Hajnoczi <stefanha@redhat.com>

View File

@@ -159,7 +159,6 @@ dummy := $(call unnest-vars,, \
crypto-obj-y \
crypto-aes-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
common-obj-m)
@@ -179,7 +178,6 @@ SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES))
$(SOFTMMU_SUBDIR_RULES): $(block-obj-y)
$(SOFTMMU_SUBDIR_RULES): $(crypto-obj-y)
$(SOFTMMU_SUBDIR_RULES): $(io-obj-y)
$(SOFTMMU_SUBDIR_RULES): config-all-devices.mak
subdir-%:
@@ -240,7 +238,7 @@ qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuu
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o libqemuutil.a libqemustub.a
fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o libqemuutil.a libqemustub.a
fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
@@ -271,8 +269,7 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
$(SRC_PATH)/qapi/event.json $(SRC_PATH)/qapi/introspect.json \
$(SRC_PATH)/qapi/crypto.json
$(SRC_PATH)/qapi/event.json $(SRC_PATH)/qapi/introspect.json
qapi-types.c qapi-types.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)

View File

@@ -8,8 +8,7 @@ util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o
# block-obj-y is code used by both qemu system emulation and qemu-img
block-obj-y = async.o thread-pool.o
block-obj-y += nbd/
block-obj-y += block.o blockjob.o
block-obj-y += nbd.o block.o blockjob.o
block-obj-y += main-loop.o iohandler.o qemu-timer.o
block-obj-$(CONFIG_POSIX) += aio-posix.o
block-obj-$(CONFIG_WIN32) += aio-win32.o
@@ -29,11 +28,6 @@ crypto-aes-obj-y = crypto/
qom-obj-y = qom/
#######################################################################
# io-obj-y is code used by both qemu system emulation and qemu-img
io-obj-y = io/
######################################################################
# Target independent part of system emulation. The long term path is to
# suppress *all* target specific code in case of system emulation, i.e. a

View File

@@ -176,7 +176,6 @@ dummy := $(call unnest-vars,.., \
crypto-obj-y \
crypto-aes-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
common-obj-m)
target-obj-y := $(target-obj-y-save)
@@ -186,7 +185,6 @@ all-obj-y += $(qom-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
$(QEMU_PROG_BUILD): config-devices.mak

View File

@@ -1 +1 @@
2.5.50
2.5.1

View File

@@ -258,7 +258,9 @@ void do_acpitable_option(const QemuOpts *opts)
acpi_table_add(opts, &err);
if (err) {
error_reportf_err(err, "Wrong acpi table provided: ");
error_report("Wrong acpi table provided: %s",
error_get_pretty(err));
error_free(err);
exit(1);
}
#endif

View File

@@ -1806,6 +1806,9 @@ static void audio_init (void)
atexit (audio_atexit);
s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
if (!s->ts) {
hw_error("Could not create audio timer\n");
}
audio_process_options ("AUDIO", audio_options);
@@ -1856,8 +1859,12 @@ static void audio_init (void)
if (!done) {
done = !audio_driver_init (s, &no_audio_driver);
assert(done);
dolog("warning: Using timer based audio emulation\n");
if (!done) {
hw_error("Could not initialize audio subsystem\n");
}
else {
dolog ("warning: Using timer based audio emulation\n");
}
}
if (conf.period.hertz <= 0) {

View File

@@ -32,10 +32,6 @@
#define AUDIO_CAP "coreaudio"
#include "audio_int.h"
#ifndef MAC_OS_X_VERSION_10_6
#define MAC_OS_X_VERSION_10_6 1060
#endif
static int isAtexit;
typedef struct {
@@ -49,233 +45,11 @@ typedef struct coreaudioVoiceOut {
AudioDeviceID outputDeviceID;
UInt32 audioDevicePropertyBufferFrameSize;
AudioStreamBasicDescription outputStreamBasicDescription;
AudioDeviceIOProcID ioprocid;
int live;
int decr;
int rpos;
} coreaudioVoiceOut;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
/* The APIs used here only become available from 10.6 */
static OSStatus coreaudio_get_voice(AudioDeviceID *id)
{
UInt32 size = sizeof(*id);
AudioObjectPropertyAddress addr = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
return AudioObjectGetPropertyData(kAudioObjectSystemObject,
&addr,
0,
NULL,
&size,
id);
}
static OSStatus coreaudio_get_framesizerange(AudioDeviceID id,
AudioValueRange *framerange)
{
UInt32 size = sizeof(*framerange);
AudioObjectPropertyAddress addr = {
kAudioDevicePropertyBufferFrameSizeRange,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
return AudioObjectGetPropertyData(id,
&addr,
0,
NULL,
&size,
framerange);
}
static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize)
{
UInt32 size = sizeof(*framesize);
AudioObjectPropertyAddress addr = {
kAudioDevicePropertyBufferFrameSize,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
return AudioObjectGetPropertyData(id,
&addr,
0,
NULL,
&size,
framesize);
}
static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize)
{
UInt32 size = sizeof(*framesize);
AudioObjectPropertyAddress addr = {
kAudioDevicePropertyBufferFrameSize,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
return AudioObjectSetPropertyData(id,
&addr,
0,
NULL,
size,
framesize);
}
static OSStatus coreaudio_get_streamformat(AudioDeviceID id,
AudioStreamBasicDescription *d)
{
UInt32 size = sizeof(*d);
AudioObjectPropertyAddress addr = {
kAudioDevicePropertyStreamFormat,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
return AudioObjectGetPropertyData(id,
&addr,
0,
NULL,
&size,
d);
}
static OSStatus coreaudio_set_streamformat(AudioDeviceID id,
AudioStreamBasicDescription *d)
{
UInt32 size = sizeof(*d);
AudioObjectPropertyAddress addr = {
kAudioDevicePropertyStreamFormat,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
return AudioObjectSetPropertyData(id,
&addr,
0,
NULL,
size,
d);
}
static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result)
{
UInt32 size = sizeof(*result);
AudioObjectPropertyAddress addr = {
kAudioDevicePropertyDeviceIsRunning,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
return AudioObjectGetPropertyData(id,
&addr,
0,
NULL,
&size,
result);
}
#else
/* Legacy versions of functions using deprecated APIs */
static OSStatus coreaudio_get_voice(AudioDeviceID *id)
{
UInt32 size = sizeof(*id);
return AudioHardwareGetProperty(
kAudioHardwarePropertyDefaultOutputDevice,
&size,
id);
}
static OSStatus coreaudio_get_framesizerange(AudioDeviceID id,
AudioValueRange *framerange)
{
UInt32 size = sizeof(*framerange);
return AudioDeviceGetProperty(
id,
0,
0,
kAudioDevicePropertyBufferFrameSizeRange,
&size,
framerange);
}
static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize)
{
UInt32 size = sizeof(*framesize);
return AudioDeviceGetProperty(
id,
0,
false,
kAudioDevicePropertyBufferFrameSize,
&size,
framesize);
}
static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize)
{
UInt32 size = sizeof(*framesize);
return AudioDeviceSetProperty(
id,
NULL,
0,
false,
kAudioDevicePropertyBufferFrameSize,
size,
framesize);
}
static OSStatus coreaudio_get_streamformat(AudioDeviceID id,
AudioStreamBasicDescription *d)
{
UInt32 size = sizeof(*d);
return AudioDeviceGetProperty(
id,
0,
false,
kAudioDevicePropertyStreamFormat,
&size,
d);
}
static OSStatus coreaudio_set_streamformat(AudioDeviceID id,
AudioStreamBasicDescription *d)
{
UInt32 size = sizeof(*d);
return AudioDeviceSetProperty(
id,
0,
0,
0,
kAudioDevicePropertyStreamFormat,
size,
d);
}
static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result)
{
UInt32 size = sizeof(*result);
return AudioDeviceGetProperty(
id,
0,
0,
kAudioDevicePropertyDeviceIsRunning,
&size,
result);
}
#endif
static void coreaudio_logstatus (OSStatus status)
{
const char *str = "BUG";
@@ -370,7 +144,10 @@ static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
{
OSStatus status;
UInt32 result = 0;
status = coreaudio_get_isrunning(outputDeviceID, &result);
UInt32 propertySize = sizeof(outputDeviceID);
status = AudioDeviceGetProperty(
outputDeviceID, 0, 0,
kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);
if (status != kAudioHardwareNoError) {
coreaudio_logerr(status,
"Could not determine whether Device is playing\n");
@@ -511,6 +288,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
{
OSStatus status;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
UInt32 propertySize;
int err;
const char *typ = "playback";
AudioValueRange frameRange;
@@ -525,7 +303,12 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
audio_pcm_init_info (&hw->info, as);
status = coreaudio_get_voice(&core->outputDeviceID);
/* open default output device */
propertySize = sizeof(core->outputDeviceID);
status = AudioHardwareGetProperty(
kAudioHardwarePropertyDefaultOutputDevice,
&propertySize,
&core->outputDeviceID);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ,
"Could not get default output Device\n");
@@ -537,8 +320,14 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
}
/* get minimum and maximum buffer frame sizes */
status = coreaudio_get_framesizerange(core->outputDeviceID,
&frameRange);
propertySize = sizeof(frameRange);
status = AudioDeviceGetProperty(
core->outputDeviceID,
0,
0,
kAudioDevicePropertyBufferFrameSizeRange,
&propertySize,
&frameRange);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ,
"Could not get device buffer frame range\n");
@@ -558,8 +347,15 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
}
/* set Buffer Frame Size */
status = coreaudio_set_framesize(core->outputDeviceID,
&core->audioDevicePropertyBufferFrameSize);
propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
status = AudioDeviceSetProperty(
core->outputDeviceID,
NULL,
0,
false,
kAudioDevicePropertyBufferFrameSize,
propertySize,
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ,
"Could not set device buffer frame size %" PRIu32 "\n",
@@ -568,8 +364,14 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
}
/* get Buffer Frame Size */
status = coreaudio_get_framesize(core->outputDeviceID,
&core->audioDevicePropertyBufferFrameSize);
propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
status = AudioDeviceGetProperty(
core->outputDeviceID,
0,
false,
kAudioDevicePropertyBufferFrameSize,
&propertySize,
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ,
"Could not get device buffer frame size\n");
@@ -578,8 +380,14 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
hw->samples = conf->nbuffers * core->audioDevicePropertyBufferFrameSize;
/* get StreamFormat */
status = coreaudio_get_streamformat(core->outputDeviceID,
&core->outputStreamBasicDescription);
propertySize = sizeof(core->outputStreamBasicDescription);
status = AudioDeviceGetProperty(
core->outputDeviceID,
0,
false,
kAudioDevicePropertyStreamFormat,
&propertySize,
&core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ,
"Could not get Device Stream properties\n");
@@ -589,8 +397,15 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
/* set Samplerate */
core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
status = coreaudio_set_streamformat(core->outputDeviceID,
&core->outputStreamBasicDescription);
propertySize = sizeof(core->outputStreamBasicDescription);
status = AudioDeviceSetProperty(
core->outputDeviceID,
0,
0,
0,
kAudioDevicePropertyStreamFormat,
propertySize,
&core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
as->freq);
@@ -599,12 +414,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
}
/* set Callback */
core->ioprocid = NULL;
status = AudioDeviceCreateIOProcID(core->outputDeviceID,
audioDeviceIOProc,
hw,
&core->ioprocid);
if (status != kAudioHardwareNoError || core->ioprocid == NULL) {
status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
core->outputDeviceID = kAudioDeviceUnknown;
return -1;
@@ -612,10 +423,10 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
/* start Playback */
if (!isPlaying(core->outputDeviceID)) {
status = AudioDeviceStart(core->outputDeviceID, core->ioprocid);
status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Could not start playback\n");
AudioDeviceDestroyIOProcID(core->outputDeviceID, core->ioprocid);
AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
core->outputDeviceID = kAudioDeviceUnknown;
return -1;
}
@@ -633,15 +444,15 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
if (!isAtexit) {
/* stop playback */
if (isPlaying(core->outputDeviceID)) {
status = AudioDeviceStop(core->outputDeviceID, core->ioprocid);
status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not stop playback\n");
}
}
/* remove callback */
status = AudioDeviceDestroyIOProcID(core->outputDeviceID,
core->ioprocid);
status = AudioDeviceRemoveIOProc(core->outputDeviceID,
audioDeviceIOProc);
if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not remove IOProc\n");
}
@@ -664,7 +475,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
case VOICE_ENABLE:
/* start playback */
if (!isPlaying(core->outputDeviceID)) {
status = AudioDeviceStart(core->outputDeviceID, core->ioprocid);
status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not resume playback\n");
}
@@ -675,8 +486,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
/* stop playback */
if (!isAtexit) {
if (isPlaying(core->outputDeviceID)) {
status = AudioDeviceStop(core->outputDeviceID,
core->ioprocid);
status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not pause playback\n");
}

View File

@@ -566,7 +566,6 @@ static CharDriverState *chr_baum_init(const char *id,
ChardevReturn *ret,
Error **errp)
{
ChardevCommon *common = qapi_ChardevDummy_base(backend->u.braille);
BaumDriverState *baum;
CharDriverState *chr;
brlapi_handle_t *handle;
@@ -577,12 +576,8 @@ static CharDriverState *chr_baum_init(const char *id,
#endif
int tty;
chr = qemu_chr_alloc(common, errp);
if (!chr) {
return NULL;
}
baum = g_malloc0(sizeof(BaumDriverState));
baum->chr = chr;
baum->chr = chr = qemu_chr_alloc();
chr->opaque = baum;
chr->chr_write = baum_write;

View File

@@ -68,13 +68,9 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id,
ChardevReturn *ret,
Error **errp)
{
ChardevCommon *common = qapi_ChardevDummy_base(backend->u.msmouse);
CharDriverState *chr;
chr = qemu_chr_alloc(common, errp);
if (!chr) {
return NULL;
}
chr = qemu_chr_alloc();
chr->chr_write = msmouse_chr_write;
chr->chr_close = msmouse_chr_close;
chr->explicit_be_open = true;

560
block.c

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "block/accounting.h"
#include "block/block_int.h"
#include "qemu/timer.h"

View File

@@ -50,7 +50,6 @@
*
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/error-report.h"
@@ -60,6 +59,7 @@
#include "qapi/qmp/qjson.h"
#include "qemu/atomic.h"
#include <inttypes.h>
#include <xseg/xseg.h>
#include <xseg/protocol.h>

View File

@@ -11,7 +11,9 @@
*
*/
#include "qemu/osdep.h"
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include "trace.h"
#include "block/block.h"

View File

@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/config-file.h"
#include "block/block_int.h"
@@ -37,7 +36,7 @@ typedef struct BDRVBlkdebugState {
int state;
int new_state;
QLIST_HEAD(, BlkdebugRule) rules[BLKDBG__MAX];
QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX];
QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs;
} BDRVBlkdebugState;
@@ -65,7 +64,7 @@ enum {
};
typedef struct BlkdebugRule {
BlkdebugEvent event;
BlkDebugEvent event;
int action;
int state;
union {
@@ -144,12 +143,69 @@ static QemuOptsList *config_groups[] = {
NULL
};
static int get_event_by_name(const char *name, BlkdebugEvent *event)
static const char *event_names[BLKDBG_EVENT_MAX] = {
[BLKDBG_L1_UPDATE] = "l1_update",
[BLKDBG_L1_GROW_ALLOC_TABLE] = "l1_grow.alloc_table",
[BLKDBG_L1_GROW_WRITE_TABLE] = "l1_grow.write_table",
[BLKDBG_L1_GROW_ACTIVATE_TABLE] = "l1_grow.activate_table",
[BLKDBG_L2_LOAD] = "l2_load",
[BLKDBG_L2_UPDATE] = "l2_update",
[BLKDBG_L2_UPDATE_COMPRESSED] = "l2_update_compressed",
[BLKDBG_L2_ALLOC_COW_READ] = "l2_alloc.cow_read",
[BLKDBG_L2_ALLOC_WRITE] = "l2_alloc.write",
[BLKDBG_READ_AIO] = "read_aio",
[BLKDBG_READ_BACKING_AIO] = "read_backing_aio",
[BLKDBG_READ_COMPRESSED] = "read_compressed",
[BLKDBG_WRITE_AIO] = "write_aio",
[BLKDBG_WRITE_COMPRESSED] = "write_compressed",
[BLKDBG_VMSTATE_LOAD] = "vmstate_load",
[BLKDBG_VMSTATE_SAVE] = "vmstate_save",
[BLKDBG_COW_READ] = "cow_read",
[BLKDBG_COW_WRITE] = "cow_write",
[BLKDBG_REFTABLE_LOAD] = "reftable_load",
[BLKDBG_REFTABLE_GROW] = "reftable_grow",
[BLKDBG_REFTABLE_UPDATE] = "reftable_update",
[BLKDBG_REFBLOCK_LOAD] = "refblock_load",
[BLKDBG_REFBLOCK_UPDATE] = "refblock_update",
[BLKDBG_REFBLOCK_UPDATE_PART] = "refblock_update_part",
[BLKDBG_REFBLOCK_ALLOC] = "refblock_alloc",
[BLKDBG_REFBLOCK_ALLOC_HOOKUP] = "refblock_alloc.hookup",
[BLKDBG_REFBLOCK_ALLOC_WRITE] = "refblock_alloc.write",
[BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS] = "refblock_alloc.write_blocks",
[BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE] = "refblock_alloc.write_table",
[BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE] = "refblock_alloc.switch_table",
[BLKDBG_CLUSTER_ALLOC] = "cluster_alloc",
[BLKDBG_CLUSTER_ALLOC_BYTES] = "cluster_alloc_bytes",
[BLKDBG_CLUSTER_FREE] = "cluster_free",
[BLKDBG_FLUSH_TO_OS] = "flush_to_os",
[BLKDBG_FLUSH_TO_DISK] = "flush_to_disk",
[BLKDBG_PWRITEV_RMW_HEAD] = "pwritev_rmw.head",
[BLKDBG_PWRITEV_RMW_AFTER_HEAD] = "pwritev_rmw.after_head",
[BLKDBG_PWRITEV_RMW_TAIL] = "pwritev_rmw.tail",
[BLKDBG_PWRITEV_RMW_AFTER_TAIL] = "pwritev_rmw.after_tail",
[BLKDBG_PWRITEV] = "pwritev",
[BLKDBG_PWRITEV_ZERO] = "pwritev_zero",
[BLKDBG_PWRITEV_DONE] = "pwritev_done",
[BLKDBG_EMPTY_IMAGE_PREPARE] = "empty_image_prepare",
};
static int get_event_by_name(const char *name, BlkDebugEvent *event)
{
int i;
for (i = 0; i < BLKDBG__MAX; i++) {
if (!strcmp(BlkdebugEvent_lookup[i], name)) {
for (i = 0; i < BLKDBG_EVENT_MAX; i++) {
if (!strcmp(event_names[i], name)) {
*event = i;
return 0;
}
@@ -168,7 +224,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
struct add_rule_data *d = opaque;
BDRVBlkdebugState *s = d->s;
const char* event_name;
BlkdebugEvent event;
BlkDebugEvent event;
struct BlkdebugRule *rule;
/* Find the right event for the rule */
@@ -508,7 +564,7 @@ static void blkdebug_close(BlockDriverState *bs)
BlkdebugRule *rule, *next;
int i;
for (i = 0; i < BLKDBG__MAX; i++) {
for (i = 0; i < BLKDBG_EVENT_MAX; i++) {
QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {
remove_rule(rule);
}
@@ -571,13 +627,13 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
return injected;
}
static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event)
static void blkdebug_debug_event(BlockDriverState *bs, BlkDebugEvent event)
{
BDRVBlkdebugState *s = bs->opaque;
struct BlkdebugRule *rule, *next;
bool injected;
assert((int)event >= 0 && event < BLKDBG__MAX);
assert((int)event >= 0 && event < BLKDBG_EVENT_MAX);
injected = false;
s->new_state = s->state;
@@ -592,7 +648,7 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
{
BDRVBlkdebugState *s = bs->opaque;
struct BlkdebugRule *rule;
BlkdebugEvent blkdebug_event;
BlkDebugEvent blkdebug_event;
if (get_event_by_name(event, &blkdebug_event) < 0) {
return -ENOENT;
@@ -634,7 +690,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
BlkdebugRule *rule, *next;
int i, ret = -ENOENT;
for (i = 0; i < BLKDBG__MAX; i++) {
for (i = 0; i < BLKDBG_EVENT_MAX; i++) {
QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {
if (rule->action == ACTION_SUSPEND &&
!strcmp(rule->options.suspend.tag, tag)) {
@@ -675,15 +731,17 @@ static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
return bdrv_truncate(bs->file->bs, offset);
}
static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
static void blkdebug_refresh_filename(BlockDriverState *bs)
{
QDict *opts;
const QDictEntry *e;
bool force_json = false;
for (e = qdict_first(options); e; e = qdict_next(options, e)) {
for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
if (strcmp(qdict_entry_key(e), "config") &&
strcmp(qdict_entry_key(e), "x-image"))
strcmp(qdict_entry_key(e), "x-image") &&
strcmp(qdict_entry_key(e), "image") &&
strncmp(qdict_entry_key(e), "image.", strlen("image.")))
{
force_json = true;
break;
@@ -699,7 +757,7 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
if (!force_json && bs->file->bs->exact_filename[0]) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"blkdebug:%s:%s",
qdict_get_try_str(options, "config") ?: "",
qdict_get_try_str(bs->options, "config") ?: "",
bs->file->bs->exact_filename);
}
@@ -709,8 +767,11 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
QINCREF(bs->file->bs->full_open_options);
qdict_put_obj(opts, "image", QOBJECT(bs->file->bs->full_open_options));
for (e = qdict_first(options); e; e = qdict_next(options, e)) {
if (strcmp(qdict_entry_key(e), "x-image")) {
for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
if (strcmp(qdict_entry_key(e), "x-image") &&
strcmp(qdict_entry_key(e), "image") &&
strncmp(qdict_entry_key(e), "image.", strlen("image.")))
{
qobject_incref(qdict_entry_value(e));
qdict_put_obj(opts, qdict_entry_key(e), qdict_entry_value(e));
}
@@ -719,12 +780,6 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
bs->full_open_options = opts;
}
static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
BlockReopenQueue *queue, Error **errp)
{
return 0;
}
static BlockDriver bdrv_blkdebug = {
.format_name = "blkdebug",
.protocol_name = "blkdebug",
@@ -733,7 +788,6 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_parse_filename = blkdebug_parse_filename,
.bdrv_file_open = blkdebug_open,
.bdrv_close = blkdebug_close,
.bdrv_reopen_prepare = blkdebug_reopen_prepare,
.bdrv_getlength = blkdebug_getlength,
.bdrv_truncate = blkdebug_truncate,
.bdrv_refresh_filename = blkdebug_refresh_filename,

View File

@@ -7,7 +7,7 @@
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include <stdarg.h>
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
#include "block/block_int.h"
#include "qapi/qmp/qdict.h"
@@ -307,7 +307,7 @@ static void blkverify_attach_aio_context(BlockDriverState *bs,
bdrv_attach_aio_context(s->test_file->bs, new_context);
}
static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
static void blkverify_refresh_filename(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;

View File

@@ -10,7 +10,6 @@
* or later. See the COPYING.LIB file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "block/blockjob.h"
@@ -458,6 +457,14 @@ bool blk_dev_has_removable_media(BlockBackend *blk)
return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
}
/*
* Does @blk's attached device model have a tray?
*/
bool blk_dev_has_tray(BlockBackend *blk)
{
return blk->dev_ops && blk->dev_ops->is_tray_open;
}
/*
* Notify @blk's attached device model of a media eject request.
* If @force is true, the medium is about to be yanked out forcefully.
@@ -474,7 +481,7 @@ void blk_dev_eject_request(BlockBackend *blk, bool force)
*/
bool blk_dev_is_tray_open(BlockBackend *blk)
{
if (blk->dev_ops && blk->dev_ops->is_tray_open) {
if (blk_dev_has_tray(blk)) {
return blk->dev_ops->is_tray_open(blk->dev_opaque);
}
return false;
@@ -1024,21 +1031,11 @@ int blk_get_max_transfer_length(BlockBackend *blk)
}
}
int blk_get_max_iov(BlockBackend *blk)
{
return blk->bs->bl.max_iov;
}
void blk_set_guest_block_size(BlockBackend *blk, int align)
{
blk->guest_block_size = align;
}
void *blk_try_blockalign(BlockBackend *blk, size_t size)
{
return qemu_try_blockalign(blk ? blk->bs : NULL, size);
}
void *blk_blockalign(BlockBackend *blk, size_t size)
{
return qemu_blockalign(blk ? blk->bs : NULL, size);

View File

@@ -22,7 +22,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"

View File

@@ -12,7 +12,6 @@
*
*/
#include "qemu/osdep.h"
#include "trace.h"
#include "block/block_int.h"
#include "block/blockjob.h"

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "block/block_int.h"

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/bswap.h"

View File

@@ -7,7 +7,6 @@
* See the COPYING file in the top-level directory.
*
*/
#include "qemu/osdep.h"
#include <glusterfs/api/glfs.h>
#include "block/block_int.h"
#include "qemu/uri.h"

View File

@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "trace.h"
#include "sysemu/block-backend.h"
#include "block/blockjob.h"
@@ -167,13 +166,9 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.max_transfer_length = bs->file->bs->bl.max_transfer_length;
bs->bl.min_mem_alignment = bs->file->bs->bl.min_mem_alignment;
bs->bl.opt_mem_alignment = bs->file->bs->bl.opt_mem_alignment;
bs->bl.max_iov = bs->file->bs->bl.max_iov;
} else {
bs->bl.min_mem_alignment = 512;
bs->bl.opt_mem_alignment = getpagesize();
/* Safe default since most protocols use readv()/writev()/etc */
bs->bl.max_iov = IOV_MAX;
}
if (bs->backing) {
@@ -194,9 +189,6 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.min_mem_alignment =
MAX(bs->bl.min_mem_alignment,
bs->backing->bs->bl.min_mem_alignment);
bs->bl.max_iov =
MIN(bs->bl.max_iov,
bs->backing->bs->bl.max_iov);
}
/* Then let the driver override it */
@@ -1301,7 +1293,6 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
if (bs->read_only) {
return -EPERM;
}
assert(!(bs->open_flags & BDRV_O_INACTIVE));
ret = bdrv_check_byte_request(bs, offset, bytes);
if (ret < 0) {
@@ -1891,8 +1882,7 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
merge = 1;
}
if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 >
bs->bl.max_iov) {
if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
merge = 0;
}
@@ -2463,7 +2453,6 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
} else if (bs->read_only) {
return -EPERM;
}
assert(!(bs->open_flags & BDRV_O_INACTIVE));
/* Do nothing if disabled. */
if (!(bs->open_flags & BDRV_O_UNMAP)) {
@@ -2625,11 +2614,10 @@ int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
bdrv_co_ioctl_entry(&data);
} else {
Coroutine *co = qemu_coroutine_create(bdrv_co_ioctl_entry);
qemu_coroutine_enter(co, &data);
while (data.ret == -EINPROGRESS) {
aio_poll(bdrv_get_aio_context(bs), true);
}
}
while (data.ret == -EINPROGRESS) {
aio_poll(bdrv_get_aio_context(bs), true);
}
return data.ret;
}

View File

@@ -23,7 +23,7 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "config-host.h"
#include <poll.h>
#include <math.h>
@@ -1243,13 +1243,8 @@ static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
iscsilun->lbprz = !!rc16->lbprz;
iscsilun->use_16_for_rw = (rc16->returned_lba > 0xffffffff);
}
break;
}
if (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {
break;
}
/* Fall through and try READ CAPACITY(10) instead. */
break;
case TYPE_ROM:
task = iscsi_readcapacity10_sync(iscsilun->iscsi, iscsilun->lun, 0, 0);
if (task != NULL && task->status == SCSI_STATUS_GOOD) {
@@ -1275,7 +1270,7 @@ static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
&& retries-- > 0);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
error_setg(errp, "iSCSI: failed to send readcapacity10/16 command");
error_setg(errp, "iSCSI: failed to send readcapacity10 command.");
} else if (!iscsilun->block_size ||
iscsilun->block_size % BDRV_SECTOR_SIZE) {
error_setg(errp, "iSCSI: the target returned an invalid "

View File

@@ -7,7 +7,6 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/aio.h"
#include "qemu/queue.h"

View File

@@ -11,7 +11,6 @@
*
*/
#include "qemu/osdep.h"
#include "trace.h"
#include "block/blockjob.h"
#include "block/block_int.h"
@@ -19,7 +18,6 @@
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
#include "qemu/bitmap.h"
#include "qemu/error-report.h"
#define SLICE_TIME 100000000ULL /* ns */
#define MAX_IN_FLIGHT 16
@@ -162,15 +160,13 @@ static void mirror_read_complete(void *opaque, int ret)
static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
{
BlockDriverState *source = s->common.bs;
int nb_sectors, sectors_per_chunk, nb_chunks, max_iov;
int nb_sectors, sectors_per_chunk, nb_chunks;
int64_t end, sector_num, next_chunk, next_sector, hbitmap_next_sector;
uint64_t delay_ns = 0;
MirrorOp *op;
int pnum;
int64_t ret;
max_iov = MIN(source->bl.max_iov, s->target->bl.max_iov);
s->sector_num = hbitmap_iter_next(&s->hbi);
if (s->sector_num < 0) {
bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
@@ -251,7 +247,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
trace_mirror_break_buf_busy(s, nb_chunks, s->in_flight);
break;
}
if (max_iov < nb_chunks + added_chunks) {
if (IOV_MAX < nb_chunks + added_chunks) {
trace_mirror_break_iov_max(s, nb_chunks, added_chunks);
break;
}
@@ -374,22 +370,11 @@ static void mirror_exit(BlockJob *job, void *opaque)
if (s->to_replace) {
to_replace = s->to_replace;
}
/* This was checked in mirror_start_job(), but meanwhile one of the
* nodes could have been newly attached to a BlockBackend. */
if (to_replace->blk && s->target->blk) {
error_report("block job: Can't create node with two BlockBackends");
data->ret = -EINVAL;
goto out;
}
if (bdrv_get_flags(s->target) != bdrv_get_flags(to_replace)) {
bdrv_reopen(s->target, bdrv_get_flags(to_replace), NULL);
}
bdrv_replace_in_backing_chain(to_replace, s->target);
}
out:
if (s->to_replace) {
bdrv_op_unblock_all(s->to_replace, s->replace_blocker);
error_free(s->replace_blocker);
@@ -655,7 +640,7 @@ static void mirror_complete(BlockJob *job, Error **errp)
Error *local_err = NULL;
int ret;
ret = bdrv_open_backing_file(s->target, NULL, "backing", &local_err);
ret = bdrv_open_backing_file(s->target, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return;
@@ -720,7 +705,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
bool is_none_mode, BlockDriverState *base)
{
MirrorBlockJob *s;
BlockDriverState *replaced_bs;
if (granularity == 0) {
granularity = bdrv_get_default_bitmap_granularity(target);
@@ -744,21 +728,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
buf_size = DEFAULT_MIRROR_BUF_SIZE;
}
/* We can't support this case as long as the block layer can't handle
* multiple BlockBackends per BlockDriverState. */
if (replaces) {
replaced_bs = bdrv_lookup_bs(replaces, replaces, errp);
if (replaced_bs == NULL) {
return;
}
} else {
replaced_bs = bs;
}
if (replaced_bs->blk && target->blk) {
error_setg(errp, "Can't create node with two BlockBackends");
return;
}
s = block_job_create(driver, bs, speed, cb, opaque, errp);
if (!s) {
return;

View File

@@ -26,7 +26,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "nbd-client.h"
#include "qemu/sockets.h"

View File

@@ -26,7 +26,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "block/nbd-client.h"
#include "qemu/uri.h"
#include "block/block_int.h"
@@ -37,6 +36,8 @@
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qstring.h"
#include <sys/types.h>
#include <unistd.h>
#define EN_OPTSTR ":exportname="
@@ -341,13 +342,13 @@ static void nbd_attach_aio_context(BlockDriverState *bs,
nbd_client_attach_aio_context(bs, new_context);
}
static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
static void nbd_refresh_filename(BlockDriverState *bs)
{
QDict *opts = qdict_new();
const char *path = qdict_get_try_str(options, "path");
const char *host = qdict_get_try_str(options, "host");
const char *port = qdict_get_try_str(options, "port");
const char *export = qdict_get_try_str(options, "export");
const char *path = qdict_get_try_str(bs->options, "path");
const char *host = qdict_get_try_str(bs->options, "host");
const char *port = qdict_get_try_str(bs->options, "port");
const char *export = qdict_get_try_str(bs->options, "export");
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("nbd")));

View File

@@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "config-host.h"
#include <poll.h>
#include "qemu-common.h"

View File

@@ -10,7 +10,6 @@
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "block/block_int.h"
#define NULL_OPT_LATENCY "latency-ns"

View File

@@ -27,7 +27,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"
@@ -62,7 +61,7 @@ typedef struct ParallelsHeader {
typedef enum ParallelsPreallocMode {
PRL_PREALLOC_MODE_FALLOCATE = 0,
PRL_PREALLOC_MODE_TRUNCATE = 1,
PRL_PREALLOC_MODE__MAX = 2,
PRL_PREALLOC_MODE_MAX = 2,
} ParallelsPreallocMode;
static const char *prealloc_mode_lookup[] = {
@@ -661,7 +660,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
s->prealloc_size = MAX(s->tracks, s->prealloc_size >> BDRV_SECTOR_BITS);
buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE);
s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf,
PRL_PREALLOC_MODE__MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err);
PRL_PREALLOC_MODE_MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err);
g_free(buf);
if (local_err != NULL) {
goto fail_options;

View File

@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "block/qapi.h"
#include "block/block_int.h"
#include "block/throttle-groups.h"
@@ -246,18 +245,15 @@ void bdrv_query_image_info(BlockDriverState *bs,
info->has_backing_filename = true;
bdrv_get_full_backing_filename(bs, backing_filename2, PATH_MAX, &err);
if (err) {
/* Can't reconstruct the full backing filename, so we must omit
* this field and apply a Best Effort to this query. */
error_propagate(errp, err);
qapi_free_ImageInfo(info);
g_free(backing_filename2);
backing_filename2 = NULL;
error_free(err);
err = NULL;
return;
}
/* Always report the full_backing_filename if present, even if it's the
* same as backing_filename. That they are same is useful info. */
if (backing_filename2) {
info->full_backing_filename = g_strdup(backing_filename2);
if (strcmp(backing_filename, backing_filename2) != 0) {
info->full_backing_filename =
g_strdup(backing_filename2);
info->has_full_backing_filename = true;
}
@@ -592,7 +588,7 @@ static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation,
int i = 0;
for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
QType type = qobject_type(entry->value);
qtype_code type = qobject_type(entry->value);
bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
const char *format = composite ? "%*s[%i]:\n" : "%*s[%i]: ";
@@ -610,7 +606,7 @@ static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation,
const QDictEntry *entry;
for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
QType type = qobject_type(entry->value);
qtype_code type = qobject_type(entry->value);
bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
const char *format = composite ? "%*s%s:\n" : "%*s%s: ";
char key[strlen(entry->key) + 1];
@@ -680,10 +676,7 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
if (info->has_backing_filename) {
func_fprintf(f, "backing file: %s", info->backing_filename);
if (!info->has_full_backing_filename) {
func_fprintf(f, " (cannot determine actual path)");
} else if (strcmp(info->backing_filename,
info->full_backing_filename) != 0) {
if (info->has_full_backing_filename) {
func_fprintf(f, " (actual path: %s)", info->full_backing_filename);
}
func_fprintf(f, "\n");

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"

View File

@@ -23,7 +23,7 @@
*/
/* Needed for CONFIG_MADVISE */
#include "qemu/osdep.h"
#include "config-host.h"
#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
#include <sys/mman.h>
@@ -31,6 +31,7 @@
#include "block/block_int.h"
#include "qemu-common.h"
#include "qemu/osdep.h"
#include "qcow2.h"
#include "trace.h"

View File

@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include <zlib.h>
#include "qemu-common.h"
@@ -1642,8 +1641,7 @@ fail:
static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
int l1_size, int64_t *visited_l1_entries,
int64_t l1_entries,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque)
BlockDriverAmendStatusCB *status_cb)
{
BDRVQcow2State *s = bs->opaque;
bool is_active_l1 = (l1_table == s->l1_table);
@@ -1669,7 +1667,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
/* unallocated */
(*visited_l1_entries)++;
if (status_cb) {
status_cb(bs, *visited_l1_entries, l1_entries, cb_opaque);
status_cb(bs, *visited_l1_entries, l1_entries);
}
continue;
}
@@ -1806,7 +1804,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
(*visited_l1_entries)++;
if (status_cb) {
status_cb(bs, *visited_l1_entries, l1_entries, cb_opaque);
status_cb(bs, *visited_l1_entries, l1_entries);
}
}
@@ -1830,8 +1828,7 @@ fail:
* qcow2 version which doesn't yet support metadata zero clusters.
*/
int qcow2_expand_zero_clusters(BlockDriverState *bs,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque)
BlockDriverAmendStatusCB *status_cb)
{
BDRVQcow2State *s = bs->opaque;
uint64_t *l1_table = NULL;
@@ -1848,7 +1845,7 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs,
ret = expand_zero_clusters_in_l1(bs, s->l1_table, s->l1_size,
&visited_l1_entries, l1_entries,
status_cb, cb_opaque);
status_cb);
if (ret < 0) {
goto fail;
}
@@ -1884,7 +1881,7 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs,
ret = expand_zero_clusters_in_l1(bs, l1_table, s->snapshots[i].l1_size,
&visited_l1_entries, l1_entries,
status_cb, cb_opaque);
status_cb);
if (ret < 0) {
goto fail;
}

View File

@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "block/qcow2.h"
@@ -1346,9 +1345,6 @@ static int inc_refcounts(BlockDriverState *bs,
if (refcount == s->refcount_max) {
fprintf(stderr, "ERROR: overflow cluster offset=0x%" PRIx64
"\n", cluster_offset);
fprintf(stderr, "Use qemu-img amend to increase the refcount entry "
"width or qemu-img convert to create a clean copy if the "
"image cannot be opened for writing\n");
res->corruptions++;
continue;
}
@@ -2471,450 +2467,3 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
return 0;
}
/* A pointer to a function of this type is given to walk_over_reftable(). That
* function will create refblocks and pass them to a RefblockFinishOp once they
* are completed (@refblock). @refblock_empty is set if the refblock is
* completely empty.
*
* Along with the refblock, a corresponding reftable entry is passed, in the
* reftable @reftable (which may be reallocated) at @reftable_index.
*
* @allocated should be set to true if a new cluster has been allocated.
*/
typedef int (RefblockFinishOp)(BlockDriverState *bs, uint64_t **reftable,
uint64_t reftable_index, uint64_t *reftable_size,
void *refblock, bool refblock_empty,
bool *allocated, Error **errp);
/**
* This "operation" for walk_over_reftable() allocates the refblock on disk (if
* it is not empty) and inserts its offset into the new reftable. The size of
* this new reftable is increased as required.
*/
static int alloc_refblock(BlockDriverState *bs, uint64_t **reftable,
uint64_t reftable_index, uint64_t *reftable_size,
void *refblock, bool refblock_empty, bool *allocated,
Error **errp)
{
BDRVQcow2State *s = bs->opaque;
int64_t offset;
if (!refblock_empty && reftable_index >= *reftable_size) {
uint64_t *new_reftable;
uint64_t new_reftable_size;
new_reftable_size = ROUND_UP(reftable_index + 1,
s->cluster_size / sizeof(uint64_t));
if (new_reftable_size > QCOW_MAX_REFTABLE_SIZE / sizeof(uint64_t)) {
error_setg(errp,
"This operation would make the refcount table grow "
"beyond the maximum size supported by QEMU, aborting");
return -ENOTSUP;
}
new_reftable = g_try_realloc(*reftable, new_reftable_size *
sizeof(uint64_t));
if (!new_reftable) {
error_setg(errp, "Failed to increase reftable buffer size");
return -ENOMEM;
}
memset(new_reftable + *reftable_size, 0,
(new_reftable_size - *reftable_size) * sizeof(uint64_t));
*reftable = new_reftable;
*reftable_size = new_reftable_size;
}
if (!refblock_empty && !(*reftable)[reftable_index]) {
offset = qcow2_alloc_clusters(bs, s->cluster_size);
if (offset < 0) {
error_setg_errno(errp, -offset, "Failed to allocate refblock");
return offset;
}
(*reftable)[reftable_index] = offset;
*allocated = true;
}
return 0;
}
/**
* This "operation" for walk_over_reftable() writes the refblock to disk at the
* offset specified by the new reftable's entry. It does not modify the new
* reftable or change any refcounts.
*/
static int flush_refblock(BlockDriverState *bs, uint64_t **reftable,
uint64_t reftable_index, uint64_t *reftable_size,
void *refblock, bool refblock_empty, bool *allocated,
Error **errp)
{
BDRVQcow2State *s = bs->opaque;
int64_t offset;
int ret;
if (reftable_index < *reftable_size && (*reftable)[reftable_index]) {
offset = (*reftable)[reftable_index];
ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size);
if (ret < 0) {
error_setg_errno(errp, -ret, "Overlap check failed");
return ret;
}
ret = bdrv_pwrite(bs->file->bs, offset, refblock, s->cluster_size);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write refblock");
return ret;
}
} else {
assert(refblock_empty);
}
return 0;
}
/**
* This function walks over the existing reftable and every referenced refblock;
* if @new_set_refcount is non-NULL, it is called for every refcount entry to
* create an equal new entry in the passed @new_refblock. Once that
* @new_refblock is completely filled, @operation will be called.
*
* @status_cb and @cb_opaque are used for the amend operation's status callback.
* @index is the index of the walk_over_reftable() calls and @total is the total
* number of walk_over_reftable() calls per amend operation. Both are used for
* calculating the parameters for the status callback.
*
* @allocated is set to true if a new cluster has been allocated.
*/
static int walk_over_reftable(BlockDriverState *bs, uint64_t **new_reftable,
uint64_t *new_reftable_index,
uint64_t *new_reftable_size,
void *new_refblock, int new_refblock_size,
int new_refcount_bits,
RefblockFinishOp *operation, bool *allocated,
Qcow2SetRefcountFunc *new_set_refcount,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, int index, int total,
Error **errp)
{
BDRVQcow2State *s = bs->opaque;
uint64_t reftable_index;
bool new_refblock_empty = true;
int refblock_index;
int new_refblock_index = 0;
int ret;
for (reftable_index = 0; reftable_index < s->refcount_table_size;
reftable_index++)
{
uint64_t refblock_offset = s->refcount_table[reftable_index]
& REFT_OFFSET_MASK;
status_cb(bs, (uint64_t)index * s->refcount_table_size + reftable_index,
(uint64_t)total * s->refcount_table_size, cb_opaque);
if (refblock_offset) {
void *refblock;
if (offset_into_cluster(s, refblock_offset)) {
qcow2_signal_corruption(bs, true, -1, -1, "Refblock offset %#"
PRIx64 " unaligned (reftable index: %#"
PRIx64 ")", refblock_offset,
reftable_index);
error_setg(errp,
"Image is corrupt (unaligned refblock offset)");
return -EIO;
}
ret = qcow2_cache_get(bs, s->refcount_block_cache, refblock_offset,
&refblock);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to retrieve refblock");
return ret;
}
for (refblock_index = 0; refblock_index < s->refcount_block_size;
refblock_index++)
{
uint64_t refcount;
if (new_refblock_index >= new_refblock_size) {
/* new_refblock is now complete */
ret = operation(bs, new_reftable, *new_reftable_index,
new_reftable_size, new_refblock,
new_refblock_empty, allocated, errp);
if (ret < 0) {
qcow2_cache_put(bs, s->refcount_block_cache, &refblock);
return ret;
}
(*new_reftable_index)++;
new_refblock_index = 0;
new_refblock_empty = true;
}
refcount = s->get_refcount(refblock, refblock_index);
if (new_refcount_bits < 64 && refcount >> new_refcount_bits) {
uint64_t offset;
qcow2_cache_put(bs, s->refcount_block_cache, &refblock);
offset = ((reftable_index << s->refcount_block_bits)
+ refblock_index) << s->cluster_bits;
error_setg(errp, "Cannot decrease refcount entry width to "
"%i bits: Cluster at offset %#" PRIx64 " has a "
"refcount of %" PRIu64, new_refcount_bits,
offset, refcount);
return -EINVAL;
}
if (new_set_refcount) {
new_set_refcount(new_refblock, new_refblock_index++,
refcount);
} else {
new_refblock_index++;
}
new_refblock_empty = new_refblock_empty && refcount == 0;
}
qcow2_cache_put(bs, s->refcount_block_cache, &refblock);
} else {
/* No refblock means every refcount is 0 */
for (refblock_index = 0; refblock_index < s->refcount_block_size;
refblock_index++)
{
if (new_refblock_index >= new_refblock_size) {
/* new_refblock is now complete */
ret = operation(bs, new_reftable, *new_reftable_index,
new_reftable_size, new_refblock,
new_refblock_empty, allocated, errp);
if (ret < 0) {
return ret;
}
(*new_reftable_index)++;
new_refblock_index = 0;
new_refblock_empty = true;
}
if (new_set_refcount) {
new_set_refcount(new_refblock, new_refblock_index++, 0);
} else {
new_refblock_index++;
}
}
}
}
if (new_refblock_index > 0) {
/* Complete the potentially existing partially filled final refblock */
if (new_set_refcount) {
for (; new_refblock_index < new_refblock_size;
new_refblock_index++)
{
new_set_refcount(new_refblock, new_refblock_index, 0);
}
}
ret = operation(bs, new_reftable, *new_reftable_index,
new_reftable_size, new_refblock, new_refblock_empty,
allocated, errp);
if (ret < 0) {
return ret;
}
(*new_reftable_index)++;
}
status_cb(bs, (uint64_t)(index + 1) * s->refcount_table_size,
(uint64_t)total * s->refcount_table_size, cb_opaque);
return 0;
}
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, Error **errp)
{
BDRVQcow2State *s = bs->opaque;
Qcow2GetRefcountFunc *new_get_refcount;
Qcow2SetRefcountFunc *new_set_refcount;
void *new_refblock = qemu_blockalign(bs->file->bs, s->cluster_size);
uint64_t *new_reftable = NULL, new_reftable_size = 0;
uint64_t *old_reftable, old_reftable_size, old_reftable_offset;
uint64_t new_reftable_index = 0;
uint64_t i;
int64_t new_reftable_offset = 0, allocated_reftable_size = 0;
int new_refblock_size, new_refcount_bits = 1 << refcount_order;
int old_refcount_order;
int walk_index = 0;
int ret;
bool new_allocation;
assert(s->qcow_version >= 3);
assert(refcount_order >= 0 && refcount_order <= 6);
/* see qcow2_open() */
new_refblock_size = 1 << (s->cluster_bits - (refcount_order - 3));
new_get_refcount = get_refcount_funcs[refcount_order];
new_set_refcount = set_refcount_funcs[refcount_order];
do {
int total_walks;
new_allocation = false;
/* At least we have to do this walk and the one which writes the
* refblocks; also, at least we have to do this loop here at least
* twice (normally), first to do the allocations, and second to
* determine that everything is correctly allocated, this then makes
* three walks in total */
total_walks = MAX(walk_index + 2, 3);
/* First, allocate the structures so they are present in the refcount
* structures */
ret = walk_over_reftable(bs, &new_reftable, &new_reftable_index,
&new_reftable_size, NULL, new_refblock_size,
new_refcount_bits, &alloc_refblock,
&new_allocation, NULL, status_cb, cb_opaque,
walk_index++, total_walks, errp);
if (ret < 0) {
goto done;
}
new_reftable_index = 0;
if (new_allocation) {
if (new_reftable_offset) {
qcow2_free_clusters(bs, new_reftable_offset,
allocated_reftable_size * sizeof(uint64_t),
QCOW2_DISCARD_NEVER);
}
new_reftable_offset = qcow2_alloc_clusters(bs, new_reftable_size *
sizeof(uint64_t));
if (new_reftable_offset < 0) {
error_setg_errno(errp, -new_reftable_offset,
"Failed to allocate the new reftable");
ret = new_reftable_offset;
goto done;
}
allocated_reftable_size = new_reftable_size;
}
} while (new_allocation);
/* Second, write the new refblocks */
ret = walk_over_reftable(bs, &new_reftable, &new_reftable_index,
&new_reftable_size, new_refblock,
new_refblock_size, new_refcount_bits,
&flush_refblock, &new_allocation, new_set_refcount,
status_cb, cb_opaque, walk_index, walk_index + 1,
errp);
if (ret < 0) {
goto done;
}
assert(!new_allocation);
/* Write the new reftable */
ret = qcow2_pre_write_overlap_check(bs, 0, new_reftable_offset,
new_reftable_size * sizeof(uint64_t));
if (ret < 0) {
error_setg_errno(errp, -ret, "Overlap check failed");
goto done;
}
for (i = 0; i < new_reftable_size; i++) {
cpu_to_be64s(&new_reftable[i]);
}
ret = bdrv_pwrite(bs->file->bs, new_reftable_offset, new_reftable,
new_reftable_size * sizeof(uint64_t));
for (i = 0; i < new_reftable_size; i++) {
be64_to_cpus(&new_reftable[i]);
}
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write the new reftable");
goto done;
}
/* Empty the refcount cache */
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to flush the refblock cache");
goto done;
}
/* Update the image header to point to the new reftable; this only updates
* the fields which are relevant to qcow2_update_header(); other fields
* such as s->refcount_table or s->refcount_bits stay stale for now
* (because we have to restore everything if qcow2_update_header() fails) */
old_refcount_order = s->refcount_order;
old_reftable_size = s->refcount_table_size;
old_reftable_offset = s->refcount_table_offset;
s->refcount_order = refcount_order;
s->refcount_table_size = new_reftable_size;
s->refcount_table_offset = new_reftable_offset;
ret = qcow2_update_header(bs);
if (ret < 0) {
s->refcount_order = old_refcount_order;
s->refcount_table_size = old_reftable_size;
s->refcount_table_offset = old_reftable_offset;
error_setg_errno(errp, -ret, "Failed to update the qcow2 header");
goto done;
}
/* Now update the rest of the in-memory information */
old_reftable = s->refcount_table;
s->refcount_table = new_reftable;
s->refcount_bits = 1 << refcount_order;
s->refcount_max = UINT64_C(1) << (s->refcount_bits - 1);
s->refcount_max += s->refcount_max - 1;
s->refcount_block_bits = s->cluster_bits - (refcount_order - 3);
s->refcount_block_size = 1 << s->refcount_block_bits;
s->get_refcount = new_get_refcount;
s->set_refcount = new_set_refcount;
/* For cleaning up all old refblocks and the old reftable below the "done"
* label */
new_reftable = old_reftable;
new_reftable_size = old_reftable_size;
new_reftable_offset = old_reftable_offset;
done:
if (new_reftable) {
/* On success, new_reftable actually points to the old reftable (and
* new_reftable_size is the old reftable's size); but that is just
* fine */
for (i = 0; i < new_reftable_size; i++) {
uint64_t offset = new_reftable[i] & REFT_OFFSET_MASK;
if (offset) {
qcow2_free_clusters(bs, offset, s->cluster_size,
QCOW2_DISCARD_OTHER);
}
}
g_free(new_reftable);
if (new_reftable_offset > 0) {
qcow2_free_clusters(bs, new_reftable_offset,
new_reftable_size * sizeof(uint64_t),
QCOW2_DISCARD_OTHER);
}
}
qemu_vfree(new_refblock);
return ret;
}

View File

@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "block/qcow2.h"

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"
@@ -1141,7 +1140,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Clear unknown autoclear feature bits */
if (!bs->read_only && !(flags & BDRV_O_INACTIVE) && s->autoclear_features) {
if (!bs->read_only && !(flags & BDRV_O_INCOMING) && s->autoclear_features) {
s->autoclear_features = 0;
ret = qcow2_update_header(bs);
if (ret < 0) {
@@ -1154,7 +1153,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
qemu_co_mutex_init(&s->lock);
/* Repair image if dirty */
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
if (!(flags & (BDRV_O_CHECK | BDRV_O_INCOMING)) && !bs->read_only &&
(s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) {
BdrvCheckResult result = {0};
@@ -1283,52 +1282,6 @@ static void qcow2_reopen_abort(BDRVReopenState *state)
g_free(state->opaque);
}
static void qcow2_join_options(QDict *options, QDict *old_options)
{
bool has_new_overlap_template =
qdict_haskey(options, QCOW2_OPT_OVERLAP) ||
qdict_haskey(options, QCOW2_OPT_OVERLAP_TEMPLATE);
bool has_new_total_cache_size =
qdict_haskey(options, QCOW2_OPT_CACHE_SIZE);
bool has_all_cache_options;
/* New overlap template overrides all old overlap options */
if (has_new_overlap_template) {
qdict_del(old_options, QCOW2_OPT_OVERLAP);
qdict_del(old_options, QCOW2_OPT_OVERLAP_TEMPLATE);
qdict_del(old_options, QCOW2_OPT_OVERLAP_MAIN_HEADER);
qdict_del(old_options, QCOW2_OPT_OVERLAP_ACTIVE_L1);
qdict_del(old_options, QCOW2_OPT_OVERLAP_ACTIVE_L2);
qdict_del(old_options, QCOW2_OPT_OVERLAP_REFCOUNT_TABLE);
qdict_del(old_options, QCOW2_OPT_OVERLAP_REFCOUNT_BLOCK);
qdict_del(old_options, QCOW2_OPT_OVERLAP_SNAPSHOT_TABLE);
qdict_del(old_options, QCOW2_OPT_OVERLAP_INACTIVE_L1);
qdict_del(old_options, QCOW2_OPT_OVERLAP_INACTIVE_L2);
}
/* New total cache size overrides all old options */
if (qdict_haskey(options, QCOW2_OPT_CACHE_SIZE)) {
qdict_del(old_options, QCOW2_OPT_L2_CACHE_SIZE);
qdict_del(old_options, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
}
qdict_join(options, old_options, false);
/*
* If after merging all cache size options are set, an old total size is
* overwritten. Do keep all options, however, if all three are new. The
* resulting error message is what we want to happen.
*/
has_all_cache_options =
qdict_haskey(options, QCOW2_OPT_CACHE_SIZE) ||
qdict_haskey(options, QCOW2_OPT_L2_CACHE_SIZE) ||
qdict_haskey(options, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
if (has_all_cache_options && !has_new_total_cache_size) {
qdict_del(options, QCOW2_OPT_CACHE_SIZE);
}
}
static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, int *pnum)
{
@@ -1686,32 +1639,6 @@ fail:
return ret;
}
static int qcow2_inactivate(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
int ret, result = 0;
ret = qcow2_cache_flush(bs, s->l2_table_cache);
if (ret) {
result = ret;
error_report("Failed to flush the L2 table cache: %s",
strerror(-ret));
}
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret) {
result = ret;
error_report("Failed to flush the refcount block cache: %s",
strerror(-ret));
}
if (result == 0) {
qcow2_mark_clean(bs);
}
return result;
}
static void qcow2_close(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
@@ -1719,8 +1646,24 @@ static void qcow2_close(BlockDriverState *bs)
/* else pre-write overlap checks in cache_destroy may crash */
s->l1_table = NULL;
if (!(s->flags & BDRV_O_INACTIVE)) {
qcow2_inactivate(bs);
if (!(bs->open_flags & BDRV_O_INCOMING)) {
int ret1, ret2;
ret1 = qcow2_cache_flush(bs, s->l2_table_cache);
ret2 = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret1) {
error_report("Failed to flush the L2 table cache: %s",
strerror(-ret1));
}
if (ret2) {
error_report("Failed to flush the refcount block cache: %s",
strerror(-ret2));
}
if (!ret1 && !ret2) {
qcow2_mark_clean(bs);
}
}
cache_clean_timer_del(bs);
@@ -1764,24 +1707,21 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
bdrv_invalidate_cache(bs->file->bs, &local_err);
if (local_err) {
error_propagate(errp, local_err);
bs->drv = NULL;
return;
}
memset(s, 0, sizeof(BDRVQcow2State));
options = qdict_clone_shallow(bs->options);
flags &= ~BDRV_O_INACTIVE;
ret = qcow2_open(bs, options, flags, &local_err);
QDECREF(options);
if (local_err) {
error_propagate(errp, local_err);
error_prepend(errp, "Could not reopen qcow2 layer: ");
bs->drv = NULL;
error_setg(errp, "Could not reopen qcow2 layer: %s",
error_get_pretty(local_err));
error_free(local_err);
return;
} else if (ret < 0) {
error_setg_errno(errp, -ret, "Could not reopen qcow2 layer");
bs->drv = NULL;
return;
}
@@ -1909,33 +1849,31 @@ int qcow2_update_header(BlockDriverState *bs)
}
/* Feature table */
if (s->qcow_version >= 3) {
Qcow2Feature features[] = {
{
.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
.bit = QCOW2_INCOMPAT_DIRTY_BITNR,
.name = "dirty bit",
},
{
.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
.bit = QCOW2_INCOMPAT_CORRUPT_BITNR,
.name = "corrupt bit",
},
{
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
.name = "lazy refcounts",
},
};
Qcow2Feature features[] = {
{
.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
.bit = QCOW2_INCOMPAT_DIRTY_BITNR,
.name = "dirty bit",
},
{
.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
.bit = QCOW2_INCOMPAT_CORRUPT_BITNR,
.name = "corrupt bit",
},
{
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
.name = "lazy refcounts",
},
};
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,
features, sizeof(features), buflen);
if (ret < 0) {
goto fail;
}
buf += ret;
buflen -= ret;
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,
features, sizeof(features), buflen);
if (ret < 0) {
goto fail;
}
buf += ret;
buflen -= ret;
/* Keep unknown header extensions */
QLIST_FOREACH(uext, &s->unknown_header_ext, next) {
@@ -2253,13 +2191,6 @@ static int qcow2_create2(const char *filename, int64_t total_size,
abort();
}
/* Create a full header (including things like feature table) */
ret = qcow2_update_header(bs);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not update qcow2 header");
goto out;
}
/* Okay, now that we have a valid image, let's give it the right size */
ret = bdrv_truncate(bs, total_size);
if (ret < 0) {
@@ -2338,7 +2269,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
DEFAULT_CLUSTER_SIZE);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
PREALLOC_MODE__MAX, PREALLOC_MODE_OFF,
PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
&local_err);
if (local_err) {
error_propagate(errp, local_err);
@@ -2826,10 +2757,6 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
.has_corrupt = true,
.refcount_bits = s->refcount_bits,
};
} else {
/* if this assertion fails, this probably means a new version was
* added without having it covered here */
assert(false);
}
return spec_info;
@@ -2897,7 +2824,7 @@ static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
* have to be removed.
*/
static int qcow2_downgrade(BlockDriverState *bs, int target_version,
BlockDriverAmendStatusCB *status_cb, void *cb_opaque)
BlockDriverAmendStatusCB *status_cb)
{
BDRVQcow2State *s = bs->opaque;
int current_version = s->qcow_version;
@@ -2912,7 +2839,13 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
}
if (s->refcount_order != 4) {
error_report("compat=0.10 requires refcount_bits=16");
/* we would have to convert the image to a refcount_order == 4 image
* here; however, since qemu (at the time of writing this) does not
* support anything different than 4 anyway, there is no point in doing
* so right now; however, we should error out (if qemu supports this in
* the future and this code has not been adapted) */
error_report("qcow2_downgrade: Image refcount orders other than 4 are "
"currently not supported.");
return -ENOTSUP;
}
@@ -2940,7 +2873,7 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
/* clearing autoclear features is trivial */
s->autoclear_features = 0;
ret = qcow2_expand_zero_clusters(bs, status_cb, cb_opaque);
ret = qcow2_expand_zero_clusters(bs, status_cb);
if (ret < 0) {
return ret;
}
@@ -2954,79 +2887,8 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
return 0;
}
typedef enum Qcow2AmendOperation {
/* This is the value Qcow2AmendHelperCBInfo::last_operation will be
* statically initialized to so that the helper CB can discern the first
* invocation from an operation change */
QCOW2_NO_OPERATION = 0,
QCOW2_CHANGING_REFCOUNT_ORDER,
QCOW2_DOWNGRADING,
} Qcow2AmendOperation;
typedef struct Qcow2AmendHelperCBInfo {
/* The code coordinating the amend operations should only modify
* these four fields; the rest will be managed by the CB */
BlockDriverAmendStatusCB *original_status_cb;
void *original_cb_opaque;
Qcow2AmendOperation current_operation;
/* Total number of operations to perform (only set once) */
int total_operations;
/* The following fields are managed by the CB */
/* Number of operations completed */
int operations_completed;
/* Cumulative offset of all completed operations */
int64_t offset_completed;
Qcow2AmendOperation last_operation;
int64_t last_work_size;
} Qcow2AmendHelperCBInfo;
static void qcow2_amend_helper_cb(BlockDriverState *bs,
int64_t operation_offset,
int64_t operation_work_size, void *opaque)
{
Qcow2AmendHelperCBInfo *info = opaque;
int64_t current_work_size;
int64_t projected_work_size;
if (info->current_operation != info->last_operation) {
if (info->last_operation != QCOW2_NO_OPERATION) {
info->offset_completed += info->last_work_size;
info->operations_completed++;
}
info->last_operation = info->current_operation;
}
assert(info->total_operations > 0);
assert(info->operations_completed < info->total_operations);
info->last_work_size = operation_work_size;
current_work_size = info->offset_completed + operation_work_size;
/* current_work_size is the total work size for (operations_completed + 1)
* operations (which includes this one), so multiply it by the number of
* operations not covered and divide it by the number of operations
* covered to get a projection for the operations not covered */
projected_work_size = current_work_size * (info->total_operations -
info->operations_completed - 1)
/ (info->operations_completed + 1);
info->original_status_cb(bs, info->offset_completed + operation_offset,
current_work_size + projected_work_size,
info->original_cb_opaque);
}
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque)
BlockDriverAmendStatusCB *status_cb)
{
BDRVQcow2State *s = bs->opaque;
int old_version = s->qcow_version, new_version = old_version;
@@ -3036,10 +2898,8 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
const char *compat = NULL;
uint64_t cluster_size = s->cluster_size;
bool encrypt;
int refcount_bits = s->refcount_bits;
int ret;
QemuOptDesc *desc = opts->list->desc;
Qcow2AmendHelperCBInfo helper_cb_info;
while (desc && desc->name) {
if (!qemu_opt_find(opts, desc->name)) {
@@ -3057,11 +2917,11 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
} else if (!strcmp(compat, "1.1")) {
new_version = 3;
} else {
error_report("Unknown compatibility level %s", compat);
fprintf(stderr, "Unknown compatibility level %s.\n", compat);
return -EINVAL;
}
} else if (!strcmp(desc->name, BLOCK_OPT_PREALLOC)) {
error_report("Cannot change preallocation mode");
fprintf(stderr, "Cannot change preallocation mode.\n");
return -ENOTSUP;
} else if (!strcmp(desc->name, BLOCK_OPT_SIZE)) {
new_size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
@@ -3074,74 +2934,47 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
!!s->cipher);
if (encrypt != !!s->cipher) {
error_report("Changing the encryption flag is not supported");
fprintf(stderr, "Changing the encryption flag is not "
"supported.\n");
return -ENOTSUP;
}
} else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) {
cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE,
cluster_size);
if (cluster_size != s->cluster_size) {
error_report("Changing the cluster size is not supported");
fprintf(stderr, "Changing the cluster size is not "
"supported.\n");
return -ENOTSUP;
}
} else if (!strcmp(desc->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
lazy_refcounts = qemu_opt_get_bool(opts, BLOCK_OPT_LAZY_REFCOUNTS,
lazy_refcounts);
} else if (!strcmp(desc->name, BLOCK_OPT_REFCOUNT_BITS)) {
refcount_bits = qemu_opt_get_number(opts, BLOCK_OPT_REFCOUNT_BITS,
refcount_bits);
if (refcount_bits <= 0 || refcount_bits > 64 ||
!is_power_of_2(refcount_bits))
{
error_report("Refcount width must be a power of two and may "
"not exceed 64 bits");
return -EINVAL;
}
error_report("Cannot change refcount entry width");
return -ENOTSUP;
} else {
/* if this point is reached, this probably means a new option was
/* if this assertion fails, this probably means a new option was
* added without having it covered here */
abort();
assert(false);
}
desc++;
}
helper_cb_info = (Qcow2AmendHelperCBInfo){
.original_status_cb = status_cb,
.original_cb_opaque = cb_opaque,
.total_operations = (new_version < old_version)
+ (s->refcount_bits != refcount_bits)
};
/* Upgrade first (some features may require compat=1.1) */
if (new_version > old_version) {
s->qcow_version = new_version;
ret = qcow2_update_header(bs);
if (ret < 0) {
s->qcow_version = old_version;
return ret;
}
}
if (s->refcount_bits != refcount_bits) {
int refcount_order = ctz32(refcount_bits);
Error *local_error = NULL;
if (new_version < 3 && refcount_bits != 16) {
error_report("Different refcount widths than 16 bits require "
"compatibility level 1.1 or above (use compat=1.1 or "
"greater)");
return -EINVAL;
}
helper_cb_info.current_operation = QCOW2_CHANGING_REFCOUNT_ORDER;
ret = qcow2_change_refcount_order(bs, refcount_order,
&qcow2_amend_helper_cb,
&helper_cb_info, &local_error);
if (ret < 0) {
error_report_err(local_error);
return ret;
if (new_version != old_version) {
if (new_version > old_version) {
/* Upgrade */
s->qcow_version = new_version;
ret = qcow2_update_header(bs);
if (ret < 0) {
s->qcow_version = old_version;
return ret;
}
} else {
ret = qcow2_downgrade(bs, new_version, status_cb);
if (ret < 0) {
return ret;
}
}
}
@@ -3156,9 +2989,9 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
if (s->use_lazy_refcounts != lazy_refcounts) {
if (lazy_refcounts) {
if (new_version < 3) {
error_report("Lazy refcounts only supported with compatibility "
"level 1.1 and above (use compat=1.1 or greater)");
if (s->qcow_version < 3) {
fprintf(stderr, "Lazy refcounts only supported with compatibility "
"level 1.1 and above (use compat=1.1 or greater)\n");
return -EINVAL;
}
s->compatible_features |= QCOW2_COMPAT_LAZY_REFCOUNTS;
@@ -3192,16 +3025,6 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
}
}
/* Downgrade last (so unsupported features can be removed before) */
if (new_version < old_version) {
helper_cb_info.current_operation = QCOW2_DOWNGRADING;
ret = qcow2_downgrade(bs, new_version, &qcow2_amend_helper_cb,
&helper_cb_info);
if (ret < 0) {
return ret;
}
}
return 0;
}
@@ -3322,7 +3145,6 @@ BlockDriver bdrv_qcow2 = {
.bdrv_reopen_prepare = qcow2_reopen_prepare,
.bdrv_reopen_commit = qcow2_reopen_commit,
.bdrv_reopen_abort = qcow2_reopen_abort,
.bdrv_join_options = qcow2_join_options,
.bdrv_create = qcow2_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_co_get_block_status = qcow2_co_get_block_status,
@@ -3354,7 +3176,6 @@ BlockDriver bdrv_qcow2 = {
.bdrv_refresh_limits = qcow2_refresh_limits,
.bdrv_invalidate_cache = qcow2_invalidate_cache,
.bdrv_inactivate = qcow2_inactivate,
.create_opts = &qcow2_create_opts,
.bdrv_check = qcow2_check,

View File

@@ -529,10 +529,6 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
int64_t size);
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, Error **errp);
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size);
@@ -557,8 +553,7 @@ int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors);
int qcow2_expand_zero_clusters(BlockDriverState *bs,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque);
BlockDriverAmendStatusCB *status_cb);
/* qcow2-snapshot.c functions */
int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);

View File

@@ -11,7 +11,6 @@
*
*/
#include "qemu/osdep.h"
#include "qed.h"
typedef struct {

View File

@@ -12,7 +12,6 @@
*
*/
#include "qemu/osdep.h"
#include "qed.h"
/**

View File

@@ -11,7 +11,6 @@
*
*/
#include "qemu/osdep.h"
#include "qed.h"
void *gencb_alloc(size_t len, BlockCompletionFunc *cb, void *opaque)

View File

@@ -50,7 +50,6 @@
* table will be deleted in favor of the existing cache entry.
*/
#include "qemu/osdep.h"
#include "trace.h"
#include "qed.h"

View File

@@ -12,7 +12,6 @@
*
*/
#include "qemu/osdep.h"
#include "trace.h"
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
#include "qed.h"

View File

@@ -12,7 +12,6 @@
*
*/
#include "qemu/osdep.h"
#include "qemu/timer.h"
#include "trace.h"
#include "qed.h"
@@ -478,7 +477,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
* feature is no longer valid.
*/
if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 &&
!bdrv_is_read_only(bs->file->bs) && !(flags & BDRV_O_INACTIVE)) {
!bdrv_is_read_only(bs->file->bs) && !(flags & BDRV_O_INCOMING)) {
s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK;
ret = qed_write_header_sync(s);
@@ -506,7 +505,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
* aid data recovery from an otherwise inconsistent image.
*/
if (!bdrv_is_read_only(bs->file->bs) &&
!(flags & BDRV_O_INACTIVE)) {
!(flags & BDRV_O_INCOMING)) {
BdrvCheckResult result = {0};
ret = qed_check(s, &result, true);
@@ -1612,8 +1611,9 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs, Error **errp)
memset(s, 0, sizeof(BDRVQEDState));
ret = bdrv_qed_open(bs, NULL, bs->open_flags, &local_err);
if (local_err) {
error_propagate(errp, local_err);
error_prepend(errp, "Could not reopen qed layer: ");
error_setg(errp, "Could not reopen qed layer: %s",
error_get_pretty(local_err));
error_free(local_err);
return;
} else if (ret < 0) {
error_setg_errno(errp, -ret, "Could not reopen qed layer");

View File

@@ -13,7 +13,6 @@
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "block/block_int.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qdict.h"
@@ -647,8 +646,9 @@ static BlockAIOCB *read_quorum_children(QuorumAIOCB *acb)
}
for (i = 0; i < s->num_children; i++) {
bdrv_aio_readv(s->children[i]->bs, acb->sector_num, &acb->qcrs[i].qiov,
acb->nb_sectors, quorum_aio_cb, &acb->qcrs[i]);
acb->qcrs[i].aiocb = bdrv_aio_readv(s->children[i]->bs, acb->sector_num,
&acb->qcrs[i].qiov, acb->nb_sectors,
quorum_aio_cb, &acb->qcrs[i]);
}
return &acb->common;
@@ -663,9 +663,10 @@ static BlockAIOCB *read_fifo_child(QuorumAIOCB *acb)
qemu_iovec_init(&acb->qcrs[acb->child_iter].qiov, acb->qiov->niov);
qemu_iovec_clone(&acb->qcrs[acb->child_iter].qiov, acb->qiov,
acb->qcrs[acb->child_iter].buf);
bdrv_aio_readv(s->children[acb->child_iter]->bs, acb->sector_num,
&acb->qcrs[acb->child_iter].qiov, acb->nb_sectors,
quorum_aio_cb, &acb->qcrs[acb->child_iter]);
acb->qcrs[acb->child_iter].aiocb =
bdrv_aio_readv(s->children[acb->child_iter]->bs, acb->sector_num,
&acb->qcrs[acb->child_iter].qiov, acb->nb_sectors,
quorum_aio_cb, &acb->qcrs[acb->child_iter]);
return &acb->common;
}
@@ -848,7 +849,7 @@ static int parse_read_pattern(const char *opt)
return QUORUM_READ_PATTERN_QUORUM;
}
for (i = 0; i < QUORUM_READ_PATTERN__MAX; i++) {
for (i = 0; i < QUORUM_READ_PATTERN_MAX; i++) {
if (!strcmp(opt, QuorumReadPattern_lookup[i])) {
return i;
}
@@ -998,7 +999,7 @@ static void quorum_attach_aio_context(BlockDriverState *bs,
}
}
static void quorum_refresh_filename(BlockDriverState *bs, QDict *options)
static void quorum_refresh_filename(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
QDict *opts;

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
@@ -52,6 +51,8 @@
#include <sys/dkio.h>
#endif
#ifdef __linux__
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <linux/cdrom.h>
@@ -499,17 +500,21 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
goto fail;
}
if (!s->use_aio && (bdrv_flags & BDRV_O_NATIVE_AIO)) {
error_setg(errp, "aio=native was specified, but it requires "
"cache.direct=on, which was not specified.");
ret = -EINVAL;
goto fail;
error_printf("WARNING: aio=native was specified for '%s', but "
"it requires cache.direct=on, which was not "
"specified. Falling back to aio=threads.\n"
" This will become an error condition in "
"future QEMU versions.\n",
bs->filename);
}
#else
if (bdrv_flags & BDRV_O_NATIVE_AIO) {
error_setg(errp, "aio=native was specified, but is not supported "
"in this build.");
ret = -EINVAL;
goto fail;
error_printf("WARNING: aio=native was specified for '%s', but "
"is not supported in this build. Falling back to "
"aio=threads.\n"
" This will become an error condition in "
"future QEMU versions.\n",
bs->filename);
}
#endif /* !defined(CONFIG_LINUX_AIO) */
@@ -1624,7 +1629,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
PREALLOC_MODE__MAX, PREALLOC_MODE_OFF,
PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
&local_err);
g_free(buf);
if (local_err) {

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
#include "block/block_int.h"

View File

@@ -26,7 +26,6 @@
* IN THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "block/block_int.h"
#include "qemu/option.h"

View File

@@ -11,7 +11,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
#include "qemu/osdep.h"
#include <inttypes.h>
#include "qemu-common.h"
#include "qemu/error-report.h"

View File

@@ -12,7 +12,6 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/uri.h"
#include "qemu/error-report.h"
@@ -1862,7 +1861,8 @@ static int sd_create(const char *filename, QemuOpts *opts,
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report_err(local_err);
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
ret = -EIO;
goto out;
}
@@ -2406,8 +2406,9 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
ret = do_sd_create(s, &new_vid, 1, &local_err);
if (ret < 0) {
error_reportf_err(local_err,
"failed to create inode for snapshot: ");
error_report("failed to create inode for snapshot: %s",
error_get_pretty(local_err));
error_free(local_err);
goto cleanup;
}

View File

@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "block/snapshot.h"
#include "block/block_int.h"
#include "qapi/qmp/qerror.h"
@@ -230,8 +229,6 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
Error **errp)
{
BlockDriver *drv = bs->drv;
int ret;
if (!drv) {
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
return -ENOMEDIUM;
@@ -242,21 +239,18 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
}
/* drain all pending i/o before deleting snapshot */
bdrv_drained_begin(bs);
bdrv_drain(bs);
if (drv->bdrv_snapshot_delete) {
ret = drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
} else if (bs->file) {
ret = bdrv_snapshot_delete(bs->file->bs, snapshot_id, name, errp);
} else {
error_setg(errp, "Block format '%s' used by device '%s' "
"does not support internal snapshot deletion",
drv->format_name, bdrv_get_device_name(bs));
ret = -ENOTSUP;
return drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
}
bdrv_drained_end(bs);
return ret;
if (bs->file) {
return bdrv_snapshot_delete(bs->file->bs, snapshot_id, name, errp);
}
error_setg(errp, "Block format '%s' used by device '%s' "
"does not support internal snapshot deletion",
drv->format_name, bdrv_get_device_name(bs));
return -ENOTSUP;
}
int bdrv_snapshot_delete_by_id_or_name(BlockDriverState *bs,

View File

@@ -22,7 +22,9 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <libssh2.h>
#include <libssh2_sftp.h>

View File

@@ -11,7 +11,6 @@
*
*/
#include "qemu/osdep.h"
#include "trace.h"
#include "block/block_int.h"
#include "block/blockjob.h"

View File

@@ -22,7 +22,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "block/throttle-groups.h"
#include "qemu/queue.h"
#include "qemu/thread.h"

View File

@@ -49,7 +49,6 @@
* so this seems to be reasonable.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"

View File

@@ -15,7 +15,6 @@
*
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "block/vhdx.h"

View File

@@ -17,7 +17,6 @@
* See the COPYING.LIB file in the top-level directory.
*
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/error-report.h"
@@ -785,13 +784,12 @@ int vhdx_parse_log(BlockDriverState *bs, BDRVVHDXState *s, bool *flushed,
if (logs.valid) {
if (bs->read_only) {
ret = -EPERM;
error_setg(errp,
"VHDX image file '%s' opened read-only, but "
"contains a log that needs to be replayed",
bs->filename);
error_append_hint(errp, "To replay the log, run:\n"
"qemu-img check -r all '%s'\n",
bs->filename);
error_setg_errno(errp, EPERM,
"VHDX image file '%s' opened read-only, but "
"contains a log that needs to be replayed. To "
"replay the log, execute:\n qemu-img check -r "
"all '%s'",
bs->filename, bs->filename);
goto exit;
}
/* now flush the log */

View File

@@ -15,7 +15,6 @@
*
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"

View File

@@ -23,7 +23,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qapi/qmp/qerror.h"
@@ -571,6 +570,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
VmdkExtent *extent;
BDRVVmdkState *s = bs->opaque;
int64_t l1_backup_offset = 0;
bool compressed;
ret = bdrv_pread(file->bs, sizeof(magic), &header, sizeof(header));
if (ret < 0) {
@@ -645,6 +645,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
header = footer.header;
}
compressed =
le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
if (le32_to_cpu(header.version) > 3) {
char buf[64];
snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
@@ -652,7 +654,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
error_setg(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bdrv_get_device_or_node_name(bs), "vmdk", buf);
return -ENOTSUP;
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) &&
!compressed) {
/* VMware KB 2064959 explains that version 3 added support for
* persistent changed block tracking (CBT), and backup software can
* read it as version=1 if it doesn't care about the changed area
@@ -761,17 +764,6 @@ static int vmdk_open_sparse(BlockDriverState *bs, BdrvChild *file, int flags,
}
}
static const char *next_line(const char *s)
{
while (*s) {
if (*s == '\n') {
return s + 1;
}
s++;
}
return s;
}
static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
const char *desc_file_path, QDict *options,
Error **errp)
@@ -781,7 +773,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
char access[11];
char type[11];
char fname[512];
const char *p, *np;
const char *p = desc;
int64_t sectors = 0;
int64_t flat_offset;
char *extent_path;
@@ -791,7 +783,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
char extent_opt_prefix[32];
Error *local_err = NULL;
for (p = desc; *p; p = next_line(p)) {
while (*p) {
/* parse extent line in one of below formats:
*
* RW [size in sectors] FLAT "file-name.vmdk" OFFSET
@@ -803,26 +795,29 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
matches = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
access, &sectors, type, fname, &flat_offset);
if (matches < 4 || strcmp(access, "RW")) {
continue;
goto next_line;
} else if (!strcmp(type, "FLAT")) {
if (matches != 5 || flat_offset < 0) {
goto invalid;
error_setg(errp, "Invalid extent lines: \n%s", p);
return -EINVAL;
}
} else if (!strcmp(type, "VMFS")) {
if (matches == 4) {
flat_offset = 0;
} else {
goto invalid;
error_setg(errp, "Invalid extent lines:\n%s", p);
return -EINVAL;
}
} else if (matches != 4) {
goto invalid;
error_setg(errp, "Invalid extent lines:\n%s", p);
return -EINVAL;
}
if (sectors <= 0 ||
(strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE")) ||
(strcmp(access, "RW"))) {
continue;
goto next_line;
}
if (!path_is_absolute(fname) && !path_has_protocol(fname) &&
@@ -879,17 +874,17 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
return -ENOTSUP;
}
extent->type = g_strdup(type);
next_line:
/* move to next line */
while (*p) {
if (*p == '\n') {
p++;
break;
}
p++;
}
}
return 0;
invalid:
np = next_line(p);
assert(np != p);
if (np[-1] == '\n') {
np--;
}
error_setg(errp, "Invalid extent line: %.*s", (int)(np - p), p);
return -EINVAL;
}
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
@@ -1503,8 +1498,8 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
if (sector_num > bs->total_sectors) {
error_report("Wrong offset: sector_num=0x%" PRIx64
" total_sectors=0x%" PRIx64,
sector_num, bs->total_sectors);
" total_sectors=0x%" PRIx64 "\n",
sector_num, bs->total_sectors);
return -EIO;
}

View File

@@ -22,7 +22,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"

View File

@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include <sys/stat.h>
#include <dirent.h>
#include "qemu-common.h"
#include "block/block_int.h"

View File

@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
#include "block/block_int.h"

View File

@@ -10,7 +10,6 @@
* See the COPYING.LIB file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "block/block_int.h"
#include "qemu/coroutine.h"
#include "block/write-threshold.h"

View File

@@ -27,8 +27,9 @@ static void nbd_accept(void *opaque)
socklen_t addr_len = sizeof(addr);
int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
if (fd >= 0) {
nbd_client_new(NULL, fd, nbd_client_put);
if (fd >= 0 && !nbd_client_new(NULL, fd, nbd_client_put)) {
shutdown(fd, 2);
close(fd);
}
}

View File

@@ -348,8 +348,7 @@ static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
}
if (!throttle_is_valid(cfg)) {
error_setg(errp, "bps/iops/max values must be within [0, %lld]",
THROTTLE_VALUE_MAX);
error_setg(errp, "bps/iops/maxs values must be 0 or greater");
return false;
}
@@ -388,6 +387,16 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
}
}
if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_WB, true)) {
*bdrv_flags |= BDRV_O_CACHE_WB;
}
if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_DIRECT, false)) {
*bdrv_flags |= BDRV_O_NOCACHE;
}
if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) {
*bdrv_flags |= BDRV_O_NO_FLUSH;
}
if ((aio = qemu_opt_get(opts, "aio")) != NULL) {
if (!strcmp(aio, "native")) {
*bdrv_flags |= BDRV_O_NATIVE_AIO;
@@ -445,7 +454,7 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
*detect_zeroes =
qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
qemu_opt_get(opts, "detect-zeroes"),
BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX,
BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
&local_error);
if (local_error) {
@@ -481,6 +490,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
QDict *interval_dict = NULL;
QList *interval_list = NULL;
const char *id;
bool has_driver_specific_opts;
BlockdevDetectZeroesOptions detect_zeroes =
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
const char *throttling_group = NULL;
@@ -504,6 +514,8 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
qdict_del(bs_opts, "id");
}
has_driver_specific_opts = !!qdict_size(bs_opts);
/* extract parameters */
snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
@@ -560,11 +572,13 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
}
if (snapshot) {
bdrv_flags |= BDRV_O_SNAPSHOT;
/* always use cache=unsafe with snapshot */
bdrv_flags &= ~BDRV_O_CACHE_MASK;
bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
}
/* init */
if ((!file || !*file) && !qdict_size(bs_opts)) {
if ((!file || !*file) && !has_driver_specific_opts) {
BlockBackendRootState *blk_rs;
blk = blk_new(qemu_opts_id(opts), errp);
@@ -592,20 +606,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
file = NULL;
}
/* bdrv_open() defaults to the values in bdrv_flags (for compatibility
* with other callers) rather than what we want as the real defaults.
* Apply the defaults here instead. */
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_WB, "on");
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_DIRECT, "off");
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
if (snapshot) {
/* always use cache=unsafe with snapshot */
qdict_put(bs_opts, BDRV_OPT_CACHE_WB, qstring_from_str("on"));
qdict_put(bs_opts, BDRV_OPT_CACHE_DIRECT, qstring_from_str("off"));
qdict_put(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, qstring_from_str("on"));
}
blk = blk_new_open(qemu_opts_id(opts), file, NULL, bs_opts, bdrv_flags,
errp);
if (!blk) {
@@ -1583,11 +1583,13 @@ static void internal_snapshot_abort(BlkActionState *common)
}
if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) {
error_reportf_err(local_error,
"Failed to delete snapshot with id '%s' and "
"name '%s' on device '%s' in abort: ",
sn->id_str, sn->name,
bdrv_get_device_name(bs));
error_report("Failed to delete snapshot with id '%s' and name '%s' on "
"device '%s' in abort: %s",
sn->id_str,
sn->name,
bdrv_get_device_name(bs),
error_get_pretty(local_error));
error_free(local_error);
}
}
@@ -2304,6 +2306,11 @@ void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
return;
}
if (!blk_dev_has_tray(blk)) {
/* Ignore this command on tray-less devices */
return;
}
if (blk_dev_is_tray_open(blk)) {
return;
}
@@ -2334,6 +2341,11 @@ void qmp_blockdev_close_tray(const char *device, Error **errp)
return;
}
if (!blk_dev_has_tray(blk)) {
/* Ignore this command on tray-less devices */
return;
}
if (!blk_dev_is_tray_open(blk)) {
return;
}
@@ -2363,7 +2375,7 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp)
return;
}
if (has_device && !blk_dev_is_tray_open(blk)) {
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
error_setg(errp, "Tray of device '%s' is not open", device);
return;
}
@@ -2382,12 +2394,19 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp)
/* This follows the convention established by bdrv_make_anon() */
if (bs->device_list.tqe_prev) {
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
bs->device_list.tqe_prev = NULL;
bdrv_device_remove(bs);
}
blk_remove_bs(blk);
if (!blk_dev_has_tray(blk)) {
/* For tray-less devices, blockdev-open-tray is a no-op (or may not be
* called at all); therefore, the medium needs to be ejected here.
* Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
* value passed here (i.e. false). */
blk_dev_change_media_cb(blk, false);
}
out:
aio_context_release(aio_context);
}
@@ -2413,7 +2432,7 @@ static void qmp_blockdev_insert_anon_medium(const char *device,
return;
}
if (has_device && !blk_dev_is_tray_open(blk)) {
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
error_setg(errp, "Tray of device '%s' is not open", device);
return;
}
@@ -2426,6 +2445,15 @@ static void qmp_blockdev_insert_anon_medium(const char *device,
blk_insert_bs(blk, bs);
QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
if (!blk_dev_has_tray(blk)) {
/* For tray-less devices, blockdev-close-tray is a no-op (or may not be
* called at all); therefore, the medium needs to be pushed into the
* slot here.
* Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
* value passed here (i.e. true). */
blk_dev_change_media_cb(blk, true);
}
}
void qmp_x_blockdev_insert_medium(const char *device, const char *node_name,
@@ -3290,23 +3318,29 @@ void qmp_blockdev_backup(const char *device, const char *target,
NULL, errp);
}
/* Parameter check and block job starting for drive mirroring.
* Caller should hold @device and @target's aio context (must be the same).
**/
static void blockdev_mirror_common(BlockDriverState *bs,
BlockDriverState *target,
bool has_replaces, const char *replaces,
enum MirrorSyncMode sync,
bool has_speed, int64_t speed,
bool has_granularity, uint32_t granularity,
bool has_buf_size, int64_t buf_size,
bool has_on_source_error,
BlockdevOnError on_source_error,
bool has_on_target_error,
BlockdevOnError on_target_error,
bool has_unmap, bool unmap,
Error **errp)
void qmp_drive_mirror(const char *device, const char *target,
bool has_format, const char *format,
bool has_node_name, const char *node_name,
bool has_replaces, const char *replaces,
enum MirrorSyncMode sync,
bool has_mode, enum NewImageMode mode,
bool has_speed, int64_t speed,
bool has_granularity, uint32_t granularity,
bool has_buf_size, int64_t buf_size,
bool has_on_source_error, BlockdevOnError on_source_error,
bool has_on_target_error, BlockdevOnError on_target_error,
bool has_unmap, bool unmap,
Error **errp)
{
BlockBackend *blk;
BlockDriverState *bs;
BlockDriverState *source, *target_bs;
AioContext *aio_context;
Error *local_err = NULL;
QDict *options;
int flags;
int64_t size;
int ret;
if (!has_speed) {
speed = 0;
@@ -3317,6 +3351,9 @@ static void blockdev_mirror_common(BlockDriverState *bs,
if (!has_on_target_error) {
on_target_error = BLOCKDEV_ON_ERROR_REPORT;
}
if (!has_mode) {
mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
}
if (!has_granularity) {
granularity = 0;
}
@@ -3338,55 +3375,6 @@ static void blockdev_mirror_common(BlockDriverState *bs,
return;
}
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR_SOURCE, errp)) {
return;
}
if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_MIRROR_TARGET, errp)) {
return;
}
if (target->blk) {
error_setg(errp, "Cannot mirror to an attached block device");
return;
}
if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) {
sync = MIRROR_SYNC_MODE_FULL;
}
/* pass the node name to replace to mirror start since it's loose coupling
* and will allow to check whether the node still exist at mirror completion
*/
mirror_start(bs, target,
has_replaces ? replaces : NULL,
speed, granularity, buf_size, sync,
on_source_error, on_target_error, unmap,
block_job_cb, bs, errp);
}
void qmp_drive_mirror(const char *device, const char *target,
bool has_format, const char *format,
bool has_node_name, const char *node_name,
bool has_replaces, const char *replaces,
enum MirrorSyncMode sync,
bool has_mode, enum NewImageMode mode,
bool has_speed, int64_t speed,
bool has_granularity, uint32_t granularity,
bool has_buf_size, int64_t buf_size,
bool has_on_source_error, BlockdevOnError on_source_error,
bool has_on_target_error, BlockdevOnError on_target_error,
bool has_unmap, bool unmap,
Error **errp)
{
BlockDriverState *bs;
BlockBackend *blk;
BlockDriverState *source, *target_bs;
AioContext *aio_context;
Error *local_err = NULL;
QDict *options = NULL;
int flags;
int64_t size;
int ret;
blk = blk_by_name(device);
if (!blk) {
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
@@ -3402,14 +3390,15 @@ void qmp_drive_mirror(const char *device, const char *target,
goto out;
}
bs = blk_bs(blk);
if (!has_mode) {
mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
}
if (!has_format) {
format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
}
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR, errp)) {
goto out;
}
flags = bs->open_flags | BDRV_O_RDWR;
source = backing_bs(bs);
if (!source && sync == MIRROR_SYNC_MODE_TOP) {
@@ -3504,81 +3493,25 @@ void qmp_drive_mirror(const char *device, const char *target,
bdrv_set_aio_context(target_bs, aio_context);
blockdev_mirror_common(bs, target_bs,
has_replaces, replaces, sync,
has_speed, speed,
has_granularity, granularity,
has_buf_size, buf_size,
has_on_source_error, on_source_error,
has_on_target_error, on_target_error,
has_unmap, unmap,
&local_err);
if (local_err) {
error_propagate(errp, local_err);
/* pass the node name to replace to mirror start since it's loose coupling
* and will allow to check whether the node still exist at mirror completion
*/
mirror_start(bs, target_bs,
has_replaces ? replaces : NULL,
speed, granularity, buf_size, sync,
on_source_error, on_target_error,
unmap,
block_job_cb, bs, &local_err);
if (local_err != NULL) {
bdrv_unref(target_bs);
error_propagate(errp, local_err);
goto out;
}
out:
aio_context_release(aio_context);
}
void qmp_blockdev_mirror(const char *device, const char *target,
bool has_replaces, const char *replaces,
MirrorSyncMode sync,
bool has_speed, int64_t speed,
bool has_granularity, uint32_t granularity,
bool has_buf_size, int64_t buf_size,
bool has_on_source_error,
BlockdevOnError on_source_error,
bool has_on_target_error,
BlockdevOnError on_target_error,
Error **errp)
{
BlockDriverState *bs;
BlockBackend *blk;
BlockDriverState *target_bs;
AioContext *aio_context;
Error *local_err = NULL;
blk = blk_by_name(device);
if (!blk) {
error_setg(errp, "Device '%s' not found", device);
return;
}
bs = blk_bs(blk);
if (!bs) {
error_setg(errp, "Device '%s' has no media", device);
return;
}
target_bs = bdrv_lookup_bs(target, target, errp);
if (!target_bs) {
return;
}
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
bdrv_ref(target_bs);
bdrv_set_aio_context(target_bs, aio_context);
blockdev_mirror_common(bs, target_bs,
has_replaces, replaces, sync,
has_speed, speed,
has_granularity, granularity,
has_buf_size, buf_size,
has_on_source_error, on_source_error,
has_on_target_error, on_target_error,
true, true,
&local_err);
if (local_err) {
error_propagate(errp, local_err);
bdrv_unref(target_bs);
}
aio_context_release(aio_context);
}
/* Get the block job for a given device name and acquire its AioContext */
static BlockJob *find_block_job(const char *device, AioContext **aio_context,
Error **errp)
@@ -3965,6 +3898,18 @@ QemuOptsList qemu_common_drive_opts = {
.name = "discard",
.type = QEMU_OPT_STRING,
.help = "discard operation (ignore/off, unmap/on)",
},{
.name = BDRV_OPT_CACHE_WB,
.type = QEMU_OPT_BOOL,
.help = "enables writeback mode for any caches",
},{
.name = BDRV_OPT_CACHE_DIRECT,
.type = QEMU_OPT_BOOL,
.help = "enables use of O_DIRECT (bypass the host page cache)",
},{
.name = BDRV_OPT_CACHE_NO_FLUSH,
.type = QEMU_OPT_BOOL,
.help = "ignore any flush requests for the device",
},{
.name = "aio",
.type = QEMU_OPT_STRING,
@@ -4072,6 +4017,18 @@ static QemuOptsList qemu_root_bds_opts = {
.name = "discard",
.type = QEMU_OPT_STRING,
.help = "discard operation (ignore/off, unmap/on)",
},{
.name = "cache.writeback",
.type = QEMU_OPT_BOOL,
.help = "enables writeback mode for any caches",
},{
.name = "cache.direct",
.type = QEMU_OPT_BOOL,
.help = "enables use of O_DIRECT (bypass the host page cache)",
},{
.name = "cache.no-flush",
.type = QEMU_OPT_BOOL,
.help = "ignore any flush requests for the device",
},{
.name = "aio",
.type = QEMU_OPT_STRING,

View File

@@ -938,7 +938,7 @@ int main(int argc, char **argv)
unsigned long tmp;
if (fscanf(fp, "%lu", &tmp) == 1) {
mmap_min_addr = tmp;
qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
}
fclose(fp);
}
@@ -955,7 +955,7 @@ int main(int argc, char **argv)
free(target_environ);
if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
if (qemu_log_enabled()) {
qemu_log("guest_base 0x%lx\n", guest_base);
log_page_dump();

View File

@@ -26,6 +26,8 @@
#include "qemu.h"
#include "target_signal.h"
//#define DEBUG_SIGNAL
void signal_init(void)
{
}

89
configure vendored
View File

@@ -250,7 +250,6 @@ vnc_jpeg=""
vnc_png=""
xen=""
xen_ctrl_version=""
xen_pv_domain_build="no"
xen_pci_passthrough=""
linux_aio=""
cap_ng=""
@@ -928,10 +927,6 @@ for opt do
;;
--enable-xen-pci-passthrough) xen_pci_passthrough="yes"
;;
--disable-xen-pv-domain-build) xen_pv_domain_build="no"
;;
--enable-xen-pv-domain-build) xen_pv_domain_build="yes"
;;
--disable-brlapi) brlapi="no"
;;
--enable-brlapi) brlapi="yes"
@@ -1943,7 +1938,6 @@ fi
if test "$xen" != "no" ; then
xen_libs="-lxenstore -lxenctrl -lxenguest"
xen_stable_libs="-lxenforeignmemory -lxengnttab -lxenevtchn"
# First we test whether Xen headers and libraries are available.
# If no, we are done and there is no Xen support.
@@ -1966,57 +1960,6 @@ EOF
# Xen unstable
elif
cat > $TMPC <<EOF &&
/*
* If we have stable libs the we don't want the libxc compat
* layers, regardless of what CFLAGS we may have been given.
*/
#undef XC_WANT_COMPAT_EVTCHN_API
#undef XC_WANT_COMPAT_GNTTAB_API
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
#include <xenctrl.h>
#include <xenstore.h>
#include <xenevtchn.h>
#include <xengnttab.h>
#include <xenforeignmemory.h>
#include <stdint.h>
#include <xen/hvm/hvm_info_table.h>
#if !defined(HVM_MAX_VCPUS)
# error HVM_MAX_VCPUS not defined
#endif
int main(void) {
xc_interface *xc = NULL;
xenforeignmemory_handle *xfmem;
xenevtchn_handle *xe;
xengnttab_handle *xg;
xen_domain_handle_t handle;
xs_daemon_open();
xc = xc_interface_open(0, 0, 0);
xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000);
xc_hvm_create_ioreq_server(xc, 0, HVM_IOREQSRV_BUFIOREQ_ATOMIC, NULL);
xc_domain_create(xc, 0, handle, 0, NULL, NULL);
xfmem = xenforeignmemory_open(0, 0);
xenforeignmemory_map(xfmem, 0, 0, 0, 0, 0);
xe = xenevtchn_open(0, 0);
xenevtchn_fd(xe);
xg = xengnttab_open(0, 0);
xengnttab_map_grant_ref(xg, 0, 0, 0);
return 0;
}
EOF
compile_prog "" "$xen_libs $xen_stable_libs"
then
xen_ctrl_version=471
xen=yes
elif
cat > $TMPC <<EOF &&
#include <xenctrl.h>
#include <stdint.h>
int main(void) {
@@ -2210,9 +2153,6 @@ EOF
fi
if test "$xen" = yes; then
if test $xen_ctrl_version -ge 471 ; then
libs_softmmu="$xen_stable_libs $libs_softmmu"
fi
libs_softmmu="$xen_libs $libs_softmmu"
fi
fi
@@ -2234,12 +2174,6 @@ if test "$xen_pci_passthrough" != "no"; then
fi
fi
if test "$xen_pv_domain_build" = "yes" &&
test "$xen" != "yes"; then
error_exit "User requested Xen PV domain builder support" \
"which requires Xen support."
fi
##########################################
# libtool probe
@@ -2492,14 +2426,6 @@ else
fi
##########################################
# getifaddrs (for tests/test-io-channel-socket )
have_ifaddrs_h=yes
if ! check_include "ifaddrs.h" ; then
have_ifaddrs_h=no
fi
##########################################
# VTE probe
@@ -4859,7 +4785,6 @@ fi
echo "xen support $xen"
if test "$xen" = "yes" ; then
echo "xen ctrl version $xen_ctrl_version"
echo "pv dom build $xen_pv_domain_build"
fi
echo "brlapi support $brlapi"
echo "bluez support $bluez"
@@ -4884,7 +4809,7 @@ echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
echo "vhost-scsi support $vhost_scsi"
echo "Trace backends $trace_backends"
if have_backend "simple"; then
if test "$trace_backend" = "simple"; then
echo "Trace output file $trace_file-<pid>"
fi
if test "$spice" = "yes"; then
@@ -5216,9 +5141,6 @@ fi
if test "$tasn1" = "yes" ; then
echo "CONFIG_TASN1=y" >> $config_host_mak
fi
if test "$have_ifaddrs_h" = "yes" ; then
echo "HAVE_IFADDRS_H=y" >> $config_host_mak
fi
if test "$vte" = "yes" ; then
echo "CONFIG_VTE=y" >> $config_host_mak
echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak
@@ -5231,9 +5153,6 @@ fi
if test "$xen" = "yes" ; then
echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
if test "$xen_pv_domain_build" = "yes" ; then
echo "CONFIG_XEN_PV_DOMAIN_BUILD=y" >> $config_host_mak
fi
fi
if test "$linux_aio" = "yes" ; then
echo "CONFIG_LINUX_AIO=y" >> $config_host_mak
@@ -5702,20 +5621,20 @@ case "$target_name" in
ppc64)
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
;;
ppc64le)
TARGET_ARCH=ppc64
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
;;
ppc64abi32)
TARGET_ARCH=ppc64
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
echo "TARGET_ABI32=y" >> $config_target_mak
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
;;
sh4|sh4eb)
TARGET_ARCH=sh4

View File

@@ -65,7 +65,7 @@ ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[])
{
int c;
unsigned long long v;
Error *err = NULL;
Error *errp = NULL;
while ((c = getopt(argc, argv,
"h" /* help */
@@ -104,9 +104,11 @@ ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[])
break;
case 'l': /* shm_size */
parse_option_size("shm_size", optarg, &args->shm_size, &err);
if (err) {
error_report_err(err);
parse_option_size("shm_size", optarg, &args->shm_size, &errp);
if (errp) {
fprintf(stderr, "cannot parse shm size: %s\n",
error_get_pretty(errp));
error_free(errp);
ivshmem_server_usage(argv[0], 1);
}
break;

View File

@@ -17,7 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "config.h"
#include "cpu.h"
#include "sysemu/cpus.h"
#include "exec/memory-internal.h"

View File

@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "config.h"
#include "cpu.h"
#include "trace.h"
#include "disas/disas.h"

46
cpus.c
View File

@@ -23,7 +23,7 @@
*/
/* Needed early for CONFIG_BSD etc. */
#include "qemu/osdep.h"
#include "config-host.h"
#include "monitor/monitor.h"
#include "qapi/qmp/qerror.h"
@@ -1310,6 +1310,8 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
static QemuCond *tcg_halt_cond;
static QemuThread *tcg_cpu_thread;
tcg_cpu_address_space_init(cpu, cpu->as);
/* share a single thread for all cpus with TCG */
if (!tcg_cpu_thread) {
cpu->thread = g_malloc0(sizeof(QemuThread));
@@ -1370,17 +1372,6 @@ void qemu_init_vcpu(CPUState *cpu)
cpu->nr_cores = smp_cores;
cpu->nr_threads = smp_threads;
cpu->stopped = true;
if (!cpu->as) {
/* If the target cpu hasn't set up any address spaces itself,
* give it the default one.
*/
AddressSpace *as = address_space_init_shareable(cpu->memory,
"cpu-memory");
cpu->num_ases = 1;
cpu_address_space_init(cpu, as, 0);
}
if (kvm_enabled()) {
qemu_kvm_start_vcpu(cpu);
} else if (tcg_enabled()) {
@@ -1567,29 +1558,22 @@ CpuInfoList *qmp_query_cpus(Error **errp)
info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
info->value->thread_id = cpu->thread_id;
#if defined(TARGET_I386)
info->value->arch = CPU_INFO_ARCH_X86;
info->value->u.x86 = g_new0(CpuInfoX86, 1);
info->value->u.x86->pc = env->eip + env->segs[R_CS].base;
info->value->has_pc = true;
info->value->pc = env->eip + env->segs[R_CS].base;
#elif defined(TARGET_PPC)
info->value->arch = CPU_INFO_ARCH_PPC;
info->value->u.ppc = g_new0(CpuInfoPPC, 1);
info->value->u.ppc->nip = env->nip;
info->value->has_nip = true;
info->value->nip = env->nip;
#elif defined(TARGET_SPARC)
info->value->arch = CPU_INFO_ARCH_SPARC;
info->value->u.sparc = g_new0(CpuInfoSPARC, 1);
info->value->u.sparc->pc = env->pc;
info->value->u.sparc->npc = env->npc;
info->value->has_pc = true;
info->value->pc = env->pc;
info->value->has_npc = true;
info->value->npc = env->npc;
#elif defined(TARGET_MIPS)
info->value->arch = CPU_INFO_ARCH_MIPS;
info->value->u.mips = g_new0(CpuInfoMIPS, 1);
info->value->u.mips->PC = env->active_tc.PC;
info->value->has_PC = true;
info->value->PC = env->active_tc.PC;
#elif defined(TARGET_TRICORE)
info->value->arch = CPU_INFO_ARCH_TRICORE;
info->value->u.tricore = g_new0(CpuInfoTricore, 1);
info->value->u.tricore->PC = env->PC;
#else
info->value->arch = CPU_INFO_ARCH_OTHER;
info->value->u.other = g_new0(CpuInfoOther, 1);
info->value->has_PC = true;
info->value->PC = env->PC;
#endif
/* XXX: waiting for the qapi to support GSList */

View File

@@ -17,7 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "config.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/memory.h"
@@ -356,7 +356,6 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
CPUTLBEntry *te;
hwaddr iotlb, xlat, sz;
unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
int asidx = cpu_asidx_from_attrs(cpu, attrs);
assert(size >= TARGET_PAGE_SIZE);
if (size != TARGET_PAGE_SIZE) {
@@ -364,7 +363,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
}
sz = size;
section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz);
section = address_space_translate_for_iotlb(cpu, paddr, &xlat, &sz);
assert(sz >= TARGET_PAGE_SIZE);
#if defined(DEBUG_TLB)
@@ -449,7 +448,6 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
void *p;
MemoryRegion *mr;
CPUState *cpu = ENV_GET_CPU(env1);
CPUIOTLBEntry *iotlbentry;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = cpu_mmu_index(env1, true);
@@ -457,9 +455,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
(addr & TARGET_PAGE_MASK))) {
cpu_ldub_code(env1, addr);
}
iotlbentry = &env1->iotlb[mmu_idx][page_index];
pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
pd = env1->iotlb[mmu_idx][page_index].addr & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu, pd);
if (memory_region_is_unassigned(mr)) {
CPUClass *cc = CPU_GET_CLASS(cpu);

View File

@@ -7,7 +7,6 @@ crypto-obj-y += tlscreds.o
crypto-obj-y += tlscredsanon.o
crypto-obj-y += tlscredsx509.o
crypto-obj-y += tlssession.o
crypto-obj-y += secret.o
# Let the userspace emulators avoid linking gnutls/etc
crypto-aes-obj-y = aes.o

View File

@@ -27,7 +27,6 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "crypto/aes.h"

View File

@@ -18,7 +18,6 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/aes.h"
#include "crypto/desrfb.h"

View File

@@ -18,7 +18,6 @@
*
*/
#include "qemu/osdep.h"
#include <gcrypt.h>

View File

@@ -18,7 +18,6 @@
*
*/
#include "qemu/osdep.h"
#include <nettle/nettle-types.h>
#include <nettle/aes.h>
#include <nettle/des.h>

View File

@@ -18,71 +18,22 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/cipher.h"
static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
static size_t alg_key_len[QCRYPTO_CIPHER_ALG_LAST] = {
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
[QCRYPTO_CIPHER_ALG_AES_192] = 24,
[QCRYPTO_CIPHER_ALG_AES_256] = 32,
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
};
static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
[QCRYPTO_CIPHER_ALG_AES_192] = 16,
[QCRYPTO_CIPHER_ALG_AES_256] = 16,
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
};
static bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
[QCRYPTO_CIPHER_MODE_ECB] = false,
[QCRYPTO_CIPHER_MODE_CBC] = true,
};
size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg)
{
if (alg >= G_N_ELEMENTS(alg_key_len)) {
return 0;
}
return alg_block_len[alg];
}
size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg)
{
if (alg >= G_N_ELEMENTS(alg_key_len)) {
return 0;
}
return alg_key_len[alg];
}
size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
if (alg >= G_N_ELEMENTS(alg_block_len)) {
return 0;
}
if (mode >= G_N_ELEMENTS(mode_need_iv)) {
return 0;
}
if (mode_need_iv[mode]) {
return alg_block_len[alg];
}
return 0;
}
static bool
qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
size_t nkey,
Error **errp)
{
if ((unsigned)alg >= QCRYPTO_CIPHER_ALG__MAX) {
if ((unsigned)alg >= QCRYPTO_CIPHER_ALG_LAST) {
error_setg(errp, "Cipher algorithm %d out of range",
alg);
return false;
@@ -90,7 +41,7 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
if (alg_key_len[alg] != nkey) {
error_setg(errp, "Cipher key length %zu should be %zu",
nkey, alg_key_len[alg]);
alg_key_len[alg], nkey);
return false;
}
return true;

View File

@@ -26,7 +26,6 @@
* (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
*/
#include "qemu/osdep.h"
#include "crypto/desrfb.h"
static void scrunch(unsigned char *, unsigned long *);

View File

@@ -18,25 +18,18 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/hash.h"
#ifdef CONFIG_GNUTLS_HASH
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG_LAST] = {
[QCRYPTO_HASH_ALG_MD5] = GNUTLS_DIG_MD5,
[QCRYPTO_HASH_ALG_SHA1] = GNUTLS_DIG_SHA1,
[QCRYPTO_HASH_ALG_SHA256] = GNUTLS_DIG_SHA256,
};
static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = {
[QCRYPTO_HASH_ALG_MD5] = 16,
[QCRYPTO_HASH_ALG_SHA1] = 20,
[QCRYPTO_HASH_ALG_SHA256] = 32,
};
gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
{
if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map)) {
@@ -45,15 +38,6 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
return false;
}
size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg)
{
if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_size)) {
return 0;
}
return qcrypto_hash_alg_size[alg];
}
int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
const struct iovec *iov,
size_t niov,

View File

@@ -18,7 +18,6 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/init.h"
#include "qemu/thread.h"

View File

@@ -1,514 +0,0 @@
/*
* QEMU crypto secret support
*
* Copyright (c) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include "qemu/osdep.h"
#include "crypto/secret.h"
#include "crypto/cipher.h"
#include "qom/object_interfaces.h"
#include "qemu/base64.h"
#include "trace.h"
static void
qcrypto_secret_load_data(QCryptoSecret *secret,
uint8_t **output,
size_t *outputlen,
Error **errp)
{
char *data = NULL;
size_t length = 0;
GError *gerr = NULL;
*output = NULL;
*outputlen = 0;
if (secret->file) {
if (secret->data) {
error_setg(errp,
"'file' and 'data' are mutually exclusive");
return;
}
if (!g_file_get_contents(secret->file, &data, &length, &gerr)) {
error_setg(errp,
"Unable to read %s: %s",
secret->file, gerr->message);
g_error_free(gerr);
return;
}
*output = (uint8_t *)data;
*outputlen = length;
} else if (secret->data) {
*outputlen = strlen(secret->data);
*output = (uint8_t *)g_strdup(secret->data);
} else {
error_setg(errp, "Either 'file' or 'data' must be provided");
}
}
static void qcrypto_secret_decrypt(QCryptoSecret *secret,
const uint8_t *input,
size_t inputlen,
uint8_t **output,
size_t *outputlen,
Error **errp)
{
uint8_t *key = NULL, *ciphertext = NULL, *iv = NULL;
size_t keylen, ciphertextlen, ivlen;
QCryptoCipher *aes = NULL;
uint8_t *plaintext = NULL;
*output = NULL;
*outputlen = 0;
if (qcrypto_secret_lookup(secret->keyid,
&key, &keylen,
errp) < 0) {
goto cleanup;
}
if (keylen != 32) {
error_setg(errp, "Key should be 32 bytes in length");
goto cleanup;
}
if (!secret->iv) {
error_setg(errp, "IV is required to decrypt secret");
goto cleanup;
}
iv = qbase64_decode(secret->iv, -1, &ivlen, errp);
if (!iv) {
goto cleanup;
}
if (ivlen != 16) {
error_setg(errp, "IV should be 16 bytes in length not %zu",
ivlen);
goto cleanup;
}
aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256,
QCRYPTO_CIPHER_MODE_CBC,
key, keylen,
errp);
if (!aes) {
goto cleanup;
}
if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) {
goto cleanup;
}
if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) {
ciphertext = qbase64_decode((const gchar*)input,
inputlen,
&ciphertextlen,
errp);
if (!ciphertext) {
goto cleanup;
}
plaintext = g_new0(uint8_t, ciphertextlen + 1);
} else {
ciphertextlen = inputlen;
plaintext = g_new0(uint8_t, inputlen + 1);
}
if (qcrypto_cipher_decrypt(aes,
ciphertext ? ciphertext : input,
plaintext,
ciphertextlen,
errp) < 0) {
plaintext = NULL;
goto cleanup;
}
if (plaintext[ciphertextlen - 1] > 16 ||
plaintext[ciphertextlen - 1] > ciphertextlen) {
error_setg(errp, "Incorrect number of padding bytes (%d) "
"found on decrypted data",
(int)plaintext[ciphertextlen - 1]);
g_free(plaintext);
plaintext = NULL;
goto cleanup;
}
/* Even though plaintext may contain arbitrary NUL
* ensure it is explicitly NUL terminated.
*/
ciphertextlen -= plaintext[ciphertextlen - 1];
plaintext[ciphertextlen] = '\0';
*output = plaintext;
*outputlen = ciphertextlen;
cleanup:
g_free(ciphertext);
g_free(iv);
g_free(key);
qcrypto_cipher_free(aes);
}
static void qcrypto_secret_decode(const uint8_t *input,
size_t inputlen,
uint8_t **output,
size_t *outputlen,
Error **errp)
{
*output = qbase64_decode((const gchar*)input,
inputlen,
outputlen,
errp);
}
static void
qcrypto_secret_prop_set_loaded(Object *obj,
bool value,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
if (value) {
Error *local_err = NULL;
uint8_t *input = NULL;
size_t inputlen = 0;
uint8_t *output = NULL;
size_t outputlen = 0;
qcrypto_secret_load_data(secret, &input, &inputlen, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
if (secret->keyid) {
qcrypto_secret_decrypt(secret, input, inputlen,
&output, &outputlen, &local_err);
g_free(input);
if (local_err) {
error_propagate(errp, local_err);
return;
}
input = output;
inputlen = outputlen;
} else {
if (secret->format != QCRYPTO_SECRET_FORMAT_RAW) {
qcrypto_secret_decode(input, inputlen,
&output, &outputlen, &local_err);
g_free(input);
if (local_err) {
error_propagate(errp, local_err);
return;
}
input = output;
inputlen = outputlen;
}
}
secret->rawdata = input;
secret->rawlen = inputlen;
} else {
g_free(secret->rawdata);
secret->rawlen = 0;
}
}
static bool
qcrypto_secret_prop_get_loaded(Object *obj,
Error **errp G_GNUC_UNUSED)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
return secret->data != NULL;
}
static void
qcrypto_secret_prop_set_format(Object *obj,
int value,
Error **errp G_GNUC_UNUSED)
{
QCryptoSecret *creds = QCRYPTO_SECRET(obj);
creds->format = value;
}
static int
qcrypto_secret_prop_get_format(Object *obj,
Error **errp G_GNUC_UNUSED)
{
QCryptoSecret *creds = QCRYPTO_SECRET(obj);
return creds->format;
}
static void
qcrypto_secret_prop_set_data(Object *obj,
const char *value,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
g_free(secret->data);
secret->data = g_strdup(value);
}
static char *
qcrypto_secret_prop_get_data(Object *obj,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
return g_strdup(secret->data);
}
static void
qcrypto_secret_prop_set_file(Object *obj,
const char *value,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
g_free(secret->file);
secret->file = g_strdup(value);
}
static char *
qcrypto_secret_prop_get_file(Object *obj,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
return g_strdup(secret->file);
}
static void
qcrypto_secret_prop_set_iv(Object *obj,
const char *value,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
g_free(secret->iv);
secret->iv = g_strdup(value);
}
static char *
qcrypto_secret_prop_get_iv(Object *obj,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
return g_strdup(secret->iv);
}
static void
qcrypto_secret_prop_set_keyid(Object *obj,
const char *value,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
g_free(secret->keyid);
secret->keyid = g_strdup(value);
}
static char *
qcrypto_secret_prop_get_keyid(Object *obj,
Error **errp)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
return g_strdup(secret->keyid);
}
static void
qcrypto_secret_complete(UserCreatable *uc, Error **errp)
{
object_property_set_bool(OBJECT(uc), true, "loaded", errp);
}
static void
qcrypto_secret_init(Object *obj)
{
object_property_add_bool(obj, "loaded",
qcrypto_secret_prop_get_loaded,
qcrypto_secret_prop_set_loaded,
NULL);
object_property_add_enum(obj, "format",
"QCryptoSecretFormat",
QCryptoSecretFormat_lookup,
qcrypto_secret_prop_get_format,
qcrypto_secret_prop_set_format,
NULL);
object_property_add_str(obj, "data",
qcrypto_secret_prop_get_data,
qcrypto_secret_prop_set_data,
NULL);
object_property_add_str(obj, "file",
qcrypto_secret_prop_get_file,
qcrypto_secret_prop_set_file,
NULL);
object_property_add_str(obj, "keyid",
qcrypto_secret_prop_get_keyid,
qcrypto_secret_prop_set_keyid,
NULL);
object_property_add_str(obj, "iv",
qcrypto_secret_prop_get_iv,
qcrypto_secret_prop_set_iv,
NULL);
}
static void
qcrypto_secret_finalize(Object *obj)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
g_free(secret->iv);
g_free(secret->file);
g_free(secret->keyid);
g_free(secret->rawdata);
g_free(secret->data);
}
static void
qcrypto_secret_class_init(ObjectClass *oc, void *data)
{
UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
ucc->complete = qcrypto_secret_complete;
}
int qcrypto_secret_lookup(const char *secretid,
uint8_t **data,
size_t *datalen,
Error **errp)
{
Object *obj;
QCryptoSecret *secret;
obj = object_resolve_path_component(
object_get_objects_root(), secretid);
if (!obj) {
error_setg(errp, "No secret with id '%s'", secretid);
return -1;
}
secret = (QCryptoSecret *)
object_dynamic_cast(obj,
TYPE_QCRYPTO_SECRET);
if (!secret) {
error_setg(errp, "Object with id '%s' is not a secret",
secretid);
return -1;
}
if (!secret->rawdata) {
error_setg(errp, "Secret with id '%s' has no data",
secretid);
return -1;
}
*data = g_new0(uint8_t, secret->rawlen + 1);
memcpy(*data, secret->rawdata, secret->rawlen);
(*data)[secret->rawlen] = '\0';
*datalen = secret->rawlen;
return 0;
}
char *qcrypto_secret_lookup_as_utf8(const char *secretid,
Error **errp)
{
uint8_t *data;
size_t datalen;
if (qcrypto_secret_lookup(secretid,
&data,
&datalen,
errp) < 0) {
return NULL;
}
if (!g_utf8_validate((const gchar*)data, datalen, NULL)) {
error_setg(errp,
"Data from secret %s is not valid UTF-8",
secretid);
g_free(data);
return NULL;
}
return (char *)data;
}
char *qcrypto_secret_lookup_as_base64(const char *secretid,
Error **errp)
{
uint8_t *data;
size_t datalen;
char *ret;
if (qcrypto_secret_lookup(secretid,
&data,
&datalen,
errp) < 0) {
return NULL;
}
ret = g_base64_encode(data, datalen);
g_free(data);
return ret;
}
static const TypeInfo qcrypto_secret_info = {
.parent = TYPE_OBJECT,
.name = TYPE_QCRYPTO_SECRET,
.instance_size = sizeof(QCryptoSecret),
.instance_init = qcrypto_secret_init,
.instance_finalize = qcrypto_secret_finalize,
.class_size = sizeof(QCryptoSecretClass),
.class_init = qcrypto_secret_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_USER_CREATABLE },
{ }
}
};
static void
qcrypto_secret_register_types(void)
{
type_register_static(&qcrypto_secret_info);
}
type_init(qcrypto_secret_register_types);

View File

@@ -18,7 +18,6 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/tlscredspriv.h"
#include "trace.h"

View File

@@ -18,7 +18,6 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/tlscredsanon.h"
#include "crypto/tlscredspriv.h"
#include "qom/object_interfaces.h"

View File

@@ -18,10 +18,8 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/tlscredsx509.h"
#include "crypto/tlscredspriv.h"
#include "crypto/secret.h"
#include "qom/object_interfaces.h"
#include "trace.h"
@@ -609,30 +607,9 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
}
if (cert != NULL && key != NULL) {
#if GNUTLS_VERSION_NUMBER >= 0x030111
char *password = NULL;
if (creds->passwordid) {
password = qcrypto_secret_lookup_as_utf8(creds->passwordid,
errp);
if (!password) {
goto cleanup;
}
}
ret = gnutls_certificate_set_x509_key_file2(creds->data,
cert, key,
GNUTLS_X509_FMT_PEM,
password,
0);
g_free(password);
#else /* GNUTLS_VERSION_NUMBER < 0x030111 */
if (creds->passwordid) {
error_setg(errp, "PKCS8 decryption requires GNUTLS >= 3.1.11");
goto cleanup;
}
ret = gnutls_certificate_set_x509_key_file(creds->data,
cert, key,
GNUTLS_X509_FMT_PEM);
#endif /* GNUTLS_VERSION_NUMBER < 0x030111 */
if (ret < 0) {
error_setg(errp, "Cannot load certificate '%s' & key '%s': %s",
cert, key, gnutls_strerror(ret));
@@ -760,27 +737,6 @@ qcrypto_tls_creds_x509_prop_set_sanity(Object *obj,
}
static void
qcrypto_tls_creds_x509_prop_set_passwordid(Object *obj,
const char *value,
Error **errp G_GNUC_UNUSED)
{
QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj);
creds->passwordid = g_strdup(value);
}
static char *
qcrypto_tls_creds_x509_prop_get_passwordid(Object *obj,
Error **errp G_GNUC_UNUSED)
{
QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj);
return g_strdup(creds->passwordid);
}
static bool
qcrypto_tls_creds_x509_prop_get_sanity(Object *obj,
Error **errp G_GNUC_UNUSED)
@@ -813,10 +769,6 @@ qcrypto_tls_creds_x509_init(Object *obj)
qcrypto_tls_creds_x509_prop_get_sanity,
qcrypto_tls_creds_x509_prop_set_sanity,
NULL);
object_property_add_str(obj, "passwordid",
qcrypto_tls_creds_x509_prop_get_passwordid,
qcrypto_tls_creds_x509_prop_set_passwordid,
NULL);
}
@@ -825,7 +777,6 @@ qcrypto_tls_creds_x509_finalize(Object *obj)
{
QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj);
g_free(creds->passwordid);
qcrypto_tls_creds_x509_unload(creds);
}

View File

@@ -18,7 +18,6 @@
*
*/
#include "qemu/osdep.h"
#include "crypto/tlssession.h"
#include "crypto/tlscredsanon.h"
#include "crypto/tlscredsx509.h"

View File

@@ -9,11 +9,6 @@ CONFIG_VGA_CIRRUS=y
CONFIG_VMWARE_VGA=y
CONFIG_VIRTIO_VGA=y
CONFIG_VMMOUSE=y
CONFIG_IPMI=y
CONFIG_IPMI_LOCAL=y
CONFIG_IPMI_EXTERN=y
CONFIG_ISA_IPMI_KCS=y
CONFIG_ISA_IPMI_BT=y
CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
@@ -51,10 +46,7 @@ CONFIG_APIC=y
CONFIG_IOAPIC=y
CONFIG_PVPANIC=y
CONFIG_MEM_HOTPLUG=y
CONFIG_NVDIMM=y
CONFIG_ACPI_NVDIMM=y
CONFIG_XIO3130=y
CONFIG_IOH3420=y
CONFIG_I82801B11=y
CONFIG_SMBIOS=y
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)

View File

@@ -9,11 +9,6 @@ CONFIG_VGA_CIRRUS=y
CONFIG_VMWARE_VGA=y
CONFIG_VIRTIO_VGA=y
CONFIG_VMMOUSE=y
CONFIG_IPMI=y
CONFIG_IPMI_LOCAL=y
CONFIG_IPMI_EXTERN=y
CONFIG_ISA_IPMI_KCS=y
CONFIG_ISA_IPMI_BT=y
CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
@@ -51,10 +46,7 @@ CONFIG_APIC=y
CONFIG_IOAPIC=y
CONFIG_PVPANIC=y
CONFIG_MEM_HOTPLUG=y
CONFIG_NVDIMM=y
CONFIG_ACPI_NVDIMM=y
CONFIG_XIO3130=y
CONFIG_IOH3420=y
CONFIG_I82801B11=y
CONFIG_SMBIOS=y
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)

View File

@@ -4,10 +4,7 @@ common-obj-$(CONFIG_ARM_DIS) += arm.o
common-obj-$(CONFIG_ARM_A64_DIS) += arm-a64.o
common-obj-$(CONFIG_ARM_A64_DIS) += libvixl/
libvixldir = $(SRC_PATH)/disas/libvixl
# The -Wno-sign-compare is needed only for gcc 4.6, which complains about
# some signed-unsigned equality comparisons in libvixl which later gcc
# versions do not.
arm-a64.o-cflags := -I$(libvixldir) -Wno-sign-compare
arm-a64.o-cflags := -I$(libvixldir)
common-obj-$(CONFIG_CRIS_DIS) += cris.o
common-obj-$(CONFIG_HPPA_DIS) += hppa.o
common-obj-$(CONFIG_I386_DIS) += i386.o

View File

@@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License
along with this file; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>. */
#include "qemu/osdep.h"
#include <stdio.h>
#include "disas/bfd.h"
/* MAX is redefined below, so remove any previous definition. */

View File

@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "vixl/a64/disasm-a64.h"
#include "a64/disasm-a64.h"
extern "C" {
#include "disas/bfd.h"

View File

@@ -22,7 +22,6 @@
/* Start of qemu specific additions. Mostly this is stub definitions
for things we don't care about. */
#include "qemu/osdep.h"
#include "disas/bfd.h"
#define ATTRIBUTE_UNUSED __attribute__((unused))
#define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')

View File

@@ -18,7 +18,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "disas/bfd.h"
//#include "sysdep.h"

View File

@@ -1,11 +1,8 @@
libvixl_OBJS = vixl/utils.o \
vixl/compiler-intrinsics.o \
vixl/a64/instructions-a64.o \
vixl/a64/decoder-a64.o \
vixl/a64/disasm-a64.o
libvixl_OBJS = utils.o \
a64/instructions-a64.o \
a64/decoder-a64.o \
a64/disasm-a64.o
# The -Wno-sign-compare is needed only for gcc 4.6, which complains about
# some signed-unsigned equality comparisons which later gcc versions do not.
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS := -I$(SRC_PATH)/disas/libvixl $(QEMU_CFLAGS) -Wno-sign-compare
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS := -I$(SRC_PATH)/disas/libvixl $(QEMU_CFLAGS)
common-obj-$(CONFIG_ARM_A64_DIS) += $(libvixl_OBJS)

View File

@@ -2,10 +2,11 @@
The code in this directory is a subset of libvixl:
https://github.com/armvixl/vixl
(specifically, it is the set of files needed for disassembly only,
taken from libvixl 1.12).
taken from libvixl 1.7).
Bugfixes should preferably be sent upstream initially.
The disassembler does not currently support the entire A64 instruction
set. Notably:
* No Advanced SIMD support.
* Limited support for system instructions.
* A few miscellaneous integer and floating point instructions are missing.

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More