Compare commits

...

31 Commits

Author SHA1 Message Date
a6885c7d11 Add Vitastor support 2024-02-07 01:11:30 +03:00
Thomas Lamprecht
676adda3c6 bump version to 8.1.5-2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-02-02 19:41:31 +01:00
Thomas Lamprecht
4ff04bdfa5 work around stuck guest IO with iothread and VirtIO block/SCSI
This essentially repeats commit 6b7c181 ("add patch to work around
stuck guest IO with iothread and VirtIO block/SCSI") with an added
fix for the SCSI event virtqueue, which requires special handling.
This is to avoid the issue [3] that made the revert 2a49e66 ("Revert
"add patch to work around stuck guest IO with iothread and VirtIO
block/SCSI"") necessary the first time around.

When using iothread, after commits
1665d9326f ("virtio-blk: implement BlockDevOps->drained_begin()")
766aa2de0f ("virtio-scsi: implement BlockDevOps->drained_begin()")
it can happen that polling gets stuck when draining. This would cause
IO in the guest to get completely stuck.

A workaround for users is stopping and resuming the vCPUs because that
would also stop and resume the dataplanes which would kick the host
notifiers.

This can happen with block jobs like backup and drive mirror as well
as with hotplug [2].

Reports in the community forum that might be about this issue[0][1]
and there is also one in the enterprise support channel.

As a workaround in the code, just re-enable notifications and kick the
virt queue after draining. Draining is already costly and rare, so no
need to worry about a performance penalty here.

Take special care to attach the SCSI event virtqueue host notifier
with the _no_poll() variant like in virtio_scsi_dataplane_start().
This avoids the issue from the first attempted fix where the iothread
would suddenly loop with 100% CPU usage whenever some guest IO came in
[3]. This is necessary because of commit 38738f7dbb ("virtio-scsi:
don't waste CPU polling the event virtqueue"). See [4] for the
relevant discussion.

[0]: https://forum.proxmox.com/threads/137286/
[1]: https://forum.proxmox.com/threads/137536/
[2]: https://issues.redhat.com/browse/RHEL-3934
[3]: https://forum.proxmox.com/threads/138140/
[4]: https://lore.kernel.org/qemu-devel/bfc7b20c-2144-46e9-acbc-e726276c5a31@proxmox.com/

Link: https://lore.kernel.org/qemu-devel/20240202153158.788922-1-hreitz@redhat.com/
Originally-by: Fiona Ebner <f.ebner@proxmox.com>
 [ TL: Update to v2 and rebased patch series handling to v8.1.5 ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-02-02 19:35:34 +01:00
Thomas Lamprecht
12b69ed9c5 bump version to 8.1.5-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-02-02 19:08:16 +01:00
Fiona Ebner
5e8903f875 stable fixes for corner case in i386 emulation and crash with VNC clipboard
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2024-02-02 19:06:29 +01:00
Fiona Ebner
4b7975e75d update submodule and patches to QEMU 8.1.5
Most notable fixes from a Proxmox VE perspective are:

* "virtio-net: correctly copy vnet header when flushing TX"
  To prevent a stack overflow that could lead to leaking parts of the
  QEMU process's memory.
* "hw/pflash: implement update buffer for block writes"
  To prevent an edge case for half-completed writes. This potentially
  affected EFI disks.
* Fixes to i386 emulation and ARM emulation.

No changes for patches were necessary (all are just automatic context
changes).

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2024-02-02 19:06:29 +01:00
Fiona Ebner
f366bb97ae bump version to 8.1.2-6
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-12-15 14:26:09 +01:00
Fiona Ebner
2a49e667ba Revert "add patch to work around stuck guest IO with iothread and VirtIO block/SCSI"
This reverts commit 6b7c1815e1.

The attempted fix has been reported to cause high CPU usage after
backup [0]. Not difficult to reproduce and it's iothreads getting
stuck in a loop. Downgrading to pve-qemu-kvm=8.1.2-4 helps which was
also verified by Christian, thanks! The issue this was supposed to fix
is much rarer, so revert for now, while upstream is still working on a
proper fix.

[0]: https://forum.proxmox.com/threads/138140/

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-12-15 14:16:26 +01:00
Thomas Lamprecht
c6eb05a799 bump version to 8.1.2-5
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-12-11 16:59:16 +01:00
Fiona Ebner
dfac4f3593 pick fix for potential deadlock with QMP resize and iothread
While the patch gives bdrv_graph_wrlock() as an example where the
issue can manifest, something similar can happen even when that is
disabled. Was able to reproduce the issue with
while true; do qm resize 115 scsi0 +4M; sleep 1; done
while running
fio --name=make-mirror-work --size=100M --direct=1 --rw=randwrite \
 --bs=4k --ioengine=psync --numjobs=5 --runtime=1200 --time_based
in the VM.

Fix picked up from:
https://lists.nongnu.org/archive/html/qemu-devel/2023-12/msg01102.html

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-12-11 16:56:50 +01:00
Fiona Ebner
6b7c1815e1 add patch to work around stuck guest IO with iothread and VirtIO block/SCSI
When using iothread, after commits
1665d9326f ("virtio-blk: implement BlockDevOps->drained_begin()")
766aa2de0f ("virtio-scsi: implement BlockDevOps->drained_begin()")
it can happen that polling gets stuck when draining. This would cause
IO in the guest to get completely stuck.

A workaround for users is stopping and resuming the vCPUs because that
would also stop and resume the dataplanes which would kick the host
notifiers.

This can happen with block jobs like backup and drive mirror as well
as with hotplug [2].

Reports in the community forum that might be about this issue[0][1]
and there is also one in the enterprise support channel.

As a workaround in the code, just re-enable notifications and kick the
virt queue after draining. Draining is already costly and rare, so no
need to worry about a performance penalty here. This was taken from
the following comment of a QEMU developer [3] (in my debugging,
I had already found re-enabling notification to work around the issue,
but also kicking the queue is more complete).

[0]: https://forum.proxmox.com/threads/137286/
[1]: https://forum.proxmox.com/threads/137536/
[2]: https://issues.redhat.com/browse/RHEL-3934
[3]: https://issues.redhat.com/browse/RHEL-3934?focusedId=23562096&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-23562096

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-12-11 16:56:50 +01:00
Thomas Lamprecht
24d732ac0f bump version to 8.1.2-4
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-11-22 14:28:25 +01:00
Fiona Ebner
df2cc786ee add fix for vnc clipboard
This fixes the host->guest direction with noNVC as a client (and
likely others).

Reported-by: Friedrich Weber <f.weber@proxmox.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Tested-by: Friedrich Weber <f.weber@proxmox.com>
2023-11-22 14:19:45 +01:00
Thomas Lamprecht
38726d3473 bump version to 8.1.2-3
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-11-20 10:35:52 +01:00
Fiona Ebner
89b46e17ec fix #5054: backport fix for software reset with SATA
The issue prevented FreeBSD 14 VMs with SATA disk from booting.

The commit it fixes e2a5d9b3d9c3 ("hw/ide/ahci: simplify and document
PxCI handling") is part of stable 8.1.2.

The patch was already applied to the block branch upstream:
https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg02711.html

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Tested-by: Friedrich Weber <f.weber@proxmox.com>
2023-11-20 10:35:00 +01:00
Thomas Lamprecht
33b22c3fe0 bump version to 8.1.2-2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-11-17 11:55:26 +01:00
Fiona Ebner
c38e337f5d revert commit breaking VirtIO network adapters for certain versions of Windows
As reported in the community forum [0] and reproduced locally this
breaks VirtIO network adapters in (at least) the German ISO of Windows
Server 2022. The fix itself was for

> Issue is not fatal but as result acpi-index/"PCI Label ID" property
> is either not shown in device details page or shows incorrect value.

so revert and tolerate that as a stop-gap, rather than have the
devices not working at all.

[0]: https://forum.proxmox.com/threads/92094/post-605684

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-11-17 11:52:52 +01:00
Fiona Ebner
763949965f fix #4710: vma create: don't use O_DIRECT for tmpfs
The implementation of the helper is_path_tmpfs() is similar to the
existing qemu_fd_getfs() function in util/mmap-alloc.c, which
unfortunately only takes an existing fd.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-11-07 16:37:34 +01:00
Thomas Lamprecht
1807330a6f bump version to 8.1.2-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Thomas Lamprecht
a31ab74058 d/control: add python3-venv as build-dependency
Seems to be required since commit 81e2b198a8 ("configure: create a
python venv unconditionally").

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Fiona Ebner
b39f726f31 d/control: add versioned Breaks for qemu-server <= 8.0.6
Upstream QEMU commit 4271f40383 ("virtio-net: correctly report maximum
tx_queue_size value") made setting an invalid tx_queue_size for a
non-vDPA/vhost-user net device a hard error. Now, qemu-server before
commit 089aed81 ("cfg2cmd: netdev: fix value for tx_queue_size") did
just that, so the newer QEMU version would break start-up for most VMs
(a default vNIC configuration would be affected).

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Fiona Ebner
a36bda146c add patch to avoid huge snapshot performance regression
Taking a snapshot became prohibitively slow because of the
migration_transferred_bytes() call in migration_rate_exceeded() [0].

This also applied to the async snapshot taking in Proxmox VE, so
work around the issue until it is fixed upstream.

[0]: https://gitlab.com/qemu-project/qemu/-/issues/1821

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Fiona Ebner
03ff63aa61 add patch to disable graph locking
There are still some issues with graph locking, e.g. deadlocks during
backup canceling [0] and initial attempts to fix it didn't work [1].
Because the AioContext locks still exist, it should still be safe to
disable graph locking.

[0]: https://lists.nongnu.org/archive/html/qemu-devel/2023-09/msg00729.html
[1]: https://lists.nongnu.org/archive/html/qemu-devel/2023-09/msg06905.html

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Fiona Ebner
10e1093325 update submodule and patches to QEMU 8.1.2
Bigger notable changes:

* Commit 1a30b0f5d7 ("block: .bdrv_open is non-coroutine and
  unlocked") broke the PVE backup patches, in particular setting up
  the backup dump block driver, because bdrv_new_open_driver() cannot
  be called from a coroutine. To fix it, bdrv_co_open() is used
  instead, and while it's a much more involved function, the result
  should be essentially the same. The only difference I noticed is
  that the BDRV_O_ALLOW_RDWR flag is also set in the resulting bds
  (block driver state), but that shouldn't hurt.

Smaller notable changes:

* aio_set_fd_handler() dropped its 'is_external' parameter stating
  that all callers now pass false in 60f782b6b7 ("aio: remove
  aio_disable_external() API"). The calls in the PVE patches also
  passed false, so just drop the parameter too.

* global_state_store() does not have a return value anymore, so the
  user in the PVE savevm-async patch was adapted. For context, see
  c33f1829f8 ("migration: never fail in global_state_store()").

* Renames affecting the PVE savevm-async patch:
  migrate_use_block() -> migrate_block() and ram_counters -> mig_stats
  9d4b1e5f22 ("migration: Move migrate_use_block() to options.c")
  aff3f6606d ("migration: Rename ram_counters to mig_stats")

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Fiona Ebner
0d9c737d61 buildsys: use QEMU's keycodemapdb again
instead of the split-out version that was last updated for QEMU 6.0.
This reverts the relevant part of 6838f03 ("bump version to 2.11.1-1")
which doesn't state a reason why the splitting was done. If something
breaks, we can still re-do it and document the reason this time.

Alternatively, it would be necessary to adapt the paths, because
keycodemapdb lives in subprojects/ rather than ui/ since QEMU commit
c53648abba ("meson: use subproject for keycodemapdb").

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Fiona Ebner
a6ddea7ef7 buildsys: fixup submodule target
It's not enough to initialize the submodules anymore, as some got
replaced by wrap files, see QEMU commit 2019cabfee ("meson:
subprojects: replace submodules with wrap files").

Download the subprojects during initialization of the QEMU submodule,
so building (without the automagical --enable-download) can succeeed
afterwards.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Fiona Ebner
89520c1cd0 d/rules: use disable-download option instead of git-submodules=ignore
See the following QEMU commits for reference:
0c5f3dcbb2 ("configure: add --enable-pypi and --disable-pypi")
ac4ccac740 ("configure: rename --enable-pypi to --enable-download, control subprojects too")
6f3ae23b29 ("configure: remove --with-git-submodules=") removed

The last one removed the option and the closest thing to
git-submodule=ignore is using disable-download. Which will then just
verify that the submodules are present.

Building now will require running either
* Running 'meson subprojects download' in the qemu submodule first.
* Using --enable-download, but then the submodules would be downloaded
  for each build (if not already downloaded in the submodule first)
  and it's just a bit too surprising if downloads happen during build.

The disable-download option will also disable automatic downloading of
missing Python modules from PyPI. Hopefully, it's enough to add them
as Debian build dependencies when required.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-24 15:01:23 +02:00
Thomas Lamprecht
eca4daeeed bump version to 8.0.2-7
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-10-04 08:33:39 +02:00
Fiona Ebner
816077299c fix #2874: SATA: avoid unsolicited write to sector 0 during reset
If there is a pending DMA operation during ide_bus_reset(), the fact
that the IDEstate is already reset before the operation is canceled
can be problematic. In particular, ide_dma_cb() might be called and
then use the reset IDEstate which contains the signature after the
reset. When used to construct the IO operation this leads to
ide_get_sector() returning 0 and nsector being 1. This is particularly
bad, because a write command will thus destroy the first sector which
often contains a partition table or similar.

Upstream discussion:
https://lists.nongnu.org/archive/html/qemu-devel/2023-08/msg04239.html

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-09-26 11:30:22 +02:00
Fiona Ebner
ef3308db71 vma: avoid compiler warning about incompatible pointer type
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-09-08 11:18:30 +02:00
Filip Schauer
0ff45eb23e backup: Fix spelling error in function name
Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
[FE: fixup patch context]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-09-08 11:13:04 +02:00
84 changed files with 2367 additions and 5770 deletions

View File

@@ -17,7 +17,10 @@ all: $(DEBS)
.PHONY: submodule
submodule:
test -f "$(SRCDIR)/configure" || git submodule update --init --recursive
ifeq ($(shell test -f "$(SRCDIR)/configure" && echo 1 || echo 0), 0)
git submodule update --init --recursive
cd $(SRCDIR); meson subprojects download
endif
PC_BIOS_FW_PURGE_LIST_IN = \
hppa-firmware.img \
@@ -36,16 +39,14 @@ PC_BIOS_FW_PURGE_LIST_IN = \
BLOB_PURGE_SED_CMDS = $(foreach FILE,$(PC_BIOS_FW_PURGE_LIST_IN),-e "/$(FILE)/d")
BLOB_PURGE_FILTER = $(foreach FILE,$(PC_BIOS_FW_PURGE_LIST_IN),-e "$(FILE)")
$(BUILDDIR): keycodemapdb | submodule
$(BUILDDIR): submodule
# check if qemu/ was used for a build
# if so, please run 'make distclean' in the submodule and try again
test ! -f $(SRCDIR)/build/config.status
rm -rf $@.tmp $@
cp -a $(SRCDIR) $@.tmp
cp -a debian $@.tmp/debian
rm -rf $@.tmp/ui/keycodemapdb
rm -rf $@.tmp/roms/edk2 # packaged separately
cp -a keycodemapdb $@.tmp/ui/
find $@.tmp/pc-bios -type f | grep $(BLOB_PURGE_FILTER) | xargs rm -f
sed -i $(BLOB_PURGE_SED_CMDS) $@.tmp/pc-bios/meson.build
echo "git clone git://git.proxmox.com/git/pve-qemu.git\\ngit checkout $(GITVERSION)" > $@.tmp/debian/SOURCE
@@ -55,7 +56,7 @@ $(BUILDDIR): keycodemapdb | submodule
deb kvm: $(DEBS)
$(DEB_DBG): $(DEB)
$(DEB): $(BUILDDIR)
cd $(BUILDDIR); dpkg-buildpackage -b -us -uc -j
cd $(BUILDDIR); dpkg-buildpackage -b -us -uc -j32
lintian $(DEBS)
sbuild: $(DSC)
@@ -73,17 +74,6 @@ dsc:
$(DSC): $(ORIG_SRC_TAR) $(BUILDDIR)
cd $(BUILDDIR); dpkg-buildpackage -S -us -uc -d
.PHONY: update
update:
cd $(SRCDIR) && git submodule deinit ui/keycodemapdb || true
rm -rf $(SRCDIR)/ui/keycodemapdb
mkdir $(SRCDIR)/ui/keycodemapdb
cd $(SRCDIR) && git submodule update --init ui/keycodemapdb
rm -rf keycodemapdb
mkdir keycodemapdb
cp -R $(SRCDIR)/ui/keycodemapdb/* keycodemapdb/
git add keycodemapdb
.PHONY: upload
upload: UPLOAD_DIST ?= $(DEB_DISTRIBUTION)
upload: $(DEBS)

79
debian/changelog vendored
View File

@@ -1,3 +1,82 @@
pve-qemu-kvm (8.1.5-2+vitastor1) bookworm; urgency=medium
* Add Vitastor support
-- Vitaliy Filippov <vitalif@yourcmc.ru> Wed, 07 Feb 2024 01:11:00 +0300
pve-qemu-kvm (8.1.5-2) bookworm; urgency=medium
* work around for a situation where guest IO might get stuck, if the VM is
configure with iothread and VirtIO block/SCSI
-- Proxmox Support Team <support@proxmox.com> Fri, 02 Feb 2024 19:41:27 +0100
pve-qemu-kvm (8.1.5-1) bookworm; urgency=medium
* update to 8.1.5 stable release, including more relevant fixes like:
- virtio-net: correctly copy vnet header when flushing TX
- hw/pflash: implement update buffer for block writes
- Fixes to i386 emulation and ARM emulation.
-- Proxmox Support Team <support@proxmox.com> Fri, 02 Feb 2024 19:08:13 +0100
pve-qemu-kvm (8.1.2-6) bookworm; urgency=medium
* revert attempted fix to avoid rare issue with stuck guest IO when using
iothread, because it caused a much more common issue with iothreads
consuming too much CPU
-- Proxmox Support Team <support@proxmox.com> Fri, 15 Dec 2023 14:22:06 +0100
pve-qemu-kvm (8.1.2-5) bookworm; urgency=medium
* backport workaround for stuck guest IO with iothread and VirtIO block/SCSI
in some rare edge cases
* backport fix for potential deadlock when issuing the "resize" QMP command
for a disk that is using iothread
-- Proxmox Support Team <support@proxmox.com> Mon, 11 Dec 2023 16:58:27 +0100
pve-qemu-kvm (8.1.2-4) bookworm; urgency=medium
* fix vnc clipboard in the host to guest direction
-- Proxmox Support Team <support@proxmox.com> Wed, 22 Nov 2023 14:28:21 +0100
pve-qemu-kvm (8.1.2-3) bookworm; urgency=medium
* fix #5054: backport fix for software reset with SATA, avoiding breakage
with, e.g., some FreeBSD VMs
-- Proxmox Support Team <support@proxmox.com> Mon, 20 Nov 2023 10:24:50 +0100
pve-qemu-kvm (8.1.2-2) bookworm; urgency=medium
* revert "x86: acpi: workaround Windows not handling name references in
Package properly" as that seems to have broken networking (and possibly
other things) one some localized variants of Windows (e.g., the German
versions).
-- Proxmox Support Team <support@proxmox.com> Fri, 17 Nov 2023 11:55:23 +0100
pve-qemu-kvm (8.1.2-1) bookworm; urgency=medium
* update submodule and patches to QEMU 8.1.2
* use QEMU's keycode-map-db again instead of our static copy from QEMU 6.0
* disable graph locking, newly introduced in the 8.1 release, as it has
still various deadlock issuess, e.g., during canceling backup jobs.
-- Proxmox Support Team <support@proxmox.com> Tue, 24 Oct 2023 13:42:45 +0200
pve-qemu-kvm (8.0.2-7) bookworm; urgency=medium
* fix #2874: SATA: avoid unsolicited write to sector 0 during reset
-- Proxmox Support Team <support@proxmox.com> Wed, 04 Oct 2023 08:33:35 +0200
pve-qemu-kvm (8.0.2-6) bookworm; urgency=medium
* fix #1534: vma: add extract-filter for disk images allowing users to pass

3
debian/control vendored
View File

@@ -37,6 +37,7 @@ Build-Depends: debhelper-compat (= 13),
python3-minimal,
python3-sphinx,
python3-sphinx-rtd-theme,
python3-venv,
quilt,
uuid-dev,
xfslibs-dev,
@@ -58,6 +59,7 @@ Depends: ceph-common (>= 0.48),
libspice-server1 (>= 0.14.0~),
libusb-1.0-0 (>= 1.0.17-1),
libusbredirparser1 (>= 0.6-2),
vitastor-client (>= 0.9.4),
libuuid1,
${misc:Depends},
${shlibs:Depends},
@@ -79,6 +81,7 @@ Replaces: pve-kvm,
qemu-system-arm,
qemu-system-x86,
qemu-utils,
Breaks: qemu-server (<= 8.0.6)
Description: Full virtualization on x86 hardware
Using KVM, one can run multiple virtual PCs, each running unmodified Linux or
Windows images. Each virtual machine has private virtualized hardware: a

View File

@@ -27,18 +27,18 @@ Signed-off-by: Ma Haocong <mahaocong@didichuxing.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
[FE: rebased for 8.0]
[FE: rebased for 8.1.1]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/mirror.c | 98 +++++++++++++++++++++-----
blockdev.c | 38 +++++++++-
include/block/block_int-global-state.h | 4 +-
qapi/block-core.json | 29 ++++++--
qapi/block-core.json | 25 ++++++-
tests/unit/test-block-iothread.c | 4 +-
5 files changed, 144 insertions(+), 29 deletions(-)
5 files changed, 142 insertions(+), 27 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 663e2b7002..9099c75992 100644
index d3cacd1708..1ff42c8af1 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -51,7 +51,7 @@ typedef struct MirrorBlockJob {
@@ -59,7 +59,7 @@ index 663e2b7002..9099c75992 100644
BdrvDirtyBitmap *dirty_bitmap;
BdrvDirtyBitmapIter *dbi;
uint8_t *buf;
@@ -703,7 +705,8 @@ static int mirror_exit_common(Job *job)
@@ -705,7 +707,8 @@ static int mirror_exit_common(Job *job)
bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
&error_abort);
if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
@@ -69,7 +69,7 @@ index 663e2b7002..9099c75992 100644
BlockDriverState *unfiltered_target = bdrv_skip_filters(target_bs);
if (bdrv_cow_bs(unfiltered_target) != backing) {
@@ -801,6 +804,16 @@ static void mirror_abort(Job *job)
@@ -809,6 +812,16 @@ static void mirror_abort(Job *job)
assert(ret == 0);
}
@@ -86,7 +86,7 @@ index 663e2b7002..9099c75992 100644
static void coroutine_fn mirror_throttle(MirrorBlockJob *s)
{
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
@@ -987,7 +1000,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
@@ -997,7 +1010,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
mirror_free_init(s);
s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
@@ -96,7 +96,7 @@ index 663e2b7002..9099c75992 100644
ret = mirror_dirty_init(s);
if (ret < 0 || job_is_cancelled(&s->common.job)) {
goto immediate_exit;
@@ -1240,6 +1254,7 @@ static const BlockJobDriver mirror_job_driver = {
@@ -1251,6 +1265,7 @@ static const BlockJobDriver mirror_job_driver = {
.run = mirror_run,
.prepare = mirror_prepare,
.abort = mirror_abort,
@@ -104,7 +104,7 @@ index 663e2b7002..9099c75992 100644
.pause = mirror_pause,
.complete = mirror_complete,
.cancel = mirror_cancel,
@@ -1256,6 +1271,7 @@ static const BlockJobDriver commit_active_job_driver = {
@@ -1267,6 +1282,7 @@ static const BlockJobDriver commit_active_job_driver = {
.run = mirror_run,
.prepare = mirror_prepare,
.abort = mirror_abort,
@@ -112,7 +112,7 @@ index 663e2b7002..9099c75992 100644
.pause = mirror_pause,
.complete = mirror_complete,
.cancel = commit_active_cancel,
@@ -1647,7 +1663,10 @@ static BlockJob *mirror_start_job(
@@ -1658,7 +1674,10 @@ static BlockJob *mirror_start_job(
BlockCompletionFunc *cb,
void *opaque,
const BlockJobDriver *driver,
@@ -124,7 +124,7 @@ index 663e2b7002..9099c75992 100644
bool auto_complete, const char *filter_node_name,
bool is_mirror, MirrorCopyMode copy_mode,
Error **errp)
@@ -1659,10 +1678,39 @@ static BlockJob *mirror_start_job(
@@ -1670,10 +1689,39 @@ static BlockJob *mirror_start_job(
uint64_t target_perms, target_shared_perms;
int ret;
@@ -166,7 +166,7 @@ index 663e2b7002..9099c75992 100644
assert(is_power_of_2(granularity));
if (buf_size < 0) {
@@ -1793,7 +1841,9 @@ static BlockJob *mirror_start_job(
@@ -1804,7 +1852,9 @@ static BlockJob *mirror_start_job(
s->replaces = g_strdup(replaces);
s->on_source_error = on_source_error;
s->on_target_error = on_target_error;
@@ -177,7 +177,7 @@ index 663e2b7002..9099c75992 100644
s->backing_mode = backing_mode;
s->zero_target = zero_target;
s->copy_mode = copy_mode;
@@ -1814,6 +1864,18 @@ static BlockJob *mirror_start_job(
@@ -1825,6 +1875,18 @@ static BlockJob *mirror_start_job(
bdrv_disable_dirty_bitmap(s->dirty_bitmap);
}
@@ -196,7 +196,7 @@ index 663e2b7002..9099c75992 100644
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
BLK_PERM_CONSISTENT_READ,
@@ -1891,6 +1953,9 @@ fail:
@@ -1902,6 +1964,9 @@ fail:
if (s->dirty_bitmap) {
bdrv_release_dirty_bitmap(s->dirty_bitmap);
}
@@ -206,7 +206,7 @@ index 663e2b7002..9099c75992 100644
job_early_fail(&s->common.job);
}
@@ -1908,31 +1973,25 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
@@ -1919,31 +1984,25 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
BlockDriverState *target, const char *replaces,
int creation_flags, int64_t speed,
uint32_t granularity, int64_t buf_size,
@@ -243,7 +243,7 @@ index 663e2b7002..9099c75992 100644
}
BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
@@ -1959,7 +2018,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
@@ -1970,7 +2029,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
job_id, bs, creation_flags, base, NULL, speed, 0, 0,
MIRROR_LEAVE_BACKING_CHAIN, false,
on_error, on_error, true, cb, opaque,
@@ -254,10 +254,10 @@ index 663e2b7002..9099c75992 100644
errp);
if (!job) {
diff --git a/blockdev.c b/blockdev.c
index e464daea58..50e4a9c682 100644
index c28462a633..a402fa4bf7 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2942,6 +2942,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
@@ -2849,6 +2849,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
BlockDriverState *target,
const char *replaces,
enum MirrorSyncMode sync,
@@ -267,15 +267,15 @@ index e464daea58..50e4a9c682 100644
BlockMirrorBackingMode backing_mode,
bool zero_target,
bool has_speed, int64_t speed,
@@ -2960,6 +2963,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
@@ -2867,6 +2870,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
{
BlockDriverState *unfiltered_bs;
int job_flags = JOB_DEFAULT;
+ BdrvDirtyBitmap *bitmap = NULL;
if (!has_speed) {
speed = 0;
@@ -3011,6 +3015,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
@@ -2921,6 +2925,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
sync = MIRROR_SYNC_MODE_FULL;
}
@@ -305,7 +305,7 @@ index e464daea58..50e4a9c682 100644
if (!replaces) {
/* We want to mirror from @bs, but keep implicit filters on top */
unfiltered_bs = bdrv_skip_implicit_filters(bs);
@@ -3056,8 +3083,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
@@ -2966,8 +2993,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
* and will allow to check whether the node still exist at mirror completion
*/
mirror_start(job_id, bs, target,
@@ -316,7 +316,7 @@ index e464daea58..50e4a9c682 100644
on_source_error, on_target_error, unmap, filter_node_name,
copy_mode, errp);
}
@@ -3202,6 +3229,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
@@ -3115,6 +3142,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
blockdev_mirror_common(arg->job_id, bs, target_bs,
arg->replaces, arg->sync,
@@ -325,7 +325,7 @@ index e464daea58..50e4a9c682 100644
backing_mode, zero_target,
arg->has_speed, arg->speed,
arg->has_granularity, arg->granularity,
@@ -3223,6 +3252,8 @@ void qmp_blockdev_mirror(const char *job_id,
@@ -3136,6 +3165,8 @@ void qmp_blockdev_mirror(const char *job_id,
const char *device, const char *target,
const char *replaces,
MirrorSyncMode sync,
@@ -334,7 +334,7 @@ index e464daea58..50e4a9c682 100644
bool has_speed, int64_t speed,
bool has_granularity, uint32_t granularity,
bool has_buf_size, int64_t buf_size,
@@ -3271,7 +3302,8 @@ void qmp_blockdev_mirror(const char *job_id,
@@ -3184,7 +3215,8 @@ void qmp_blockdev_mirror(const char *job_id,
}
blockdev_mirror_common(job_id, bs, target_bs,
@@ -345,7 +345,7 @@ index e464daea58..50e4a9c682 100644
has_granularity, granularity,
has_buf_size, buf_size,
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
index 902406eb99..d559be928c 100644
index da5fb31089..32f0f9858a 100644
--- a/include/block/block_int-global-state.h
+++ b/include/block/block_int-global-state.h
@@ -152,7 +152,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
@@ -360,31 +360,26 @@ index 902406eb99..d559be928c 100644
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index c05ad0c07e..3c945c1f93 100644
index bca1a0c372..a5cea82139 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2095,10 +2095,19 @@
# (all the disk, only the sectors allocated in the topmost image, or
# only new I/O).
@@ -2145,6 +2145,15 @@
# destination (all the disk, only the sectors allocated in the
# topmost image, or only new I/O).
#
+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This argument must
+# be present for bitmap mode and absent otherwise. The bitmap's
+# granularity is used instead of @granularity (since 4.1).
+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This
+# argument must be present for bitmap mode and absent otherwise.
+# The bitmap's granularity is used instead of @granularity (Since
+# 4.1).
+#
+# @bitmap-mode: Specifies the type of data the bitmap should contain after
+# the operation concludes. Must be present if sync is "bitmap".
+# Must NOT be present otherwise. (Since 4.1)
+# @bitmap-mode: Specifies the type of data the bitmap should contain
+# after the operation concludes. Must be present if sync is
+# "bitmap". Must NOT be present otherwise. (Since 4.1)
+#
# @granularity: granularity of the dirty bitmap, default is 64K
# if the image format doesn't have clusters, 4K if the clusters
# are smaller than that, else the cluster size. Must be a
-# power of 2 between 512 and 64M (since 1.4).
+# power of 2 between 512 and 64M. Must not be specified if
+# @bitmap is present (since 1.4).
#
# @buf-size: maximum amount of data in flight from source to
# target (since 1.4).
@@ -2138,7 +2147,9 @@
# @granularity: granularity of the dirty bitmap, default is 64K if the
# image format doesn't have clusters, 4K if the clusters are
# smaller than that, else the cluster size. Must be a power of 2
@@ -2187,7 +2196,9 @@
{ 'struct': 'DriveMirror',
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
'*format': 'str', '*node-name': 'str', '*replaces': 'str',
@@ -395,28 +390,23 @@ index c05ad0c07e..3c945c1f93 100644
'*speed': 'int', '*granularity': 'uint32',
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
'*on-target-error': 'BlockdevOnError',
@@ -2417,10 +2428,19 @@
# (all the disk, only the sectors allocated in the topmost image, or
# only new I/O).
@@ -2471,6 +2482,15 @@
# destination (all the disk, only the sectors allocated in the
# topmost image, or only new I/O).
#
+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This argument must
+# be present for bitmap mode and absent otherwise. The bitmap's
+# granularity is used instead of @granularity (since 4.1).
+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This
+# argument must be present for bitmap mode and absent otherwise.
+# The bitmap's granularity is used instead of @granularity (since
+# 4.1).
+#
+# @bitmap-mode: Specifies the type of data the bitmap should contain after
+# the operation concludes. Must be present if sync is "bitmap".
+# Must NOT be present otherwise. (Since 4.1)
+# @bitmap-mode: Specifies the type of data the bitmap should contain
+# after the operation concludes. Must be present if sync is
+# "bitmap". Must NOT be present otherwise. (Since 4.1)
+#
# @granularity: granularity of the dirty bitmap, default is 64K
# if the image format doesn't have clusters, 4K if the clusters
# are smaller than that, else the cluster size. Must be a
-# power of 2 between 512 and 64M
+# power of 2 between 512 and 64M . Must not be specified if
+# @bitmap is present.
#
# @buf-size: maximum amount of data in flight from source to
# target
@@ -2470,7 +2490,8 @@
# @granularity: granularity of the dirty bitmap, default is 64K if the
# image format doesn't have clusters, 4K if the clusters are
# smaller than that, else the cluster size. Must be a power of 2
@@ -2521,7 +2541,8 @@
{ 'command': 'blockdev-mirror',
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
'*replaces': 'str',
@@ -427,7 +417,7 @@ index c05ad0c07e..3c945c1f93 100644
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
'*on-target-error': 'BlockdevOnError',
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
index 3a5e1eb2c4..c1ecc49073 100644
index d727a5fee8..8a34aa2328 100644
--- a/tests/unit/test-block-iothread.c
+++ b/tests/unit/test-block-iothread.c
@@ -757,8 +757,8 @@ static void test_propagate_mirror(void)

View File

@@ -24,10 +24,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 9099c75992..e2ff42067b 100644
index 1ff42c8af1..11b8a8e959 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -680,8 +680,6 @@ static int mirror_exit_common(Job *job)
@@ -682,8 +682,6 @@ static int mirror_exit_common(Job *job)
bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
}
@@ -36,7 +36,7 @@ index 9099c75992..e2ff42067b 100644
/* Make sure that the source BDS doesn't go away during bdrv_replace_node,
* before we can call bdrv_drained_end */
bdrv_ref(src);
@@ -782,6 +780,18 @@ static int mirror_exit_common(Job *job)
@@ -788,6 +786,18 @@ static int mirror_exit_common(Job *job)
block_job_remove_all_bdrv(bjob);
bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort);
@@ -55,7 +55,7 @@ index 9099c75992..e2ff42067b 100644
bs_opaque->job = NULL;
bdrv_drained_end(src);
@@ -1688,10 +1698,6 @@ static BlockJob *mirror_start_job(
@@ -1699,10 +1709,6 @@ static BlockJob *mirror_start_job(
" sync mode",
MirrorSyncMode_str(sync_mode));
return NULL;
@@ -66,7 +66,7 @@ index 9099c75992..e2ff42067b 100644
}
} else if (bitmap) {
error_setg(errp,
@@ -1708,6 +1714,12 @@ static BlockJob *mirror_start_job(
@@ -1719,6 +1725,12 @@ static BlockJob *mirror_start_job(
return NULL;
}
granularity = bdrv_dirty_bitmap_granularity(bitmap);

View File

@@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 3 insertions(+)
diff --git a/blockdev.c b/blockdev.c
index 50e4a9c682..e6b2b1e338 100644
index a402fa4bf7..01b0ab0549 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3036,6 +3036,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
@@ -2946,6 +2946,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
return;
}

View File

@@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index e2ff42067b..f42953837b 100644
index 11b8a8e959..00f2665ca4 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -786,8 +786,8 @@ static int mirror_exit_common(Job *job)
@@ -792,8 +792,8 @@ static int mirror_exit_common(Job *job)
job->ret == 0 && ret == 0)) {
/* Success; synchronize copy back to sync. */
bdrv_clear_dirty_bitmap(s->sync_bitmap, NULL);
@@ -30,7 +30,7 @@ index e2ff42067b..f42953837b 100644
}
}
bdrv_release_dirty_bitmap(s->dirty_bitmap);
@@ -1881,11 +1881,8 @@ static BlockJob *mirror_start_job(
@@ -1892,11 +1892,8 @@ static BlockJob *mirror_start_job(
}
if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) {

View File

@@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
3 files changed, 70 insertions(+), 59 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index f42953837b..8f79efaa87 100644
index 00f2665ca4..60cf574de5 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1688,31 +1688,13 @@ static BlockJob *mirror_start_job(
@@ -1699,31 +1699,13 @@ static BlockJob *mirror_start_job(
uint64_t target_perms, target_shared_perms;
int ret;
@@ -62,10 +62,10 @@ index f42953837b..8f79efaa87 100644
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
diff --git a/blockdev.c b/blockdev.c
index e6b2b1e338..bdae211a54 100644
index 01b0ab0549..cd5f205ad1 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3015,7 +3015,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
@@ -2925,7 +2925,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
sync = MIRROR_SYNC_MODE_FULL;
}

View File

@@ -48,7 +48,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
6 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 033390f699..ad35d4fea8 100644
index 965f5d5450..e04bd059b6 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -16,6 +16,7 @@ extern QemuOptsList qemu_mon_opts;
@@ -60,10 +60,10 @@ index 033390f699..ad35d4fea8 100644
void monitor_init_globals(void);
void monitor_init_globals_core(void);
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index 53e3808054..a19f8cbc2b 100644
index 252de85681..8db28f9272 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -152,6 +152,13 @@ typedef struct {
@@ -151,6 +151,13 @@ typedef struct {
QemuMutex qmp_queue_lock;
/* Input queue that holds all the parsed QMP requests */
GQueue *qmp_requests;
@@ -78,10 +78,10 @@ index 53e3808054..a19f8cbc2b 100644
/**
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 8dc96f6af9..f3c38cb714 100644
index dc352f9e9d..56e1307014 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -135,6 +135,21 @@ bool monitor_cur_is_qmp(void)
@@ -117,6 +117,21 @@ bool monitor_cur_is_qmp(void)
return cur_mon && monitor_is_qmp(cur_mon);
}
@@ -104,10 +104,10 @@ index 8dc96f6af9..f3c38cb714 100644
* Is @mon is using readline?
* Note: not all HMP monitors use readline, e.g., gdbserver has a
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 092c527b6f..6b8cfcf6d8 100644
index a239945e8d..589c9524f8 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -141,6 +141,8 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
@@ -165,6 +165,8 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
QDict *rsp;
QDict *error;
@@ -116,7 +116,7 @@ index 092c527b6f..6b8cfcf6d8 100644
rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon),
&mon->common);
@@ -156,7 +158,17 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
@@ -180,7 +182,17 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
}
}
@@ -135,7 +135,7 @@ index 092c527b6f..6b8cfcf6d8 100644
qobject_unref(rsp);
}
@@ -444,6 +456,7 @@ static void monitor_qmp_event(void *opaque, QEMUChrEvent event)
@@ -461,6 +473,7 @@ static void monitor_qmp_event(void *opaque, QEMUChrEvent event)
switch (event) {
case CHR_EVENT_OPENED:
@@ -144,7 +144,7 @@ index 092c527b6f..6b8cfcf6d8 100644
monitor_qmp_caps_reset(mon);
data = qmp_greeting(mon);
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 0990873ec8..e605003771 100644
index 176b549473..790bb7d1da 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -117,16 +117,28 @@ typedef struct QmpDispatchBH {
@@ -180,13 +180,13 @@ index 0990873ec8..e605003771 100644
aio_co_wake(data->co);
}
@@ -231,6 +243,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
@@ -253,6 +265,7 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ
.ret = &ret,
.errp = &err,
.co = qemu_coroutine_self(),
+ .conn_nr = monitor_get_connection_nr(cur_mon),
};
aio_bh_schedule_oneshot(qemu_get_aio_context(), do_qmp_dispatch_bh,
aio_bh_schedule_oneshot(iohandler_get_aio_context(), do_qmp_dispatch_bh,
&data);
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
index afa477aae6..d3ff124bf3 100644

View File

@@ -22,10 +22,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 9cbbb16121..d624866bb6 100644
index 32c70c9e99..984b6a3145 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1780,7 +1780,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
@@ -1781,7 +1781,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
uint8_t cdb[16];
int len;
struct SCSIDevice *sdev = NULL;
@@ -34,7 +34,7 @@ index 9cbbb16121..d624866bb6 100644
lba_count = le32_to_cpu(cmd->frame->io.header.data_len);
lba_start_lo = le32_to_cpu(cmd->frame->io.lba_lo);
@@ -1789,7 +1789,6 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
@@ -1790,7 +1790,6 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
target_id = cmd->frame->header.target_id;
lun_id = cmd->frame->header.lun_id;
@@ -42,7 +42,7 @@ index 9cbbb16121..d624866bb6 100644
if (target_id < MFI_MAX_LD && lun_id == 0) {
sdev = scsi_device_find(&s->bus, 0, target_id, lun_id);
@@ -1804,15 +1803,6 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
@@ -1805,15 +1804,6 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
return MFI_STAT_DEVICE_NOT_FOUND;
}
@@ -58,7 +58,7 @@ index 9cbbb16121..d624866bb6 100644
cmd->iov_size = lba_count * sdev->blocksize;
if (megasas_map_sgl(s, cmd, &cmd->frame->io.sgl)) {
megasas_write_sense(cmd, SENSE_CODE(TARGET_FAILURE));
@@ -1823,7 +1813,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
@@ -1824,7 +1814,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
megasas_encode_lba(cdb, lba_start, lba_count, is_write);
cmd->req = scsi_req_new(sdev, cmd->index,

View File

@@ -55,7 +55,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 45d14a25e9..08e1f0c3d7 100644
index c3508acbb1..289347af58 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -444,7 +444,7 @@ static void ide_trim_bh_cb(void *opaque)
@@ -76,8 +76,8 @@ index 45d14a25e9..08e1f0c3d7 100644
replay_bh_schedule_event(iocb->bh);
}
}
@@ -515,9 +517,6 @@ BlockAIOCB *ide_issue_trim(
IDEState *s = opaque;
@@ -516,9 +518,6 @@ BlockAIOCB *ide_issue_trim(
IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master;
TrimAIOCB *iocb;
- /* Paired with a decrement in ide_trim_bh_cb() */
@@ -85,8 +85,8 @@ index 45d14a25e9..08e1f0c3d7 100644
-
iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
iocb->s = s;
iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
@@ -740,8 +739,9 @@ void ide_cancel_dma_sync(IDEState *s)
iocb->bh = qemu_bh_new_guarded(ide_trim_bh_cb, iocb,
@@ -742,8 +741,9 @@ void ide_cancel_dma_sync(IDEState *s)
*/
if (s->bus->dma->aiocb) {
trace_ide_cancel_dma_sync_remaining();

View File

@@ -20,7 +20,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 6 insertions(+)
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index fe73aa94b1..7eaf498439 100644
index 032fc5f405..e1ae3b7316 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -805,8 +805,11 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s)

View File

@@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Fri, 28 Apr 2023 19:48:06 +0400
Subject: [PATCH] ui: return NULL when getting cursor without a console
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
VNC may try to get the current cursor even when there are no consoles
and crashes. Simple reproducer is qemu with -nodefaults.
Fixes: (again)
https://gitlab.com/qemu-project/qemu/-/issues/1548
Fixes: commit 385ac97f8 ("ui: keep current cursor with QemuConsole")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(picked up from https://lists.nongnu.org/archive/html/qemu-devel/2023-04/msg05598.html)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
ui/console.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/console.c b/ui/console.c
index e173731e20..7461446e71 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -2306,7 +2306,7 @@ QEMUCursor *qemu_console_get_cursor(QemuConsole *con)
if (con == NULL) {
con = active_console;
}
- return con->cursor;
+ return con ? con->cursor : NULL;
}
bool qemu_console_is_visible(QemuConsole *con)

View File

@@ -0,0 +1,140 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Thu, 28 Sep 2023 10:07:03 +0200
Subject: [PATCH] Revert "Revert "graph-lock: Disable locking for now""
This reverts commit 3cce22defb4b0e47cf135444e30cc673cff5ebad.
There are still some issues with graph locking, e.g. deadlocks during
backup canceling [0]. Because the AioContext locks still exist, it
should be safe to disable locking again.
From the original 80fc5d2600 ("graph-lock: Disable locking for now"):
> We don't currently rely on graph locking yet. It is supposed to replace
> the AioContext lock eventually to enable multiqueue support, but as long
> as we still have the AioContext lock, it is sufficient without the graph
> lock. Once the AioContext lock goes away, the deadlock doesn't exist any
> more either and this commit can be reverted. (Of course, it can also be
> reverted while the AioContext lock still exists if the callers have been
> fixed.)
[0]: https://lists.nongnu.org/archive/html/qemu-devel/2023-09/msg00729.html
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/graph-lock.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/block/graph-lock.c b/block/graph-lock.c
index 5e66f01ae8..5c2873262a 100644
--- a/block/graph-lock.c
+++ b/block/graph-lock.c
@@ -30,8 +30,10 @@ BdrvGraphLock graph_lock;
/* Protects the list of aiocontext and orphaned_reader_count */
static QemuMutex aio_context_list_lock;
+#if 0
/* Written and read with atomic operations. */
static int has_writer;
+#endif
/*
* A reader coroutine could move from an AioContext to another.
@@ -88,6 +90,7 @@ void unregister_aiocontext(AioContext *ctx)
g_free(ctx->bdrv_graph);
}
+#if 0
static uint32_t reader_count(void)
{
BdrvGraphRWlock *brdv_graph;
@@ -105,12 +108,19 @@ static uint32_t reader_count(void)
assert((int32_t)rd >= 0);
return rd;
}
+#endif
void bdrv_graph_wrlock(BlockDriverState *bs)
{
+#if 0
AioContext *ctx = NULL;
GLOBAL_STATE_CODE();
+ /*
+ * TODO Some callers hold an AioContext lock when this is called, which
+ * causes deadlocks. Reenable once the AioContext locking is cleaned up (or
+ * AioContext locks are gone).
+ */
assert(!qatomic_read(&has_writer));
/*
@@ -158,11 +168,13 @@ void bdrv_graph_wrlock(BlockDriverState *bs)
if (ctx) {
aio_context_acquire(bdrv_get_aio_context(bs));
}
+#endif
}
void bdrv_graph_wrunlock(void)
{
GLOBAL_STATE_CODE();
+#if 0
QEMU_LOCK_GUARD(&aio_context_list_lock);
assert(qatomic_read(&has_writer));
@@ -174,10 +186,13 @@ void bdrv_graph_wrunlock(void)
/* Wake up all coroutine that are waiting to read the graph */
qemu_co_enter_all(&reader_queue, &aio_context_list_lock);
+#endif
}
void coroutine_fn bdrv_graph_co_rdlock(void)
{
+ /* TODO Reenable when wrlock is reenabled */
+#if 0
BdrvGraphRWlock *bdrv_graph;
bdrv_graph = qemu_get_current_aio_context()->bdrv_graph;
@@ -237,10 +252,12 @@ void coroutine_fn bdrv_graph_co_rdlock(void)
qemu_co_queue_wait(&reader_queue, &aio_context_list_lock);
}
}
+#endif
}
void coroutine_fn bdrv_graph_co_rdunlock(void)
{
+#if 0
BdrvGraphRWlock *bdrv_graph;
bdrv_graph = qemu_get_current_aio_context()->bdrv_graph;
@@ -258,6 +275,7 @@ void coroutine_fn bdrv_graph_co_rdunlock(void)
if (qatomic_read(&has_writer)) {
aio_wait_kick();
}
+#endif
}
void bdrv_graph_rdlock_main_loop(void)
@@ -275,13 +293,19 @@ void bdrv_graph_rdunlock_main_loop(void)
void assert_bdrv_graph_readable(void)
{
/* reader_count() is slow due to aio_context_list_lock lock contention */
+ /* TODO Reenable when wrlock is reenabled */
+#if 0
#ifdef CONFIG_DEBUG_GRAPH_LOCK
assert(qemu_in_main_thread() || reader_count());
#endif
+#endif
}
void assert_bdrv_graph_writable(void)
{
assert(qemu_in_main_thread());
+ /* TODO Reenable when wrlock is reenabled */
+#if 0
assert(qatomic_read(&has_writer));
+#endif
}

View File

@@ -1,130 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:06 -0400
Subject: [PATCH] memory: prevent dma-reentracy issues
Add a flag to the DeviceState, when a device is engaged in PIO/MMIO/DMA.
This flag is set/checked prior to calling a device's MemoryRegion
handlers, and set when device code initiates DMA. The purpose of this
flag is to prevent two types of DMA-based reentrancy issues:
1.) mmio -> dma -> mmio case
2.) bh -> dma write -> mmio case
These issues have led to problems such as stack-exhaustion and
use-after-frees.
Summary of the problem from Peter Maydell:
https://lore.kernel.org/qemu-devel/CAFEAcA_23vc7hE3iaM-JVA6W38LK4hJoWae5KcknhPRD5fPBZA@mail.gmail.com
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/62
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/540
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/541
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/556
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/557
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/827
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1282
Resolves: CVE-2023-0330
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20230427211013.2994127-2-alxndr@bu.edu>
[thuth: Replace warn_report() with warn_report_once()]
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry-picked from commit a2e1753b8054344f32cf94f31c6399a58794a380)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
include/exec/memory.h | 5 +++++
include/hw/qdev-core.h | 7 +++++++
softmmu/memory.c | 16 ++++++++++++++++
3 files changed, 28 insertions(+)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 15ade918ba..e45ce6061f 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -767,6 +767,8 @@ struct MemoryRegion {
bool is_iommu;
RAMBlock *ram_block;
Object *owner;
+ /* owner as TYPE_DEVICE. Used for re-entrancy checks in MR access hotpath */
+ DeviceState *dev;
const MemoryRegionOps *ops;
void *opaque;
@@ -791,6 +793,9 @@ struct MemoryRegion {
unsigned ioeventfd_nb;
MemoryRegionIoeventfd *ioeventfds;
RamDiscardManager *rdm; /* Only for RAM */
+
+ /* For devices designed to perform re-entrant IO into their own IO MRs */
+ bool disable_reentrancy_guard;
};
struct IOMMUMemoryRegion {
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index bd50ad5ee1..7623703943 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -162,6 +162,10 @@ struct NamedClockList {
QLIST_ENTRY(NamedClockList) node;
};
+typedef struct {
+ bool engaged_in_io;
+} MemReentrancyGuard;
+
/**
* DeviceState:
* @realized: Indicates whether the device has been fully constructed.
@@ -194,6 +198,9 @@ struct DeviceState {
int alias_required_for_version;
ResettableState reset;
GSList *unplug_blockers;
+
+ /* Is the device currently in mmio/pio/dma? Used to prevent re-entrancy */
+ MemReentrancyGuard mem_reentrancy_guard;
};
struct DeviceListener {
diff --git a/softmmu/memory.c b/softmmu/memory.c
index b1a6cae6f5..b7b3386e9d 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -542,6 +542,18 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
access_size_max = 4;
}
+ /* Do not allow more than one simultaneous access to a device's IO Regions */
+ if (mr->dev && !mr->disable_reentrancy_guard &&
+ !mr->ram_device && !mr->ram && !mr->rom_device && !mr->readonly) {
+ if (mr->dev->mem_reentrancy_guard.engaged_in_io) {
+ warn_report_once("Blocked re-entrant IO on MemoryRegion: "
+ "%s at addr: 0x%" HWADDR_PRIX,
+ memory_region_name(mr), addr);
+ return MEMTX_ACCESS_ERROR;
+ }
+ mr->dev->mem_reentrancy_guard.engaged_in_io = true;
+ }
+
/* FIXME: support unaligned access? */
access_size = MAX(MIN(size, access_size_max), access_size_min);
access_mask = MAKE_64BIT_MASK(0, access_size * 8);
@@ -556,6 +568,9 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
access_mask, attrs);
}
}
+ if (mr->dev) {
+ mr->dev->mem_reentrancy_guard.engaged_in_io = false;
+ }
return r;
}
@@ -1170,6 +1185,7 @@ static void memory_region_do_init(MemoryRegion *mr,
}
mr->name = g_strdup(name);
mr->owner = owner;
+ mr->dev = (DeviceState *) object_dynamic_cast(mr->owner, TYPE_DEVICE);
mr->ram_block = NULL;
if (name) {

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:10 -0400
Subject: [PATCH] lsi53c895a: disable reentrancy detection for script RAM
As the code is designed to use the memory APIs to access the script ram,
disable reentrancy checks for the pseudo-RAM ram_io MemoryRegion.
In the future, ram_io may be converted from an IO to a proper RAM MemoryRegion.
Reported-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Message-Id: <20230427211013.2994127-6-alxndr@bu.edu>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry-picked from commit bfd6e7ae6a72b84e2eb9574f56e6ec037f05182c)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/scsi/lsi53c895a.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index bbf32d3f73..17af67935f 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -2313,6 +2313,12 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
memory_region_init_io(&s->io_io, OBJECT(s), &lsi_io_ops, s,
"lsi-io", 256);
+ /*
+ * Since we use the address-space API to interact with ram_io, disable the
+ * re-entrancy guard.
+ */
+ s->ram_io.disable_reentrancy_guard = true;
+
address_space_init(&s->pci_io_as, pci_address_space_io(dev), "lsi-pci-io");
qdev_init_gpio_out(d, &s->ext_irq, 1);

View File

@@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Thu, 28 Sep 2023 11:19:14 +0200
Subject: [PATCH] migration states: workaround snapshot performance regression
Commit 813cd616 ("migration: Use migration_transferred_bytes() to
calculate rate_limit") introduced a prohibitive performance regression
when taking a snapshot [0]. The reason turns out to be the flushing
done by migration_transferred_bytes()
Just use a _noflush version of the relevant function as a workaround
until upstream fixes the issue. This is inspired by a not-applied
upstream series [1], but doing the very minimum to avoid the
regression.
[0]: https://gitlab.com/qemu-project/qemu/-/issues/1821
[1]: https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg07708.html
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
migration/migration-stats.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/migration/migration-stats.c b/migration/migration-stats.c
index 095d6d75bb..8073c8ebaa 100644
--- a/migration/migration-stats.c
+++ b/migration/migration-stats.c
@@ -18,6 +18,20 @@
MigrationAtomicStats mig_stats;
+/*
+ * Same as migration_transferred_bytes below, but using the _noflush
+ * variant of qemu_file_transferred() to avoid a performance
+ * regression in migration_rate_exceeded().
+ */
+static uint64_t migration_transferred_bytes_noflush(QEMUFile *f)
+{
+ uint64_t multifd = stat64_get(&mig_stats.multifd_bytes);
+ uint64_t qemu_file = qemu_file_transferred_noflush(f);
+
+ trace_migration_transferred_bytes(qemu_file, multifd);
+ return qemu_file + multifd;
+}
+
bool migration_rate_exceeded(QEMUFile *f)
{
if (qemu_file_get_error(f)) {
@@ -25,7 +39,7 @@ bool migration_rate_exceeded(QEMUFile *f)
}
uint64_t rate_limit_start = stat64_get(&mig_stats.rate_limit_start);
- uint64_t rate_limit_current = migration_transferred_bytes(f);
+ uint64_t rate_limit_current = migration_transferred_bytes_noflush(f);
uint64_t rate_limit_used = rate_limit_current - rate_limit_start;
uint64_t rate_limit_max = stat64_get(&mig_stats.rate_limit_max);

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 17 Nov 2023 11:18:06 +0100
Subject: [PATCH] Revert "x86: acpi: workaround Windows not handling name
references in Package properly"
This reverts commit 44d975ef340e2f21f236f9520c53e1b30d2213a4.
As reported in the community forum [0] and reproduced locally this
breaks VirtIO network adapters in (at least) the German ISO of Windows
Server 2022. The fix itself was for
> Issue is not fatal but as result acpi-index/"PCI Label ID" property
> is either not shown in device details page or shows incorrect value.
so revert and tolerate that as a stop-gap, rather than have the
devices not working at all.
[0]: https://forum.proxmox.com/threads/92094/post-605684
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/i386/acpi-build.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index bb12b0ad43..de14d3c3da 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -362,13 +362,9 @@ Aml *aml_pci_device_dsm(void)
{
Aml *params = aml_local(0);
Aml *pkg = aml_package(2);
- aml_append(pkg, aml_int(0));
- aml_append(pkg, aml_int(0));
+ aml_append(pkg, aml_name("BSEL"));
+ aml_append(pkg, aml_name("ASUN"));
aml_append(method, aml_store(pkg, params));
- aml_append(method,
- aml_store(aml_name("BSEL"), aml_index(params, aml_int(0))));
- aml_append(method,
- aml_store(aml_name("ASUN"), aml_index(params, aml_int(1))));
aml_append(method,
aml_return(aml_call5("PDSM", aml_arg(0), aml_arg(1),
aml_arg(2), aml_arg(3), params))

View File

@@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:11 -0400
Subject: [PATCH] bcm2835_property: disable reentrancy detection for iomem
As the code is designed for re-entrant calls from bcm2835_property to
bcm2835_mbox and back into bcm2835_property, mark iomem as
reentrancy-safe.
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20230427211013.2994127-7-alxndr@bu.edu>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry-picked from commit 985c4a4e547afb9573b6bd6843d20eb2c3d1d1cd)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/misc/bcm2835_property.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index 890ae7bae5..de056ea2df 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -382,6 +382,13 @@ static void bcm2835_property_init(Object *obj)
memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_property_ops, s,
TYPE_BCM2835_PROPERTY, 0x10);
+
+ /*
+ * bcm2835_property_ops call into bcm2835_mbox, which in-turn reads from
+ * iomem. As such, mark iomem as re-entracy safe.
+ */
+ s->iomem.disable_reentrancy_guard = true;
+
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
sysbus_init_irq(SYS_BUS_DEVICE(s), &s->mbox_irq);
}

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:12 -0400
Subject: [PATCH] raven: disable reentrancy detection for iomem
As the code is designed for re-entrant calls from raven_io_ops to
pci-conf, mark raven_io_ops as reentrancy-safe.
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Message-Id: <20230427211013.2994127-8-alxndr@bu.edu>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry-picked from commit 6dad5a6810d9c60ca320d01276f6133bbcfa1fc7)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/pci-host/raven.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
index 072ffe3c5e..9a11ac4b2b 100644
--- a/hw/pci-host/raven.c
+++ b/hw/pci-host/raven.c
@@ -294,6 +294,13 @@ static void raven_pcihost_initfn(Object *obj)
memory_region_init(&s->pci_memory, obj, "pci-memory", 0x3f000000);
address_space_init(&s->pci_io_as, &s->pci_io, "raven-io");
+ /*
+ * Raven's raven_io_ops use the address-space API to access pci-conf-idx
+ * (which is also owned by the raven device). As such, mark the
+ * pci_io_non_contiguous as re-entrancy safe.
+ */
+ s->pci_io_non_contiguous.disable_reentrancy_guard = true;
+
/* CPU address space */
memory_region_add_subregion(address_space_mem, PCI_IO_BASE_ADDR,
&s->pci_io);

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 1 Feb 2022 20:09:41 +0100
Subject: [PATCH] target/i386: the sgx_epc_get_section stub is reachable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The sgx_epc_get_section stub is reachable from cpu_x86_cpuid. It
should not assert, instead it should just return true just like
the "real" sgx_epc_get_section does when SGX is disabled.
Reported-by: Vladimír Beneš <vbenes@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20220201190941.106001-1-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry-picked from commit 219615740425d9683588207b40a365e6741691a6)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/i386/sgx-stub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c
index 26833eb233..16b1dfd90b 100644
--- a/hw/i386/sgx-stub.c
+++ b/hw/i386/sgx-stub.c
@@ -34,5 +34,5 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms)
bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
{
- g_assert_not_reached();
+ return true;
}

View File

@@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:13 -0400
Subject: [PATCH] apic: disable reentrancy detection for apic-msi
As the code is designed for re-entrant calls to apic-msi, mark apic-msi
as reentrancy-safe.
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Message-Id: <20230427211013.2994127-9-alxndr@bu.edu>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry-picked from commit 50795ee051a342c681a9b45671c552fbd6274db8)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/intc/apic.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 20b5a94073..ac3d47d231 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -885,6 +885,13 @@ static void apic_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi",
APIC_SPACE_SIZE);
+ /*
+ * apic-msi's apic_mem_write can call into ioapic_eoi_broadcast, which can
+ * write back to apic-msi. As such mark the apic-msi region re-entrancy
+ * safe.
+ */
+ s->io_memory.disable_reentrancy_guard = true;
+
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, apic_timer, s);
local_apics[s->id] = s;

View File

@@ -0,0 +1,86 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Wed, 24 Jan 2024 11:57:48 +0100
Subject: [PATCH] ui/clipboard: mark type as not available when there is no
data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With VNC, a client can send a non-extended VNC_MSG_CLIENT_CUT_TEXT
message with len=0. In qemu_clipboard_set_data(), the clipboard info
will be updated setting data to NULL (because g_memdup(data, size)
returns NULL when size is 0). If the client does not set the
VNC_ENCODING_CLIPBOARD_EXT feature when setting up the encodings, then
the 'request' callback for the clipboard peer is not initialized.
Later, because data is NULL, qemu_clipboard_request() can be reached
via vdagent_chr_write() and vdagent_clipboard_recv_request() and
there, the clipboard owner's 'request' callback will be attempted to
be called, but that is a NULL pointer.
In particular, this can happen when using the KRDC (22.12.3) VNC
client.
Another scenario leading to the same issue is with two clients (say
noVNC and KRDC):
The noVNC client sets the extension VNC_FEATURE_CLIPBOARD_EXT and
initializes its cbpeer.
The KRDC client does not, but triggers a vnc_client_cut_text() (note
it's not the _ext variant)). There, a new clipboard info with it as
the 'owner' is created and via qemu_clipboard_set_data() is called,
which in turn calls qemu_clipboard_update() with that info.
In qemu_clipboard_update(), the notifier for the noVNC client will be
called, i.e. vnc_clipboard_notify() and also set vs->cbinfo for the
noVNC client. The 'owner' in that clipboard info is the clipboard peer
for the KRDC client, which did not initialize the 'request' function.
That sounds correct to me, it is the owner of that clipboard info.
Then when noVNC sends a VNC_MSG_CLIENT_CUT_TEXT message (it did set
the VNC_FEATURE_CLIPBOARD_EXT feature correctly, so a check for it
passes), that clipboard info is passed to qemu_clipboard_request() and
the original segfault still happens.
Fix the issue by handling updates with size 0 differently. In
particular, mark in the clipboard info that the type is not available.
While at it, switch to g_memdup2(), because g_memdup() is deprecated.
Cc: qemu-stable@nongnu.org
Fixes: CVE-2023-6683
Reported-by: Markus Frank <m.frank@proxmox.com>
Suggested-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Markus Frank <m.frank@proxmox.com>
(picked from https://lists.nongnu.org/archive/html/qemu-stable/2024-01/msg00228.html)
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
ui/clipboard.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/ui/clipboard.c b/ui/clipboard.c
index 3d14bffaf8..b3f6fa3c9e 100644
--- a/ui/clipboard.c
+++ b/ui/clipboard.c
@@ -163,9 +163,15 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
}
g_free(info->types[type].data);
- info->types[type].data = g_memdup(data, size);
- info->types[type].size = size;
- info->types[type].available = true;
+ if (size) {
+ info->types[type].data = g_memdup2(data, size);
+ info->types[type].size = size;
+ info->types[type].available = true;
+ } else {
+ info->types[type].data = NULL;
+ info->types[type].size = 0;
+ info->types[type].available = false;
+ }
if (update) {
qemu_clipboard_update(info);

View File

@@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hanna Czenczek <hreitz@redhat.com>
Date: Fri, 2 Feb 2024 16:31:56 +0100
Subject: [PATCH] virtio-scsi: Attach event vq notifier with no_poll
As of commit 38738f7dbbda90fbc161757b7f4be35b52205552 ("virtio-scsi:
don't waste CPU polling the event virtqueue"), we only attach an io_read
notifier for the virtio-scsi event virtqueue instead, and no polling
notifiers. During operation, the event virtqueue is typically
non-empty, but none of the buffers are intended to be used immediately.
Instead, they only get used when certain events occur. Therefore, it
makes no sense to continuously poll it when non-empty, because it is
supposed to be and stay non-empty.
We do this by using virtio_queue_aio_attach_host_notifier_no_poll()
instead of virtio_queue_aio_attach_host_notifier() for the event
virtqueue.
Commit 766aa2de0f29b657148e04599320d771c36fd126 ("virtio-scsi: implement
BlockDevOps->drained_begin()") however has virtio_scsi_drained_end() use
virtio_queue_aio_attach_host_notifier() for all virtqueues, including
the event virtqueue. This can lead to it being polled again, undoing
the benefit of commit 38738f7dbbda90fbc161757b7f4be35b52205552.
Fix it by using virtio_queue_aio_attach_host_notifier_no_poll() for the
event virtqueue.
("virtio-scsi: implement BlockDevOps->drained_begin()")
Reported-by: Fiona Ebner <f.ebner@proxmox.com>
Fixes: 766aa2de0f29b657148e04599320d771c36fd126
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
hw/scsi/virtio-scsi.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 45b95ea070..ad24a882fd 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -1148,6 +1148,7 @@ static void virtio_scsi_drained_begin(SCSIBus *bus)
static void virtio_scsi_drained_end(SCSIBus *bus)
{
VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
+ VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
VirtIODevice *vdev = VIRTIO_DEVICE(s);
uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED +
s->parent_obj.conf.num_queues;
@@ -1165,7 +1166,11 @@ static void virtio_scsi_drained_end(SCSIBus *bus)
for (uint32_t i = 0; i < total_queues; i++) {
VirtQueue *vq = virtio_get_queue(vdev, i);
- virtio_queue_aio_attach_host_notifier(vq, s->ctx);
+ if (vq == vs->event_vq) {
+ virtio_queue_aio_attach_host_notifier_no_poll(vq, s->ctx);
+ } else {
+ virtio_queue_aio_attach_host_notifier(vq, s->ctx);
+ }
}
}

View File

@@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Li Feng <fengli@smartx.com>
Date: Mon, 31 Jul 2023 20:10:06 +0800
Subject: [PATCH] vhost: fix the fd leak
When the vhost-user reconnect to the backend, the notifer should be
cleanup. Otherwise, the fd resource will be exhausted.
Fixes: f9a09ca3ea ("vhost: add support for configure interrupt")
Signed-off-by: Li Feng <fengli@smartx.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
---
hw/virtio/vhost.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index a266396576..8e3311781f 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -2034,6 +2034,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
event_notifier_test_and_clear(
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
event_notifier_test_and_clear(&vdev->config_notifier);
+ event_notifier_cleanup(
+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
trace_vhost_dev_stop(hdev, vdev->name, vrings);

View File

@@ -0,0 +1,125 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hanna Czenczek <hreitz@redhat.com>
Date: Fri, 2 Feb 2024 16:31:57 +0100
Subject: [PATCH] virtio: Re-enable notifications after drain
During drain, we do not care about virtqueue notifications, which is why
we remove the handlers on it. When removing those handlers, whether vq
notifications are enabled or not depends on whether we were in polling
mode or not; if not, they are enabled (by default); if so, they have
been disabled by the io_poll_start callback.
Because we do not care about those notifications after removing the
handlers, this is fine. However, we have to explicitly ensure they are
enabled when re-attaching the handlers, so we will resume receiving
notifications. We do this in virtio_queue_aio_attach_host_notifier*().
If such a function is called while we are in a polling section,
attaching the notifiers will then invoke the io_poll_start callback,
re-disabling notifications.
Because we will always miss virtqueue updates in the drained section, we
also need to poll the virtqueue once after attaching the notifiers.
Buglink: https://issues.redhat.com/browse/RHEL-3934
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
hw/virtio/virtio.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/block/aio.h | 7 ++++++-
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 969c25f4cf..02cce83111 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3526,6 +3526,17 @@ static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n)
void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
{
+ /*
+ * virtio_queue_aio_detach_host_notifier() can leave notifications disabled.
+ * Re-enable them. (And if detach has not been used before, notifications
+ * being enabled is still the default state while a notifier is attached;
+ * see virtio_queue_host_notifier_aio_poll_end(), which will always leave
+ * notifications enabled once the polling section is left.)
+ */
+ if (!virtio_queue_get_notification(vq)) {
+ virtio_queue_set_notification(vq, 1);
+ }
+
aio_set_event_notifier(ctx, &vq->host_notifier,
virtio_queue_host_notifier_read,
virtio_queue_host_notifier_aio_poll,
@@ -3533,6 +3544,13 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
aio_set_event_notifier_poll(ctx, &vq->host_notifier,
virtio_queue_host_notifier_aio_poll_begin,
virtio_queue_host_notifier_aio_poll_end);
+
+ /*
+ * We will have ignored notifications about new requests from the guest
+ * while no notifiers were attached, so "kick" the virt queue to process
+ * those requests now.
+ */
+ event_notifier_set(&vq->host_notifier);
}
/*
@@ -3543,14 +3561,38 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
*/
void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx)
{
+ /* See virtio_queue_aio_attach_host_notifier() */
+ if (!virtio_queue_get_notification(vq)) {
+ virtio_queue_set_notification(vq, 1);
+ }
+
aio_set_event_notifier(ctx, &vq->host_notifier,
virtio_queue_host_notifier_read,
NULL, NULL);
+
+ /*
+ * See virtio_queue_aio_attach_host_notifier().
+ * Note that this may be unnecessary for the type of virtqueues this
+ * function is used for. Still, it will not hurt to have a quick look into
+ * whether we can/should process any of the virtqueue elements.
+ */
+ event_notifier_set(&vq->host_notifier);
}
void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx)
{
aio_set_event_notifier(ctx, &vq->host_notifier, NULL, NULL, NULL);
+
+ /*
+ * aio_set_event_notifier_poll() does not guarantee whether io_poll_end()
+ * will run after io_poll_begin(), so by removing the notifier, we do not
+ * know whether virtio_queue_host_notifier_aio_poll_end() has run after a
+ * previous virtio_queue_host_notifier_aio_poll_begin(), i.e. whether
+ * notifications are enabled or disabled. It does not really matter anyway;
+ * we just removed the notifier, so we do not care about notifications until
+ * we potentially re-attach it. The attach_host_notifier functions will
+ * ensure that notifications are enabled again when they are needed.
+ */
}
void virtio_queue_host_notifier_read(EventNotifier *n)
diff --git a/include/block/aio.h b/include/block/aio.h
index 32042e8905..79efadfa48 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -498,9 +498,14 @@ void aio_set_event_notifier(AioContext *ctx,
AioPollFn *io_poll,
EventNotifierHandler *io_poll_ready);
-/* Set polling begin/end callbacks for an event notifier that has already been
+/*
+ * Set polling begin/end callbacks for an event notifier that has already been
* registered with aio_set_event_notifier. Do nothing if the event notifier is
* not registered.
+ *
+ * Note that if the io_poll_end() callback (or the entire notifier) is removed
+ * during polling, it will not be called, so an io_poll_begin() is not
+ * necessarily always followed by an io_poll_end().
*/
void aio_set_event_notifier_poll(AioContext *ctx,
EventNotifier *notifier,

1271
debian/patches/pve-qemu-8.1-vitastor.patch vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index c2dee3f056..9681bd0434 100644
index 7f540b03ed..ca551baa42 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -553,7 +553,7 @@ static QemuOptsList raw_runtime_opts = {
@@ -563,7 +563,7 @@ static QemuOptsList raw_runtime_opts = {
{
.name = "locking",
.type = QEMU_OPT_STRING,
@@ -26,7 +26,7 @@ index c2dee3f056..9681bd0434 100644
},
{
.name = "pr-manager",
@@ -653,7 +653,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
@@ -663,7 +663,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
s->use_lock = false;
break;
case ON_OFF_AUTO_AUTO:

View File

@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/net/net.h b/include/net/net.h
index 1448d00afb..d1601d32c1 100644
index 685ec58318..22edf4ee96 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -258,8 +258,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
@@ -260,8 +260,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
int net_hub_id_for_client(NetClientState *nc, int *id);
NetClientState *net_hub_port_find(int hub_id);

View File

@@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d243e290d3..3489b05ec4 100644
index 0893b794e9..6d650a58b9 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2203,9 +2203,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
@@ -2243,9 +2243,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
#define CPU_RESOLVING_TYPE TYPE_X86_CPU
#ifdef TARGET_X86_64

View File

@@ -9,7 +9,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/block/gluster.c b/block/gluster.c
index 185a83e5e5..f11a40aa9e 100644
index ad5fadbe79..d0011085c4 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -43,7 +43,7 @@
@@ -24,7 +24,7 @@ index 185a83e5e5..f11a40aa9e 100644
@@ -425,6 +425,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
int old_errno;
SocketAddressList *server;
unsigned long long port;
uint64_t port;
+ const char *logfile;
glfs = glfs_find_preopened(gconf->volume);

View File

@@ -16,7 +16,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/block/gluster.c b/block/gluster.c
index f11a40aa9e..6756e6b886 100644
index d0011085c4..2df3d6e35d 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -58,6 +58,7 @@ typedef struct GlusterAIOCB {

View File

@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/qemu-img.c b/qemu-img.c
index 9aeac69fa6..0919fac1f1 100644
index 78433f3746..25d427edd1 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3059,7 +3059,8 @@ static int img_info(int argc, char **argv)
@@ -3062,7 +3062,8 @@ static int img_info(int argc, char **argv)
list = collect_image_info_list(image_opts, filename, fmt, chain,
force_share);
if (!list) {

View File

@@ -54,10 +54,10 @@ index 1b1dab5b17..d1616c045a 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 0919fac1f1..c584de648c 100644
index 25d427edd1..220e6ec577 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4885,10 +4885,12 @@ static int img_bitmap(int argc, char **argv)
@@ -4899,10 +4899,12 @@ static int img_bitmap(int argc, char **argv)
#define C_IF 04
#define C_OF 010
#define C_SKIP 020
@@ -70,7 +70,7 @@ index 0919fac1f1..c584de648c 100644
};
struct DdIo {
@@ -4964,6 +4966,19 @@ static int img_dd_skip(const char *arg,
@@ -4978,6 +4980,19 @@ static int img_dd_skip(const char *arg,
return 0;
}
@@ -90,7 +90,7 @@ index 0919fac1f1..c584de648c 100644
static int img_dd(int argc, char **argv)
{
int ret = 0;
@@ -5004,6 +5019,7 @@ static int img_dd(int argc, char **argv)
@@ -5018,6 +5033,7 @@ static int img_dd(int argc, char **argv)
{ "if", img_dd_if, C_IF },
{ "of", img_dd_of, C_OF },
{ "skip", img_dd_skip, C_SKIP },
@@ -98,7 +98,7 @@ index 0919fac1f1..c584de648c 100644
{ NULL, NULL, 0 }
};
const struct option long_options[] = {
@@ -5079,91 +5095,112 @@ static int img_dd(int argc, char **argv)
@@ -5093,91 +5109,112 @@ static int img_dd(int argc, char **argv)
arg = NULL;
}
@@ -275,7 +275,7 @@ index 0919fac1f1..c584de648c 100644
}
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
@@ -5180,20 +5217,43 @@ static int img_dd(int argc, char **argv)
@@ -5194,20 +5231,43 @@ static int img_dd(int argc, char **argv)
in.buf = g_new(uint8_t, in.bsz);
for (out_pos = 0; in_pos < size; ) {

View File

@@ -16,10 +16,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index c584de648c..a57ceeddfe 100644
index 220e6ec577..58bf9b43d1 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4886,11 +4886,13 @@ static int img_bitmap(int argc, char **argv)
@@ -4900,11 +4900,13 @@ static int img_bitmap(int argc, char **argv)
#define C_OF 010
#define C_SKIP 020
#define C_OSIZE 040
@@ -33,7 +33,7 @@ index c584de648c..a57ceeddfe 100644
};
struct DdIo {
@@ -4979,6 +4981,19 @@ static int img_dd_osize(const char *arg,
@@ -4993,6 +4995,19 @@ static int img_dd_osize(const char *arg,
return 0;
}
@@ -53,7 +53,7 @@ index c584de648c..a57ceeddfe 100644
static int img_dd(int argc, char **argv)
{
int ret = 0;
@@ -4993,12 +5008,14 @@ static int img_dd(int argc, char **argv)
@@ -5007,12 +5022,14 @@ static int img_dd(int argc, char **argv)
int c, i;
const char *out_fmt = "raw";
const char *fmt = NULL;
@@ -69,7 +69,7 @@ index c584de648c..a57ceeddfe 100644
};
struct DdIo in = {
.bsz = 512, /* Block size is by default 512 bytes */
@@ -5020,6 +5037,7 @@ static int img_dd(int argc, char **argv)
@@ -5034,6 +5051,7 @@ static int img_dd(int argc, char **argv)
{ "of", img_dd_of, C_OF },
{ "skip", img_dd_skip, C_SKIP },
{ "osize", img_dd_osize, C_OSIZE },
@@ -77,7 +77,7 @@ index c584de648c..a57ceeddfe 100644
{ NULL, NULL, 0 }
};
const struct option long_options[] = {
@@ -5216,9 +5234,10 @@ static int img_dd(int argc, char **argv)
@@ -5230,9 +5248,10 @@ static int img_dd(int argc, char **argv)
in.buf = g_new(uint8_t, in.bsz);
@@ -90,7 +90,7 @@ index c584de648c..a57ceeddfe 100644
if (blk1) {
in_ret = blk_pread(blk1, in_pos, bytes, in.buf, 0);
if (in_ret == 0) {
@@ -5227,6 +5246,9 @@ static int img_dd(int argc, char **argv)
@@ -5241,6 +5260,9 @@ static int img_dd(int argc, char **argv)
} else {
in_ret = read(STDIN_FILENO, in.buf, bytes);
if (in_ret == 0) {

View File

@@ -65,10 +65,10 @@ index d1616c045a..b5b0bb4467 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index a57ceeddfe..06d814e39c 100644
index 58bf9b43d1..9d414d639b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -5010,7 +5010,7 @@ static int img_dd(int argc, char **argv)
@@ -5024,7 +5024,7 @@ static int img_dd(int argc, char **argv)
const char *fmt = NULL;
int64_t size = 0, readsize = 0;
int64_t out_pos, in_pos;
@@ -77,7 +77,7 @@ index a57ceeddfe..06d814e39c 100644
struct DdInfo dd = {
.flags = 0,
.count = 0,
@@ -5048,7 +5048,7 @@ static int img_dd(int argc, char **argv)
@@ -5062,7 +5062,7 @@ static int img_dd(int argc, char **argv)
{ 0, 0, 0, 0 }
};
@@ -86,7 +86,7 @@ index a57ceeddfe..06d814e39c 100644
if (c == EOF) {
break;
}
@@ -5068,6 +5068,9 @@ static int img_dd(int argc, char **argv)
@@ -5082,6 +5082,9 @@ static int img_dd(int argc, char **argv)
case 'h':
help();
break;
@@ -96,7 +96,7 @@ index a57ceeddfe..06d814e39c 100644
case 'U':
force_share = true;
break;
@@ -5198,13 +5201,15 @@ static int img_dd(int argc, char **argv)
@@ -5212,13 +5215,15 @@ static int img_dd(int argc, char **argv)
size - in.bsz * in.offset, &error_abort);
}

View File

@@ -46,10 +46,10 @@ index b5b0bb4467..36f97e1f19 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 06d814e39c..e2c06c496d 100644
index 9d414d639b..e13a12137b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -5002,6 +5002,7 @@ static int img_dd(int argc, char **argv)
@@ -5016,6 +5016,7 @@ static int img_dd(int argc, char **argv)
BlockDriver *drv = NULL, *proto_drv = NULL;
BlockBackend *blk1 = NULL, *blk2 = NULL;
QemuOpts *opts = NULL;
@@ -57,7 +57,7 @@ index 06d814e39c..e2c06c496d 100644
QemuOptsList *create_opts = NULL;
Error *local_err = NULL;
bool image_opts = false;
@@ -5011,6 +5012,7 @@ static int img_dd(int argc, char **argv)
@@ -5025,6 +5026,7 @@ static int img_dd(int argc, char **argv)
int64_t size = 0, readsize = 0;
int64_t out_pos, in_pos;
bool force_share = false, skip_create = false;
@@ -65,7 +65,7 @@ index 06d814e39c..e2c06c496d 100644
struct DdInfo dd = {
.flags = 0,
.count = 0,
@@ -5048,7 +5050,7 @@ static int img_dd(int argc, char **argv)
@@ -5062,7 +5064,7 @@ static int img_dd(int argc, char **argv)
{ 0, 0, 0, 0 }
};
@@ -74,7 +74,7 @@ index 06d814e39c..e2c06c496d 100644
if (c == EOF) {
break;
}
@@ -5071,6 +5073,19 @@ static int img_dd(int argc, char **argv)
@@ -5085,6 +5087,19 @@ static int img_dd(int argc, char **argv)
case 'n':
skip_create = true;
break;
@@ -94,7 +94,7 @@ index 06d814e39c..e2c06c496d 100644
case 'U':
force_share = true;
break;
@@ -5130,11 +5145,24 @@ static int img_dd(int argc, char **argv)
@@ -5144,11 +5159,24 @@ static int img_dd(int argc, char **argv)
if (dd.flags & C_IF) {
blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
force_share);
@@ -120,7 +120,7 @@ index 06d814e39c..e2c06c496d 100644
}
if (dd.flags & C_OSIZE) {
@@ -5289,6 +5317,7 @@ static int img_dd(int argc, char **argv)
@@ -5303,6 +5331,7 @@ static int img_dd(int argc, char **argv)
out:
g_free(arg);
qemu_opts_del(opts);

View File

@@ -59,10 +59,10 @@ index c3e55ef9e9..0e32e6201f 100644
qapi_free_BalloonInfo(info);
}
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 746f07c4d2..a41854b902 100644
index d004cf29d2..2660ed520b 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -804,8 +804,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
@@ -782,8 +782,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
{
VirtIOBalloon *dev = opaque;
@@ -103,12 +103,12 @@ index 746f07c4d2..a41854b902 100644
static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
diff --git a/qapi/machine.json b/qapi/machine.json
index 604b686e59..15f5f86683 100644
index a08b6576ca..5c9a4d55f4 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1056,9 +1056,29 @@
# @actual: the logical size of the VM in bytes
# Formula used: logical_vm_size = vm_ram_size - balloon_size
@@ -1063,9 +1063,29 @@
# @actual: the logical size of the VM in bytes Formula used:
# logical_vm_size = vm_ram_size - balloon_size
#
+# @last_update: time when stats got updated from guest
+#

View File

@@ -13,10 +13,10 @@ Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index b98ff15089..24595f618c 100644
index 3860a50c3b..40821e2317 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -103,6 +103,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
@@ -91,6 +91,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
info->numa_mem_supported = mc->numa_mem_supported;
info->deprecated = !!mc->deprecation_reason;
info->acpi = !!object_class_property_find(OBJECT_CLASS(mc), "acpi");
@@ -30,19 +30,19 @@ index b98ff15089..24595f618c 100644
info->default_cpu_type = g_strdup(mc->default_cpu_type);
}
diff --git a/qapi/machine.json b/qapi/machine.json
index 15f5f86683..c904280085 100644
index 5c9a4d55f4..fbb61f18e4 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -138,6 +138,8 @@
@@ -139,6 +139,8 @@
#
# @is-default: whether the machine is default
#
+# @is-current: whether this machine is currently used
+#
# @cpu-max: maximum number of CPUs supported by the machine type
# (since 1.5)
# (since 1.5)
#
@@ -161,7 +163,7 @@
@@ -163,7 +165,7 @@
##
{ 'struct': 'MachineInfo',
'data': { 'name': 'str', '*alias': 'str',

View File

@@ -14,10 +14,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2 files changed, 7 insertions(+)
diff --git a/qapi/ui.json b/qapi/ui.json
index 98322342f7..316d4dc933 100644
index 006616aa77..dfd1d3e36b 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -310,11 +310,14 @@
@@ -317,11 +317,14 @@
#
# @channels: a list of @SpiceChannel for each active spice channel
#

View File

@@ -269,14 +269,14 @@ index 0000000000..17ae2cb261
+
+#endif /* QIO_CHANNEL_SAVEVM_ASYNC_H */
diff --git a/migration/meson.build b/migration/meson.build
index 0d1bb9f96e..8a142fc7a9 100644
index 1ae28523a1..37ddcb5d60 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -13,6 +13,7 @@ softmmu_ss.add(files(
@@ -13,6 +13,7 @@ system_ss.add(files(
'block-dirty-bitmap.c',
'channel.c',
'channel-block.c',
+ 'channel-savevm-async.c',
'colo-failover.c',
'colo.c',
'dirtyrate.c',
'exec.c',
'fd.c',

View File

@@ -35,20 +35,20 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
include/migration/snapshot.h | 2 +
include/monitor/hmp.h | 3 +
migration/meson.build | 1 +
migration/savevm-async.c | 533 +++++++++++++++++++++++++++++++++++
migration/savevm-async.c | 531 +++++++++++++++++++++++++++++++++++
monitor/hmp-cmds.c | 38 +++
qapi/migration.json | 34 +++
qapi/misc.json | 16 ++
qemu-options.hx | 12 +
softmmu/vl.c | 10 +
11 files changed, 679 insertions(+)
11 files changed, 677 insertions(+)
create mode 100644 migration/savevm-async.c
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 47d63d26db..a166bff3d5 100644
index f5b37eb74a..10fdd822e0 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -540,6 +540,19 @@ SRST
@@ -525,6 +525,19 @@ SRST
Show current migration parameters.
ERST
@@ -69,10 +69,10 @@ index 47d63d26db..a166bff3d5 100644
.name = "balloon",
.args_type = "",
diff --git a/hmp-commands.hx b/hmp-commands.hx
index bb85ee1d26..d9f9f42d11 100644
index 2cbd0f77a0..e352f86872 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1846,3 +1846,20 @@ SRST
@@ -1865,3 +1865,20 @@ SRST
List event channels in the guest
ERST
#endif
@@ -105,7 +105,7 @@ index e72083b117..c846d37806 100644
+
#endif
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index fdb69b7f9c..fdf6b45fb8 100644
index 13f9a2dedb..7a7def7530 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -28,6 +28,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
@@ -126,11 +126,11 @@ index fdb69b7f9c..fdf6b45fb8 100644
void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict);
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
diff --git a/migration/meson.build b/migration/meson.build
index 8a142fc7a9..a7824b5266 100644
index 37ddcb5d60..07f6057acc 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -25,6 +25,7 @@ softmmu_ss.add(files(
'multifd-zlib.c',
@@ -26,6 +26,7 @@ system_ss.add(files(
'options.c',
'postcopy-ram.c',
'savevm.c',
+ 'savevm-async.c',
@@ -139,13 +139,15 @@ index 8a142fc7a9..a7824b5266 100644
'threadinfo.c',
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
new file mode 100644
index 0000000000..aa2017d496
index 0000000000..e9fc18fb10
--- /dev/null
+++ b/migration/savevm-async.c
@@ -0,0 +1,533 @@
@@ -0,0 +1,531 @@
+#include "qemu/osdep.h"
+#include "migration/channel-savevm-async.h"
+#include "migration/migration.h"
+#include "migration/migration-stats.h"
+#include "migration/options.h"
+#include "migration/savevm.h"
+#include "migration/snapshot.h"
+#include "migration/global_state.h"
@@ -420,11 +422,7 @@ index 0000000000..aa2017d496
+ DPRINTF("savevm iterate pending size %lu ret %d\n", pending_size, ret);
+ } else {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
+ ret = global_state_store();
+ if (ret) {
+ save_snapshot_error("global_state_store error %d", ret);
+ break;
+ }
+ global_state_store();
+
+ DPRINTF("savevm iterate complete\n");
+ break;
@@ -485,7 +483,7 @@ index 0000000000..aa2017d496
+ return;
+ }
+
+ if (migrate_use_block()) {
+ if (migrate_block()) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Block migration and snapshots are incompatible");
+ return;
@@ -538,7 +536,7 @@ index 0000000000..aa2017d496
+ * here (blocking main thread, from QMP) to avoid race conditions.
+ */
+ migrate_init(ms);
+ memset(&ram_counters, 0, sizeof(ram_counters));
+ memset(&mig_stats, 0, sizeof(mig_stats));
+ memset(&compression_counters, 0, sizeof(compression_counters));
+ ms->to_dst_file = snap_state.file;
+
@@ -730,12 +728,12 @@ index 6c559b48c8..91be698308 100644
+ }
+}
diff --git a/qapi/migration.json b/qapi/migration.json
index c84fa10e86..1702b92553 100644
index 8843e74b59..aca0ca1ac1 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -261,6 +261,40 @@
'*compression': 'CompressionStats',
'*socket-address': ['SocketAddress'] } }
@@ -291,6 +291,40 @@
'*dirty-limit-throttle-time-per-round': 'uint64',
'*dirty-limit-ring-full-time': 'uint64'} }
+##
+# @SaveVMInfo:
@@ -775,10 +773,10 @@ index c84fa10e86..1702b92553 100644
# @query-migrate:
#
diff --git a/qapi/misc.json b/qapi/misc.json
index 6ddd16ea28..e5681ae8a2 100644
index cda2effa81..94a58bb0bf 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -469,6 +469,22 @@
@@ -456,6 +456,22 @@
##
{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
@@ -802,10 +800,10 @@ index 6ddd16ea28..e5681ae8a2 100644
# @CommandLineParameterType:
#
diff --git a/qemu-options.hx b/qemu-options.hx
index fdddfab6ff..fdd551c2bb 100644
index 8073f5edf5..dc1ececc9c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4398,6 +4398,18 @@ SRST
@@ -4483,6 +4483,18 @@ SRST
Start right away with a saved state (``loadvm`` in monitor)
ERST
@@ -825,7 +823,7 @@ index fdddfab6ff..fdd551c2bb 100644
DEF("daemonize", 0, QEMU_OPTION_daemonize, \
"-daemonize daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
diff --git a/softmmu/vl.c b/softmmu/vl.c
index ea20b23e4c..0eabc71b68 100644
index c9e9ede237..3f2681aded 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -164,6 +164,7 @@ static const char *accelerators;
@@ -836,7 +834,7 @@ index ea20b23e4c..0eabc71b68 100644
static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts);
static int display_remote;
@@ -2612,6 +2613,12 @@ void qmp_x_exit_preconfig(Error **errp)
@@ -2647,6 +2648,12 @@ void qmp_x_exit_preconfig(Error **errp)
if (loadvm) {
load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
@@ -849,7 +847,7 @@ index ea20b23e4c..0eabc71b68 100644
}
if (replay_mode != REPLAY_MODE_NONE) {
replay_vmstate_init();
@@ -3159,6 +3166,9 @@ void qemu_init(int argc, char **argv)
@@ -3194,6 +3201,9 @@ void qemu_init(int argc, char **argv)
case QEMU_OPTION_loadvm:
loadvm = optarg;
break;

View File

@@ -19,11 +19,11 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
3 files changed, 38 insertions(+), 18 deletions(-)
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 102ab3b439..5ced17aba4 100644
index 19c33c9985..e9ffff0f0a 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -31,8 +31,8 @@
#include "trace.h"
@@ -33,8 +33,8 @@
#include "options.h"
#include "qapi/error.h"
-#define IO_BUF_SIZE 32768
@@ -33,7 +33,7 @@ index 102ab3b439..5ced17aba4 100644
struct QEMUFile {
const QEMUFileHooks *hooks;
@@ -55,7 +55,8 @@ struct QEMUFile {
@@ -46,7 +46,8 @@ struct QEMUFile {
int buf_index;
int buf_size; /* 0 when writing */
@@ -43,8 +43,8 @@ index 102ab3b439..5ced17aba4 100644
DECLARE_BITMAP(may_free, MAX_IOV_SIZE);
struct iovec iov[MAX_IOV_SIZE];
@@ -127,7 +128,9 @@ bool qemu_file_mode_is_not_valid(const char *mode)
return false;
@@ -100,7 +101,9 @@ int qemu_file_shutdown(QEMUFile *f)
return 0;
}
-static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
@@ -54,7 +54,7 @@ index 102ab3b439..5ced17aba4 100644
{
QEMUFile *f;
@@ -136,6 +139,8 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
@@ -109,6 +112,8 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
object_ref(ioc);
f->ioc = ioc;
f->is_writable = is_writable;
@@ -63,7 +63,7 @@ index 102ab3b439..5ced17aba4 100644
return f;
}
@@ -146,17 +151,27 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
@@ -119,17 +124,27 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
*/
QEMUFile *qemu_file_get_return_path(QEMUFile *f)
{
@@ -94,7 +94,7 @@ index 102ab3b439..5ced17aba4 100644
}
void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks)
@@ -414,7 +429,7 @@ static ssize_t qemu_fill_buffer(QEMUFile *f)
@@ -375,7 +390,7 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f)
do {
len = qio_channel_read(f->ioc,
(char *)f->buf + pending,
@@ -103,7 +103,7 @@ index 102ab3b439..5ced17aba4 100644
&local_error);
if (len == QIO_CHANNEL_ERR_BLOCK) {
if (qemu_in_coroutine()) {
@@ -464,6 +479,8 @@ int qemu_fclose(QEMUFile *f)
@@ -425,6 +440,8 @@ int qemu_fclose(QEMUFile *f)
}
g_clear_pointer(&f->ioc, object_unref);
@@ -112,7 +112,7 @@ index 102ab3b439..5ced17aba4 100644
/* If any error was spotted before closing, we should report it
* instead of the close() return value.
*/
@@ -518,7 +535,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len)
@@ -479,7 +496,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len)
{
if (!add_to_iovec(f, f->buf + f->buf_index, len, false)) {
f->buf_index += len;
@@ -121,7 +121,7 @@ index 102ab3b439..5ced17aba4 100644
qemu_fflush(f);
}
}
@@ -544,7 +561,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
@@ -504,7 +521,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
}
while (size > 0) {
@@ -130,7 +130,7 @@ index 102ab3b439..5ced17aba4 100644
if (l > size) {
l = size;
}
@@ -591,8 +608,8 @@ size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset)
@@ -549,8 +566,8 @@ size_t coroutine_mixed_fn qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t si
size_t index;
assert(!qemu_file_is_writable(f));
@@ -141,7 +141,7 @@ index 102ab3b439..5ced17aba4 100644
/* The 1st byte to read from */
index = f->buf_index + offset;
@@ -642,7 +659,7 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
@@ -600,7 +617,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size
size_t res;
uint8_t *src;
@@ -150,16 +150,16 @@ index 102ab3b439..5ced17aba4 100644
if (res == 0) {
return done;
}
@@ -676,7 +693,7 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
@@ -634,7 +651,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size
*/
size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size)
size_t coroutine_mixed_fn qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size)
{
- if (size < IO_BUF_SIZE) {
+ if (size < f->buf_allocated_size) {
size_t res;
uint8_t *src = NULL;
@@ -701,7 +718,7 @@ int qemu_peek_byte(QEMUFile *f, int offset)
@@ -659,7 +676,7 @@ int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int offset)
int index = f->buf_index + offset;
assert(!qemu_file_is_writable(f));
@@ -168,7 +168,7 @@ index 102ab3b439..5ced17aba4 100644
if (index >= f->buf_size) {
qemu_fill_buffer(f);
@@ -853,7 +870,7 @@ static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len,
@@ -777,7 +794,7 @@ static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len,
ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream,
const uint8_t *p, size_t size)
{
@@ -178,7 +178,7 @@ index 102ab3b439..5ced17aba4 100644
if (blen < compressBound(size)) {
return -1;
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
index 9d0155a2a1..cc06240e8d 100644
index 47015f5201..1312b7c903 100644
--- a/migration/qemu-file.h
+++ b/migration/qemu-file.h
@@ -63,7 +63,9 @@ typedef struct QEMUFileHooks {
@@ -192,10 +192,10 @@ index 9d0155a2a1..cc06240e8d 100644
int qemu_fclose(QEMUFile *f);
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
index aa2017d496..b97f2c4f14 100644
index e9fc18fb10..80624fada8 100644
--- a/migration/savevm-async.c
+++ b/migration/savevm-async.c
@@ -380,7 +380,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
@@ -378,7 +378,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
QIOChannel *ioc = QIO_CHANNEL(qio_channel_savevm_async_new(snap_state.target,
&snap_state.bs_pos));
@@ -204,7 +204,7 @@ index aa2017d496..b97f2c4f14 100644
if (!snap_state.file) {
error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
@@ -498,7 +498,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
@@ -496,7 +496,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
blk_op_block_all(be, blocker);
/* restore the VM state */

View File

@@ -13,17 +13,17 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
create mode 100644 block/zeroinit.c
diff --git a/block/meson.build b/block/meson.build
index 382bec0e7d..253fe49fa2 100644
index 529fc172c6..1833c71ce9 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -44,6 +44,7 @@ block_ss.add(files(
'vmdk.c',
'vpc.c',
@@ -40,6 +40,7 @@ block_ss.add(files(
'throttle-groups.c',
'throttle.c',
'write-threshold.c',
+ 'zeroinit.c',
), zstd, zlib, gnutls)
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
diff --git a/block/zeroinit.c b/block/zeroinit.c
new file mode 100644
index 0000000000..1257342724

View File

@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 files changed, 11 insertions(+)
diff --git a/qemu-options.hx b/qemu-options.hx
index fdd551c2bb..4eb43b7bc5 100644
index dc1ececc9c..848d2dfdd1 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1162,6 +1162,9 @@ legacy PC, they are not recommended for modern configurations.
@@ -1197,6 +1197,9 @@ legacy PC, they are not recommended for modern configurations.
ERST
@@ -28,10 +28,10 @@ index fdd551c2bb..4eb43b7bc5 100644
"-fda/-fdb file use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 0eabc71b68..323f6a23d4 100644
index 3f2681aded..1a3b9cc4b8 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2648,6 +2648,7 @@ void qemu_init(int argc, char **argv)
@@ -2683,6 +2683,7 @@ void qemu_init(int argc, char **argv)
MachineClass *machine_class;
bool userconfig = true;
FILE *vmstate_dump_file = NULL;
@@ -39,7 +39,7 @@ index 0eabc71b68..323f6a23d4 100644
qemu_add_opts(&qemu_drive_opts);
qemu_add_drive_opts(&qemu_legacy_drive_opts);
@@ -3271,6 +3272,13 @@ void qemu_init(int argc, char **argv)
@@ -3306,6 +3307,13 @@ void qemu_init(int argc, char **argv)
machine_parse_property_opt(qemu_find_opts("smp-opts"),
"smp", optarg);
break;

View File

@@ -13,10 +13,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 9681bd0434..044890822d 100644
index ca551baa42..8b3b83e9d4 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2483,6 +2483,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
@@ -2873,6 +2873,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
int fd;
uint64_t perm, shared;
int result = 0;
@@ -24,7 +24,7 @@ index 9681bd0434..044890822d 100644
/* Validate options and set default values */
assert(options->driver == BLOCKDEV_DRIVER_FILE);
@@ -2523,19 +2524,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
@@ -2913,19 +2914,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
@@ -59,7 +59,7 @@ index 9681bd0434..044890822d 100644
}
/* Clear the file by truncating it to 0 */
@@ -2589,13 +2593,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
@@ -2979,13 +2983,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
}
out_unlock:
@@ -82,7 +82,7 @@ index 9681bd0434..044890822d 100644
}
out_close:
@@ -2619,6 +2625,7 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
@@ -3009,6 +3015,7 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
PreallocMode prealloc;
char *buf = NULL;
Error *local_err = NULL;
@@ -90,7 +90,7 @@ index 9681bd0434..044890822d 100644
/* Skip file: protocol prefix */
strstart(filename, "file:", &filename);
@@ -2641,6 +2648,18 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
@@ -3031,6 +3038,18 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
return -EINVAL;
}
@@ -109,7 +109,7 @@ index 9681bd0434..044890822d 100644
options = (BlockdevCreateOptions) {
.driver = BLOCKDEV_DRIVER_FILE,
.u.file = {
@@ -2652,6 +2671,8 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
@@ -3042,6 +3061,8 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
.nocow = nocow,
.has_extent_size_hint = has_extent_size_hint,
.extent_size_hint = extent_size_hint,
@@ -119,10 +119,10 @@ index 9681bd0434..044890822d 100644
};
return raw_co_create(&options, errp);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3c945c1f93..542add004b 100644
index a5cea82139..bb471c078d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4740,7 +4740,8 @@
@@ -4880,7 +4880,8 @@
'size': 'size',
'*preallocation': 'PreallocMode',
'*nocow': 'bool',

View File

@@ -18,10 +18,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 6b8cfcf6d8..3ec67e32d3 100644
index 589c9524f8..2505dd658a 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -519,8 +519,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
@@ -536,8 +536,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
qemu_chr_fe_set_echo(&mon->common.chr, true);
/* Note: we run QMP monitor in I/O thread when @chr supports that */

View File

@@ -26,10 +26,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 2f6ccf5623..a5927e92f1 100644
index f0d35c6401..1427983543 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -142,7 +142,8 @@ GlobalProperty hw_compat_4_0[] = {
@@ -148,7 +148,8 @@ GlobalProperty hw_compat_4_0[] = {
{ "virtio-vga", "edid", "false" },
{ "virtio-gpu-device", "edid", "false" },
{ "virtio-device", "use-started", "false" },

View File

@@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
4 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 24595f618c..ee9cb0cd04 100644
index 40821e2317..ee93ddd69a 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -107,6 +107,11 @@ MachineInfoList *qmp_query_machines(Error **errp)
@@ -95,6 +95,11 @@ MachineInfoList *qmp_query_machines(Error **errp)
if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
info->has_is_current = true;
info->is_current = true;
@@ -37,10 +37,10 @@ index 24595f618c..ee9cb0cd04 100644
if (mc->default_cpu_type) {
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6fbbfd56c8..61a526e97d 100644
index ed83360198..f8b88cd86a 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -232,6 +232,8 @@ struct MachineClass {
@@ -235,6 +235,8 @@ struct MachineClass {
const char *desc;
const char *deprecation_reason;
@@ -50,10 +50,10 @@ index 6fbbfd56c8..61a526e97d 100644
void (*reset)(MachineState *state, ShutdownCause reason);
void (*wakeup)(MachineState *state);
diff --git a/qapi/machine.json b/qapi/machine.json
index c904280085..47f3facdb2 100644
index fbb61f18e4..7da3c519ba 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -159,6 +159,8 @@
@@ -161,6 +161,8 @@
#
# @acpi: machine type supports ACPI (since 8.0)
#
@@ -62,7 +62,7 @@ index c904280085..47f3facdb2 100644
# Since: 1.2
##
{ 'struct': 'MachineInfo',
@@ -166,7 +168,7 @@
@@ -168,7 +170,7 @@
'*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
'deprecated': 'bool', '*default-cpu-type': 'str',
@@ -72,10 +72,10 @@ index c904280085..47f3facdb2 100644
##
# @query-machines:
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 323f6a23d4..25abdc9da7 100644
index 1a3b9cc4b8..e9b5f62cc3 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1578,6 +1578,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
@@ -1597,6 +1597,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
static MachineClass *select_machine(QDict *qdict, Error **errp)
{
const char *optarg = qdict_get_try_str(qdict, "type");
@@ -83,7 +83,7 @@ index 323f6a23d4..25abdc9da7 100644
GSList *machines = object_class_get_list(TYPE_MACHINE, false);
MachineClass *machine_class;
Error *local_err = NULL;
@@ -1595,6 +1596,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
@@ -1614,6 +1615,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
}
}
@@ -95,7 +95,7 @@ index 323f6a23d4..25abdc9da7 100644
g_slist_free(machines);
if (local_err) {
error_append_hint(&local_err, "Use -machine help to list supported machines\n");
@@ -3213,12 +3219,31 @@ void qemu_init(int argc, char **argv)
@@ -3248,12 +3254,31 @@ void qemu_init(int argc, char **argv)
case QEMU_OPTION_machine:
{
bool help;

View File

@@ -16,33 +16,33 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
block/meson.build | 2 +
meson.build | 5 +
vma-reader.c | 867 ++++++++++++++++++++++++++++++++++++++++++++
vma-writer.c | 793 ++++++++++++++++++++++++++++++++++++++++
vma-writer.c | 818 +++++++++++++++++++++++++++++++++++++++++
vma.c | 900 ++++++++++++++++++++++++++++++++++++++++++++++
vma.h | 150 ++++++++
6 files changed, 2717 insertions(+)
6 files changed, 2742 insertions(+)
create mode 100644 vma-reader.c
create mode 100644 vma-writer.c
create mode 100644 vma.c
create mode 100644 vma.h
diff --git a/block/meson.build b/block/meson.build
index 253fe49fa2..744b698a82 100644
index 1833c71ce9..59b71ba9f3 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -47,6 +47,8 @@ block_ss.add(files(
@@ -43,6 +43,8 @@ block_ss.add(files(
'zeroinit.c',
), zstd, zlib, gnutls)
+block_ss.add(files('../vma-writer.c'), libuuid)
+
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
softmmu_ss.add(files('block-ram-registrar.c'))
system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
system_ss.add(files('block-ram-registrar.c'))
diff --git a/meson.build b/meson.build
index 30447cfaef..38a4e2bcef 100644
index a9c4f28247..cd95530d3b 100644
--- a/meson.build
+++ b/meson.build
@@ -1527,6 +1527,8 @@ keyutils = dependency('libkeyutils', required: false,
@@ -1778,6 +1778,8 @@ endif
has_gettid = cc.has_function('gettid')
@@ -51,7 +51,7 @@ index 30447cfaef..38a4e2bcef 100644
# libselinux
selinux = dependency('libselinux',
required: get_option('selinux'),
@@ -3650,6 +3652,9 @@ if have_tools
@@ -3908,6 +3910,9 @@ if have_tools
dependencies: [blockdev, qemuutil, gnutls, selinux],
install: true)
@@ -936,10 +936,10 @@ index 0000000000..81a891c6b1
+
diff --git a/vma-writer.c b/vma-writer.c
new file mode 100644
index 0000000000..ac7da237d0
index 0000000000..126b296647
--- /dev/null
+++ b/vma-writer.c
@@ -0,0 +1,793 @@
@@ -0,0 +1,818 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
@@ -955,6 +955,8 @@ index 0000000000..ac7da237d0
+
+#include "qemu/osdep.h"
+#include <glib.h>
+#include <linux/magic.h>
+#include <sys/vfs.h>
+#include <uuid/uuid.h>
+
+#include "vma.h"
@@ -963,6 +965,7 @@ index 0000000000..ac7da237d0
+#include "qemu/main-loop.h"
+#include "qemu/coroutine.h"
+#include "qemu/cutils.h"
+#include "qemu/error-report.h"
+#include "qemu/memalign.h"
+
+#define DEBUG_VMA 0
@@ -1146,10 +1149,10 @@ index 0000000000..ac7da237d0
+{
+ assert(qemu_in_coroutine());
+ AioContext *ctx = qemu_get_current_aio_context();
+ aio_set_fd_handler(ctx, fd, false, NULL, (IOHandler *)qemu_coroutine_enter,
+ NULL, NULL, qemu_coroutine_self());
+ aio_set_fd_handler(ctx, fd, NULL, (IOHandler *)qemu_coroutine_enter, NULL,
+ NULL, qemu_coroutine_self());
+ qemu_coroutine_yield();
+ aio_set_fd_handler(ctx, fd, false, NULL, NULL, NULL, NULL, NULL);
+ aio_set_fd_handler(ctx, fd, NULL, NULL, NULL, NULL, NULL);
+}
+
+static ssize_t coroutine_fn
@@ -1198,6 +1201,23 @@ index 0000000000..ac7da237d0
+ return (done == bytes) ? bytes : -1;
+}
+
+static bool is_path_tmpfs(const char *path) {
+ struct statfs fs;
+ int ret;
+
+ do {
+ ret = statfs(path, &fs);
+ } while (ret != 0 && errno == EINTR);
+
+ if (ret != 0) {
+ warn_report("statfs call for %s failed, assuming not tmpfs - %s\n",
+ path, strerror(errno));
+ return false;
+ }
+
+ return fs.f_type == TMPFS_MAGIC;
+}
+
+VmaWriter *vma_writer_create(const char *filename, uuid_t uuid, Error **errp)
+{
+ const char *p;
@@ -1247,8 +1267,13 @@ index 0000000000..ac7da237d0
+ }
+ /* try to use O_NONBLOCK */
+ fcntl(vmaw->fd, F_SETFL, fcntl(vmaw->fd, F_GETFL)|O_NONBLOCK);
+ } else {
+ oflags = O_NONBLOCK|O_DIRECT|O_WRONLY|O_EXCL;
+ } else {
+ gchar *dirname = g_path_get_dirname(filename);
+ oflags = O_NONBLOCK|O_WRONLY|O_EXCL;
+ if (!is_path_tmpfs(dirname)) {
+ oflags |= O_DIRECT;
+ }
+ g_free(dirname);
+ vmaw->fd = qemu_create(filename, oflags, 0644, errp);
+ }
+
@@ -1735,7 +1760,7 @@ index 0000000000..ac7da237d0
+}
diff --git a/vma.c b/vma.c
new file mode 100644
index 0000000000..cf2a2a74af
index 0000000000..347f6283ca
--- /dev/null
+++ b/vma.c
@@ -0,0 +1,900 @@
@@ -1917,7 +1942,7 @@ index 0000000000..cf2a2a74af
+ const char *filename;
+ const char *dirname;
+ const char *readmap = NULL;
+ const gchar **drive_list = NULL;
+ gchar **drive_list = NULL;
+
+ for (;;) {
+ c = getopt(argc, argv, "hvd:r:");

View File

@@ -243,7 +243,7 @@ index 39410dcf8d..af87fa6aa9 100644
if (perf->max_chunk && perf->max_chunk < cluster_size) {
error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
diff --git a/block/meson.build b/block/meson.build
index 744b698a82..f580f95395 100644
index 59b71ba9f3..6fde9f7dcd 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -4,6 +4,7 @@ block_ss.add(files(
@@ -255,7 +255,7 @@ index 744b698a82..f580f95395 100644
'blkdebug.c',
'blklogwrites.c',
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index f01bb8b617..d7ffd1826e 100644
index 74195c3004..0f2e1817ad 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -26,6 +26,7 @@

View File

@@ -84,30 +84,68 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
create jobs in a drained section]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/meson.build | 5 +
block/monitor/block-hmp-cmds.c | 39 ++
blockdev.c | 1 +
hmp-commands-info.hx | 14 +
hmp-commands.hx | 29 +
include/monitor/hmp.h | 3 +
meson.build | 1 +
monitor/hmp-cmds.c | 72 +++
proxmox-backup-client.c | 146 +++++
proxmox-backup-client.h | 60 ++
pve-backup.c | 1067 ++++++++++++++++++++++++++++++++
qapi/block-core.json | 229 +++++++
qapi/common.json | 13 +
qapi/machine.json | 15 +-
14 files changed, 1681 insertions(+), 13 deletions(-)
block/backup-dump.c | 10 +-
block/meson.build | 5 +
block/monitor/block-hmp-cmds.c | 39 ++
blockdev.c | 1 +
hmp-commands-info.hx | 14 +
hmp-commands.hx | 29 +
include/block/block_int-common.h | 2 +-
include/monitor/hmp.h | 3 +
meson.build | 1 +
monitor/hmp-cmds.c | 72 ++
proxmox-backup-client.c | 146 ++++
proxmox-backup-client.h | 60 ++
pve-backup.c | 1067 ++++++++++++++++++++++++++++++
qapi/block-core.json | 229 +++++++
qapi/common.json | 14 +
qapi/machine.json | 16 +-
16 files changed, 1690 insertions(+), 18 deletions(-)
create mode 100644 proxmox-backup-client.c
create mode 100644 proxmox-backup-client.h
create mode 100644 pve-backup.c
diff --git a/block/backup-dump.c b/block/backup-dump.c
index 232a094426..e46abf1070 100644
--- a/block/backup-dump.c
+++ b/block/backup-dump.c
@@ -9,6 +9,8 @@
*/
#include "qemu/osdep.h"
+
+#include "qapi/qmp/qdict.h"
#include "qom/object_interfaces.h"
#include "block/block_int.h"
@@ -141,7 +143,7 @@ static void bdrv_backup_dump_init(void)
block_init(bdrv_backup_dump_init);
-BlockDriverState *bdrv_backup_dump_create(
+BlockDriverState *coroutine_fn bdrv_co_backup_dump_create(
int dump_cb_block_size,
uint64_t byte_size,
BackupDumpFunc *dump_cb,
@@ -149,9 +151,11 @@ BlockDriverState *bdrv_backup_dump_create(
Error **errp)
{
BDRVBackupDumpState *state;
- BlockDriverState *bs = bdrv_new_open_driver(
- &bdrv_backup_dump_drive, NULL, BDRV_O_RDWR, errp);
+ QDict *options = qdict_new();
+ qdict_put_str(options, "driver", "backup-dump-drive");
+
+ BlockDriverState *bs = bdrv_co_open(NULL, NULL, options, BDRV_O_RDWR, errp);
if (!bs) {
return NULL;
}
diff --git a/block/meson.build b/block/meson.build
index f580f95395..5bcebb934b 100644
index 6fde9f7dcd..6d468f89e5 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -49,6 +49,11 @@ block_ss.add(files(
@@ -45,6 +45,11 @@ block_ss.add(files(
), zstd, zlib, gnutls)
block_ss.add(files('../vma-writer.c'), libuuid)
@@ -117,8 +155,8 @@ index f580f95395..5bcebb934b 100644
+), libproxmox_backup_qemu)
+
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
softmmu_ss.add(files('block-ram-registrar.c'))
system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
system_ss.add(files('block-ram-registrar.c'))
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index ca2599de44..6efe28cef5 100644
--- a/block/monitor/block-hmp-cmds.c
@@ -167,7 +205,7 @@ index ca2599de44..6efe28cef5 100644
+ hmp_handle_error(mon, error);
+}
diff --git a/blockdev.c b/blockdev.c
index bdae211a54..315a27fc09 100644
index cd5f205ad1..7793143d76 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -37,6 +37,7 @@
@@ -179,10 +217,10 @@ index bdae211a54..315a27fc09 100644
#include "monitor/monitor.h"
#include "qemu/error-report.h"
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index a166bff3d5..4b75966c2e 100644
index 10fdd822e0..15937793c1 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -486,6 +486,20 @@ SRST
@@ -471,6 +471,20 @@ SRST
Show the current VM UUID.
ERST
@@ -204,7 +242,7 @@ index a166bff3d5..4b75966c2e 100644
{
.name = "usernet",
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d9f9f42d11..ddb9678dc3 100644
index e352f86872..0c8b6725fb 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -101,6 +101,35 @@ ERST
@@ -243,8 +281,21 @@ index d9f9f42d11..ddb9678dc3 100644
ERST
{
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 0f2e1817ad..0a0339eee4 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -63,7 +63,7 @@
typedef int BackupDumpFunc(void *opaque, uint64_t offset, uint64_t bytes, const void *buf);
-BlockDriverState *bdrv_backup_dump_create(
+BlockDriverState *coroutine_fn bdrv_co_backup_dump_create(
int dump_cb_block_size,
uint64_t byte_size,
BackupDumpFunc *dump_cb,
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index fdf6b45fb8..e01b2201d8 100644
index 7a7def7530..cba7afe70c 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -32,6 +32,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
@@ -265,10 +316,10 @@ index fdf6b45fb8..e01b2201d8 100644
void hmp_device_add(Monitor *mon, const QDict *qdict);
void hmp_device_del(Monitor *mon, const QDict *qdict);
diff --git a/meson.build b/meson.build
index 38a4e2bcef..443b3238f9 100644
index cd95530d3b..d53976d621 100644
--- a/meson.build
+++ b/meson.build
@@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
@@ -1779,6 +1779,7 @@ endif
has_gettid = cc.has_function('gettid')
libuuid = cc.find_library('uuid', required: true)
@@ -586,7 +637,7 @@ index 0000000000..8cbf645b2c
+#endif /* PROXMOX_BACKUP_CLIENT_H */
diff --git a/pve-backup.c b/pve-backup.c
new file mode 100644
index 0000000000..8ff0d88297
index 0000000000..d84d807654
--- /dev/null
+++ b/pve-backup.c
@@ -0,0 +1,1067 @@
@@ -700,7 +751,7 @@ index 0000000000..8ff0d88297
+ return error_or_canceled;
+}
+
+static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes, size_t reused)
+static void pvebackup_add_transferred_bytes(size_t transferred, size_t zero_bytes, size_t reused)
+{
+ qemu_mutex_lock(&backup_state.stat.lock);
+ backup_state.stat.zero_bytes += zero_bytes;
@@ -761,7 +812,7 @@ index 0000000000..8ff0d88297
+ }
+
+ qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
+ pvebackup_add_transfered_bytes(size, is_zero_block ? size : 0, reused);
+ pvebackup_add_transferred_bytes(size, is_zero_block ? size : 0, reused);
+
+ return size;
+}
@@ -819,11 +870,11 @@ index 0000000000..8ff0d88297
+ } else {
+ if (remaining >= VMA_CLUSTER_SIZE) {
+ assert(ret == VMA_CLUSTER_SIZE);
+ pvebackup_add_transfered_bytes(VMA_CLUSTER_SIZE, zero_bytes, 0);
+ pvebackup_add_transferred_bytes(VMA_CLUSTER_SIZE, zero_bytes, 0);
+ remaining -= VMA_CLUSTER_SIZE;
+ } else {
+ assert(ret == remaining);
+ pvebackup_add_transfered_bytes(remaining, zero_bytes, 0);
+ pvebackup_add_transferred_bytes(remaining, zero_bytes, 0);
+ remaining = 0;
+ }
+ }
@@ -1394,7 +1445,7 @@ index 0000000000..8ff0d88297
+ goto err_mutex;
+ }
+
+ if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, errp))) {
+ if (!(di->target = bdrv_co_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, errp))) {
+ goto err_mutex;
+ }
+
@@ -1422,7 +1473,7 @@ index 0000000000..8ff0d88297
+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+ l = g_list_next(l);
+
+ if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, errp))) {
+ if (!(di->target = bdrv_co_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, errp))) {
+ goto err_mutex;
+ }
+
@@ -1658,10 +1709,10 @@ index 0000000000..8ff0d88297
+ return ret;
+}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 542add004b..985859ddee 100644
index bb471c078d..1b8462a51b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -835,6 +835,235 @@
@@ -839,6 +839,235 @@
{ 'command': 'query-block', 'returns': ['BlockInfo'],
'allow-preconfig': true }
@@ -1898,10 +1949,10 @@ index 542add004b..985859ddee 100644
# @BlockDeviceTimedStats:
#
diff --git a/qapi/common.json b/qapi/common.json
index 356db3f670..aae8a3b682 100644
index 6fed9cde1a..630a2a8f9a 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -206,3 +206,16 @@
@@ -207,3 +207,17 @@
##
{ 'struct': 'HumanReadableText',
'data': { 'human-readable-text': 'str' } }
@@ -1915,11 +1966,12 @@ index 356db3f670..aae8a3b682 100644
+#
+# Since: 0.14.0
+#
+# Notes: If no UUID was specified for the guest, a null UUID is returned.
+# Notes: If no UUID was specified for the guest, a null UUID is
+# returned.
+##
+{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
diff --git a/qapi/machine.json b/qapi/machine.json
index 47f3facdb2..46760978ae 100644
index 7da3c519ba..888457f810 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -4,6 +4,8 @@
@@ -1931,7 +1983,7 @@ index 47f3facdb2..46760978ae 100644
##
# = Machines
##
@@ -228,19 +230,6 @@
@@ -230,20 +232,6 @@
##
{ 'command': 'query-target', 'returns': 'TargetInfo' }
@@ -1944,7 +1996,8 @@ index 47f3facdb2..46760978ae 100644
-#
-# Since: 0.14
-#
-# Notes: If no UUID was specified for the guest, a null UUID is returned.
-# Notes: If no UUID was specified for the guest, a null UUID is
-# returned.
-##
-{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
-

View File

@@ -14,10 +14,10 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
create mode 100644 pbs-restore.c
diff --git a/meson.build b/meson.build
index 443b3238f9..32ab849ce6 100644
index d53976d621..c3330310d9 100644
--- a/meson.build
+++ b/meson.build
@@ -3656,6 +3656,10 @@ if have_tools
@@ -3914,6 +3914,10 @@ if have_tools
vma = executable('vma', files('vma.c', 'vma-reader.c') + genh,
dependencies: [authz, block, crypto, io, qom], install: true)

View File

@@ -24,10 +24,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
create mode 100644 block/pbs.c
diff --git a/block/meson.build b/block/meson.build
index 5bcebb934b..eece0d5743 100644
index 6d468f89e5..becc99ac4e 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -54,6 +54,9 @@ block_ss.add(files(
@@ -50,6 +50,9 @@ block_ss.add(files(
'../pve-backup.c',
), libproxmox_backup_qemu)
@@ -35,8 +35,8 @@ index 5bcebb934b..eece0d5743 100644
+block_ss.add(when: 'CONFIG_PBS_BDRV', if_true: libproxmox_backup_qemu)
+
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
softmmu_ss.add(files('block-ram-registrar.c'))
system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
system_ss.add(files('block-ram-registrar.c'))
diff --git a/block/pbs.c b/block/pbs.c
new file mode 100644
index 0000000000..a2211e0f3b
@@ -349,40 +349,40 @@ index 0000000000..a2211e0f3b
+
+block_init(bdrv_pbs_init);
diff --git a/configure b/configure
index a62a3e6be9..1ac0feb46b 100755
index 133f4e3235..f5a830c1f3 100755
--- a/configure
+++ b/configure
@@ -288,6 +288,7 @@ linux_user=""
@@ -256,6 +256,7 @@ qemu_suffix="qemu"
softmmu="yes"
linux_user=""
bsd_user=""
pie=""
coroutine=""
+pbs_bdrv="yes"
plugins="$default_feature"
meson=""
ninja=""
@@ -873,6 +874,10 @@ for opt do
python=
@@ -809,6 +810,10 @@ for opt do
;;
--with-coroutine=*) coroutine="$optarg"
--enable-download) download="enabled"; git_submodules_action=update;
;;
+ --disable-pbs-bdrv) pbs_bdrv="no"
+ ;;
+ --enable-pbs-bdrv) pbs_bdrv="yes"
+ ;;
--with-git=*) git="$optarg"
;;
--with-git-submodules=*)
@@ -1049,6 +1054,7 @@ cat << EOF
debug-info debugging information
safe-stack SafeStack Stack Smash Protection. Depends on
clang/llvm and requires coroutine backend ucontext.
--enable-plugins) if test "$mingw32" = "yes"; then
error_exit "TCG plugins not currently supported on Windows platforms"
else
@@ -959,6 +964,7 @@ cat << EOF
bsd-user all BSD usermode emulation targets
pie Position Independent Executables
debug-tcg TCG debugging (default is disabled)
+ pbs-bdrv Proxmox backup server read-only block driver support
NOTE: The object files are built at the place where configure is launched
EOF
@@ -2386,6 +2392,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
if test "$modules" = "yes"; then
echo "CONFIG_MODULES=y" >> $config_host_mak
@@ -1744,6 +1750,9 @@ if test "$solaris" = "yes" ; then
fi
echo "SRC_PATH=$source_path" >> $config_host_mak
echo "TARGET_DIRS=$target_list" >> $config_host_mak
+if test "$pbs_bdrv" = "yes" ; then
+ echo "CONFIG_PBS_BDRV=y" >> $config_host_mak
+fi
@@ -390,10 +390,10 @@ index a62a3e6be9..1ac0feb46b 100755
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
diff --git a/meson.build b/meson.build
index 32ab849ce6..69afe3441b 100644
index c3330310d9..cbfc9a43fb 100644
--- a/meson.build
+++ b/meson.build
@@ -4041,7 +4041,7 @@ summary_info += {'bzip2 support': libbzip2}
@@ -4319,7 +4319,7 @@ summary_info += {'bzip2 support': libbzip2}
summary_info += {'lzfse support': liblzfse}
summary_info += {'zstd support': zstd}
summary_info += {'NUMA host support': numa}
@@ -403,10 +403,10 @@ index 32ab849ce6..69afe3441b 100644
summary_info += {'libdaxctl support': libdaxctl}
summary_info += {'libudev': libudev}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 985859ddee..d601fb4ab2 100644
index 1b8462a51b..d67a6d448a 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3304,6 +3304,7 @@
@@ -3396,6 +3396,7 @@
'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum',
'raw', 'rbd',
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
@@ -414,7 +414,7 @@ index 985859ddee..d601fb4ab2 100644
'ssh', 'throttle', 'vdi', 'vhdx',
{ 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
{ 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
@@ -3380,6 +3381,17 @@
@@ -3482,6 +3483,17 @@
{ 'struct': 'BlockdevOptionsNull',
'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
@@ -432,7 +432,7 @@ index 985859ddee..d601fb4ab2 100644
##
# @BlockdevOptionsNVMe:
#
@@ -4753,6 +4765,7 @@
@@ -4890,6 +4902,7 @@
'nfs': 'BlockdevOptionsNfs',
'null-aio': 'BlockdevOptionsNull',
'null-co': 'BlockdevOptionsNull',

View File

@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/meson.build b/meson.build
index 69afe3441b..b2e9b2aec7 100644
index cbfc9a43fb..8206270272 100644
--- a/meson.build
+++ b/meson.build
@@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
@@ -1779,6 +1779,7 @@ endif
has_gettid = cc.has_function('gettid')
libuuid = cc.find_library('uuid', required: true)
@@ -25,16 +25,16 @@ index 69afe3441b..b2e9b2aec7 100644
libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
# libselinux
@@ -3144,6 +3145,7 @@ if have_block
@@ -3406,6 +3407,7 @@ if have_block
# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
# os-win32.c does not
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
+ blockdev_ss.add(when: 'CONFIG_POSIX', if_true: libsystemd)
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
system_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
endif
diff --git a/os-posix.c b/os-posix.c
index 90ea71725f..33745a8c22 100644
index cfcb96533c..fb2ad87009 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -28,6 +28,8 @@
@@ -46,7 +46,7 @@ index 90ea71725f..33745a8c22 100644
/* Needed early for CONFIG_BSD etc. */
#include "net/slirp.h"
@@ -301,9 +303,10 @@ void os_setup_post(void)
@@ -310,9 +312,10 @@ void os_setup_post(void)
dup2(fd, 0);
dup2(fd, 1);

View File

@@ -26,7 +26,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
create mode 100644 migration/pbs-state.c
diff --git a/include/migration/misc.h b/include/migration/misc.h
index 8b49841016..78f63ca400 100644
index 7dcc0b5c2c..4c940b2475 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -77,4 +77,7 @@ bool migration_in_bg_snapshot(void);
@@ -38,25 +38,24 @@ index 8b49841016..78f63ca400 100644
+
#endif
diff --git a/migration/meson.build b/migration/meson.build
index a7824b5266..de6a271b58 100644
index 07f6057acc..343994d891 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -6,8 +6,10 @@ migration_files = files(
@@ -7,7 +7,9 @@ migration_files = files(
'vmstate.c',
'qemu-file.c',
'yank_functions.c',
+ 'pbs-state.c',
)
softmmu_ss.add(migration_files)
+softmmu_ss.add(libproxmox_backup_qemu)
+system_ss.add(libproxmox_backup_qemu)
softmmu_ss.add(files(
system_ss.add(files(
'block-dirty-bitmap.c',
diff --git a/migration/migration.c b/migration/migration.c
index 99f86bd6c2..db229e72c9 100644
index 7a4c8beb5d..0a955a2a18 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -245,6 +245,7 @@ void migration_object_init(void)
@@ -162,6 +162,7 @@ void migration_object_init(void)
blk_mig_init();
ram_mig_init();
dirty_bitmap_mig_init();
@@ -175,7 +174,7 @@ index 0000000000..887e998b9e
+ NULL);
+}
diff --git a/pve-backup.c b/pve-backup.c
index 8ff0d88297..53f5c5e311 100644
index d84d807654..9c8b88d075 100644
--- a/pve-backup.c
+++ b/pve-backup.c
@@ -1060,6 +1060,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
@@ -187,10 +186,10 @@ index 8ff0d88297..53f5c5e311 100644
ret->pbs_masterkey = true;
ret->backup_max_workers = true;
diff --git a/qapi/block-core.json b/qapi/block-core.json
index d601fb4ab2..16be1e02ec 100644
index d67a6d448a..09de550c95 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -987,6 +987,11 @@
@@ -991,6 +991,11 @@
# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
# safely be set for savevm-async.
#
@@ -202,7 +201,7 @@ index d601fb4ab2..16be1e02ec 100644
# @pbs-masterkey: True if the QMP backup call supports the 'master_keyfile'
# parameter.
#
@@ -997,6 +1002,7 @@
@@ -1001,6 +1006,7 @@
'data': { 'pbs-dirty-bitmap': 'bool',
'query-bitmap-info': 'bool',
'pbs-dirty-bitmap-savevm': 'bool',

View File

@@ -19,10 +19,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 7eaf498439..509f3df0a6 100644
index e1ae3b7316..285dd1d148 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -539,7 +539,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
@@ -540,7 +540,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, &local_err)) {
error_report_err(local_err);

View File

@@ -21,10 +21,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 30 insertions(+)
diff --git a/block/iscsi.c b/block/iscsi.c
index 9fc0bed90b..1d40933165 100644
index 34f97ab646..398782963d 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1392,12 +1392,42 @@ static char *get_initiator_name(QemuOpts *opts)
@@ -1391,12 +1391,42 @@ static char *get_initiator_name(QemuOpts *opts)
const char *name;
char *iscsi_name;
UuidInfo *uuid_info;

View File

@@ -11,7 +11,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/stream.c b/block/stream.c
index 7f9e1ecdbb..6a29d80398 100644
index e522bbdec5..afed72db55 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -27,7 +27,7 @@ enum {

View File

@@ -17,17 +17,17 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 4 insertions(+)
diff --git a/block/io.c b/block/io.c
index 2e267a85ab..449a44bf20 100644
index 83d1b1dfdc..24a3c84c93 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1576,6 +1576,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
{
int ret;
@@ -1710,6 +1710,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
int sliced_niov;
size_t sliced_head, sliced_tail;
+ if (!qiov) {
+ return 0;
+ }
+
bdrv_check_qiov_request(*offset, *bytes, *qiov, *qiov_offset, &error_abort);
if (!bdrv_init_padding(bs, *offset, *bytes, pad)) {
/* Should have been checked by the caller already */
ret = bdrv_check_request32(*offset, *bytes, *qiov, *qiov_offset);
if (ret < 0) {

View File

@@ -393,7 +393,7 @@ index 0000000000..b75d7c6460
+
+block_init(bdrv_alloc_track_init);
diff --git a/block/meson.build b/block/meson.build
index eece0d5743..8a68162cc0 100644
index becc99ac4e..0a69836593 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -2,6 +2,7 @@ block_ss.add(genh)

View File

@@ -52,7 +52,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
5 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/include/migration/register.h b/include/migration/register.h
index a8dfd8fefd..fa9b0b0f10 100644
index 90914f32f5..c728fd9120 100644
--- a/include/migration/register.h
+++ b/include/migration/register.h
@@ -43,9 +43,9 @@ typedef struct SaveVMHandlers {
@@ -67,10 +67,10 @@ index a8dfd8fefd..fa9b0b0f10 100644
* must_precopy:
* - must be migrated in precopy or in stopped state
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 509f3df0a6..42dc4a8d61 100644
index 285dd1d148..f7ee5a74d9 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -1220,10 +1220,17 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
@@ -1219,10 +1219,17 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
{
DBMSaveState *s = &((DBMState *)opaque)->save;
SaveBitmapState *dbms = NULL;
@@ -90,7 +90,7 @@ index 509f3df0a6..42dc4a8d61 100644
return -1;
}
@@ -1231,7 +1238,9 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
@@ -1230,7 +1237,9 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
send_bitmap_start(f, s, dbms);
}
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
@@ -102,10 +102,10 @@ index 509f3df0a6..42dc4a8d61 100644
}
diff --git a/migration/block.c b/migration/block.c
index b2497bbd32..c9d55be642 100644
index 86c2256a2b..8423e0c9f9 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -716,21 +716,30 @@ static void block_migration_cleanup(void *opaque)
@@ -725,21 +725,30 @@ static void block_migration_cleanup(void *opaque)
static int block_save_setup(QEMUFile *f, void *opaque)
{
int ret;
@@ -140,10 +140,10 @@ index b2497bbd32..c9d55be642 100644
if (ret) {
return ret;
diff --git a/migration/ram.c b/migration/ram.c
index 79d881f735..0ecbbc3202 100644
index 6e1514f69f..6a1aec7031 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3117,8 +3117,16 @@ static void migration_bitmap_clear_discarded_pages(RAMState *rs)
@@ -2896,8 +2896,16 @@ static void migration_bitmap_clear_discarded_pages(RAMState *rs)
static void ram_init_bitmaps(RAMState *rs)
{
@@ -162,7 +162,7 @@ index 79d881f735..0ecbbc3202 100644
qemu_mutex_lock_ramlist();
WITH_RCU_READ_LOCK_GUARD() {
@@ -3130,7 +3138,9 @@ static void ram_init_bitmaps(RAMState *rs)
@@ -2909,7 +2917,9 @@ static void ram_init_bitmaps(RAMState *rs)
}
}
qemu_mutex_unlock_ramlist();
@@ -174,11 +174,11 @@ index 79d881f735..0ecbbc3202 100644
/*
* After an eventual first bitmap sync, fixup the initial bitmap
diff --git a/migration/savevm.c b/migration/savevm.c
index aa54a67fda..fc6a82a555 100644
index d60c4f487a..3c015722f7 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1621,10 +1621,8 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
memset(&compression_counters, 0, sizeof(compression_counters));
@@ -1625,10 +1625,8 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
reset_vfio_bytes_transferred();
ms->to_dst_file = f;
- qemu_mutex_unlock_iothread();

View File

@@ -13,10 +13,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 2 deletions(-)
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
index b97f2c4f14..87ea0573d3 100644
index 80624fada8..b1d85a4b41 100644
--- a/migration/savevm-async.c
+++ b/migration/savevm-async.c
@@ -403,10 +403,8 @@ void qmp_savevm_start(const char *statefile, Error **errp)
@@ -401,10 +401,8 @@ void qmp_savevm_start(const char *statefile, Error **errp)
snap_state.state = SAVE_STATE_ACTIVE;
snap_state.finalize_bh = qemu_bh_new(process_savevm_finalize, &snap_state);
snap_state.co = qemu_coroutine_create(&process_savevm_co, NULL);

17
debian/patches/series vendored
View File

@@ -1,14 +1,14 @@
extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
extra/0002-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
extra/0003-ide-avoid-potential-deadlock-when-draining-during-tr.patch
extra/0004-ui-return-NULL-when-getting-cursor-without-a-console.patch
extra/0005-memory-prevent-dma-reentracy-issues.patch
extra/0006-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
extra/0007-bcm2835_property-disable-reentrancy-detection-for-io.patch
extra/0008-raven-disable-reentrancy-detection-for-iomem.patch
extra/0009-apic-disable-reentrancy-detection-for-apic-msi.patch
extra/0010-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch
extra/0011-vhost-fix-the-fd-leak.patch
extra/0004-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch
extra/0005-Revert-Revert-graph-lock-Disable-locking-for-now.patch
extra/0006-migration-states-workaround-snapshot-performance-reg.patch
extra/0007-Revert-x86-acpi-workaround-Windows-not-handling-name.patch
extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch
extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch
extra/0010-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch
extra/0011-virtio-Re-enable-notifications-after-drain.patch
bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
@@ -60,3 +60,4 @@ pve/0042-Revert-block-rbd-implement-bdrv_co_block_status.patch
pve/0043-alloc-track-fix-deadlock-during-drop.patch
pve/0044-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
pve/0045-savevm-async-don-t-hold-BQL-during-setup.patch
pve-qemu-8.1-vitastor.patch

2
debian/rules vendored
View File

@@ -38,7 +38,7 @@ endif
# guest-agent is only required for guest systems
./configure \
--with-git-submodules=ignore \
--disable-download \
--docdir=/usr/share/doc/pve-qemu-kvm \
--localstatedir=/var \
--prefix=/usr \

View File

@@ -1,27 +0,0 @@
Copyright (c) Individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of PyCA Cryptography nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -1,114 +0,0 @@
Key code / scan code / key symbol mapping database
==================================================
This module provides a database that maps between different
key code / scan code / key symbol sets:
- Linux evdev
- OS-X
- AT Set 1
- AT Set 2
- AT Set 3
- XT
- Linux XT KBD driver
- USB HID
- Win32
- XWin XT
- XKBD XT
- Xorg Evdev
- Xorg KBD
- Xorg OS-X
- XOrg Cygwin
- RFB
Licensing
---------
The contents of this package are dual licensed under the terms of:
- GNU General Public License (version 2 or later)
- 3-clause BSD License
The output files generated by keymap-gen may be distributed & used under
the terms of either of the above licenses.
Data formats
------------
The following output formats are possible
- Code map
An array mapping between key code sets values
Indexes in the array are values from the source code set.
Entries in the array are values from the target code set
- Code table
An array listing all values in a key code set
Indexes in the array are simply a numeric counter
Entries in the array are values from the key code set
The size of the array matches the total number of entries in
the keycode database.
- Name map
An array mapping between key code sets values and names
Indexes in the array are values from the source code set
Entries in the array are names from the target code set
- Name table
An array listing all names in a key code set
Indexes in the array are simply a numeric counter
Entries in the array are values from the key code set
The size of the array matches the total number of entries in
the keycode database.
Output languages
----------------
The tool is capable of generating data tables for the following
programming languages / environments
- Standard C
- GLib2 (standard C, but with GLib2 data types)
- Python
- Perl
Usage
-----
Map values from AT Set 1 to USB HID, generating tables for the
C programming language
$ keymap-gen --lang stdc code-map data/keymaps.csv atset1 usb
Generate a tables of names for Linux key codes, OS-X key codes,
in python - equivalent array indexes map between the two sets.
A variable name override is used
$ keymap-gen --varname linux_keycodes --lang stdc \
code-table data/keymaps.csv linux
$ keymap-gen --varname osx_keycodes --lang stdc \
code-table data/keymaps.csv os-x
Generate a mapping from XOrg XWin values to Win32 names
$ keymap-gen --lang perl name-map data/keymaps.csv xorgxwin win32
Generate a table of names for Linux key codes in Perl
$ keymap-gen --lang perl name-table data/keymaps.csv linux

View File

@@ -1,89 +0,0 @@
This directory contains the raw data for mapping between different
keyboard codes. Naming if often based on the US keyboard layout, but
does not indicate the symbol actually generated by the key.
The columns currently in this data set are:
Linux
-----
Name and value of the hardware independent keycodes used by the linux
kernel and exposed through the input subsystem.
References: linux/input.h
macOS
-----
Low level key codes as exposed by Mac OS X/macOS.
References: Carbon/HIToolbox/Events.h
PC scan code sets
-----------------
Scan codes for the three orignal PC keyboard generations:
Set 1: XT
Set 2: AT
Set 3: PS/2
The sets include codes for modern keys as well and not just the keys
present on those original keyboards.
References: linux/drivers/input/keyboard/atkbd.c
USB HID
-------
Codes as specified by the HID profile in USB.
References: linux/drivers/hid/usbhid/usbkbd.c
Windows Virtual-key codes
-------------------------
The low level, hardware independent "VKEYs" exposed by Windows.
References: mingw32/winuser.h
XWin XT
-------
X11 keycodes generated by the XWin server. Based on the XT scan code
set.
References: xorg-server/hw/xwin/{winkeybd.c,winkeynames.h}
Xfree86 KBD XT
--------------
X11 keycodes generated by the Xfree86 keyboard drivers. Based on the XT
scan code set.
References: xf86-input-keyboard/src/at_scancode.c
X11 keysyms
-----------
Corresponding X11 keysym value(s) for a US keyboard layout.
WARNING: These columns represent symbols, not physical keys, and should
be used with extreme care.
References: http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
HTML KeyboardEvent.code
-----------------------
Key codes seen in the KeyboardEvent.code attribute as part of the
UI Events specification.
References: https://www.w3.org/TR/uievents-code/
XKEYBOARD key names
-------------------
Hardware independent key names as used in the XKEYBOARD extension.
References: /usr/share/X11/xkb/keycodes/

View File

@@ -1,539 +0,0 @@
"Linux Name","Linux Keycode","OS-X Name","OS-X Keycode","AT set1 keycode","AT set2 keycode","AT set3 keycode","USB Keycodes","Win32 Name","Win32 Keycode","Xwin XT","Xfree86 KBD XT","X11 keysym name","X11 keysym","HTML code","XKB key name","QEMU QKeyCode","Sun KBD","Apple ADB"
KEY_RESERVED,0,,0xff,,,,,,,,,,,,,unmapped,,0xff
KEY_ESC,1,Escape,0x35,0x01,0x76,0x08,41,VK_ESCAPE,0x1b,1,1,XK_Escape,0xff1b,Escape,ESC,esc,0x1d,0x35
KEY_1,2,ANSI_1,0x12,0x02,0x16,0x16,30,VK_1,0x31,2,2,XK_1,0x0031,Digit1,AE01,1,0x1e,0x12
KEY_1,2,ANSI_1,0x12,0x02,0x16,0x16,30,VK_1,0x31,2,2,XK_exclam,0x0021,Digit1,AE01,1,0x1e,0x12
KEY_2,3,ANSI_2,0x13,0x03,0x1e,0x1e,31,VK_2,0x32,3,3,XK_2,0x0032,Digit2,AE02,2,0x1f,0x13
KEY_2,3,ANSI_2,0x13,0x03,0x1e,0x1e,31,VK_2,0x32,3,3,XK_at,0x0040,Digit2,AE02,2,0x1f,0x13
KEY_3,4,ANSI_3,0x14,0x04,0x26,0x26,32,VK_3,0x33,4,4,XK_3,0x0033,Digit3,AE03,3,0x20,0x14
KEY_3,4,ANSI_3,0x14,0x04,0x26,0x26,32,VK_3,0x33,4,4,XK_numbersign,0x0023,Digit3,AE03,3,0x20,0x14
KEY_4,5,ANSI_4,0x15,0x05,0x25,0x25,33,VK_4,0x34,5,5,XK_4,0x0034,Digit4,AE04,4,0x21,0x15
KEY_4,5,ANSI_4,0x15,0x05,0x25,0x25,33,VK_4,0x34,5,5,XK_dollar,0x0024,Digit4,AE04,4,0x21,0x15
KEY_5,6,ANSI_5,0x17,0x06,0x2e,0x2e,34,VK_5,0x35,6,6,XK_5,0x0035,Digit5,AE05,5,0x22,0x17
KEY_5,6,ANSI_5,0x17,0x06,0x2e,0x2e,34,VK_5,0x35,6,6,XK_percent,0x0025,Digit5,AE05,5,0x22,0x17
KEY_6,7,ANSI_6,0x16,0x07,0x36,0x36,35,VK_6,0x36,7,7,XK_6,0x0036,Digit6,AE06,6,0x23,0x16
KEY_6,7,ANSI_6,0x16,0x07,0x36,0x36,35,VK_6,0x36,7,7,XK_asciicircum,0x005e,Digit6,AE06,6,0x23,0x16
KEY_7,8,ANSI_7,0x1a,0x08,0x3d,0x3d,36,VK_7,0x37,8,8,XK_7,0x0037,Digit7,AE07,7,0x24,0x1a
KEY_7,8,ANSI_7,0x1a,0x08,0x3d,0x3d,36,VK_7,0x37,8,8,XK_ampersand,0x0026,Digit7,AE07,7,0x24,0x1a
KEY_8,9,ANSI_8,0x1c,0x09,0x3e,0x3e,37,VK_8,0x38,9,9,XK_8,0x0038,Digit8,AE08,8,0x25,0x1c
KEY_8,9,ANSI_8,0x1c,0x09,0x3e,0x3e,37,VK_8,0x38,9,9,XK_asterisk,0x002a,Digit8,AE08,8,0x25,0x1c
KEY_9,10,ANSI_9,0x19,0x0a,0x46,0x46,38,VK_9,0x39,10,10,XK_9,0x0039,Digit9,AE09,9,0x26,0x19
KEY_9,10,ANSI_9,0x19,0x0a,0x46,0x46,38,VK_9,0x39,10,10,XK_parenleft,0x0028,Digit9,AE09,9,0x26,0x19
KEY_0,11,ANSI_0,0x1d,0x0b,0x45,0x45,39,VK_0,0x30,11,11,XK_0,0x0030,Digit0,AE10,0,0x27,0x1d
KEY_0,11,ANSI_0,0x1d,0x0b,0x45,0x45,39,VK_0,0x30,11,11,XK_parenright,0x0029,Digit0,AE10,0,0x27,0x1d
KEY_MINUS,12,ANSI_Minus,0x1b,0x0c,0x4e,0x4e,45,VK_OEM_MINUS,0xbd,12,12,XK_minus,0x002d,Minus,AE11,minus,0x28,0x1b
KEY_MINUS,12,ANSI_Minus,0x1b,0x0c,0x4e,0x4e,45,VK_OEM_MINUS,0xbd,12,12,XK_underscore,0x005f,Minus,AE11,minus,0x28,0x1b
KEY_EQUAL,13,ANSI_Equal,0x18,0x0d,0x55,0x55,46,VK_OEM_PLUS,0xbb,13,13,XK_equal,0x003d,Equal,AE12,equal,0x29,0x18
KEY_EQUAL,13,ANSI_Equal,0x18,0x0d,0x55,0x55,46,VK_OEM_PLUS,0xbb,13,13,XK_plus,0x002b,Equal,AE12,equal,0x29,0x18
KEY_BACKSPACE,14,Delete,0x33,0x0e,0x66,0x66,42,VK_BACK,0x08,14,14,XK_BackSpace,0xff08,Backspace,BKSP,backspace,0x2b,0x33
KEY_TAB,15,Tab,0x30,0x0f,0x0d,0x0d,43,VK_TAB,0x09,15,15,XK_Tab,0xff09,Tab,TAB,tab,0x35,0x30
KEY_Q,16,ANSI_Q,0xc,0x10,0x15,0x15,20,VK_Q,0x51,16,16,XK_Q,0x0051,KeyQ,AD01,q,0x36,0xc
KEY_Q,16,ANSI_Q,0xc,0x10,0x15,0x15,20,VK_Q,0x51,16,16,XK_q,0x0071,KeyQ,AD01,q,0x36,0xc
KEY_W,17,ANSI_W,0xd,0x11,0x1d,0x1d,26,VK_W,0x57,17,17,XK_W,0x0057,KeyW,AD02,w,0x37,0xd
KEY_W,17,ANSI_W,0xd,0x11,0x1d,0x1d,26,VK_W,0x57,17,17,XK_w,0x0077,KeyW,AD02,w,0x37,0xd
KEY_E,18,ANSI_E,0xe,0x12,0x24,0x24,8,VK_E,0x45,18,18,XK_E,0x0045,KeyE,AD03,e,0x38,0xe
KEY_E,18,ANSI_E,0xe,0x12,0x24,0x24,8,VK_E,0x45,18,18,XK_e,0x0065,KeyE,AD03,e,0x38,0xe
KEY_R,19,ANSI_R,0xf,0x13,0x2d,0x2d,21,VK_R,0x52,19,19,XK_R,0x0052,KeyR,AD04,r,0x39,0xf
KEY_R,19,ANSI_R,0xf,0x13,0x2d,0x2d,21,VK_R,0x52,19,19,XK_r,0x0072,KeyR,AD04,r,0x39,0xf
KEY_T,20,ANSI_T,0x11,0x14,0x2c,0x2c,23,VK_T,0x54,20,20,XK_T,0x0054,KeyT,AD05,t,0x3a,0x11
KEY_T,20,ANSI_T,0x11,0x14,0x2c,0x2c,23,VK_T,0x54,20,20,XK_t,0x0074,KeyT,AD05,t,0x3a,0x11
KEY_Y,21,ANSI_Y,0x10,0x15,0x35,0x35,28,VK_Y,0x59,21,21,XK_Y,0x0059,KeyY,AD06,y,0x3b,0x10
KEY_Y,21,ANSI_Y,0x10,0x15,0x35,0x35,28,VK_Y,0x59,21,21,XK_y,0x0079,KeyY,AD06,y,0x3b,0x10
KEY_U,22,ANSI_U,0x20,0x16,0x3c,0x3c,24,VK_U,0x55,22,22,XK_U,0x0055,KeyU,AD07,u,0x3c,0x20
KEY_U,22,ANSI_U,0x20,0x16,0x3c,0x3c,24,VK_U,0x55,22,22,XK_u,0x0075,KeyU,AD07,u,0x3c,0x20
KEY_I,23,ANSI_I,0x22,0x17,0x43,0x43,12,VK_I,0x49,23,23,XK_I,0x0049,KeyI,AD08,i,0x3d,0x22
KEY_I,23,ANSI_I,0x22,0x17,0x43,0x43,12,VK_I,0x49,23,23,XK_i,0x0069,KeyI,AD08,i,0x3d,0x22
KEY_O,24,ANSI_O,0x1f,0x18,0x44,0x44,18,VK_O,0x4f,24,24,XK_O,0x004f,KeyO,AD09,o,0x3e,0x1f
KEY_O,24,ANSI_O,0x1f,0x18,0x44,0x44,18,VK_O,0x4f,24,24,XK_o,0x006f,KeyO,AD09,o,0x3e,0x1f
KEY_P,25,ANSI_P,0x23,0x19,0x4d,0x4d,19,VK_P,0x50,25,25,XK_P,0x0050,KeyP,AD10,p,0x3f,0x23
KEY_P,25,ANSI_P,0x23,0x19,0x4d,0x4d,19,VK_P,0x50,25,25,XK_p,0x0070,KeyP,AD10,p,0x3f,0x23
KEY_LEFTBRACE,26,ANSI_LeftBracket,0x21,0x1a,0x54,0x54,47,VK_OEM_4,0xdb,26,26,XK_bracketleft,0x005b,BracketLeft,AD11,bracket_left,0x40,0x21
KEY_LEFTBRACE,26,ANSI_LeftBracket,0x21,0x1a,0x54,0x54,47,VK_OEM_4,0xdb,26,26,XK_braceleft,0x007b,BracketLeft,AD11,bracket_left,0x40,0x21
KEY_RIGHTBRACE,27,ANSI_RightBracket,0x1e,0x1b,0x5b,0x5b,48,VK_OEM_6,0xdd,27,27,XK_bracketright,0x005d,BracketRight,AD12,bracket_right,0x41,0x1e
KEY_RIGHTBRACE,27,ANSI_RightBracket,0x1e,0x1b,0x5b,0x5b,48,VK_OEM_6,0xdd,27,27,XK_braceright,0x007d,BracketRight,AD12,bracket_right,0x41,0x1e
KEY_ENTER,28,Return,0x24,0x1c,0x5a,0x5a,40,VK_RETURN,0x0d,28,28,XK_Return,0xff0d,Enter,RTRN,ret,0x59,0x24
KEY_LEFTCTRL,29,Control,0x3b,0x1d,0x14,0x11,224,VK_LCONTROL,0xa2,29,29,XK_Control_L,0xffe3,ControlLeft,LCTL,ctrl,0x4c,0x36
KEY_LEFTCTRL,29,Control,0x3b,0x1d,0x14,0x11,224,VK_CONTROL,0x11,29,29,XK_Control_L,0xffe3,ControlLeft,LCTL,ctrl,0x4c,0x36
KEY_A,30,ANSI_A,0x0,0x1e,0x1c,0x1c,4,VK_A,0x41,30,30,XK_A,0x0041,KeyA,AC01,a,0x4d,0x0
KEY_A,30,ANSI_A,0x0,0x1e,0x1c,0x1c,4,VK_A,0x41,30,30,XK_a,0x0061,KeyA,AC01,a,0x4d,0x0
KEY_S,31,ANSI_S,0x1,0x1f,0x1b,0x1b,22,VK_S,0x53,31,31,XK_S,0x0053,KeyS,AC02,s,0x4e,0x1
KEY_S,31,ANSI_S,0x1,0x1f,0x1b,0x1b,22,VK_S,0x53,31,31,XK_s,0x0073,KeyS,AC02,s,0x4e,0x1
KEY_D,32,ANSI_D,0x2,0x20,0x23,0x23,7,VK_D,0x44,32,32,XK_D,0x0044,KeyD,AC03,d,0x4f,0x2
KEY_D,32,ANSI_D,0x2,0x20,0x23,0x23,7,VK_D,0x44,32,32,XK_d,0x0064,KeyD,AC03,d,0x4f,0x2
KEY_F,33,ANSI_F,0x3,0x21,0x2b,0x2b,9,VK_F,0x46,33,33,XK_F,0x0046,KeyF,AC04,f,0x50,0x3
KEY_F,33,ANSI_F,0x3,0x21,0x2b,0x2b,9,VK_F,0x46,33,33,XK_f,0x0066,KeyF,AC04,f,0x50,0x3
KEY_G,34,ANSI_G,0x5,0x22,0x34,0x34,10,VK_G,0x47,34,34,XK_G,0x0047,KeyG,AC05,g,0x51,0x5
KEY_G,34,ANSI_G,0x5,0x22,0x34,0x34,10,VK_G,0x47,34,34,XK_g,0x0067,KeyG,AC05,g,0x51,0x5
KEY_H,35,ANSI_H,0x4,0x23,0x33,0x33,11,VK_H,0x48,35,35,XK_H,0x0048,KeyH,AC06,h,0x52,0x4
KEY_H,35,ANSI_H,0x4,0x23,0x33,0x33,11,VK_H,0x48,35,35,XK_h,0x0068,KeyH,AC06,h,0x52,0x4
KEY_J,36,ANSI_J,0x26,0x24,0x3b,0x3b,13,VK_J,0x4a,36,36,XK_J,0x004a,KeyJ,AC07,j,0x53,0x26
KEY_J,36,ANSI_J,0x26,0x24,0x3b,0x3b,13,VK_J,0x4a,36,36,XK_j,0x006a,KeyJ,AC07,j,0x53,0x26
KEY_K,37,ANSI_K,0x28,0x25,0x42,0x42,14,VK_K,0x4b,37,37,XK_K,0x004b,KeyK,AC08,k,0x54,0x28
KEY_K,37,ANSI_K,0x28,0x25,0x42,0x42,14,VK_K,0x4b,37,37,XK_k,0x006b,KeyK,AC08,k,0x54,0x28
KEY_L,38,ANSI_L,0x25,0x26,0x4b,0x4b,15,VK_L,0x4c,38,38,XK_L,0x004c,KeyL,AC09,l,0x55,0x25
KEY_L,38,ANSI_L,0x25,0x26,0x4b,0x4b,15,VK_L,0x4c,38,38,XK_l,0x006c,KeyL,AC09,l,0x55,0x25
KEY_SEMICOLON,39,ANSI_Semicolon,0x29,0x27,0x4c,0x4c,51,VK_OEM_1,0xba,39,39,XK_semicolon,0x003b,Semicolon,AC10,semicolon,0x56,0x29
KEY_SEMICOLON,39,ANSI_Semicolon,0x29,0x27,0x4c,0x4c,51,VK_OEM_1,0xba,39,39,XK_colon,0x003a,Semicolon,AC10,semicolon,0x56,0x29
KEY_APOSTROPHE,40,ANSI_Quote,0x27,0x28,0x52,0x52,52,VK_OEM_7,0xde,40,40,XK_apostrophe,0x0027,Quote,AC11,apostrophe,0x57,0x27
KEY_APOSTROPHE,40,ANSI_Quote,0x27,0x28,0x52,0x52,52,VK_OEM_7,0xde,40,40,XK_quotedbl,0x0022,Quote,AC11,apostrophe,0x57,0x27
KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_grave,0x0060,Backquote,TLDE,grave_accent,0x2a,0x32
KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_grave,0x0060,Backquote,AB00,grave_accent,0x2a,0x32
KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_asciitilde,0x007e,Backquote,TLDE,grave_accent,0x2a,0x32
KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_asciitilde,0x007e,Backquote,AB00,grave_accent,0x2a,0x32
KEY_SHIFT,42,Shift,0x38,0x2a,0x12,0x12,225,VK_SHIFT,0x10,42,42,XK_Shift_L,0xffe1,ShiftLeft,LFSH,shift,0x63,0x38
KEY_LEFTSHIFT,42,Shift,0x38,0x2a,0x12,0x12,225,VK_LSHIFT,0xa0,42,42,XK_Shift_L,0xffe1,ShiftLeft,LFSH,shift,0x63,0x38
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,BKSL,backslash,0x58,0x2a
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,AC12,backslash,0x58,0x2a
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,BKSL,backslash,0x58,0x2a
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,AC12,backslash,0x58,0x2a
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,BKSL,backslash,0x58,0x2a
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,AC12,backslash,0x58,0x2a
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,BKSL,backslash,0x58,0x2a
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,AC12,backslash,0x58,0x2a
KEY_Z,44,ANSI_Z,0x6,0x2c,0x1a,0x1a,29,VK_Z,0x5a,44,44,XK_Z,0x005a,KeyZ,AB01,z,0x64,0x6
KEY_Z,44,ANSI_Z,0x6,0x2c,0x1a,0x1a,29,VK_Z,0x5a,44,44,XK_z,0x007a,KeyZ,AB01,z,0x64,0x6
KEY_X,45,ANSI_X,0x7,0x2d,0x22,0x22,27,VK_X,0x58,45,45,XK_X,0x0058,KeyX,AB02,x,0x65,0x7
KEY_X,45,ANSI_X,0x7,0x2d,0x22,0x22,27,VK_X,0x58,45,45,XK_x,0x0078,KeyX,AB02,x,0x65,0x7
KEY_C,46,ANSI_C,0x8,0x2e,0x21,0x21,6,VK_C,0x43,46,46,XK_C,0x0043,KeyC,AB03,c,0x66,0x8
KEY_C,46,ANSI_C,0x8,0x2e,0x21,0x21,6,VK_C,0x43,46,46,XK_c,0x0063,KeyC,AB03,c,0x66,0x8
KEY_V,47,ANSI_V,0x9,0x2f,0x2a,0x2a,25,VK_V,0x56,47,47,XK_V,0x0056,KeyV,AB04,v,0x67,0x9
KEY_V,47,ANSI_V,0x9,0x2f,0x2a,0x2a,25,VK_V,0x56,47,47,XK_v,0x0076,KeyV,AB04,v,0x67,0x9
KEY_B,48,ANSI_B,0xb,0x30,0x32,0x32,5,VK_B,0x42,48,48,XK_B,0x0042,KeyB,AB05,b,0x68,0xb
KEY_B,48,ANSI_B,0xb,0x30,0x32,0x32,5,VK_B,0x42,48,48,XK_b,0x0062,KeyB,AB05,b,0x68,0xb
KEY_N,49,ANSI_N,0x2d,0x31,0x31,0x31,17,VK_N,0x4e,49,49,XK_N,0x004e,KeyN,AB06,n,0x69,0x2d
KEY_N,49,ANSI_N,0x2d,0x31,0x31,0x31,17,VK_N,0x4e,49,49,XK_n,0x006e,KeyN,AB06,n,0x69,0x2d
KEY_M,50,ANSI_M,0x2e,0x32,0x3a,0x3a,16,VK_M,0x4d,50,50,XK_M,0x004d,KeyM,AB07,m,0x6a,0x2e
KEY_M,50,ANSI_M,0x2e,0x32,0x3a,0x3a,16,VK_M,0x4d,50,50,XK_m,0x006d,KeyM,AB07,m,0x6a,0x2e
KEY_COMMA,51,ANSI_Comma,0x2b,0x33,0x41,0x41,54,VK_OEM_COMMA,0xbc,51,51,XK_comma,0x002c,Comma,AB08,comma,0x6b,0x2b
KEY_COMMA,51,ANSI_Comma,0x2b,0x33,0x41,0x41,54,VK_OEM_COMMA,0xbc,51,51,XK_less,0x003c,Comma,AB08,comma,0x6b,0x2b
KEY_DOT,52,ANSI_Period,0x2f,0x34,0x49,0x49,55,VK_OEM_PERIOD,0xbe,52,52,XK_period,0x002e,Period,AB09,dot,0x6c,0x2f
KEY_DOT,52,ANSI_Period,0x2f,0x34,0x49,0x49,55,VK_OEM_PERIOD,0xbe,52,52,XK_greater,0x003e,Period,AB09,dot,0x6c,0x2f
KEY_SLASH,53,ANSI_Slash,0x2c,0x35,0x4a,0x4a,56,VK_OEM_2,0xbf,53,53,XK_slash,0x002f,Slash,AB10,slash,0x6d,0x2c
KEY_SLASH,53,ANSI_Slash,0x2c,0x35,0x4a,0x4a,56,VK_OEM_2,0xbf,53,53,XK_question,0x003f,Slash,AB10,slash,0x6d,0x2c
KEY_RIGHTSHIFT,54,RightShift,0x3c,0x36,0x59,0x59,229,VK_RSHIFT,0xa1,54,54,XK_Shift_R,0xffe2,ShiftRight,RTSH,shift_r,0x6e,0x7b
KEY_KPASTERISK,55,ANSI_KeypadMultiply,0x43,0x37,0x7c,0x7e,85,VK_MULTIPLY,0x6a,55,55,XK_multiply,0x00d7,NumpadMultiply,KPMU,asterisk,0x2f,0x43
KEY_KPASTERISK,55,ANSI_KeypadMultiply,0x43,0x37,0x7c,0x7e,85,VK_MULTIPLY,0x6a,55,55,XK_multiply,0x00d7,NumpadMultiply,KPMU,kp_multiply,0x2f,0x43
KEY_LEFTALT,56,Option,0x3a,0x38,0x11,0x19,226,VK_LMENU,0xa4,56,56,XK_Alt_L,0xffe9,AltLeft,LALT,alt,0x13,0x3a
KEY_LEFTALT,56,Option,0x3a,0x38,0x11,0x19,226,VK_MENU,0x12,56,56,XK_Alt_L,0xffe9,AltLeft,LALT,alt,0x13,0x3a
KEY_SPACE,57,Space,0x31,0x39,0x29,0x29,44,VK_SPACE,0x20,57,57,XK_space,0x0020,Space,SPCE,spc,0x79,0x31
KEY_CAPSLOCK,58,CapsLock,0x39,0x3a,0x58,0x14,57,VK_CAPITAL,0x14,58,58,XK_Caps_Lock,0xffe5,CapsLock,CAPS,caps_lock,0x77,0x39
KEY_F1,59,F1,0x7a,0x3b,0x05,0x07,58,VK_F1,0x70,59,59,XK_F1,0xffbe,F1,FK01,f1,0x05,0x7a
KEY_F2,60,F2,0x78,0x3c,0x06,0x0f,59,VK_F2,0x71,60,60,XK_F2,0xffbf,F2,FK02,f2,0x06,0x78
KEY_F3,61,F3,0x63,0x3d,0x04,0x17,60,VK_F3,0x72,61,61,XK_F3,0xffc0,F3,FK03,f3,0x08,0x63
KEY_F4,62,F4,0x76,0x3e,0x0c,0x1f,61,VK_F4,0x73,62,62,XK_F4,0xffc1,F4,FK04,f4,0x0a,0x76
KEY_F5,63,F5,0x60,0x3f,0x03,0x27,62,VK_F5,0x74,63,63,XK_F5,0xffc2,F5,FK05,f5,0x0c,0x60
KEY_F6,64,F6,0x61,0x40,0x0b,0x2f,63,VK_F6,0x75,64,64,XK_F6,0xffc3,F6,FK06,f6,0x0e,0x61
KEY_F7,65,F7,0x62,0x41,0x83,0x37,64,VK_F7,0x76,65,65,XK_F7,0xffc4,F7,FK07,f7,0x10,0x62
KEY_F8,66,F8,0x64,0x42,0x0a,0x3f,65,VK_F8,0x77,66,66,XK_F8,0xffc5,F8,FK08,f8,0x11,0x64
KEY_F9,67,F9,0x65,0x43,0x01,0x47,66,VK_F9,0x78,67,67,XK_F9,0xffc6,F9,FK09,f9,0x12,0x65
KEY_F10,68,F10,0x6d,0x44,0x09,0x4f,67,VK_F10,0x79,68,68,XK_F10,0xffc7,F10,FK10,f10,0x07,0x6d
KEY_NUMLOCK,69,ANSI_KeypadClear,0x47,0x45,0x77,0x76,83,VK_NUMLOCK,0x90,69,69,XK_Num_Lock,0xff7f,NumLock,NMLK,num_lock,0x62,0x47
KEY_SCROLLLOCK,70,,,0x46,0x7e,0x5f,71,VK_SCROLL,0x91,70,70,XK_Scroll_Lock,0xff14,ScrollLock,SCLK,scroll_lock,0x17,0x6b
KEY_KP7,71,ANSI_Keypad7,0x59,0x47,0x6c,0x6c,95,VK_NUMPAD7,0x67,71,71,XK_KP_7,0xffb7,Numpad7,KP7,kp_7,0x44,0x59
KEY_KP8,72,ANSI_Keypad8,0x5b,0x48,0x75,0x75,96,VK_NUMPAD8,0x68,72,72,XK_KP_8,0xffb8,Numpad8,KP8,kp_8,0x45,0x5b
KEY_KP9,73,ANSI_Keypad9,0x5c,0x49,0x7d,0x7d,97,VK_NUMPAD9,0x69,73,73,XK_KP_9,0xffb9,Numpad9,KP9,kp_9,0x46,0x5c
KEY_KPMINUS,74,ANSI_KeypadMinus,0x4e,0x4a,0x7b,0x4e,86,VK_SUBTRACT,0x6d,74,74,XK_KP_Subtract,0xffad,NumpadSubtract,KPSU,kp_subtract,0x47,0x4e
KEY_KP4,75,ANSI_Keypad4,0x56,0x4b,0x6b,0x6b,92,VK_NUMPAD4,0x64,75,75,XK_KP_4,0xffb4,Numpad4,KP4,kp_4,0x5b,0x56
KEY_KP5,76,ANSI_Keypad5,0x57,0x4c,0x73,0x73,93,VK_NUMPAD5,0x65,76,76,XK_KP_5,0xffb5,Numpad5,KP5,kp_5,0x5c,0x57
KEY_KP6,77,ANSI_Keypad6,0x58,0x4d,0x74,0x74,94,VK_NUMPAD6,0x66,77,77,XK_KP_6,0xffb6,Numpad6,KP6,kp_6,0x5d,0x58
KEY_KPPLUS,78,ANSI_KeypadPlus,0x45,0x4e,0x79,0x7c,87,VK_ADD,0x6b,78,78,XK_KP_Add,0xffab,NumpadAdd,KPAD,kp_add,0x7d,0x45
KEY_KP1,79,ANSI_Keypad1,0x53,0x4f,0x69,0x69,89,VK_NUMPAD1,0x61,79,79,XK_KP_1,0xffb1,Numpad1,KP1,kp_1,0x70,0x53
KEY_KP2,80,ANSI_Keypad2,0x54,0x50,0x72,0x72,90,VK_NUMPAD2,0x62,80,80,XK_KP_2,0xffb2,Numpad2,KP2,kp_2,0x71,0x54
KEY_KP3,81,ANSI_Keypad3,0x55,0x51,0x7a,0x7a,91,VK_NUMPAD3,0x63,81,81,XK_KP_3,0xffb3,Numpad3,KP3,kp_3,0x72,0x55
KEY_KP0,82,ANSI_Keypad0,0x52,0x52,0x70,0x70,98,VK_NUMPAD0,0x60,82,82,XK_KP_0,0xffb0,Numpad0,KP0,kp_0,0x5e,0x52
KEY_KPDOT,83,ANSI_KeypadDecimal,0x41,0x53,0x71,0x71,99,VK_DECIMAL,0x6e,83,83,XK_KP_Decimal,0xffae,NumpadDecimal,KPDL,kp_decimal,0x32,0x41
KEY_KPDOT,83,ANSI_KeypadDecimal,0x41,0x53,0x71,0x71,99,VK_DECIMAL,0x6e,83,83,XK_KP_Decimal,0xffae,NumpadDecimal,KPDC,kp_decimal,0x32,0x41
,84,,,0x54,,,,,,,,,,,,,,
KEY_ZENKAKUHANKAKU,85,,,0x76,0x5f,,148,,,,,,,Lang5,HZTG,,,
KEY_102ND,86,,,0x56,0x61,0x13,100,VK_OEM_102,0xe2,86,86,,,IntlBackslash,LSGT,less,0x7c,
KEY_F11,87,F11,0x67,0x57,0x78,0x56,68,VK_F11,0x7a,87,87,XK_F11,0xffc8,F11,FK11,f11,0x09,0x67
KEY_F12,88,F12,0x6f,0x58,0x07,0x5e,69,VK_F12,0x7b,88,88,XK_F12,0xffc9,F12,FK12,f12,0x0b,0x6f
KEY_RO,89,JIS_Underscore,0x5e,0x73,0x51,,135,,,,,,,IntlRo,AB11,ro,,
KEY_KATAKANA,90,,,0x78,0x63,,146,VK_KANA,0x15,,,,,Katakana,KATA,,,
KEY_KATAKANA,90,,,0x78,0x63,,146,VK_KANA,0x15,,,,,Lang3,KATA,,,
KEY_HIRAGANA,91,,,0x77,0x62,0x87,147,,,,,,,Hiragana,HIRA,hiragana,,
KEY_HIRAGANA,91,,,0x77,0x62,0x87,147,,,,,,,Lang4,HIRA,hiragana,,
KEY_HENKAN,92,,,0x79,0x64,0x86,138,,,,,,,Convert,HENK,henkan,,
KEY_KATAKANAHIRAGANA,93,,,0x70,0x13,0x87,136,,,0xc8,0xc8,,,KanaMode,HKTG,katakanahiragana,,
KEY_MUHENKAN,94,,,0x7b,0x67,0x85,139,,,,,,,NonConvert,NFER,muhenkan,,
KEY_MUHENKAN,94,,,0x7b,0x67,0x85,139,,,,,,,NonConvert,MUHE,muhenkan,,
KEY_KPJPCOMMA,95,JIS_KeypadComma,0x5f,0x5c,0x27,,140,,,,,XK_KP_Separator,0xffac,,KPSP,,,
KEY_KPJPCOMMA,95,JIS_KeypadComma,0x5f,0x5c,0x27,,140,,,,,XK_KP_Separator,0xffac,,JPCM,,,
KEY_KPENTER,96,ANSI_KeypadEnter,0x4c,0xe01c,0xe05a,0x79,88,,,0x64,0x64,XK_KP_Enter,0xff8d,NumpadEnter,KPEN,kp_enter,0x5a,0x4c
KEY_RIGHTCTRL,97,RightControl,0x3e,0xe01d,0xe014,0x58,228,VK_RCONTROL,0xa3,0x65,0x65,XK_Control_R,0xffe4,ControlRight,RCTL,ctrl_r,0x4c,0x7d
KEY_KPSLASH,98,ANSI_KeypadDivide,0x4b,0xe035,0xe04a,0x4a,84,VK_DIVIDE,0x6f,0x68,0x68,XK_KP_Divide,0xffaf,NumpadDivide,KPDV,kp_divide,0x2e,0x4b
KEY_SYSRQ,99,,,0x54,0x7f,0x57,70,VK_SNAPSHOT,0x2c,0x67,0x67,XK_Sys_Req,0xff15,PrintScreen,PRSC,print,0x16,0x69
KEY_SYSRQ,99,,,0x54,0x7f,0x57,70,VK_SNAPSHOT,0x2c,0x67,0x67,XK_Sys_Req,0xff15,PrintScreen,SYRQ,sysrq,0x16,0x69
KEY_RIGHTALT,100,RightOption,0x3d,0xe038,0xe011,0x39,230,VK_RMENU,0xa5,0x69,0x69,XK_Alt_R,0xffea,AltRight,ALGR,alt_r,0x0d,0x7c
KEY_RIGHTALT,100,RightOption,0x3d,0xe038,0xe011,0x39,230,VK_RMENU,0xa5,0x69,0x69,XK_Alt_R,0xffea,AltRight,RALT,alt_r,0x0d,0x7c
KEY_LINEFEED,101,,,0x5b,,,,,,,,,,,LNFD,lf,0x6f,
KEY_HOME,102,Home,0x73,0xe047,0xe06c,0x6e,74,VK_HOME,0x24,0x59,0x59,XK_Home,0xff50,Home,HOME,home,0x34,0x73
KEY_UP,103,UpArrow,0x7e,0xe048,0xe075,0x63,82,VK_UP,0x26,0x5a,0x5a,XK_Up,0xff52,ArrowUp,UP,up,0x14,0x3e
KEY_PAGEUP,104,PageUp,0x74,0xe049,0xe07d,0x6f,75,VK_PRIOR,0x21,0x5b,0x5b,XK_Page_Up,0xff55,PageUp,PGUP,pgup,0x60,0x74
KEY_LEFT,105,LeftArrow,0x7b,0xe04b,0xe06b,0x61,80,VK_LEFT,0x25,0x5c,0x5c,XK_Left,0xff51,ArrowLeft,LEFT,left,0x18,0x3b
KEY_RIGHT,106,RightArrow,0x7c,0xe04d,0xe074,0x6a,79,VK_RIGHT,0x27,0x5e,0x5e,XK_Right,0xff53,ArrowRight,RGHT,right,0x1c,0x3c
KEY_END,107,End,0x77,0xe04f,0xe069,0x65,77,VK_END,0x23,0x5f,0x5f,XK_End,0xff57,End,END,end,0x4a,0x77
KEY_DOWN,108,DownArrow,0x7d,0xe050,0xe072,0x60,81,VK_DOWN,0x28,0x60,0x60,XK_Down,0xff54,ArrowDown,DOWN,down,0x1b,0x3d
KEY_PAGEDOWN,109,PageDown,0x79,0xe051,0xe07a,0x6d,78,VK_NEXT,0x22,0x61,0x61,XK_Page_Down,0xff56,PageDown,PGDN,pgdn,0x7b,0x79
KEY_INSERT,110,,,0xe052,0xe070,0x67,73,VK_INSERT,0x2d,0x62,0x62,XK_Insert,0xff63,Insert,INS,insert,0x2c,0x72
KEY_DELETE,111,ForwardDelete,0x75,0xe053,0xe071,0x64,76,VK_DELETE,0x2e,0x63,0x63,XK_Delete,0xffff,Delete,DEL,delete,0x42,0x75
KEY_DELETE,111,ForwardDelete,0x75,0xe053,0xe071,0x64,76,VK_DELETE,0x2e,0x63,0x63,XK_Delete,0xffff,Delete,DELE,,0x42,0x75
KEY_MACRO,112,,,0xe06f,0xe06f,0x8e,,,,,,,,,I120,,,
KEY_MUTE,113,Mute,0x4a,0xe020,0xe023,0x9c,127,VK_VOLUME_MUTE,0xad,,,,,AudioVolumeMute,MUTE,audiomute,,
KEY_MUTE,113,Mute,0x4a,0xe020,0xe023,0x9c,239,VK_VOLUME_MUTE,0xad,,,,,AudioVolumeMute,MUTE,audiomute,,
KEY_VOLUMEDOWN,114,VolumeDown,0x49,0xe02e,0xe021,0x9d,129,VK_VOLUME_DOWN,0xae,,,,,AudioVolumeDown,VOL-,volumedown,,
KEY_VOLUMEDOWN,114,VolumeDown,0x49,0xe02e,0xe021,0x9d,238,VK_VOLUME_DOWN,0xae,,,,,AudioVolumeDown,VOL-,volumedown,,
KEY_VOLUMEUP,115,VolumeUp,0x48,0xe030,0xe032,0x95,128,VK_VOLUME_UP,0xaf,,,,,AudioVolumeUp,VOL+,volumeup,,
KEY_VOLUMEUP,115,VolumeUp,0x48,0xe030,0xe032,0x95,237,VK_VOLUME_UP,0xaf,,,,,AudioVolumeUp,VOL+,volumeup,,
KEY_POWER,116,,,0xe05e,0xe037,,102,,,,,,,Power,POWR,power,,0x7f7f
KEY_KPEQUAL,117,ANSI_KeypadEquals,0x51,0x59,0x0f,,103,,,0x76,0x76,XK_KP_Equal,0xffbd,NumpadEqual,KPEQ,kp_equals,0x2d,0x51
KEY_KPPLUSMINUS,118,,,0xe04e,0xe079,,,,,,,,,,I126,,,
KEY_PAUSE,119,,,0xe046,0xe077,0x62,72,VK_PAUSE,0x013,0x66,0x66,XK_Pause,0xff13,Pause,PAUS,pause,0x15,0x71
KEY_SCALE,120,,,0xe00b,,,,,,,,,,,I128,,,
KEY_KPCOMMA,121,,,0x7e,0x6d,,133,VK_SEPARATOR??,0x6c,,,,,NumpadComma,KPCO,kp_comma,,
KEY_KPCOMMA,121,,,0x7e,0x6d,,133,VK_SEPARATOR??,0x6c,,,,,NumpadComma,I129,,,
KEY_HANGEUL,122,JIS_Kana,0x68,0x72,,,144,VK_HANGEUL,0x15,,0x71,,,Lang1,HNGL,,,
KEY_HANJA,123,JIS_Eisu,0x66,0x71,,,145,VK_HANJA,0x19,,0x72,,,Lang2,HJCV,,,
KEY_YEN,124,JIS_Yen,0x5d,0x7d,0x6a,0x5d,137,,,0x7d,0x7d,,,IntlYen,AE13,yen,,
KEY_LEFTMETA,125,Command,0x37,0xe05b,0xe01f,0x8b,227,VK_LWIN,0x5b,0x6b,0x6b,XK_Meta_L,0xffe7,MetaLeft,LMTA,meta_l,0x78,0x37
KEY_LEFTMETA,125,Command,0x37,0xe05b,0xe01f,0x8b,227,VK_LWIN,0x5b,0x6b,0x6b,XK_Meta_L,0xffe7,MetaLeft,LWIN,meta_l,0x78,0x37
KEY_RIGHTMETA,126,RightCommand,0x36,0xe05c,0xe027,0x8c,231,VK_RWIN,0x5c,0x6c,0x6c,XK_Meta_R,0xffe8,MetaRight,RMTA,meta_r,0x7a,0x37
KEY_RIGHTMETA,126,RightCommand,0x36,0xe05c,0xe027,0x8c,231,VK_RWIN,0x5c,0x6c,0x6c,XK_Meta_R,0xffe8,MetaRight,RWIN,meta_r,0x7a,0x37
KEY_COMPOSE,127,,0x6e,0xe05d,0xe02f,0x8d,101,VK_APPS,0x5d,0x6d,0x6d,,,ContextMenu,MENU,compose,0x43,
KEY_COMPOSE,127,,0x6e,0xe05d,0xe02f,0x8d,101,VK_APPS,0x5d,0x6d,0x6d,,,ContextMenu,COMP,compose,0x43,
KEY_STOP,128,,,0xe068,0xe028,0x0a,120,VK_BROWSER_STOP,0xa9,,,,,BrowserStop,STOP,stop,0x01,
KEY_STOP,128,,,0xe068,0xe028,0x0a,243,VK_BROWSER_STOP,0xa9,,,,,BrowserStop,STOP,stop,0x01,
KEY_AGAIN,129,,,0xe005,,0x0b,121,,,,,,,Again,AGAI,again,0x03,
KEY_PROPS,130,,,0xe006,,0x0c,,,,,,,,Props,PROP,props,0x19,
KEY_UNDO,131,,,0xe007,,0x10,122,,,,,,,Undo,UNDO,undo,0x1a,
KEY_FRONT,132,,,0xe00c,,,119,,,,,,,,FRNT,front,0x31,
KEY_COPY,133,,,0xe078,,0x18,124,,,,,,,Copy,COPY,copy,0x33,
KEY_OPEN,134,,,0x64,,0x20,116,,,,,,,Open,OPEN,open,0x48,
KEY_PASTE,135,,,0x65,,0x28,125,,,,,,,Paste,PAST,paste,0x49,
KEY_FIND,136,,,0xe041,,0x30,126,,,,,,,Find,FIND,find,0x5f,
KEY_FIND,136,,,0xe041,,0x30,244,,,,,,,Find,FIND,find,0x5f,
KEY_CUT,137,,,0xe03c,,0x38,123,,,,,,,Cut,CUT,cut,0x61,
KEY_HELP,138,Help,0x72,0xe075,,0x09,117,VK_HELP,0x2f,,,XK_Help,0xff6a,Help,HELP,help,0x76,
KEY_MENU,139,,,0xe01e,,0x91,118,,,,,,,,I147,menu,,
KEY_CALC,140,,,0xe021,0xe02b,0xa3,251,,,,,,,LaunchApp2,I148,calculator,,
KEY_SETUP,141,,,0x66,,,,,,,,,,,I149,,,
KEY_SLEEP,142,,,0xe05f,0xe03f,,248,VK_SLEEP,0x5f,,,,,Sleep,I150,sleep,,
KEY_WAKEUP,143,,,0xe063,0xe05e,,,,,,,,,WakeUp,I151,wake,,
KEY_FILE,144,,,0x67,,,,,,,,,,,I152,,,
KEY_SENDFILE,145,,,0x68,,,,,,,,,,,I153,,,
KEY_DELETEFILE,146,,,0x69,,,,,,,,,,,I154,,,
KEY_XFER,147,,,0xe013,,0xa2,,,,,,,,,XFER,,,
KEY_XFER,147,,,0xe013,,0xa2,,,,,,,,,I155,,,
KEY_PROG1,148,,,0xe01f,,0xa0,,,,,,,,,I156,,,
KEY_PROG2,149,,,0xe017,,0xa1,,,,,,,,,I157,,,
KEY_WWW,150,,,0xe002,,,240,,,,,,,,I158,,,
KEY_MSDOS,151,,,0x6a,,,,,,,,,,,I159,,,
KEY_SCREENLOCK,152,,,0xe012,,0x96,249,,,,,,,,I160,,,
KEY_DIRECTION,153,,,0x6b,,,,,,,,,,,I161,,,
KEY_CYCLEWINDOWS,154,,,0xe026,,0x9b,,,,,,,,,I162,,,
KEY_MAIL,155,,,0xe06c,0xe048,,,,,,,,,LaunchMail,I163,mail,,
KEY_BOOKMARKS,156,,,0xe066,0xe018,,,,,,,,,BrowserFavorites,I164,ac_bookmarks,,
KEY_COMPUTER,157,,,0xe06b,0xe040,,,,,,,,,LaunchApp1,I165,computer,,
KEY_BACK,158,,,0xe06a,0xe038,,241,VK_BROWSER_BACK,0xa6,,,,,BrowserBack,I166,ac_back,,
KEY_FORWARD,159,,,0xe069,0xe030,,242,VK_BROWSER_FORWARD,0xa7,,,,,BrowserForward,I167,ac_forward,,
KEY_CLOSECD,160,,,0xe023,,0x9a,,,,,,,,,I168,,,
KEY_EJECTCD,161,,,0x6c,,,236,,,,,,,,I169,,,
KEY_EJECTCLOSECD,162,,,0xe07d,,,,,,,,,,Eject,I170,,,
KEY_NEXTSONG,163,,,0xe019,0xe04d,0x93,235,VK_MEDIA_NEXT_TRACK,0xb0,,,,,MediaTrackNext,I171,audionext,,
KEY_PLAYPAUSE,164,,,0xe022,0xe034,,232,VK_MEDIA_PLAY_PAUSE,0xb3,,,,,MediaPlayPause,I172,audioplay,,
KEY_PREVIOUSSONG,165,,,0xe010,0xe015,0x94,234,VK_MEDIA_PREV_TRACK,0xb1,,,,,MediaTrackPrevious,I173,audioprev,,
KEY_STOPCD,166,,,0xe024,0xe03b,0x98,233,VK_MEDIA_STOP,0xb2,,,,,MediaStop,I174,audiostop,,
KEY_RECORD,167,,,0xe031,,0x9e,,,,,,,,,I175,,,
KEY_REWIND,168,,,0xe018,,0x9f,,,,,,,,,I176,,,
KEY_PHONE,169,,,0x63,,,,,,,,,,,I177,,,
KEY_ISO,170,ISO_Section,0xa,,,,,,,,,,,,I178,,,
KEY_CONFIG,171,,,0xe001,,,,,,,,,,,I179,,,
KEY_HOMEPAGE,172,,,0xe032,0xe03a,0x97,,VK_BROWSER_HOME,0xac,,,,,BrowserHome,I180,ac_home,,
KEY_REFRESH,173,,,0xe067,0xe020,,250,VK_BROWSER_REFRESH,0xa8,,,,,BrowserRefresh,I181,ac_refresh,,
KEY_EXIT,174,,,,,,,,,,,,,,I182,,,
KEY_MOVE,175,,,,,,,,,,,,,,I183,,,
KEY_EDIT,176,,,0xe008,,,247,,,,,,,,I184,,,
KEY_SCROLLUP,177,,,0x75,,,245,,,,,,,,I185,,,
KEY_SCROLLDOWN,178,,,0xe00f,,,246,,,,,,,,I186,,,
KEY_KPLEFTPAREN,179,,,0xe076,,,182,,,,,,,NumpadParenLeft,I187,,,
KEY_KPRIGHTPAREN,180,,,0xe07b,,,183,,,,,,,NumpadParenRight,I188,,,
KEY_NEW,181,,,0xe009,,,,,,,,,,,I189,,,
KEY_REDO,182,,,0xe00a,,,,,,,,,,,I190,,,
KEY_F13,183,F13,0x69,0x5d,0x2f,0x7f,104,VK_F13,0x7c,0x6e,0x6e,,,F13,FK13,,,0x69
KEY_F14,184,F14,0x6b,0x5e,0x37,0x80,105,VK_F14,0x7d,0x6f,0x6f,,,F14,FK14,,,0x6b
KEY_F15,185,F15,0x71,0x5f,0x3f,0x81,106,VK_F15,0x7e,0x70,0x70,,,F15,FK15,,,0x71
KEY_F16,186,F16,0x6a,0x55,,0x82,107,VK_F16,0x7f,0x71,0x71,,,F16,FK16,,,
KEY_F17,187,F17,0x40,0xe003,,0x83,108,VK_F17,0x80,0x72,0x72,,,F17,FK17,,,
KEY_F18,188,F18,0x4f,0xe077,,,109,VK_F18,0x81,,,,,F18,FK18,,,
KEY_F19,189,F19,0x50,0xe004,,,110,VK_F19,0x82,,,,,F19,FK19,,,
KEY_F20,190,F20,0x5a,0x5a,,,111,VK_F20,0x83,,,,,F20,FK20,,,
KEY_F21,191,,,0x74,,,112,VK_F21,0x84,,,,,F21,FK21,,,
KEY_F22,192,,,0xe079,,,113,VK_F22,0x85,,,,,F22,FK22,,,
KEY_F23,193,,,0x6d,,,114,VK_F23,0x86,,,,,F23,FK23,,,
KEY_F24,194,,,0x6f,,,115,VK_F24,0x87,,,,,F24,FK24,,,
,195,,,0xe015,,,,,,,,,,,,,,
,196,,,0xe016,,,,,,,,,,,,,,
,197,,,0xe01a,,,,,,,,,,,,,,
,198,,,0xe01b,,,,,,,,,,,,,,
,199,,,0xe027,,,,,,,,,,,,,,
KEY_PLAYCD,200,,,0xe028,,,,,,,,,,,I208,,,
KEY_PAUSECD,201,,,0xe029,,,,,,,,,,,I209,,,
KEY_PROG3,202,,,0xe02b,,,,,,,,,,,I210,,,
KEY_PROG4,203,,,0xe02c,,,,,,,,,,,I211,,,
KEY_DASHBOARD,204,,,0xe02d,,,,,,,,,,,I212,,,
KEY_SUSPEND,205,,,0xe025,,,,,,,,,,Suspend,I213,,,
KEY_CLOSE,206,,,0xe02f,,,,,,,,,,,I214,,,
KEY_PLAY,207,,,0xe033,,,,VK_PLAY,0xfa,,,,,,I215,,,
KEY_FASTFORWARD,208,,,0xe034,,,,,,,,,,,I216,,,
KEY_BASSBOOST,209,,,0xe036,,,,,,,,,,,I217,,,
KEY_PRINT,210,,,0xe039,,,,VK_PRINT,0x2a,,,,,,I218,,,
KEY_HP,211,,,0xe03a,,,,,,,,,,,I219,,,
KEY_CAMERA,212,,,0xe03b,,,,,,,,,,,I220,,,
KEY_SOUND,213,,,0xe03d,,,,,,,,,,,I221,,,
KEY_QUESTION,214,,,0xe03e,,,,,,,,,,,I222,,,
KEY_EMAIL,215,,,0xe03f,,,,VK_LAUNCH_MAIL,0xb4,,,,,,I223,,,
KEY_CHAT,216,,,0xe040,,,,,,,,,,,I224,,,
KEY_SEARCH,217,,,0xe065,0xe010,,,VK_BROWSER_SEARCH,0xaa,,,,,BrowserSearch,I225,,,
KEY_CONNECT,218,,,0xe042,,,,,,,,,,,I226,,,
KEY_FINANCE,219,,,0xe043,,,,,,,,,,,I227,,,
KEY_SPORT,220,,,0xe044,,,,,,,,,,,I228,,,
KEY_SHOP,221,,,0xe045,,,,,,,,,,,I229,,,
KEY_ALTERASE,222,,,0xe014,,,,,,,,,,,I230,,,
KEY_CANCEL,223,,,0xe04a,,,,,,,,,,,I231,,,
KEY_BRIGHTNESSDOWN,224,,,0xe04c,,,,,,,,,,,I232,,,
KEY_BRIGHTNESSUP,225,,,0xe054,,,,,,,,,,,I233,,,
KEY_MEDIA,226,,,0xe06d,0xe050,,,,,,,,,MediaSelect,I234,mediaselect,,
KEY_SWITCHVIDEOMODE,227,,,0xe056,,,,,,,,,,,I235,,,
KEY_KBDILLUMTOGGLE,228,,,0xe057,,,,,,,,,,,I236,,,
KEY_KBDILLUMDOWN,229,,,0xe058,,,,,,,,,,,I237,,,
KEY_KBDILLUMUP,230,,,0xe059,,,,,,,,,,,I238,,,
KEY_SEND,231,,,0xe05a,,,,,,,,,,,I239,,,
KEY_REPLY,232,,,0xe064,,,,,,,,,,,I240,,,
KEY_FORWARDMAIL,233,,,0xe00e,,,,,,,,,,,I241,,,
KEY_SAVE,234,,,0xe055,,,,,,,,,,,I242,,,
KEY_DOCUMENTS,235,,,0xe070,,,,,,,,,,,I243,,,
KEY_BATTERY,236,,,0xe071,,,,,,,,,,,I244,,,
KEY_BLUETOOTH,237,,,0xe072,,,,,,,,,,,I245,,,
KEY_WLAN,238,,,0xe073,,,,,,,,,,,I246,,,
KEY_UWB,239,,,0xe074,,,,,,,,,,,I247,,,
KEY_UNKNOWN,240,,,,,,,,,,,,,,I248,,,
KEY_VIDEO_NEXT,241,,,,,,,,,,,,,,I249,,,
KEY_VIDEO_PREV,242,,,,,,,,,,,,,,I250,,,
KEY_BRIGHTNESS_CYCLE,243,,,,,,,,,,,,,,I251,,,
KEY_BRIGHTNESS_ZERO,244,,,,,,,,,,,,,,I252,,,
KEY_DISPLAY_OFF,245,,,,,,,,,,,,,,I253,,,
KEY_WIMAX,246,,,,,,,,,,,,,,,,,
,247,,,,,,,,,,,,,,,,,
,248,,,,,,,,,,,,,,,,,
,249,,,,,,,,,,,,,,,,,
,250,,,,,,,,,,,,,,,,,
,251,,,,,,,,,,,,,,,,,
,252,,,,,,,,,,,,,,,,,
,253,,,,,,,,,,,,,,,,,
,254,,,,,,,,,,,,,,,,,
,255,,,,0xe012,,,,,,,,,,,,,
BTN_MISC,0x100,,,,,,,,,,,,,,,,,
BTN_0,0x100,,,,,,,VK_LBUTTON,0x01,,,,,,,,,
BTN_1,0x101,,,,,,,VK_RBUTTON,0x02,,,,,,,,,
BTN_2,0x102,,,,,,,VK_MBUTTON,0x04,,,,,,,,,
BTN_3,0x103,,,,,,,VK_XBUTTON1,0x05,,,,,,,,,
BTN_4,0x104,,,,,,,VK_XBUTTON2,0x06,,,,,,,,,
BTN_5,0x105,,,,,,,,,,,,,,,,,
BTN_6,0x106,,,,,,,,,,,,,,,,,
BTN_7,0x107,,,,,,,,,,,,,,,,,
BTN_8,0x108,,,,,,,,,,,,,,,,,
BTN_9,0x109,,,,,,,,,,,,,,,,,
BTN_MOUSE,0x110,,,,,,,,,,,,,,,,,
BTN_LEFT,0x110,,,,,,,,,,,,,,,,,
BTN_RIGHT,0x111,,,,,,,,,,,,,,,,,
BTN_MIDDLE,0x112,,,,,,,,,,,,,,,,,
BTN_SIDE,0x113,,,,,,,,,,,,,,,,,
BTN_EXTRA,0x114,,,,,,,,,,,,,,,,,
BTN_FORWARD,0x115,,,,,,,,,,,,,,,,,
BTN_BACK,0x116,,,,,,,,,,,,,,,,,
BTN_TASK,0x117,,,,,,,,,,,,,,,,,
BTN_JOYSTICK,0x120,,,,,,,,,,,,,,,,,
BTN_TRIGGER,0x120,,,,,,,,,,,,,,,,,
BTN_THUMB,0x121,,,,,,,,,,,,,,,,,
BTN_THUMB2,0x122,,,,,,,,,,,,,,,,,
BTN_TOP,0x123,,,,,,,,,,,,,,,,,
BTN_TOP2,0x124,,,,,,,,,,,,,,,,,
BTN_PINKIE,0x125,,,,,,,,,,,,,,,,,
BTN_BASE,0x126,,,,,,,,,,,,,,,,,
BTN_BASE2,0x127,,,,,,,,,,,,,,,,,
BTN_BASE3,0x128,,,,,,,,,,,,,,,,,
BTN_BASE4,0x129,,,,,,,,,,,,,,,,,
BTN_BASE5,0x12a,,,,,,,,,,,,,,,,,
BTN_BASE6,0x12b,,,,,,,,,,,,,,,,,
BTN_DEAD,0x12f,,,,,,,,,,,,,,,,,
BTN_GAMEPAD,0x130,,,,,,,,,,,,,,,,,
BTN_A,0x130,,,,,,,,,,,,,,,,,
BTN_B,0x131,,,,,,,,,,,,,,,,,
BTN_C,0x132,,,,,,,,,,,,,,,,,
BTN_X,0x133,,,,,,,,,,,,,,,,,
BTN_Y,0x134,,,,,,,,,,,,,,,,,
BTN_Z,0x135,,,,,,,,,,,,,,,,,
BTN_TL,0x136,,,,,,,,,,,,,,,,,
BTN_TR,0x137,,,,,,,,,,,,,,,,,
BTN_TL2,0x138,,,,,,,,,,,,,,,,,
BTN_TR2,0x139,,,,,,,,,,,,,,,,,
BTN_SELECT,0x13a,,,,,,,,,,,,,,,,,
BTN_START,0x13b,,,,,,,,,,,,,,,,,
BTN_MODE,0x13c,,,,,,,,,,,,,,,,,
BTN_THUMBL,0x13d,,,,,,,,,,,,,,,,,
BTN_THUMBR,0x13e,,,,,,,,,,,,,,,,,
BTN_DIGI,0x140,,,,,,,,,,,,,,,,,
BTN_TOOL_PEN,0x140,,,,,,,,,,,,,,,,,
BTN_TOOL_RUBBER,0x141,,,,,,,,,,,,,,,,,
BTN_TOOL_BRUSH,0x142,,,,,,,,,,,,,,,,,
BTN_TOOL_PENCIL,0x143,,,,,,,,,,,,,,,,,
BTN_TOOL_AIRBRUSH,0x144,,,,,,,,,,,,,,,,,
BTN_TOOL_FINGER,0x145,,,,,,,,,,,,,,,,,
BTN_TOOL_MOUSE,0x146,,,,,,,,,,,,,,,,,
BTN_TOOL_LENS,0x147,,,,,,,,,,,,,,,,,
BTN_TOUCH,0x14a,,,,,,,,,,,,,,,,,
BTN_STYLUS,0x14b,,,,,,,,,,,,,,,,,
BTN_STYLUS2,0x14c,,,,,,,,,,,,,,,,,
BTN_TOOL_DOUBLETAP,0x14d,,,,,,,,,,,,,,,,,
BTN_TOOL_TRIPLETAP,0x14e,,,,,,,,,,,,,,,,,
BTN_TOOL_QUADTAP,0x14f,,,,,,,,,,,,,,,,,
BTN_WHEEL,0x150,,,,,,,,,,,,,,,,,
BTN_GEAR_DOWN,0x150,,,,,,,,,,,,,,,,,
BTN_GEAR_UP,0x151,,,,,,,,,,,,,,,,,
KEY_OK,0x160,,,,,,,,,,,,,,,,,
KEY_SELECT,0x161,,,,,,,VK_SELECT,0x29,,,XK_Select,0xff60,Select,SELE,,,
KEY_GOTO,0x162,,,,,,,,,,,,,,,,,
KEY_CLEAR,0x163,,,,,,,,,,,,,NumpadClear,CLR,,,
KEY_POWER2,0x164,,,,,,,,,,,,,,,,,
KEY_OPTION,0x165,,,,,,,,,,,,,,,,,
KEY_INFO,0x166,,,,,,,,,,,,,,,,,
KEY_TIME,0x167,,,,,,,,,,,,,,,,,
KEY_VENDOR,0x168,,,,,,,,,,,,,,,,,
KEY_ARCHIVE,0x169,,,,,,,,,,,,,,,,,
KEY_PROGRAM,0x16a,,,,,,,,,,,,,,,,,
KEY_CHANNEL,0x16b,,,,,,,,,,,,,,,,,
KEY_FAVORITES,0x16c,,,,,,,VK_BROWSER_FAVOURITES,0xab,,,,,,,,,
KEY_EPG,0x16d,,,,,,,,,,,,,,,,,
KEY_PVR,0x16e,,,,,,,,,,,,,,,,,
KEY_MHP,0x16f,,,,,,,,,,,,,,,,,
KEY_LANGUAGE,0x170,,,,,,,,,,,,,,,,,
KEY_TITLE,0x171,,,,,,,,,,,,,,,,,
KEY_SUBTITLE,0x172,,,,,,,,,,,,,,,,,
KEY_ANGLE,0x173,,,,,,,,,,,,,,,,,
KEY_ZOOM,0x174,,,,,,,VK_ZOOM,0xfb,,,,,,,,,
KEY_MODE,0x175,,,,,,,,,,,,,,,,,
KEY_KEYBOARD,0x176,,,,,,,,,,,,,,,,,
KEY_SCREEN,0x177,,,,,,,,,,,,,,,,,
KEY_PC,0x178,,,,,,,,,,,,,,,,,
KEY_TV,0x179,,,,,,,,,,,,,,,,,
KEY_TV2,0x17a,,,,,,,,,,,,,,,,,
KEY_VCR,0x17b,,,,,,,,,,,,,,,,,
KEY_VCR2,0x17c,,,,,,,,,,,,,,,,,
KEY_SAT,0x17d,,,,,,,,,,,,,,,,,
KEY_SAT2,0x17e,,,,,,,,,,,,,,,,,
KEY_CD,0x17f,,,,,,,,,,,,,,,,,
KEY_TAPE,0x180,,,,,,,,,,,,,,,,,
KEY_RADIO,0x181,,,,,,,,,,,,,,,,,
KEY_TUNER,0x182,,,,,,,,,,,,,,,,,
KEY_PLAYER,0x183,,,,,,,,,,,,,,,,,
KEY_TEXT,0x184,,,,,,,,,,,,,,,,,
KEY_DVD,0x185,,,,,,,,,,,,,,,,,
KEY_AUX,0x186,,,,,,,,,,,,,,,,,
KEY_MP3,0x187,,,,,,,,,,,,,,,,,
KEY_AUDIO,0x188,,,,,,,,,,,,,,,,,
KEY_VIDEO,0x189,,,,,,,,,,,,,,,,,
KEY_DIRECTORY,0x18a,,,,,,,,,,,,,,,,,
KEY_LIST,0x18b,,,,,,,,,,,,,,,,,
KEY_MEMO,0x18c,,,,,,,,,,,,,,,,,
KEY_CALENDAR,0x18d,,,,,,,,,,,,,,,,,
KEY_RED,0x18e,,,,,,,,,,,,,,,,,
KEY_GREEN,0x18f,,,,,,,,,,,,,,,,,
KEY_YELLOW,0x190,,,,,,,,,,,,,,,,,
KEY_BLUE,0x191,,,,,,,,,,,,,,,,,
KEY_CHANNELUP,0x192,,,,,,,,,,,,,,,,,
KEY_CHANNELDOWN,0x193,,,,,,,,,,,,,,,,,
KEY_FIRST,0x194,,,,,,,,,,,,,,,,,
KEY_LAST,0x195,,,,,,,,,,,,,,,,,
KEY_AB,0x196,,,,,,,,,,,,,,,,,
KEY_NEXT,0x197,,,,,,,,,,,,,,,,,
KEY_RESTART,0x198,,,,,,,,,,,,,,,,,
KEY_SLOW,0x199,,,,,,,,,,,,,,,,,
KEY_SHUFFLE,0x19a,,,,,,,,,,,,,,,,,
KEY_BREAK,0x19b,,,,,,,,,,,,,,BREA,,,
KEY_BREAK,0x19b,,,,,,,,,,,,,,BRK,,,
KEY_PREVIOUS,0x19c,,,,,,,,,,,,,,,,,
KEY_DIGITS,0x19d,,,,,,,,,,,,,,,,,
KEY_TEEN,0x19e,,,,,,,,,,,,,,,,,
KEY_TWEN,0x19f,,,,,,,,,,,,,,,,,
KEY_VIDEOPHONE,0x1a0,,,,,,,,,,,,,,,,,
KEY_GAMES,0x1a1,,,,,,,,,,,,,,,,,
KEY_ZOOMIN,0x1a2,,,,,,,,,,,,,,,,,
KEY_ZOOMOUT,0x1a3,,,,,,,,,,,,,,,,,
KEY_ZOOMRESET,0x1a4,,,,,,,,,,,,,,,,,
KEY_WORDPROCESSOR,0x1a5,,,,,,,,,,,,,,,,,
KEY_EDITOR,0x1a6,,,,,,,,,,,,,,,,,
KEY_SPREADSHEET,0x1a7,,,,,,,,,,,,,,,,,
KEY_GRAPHICSEDITOR,0x1a8,,,,,,,,,,,,,,,,,
KEY_PRESENTATION,0x1a9,,,,,,,,,,,,,,,,,
KEY_DATABASE,0x1aa,,,,,,,,,,,,,,,,,
KEY_NEWS,0x1ab,,,,,,,,,,,,,,,,,
KEY_VOICEMAIL,0x1ac,,,,,,,,,,,,,,,,,
KEY_ADDRESSBOOK,0x1ad,,,,,,,,,,,,,,,,,
KEY_MESSENGER,0x1ae,,,,,,,,,,,,,,,,,
KEY_DISPLAYTOGGLE,0x1af,,,,,,,,,,,,,,,,,
KEY_SPELLCHECK,0x1b0,,,,,,,,,,,,,,,,,
KEY_LOGOFF,0x1b1,,,,,,,,,,,,,,,,,
KEY_DOLLAR,0x1b2,,,,,,,,,,,,,,,,,
KEY_EURO,0x1b3,,,,,,,,,,,,,,,,,
KEY_FRAMEBACK,0x1b4,,,,,,,,,,,,,,,,,
KEY_FRAMEFORWARD,0x1b5,,,,,,,,,,,,,,,,,
KEY_CONTEXT_MENU,0x1b6,,,,,,,,,,,,,,,,,
KEY_MEDIA_REPEAT,0x1b7,,,,,,,,,,,,,,,,,
KEY_DEL_EOL,0x1c0,,,,,,,,,,,,,,,,,
KEY_DEL_EOS,0x1c1,,,,,,,,,,,,,,,,,
KEY_INS_LINE,0x1c2,,,,,,,,,,,,,,,,,
KEY_DEL_LINE,0x1c3,,,,,,,,,,,,,,,,,
KEY_FN,0x1d0,Function,0x3f,,,,,,,,,,,Fn,,,,
KEY_FN_ESC,0x1d1,,,,,,,,,,,,,,,,,
KEY_FN_F1,0x1d2,,,,,,,,,,,,,,,,,
KEY_FN_F2,0x1d3,,,,,,,,,,,,,,,,,
KEY_FN_F3,0x1d4,,,,,,,,,,,,,,,,,
KEY_FN_F4,0x1d5,,,,,,,,,,,,,,,,,
KEY_FN_F5,0x1d6,,,,,,,,,,,,,,,,,
KEY_FN_F6,0x1d7,,,,,,,,,,,,,,,,,
KEY_FN_F7,0x1d8,,,,,,,,,,,,,,,,,
KEY_FN_F8,0x1d9,,,,,,,,,,,,,,,,,
KEY_FN_F9,0x1da,,,,,,,,,,,,,,,,,
KEY_FN_F10,0x1db,,,,,,,,,,,,,,,,,
KEY_FN_F11,0x1dc,,,,,,,,,,,,,,,,,
KEY_FN_F12,0x1dd,,,,,,,,,,,,,,,,,
KEY_FN_1,0x1de,,,,,,,,,,,,,,,,,
KEY_FN_2,0x1df,,,,,,,,,,,,,,,,,
KEY_FN_D,0x1e0,,,,,,,,,,,,,,,,,
KEY_FN_E,0x1e1,,,,,,,,,,,,,,,,,
KEY_FN_F,0x1e2,,,,,,,,,,,,,,,,,
KEY_FN_S,0x1e3,,,,,,,,,,,,,,,,,
KEY_FN_B,0x1e4,,,,,,,,,,,,,,,,,
KEY_BRL_DOT1,0x1f1,,,,,,,,,,,,,,,,,
KEY_BRL_DOT2,0x1f2,,,,,,,,,,,,,,,,,
KEY_BRL_DOT3,0x1f3,,,,,,,,,,,,,,,,,
KEY_BRL_DOT4,0x1f4,,,,,,,,,,,,,,,,,
KEY_BRL_DOT5,0x1f5,,,,,,,,,,,,,,,,,
KEY_BRL_DOT6,0x1f6,,,,,,,,,,,,,,,,,
KEY_BRL_DOT7,0x1f7,,,,,,,,,,,,,,,,,
KEY_BRL_DOT8,0x1f8,,,,,,,,,,,,,,,,,
KEY_BRL_DOT9,0x1f9,,,,,,,,,,,,,,,,,
KEY_BRL_DOT10,0x1fa,,,,,,,,,,,,,,,,,
KEY_NUMERIC_0,0x200,,,,,,,,,,,,,,,,,
KEY_NUMERIC_1,0x201,,,,,,,,,,,,,,,,,
KEY_NUMERIC_2,0x202,,,,,,,,,,,,,,,,,
KEY_NUMERIC_3,0x203,,,,,,,,,,,,,,,,,
KEY_NUMERIC_4,0x204,,,,,,,,,,,,,,,,,
KEY_NUMERIC_5,0x205,,,,,,,,,,,,,,,,,
KEY_NUMERIC_6,0x206,,,,,,,,,,,,,,,,,
KEY_NUMERIC_7,0x207,,,,,,,,,,,,,,,,,
KEY_NUMERIC_8,0x208,,,,,,,,,,,,,,,,,
KEY_NUMERIC_9,0x209,,,,,,,,,,,,,,,,,
KEY_NUMERIC_STAR,0x20a,,,,,,,,,,,,,NumpadStar,,,,
KEY_NUMERIC_POUND,0x20b,,,,,,,,,,,,,NumpadHash,,,,
KEY_RFKILL,0x20c,,,,,,,,,,,,,,,,,
1 Linux Name Linux Keycode OS-X Name OS-X Keycode AT set1 keycode AT set2 keycode AT set3 keycode USB Keycodes Win32 Name Win32 Keycode Xwin XT Xfree86 KBD XT X11 keysym name X11 keysym HTML code XKB key name QEMU QKeyCode Sun KBD Apple ADB
2 KEY_RESERVED 0 0xff unmapped 0xff
3 KEY_ESC 1 Escape 0x35 0x01 0x76 0x08 41 VK_ESCAPE 0x1b 1 1 XK_Escape 0xff1b Escape ESC esc 0x1d 0x35
4 KEY_1 2 ANSI_1 0x12 0x02 0x16 0x16 30 VK_1 0x31 2 2 XK_1 0x0031 Digit1 AE01 1 0x1e 0x12
5 KEY_1 2 ANSI_1 0x12 0x02 0x16 0x16 30 VK_1 0x31 2 2 XK_exclam 0x0021 Digit1 AE01 1 0x1e 0x12
6 KEY_2 3 ANSI_2 0x13 0x03 0x1e 0x1e 31 VK_2 0x32 3 3 XK_2 0x0032 Digit2 AE02 2 0x1f 0x13
7 KEY_2 3 ANSI_2 0x13 0x03 0x1e 0x1e 31 VK_2 0x32 3 3 XK_at 0x0040 Digit2 AE02 2 0x1f 0x13
8 KEY_3 4 ANSI_3 0x14 0x04 0x26 0x26 32 VK_3 0x33 4 4 XK_3 0x0033 Digit3 AE03 3 0x20 0x14
9 KEY_3 4 ANSI_3 0x14 0x04 0x26 0x26 32 VK_3 0x33 4 4 XK_numbersign 0x0023 Digit3 AE03 3 0x20 0x14
10 KEY_4 5 ANSI_4 0x15 0x05 0x25 0x25 33 VK_4 0x34 5 5 XK_4 0x0034 Digit4 AE04 4 0x21 0x15
11 KEY_4 5 ANSI_4 0x15 0x05 0x25 0x25 33 VK_4 0x34 5 5 XK_dollar 0x0024 Digit4 AE04 4 0x21 0x15
12 KEY_5 6 ANSI_5 0x17 0x06 0x2e 0x2e 34 VK_5 0x35 6 6 XK_5 0x0035 Digit5 AE05 5 0x22 0x17
13 KEY_5 6 ANSI_5 0x17 0x06 0x2e 0x2e 34 VK_5 0x35 6 6 XK_percent 0x0025 Digit5 AE05 5 0x22 0x17
14 KEY_6 7 ANSI_6 0x16 0x07 0x36 0x36 35 VK_6 0x36 7 7 XK_6 0x0036 Digit6 AE06 6 0x23 0x16
15 KEY_6 7 ANSI_6 0x16 0x07 0x36 0x36 35 VK_6 0x36 7 7 XK_asciicircum 0x005e Digit6 AE06 6 0x23 0x16
16 KEY_7 8 ANSI_7 0x1a 0x08 0x3d 0x3d 36 VK_7 0x37 8 8 XK_7 0x0037 Digit7 AE07 7 0x24 0x1a
17 KEY_7 8 ANSI_7 0x1a 0x08 0x3d 0x3d 36 VK_7 0x37 8 8 XK_ampersand 0x0026 Digit7 AE07 7 0x24 0x1a
18 KEY_8 9 ANSI_8 0x1c 0x09 0x3e 0x3e 37 VK_8 0x38 9 9 XK_8 0x0038 Digit8 AE08 8 0x25 0x1c
19 KEY_8 9 ANSI_8 0x1c 0x09 0x3e 0x3e 37 VK_8 0x38 9 9 XK_asterisk 0x002a Digit8 AE08 8 0x25 0x1c
20 KEY_9 10 ANSI_9 0x19 0x0a 0x46 0x46 38 VK_9 0x39 10 10 XK_9 0x0039 Digit9 AE09 9 0x26 0x19
21 KEY_9 10 ANSI_9 0x19 0x0a 0x46 0x46 38 VK_9 0x39 10 10 XK_parenleft 0x0028 Digit9 AE09 9 0x26 0x19
22 KEY_0 11 ANSI_0 0x1d 0x0b 0x45 0x45 39 VK_0 0x30 11 11 XK_0 0x0030 Digit0 AE10 0 0x27 0x1d
23 KEY_0 11 ANSI_0 0x1d 0x0b 0x45 0x45 39 VK_0 0x30 11 11 XK_parenright 0x0029 Digit0 AE10 0 0x27 0x1d
24 KEY_MINUS 12 ANSI_Minus 0x1b 0x0c 0x4e 0x4e 45 VK_OEM_MINUS 0xbd 12 12 XK_minus 0x002d Minus AE11 minus 0x28 0x1b
25 KEY_MINUS 12 ANSI_Minus 0x1b 0x0c 0x4e 0x4e 45 VK_OEM_MINUS 0xbd 12 12 XK_underscore 0x005f Minus AE11 minus 0x28 0x1b
26 KEY_EQUAL 13 ANSI_Equal 0x18 0x0d 0x55 0x55 46 VK_OEM_PLUS 0xbb 13 13 XK_equal 0x003d Equal AE12 equal 0x29 0x18
27 KEY_EQUAL 13 ANSI_Equal 0x18 0x0d 0x55 0x55 46 VK_OEM_PLUS 0xbb 13 13 XK_plus 0x002b Equal AE12 equal 0x29 0x18
28 KEY_BACKSPACE 14 Delete 0x33 0x0e 0x66 0x66 42 VK_BACK 0x08 14 14 XK_BackSpace 0xff08 Backspace BKSP backspace 0x2b 0x33
29 KEY_TAB 15 Tab 0x30 0x0f 0x0d 0x0d 43 VK_TAB 0x09 15 15 XK_Tab 0xff09 Tab TAB tab 0x35 0x30
30 KEY_Q 16 ANSI_Q 0xc 0x10 0x15 0x15 20 VK_Q 0x51 16 16 XK_Q 0x0051 KeyQ AD01 q 0x36 0xc
31 KEY_Q 16 ANSI_Q 0xc 0x10 0x15 0x15 20 VK_Q 0x51 16 16 XK_q 0x0071 KeyQ AD01 q 0x36 0xc
32 KEY_W 17 ANSI_W 0xd 0x11 0x1d 0x1d 26 VK_W 0x57 17 17 XK_W 0x0057 KeyW AD02 w 0x37 0xd
33 KEY_W 17 ANSI_W 0xd 0x11 0x1d 0x1d 26 VK_W 0x57 17 17 XK_w 0x0077 KeyW AD02 w 0x37 0xd
34 KEY_E 18 ANSI_E 0xe 0x12 0x24 0x24 8 VK_E 0x45 18 18 XK_E 0x0045 KeyE AD03 e 0x38 0xe
35 KEY_E 18 ANSI_E 0xe 0x12 0x24 0x24 8 VK_E 0x45 18 18 XK_e 0x0065 KeyE AD03 e 0x38 0xe
36 KEY_R 19 ANSI_R 0xf 0x13 0x2d 0x2d 21 VK_R 0x52 19 19 XK_R 0x0052 KeyR AD04 r 0x39 0xf
37 KEY_R 19 ANSI_R 0xf 0x13 0x2d 0x2d 21 VK_R 0x52 19 19 XK_r 0x0072 KeyR AD04 r 0x39 0xf
38 KEY_T 20 ANSI_T 0x11 0x14 0x2c 0x2c 23 VK_T 0x54 20 20 XK_T 0x0054 KeyT AD05 t 0x3a 0x11
39 KEY_T 20 ANSI_T 0x11 0x14 0x2c 0x2c 23 VK_T 0x54 20 20 XK_t 0x0074 KeyT AD05 t 0x3a 0x11
40 KEY_Y 21 ANSI_Y 0x10 0x15 0x35 0x35 28 VK_Y 0x59 21 21 XK_Y 0x0059 KeyY AD06 y 0x3b 0x10
41 KEY_Y 21 ANSI_Y 0x10 0x15 0x35 0x35 28 VK_Y 0x59 21 21 XK_y 0x0079 KeyY AD06 y 0x3b 0x10
42 KEY_U 22 ANSI_U 0x20 0x16 0x3c 0x3c 24 VK_U 0x55 22 22 XK_U 0x0055 KeyU AD07 u 0x3c 0x20
43 KEY_U 22 ANSI_U 0x20 0x16 0x3c 0x3c 24 VK_U 0x55 22 22 XK_u 0x0075 KeyU AD07 u 0x3c 0x20
44 KEY_I 23 ANSI_I 0x22 0x17 0x43 0x43 12 VK_I 0x49 23 23 XK_I 0x0049 KeyI AD08 i 0x3d 0x22
45 KEY_I 23 ANSI_I 0x22 0x17 0x43 0x43 12 VK_I 0x49 23 23 XK_i 0x0069 KeyI AD08 i 0x3d 0x22
46 KEY_O 24 ANSI_O 0x1f 0x18 0x44 0x44 18 VK_O 0x4f 24 24 XK_O 0x004f KeyO AD09 o 0x3e 0x1f
47 KEY_O 24 ANSI_O 0x1f 0x18 0x44 0x44 18 VK_O 0x4f 24 24 XK_o 0x006f KeyO AD09 o 0x3e 0x1f
48 KEY_P 25 ANSI_P 0x23 0x19 0x4d 0x4d 19 VK_P 0x50 25 25 XK_P 0x0050 KeyP AD10 p 0x3f 0x23
49 KEY_P 25 ANSI_P 0x23 0x19 0x4d 0x4d 19 VK_P 0x50 25 25 XK_p 0x0070 KeyP AD10 p 0x3f 0x23
50 KEY_LEFTBRACE 26 ANSI_LeftBracket 0x21 0x1a 0x54 0x54 47 VK_OEM_4 0xdb 26 26 XK_bracketleft 0x005b BracketLeft AD11 bracket_left 0x40 0x21
51 KEY_LEFTBRACE 26 ANSI_LeftBracket 0x21 0x1a 0x54 0x54 47 VK_OEM_4 0xdb 26 26 XK_braceleft 0x007b BracketLeft AD11 bracket_left 0x40 0x21
52 KEY_RIGHTBRACE 27 ANSI_RightBracket 0x1e 0x1b 0x5b 0x5b 48 VK_OEM_6 0xdd 27 27 XK_bracketright 0x005d BracketRight AD12 bracket_right 0x41 0x1e
53 KEY_RIGHTBRACE 27 ANSI_RightBracket 0x1e 0x1b 0x5b 0x5b 48 VK_OEM_6 0xdd 27 27 XK_braceright 0x007d BracketRight AD12 bracket_right 0x41 0x1e
54 KEY_ENTER 28 Return 0x24 0x1c 0x5a 0x5a 40 VK_RETURN 0x0d 28 28 XK_Return 0xff0d Enter RTRN ret 0x59 0x24
55 KEY_LEFTCTRL 29 Control 0x3b 0x1d 0x14 0x11 224 VK_LCONTROL 0xa2 29 29 XK_Control_L 0xffe3 ControlLeft LCTL ctrl 0x4c 0x36
56 KEY_LEFTCTRL 29 Control 0x3b 0x1d 0x14 0x11 224 VK_CONTROL 0x11 29 29 XK_Control_L 0xffe3 ControlLeft LCTL ctrl 0x4c 0x36
57 KEY_A 30 ANSI_A 0x0 0x1e 0x1c 0x1c 4 VK_A 0x41 30 30 XK_A 0x0041 KeyA AC01 a 0x4d 0x0
58 KEY_A 30 ANSI_A 0x0 0x1e 0x1c 0x1c 4 VK_A 0x41 30 30 XK_a 0x0061 KeyA AC01 a 0x4d 0x0
59 KEY_S 31 ANSI_S 0x1 0x1f 0x1b 0x1b 22 VK_S 0x53 31 31 XK_S 0x0053 KeyS AC02 s 0x4e 0x1
60 KEY_S 31 ANSI_S 0x1 0x1f 0x1b 0x1b 22 VK_S 0x53 31 31 XK_s 0x0073 KeyS AC02 s 0x4e 0x1
61 KEY_D 32 ANSI_D 0x2 0x20 0x23 0x23 7 VK_D 0x44 32 32 XK_D 0x0044 KeyD AC03 d 0x4f 0x2
62 KEY_D 32 ANSI_D 0x2 0x20 0x23 0x23 7 VK_D 0x44 32 32 XK_d 0x0064 KeyD AC03 d 0x4f 0x2
63 KEY_F 33 ANSI_F 0x3 0x21 0x2b 0x2b 9 VK_F 0x46 33 33 XK_F 0x0046 KeyF AC04 f 0x50 0x3
64 KEY_F 33 ANSI_F 0x3 0x21 0x2b 0x2b 9 VK_F 0x46 33 33 XK_f 0x0066 KeyF AC04 f 0x50 0x3
65 KEY_G 34 ANSI_G 0x5 0x22 0x34 0x34 10 VK_G 0x47 34 34 XK_G 0x0047 KeyG AC05 g 0x51 0x5
66 KEY_G 34 ANSI_G 0x5 0x22 0x34 0x34 10 VK_G 0x47 34 34 XK_g 0x0067 KeyG AC05 g 0x51 0x5
67 KEY_H 35 ANSI_H 0x4 0x23 0x33 0x33 11 VK_H 0x48 35 35 XK_H 0x0048 KeyH AC06 h 0x52 0x4
68 KEY_H 35 ANSI_H 0x4 0x23 0x33 0x33 11 VK_H 0x48 35 35 XK_h 0x0068 KeyH AC06 h 0x52 0x4
69 KEY_J 36 ANSI_J 0x26 0x24 0x3b 0x3b 13 VK_J 0x4a 36 36 XK_J 0x004a KeyJ AC07 j 0x53 0x26
70 KEY_J 36 ANSI_J 0x26 0x24 0x3b 0x3b 13 VK_J 0x4a 36 36 XK_j 0x006a KeyJ AC07 j 0x53 0x26
71 KEY_K 37 ANSI_K 0x28 0x25 0x42 0x42 14 VK_K 0x4b 37 37 XK_K 0x004b KeyK AC08 k 0x54 0x28
72 KEY_K 37 ANSI_K 0x28 0x25 0x42 0x42 14 VK_K 0x4b 37 37 XK_k 0x006b KeyK AC08 k 0x54 0x28
73 KEY_L 38 ANSI_L 0x25 0x26 0x4b 0x4b 15 VK_L 0x4c 38 38 XK_L 0x004c KeyL AC09 l 0x55 0x25
74 KEY_L 38 ANSI_L 0x25 0x26 0x4b 0x4b 15 VK_L 0x4c 38 38 XK_l 0x006c KeyL AC09 l 0x55 0x25
75 KEY_SEMICOLON 39 ANSI_Semicolon 0x29 0x27 0x4c 0x4c 51 VK_OEM_1 0xba 39 39 XK_semicolon 0x003b Semicolon AC10 semicolon 0x56 0x29
76 KEY_SEMICOLON 39 ANSI_Semicolon 0x29 0x27 0x4c 0x4c 51 VK_OEM_1 0xba 39 39 XK_colon 0x003a Semicolon AC10 semicolon 0x56 0x29
77 KEY_APOSTROPHE 40 ANSI_Quote 0x27 0x28 0x52 0x52 52 VK_OEM_7 0xde 40 40 XK_apostrophe 0x0027 Quote AC11 apostrophe 0x57 0x27
78 KEY_APOSTROPHE 40 ANSI_Quote 0x27 0x28 0x52 0x52 52 VK_OEM_7 0xde 40 40 XK_quotedbl 0x0022 Quote AC11 apostrophe 0x57 0x27
79 KEY_GRAVE 41 ANSI_Grave 0x32 0x29 0x0e 0x0e 53 VK_OEM_3 0xc0 41 41 XK_grave 0x0060 Backquote TLDE grave_accent 0x2a 0x32
80 KEY_GRAVE 41 ANSI_Grave 0x32 0x29 0x0e 0x0e 53 VK_OEM_3 0xc0 41 41 XK_grave 0x0060 Backquote AB00 grave_accent 0x2a 0x32
81 KEY_GRAVE 41 ANSI_Grave 0x32 0x29 0x0e 0x0e 53 VK_OEM_3 0xc0 41 41 XK_asciitilde 0x007e Backquote TLDE grave_accent 0x2a 0x32
82 KEY_GRAVE 41 ANSI_Grave 0x32 0x29 0x0e 0x0e 53 VK_OEM_3 0xc0 41 41 XK_asciitilde 0x007e Backquote AB00 grave_accent 0x2a 0x32
83 KEY_SHIFT 42 Shift 0x38 0x2a 0x12 0x12 225 VK_SHIFT 0x10 42 42 XK_Shift_L 0xffe1 ShiftLeft LFSH shift 0x63 0x38
84 KEY_LEFTSHIFT 42 Shift 0x38 0x2a 0x12 0x12 225 VK_LSHIFT 0xa0 42 42 XK_Shift_L 0xffe1 ShiftLeft LFSH shift 0x63 0x38
85 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 49 VK_OEM_5 0xdc 43 43 XK_backslash 0x005c Backslash BKSL backslash 0x58 0x2a
86 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 49 VK_OEM_5 0xdc 43 43 XK_backslash 0x005c Backslash AC12 backslash 0x58 0x2a
87 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 49 VK_OEM_5 0xdc 43 43 XK_bar 0x007c Backslash BKSL backslash 0x58 0x2a
88 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 49 VK_OEM_5 0xdc 43 43 XK_bar 0x007c Backslash AC12 backslash 0x58 0x2a
89 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 50 VK_OEM_5 0xdc 43 43 XK_backslash 0x005c Backslash BKSL backslash 0x58 0x2a
90 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 50 VK_OEM_5 0xdc 43 43 XK_backslash 0x005c Backslash AC12 backslash 0x58 0x2a
91 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 50 VK_OEM_5 0xdc 43 43 XK_bar 0x007c Backslash BKSL backslash 0x58 0x2a
92 KEY_BACKSLASH 43 ANSI_Backslash 0x2a 0x2b 0x5d 0x5c 50 VK_OEM_5 0xdc 43 43 XK_bar 0x007c Backslash AC12 backslash 0x58 0x2a
93 KEY_Z 44 ANSI_Z 0x6 0x2c 0x1a 0x1a 29 VK_Z 0x5a 44 44 XK_Z 0x005a KeyZ AB01 z 0x64 0x6
94 KEY_Z 44 ANSI_Z 0x6 0x2c 0x1a 0x1a 29 VK_Z 0x5a 44 44 XK_z 0x007a KeyZ AB01 z 0x64 0x6
95 KEY_X 45 ANSI_X 0x7 0x2d 0x22 0x22 27 VK_X 0x58 45 45 XK_X 0x0058 KeyX AB02 x 0x65 0x7
96 KEY_X 45 ANSI_X 0x7 0x2d 0x22 0x22 27 VK_X 0x58 45 45 XK_x 0x0078 KeyX AB02 x 0x65 0x7
97 KEY_C 46 ANSI_C 0x8 0x2e 0x21 0x21 6 VK_C 0x43 46 46 XK_C 0x0043 KeyC AB03 c 0x66 0x8
98 KEY_C 46 ANSI_C 0x8 0x2e 0x21 0x21 6 VK_C 0x43 46 46 XK_c 0x0063 KeyC AB03 c 0x66 0x8
99 KEY_V 47 ANSI_V 0x9 0x2f 0x2a 0x2a 25 VK_V 0x56 47 47 XK_V 0x0056 KeyV AB04 v 0x67 0x9
100 KEY_V 47 ANSI_V 0x9 0x2f 0x2a 0x2a 25 VK_V 0x56 47 47 XK_v 0x0076 KeyV AB04 v 0x67 0x9
101 KEY_B 48 ANSI_B 0xb 0x30 0x32 0x32 5 VK_B 0x42 48 48 XK_B 0x0042 KeyB AB05 b 0x68 0xb
102 KEY_B 48 ANSI_B 0xb 0x30 0x32 0x32 5 VK_B 0x42 48 48 XK_b 0x0062 KeyB AB05 b 0x68 0xb
103 KEY_N 49 ANSI_N 0x2d 0x31 0x31 0x31 17 VK_N 0x4e 49 49 XK_N 0x004e KeyN AB06 n 0x69 0x2d
104 KEY_N 49 ANSI_N 0x2d 0x31 0x31 0x31 17 VK_N 0x4e 49 49 XK_n 0x006e KeyN AB06 n 0x69 0x2d
105 KEY_M 50 ANSI_M 0x2e 0x32 0x3a 0x3a 16 VK_M 0x4d 50 50 XK_M 0x004d KeyM AB07 m 0x6a 0x2e
106 KEY_M 50 ANSI_M 0x2e 0x32 0x3a 0x3a 16 VK_M 0x4d 50 50 XK_m 0x006d KeyM AB07 m 0x6a 0x2e
107 KEY_COMMA 51 ANSI_Comma 0x2b 0x33 0x41 0x41 54 VK_OEM_COMMA 0xbc 51 51 XK_comma 0x002c Comma AB08 comma 0x6b 0x2b
108 KEY_COMMA 51 ANSI_Comma 0x2b 0x33 0x41 0x41 54 VK_OEM_COMMA 0xbc 51 51 XK_less 0x003c Comma AB08 comma 0x6b 0x2b
109 KEY_DOT 52 ANSI_Period 0x2f 0x34 0x49 0x49 55 VK_OEM_PERIOD 0xbe 52 52 XK_period 0x002e Period AB09 dot 0x6c 0x2f
110 KEY_DOT 52 ANSI_Period 0x2f 0x34 0x49 0x49 55 VK_OEM_PERIOD 0xbe 52 52 XK_greater 0x003e Period AB09 dot 0x6c 0x2f
111 KEY_SLASH 53 ANSI_Slash 0x2c 0x35 0x4a 0x4a 56 VK_OEM_2 0xbf 53 53 XK_slash 0x002f Slash AB10 slash 0x6d 0x2c
112 KEY_SLASH 53 ANSI_Slash 0x2c 0x35 0x4a 0x4a 56 VK_OEM_2 0xbf 53 53 XK_question 0x003f Slash AB10 slash 0x6d 0x2c
113 KEY_RIGHTSHIFT 54 RightShift 0x3c 0x36 0x59 0x59 229 VK_RSHIFT 0xa1 54 54 XK_Shift_R 0xffe2 ShiftRight RTSH shift_r 0x6e 0x7b
114 KEY_KPASTERISK 55 ANSI_KeypadMultiply 0x43 0x37 0x7c 0x7e 85 VK_MULTIPLY 0x6a 55 55 XK_multiply 0x00d7 NumpadMultiply KPMU asterisk 0x2f 0x43
115 KEY_KPASTERISK 55 ANSI_KeypadMultiply 0x43 0x37 0x7c 0x7e 85 VK_MULTIPLY 0x6a 55 55 XK_multiply 0x00d7 NumpadMultiply KPMU kp_multiply 0x2f 0x43
116 KEY_LEFTALT 56 Option 0x3a 0x38 0x11 0x19 226 VK_LMENU 0xa4 56 56 XK_Alt_L 0xffe9 AltLeft LALT alt 0x13 0x3a
117 KEY_LEFTALT 56 Option 0x3a 0x38 0x11 0x19 226 VK_MENU 0x12 56 56 XK_Alt_L 0xffe9 AltLeft LALT alt 0x13 0x3a
118 KEY_SPACE 57 Space 0x31 0x39 0x29 0x29 44 VK_SPACE 0x20 57 57 XK_space 0x0020 Space SPCE spc 0x79 0x31
119 KEY_CAPSLOCK 58 CapsLock 0x39 0x3a 0x58 0x14 57 VK_CAPITAL 0x14 58 58 XK_Caps_Lock 0xffe5 CapsLock CAPS caps_lock 0x77 0x39
120 KEY_F1 59 F1 0x7a 0x3b 0x05 0x07 58 VK_F1 0x70 59 59 XK_F1 0xffbe F1 FK01 f1 0x05 0x7a
121 KEY_F2 60 F2 0x78 0x3c 0x06 0x0f 59 VK_F2 0x71 60 60 XK_F2 0xffbf F2 FK02 f2 0x06 0x78
122 KEY_F3 61 F3 0x63 0x3d 0x04 0x17 60 VK_F3 0x72 61 61 XK_F3 0xffc0 F3 FK03 f3 0x08 0x63
123 KEY_F4 62 F4 0x76 0x3e 0x0c 0x1f 61 VK_F4 0x73 62 62 XK_F4 0xffc1 F4 FK04 f4 0x0a 0x76
124 KEY_F5 63 F5 0x60 0x3f 0x03 0x27 62 VK_F5 0x74 63 63 XK_F5 0xffc2 F5 FK05 f5 0x0c 0x60
125 KEY_F6 64 F6 0x61 0x40 0x0b 0x2f 63 VK_F6 0x75 64 64 XK_F6 0xffc3 F6 FK06 f6 0x0e 0x61
126 KEY_F7 65 F7 0x62 0x41 0x83 0x37 64 VK_F7 0x76 65 65 XK_F7 0xffc4 F7 FK07 f7 0x10 0x62
127 KEY_F8 66 F8 0x64 0x42 0x0a 0x3f 65 VK_F8 0x77 66 66 XK_F8 0xffc5 F8 FK08 f8 0x11 0x64
128 KEY_F9 67 F9 0x65 0x43 0x01 0x47 66 VK_F9 0x78 67 67 XK_F9 0xffc6 F9 FK09 f9 0x12 0x65
129 KEY_F10 68 F10 0x6d 0x44 0x09 0x4f 67 VK_F10 0x79 68 68 XK_F10 0xffc7 F10 FK10 f10 0x07 0x6d
130 KEY_NUMLOCK 69 ANSI_KeypadClear 0x47 0x45 0x77 0x76 83 VK_NUMLOCK 0x90 69 69 XK_Num_Lock 0xff7f NumLock NMLK num_lock 0x62 0x47
131 KEY_SCROLLLOCK 70 0x46 0x7e 0x5f 71 VK_SCROLL 0x91 70 70 XK_Scroll_Lock 0xff14 ScrollLock SCLK scroll_lock 0x17 0x6b
132 KEY_KP7 71 ANSI_Keypad7 0x59 0x47 0x6c 0x6c 95 VK_NUMPAD7 0x67 71 71 XK_KP_7 0xffb7 Numpad7 KP7 kp_7 0x44 0x59
133 KEY_KP8 72 ANSI_Keypad8 0x5b 0x48 0x75 0x75 96 VK_NUMPAD8 0x68 72 72 XK_KP_8 0xffb8 Numpad8 KP8 kp_8 0x45 0x5b
134 KEY_KP9 73 ANSI_Keypad9 0x5c 0x49 0x7d 0x7d 97 VK_NUMPAD9 0x69 73 73 XK_KP_9 0xffb9 Numpad9 KP9 kp_9 0x46 0x5c
135 KEY_KPMINUS 74 ANSI_KeypadMinus 0x4e 0x4a 0x7b 0x4e 86 VK_SUBTRACT 0x6d 74 74 XK_KP_Subtract 0xffad NumpadSubtract KPSU kp_subtract 0x47 0x4e
136 KEY_KP4 75 ANSI_Keypad4 0x56 0x4b 0x6b 0x6b 92 VK_NUMPAD4 0x64 75 75 XK_KP_4 0xffb4 Numpad4 KP4 kp_4 0x5b 0x56
137 KEY_KP5 76 ANSI_Keypad5 0x57 0x4c 0x73 0x73 93 VK_NUMPAD5 0x65 76 76 XK_KP_5 0xffb5 Numpad5 KP5 kp_5 0x5c 0x57
138 KEY_KP6 77 ANSI_Keypad6 0x58 0x4d 0x74 0x74 94 VK_NUMPAD6 0x66 77 77 XK_KP_6 0xffb6 Numpad6 KP6 kp_6 0x5d 0x58
139 KEY_KPPLUS 78 ANSI_KeypadPlus 0x45 0x4e 0x79 0x7c 87 VK_ADD 0x6b 78 78 XK_KP_Add 0xffab NumpadAdd KPAD kp_add 0x7d 0x45
140 KEY_KP1 79 ANSI_Keypad1 0x53 0x4f 0x69 0x69 89 VK_NUMPAD1 0x61 79 79 XK_KP_1 0xffb1 Numpad1 KP1 kp_1 0x70 0x53
141 KEY_KP2 80 ANSI_Keypad2 0x54 0x50 0x72 0x72 90 VK_NUMPAD2 0x62 80 80 XK_KP_2 0xffb2 Numpad2 KP2 kp_2 0x71 0x54
142 KEY_KP3 81 ANSI_Keypad3 0x55 0x51 0x7a 0x7a 91 VK_NUMPAD3 0x63 81 81 XK_KP_3 0xffb3 Numpad3 KP3 kp_3 0x72 0x55
143 KEY_KP0 82 ANSI_Keypad0 0x52 0x52 0x70 0x70 98 VK_NUMPAD0 0x60 82 82 XK_KP_0 0xffb0 Numpad0 KP0 kp_0 0x5e 0x52
144 KEY_KPDOT 83 ANSI_KeypadDecimal 0x41 0x53 0x71 0x71 99 VK_DECIMAL 0x6e 83 83 XK_KP_Decimal 0xffae NumpadDecimal KPDL kp_decimal 0x32 0x41
145 KEY_KPDOT 83 ANSI_KeypadDecimal 0x41 0x53 0x71 0x71 99 VK_DECIMAL 0x6e 83 83 XK_KP_Decimal 0xffae NumpadDecimal KPDC kp_decimal 0x32 0x41
146 84 0x54
147 KEY_ZENKAKUHANKAKU 85 0x76 0x5f 148 Lang5 HZTG
148 KEY_102ND 86 0x56 0x61 0x13 100 VK_OEM_102 0xe2 86 86 IntlBackslash LSGT less 0x7c
149 KEY_F11 87 F11 0x67 0x57 0x78 0x56 68 VK_F11 0x7a 87 87 XK_F11 0xffc8 F11 FK11 f11 0x09 0x67
150 KEY_F12 88 F12 0x6f 0x58 0x07 0x5e 69 VK_F12 0x7b 88 88 XK_F12 0xffc9 F12 FK12 f12 0x0b 0x6f
151 KEY_RO 89 JIS_Underscore 0x5e 0x73 0x51 135 IntlRo AB11 ro
152 KEY_KATAKANA 90 0x78 0x63 146 VK_KANA 0x15 Katakana KATA
153 KEY_KATAKANA 90 0x78 0x63 146 VK_KANA 0x15 Lang3 KATA
154 KEY_HIRAGANA 91 0x77 0x62 0x87 147 Hiragana HIRA hiragana
155 KEY_HIRAGANA 91 0x77 0x62 0x87 147 Lang4 HIRA hiragana
156 KEY_HENKAN 92 0x79 0x64 0x86 138 Convert HENK henkan
157 KEY_KATAKANAHIRAGANA 93 0x70 0x13 0x87 136 0xc8 0xc8 KanaMode HKTG katakanahiragana
158 KEY_MUHENKAN 94 0x7b 0x67 0x85 139 NonConvert NFER muhenkan
159 KEY_MUHENKAN 94 0x7b 0x67 0x85 139 NonConvert MUHE muhenkan
160 KEY_KPJPCOMMA 95 JIS_KeypadComma 0x5f 0x5c 0x27 140 XK_KP_Separator 0xffac KPSP
161 KEY_KPJPCOMMA 95 JIS_KeypadComma 0x5f 0x5c 0x27 140 XK_KP_Separator 0xffac JPCM
162 KEY_KPENTER 96 ANSI_KeypadEnter 0x4c 0xe01c 0xe05a 0x79 88 0x64 0x64 XK_KP_Enter 0xff8d NumpadEnter KPEN kp_enter 0x5a 0x4c
163 KEY_RIGHTCTRL 97 RightControl 0x3e 0xe01d 0xe014 0x58 228 VK_RCONTROL 0xa3 0x65 0x65 XK_Control_R 0xffe4 ControlRight RCTL ctrl_r 0x4c 0x7d
164 KEY_KPSLASH 98 ANSI_KeypadDivide 0x4b 0xe035 0xe04a 0x4a 84 VK_DIVIDE 0x6f 0x68 0x68 XK_KP_Divide 0xffaf NumpadDivide KPDV kp_divide 0x2e 0x4b
165 KEY_SYSRQ 99 0x54 0x7f 0x57 70 VK_SNAPSHOT 0x2c 0x67 0x67 XK_Sys_Req 0xff15 PrintScreen PRSC print 0x16 0x69
166 KEY_SYSRQ 99 0x54 0x7f 0x57 70 VK_SNAPSHOT 0x2c 0x67 0x67 XK_Sys_Req 0xff15 PrintScreen SYRQ sysrq 0x16 0x69
167 KEY_RIGHTALT 100 RightOption 0x3d 0xe038 0xe011 0x39 230 VK_RMENU 0xa5 0x69 0x69 XK_Alt_R 0xffea AltRight ALGR alt_r 0x0d 0x7c
168 KEY_RIGHTALT 100 RightOption 0x3d 0xe038 0xe011 0x39 230 VK_RMENU 0xa5 0x69 0x69 XK_Alt_R 0xffea AltRight RALT alt_r 0x0d 0x7c
169 KEY_LINEFEED 101 0x5b LNFD lf 0x6f
170 KEY_HOME 102 Home 0x73 0xe047 0xe06c 0x6e 74 VK_HOME 0x24 0x59 0x59 XK_Home 0xff50 Home HOME home 0x34 0x73
171 KEY_UP 103 UpArrow 0x7e 0xe048 0xe075 0x63 82 VK_UP 0x26 0x5a 0x5a XK_Up 0xff52 ArrowUp UP up 0x14 0x3e
172 KEY_PAGEUP 104 PageUp 0x74 0xe049 0xe07d 0x6f 75 VK_PRIOR 0x21 0x5b 0x5b XK_Page_Up 0xff55 PageUp PGUP pgup 0x60 0x74
173 KEY_LEFT 105 LeftArrow 0x7b 0xe04b 0xe06b 0x61 80 VK_LEFT 0x25 0x5c 0x5c XK_Left 0xff51 ArrowLeft LEFT left 0x18 0x3b
174 KEY_RIGHT 106 RightArrow 0x7c 0xe04d 0xe074 0x6a 79 VK_RIGHT 0x27 0x5e 0x5e XK_Right 0xff53 ArrowRight RGHT right 0x1c 0x3c
175 KEY_END 107 End 0x77 0xe04f 0xe069 0x65 77 VK_END 0x23 0x5f 0x5f XK_End 0xff57 End END end 0x4a 0x77
176 KEY_DOWN 108 DownArrow 0x7d 0xe050 0xe072 0x60 81 VK_DOWN 0x28 0x60 0x60 XK_Down 0xff54 ArrowDown DOWN down 0x1b 0x3d
177 KEY_PAGEDOWN 109 PageDown 0x79 0xe051 0xe07a 0x6d 78 VK_NEXT 0x22 0x61 0x61 XK_Page_Down 0xff56 PageDown PGDN pgdn 0x7b 0x79
178 KEY_INSERT 110 0xe052 0xe070 0x67 73 VK_INSERT 0x2d 0x62 0x62 XK_Insert 0xff63 Insert INS insert 0x2c 0x72
179 KEY_DELETE 111 ForwardDelete 0x75 0xe053 0xe071 0x64 76 VK_DELETE 0x2e 0x63 0x63 XK_Delete 0xffff Delete DEL delete 0x42 0x75
180 KEY_DELETE 111 ForwardDelete 0x75 0xe053 0xe071 0x64 76 VK_DELETE 0x2e 0x63 0x63 XK_Delete 0xffff Delete DELE 0x42 0x75
181 KEY_MACRO 112 0xe06f 0xe06f 0x8e I120
182 KEY_MUTE 113 Mute 0x4a 0xe020 0xe023 0x9c 127 VK_VOLUME_MUTE 0xad AudioVolumeMute MUTE audiomute
183 KEY_MUTE 113 Mute 0x4a 0xe020 0xe023 0x9c 239 VK_VOLUME_MUTE 0xad AudioVolumeMute MUTE audiomute
184 KEY_VOLUMEDOWN 114 VolumeDown 0x49 0xe02e 0xe021 0x9d 129 VK_VOLUME_DOWN 0xae AudioVolumeDown VOL- volumedown
185 KEY_VOLUMEDOWN 114 VolumeDown 0x49 0xe02e 0xe021 0x9d 238 VK_VOLUME_DOWN 0xae AudioVolumeDown VOL- volumedown
186 KEY_VOLUMEUP 115 VolumeUp 0x48 0xe030 0xe032 0x95 128 VK_VOLUME_UP 0xaf AudioVolumeUp VOL+ volumeup
187 KEY_VOLUMEUP 115 VolumeUp 0x48 0xe030 0xe032 0x95 237 VK_VOLUME_UP 0xaf AudioVolumeUp VOL+ volumeup
188 KEY_POWER 116 0xe05e 0xe037 102 Power POWR power 0x7f7f
189 KEY_KPEQUAL 117 ANSI_KeypadEquals 0x51 0x59 0x0f 103 0x76 0x76 XK_KP_Equal 0xffbd NumpadEqual KPEQ kp_equals 0x2d 0x51
190 KEY_KPPLUSMINUS 118 0xe04e 0xe079 I126
191 KEY_PAUSE 119 0xe046 0xe077 0x62 72 VK_PAUSE 0x013 0x66 0x66 XK_Pause 0xff13 Pause PAUS pause 0x15 0x71
192 KEY_SCALE 120 0xe00b I128
193 KEY_KPCOMMA 121 0x7e 0x6d 133 VK_SEPARATOR?? 0x6c NumpadComma KPCO kp_comma
194 KEY_KPCOMMA 121 0x7e 0x6d 133 VK_SEPARATOR?? 0x6c NumpadComma I129
195 KEY_HANGEUL 122 JIS_Kana 0x68 0x72 144 VK_HANGEUL 0x15 0x71 Lang1 HNGL
196 KEY_HANJA 123 JIS_Eisu 0x66 0x71 145 VK_HANJA 0x19 0x72 Lang2 HJCV
197 KEY_YEN 124 JIS_Yen 0x5d 0x7d 0x6a 0x5d 137 0x7d 0x7d IntlYen AE13 yen
198 KEY_LEFTMETA 125 Command 0x37 0xe05b 0xe01f 0x8b 227 VK_LWIN 0x5b 0x6b 0x6b XK_Meta_L 0xffe7 MetaLeft LMTA meta_l 0x78 0x37
199 KEY_LEFTMETA 125 Command 0x37 0xe05b 0xe01f 0x8b 227 VK_LWIN 0x5b 0x6b 0x6b XK_Meta_L 0xffe7 MetaLeft LWIN meta_l 0x78 0x37
200 KEY_RIGHTMETA 126 RightCommand 0x36 0xe05c 0xe027 0x8c 231 VK_RWIN 0x5c 0x6c 0x6c XK_Meta_R 0xffe8 MetaRight RMTA meta_r 0x7a 0x37
201 KEY_RIGHTMETA 126 RightCommand 0x36 0xe05c 0xe027 0x8c 231 VK_RWIN 0x5c 0x6c 0x6c XK_Meta_R 0xffe8 MetaRight RWIN meta_r 0x7a 0x37
202 KEY_COMPOSE 127 0x6e 0xe05d 0xe02f 0x8d 101 VK_APPS 0x5d 0x6d 0x6d ContextMenu MENU compose 0x43
203 KEY_COMPOSE 127 0x6e 0xe05d 0xe02f 0x8d 101 VK_APPS 0x5d 0x6d 0x6d ContextMenu COMP compose 0x43
204 KEY_STOP 128 0xe068 0xe028 0x0a 120 VK_BROWSER_STOP 0xa9 BrowserStop STOP stop 0x01
205 KEY_STOP 128 0xe068 0xe028 0x0a 243 VK_BROWSER_STOP 0xa9 BrowserStop STOP stop 0x01
206 KEY_AGAIN 129 0xe005 0x0b 121 Again AGAI again 0x03
207 KEY_PROPS 130 0xe006 0x0c Props PROP props 0x19
208 KEY_UNDO 131 0xe007 0x10 122 Undo UNDO undo 0x1a
209 KEY_FRONT 132 0xe00c 119 FRNT front 0x31
210 KEY_COPY 133 0xe078 0x18 124 Copy COPY copy 0x33
211 KEY_OPEN 134 0x64 0x20 116 Open OPEN open 0x48
212 KEY_PASTE 135 0x65 0x28 125 Paste PAST paste 0x49
213 KEY_FIND 136 0xe041 0x30 126 Find FIND find 0x5f
214 KEY_FIND 136 0xe041 0x30 244 Find FIND find 0x5f
215 KEY_CUT 137 0xe03c 0x38 123 Cut CUT cut 0x61
216 KEY_HELP 138 Help 0x72 0xe075 0x09 117 VK_HELP 0x2f XK_Help 0xff6a Help HELP help 0x76
217 KEY_MENU 139 0xe01e 0x91 118 I147 menu
218 KEY_CALC 140 0xe021 0xe02b 0xa3 251 LaunchApp2 I148 calculator
219 KEY_SETUP 141 0x66 I149
220 KEY_SLEEP 142 0xe05f 0xe03f 248 VK_SLEEP 0x5f Sleep I150 sleep
221 KEY_WAKEUP 143 0xe063 0xe05e WakeUp I151 wake
222 KEY_FILE 144 0x67 I152
223 KEY_SENDFILE 145 0x68 I153
224 KEY_DELETEFILE 146 0x69 I154
225 KEY_XFER 147 0xe013 0xa2 XFER
226 KEY_XFER 147 0xe013 0xa2 I155
227 KEY_PROG1 148 0xe01f 0xa0 I156
228 KEY_PROG2 149 0xe017 0xa1 I157
229 KEY_WWW 150 0xe002 240 I158
230 KEY_MSDOS 151 0x6a I159
231 KEY_SCREENLOCK 152 0xe012 0x96 249 I160
232 KEY_DIRECTION 153 0x6b I161
233 KEY_CYCLEWINDOWS 154 0xe026 0x9b I162
234 KEY_MAIL 155 0xe06c 0xe048 LaunchMail I163 mail
235 KEY_BOOKMARKS 156 0xe066 0xe018 BrowserFavorites I164 ac_bookmarks
236 KEY_COMPUTER 157 0xe06b 0xe040 LaunchApp1 I165 computer
237 KEY_BACK 158 0xe06a 0xe038 241 VK_BROWSER_BACK 0xa6 BrowserBack I166 ac_back
238 KEY_FORWARD 159 0xe069 0xe030 242 VK_BROWSER_FORWARD 0xa7 BrowserForward I167 ac_forward
239 KEY_CLOSECD 160 0xe023 0x9a I168
240 KEY_EJECTCD 161 0x6c 236 I169
241 KEY_EJECTCLOSECD 162 0xe07d Eject I170
242 KEY_NEXTSONG 163 0xe019 0xe04d 0x93 235 VK_MEDIA_NEXT_TRACK 0xb0 MediaTrackNext I171 audionext
243 KEY_PLAYPAUSE 164 0xe022 0xe034 232 VK_MEDIA_PLAY_PAUSE 0xb3 MediaPlayPause I172 audioplay
244 KEY_PREVIOUSSONG 165 0xe010 0xe015 0x94 234 VK_MEDIA_PREV_TRACK 0xb1 MediaTrackPrevious I173 audioprev
245 KEY_STOPCD 166 0xe024 0xe03b 0x98 233 VK_MEDIA_STOP 0xb2 MediaStop I174 audiostop
246 KEY_RECORD 167 0xe031 0x9e I175
247 KEY_REWIND 168 0xe018 0x9f I176
248 KEY_PHONE 169 0x63 I177
249 KEY_ISO 170 ISO_Section 0xa I178
250 KEY_CONFIG 171 0xe001 I179
251 KEY_HOMEPAGE 172 0xe032 0xe03a 0x97 VK_BROWSER_HOME 0xac BrowserHome I180 ac_home
252 KEY_REFRESH 173 0xe067 0xe020 250 VK_BROWSER_REFRESH 0xa8 BrowserRefresh I181 ac_refresh
253 KEY_EXIT 174 I182
254 KEY_MOVE 175 I183
255 KEY_EDIT 176 0xe008 247 I184
256 KEY_SCROLLUP 177 0x75 245 I185
257 KEY_SCROLLDOWN 178 0xe00f 246 I186
258 KEY_KPLEFTPAREN 179 0xe076 182 NumpadParenLeft I187
259 KEY_KPRIGHTPAREN 180 0xe07b 183 NumpadParenRight I188
260 KEY_NEW 181 0xe009 I189
261 KEY_REDO 182 0xe00a I190
262 KEY_F13 183 F13 0x69 0x5d 0x2f 0x7f 104 VK_F13 0x7c 0x6e 0x6e F13 FK13 0x69
263 KEY_F14 184 F14 0x6b 0x5e 0x37 0x80 105 VK_F14 0x7d 0x6f 0x6f F14 FK14 0x6b
264 KEY_F15 185 F15 0x71 0x5f 0x3f 0x81 106 VK_F15 0x7e 0x70 0x70 F15 FK15 0x71
265 KEY_F16 186 F16 0x6a 0x55 0x82 107 VK_F16 0x7f 0x71 0x71 F16 FK16
266 KEY_F17 187 F17 0x40 0xe003 0x83 108 VK_F17 0x80 0x72 0x72 F17 FK17
267 KEY_F18 188 F18 0x4f 0xe077 109 VK_F18 0x81 F18 FK18
268 KEY_F19 189 F19 0x50 0xe004 110 VK_F19 0x82 F19 FK19
269 KEY_F20 190 F20 0x5a 0x5a 111 VK_F20 0x83 F20 FK20
270 KEY_F21 191 0x74 112 VK_F21 0x84 F21 FK21
271 KEY_F22 192 0xe079 113 VK_F22 0x85 F22 FK22
272 KEY_F23 193 0x6d 114 VK_F23 0x86 F23 FK23
273 KEY_F24 194 0x6f 115 VK_F24 0x87 F24 FK24
274 195 0xe015
275 196 0xe016
276 197 0xe01a
277 198 0xe01b
278 199 0xe027
279 KEY_PLAYCD 200 0xe028 I208
280 KEY_PAUSECD 201 0xe029 I209
281 KEY_PROG3 202 0xe02b I210
282 KEY_PROG4 203 0xe02c I211
283 KEY_DASHBOARD 204 0xe02d I212
284 KEY_SUSPEND 205 0xe025 Suspend I213
285 KEY_CLOSE 206 0xe02f I214
286 KEY_PLAY 207 0xe033 VK_PLAY 0xfa I215
287 KEY_FASTFORWARD 208 0xe034 I216
288 KEY_BASSBOOST 209 0xe036 I217
289 KEY_PRINT 210 0xe039 VK_PRINT 0x2a I218
290 KEY_HP 211 0xe03a I219
291 KEY_CAMERA 212 0xe03b I220
292 KEY_SOUND 213 0xe03d I221
293 KEY_QUESTION 214 0xe03e I222
294 KEY_EMAIL 215 0xe03f VK_LAUNCH_MAIL 0xb4 I223
295 KEY_CHAT 216 0xe040 I224
296 KEY_SEARCH 217 0xe065 0xe010 VK_BROWSER_SEARCH 0xaa BrowserSearch I225
297 KEY_CONNECT 218 0xe042 I226
298 KEY_FINANCE 219 0xe043 I227
299 KEY_SPORT 220 0xe044 I228
300 KEY_SHOP 221 0xe045 I229
301 KEY_ALTERASE 222 0xe014 I230
302 KEY_CANCEL 223 0xe04a I231
303 KEY_BRIGHTNESSDOWN 224 0xe04c I232
304 KEY_BRIGHTNESSUP 225 0xe054 I233
305 KEY_MEDIA 226 0xe06d 0xe050 MediaSelect I234 mediaselect
306 KEY_SWITCHVIDEOMODE 227 0xe056 I235
307 KEY_KBDILLUMTOGGLE 228 0xe057 I236
308 KEY_KBDILLUMDOWN 229 0xe058 I237
309 KEY_KBDILLUMUP 230 0xe059 I238
310 KEY_SEND 231 0xe05a I239
311 KEY_REPLY 232 0xe064 I240
312 KEY_FORWARDMAIL 233 0xe00e I241
313 KEY_SAVE 234 0xe055 I242
314 KEY_DOCUMENTS 235 0xe070 I243
315 KEY_BATTERY 236 0xe071 I244
316 KEY_BLUETOOTH 237 0xe072 I245
317 KEY_WLAN 238 0xe073 I246
318 KEY_UWB 239 0xe074 I247
319 KEY_UNKNOWN 240 I248
320 KEY_VIDEO_NEXT 241 I249
321 KEY_VIDEO_PREV 242 I250
322 KEY_BRIGHTNESS_CYCLE 243 I251
323 KEY_BRIGHTNESS_ZERO 244 I252
324 KEY_DISPLAY_OFF 245 I253
325 KEY_WIMAX 246
326 247
327 248
328 249
329 250
330 251
331 252
332 253
333 254
334 255 0xe012
335 BTN_MISC 0x100
336 BTN_0 0x100 VK_LBUTTON 0x01
337 BTN_1 0x101 VK_RBUTTON 0x02
338 BTN_2 0x102 VK_MBUTTON 0x04
339 BTN_3 0x103 VK_XBUTTON1 0x05
340 BTN_4 0x104 VK_XBUTTON2 0x06
341 BTN_5 0x105
342 BTN_6 0x106
343 BTN_7 0x107
344 BTN_8 0x108
345 BTN_9 0x109
346 BTN_MOUSE 0x110
347 BTN_LEFT 0x110
348 BTN_RIGHT 0x111
349 BTN_MIDDLE 0x112
350 BTN_SIDE 0x113
351 BTN_EXTRA 0x114
352 BTN_FORWARD 0x115
353 BTN_BACK 0x116
354 BTN_TASK 0x117
355 BTN_JOYSTICK 0x120
356 BTN_TRIGGER 0x120
357 BTN_THUMB 0x121
358 BTN_THUMB2 0x122
359 BTN_TOP 0x123
360 BTN_TOP2 0x124
361 BTN_PINKIE 0x125
362 BTN_BASE 0x126
363 BTN_BASE2 0x127
364 BTN_BASE3 0x128
365 BTN_BASE4 0x129
366 BTN_BASE5 0x12a
367 BTN_BASE6 0x12b
368 BTN_DEAD 0x12f
369 BTN_GAMEPAD 0x130
370 BTN_A 0x130
371 BTN_B 0x131
372 BTN_C 0x132
373 BTN_X 0x133
374 BTN_Y 0x134
375 BTN_Z 0x135
376 BTN_TL 0x136
377 BTN_TR 0x137
378 BTN_TL2 0x138
379 BTN_TR2 0x139
380 BTN_SELECT 0x13a
381 BTN_START 0x13b
382 BTN_MODE 0x13c
383 BTN_THUMBL 0x13d
384 BTN_THUMBR 0x13e
385 BTN_DIGI 0x140
386 BTN_TOOL_PEN 0x140
387 BTN_TOOL_RUBBER 0x141
388 BTN_TOOL_BRUSH 0x142
389 BTN_TOOL_PENCIL 0x143
390 BTN_TOOL_AIRBRUSH 0x144
391 BTN_TOOL_FINGER 0x145
392 BTN_TOOL_MOUSE 0x146
393 BTN_TOOL_LENS 0x147
394 BTN_TOUCH 0x14a
395 BTN_STYLUS 0x14b
396 BTN_STYLUS2 0x14c
397 BTN_TOOL_DOUBLETAP 0x14d
398 BTN_TOOL_TRIPLETAP 0x14e
399 BTN_TOOL_QUADTAP 0x14f
400 BTN_WHEEL 0x150
401 BTN_GEAR_DOWN 0x150
402 BTN_GEAR_UP 0x151
403 KEY_OK 0x160
404 KEY_SELECT 0x161 VK_SELECT 0x29 XK_Select 0xff60 Select SELE
405 KEY_GOTO 0x162
406 KEY_CLEAR 0x163 NumpadClear CLR
407 KEY_POWER2 0x164
408 KEY_OPTION 0x165
409 KEY_INFO 0x166
410 KEY_TIME 0x167
411 KEY_VENDOR 0x168
412 KEY_ARCHIVE 0x169
413 KEY_PROGRAM 0x16a
414 KEY_CHANNEL 0x16b
415 KEY_FAVORITES 0x16c VK_BROWSER_FAVOURITES 0xab
416 KEY_EPG 0x16d
417 KEY_PVR 0x16e
418 KEY_MHP 0x16f
419 KEY_LANGUAGE 0x170
420 KEY_TITLE 0x171
421 KEY_SUBTITLE 0x172
422 KEY_ANGLE 0x173
423 KEY_ZOOM 0x174 VK_ZOOM 0xfb
424 KEY_MODE 0x175
425 KEY_KEYBOARD 0x176
426 KEY_SCREEN 0x177
427 KEY_PC 0x178
428 KEY_TV 0x179
429 KEY_TV2 0x17a
430 KEY_VCR 0x17b
431 KEY_VCR2 0x17c
432 KEY_SAT 0x17d
433 KEY_SAT2 0x17e
434 KEY_CD 0x17f
435 KEY_TAPE 0x180
436 KEY_RADIO 0x181
437 KEY_TUNER 0x182
438 KEY_PLAYER 0x183
439 KEY_TEXT 0x184
440 KEY_DVD 0x185
441 KEY_AUX 0x186
442 KEY_MP3 0x187
443 KEY_AUDIO 0x188
444 KEY_VIDEO 0x189
445 KEY_DIRECTORY 0x18a
446 KEY_LIST 0x18b
447 KEY_MEMO 0x18c
448 KEY_CALENDAR 0x18d
449 KEY_RED 0x18e
450 KEY_GREEN 0x18f
451 KEY_YELLOW 0x190
452 KEY_BLUE 0x191
453 KEY_CHANNELUP 0x192
454 KEY_CHANNELDOWN 0x193
455 KEY_FIRST 0x194
456 KEY_LAST 0x195
457 KEY_AB 0x196
458 KEY_NEXT 0x197
459 KEY_RESTART 0x198
460 KEY_SLOW 0x199
461 KEY_SHUFFLE 0x19a
462 KEY_BREAK 0x19b BREA
463 KEY_BREAK 0x19b BRK
464 KEY_PREVIOUS 0x19c
465 KEY_DIGITS 0x19d
466 KEY_TEEN 0x19e
467 KEY_TWEN 0x19f
468 KEY_VIDEOPHONE 0x1a0
469 KEY_GAMES 0x1a1
470 KEY_ZOOMIN 0x1a2
471 KEY_ZOOMOUT 0x1a3
472 KEY_ZOOMRESET 0x1a4
473 KEY_WORDPROCESSOR 0x1a5
474 KEY_EDITOR 0x1a6
475 KEY_SPREADSHEET 0x1a7
476 KEY_GRAPHICSEDITOR 0x1a8
477 KEY_PRESENTATION 0x1a9
478 KEY_DATABASE 0x1aa
479 KEY_NEWS 0x1ab
480 KEY_VOICEMAIL 0x1ac
481 KEY_ADDRESSBOOK 0x1ad
482 KEY_MESSENGER 0x1ae
483 KEY_DISPLAYTOGGLE 0x1af
484 KEY_SPELLCHECK 0x1b0
485 KEY_LOGOFF 0x1b1
486 KEY_DOLLAR 0x1b2
487 KEY_EURO 0x1b3
488 KEY_FRAMEBACK 0x1b4
489 KEY_FRAMEFORWARD 0x1b5
490 KEY_CONTEXT_MENU 0x1b6
491 KEY_MEDIA_REPEAT 0x1b7
492 KEY_DEL_EOL 0x1c0
493 KEY_DEL_EOS 0x1c1
494 KEY_INS_LINE 0x1c2
495 KEY_DEL_LINE 0x1c3
496 KEY_FN 0x1d0 Function 0x3f Fn
497 KEY_FN_ESC 0x1d1
498 KEY_FN_F1 0x1d2
499 KEY_FN_F2 0x1d3
500 KEY_FN_F3 0x1d4
501 KEY_FN_F4 0x1d5
502 KEY_FN_F5 0x1d6
503 KEY_FN_F6 0x1d7
504 KEY_FN_F7 0x1d8
505 KEY_FN_F8 0x1d9
506 KEY_FN_F9 0x1da
507 KEY_FN_F10 0x1db
508 KEY_FN_F11 0x1dc
509 KEY_FN_F12 0x1dd
510 KEY_FN_1 0x1de
511 KEY_FN_2 0x1df
512 KEY_FN_D 0x1e0
513 KEY_FN_E 0x1e1
514 KEY_FN_F 0x1e2
515 KEY_FN_S 0x1e3
516 KEY_FN_B 0x1e4
517 KEY_BRL_DOT1 0x1f1
518 KEY_BRL_DOT2 0x1f2
519 KEY_BRL_DOT3 0x1f3
520 KEY_BRL_DOT4 0x1f4
521 KEY_BRL_DOT5 0x1f5
522 KEY_BRL_DOT6 0x1f6
523 KEY_BRL_DOT7 0x1f7
524 KEY_BRL_DOT8 0x1f8
525 KEY_BRL_DOT9 0x1f9
526 KEY_BRL_DOT10 0x1fa
527 KEY_NUMERIC_0 0x200
528 KEY_NUMERIC_1 0x201
529 KEY_NUMERIC_2 0x202
530 KEY_NUMERIC_3 0x203
531 KEY_NUMERIC_4 0x204
532 KEY_NUMERIC_5 0x205
533 KEY_NUMERIC_6 0x206
534 KEY_NUMERIC_7 0x207
535 KEY_NUMERIC_8 0x208
536 KEY_NUMERIC_9 0x209
537 KEY_NUMERIC_STAR 0x20a NumpadStar
538 KEY_NUMERIC_POUND 0x20b NumpadHash
539 KEY_RFKILL 0x20c

View File

@@ -1 +0,0 @@
project('keycodemapdb')

View File

@@ -1,11 +0,0 @@
osx2win32.*
osx2win32_name.*
osx2xkb.*
osx2xkb_name.*
html2win32.*
html2win32_name.*
osx.*
osx_name.*
stdc
stdc++
node_modules/

View File

@@ -1,150 +0,0 @@
TESTS := stdc stdc++ python2 python3 javascript
check: $(TESTS)
@set -e; for fn in $(TESTS); do \
./$$fn; \
echo $$fn: OK; \
done
@echo Done.
GEN := ../tools/keymap-gen
DATA := ../data/keymaps.csv
SOURCES := $(GEN) $(DATA)
.DELETE_ON_ERROR:
stdc: stdc.c osx2win32.h osx2win32.c osx2win32_name.h osx2win32_name.c \
osx2xkb.h osx2xkb.c osx2xkb_name.h osx2xkb_name.c \
html2win32.h html2win32.c html2win32_name.h html2win32_name.c \
osx.h osx.c osx_name.h osx_name.c
$(CC) -Wall -o $@ $(filter %.c, $^)
osx2win32.c: $(SOURCES)
$(GEN) --lang stdc code-map $(DATA) osx win32 > $@
osx2win32.h: $(SOURCES)
$(GEN) --lang stdc-header code-map $(DATA) osx win32 > $@
osx2win32_name.c: $(SOURCES)
$(GEN) --lang stdc name-map $(DATA) osx win32 > $@
osx2win32_name.h: $(SOURCES)
$(GEN) --lang stdc-header name-map $(DATA) osx win32 > $@
osx2xkb.c: $(SOURCES)
$(GEN) --lang stdc code-map $(DATA) osx xkb > $@
osx2xkb.h: $(SOURCES)
$(GEN) --lang stdc-header code-map $(DATA) osx xkb > $@
osx2xkb_name.c: $(SOURCES)
$(GEN) --lang stdc name-map $(DATA) osx xkb > $@
osx2xkb_name.h: $(SOURCES)
$(GEN) --lang stdc-header name-map $(DATA) osx xkb > $@
html2win32.c: $(SOURCES)
$(GEN) --lang stdc code-map $(DATA) html win32 > $@
html2win32.h: $(SOURCES)
$(GEN) --lang stdc-header code-map $(DATA) html win32 > $@
html2win32_name.c: $(SOURCES)
$(GEN) --lang stdc name-map $(DATA) html win32 > $@
html2win32_name.h: $(SOURCES)
$(GEN) --lang stdc-header name-map $(DATA) html win32 > $@
osx.c: $(SOURCES)
$(GEN) --lang stdc code-table $(DATA) osx > $@
osx.h: $(SOURCES)
$(GEN) --lang stdc-header code-table $(DATA) osx > $@
osx_name.c: $(SOURCES)
$(GEN) --lang stdc name-table $(DATA) osx > $@
osx_name.h: $(SOURCES)
$(GEN) --lang stdc-header name-table $(DATA) osx > $@
stdc++: stdc++.cc osx2win32.hh osx2win32.cc osx2win32_name.hh osx2win32_name.cc \
osx2xkb.hh osx2xkb.cc osx2xkb_name.hh osx2xkb_name.cc \
html2win32.hh html2win32.cc html2win32_name.hh html2win32_name.cc \
osx.hh osx.cc osx_name.hh osx_name.cc
$(CXX) -Wall -std=c++11 -o $@ $(filter %.cc, $^)
osx2win32.cc: $(SOURCES)
$(GEN) --lang stdc++ code-map $(DATA) osx win32 > $@
osx2win32.hh: $(SOURCES)
$(GEN) --lang stdc++-header code-map $(DATA) osx win32 > $@
osx2win32_name.cc: $(SOURCES)
$(GEN) --lang stdc++ name-map $(DATA) osx win32 > $@
osx2win32_name.hh: $(SOURCES)
$(GEN) --lang stdc++-header name-map $(DATA) osx win32 > $@
osx2xkb.cc: $(SOURCES)
$(GEN) --lang stdc++ code-map $(DATA) osx xkb > $@
osx2xkb.hh: $(SOURCES)
$(GEN) --lang stdc++-header code-map $(DATA) osx xkb > $@
osx2xkb_name.cc: $(SOURCES)
$(GEN) --lang stdc++ name-map $(DATA) osx xkb > $@
osx2xkb_name.hh: $(SOURCES)
$(GEN) --lang stdc++-header name-map $(DATA) osx xkb > $@
html2win32.cc: $(SOURCES)
$(GEN) --lang stdc++ code-map $(DATA) html win32 > $@
html2win32.hh: $(SOURCES)
$(GEN) --lang stdc++-header code-map $(DATA) html win32 > $@
html2win32_name.cc: $(SOURCES)
$(GEN) --lang stdc++ name-map $(DATA) html win32 > $@
html2win32_name.hh: $(SOURCES)
$(GEN) --lang stdc++-header name-map $(DATA) html win32 > $@
osx.cc: $(SOURCES)
$(GEN) --lang stdc++ code-table $(DATA) osx > $@
osx.hh: $(SOURCES)
$(GEN) --lang stdc++-header code-table $(DATA) osx > $@
osx_name.cc: $(SOURCES)
$(GEN) --lang stdc++ name-table $(DATA) osx > $@
osx_name.hh: $(SOURCES)
$(GEN) --lang stdc++-header name-table $(DATA) osx > $@
python2: osx2win32.py osx2win32_name.py \
osx2xkb.py osx2xkb_name.py \
html2win32.py html2win32_name.py \
osx.py osx_name.py
osx2win32.py: $(SOURCES)
$(GEN) --lang python2 code-map $(DATA) osx win32 > $@
osx2win32_name.py: $(SOURCES)
$(GEN) --lang python2 name-map $(DATA) osx win32 > $@
osx2xkb.py: $(SOURCES)
$(GEN) --lang python2 code-map $(DATA) osx xkb > $@
osx2xkb_name.py: $(SOURCES)
$(GEN) --lang python2 name-map $(DATA) osx xkb > $@
html2win32.py: $(SOURCES)
$(GEN) --lang python2 code-map $(DATA) html win32 > $@
html2win32_name.py: $(SOURCES)
$(GEN) --lang python2 name-map $(DATA) html win32 > $@
osx.py: $(SOURCES)
$(GEN) --lang python2 code-table $(DATA) osx > $@
osx_name.py: $(SOURCES)
$(GEN) --lang python2 name-table $(DATA) osx > $@
javascript: node_modules/babel-core \
node_modules/babel-plugin-transform-es2015-modules-commonjs \
osx2win32.js osx2win32_name.js \
osx2xkb.js osx2xkb_name.js \
html2win32.js html2win32_name.js \
osx.js osx_name.js
node_modules/babel-core:
npm install babel-core
node_modules/babel-plugin-transform-es2015-modules-commonjs:
npm install babel-plugin-transform-es2015-modules-commonjs
osx2win32.js: $(SOURCES)
$(GEN) --lang js code-map $(DATA) osx win32 > $@
osx2win32_name.js: $(SOURCES)
$(GEN) --lang js name-map $(DATA) osx win32 > $@
osx2xkb.js: $(SOURCES)
$(GEN) --lang js code-map $(DATA) osx xkb > $@
osx2xkb_name.js: $(SOURCES)
$(GEN) --lang js name-map $(DATA) osx xkb > $@
html2win32.js: $(SOURCES)
$(GEN) --lang js code-map $(DATA) html win32 > $@
html2win32_name.js: $(SOURCES)
$(GEN) --lang js name-map $(DATA) html win32 > $@
osx.js: $(SOURCES)
$(GEN) --lang js code-table $(DATA) osx > $@
osx_name.js: $(SOURCES)
$(GEN) --lang js name-table $(DATA) osx > $@
clean:
rm -rf node_modules
rm -f osx2win32.*
rm -f osx2win32_name.*
rm -f osx2xkb.*
rm -f osx2xkb_name.*
rm -f html2win32.*
rm -f html2win32_name.*
rm -f osx.*
rm -f osx_name.*
rm -f stdc stdc++

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env node
/*
* Keycode Map Generator JavaScript Tests
*
* Copyright 2017 Pierre Ossman for Cendio AB
*
* This file is dual license under the terms of the GPLv2 or later
* and 3-clause BSD licenses.
*/
"use strict";
var assert = require('assert');
var babel = require('babel-core');
var fs = require('fs');
function include(fn) {
var options = {
plugins: ["transform-es2015-modules-commonjs"]
};
var code = babel.transformFileSync(fn, options).code;
fs.writeFileSync("." + fn + "_nodejs.js", code);
var imp = require("./." + fn + "_nodejs.js");
fs.unlinkSync("./." + fn + "_nodejs.js");
return imp
}
var code_map_osx_to_win32 = include("osx2win32.js").default;
var name_map_osx_to_win32 = include("osx2win32_name.js").default;
var code_map_osx_to_xkb = include("osx2xkb.js").default;
var name_map_osx_to_xkb = include("osx2xkb_name.js").default;
var code_map_html_to_win32 = include("html2win32.js").default;
var name_map_html_to_win32 = include("html2win32_name.js").default;
var code_table_osx = include("osx.js").default;
var name_table_osx = include("osx_name.js").default;
assert.equal(code_map_osx_to_win32[0x1d], 0x30);
assert.equal(name_map_osx_to_win32[0x1d], "VK_0");
assert.equal(code_map_osx_to_xkb[0x1d], "AE10");
assert.equal(name_map_osx_to_xkb[0x1d], "AE10");
assert.equal(code_map_html_to_win32["ControlLeft"], 0x11);
assert.equal(name_map_html_to_win32["ControlLeft"], "VK_CONTROL");
assert.equal(code_table_osx[0x1d], 0x3b);
assert.equal(name_table_osx[0x1d], "Control");

View File

@@ -1,3 +0,0 @@
#!/bin/sh
python ./test.py

View File

@@ -1,3 +0,0 @@
#!/bin/sh
python3 ./test.py

View File

@@ -1,40 +0,0 @@
/*
* Keycode Map Generator C++ Tests
*
* Copyright 2017 Pierre Ossman for Cendio AB
*
* This file is dual license under the terms of the GPLv2 or later
* and 3-clause BSD licenses.
*/
#include <assert.h>
#include <string.h>
#include "osx2win32.hh"
#include "osx2win32_name.hh"
#include "osx2xkb.hh"
#include "osx2xkb_name.hh"
#include "html2win32.hh"
#include "html2win32_name.hh"
#include "osx.hh"
#include "osx_name.hh"
int main(int argc, char** argv)
{
assert(code_map_osx_to_win32[0x1d] == 0x30);
assert(strcmp(name_map_osx_to_win32[0x1d], "VK_0") == 0);
assert(strcmp(code_map_osx_to_xkb[0x1d], "AE10") == 0);
assert(strcmp(name_map_osx_to_xkb[0x1d], "AE10") == 0);
assert(code_map_html_to_win32.at("ControlLeft") == 0x11);
assert(strcmp(name_map_html_to_win32.at("ControlLeft"), "VK_CONTROL") == 0);
assert(code_table_osx[0x1d] == 0x3b);
assert(strcmp(name_table_osx[0x1d], "Control") == 0);
return 0;
}

View File

@@ -1,64 +0,0 @@
/*
* Keycode Map Generator C Tests
*
* Copyright 2017 Pierre Ossman for Cendio AB
*
* This file is dual license under the terms of the GPLv2 or later
* and 3-clause BSD licenses.
*/
#include <assert.h>
#include <string.h>
#include "osx2win32.h"
#include "osx2win32_name.h"
#include "osx2xkb.h"
#include "osx2xkb_name.h"
#include "html2win32.h"
#include "html2win32_name.h"
#include "osx.h"
#include "osx_name.h"
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
int main(int argc, char** argv)
{
unsigned i;
assert(code_map_osx_to_win32_len == ARRAY_SIZE(code_map_osx_to_win32));
assert(code_map_osx_to_win32[0x1d] == 0x30);
assert(name_map_osx_to_win32_len == ARRAY_SIZE(name_map_osx_to_win32));
assert(strcmp(name_map_osx_to_win32[0x1d], "VK_0") == 0);
assert(code_map_osx_to_xkb_len == ARRAY_SIZE(code_map_osx_to_xkb));
assert(strcmp(code_map_osx_to_xkb[0x1d], "AE10") == 0);
assert(name_map_osx_to_xkb_len == ARRAY_SIZE(name_map_osx_to_xkb));
assert(strcmp(name_map_osx_to_xkb[0x1d], "AE10") == 0);
assert(code_map_html_to_win32_len == ARRAY_SIZE(code_map_html_to_win32));
for (i = 0;i < code_map_html_to_win32_len;i++) {
if (strcmp(code_map_html_to_win32[i].from, "ControlLeft") == 0) {
assert(code_map_html_to_win32[i].to == 0x11);
break;
}
}
assert(i != code_map_html_to_win32_len);
assert(name_map_html_to_win32_len == ARRAY_SIZE(name_map_html_to_win32));
for (i = 0;i < name_map_html_to_win32_len;i++) {
if (strcmp(name_map_html_to_win32[i].from, "ControlLeft") == 0) {
assert(strcmp(name_map_html_to_win32[i].to, "VK_CONTROL") == 0);
break;
}
}
assert(i != name_map_html_to_win32_len);
assert(code_table_osx_len == ARRAY_SIZE(code_table_osx));
assert(code_table_osx[0x1d] == 0x3b);
assert(name_table_osx_len == ARRAY_SIZE(name_table_osx));
assert(strcmp(name_table_osx[0x1d], "Control") == 0);
return 0;
}

View File

@@ -1,30 +0,0 @@
# Keycode Map Generator Python Tests
#
# Copyright 2017 Pierre Ossman for Cendio AB
#
# This file is dual license under the terms of the GPLv2 or later
# and 3-clause BSD licenses.
import osx2win32
import osx2win32_name
import osx2xkb
import osx2xkb_name
import html2win32
import html2win32_name
import osx
import osx_name
assert osx2win32.code_map_osx_to_win32[0x1d] == 0x30
assert osx2win32_name.name_map_osx_to_win32[0x1d] == "VK_0"
assert osx2xkb.code_map_osx_to_xkb[0x1d] == "AE10"
assert osx2xkb_name.name_map_osx_to_xkb[0x1d] == "AE10"
assert html2win32.code_map_html_to_win32["ControlLeft"] == 0x11
assert html2win32_name.name_map_html_to_win32["ControlLeft"] == "VK_CONTROL"
assert osx.code_table_osx[0x1d] == 0x3b;
assert osx_name.name_table_osx[0x1d] == "Control";

View File

@@ -1,20 +0,0 @@
argparse is (c) 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
The argparse module was contributed to Python as of Python 2.7 and thus
was licensed under the Python license. Same license applies to all files in
the argparse package project.
For details about the Python License, please see doc/Python-License.txt.
History
-------
Before (and including) argparse 1.1, the argparse package was licensed under
Apache License v2.0.
After argparse 1.1, all project files from the argparse project were deleted
due to license compatibility issues between Apache License 2.0 and GNU GPL v2.
The project repository then had a clean start with some files taken from
Python 2.7.1, so definitely all files are under Python License now.

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2
qemu

Submodule qemu updated: f7f686b61c...20a1b341a0