* Thu Aug 27 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 5.1.0-4.el8

- kvm-Drop-bogus-IPv6-messages.patch [bz#1867075]
- kvm-machine-types-numa-set-numa_mem_supported-on-old-mac.patch [bz#1849707]
- kvm-machine_types-numa-compatibility-for-auto_enable_num.patch [bz#1849707]
- kvm-migration-Add-block-bitmap-mapping-parameter.patch [bz#1790492]
- kvm-iotests.py-Let-wait_migration-return-on-failure.patch [bz#1790492]
- kvm-iotests-Test-node-bitmap-aliases-during-migration.patch [bz#1790492]
- Resolves: bz#1790492
  ('dirty-bitmaps' migration capability should allow configuring target nodenames)
- Resolves: bz#1849707
  (8.3 machine types for x86 - 5.1 update)
- Resolves: bz#1867075
  (CVE-2020-10756 virt:8.3/qemu-kvm: QEMU: slirp: networking out-of-bounds read information disclosure vulnerability [rhel-av-8])
This commit is contained in:
Danilo C. L. de Paula 2020-08-27 14:28:38 -04:00
parent 915cb810be
commit e5fba7f9b3
7 changed files with 1904 additions and 1 deletions

View File

@ -0,0 +1,51 @@
From 6ceab004edfb7c1f0f03701bc2ae443941468fd7 Mon Sep 17 00:00:00 2001
From: Jon Maloy <jmaloy@redhat.com>
Date: Mon, 17 Aug 2020 22:06:08 -0400
Subject: [PATCH 1/6] Drop bogus IPv6 messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Jon Maloy <jmaloy@redhat.com>
Message-id: <20200817220608.1142611-2-jmaloy@redhat.com>
Patchwork-id: 98161
O-Subject: [RHEL-AV-8.3.0 qemu-kvm PATCH 1/1] Drop bogus IPv6 messages
Bugzilla: 1867075
RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
From: Ralf Haferkamp <rhafer@suse.com>
Drop IPv6 message shorter than what's mentioned in the payload
length header (+ the size of the IPv6 header). They're invalid an could
lead to data leakage in icmp6_send_echoreply().
(cherry picked from libslirp commit c7ede54cbd2e2b25385325600958ba0124e31cc0)
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
slirp/src/ip6_input.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/slirp/src/ip6_input.c b/slirp/src/ip6_input.c
index a83e4f8e3d..f7ef354ee4 100644
--- a/slirp/src/ip6_input.c
+++ b/slirp/src/ip6_input.c
@@ -56,6 +56,13 @@ void ip6_input(struct mbuf *m)
goto bad;
}
+ // Check if the message size is big enough to hold what's
+ // set in the payload length header. If not this is an invalid
+ // packet
+ if (m->m_len < ntohs(ip6->ip_pl) + sizeof(struct ip6)) {
+ goto bad;
+ }
+
/* check ip_ttl for a correct ICMP reply */
if (ip6->ip_hl == 0) {
icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
--
2.27.0

View File

@ -0,0 +1,655 @@
From 2877fd4f92a86f43a113691f56738b09a0b4d500 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Mon, 24 Aug 2020 09:20:38 -0400
Subject: [PATCH 6/6] iotests: Test node/bitmap aliases during migration
RH-Author: Max Reitz <mreitz@redhat.com>
Message-id: <20200824092038.227913-4-mreitz@redhat.com>
Patchwork-id: 98214
O-Subject: [RHEL-AV-8.3.0 qemu-kvm PATCH 3/3] iotests: Test node/bitmap aliases during migration
Bugzilla: 1790492
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200820150725.68687-4-mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Eric Blake <eblake@redhat.com>
[eblake: fold in python cleanups recommended by Vladimir]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit cb5c6cd2dc984812f560fbe41f57a6bfc34d8708)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tests/qemu-iotests/300 | 593 +++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/300.out | 5 +
tests/qemu-iotests/group | 1 +
3 files changed, 599 insertions(+)
create mode 100755 tests/qemu-iotests/300
create mode 100644 tests/qemu-iotests/300.out
diff --git a/tests/qemu-iotests/300 b/tests/qemu-iotests/300
new file mode 100755
index 0000000000..5b75121b84
--- /dev/null
+++ b/tests/qemu-iotests/300
@@ -0,0 +1,593 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 Red Hat, Inc.
+#
+# Tests for dirty bitmaps migration with node aliases
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import random
+import re
+from typing import Dict, List, Optional, Union
+import iotests
+import qemu
+
+BlockBitmapMapping = List[Dict[str, Union[str, List[Dict[str, str]]]]]
+
+assert iotests.sock_dir is not None
+mig_sock = os.path.join(iotests.sock_dir, 'mig_sock')
+
+
+class TestDirtyBitmapMigration(iotests.QMPTestCase):
+ src_node_name: str = ''
+ dst_node_name: str = ''
+ src_bmap_name: str = ''
+ dst_bmap_name: str = ''
+
+ def setUp(self) -> None:
+ self.vm_a = iotests.VM(path_suffix='-a')
+ self.vm_a.add_blockdev(f'node-name={self.src_node_name},'
+ 'driver=null-co')
+ self.vm_a.launch()
+
+ self.vm_b = iotests.VM(path_suffix='-b')
+ self.vm_b.add_blockdev(f'node-name={self.dst_node_name},'
+ 'driver=null-co')
+ self.vm_b.add_incoming(f'unix:{mig_sock}')
+ self.vm_b.launch()
+
+ result = self.vm_a.qmp('block-dirty-bitmap-add',
+ node=self.src_node_name,
+ name=self.src_bmap_name)
+ self.assert_qmp(result, 'return', {})
+
+ # Dirty some random megabytes
+ for _ in range(9):
+ mb_ofs = random.randrange(1024)
+ self.vm_a.hmp_qemu_io(self.src_node_name, f'discard {mb_ofs}M 1M')
+
+ result = self.vm_a.qmp('x-debug-block-dirty-bitmap-sha256',
+ node=self.src_node_name,
+ name=self.src_bmap_name)
+ self.bitmap_hash_reference = result['return']['sha256']
+
+ caps = [{'capability': name, 'state': True}
+ for name in ('dirty-bitmaps', 'events')]
+
+ for vm in (self.vm_a, self.vm_b):
+ result = vm.qmp('migrate-set-capabilities', capabilities=caps)
+ self.assert_qmp(result, 'return', {})
+
+ def tearDown(self) -> None:
+ self.vm_a.shutdown()
+ self.vm_b.shutdown()
+ try:
+ os.remove(mig_sock)
+ except OSError:
+ pass
+
+ def check_bitmap(self, bitmap_name_valid: bool) -> None:
+ result = self.vm_b.qmp('x-debug-block-dirty-bitmap-sha256',
+ node=self.dst_node_name,
+ name=self.dst_bmap_name)
+ if bitmap_name_valid:
+ self.assert_qmp(result, 'return/sha256',
+ self.bitmap_hash_reference)
+ else:
+ self.assert_qmp(result, 'error/desc',
+ f"Dirty bitmap '{self.dst_bmap_name}' not found")
+
+ def migrate(self, bitmap_name_valid: bool = True,
+ migration_success: bool = True) -> None:
+ result = self.vm_a.qmp('migrate', uri=f'unix:{mig_sock}')
+ self.assert_qmp(result, 'return', {})
+
+ with iotests.Timeout(5, 'Timeout waiting for migration to complete'):
+ self.assertEqual(self.vm_a.wait_migration('postmigrate'),
+ migration_success)
+ self.assertEqual(self.vm_b.wait_migration('running'),
+ migration_success)
+
+ if migration_success:
+ self.check_bitmap(bitmap_name_valid)
+
+ def verify_dest_error(self, msg: Optional[str]) -> None:
+ """
+ Check whether the given error message is present in vm_b's log.
+ (vm_b is shut down to do so.)
+ If @msg is None, check that there has not been any error.
+ """
+ self.vm_b.shutdown()
+ if msg is None:
+ self.assertNotIn('qemu-system-', self.vm_b.get_log())
+ else:
+ self.assertIn(msg, self.vm_b.get_log())
+
+ @staticmethod
+ def mapping(node_name: str, node_alias: str,
+ bitmap_name: str, bitmap_alias: str) -> BlockBitmapMapping:
+ return [{
+ 'node-name': node_name,
+ 'alias': node_alias,
+ 'bitmaps': [{
+ 'name': bitmap_name,
+ 'alias': bitmap_alias
+ }]
+ }]
+
+ def set_mapping(self, vm: iotests.VM, mapping: BlockBitmapMapping,
+ error: Optional[str] = None) -> None:
+ """
+ Invoke migrate-set-parameters on @vm to set the given @mapping.
+ Check for success if @error is None, or verify the error message
+ if it is not.
+ On success, verify that "info migrate_parameters" on HMP returns
+ our mapping. (Just to check its formatting code.)
+ """
+ result = vm.qmp('migrate-set-parameters',
+ block_bitmap_mapping=mapping)
+
+ if error is None:
+ self.assert_qmp(result, 'return', {})
+
+ result = vm.qmp('human-monitor-command',
+ command_line='info migrate_parameters')
+
+ m = re.search(r'^block-bitmap-mapping:\r?(\n .*)*\n',
+ result['return'], flags=re.MULTILINE)
+ hmp_mapping = m.group(0).replace('\r', '') if m else None
+
+ self.assertEqual(hmp_mapping, self.to_hmp_mapping(mapping))
+ else:
+ self.assert_qmp(result, 'error/desc', error)
+
+ @staticmethod
+ def to_hmp_mapping(mapping: BlockBitmapMapping) -> str:
+ result = 'block-bitmap-mapping:\n'
+
+ for node in mapping:
+ result += f" '{node['node-name']}' -> '{node['alias']}'\n"
+
+ assert isinstance(node['bitmaps'], list)
+ for bitmap in node['bitmaps']:
+ result += f" '{bitmap['name']}' -> '{bitmap['alias']}'\n"
+
+ return result
+
+
+class TestAliasMigration(TestDirtyBitmapMigration):
+ src_node_name = 'node0'
+ dst_node_name = 'node0'
+ src_bmap_name = 'bmap0'
+ dst_bmap_name = 'bmap0'
+
+ def test_migration_without_alias(self) -> None:
+ self.migrate(self.src_node_name == self.dst_node_name and
+ self.src_bmap_name == self.dst_bmap_name)
+
+ # Check for error message on the destination
+ if self.src_node_name != self.dst_node_name:
+ self.verify_dest_error(f"Cannot find "
+ f"device={self.src_node_name} nor "
+ f"node_name={self.src_node_name}")
+ else:
+ self.verify_dest_error(None)
+
+ def test_alias_on_src_migration(self) -> None:
+ mapping = self.mapping(self.src_node_name, self.dst_node_name,
+ self.src_bmap_name, self.dst_bmap_name)
+
+ self.set_mapping(self.vm_a, mapping)
+ self.migrate()
+ self.verify_dest_error(None)
+
+ def test_alias_on_dst_migration(self) -> None:
+ mapping = self.mapping(self.dst_node_name, self.src_node_name,
+ self.dst_bmap_name, self.src_bmap_name)
+
+ self.set_mapping(self.vm_b, mapping)
+ self.migrate()
+ self.verify_dest_error(None)
+
+ def test_alias_on_both_migration(self) -> None:
+ src_map = self.mapping(self.src_node_name, 'node-alias',
+ self.src_bmap_name, 'bmap-alias')
+
+ dst_map = self.mapping(self.dst_node_name, 'node-alias',
+ self.dst_bmap_name, 'bmap-alias')
+
+ self.set_mapping(self.vm_a, src_map)
+ self.set_mapping(self.vm_b, dst_map)
+ self.migrate()
+ self.verify_dest_error(None)
+
+
+class TestNodeAliasMigration(TestAliasMigration):
+ src_node_name = 'node-src'
+ dst_node_name = 'node-dst'
+
+
+class TestBitmapAliasMigration(TestAliasMigration):
+ src_bmap_name = 'bmap-src'
+ dst_bmap_name = 'bmap-dst'
+
+
+class TestFullAliasMigration(TestAliasMigration):
+ src_node_name = 'node-src'
+ dst_node_name = 'node-dst'
+ src_bmap_name = 'bmap-src'
+ dst_bmap_name = 'bmap-dst'
+
+
+class TestLongBitmapNames(TestAliasMigration):
+ # Giving long bitmap names is OK, as long as there is a short alias for
+ # migration
+ src_bmap_name = 'a' * 512
+ dst_bmap_name = 'b' * 512
+
+ # Skip all tests that do not use the intermediate alias
+ def test_migration_without_alias(self) -> None:
+ pass
+
+ def test_alias_on_src_migration(self) -> None:
+ pass
+
+ def test_alias_on_dst_migration(self) -> None:
+ pass
+
+
+class TestBlockBitmapMappingErrors(TestDirtyBitmapMigration):
+ src_node_name = 'node0'
+ dst_node_name = 'node0'
+ src_bmap_name = 'bmap0'
+ dst_bmap_name = 'bmap0'
+
+ """
+ Note that mapping nodes or bitmaps that do not exist is not an error.
+ """
+
+ def test_non_injective_node_mapping(self) -> None:
+ mapping: BlockBitmapMapping = [
+ {
+ 'node-name': 'node0',
+ 'alias': 'common-alias',
+ 'bitmaps': [{
+ 'name': 'bmap0',
+ 'alias': 'bmap-alias0'
+ }]
+ },
+ {
+ 'node-name': 'node1',
+ 'alias': 'common-alias',
+ 'bitmaps': [{
+ 'name': 'bmap1',
+ 'alias': 'bmap-alias1'
+ }]
+ }
+ ]
+
+ self.set_mapping(self.vm_a, mapping,
+ "Invalid mapping given for block-bitmap-mapping: "
+ "The node alias 'common-alias' is used twice")
+
+ def test_non_injective_bitmap_mapping(self) -> None:
+ mapping: BlockBitmapMapping = [{
+ 'node-name': 'node0',
+ 'alias': 'node-alias0',
+ 'bitmaps': [
+ {
+ 'name': 'bmap0',
+ 'alias': 'common-alias'
+ },
+ {
+ 'name': 'bmap1',
+ 'alias': 'common-alias'
+ }
+ ]
+ }]
+
+ self.set_mapping(self.vm_a, mapping,
+ "Invalid mapping given for block-bitmap-mapping: "
+ "The bitmap alias 'node-alias0'/'common-alias' is "
+ "used twice")
+
+ def test_ambiguous_node_mapping(self) -> None:
+ mapping: BlockBitmapMapping = [
+ {
+ 'node-name': 'node0',
+ 'alias': 'node-alias0',
+ 'bitmaps': [{
+ 'name': 'bmap0',
+ 'alias': 'bmap-alias0'
+ }]
+ },
+ {
+ 'node-name': 'node0',
+ 'alias': 'node-alias1',
+ 'bitmaps': [{
+ 'name': 'bmap0',
+ 'alias': 'bmap-alias0'
+ }]
+ }
+ ]
+
+ self.set_mapping(self.vm_a, mapping,
+ "Invalid mapping given for block-bitmap-mapping: "
+ "The node name 'node0' is mapped twice")
+
+ def test_ambiguous_bitmap_mapping(self) -> None:
+ mapping: BlockBitmapMapping = [{
+ 'node-name': 'node0',
+ 'alias': 'node-alias0',
+ 'bitmaps': [
+ {
+ 'name': 'bmap0',
+ 'alias': 'bmap-alias0'
+ },
+ {
+ 'name': 'bmap0',
+ 'alias': 'bmap-alias1'
+ }
+ ]
+ }]
+
+ self.set_mapping(self.vm_a, mapping,
+ "Invalid mapping given for block-bitmap-mapping: "
+ "The bitmap 'node0'/'bmap0' is mapped twice")
+
+ def test_migratee_node_is_not_mapped_on_src(self) -> None:
+ self.set_mapping(self.vm_a, [])
+ # Should just ignore all bitmaps on unmapped nodes
+ self.migrate(False)
+ self.verify_dest_error(None)
+
+ def test_migratee_node_is_not_mapped_on_dst(self) -> None:
+ self.set_mapping(self.vm_b, [])
+ self.migrate(False)
+ self.verify_dest_error(f"Unknown node alias '{self.src_node_name}'")
+
+ def test_migratee_bitmap_is_not_mapped_on_src(self) -> None:
+ mapping: BlockBitmapMapping = [{
+ 'node-name': self.src_node_name,
+ 'alias': self.dst_node_name,
+ 'bitmaps': []
+ }]
+
+ self.set_mapping(self.vm_a, mapping)
+ # Should just ignore all unmapped bitmaps
+ self.migrate(False)
+ self.verify_dest_error(None)
+
+ def test_migratee_bitmap_is_not_mapped_on_dst(self) -> None:
+ mapping: BlockBitmapMapping = [{
+ 'node-name': self.dst_node_name,
+ 'alias': self.src_node_name,
+ 'bitmaps': []
+ }]
+
+ self.set_mapping(self.vm_b, mapping)
+ self.migrate(False)
+ self.verify_dest_error(f"Unknown bitmap alias "
+ f"'{self.src_bmap_name}' "
+ f"on node '{self.dst_node_name}' "
+ f"(alias '{self.src_node_name}')")
+
+ def test_unused_mapping_on_dst(self) -> None:
+ # Let the source not send any bitmaps
+ self.set_mapping(self.vm_a, [])
+
+ # Establish some mapping on the destination
+ self.set_mapping(self.vm_b, [])
+
+ # The fact that there is a mapping on B without any bitmaps
+ # being received should be fine, not fatal
+ self.migrate(False)
+ self.verify_dest_error(None)
+
+ def test_non_wellformed_node_alias(self) -> None:
+ alias = '123-foo'
+
+ mapping: BlockBitmapMapping = [{
+ 'node-name': self.src_node_name,
+ 'alias': alias,
+ 'bitmaps': []
+ }]
+
+ self.set_mapping(self.vm_a, mapping,
+ f"Invalid mapping given for block-bitmap-mapping: "
+ f"The node alias '{alias}' is not well-formed")
+
+ def test_node_alias_too_long(self) -> None:
+ alias = 'a' * 256
+
+ mapping: BlockBitmapMapping = [{
+ 'node-name': self.src_node_name,
+ 'alias': alias,
+ 'bitmaps': []
+ }]
+
+ self.set_mapping(self.vm_a, mapping,
+ f"Invalid mapping given for block-bitmap-mapping: "
+ f"The node alias '{alias}' is longer than 255 bytes")
+
+ def test_bitmap_alias_too_long(self) -> None:
+ alias = 'a' * 256
+
+ mapping = self.mapping(self.src_node_name, self.dst_node_name,
+ self.src_bmap_name, alias)
+
+ self.set_mapping(self.vm_a, mapping,
+ f"Invalid mapping given for block-bitmap-mapping: "
+ f"The bitmap alias '{alias}' is longer than 255 "
+ f"bytes")
+
+ def test_bitmap_name_too_long(self) -> None:
+ name = 'a' * 256
+
+ result = self.vm_a.qmp('block-dirty-bitmap-add',
+ node=self.src_node_name,
+ name=name)
+ self.assert_qmp(result, 'return', {})
+
+ self.migrate(False, False)
+
+ # Check for the error in the source's log
+ self.vm_a.shutdown()
+ self.assertIn(f"Cannot migrate bitmap '{name}' on node "
+ f"'{self.src_node_name}': Name is longer than 255 bytes",
+ self.vm_a.get_log())
+
+ # Expect abnormal shutdown of the destination VM because of
+ # the failed migration
+ try:
+ self.vm_b.shutdown()
+ except qemu.machine.AbnormalShutdown:
+ pass
+
+ def test_aliased_bitmap_name_too_long(self) -> None:
+ # Longer than the maximum for bitmap names
+ self.dst_bmap_name = 'a' * 1024
+
+ mapping = self.mapping(self.dst_node_name, self.src_node_name,
+ self.dst_bmap_name, self.src_bmap_name)
+
+ # We would have to create this bitmap during migration, and
+ # that would fail, because the name is too long. Better to
+ # catch it early.
+ self.set_mapping(self.vm_b, mapping,
+ f"Invalid mapping given for block-bitmap-mapping: "
+ f"The bitmap name '{self.dst_bmap_name}' is longer "
+ f"than 1023 bytes")
+
+ def test_node_name_too_long(self) -> None:
+ # Longer than the maximum for node names
+ self.dst_node_name = 'a' * 32
+
+ mapping = self.mapping(self.dst_node_name, self.src_node_name,
+ self.dst_bmap_name, self.src_bmap_name)
+
+ # During migration, this would appear simply as a node that
+ # cannot be found. Still better to catch impossible node
+ # names early (similar to test_non_wellformed_node_alias).
+ self.set_mapping(self.vm_b, mapping,
+ f"Invalid mapping given for block-bitmap-mapping: "
+ f"The node name '{self.dst_node_name}' is longer "
+ f"than 31 bytes")
+
+
+class TestCrossAliasMigration(TestDirtyBitmapMigration):
+ """
+ Swap aliases, both to see that qemu does not get confused, and
+ that we can migrate multiple things at once.
+
+ So we migrate this:
+ node-a.bmap-a -> node-b.bmap-b
+ node-a.bmap-b -> node-b.bmap-a
+ node-b.bmap-a -> node-a.bmap-b
+ node-b.bmap-b -> node-a.bmap-a
+ """
+
+ src_node_name = 'node-a'
+ dst_node_name = 'node-b'
+ src_bmap_name = 'bmap-a'
+ dst_bmap_name = 'bmap-b'
+
+ def setUp(self) -> None:
+ TestDirtyBitmapMigration.setUp(self)
+
+ # Now create another block device and let both have two bitmaps each
+ result = self.vm_a.qmp('blockdev-add',
+ node_name='node-b', driver='null-co')
+ self.assert_qmp(result, 'return', {})
+
+ result = self.vm_b.qmp('blockdev-add',
+ node_name='node-a', driver='null-co')
+ self.assert_qmp(result, 'return', {})
+
+ bmaps_to_add = (('node-a', 'bmap-b'),
+ ('node-b', 'bmap-a'),
+ ('node-b', 'bmap-b'))
+
+ for (node, bmap) in bmaps_to_add:
+ result = self.vm_a.qmp('block-dirty-bitmap-add',
+ node=node, name=bmap)
+ self.assert_qmp(result, 'return', {})
+
+ @staticmethod
+ def cross_mapping() -> BlockBitmapMapping:
+ return [
+ {
+ 'node-name': 'node-a',
+ 'alias': 'node-b',
+ 'bitmaps': [
+ {
+ 'name': 'bmap-a',
+ 'alias': 'bmap-b'
+ },
+ {
+ 'name': 'bmap-b',
+ 'alias': 'bmap-a'
+ }
+ ]
+ },
+ {
+ 'node-name': 'node-b',
+ 'alias': 'node-a',
+ 'bitmaps': [
+ {
+ 'name': 'bmap-b',
+ 'alias': 'bmap-a'
+ },
+ {
+ 'name': 'bmap-a',
+ 'alias': 'bmap-b'
+ }
+ ]
+ }
+ ]
+
+ def verify_dest_has_all_bitmaps(self) -> None:
+ bitmaps = self.vm_b.query_bitmaps()
+
+ # Extract and sort bitmap names
+ for node in bitmaps:
+ bitmaps[node] = sorted((bmap['name'] for bmap in bitmaps[node]))
+
+ self.assertEqual(bitmaps,
+ {'node-a': ['bmap-a', 'bmap-b'],
+ 'node-b': ['bmap-a', 'bmap-b']})
+
+ def test_alias_on_src(self) -> None:
+ self.set_mapping(self.vm_a, self.cross_mapping())
+
+ # Checks that node-a.bmap-a was migrated to node-b.bmap-b, and
+ # that is enough
+ self.migrate()
+ self.verify_dest_has_all_bitmaps()
+ self.verify_dest_error(None)
+
+ def test_alias_on_dst(self) -> None:
+ self.set_mapping(self.vm_b, self.cross_mapping())
+
+ # Checks that node-a.bmap-a was migrated to node-b.bmap-b, and
+ # that is enough
+ self.migrate()
+ self.verify_dest_has_all_bitmaps()
+ self.verify_dest_error(None)
+
+
+if __name__ == '__main__':
+ iotests.main(supported_protocols=['file'])
diff --git a/tests/qemu-iotests/300.out b/tests/qemu-iotests/300.out
new file mode 100644
index 0000000000..cafb8161f7
--- /dev/null
+++ b/tests/qemu-iotests/300.out
@@ -0,0 +1,5 @@
+.....................................
+----------------------------------------------------------------------
+Ran 37 tests
+
+OK
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 025ed5238d..b0b55e241c 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -307,5 +307,6 @@
296 rw
297 meta
299 auto quick
+300 migration
301 backing quick
302 quick
--
2.27.0

View File

@ -0,0 +1,66 @@
From 2a597bba9b1e07adb6531628962682a0e53d29b1 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Mon, 24 Aug 2020 09:20:37 -0400
Subject: [PATCH 5/6] iotests.py: Let wait_migration() return on failure
RH-Author: Max Reitz <mreitz@redhat.com>
Message-id: <20200824092038.227913-3-mreitz@redhat.com>
Patchwork-id: 98213
O-Subject: [RHEL-AV-8.3.0 qemu-kvm PATCH 2/3] iotests.py: Let wait_migration() return on failure
Bugzilla: 1790492
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Let wait_migration() return on failure (with the return value indicating
whether the migration was completed or has failed), so we can use it for
migrations that are expected to fail, too.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200820150725.68687-3-mreitz@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 4bf63c80357031be4eb8fff8a751f40e73ef1c10)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tests/qemu-iotests/iotests.py | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 717b5b652c..e197c73ca5 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -729,16 +729,22 @@ class VM(qtest.QEMUQtestMachine):
}
]))
- def wait_migration(self, expect_runstate):
+ def wait_migration(self, expect_runstate: Optional[str]) -> bool:
while True:
event = self.event_wait('MIGRATION')
log(event, filters=[filter_qmp_event])
- if event['data']['status'] == 'completed':
+ if event['data']['status'] in ('completed', 'failed'):
break
- # The event may occur in finish-migrate, so wait for the expected
- # post-migration runstate
- while self.qmp('query-status')['return']['status'] != expect_runstate:
- pass
+
+ if event['data']['status'] == 'completed':
+ # The event may occur in finish-migrate, so wait for the expected
+ # post-migration runstate
+ runstate = None
+ while runstate != expect_runstate:
+ runstate = self.qmp('query-status')['return']['status']
+ return True
+ else:
+ return False
def node_info(self, node_name):
nodes = self.qmp('query-named-block-nodes')
--
2.27.0

View File

@ -0,0 +1,77 @@
From 6d7ba662e980fcc6f3056173043136063e6d68db Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Thu, 20 Aug 2020 15:14:18 -0400
Subject: [PATCH 2/6] machine types/numa: set numa_mem_supported on old machine
types
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200820151419.14723-2-dgilbert@redhat.com>
Patchwork-id: 98197
O-Subject: [RHEL-AV 8.3.0 qemu-kvm PATCH 1/2] machine types/numa: set numa_mem_supported on old machine types
Bugzilla: 1849707
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Acked-by: David Hildenbrand <david@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Reenable the -numa mem= syntax for old machine types, this is making
the downstream old machines behave in the same way as the upstream old
machines changed in upstream 32a354dc6c07d7.
Power already seems to have the change.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
hw/arm/virt.c | 2 +-
hw/i386/pc_piix.c | 1 +
hw/i386/pc_q35.c | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f087483a04..26a7920081 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2755,7 +2755,6 @@ static void rhel_machine_class_init(ObjectClass *oc, void *data)
hc->plug = virt_machine_device_plug_cb;
hc->unplug_request = virt_machine_device_unplug_request_cb;
hc->unplug = virt_machine_device_unplug_cb;
- mc->numa_mem_supported = true;
mc->nvdimm_supported = true;
mc->auto_enable_numa_with_memhp = true;
mc->default_ram_id = "mach-virt.ram";
@@ -2860,5 +2859,6 @@ static void rhel820_virt_options(MachineClass *mc)
rhel830_virt_options(mc);
compat_props_add(mc->compat_props, hw_compat_rhel_8_2,
hw_compat_rhel_8_2_len);
+ mc->numa_mem_supported = true;
}
DEFINE_RHEL_MACHINE(8, 2, 0)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 4af4497a0c..bda2d9ffc8 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -1009,6 +1009,7 @@ static void pc_machine_rhel7_options(MachineClass *m)
pcmc->default_nic_model = "e1000";
m->default_display = "std";
m->no_parallel = 1;
+ m->numa_mem_supported = true;
machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
m->alias = "pc";
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c709460ab7..d1e3a9b575 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -617,6 +617,7 @@ static void pc_q35_machine_rhel820_options(MachineClass *m)
pc_q35_machine_rhel_options(m);
m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)";
m->alias = NULL;
+ m->numa_mem_supported = true;
pcmc->smbios_stream_product = "RHEL-AV";
pcmc->smbios_stream_version = "8.2.0";
compat_props_add(m->compat_props, hw_compat_rhel_8_2,
--
2.27.0

View File

@ -0,0 +1,81 @@
From 25c5644164e3286dc722d59c8d7876b1c49c1385 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Thu, 20 Aug 2020 15:14:19 -0400
Subject: [PATCH 3/6] machine_types/numa: compatibility for
auto_enable_numa_with_memdev
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200820151419.14723-3-dgilbert@redhat.com>
Patchwork-id: 98196
O-Subject: [RHEL-AV 8.3.0 qemu-kvm PATCH 2/2] machine_types/numa: compatibility for auto_enable_numa_with_memdev
Bugzilla: 1849707
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: David Hildenbrand <david@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
The auto_enable_numa_with_memdev flag automatically creates NUMA a
NUMA node in a case like:
-m 8G,maxmem=16G
but we need it to keep old machine types the same.
This is (mostly) done for upstream machine types in 195784a0cfad.
Power seems to have auto_enable_numa permenantly on anyway.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
hw/arm/virt.c | 2 ++
hw/i386/pc_piix.c | 1 +
hw/i386/pc_q35.c | 1 +
3 files changed, 4 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 26a7920081..26102f22ff 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2757,6 +2757,7 @@ static void rhel_machine_class_init(ObjectClass *oc, void *data)
hc->unplug = virt_machine_device_unplug_cb;
mc->nvdimm_supported = true;
mc->auto_enable_numa_with_memhp = true;
+ mc->auto_enable_numa_with_memdev = true;
mc->default_ram_id = "mach-virt.ram";
object_class_property_add(oc, "acpi", "OnOffAuto",
@@ -2860,5 +2861,6 @@ static void rhel820_virt_options(MachineClass *mc)
compat_props_add(mc->compat_props, hw_compat_rhel_8_2,
hw_compat_rhel_8_2_len);
mc->numa_mem_supported = true;
+ mc->auto_enable_numa_with_memdev = false;
}
DEFINE_RHEL_MACHINE(8, 2, 0)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index bda2d9ffc8..2415c5edd6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -1010,6 +1010,7 @@ static void pc_machine_rhel7_options(MachineClass *m)
m->default_display = "std";
m->no_parallel = 1;
m->numa_mem_supported = true;
+ m->auto_enable_numa_with_memdev = false;
machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
m->alias = "pc";
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index d1e3a9b575..87a0572ec1 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -618,6 +618,7 @@ static void pc_q35_machine_rhel820_options(MachineClass *m)
m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)";
m->alias = NULL;
m->numa_mem_supported = true;
+ m->auto_enable_numa_with_memdev = false;
pcmc->smbios_stream_product = "RHEL-AV";
pcmc->smbios_stream_version = "8.2.0";
compat_props_add(m->compat_props, hw_compat_rhel_8_2,
--
2.27.0

View File

@ -0,0 +1,947 @@
From 8ac15801169cb8744b57b939a3c751ea9d381d98 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Mon, 24 Aug 2020 09:20:36 -0400
Subject: [PATCH 4/6] migration: Add block-bitmap-mapping parameter
RH-Author: Max Reitz <mreitz@redhat.com>
Message-id: <20200824092038.227913-2-mreitz@redhat.com>
Patchwork-id: 98211
O-Subject: [RHEL-AV-8.3.0 qemu-kvm PATCH 1/3] migration: Add block-bitmap-mapping parameter
Bugzilla: 1790492
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
This migration parameter allows mapping block node names and bitmap
names to aliases for the purpose of block dirty bitmap migration.
This way, management tools can use different node and bitmap names on
the source and destination and pass the mapping of how bitmaps are to be
transferred to qemu (on the source, the destination, or even both with
arbitrary aliases in the migration stream).
While touching this code, fix a bug where bitmap names longer than 255
bytes would fail an assertion in qemu_put_counted_string().
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200820150725.68687-2-mreitz@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 31e4c354b38cd42a051ad030eb7779d5e7ee32fe)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/block-dirty-bitmap.c | 412 ++++++++++++++++++++++++++++-----
migration/migration.c | 30 +++
migration/migration.h | 3 +
monitor/hmp-cmds.c | 30 +++
qapi/migration.json | 104 ++++++++-
5 files changed, 522 insertions(+), 57 deletions(-)
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 784330ebe1..549e14daba 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -29,10 +29,10 @@
*
* # Header (shared for different chunk types)
* 1, 2 or 4 bytes: flags (see qemu_{put,put}_flags)
- * [ 1 byte: node name size ] \ flags & DEVICE_NAME
- * [ n bytes: node name ] /
- * [ 1 byte: bitmap name size ] \ flags & BITMAP_NAME
- * [ n bytes: bitmap name ] /
+ * [ 1 byte: node alias size ] \ flags & DEVICE_NAME
+ * [ n bytes: node alias ] /
+ * [ 1 byte: bitmap alias size ] \ flags & BITMAP_NAME
+ * [ n bytes: bitmap alias ] /
*
* # Start of bitmap migration (flags & START)
* header
@@ -72,7 +72,9 @@
#include "migration/register.h"
#include "qemu/hbitmap.h"
#include "qemu/cutils.h"
+#include "qemu/id.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-migration.h"
#include "trace.h"
#define CHUNK_SIZE (1 << 10)
@@ -104,7 +106,8 @@
typedef struct SaveBitmapState {
/* Written during setup phase. */
BlockDriverState *bs;
- const char *node_name;
+ char *node_alias;
+ char *bitmap_alias;
BdrvDirtyBitmap *bitmap;
uint64_t total_sectors;
uint64_t sectors_per_chunk;
@@ -138,8 +141,9 @@ typedef struct LoadBitmapState {
/* State of the dirty bitmap migration (DBM) during load process */
typedef struct DBMLoadState {
uint32_t flags;
- char node_name[256];
- char bitmap_name[256];
+ char node_alias[256];
+ char bitmap_alias[256];
+ char bitmap_name[BDRV_BITMAP_MAX_NAME_SIZE + 1];
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
@@ -165,6 +169,188 @@ typedef struct DBMState {
static DBMState dbm_state;
+/* For hash tables that map node/bitmap names to aliases */
+typedef struct AliasMapInnerNode {
+ char *string;
+ GHashTable *subtree;
+} AliasMapInnerNode;
+
+static void free_alias_map_inner_node(void *amin_ptr)
+{
+ AliasMapInnerNode *amin = amin_ptr;
+
+ g_free(amin->string);
+ g_hash_table_unref(amin->subtree);
+ g_free(amin);
+}
+
+/**
+ * Construct an alias map based on the given QMP structure.
+ *
+ * (Note that we cannot store such maps in the MigrationParameters
+ * object, because that struct is defined by the QAPI schema, which
+ * makes it basically impossible to have dicts with arbitrary keys.
+ * Therefore, we instead have to construct these maps when migration
+ * starts.)
+ *
+ * @bbm is the block_bitmap_mapping from the migration parameters.
+ *
+ * If @name_to_alias is true, the returned hash table will map node
+ * and bitmap names to their respective aliases (for outgoing
+ * migration).
+ *
+ * If @name_to_alias is false, the returned hash table will map node
+ * and bitmap aliases to their respective names (for incoming
+ * migration).
+ *
+ * The hash table maps node names/aliases to AliasMapInnerNode
+ * objects, whose .string is the respective node alias/name, and whose
+ * .subtree table maps bitmap names/aliases to the respective bitmap
+ * alias/name.
+ */
+static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm,
+ bool name_to_alias,
+ Error **errp)
+{
+ GHashTable *alias_map;
+ size_t max_node_name_len = sizeof_field(BlockDriverState, node_name) - 1;
+
+ alias_map = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, free_alias_map_inner_node);
+
+ for (; bbm; bbm = bbm->next) {
+ const BitmapMigrationNodeAlias *bmna = bbm->value;
+ const BitmapMigrationBitmapAliasList *bmbal;
+ AliasMapInnerNode *amin;
+ GHashTable *bitmaps_map;
+ const char *node_map_from, *node_map_to;
+
+ if (!id_wellformed(bmna->alias)) {
+ error_setg(errp, "The node alias '%s' is not well-formed",
+ bmna->alias);
+ goto fail;
+ }
+
+ if (strlen(bmna->alias) > UINT8_MAX) {
+ error_setg(errp, "The node alias '%s' is longer than %u bytes",
+ bmna->alias, UINT8_MAX);
+ goto fail;
+ }
+
+ if (strlen(bmna->node_name) > max_node_name_len) {
+ error_setg(errp, "The node name '%s' is longer than %zu bytes",
+ bmna->node_name, max_node_name_len);
+ goto fail;
+ }
+
+ if (name_to_alias) {
+ if (g_hash_table_contains(alias_map, bmna->node_name)) {
+ error_setg(errp, "The node name '%s' is mapped twice",
+ bmna->node_name);
+ goto fail;
+ }
+
+ node_map_from = bmna->node_name;
+ node_map_to = bmna->alias;
+ } else {
+ if (g_hash_table_contains(alias_map, bmna->alias)) {
+ error_setg(errp, "The node alias '%s' is used twice",
+ bmna->alias);
+ goto fail;
+ }
+
+ node_map_from = bmna->alias;
+ node_map_to = bmna->node_name;
+ }
+
+ bitmaps_map = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+
+ amin = g_new(AliasMapInnerNode, 1);
+ *amin = (AliasMapInnerNode){
+ .string = g_strdup(node_map_to),
+ .subtree = bitmaps_map,
+ };
+
+ g_hash_table_insert(alias_map, g_strdup(node_map_from), amin);
+
+ for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
+ const BitmapMigrationBitmapAlias *bmba = bmbal->value;
+ const char *bmap_map_from, *bmap_map_to;
+
+ if (strlen(bmba->alias) > UINT8_MAX) {
+ error_setg(errp,
+ "The bitmap alias '%s' is longer than %u bytes",
+ bmba->alias, UINT8_MAX);
+ goto fail;
+ }
+
+ if (strlen(bmba->name) > BDRV_BITMAP_MAX_NAME_SIZE) {
+ error_setg(errp, "The bitmap name '%s' is longer than %d bytes",
+ bmba->name, BDRV_BITMAP_MAX_NAME_SIZE);
+ goto fail;
+ }
+
+ if (name_to_alias) {
+ bmap_map_from = bmba->name;
+ bmap_map_to = bmba->alias;
+
+ if (g_hash_table_contains(bitmaps_map, bmba->name)) {
+ error_setg(errp, "The bitmap '%s'/'%s' is mapped twice",
+ bmna->node_name, bmba->name);
+ goto fail;
+ }
+ } else {
+ bmap_map_from = bmba->alias;
+ bmap_map_to = bmba->name;
+
+ if (g_hash_table_contains(bitmaps_map, bmba->alias)) {
+ error_setg(errp, "The bitmap alias '%s'/'%s' is used twice",
+ bmna->alias, bmba->alias);
+ goto fail;
+ }
+ }
+
+ g_hash_table_insert(bitmaps_map,
+ g_strdup(bmap_map_from), g_strdup(bmap_map_to));
+ }
+ }
+
+ return alias_map;
+
+fail:
+ g_hash_table_destroy(alias_map);
+ return NULL;
+}
+
+/**
+ * Run construct_alias_map() in both directions to check whether @bbm
+ * is valid.
+ * (This function is to be used by migration/migration.c to validate
+ * the user-specified block-bitmap-mapping migration parameter.)
+ *
+ * Returns true if and only if the mapping is valid.
+ */
+bool check_dirty_bitmap_mig_alias_map(const BitmapMigrationNodeAliasList *bbm,
+ Error **errp)
+{
+ GHashTable *alias_map;
+
+ alias_map = construct_alias_map(bbm, true, errp);
+ if (!alias_map) {
+ return false;
+ }
+ g_hash_table_destroy(alias_map);
+
+ alias_map = construct_alias_map(bbm, false, errp);
+ if (!alias_map) {
+ return false;
+ }
+ g_hash_table_destroy(alias_map);
+
+ return true;
+}
+
static uint32_t qemu_get_bitmap_flags(QEMUFile *f)
{
uint8_t flags = qemu_get_byte(f);
@@ -207,11 +393,11 @@ static void send_bitmap_header(QEMUFile *f, DBMSaveState *s,
qemu_put_bitmap_flags(f, flags);
if (flags & DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME) {
- qemu_put_counted_string(f, dbms->node_name);
+ qemu_put_counted_string(f, dbms->node_alias);
}
if (flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) {
- qemu_put_counted_string(f, bdrv_dirty_bitmap_name(bitmap));
+ qemu_put_counted_string(f, dbms->bitmap_alias);
}
}
@@ -282,18 +468,25 @@ static void dirty_bitmap_do_save_cleanup(DBMSaveState *s)
QSIMPLEQ_REMOVE_HEAD(&s->dbms_list, entry);
bdrv_dirty_bitmap_set_busy(dbms->bitmap, false);
bdrv_unref(dbms->bs);
+ g_free(dbms->node_alias);
+ g_free(dbms->bitmap_alias);
g_free(dbms);
}
}
/* Called with iothread lock taken. */
static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
- const char *bs_name)
+ const char *bs_name, GHashTable *alias_map)
{
BdrvDirtyBitmap *bitmap;
SaveBitmapState *dbms;
+ GHashTable *bitmap_aliases;
+ const char *node_alias, *bitmap_name, *bitmap_alias;
Error *local_err = NULL;
+ /* When an alias map is given, @bs_name must be @bs's node name */
+ assert(!alias_map || !strcmp(bs_name, bdrv_get_node_name(bs)));
+
FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
if (bdrv_dirty_bitmap_name(bitmap)) {
break;
@@ -303,21 +496,39 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
return 0;
}
+ bitmap_name = bdrv_dirty_bitmap_name(bitmap);
+
if (!bs_name || strcmp(bs_name, "") == 0) {
error_report("Bitmap '%s' in unnamed node can't be migrated",
- bdrv_dirty_bitmap_name(bitmap));
+ bitmap_name);
return -1;
}
- if (bs_name[0] == '#') {
+ if (alias_map) {
+ const AliasMapInnerNode *amin = g_hash_table_lookup(alias_map, bs_name);
+
+ if (!amin) {
+ /* Skip bitmaps on nodes with no alias */
+ return 0;
+ }
+
+ node_alias = amin->string;
+ bitmap_aliases = amin->subtree;
+ } else {
+ node_alias = bs_name;
+ bitmap_aliases = NULL;
+ }
+
+ if (node_alias[0] == '#') {
error_report("Bitmap '%s' in a node with auto-generated "
"name '%s' can't be migrated",
- bdrv_dirty_bitmap_name(bitmap), bs_name);
+ bitmap_name, node_alias);
return -1;
}
FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
- if (!bdrv_dirty_bitmap_name(bitmap)) {
+ bitmap_name = bdrv_dirty_bitmap_name(bitmap);
+ if (!bitmap_name) {
continue;
}
@@ -326,12 +537,29 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
return -1;
}
+ if (bitmap_aliases) {
+ bitmap_alias = g_hash_table_lookup(bitmap_aliases, bitmap_name);
+ if (!bitmap_alias) {
+ /* Skip bitmaps with no alias */
+ continue;
+ }
+ } else {
+ if (strlen(bitmap_name) > UINT8_MAX) {
+ error_report("Cannot migrate bitmap '%s' on node '%s': "
+ "Name is longer than %u bytes",
+ bitmap_name, bs_name, UINT8_MAX);
+ return -1;
+ }
+ bitmap_alias = bitmap_name;
+ }
+
bdrv_ref(bs);
bdrv_dirty_bitmap_set_busy(bitmap, true);
dbms = g_new0(SaveBitmapState, 1);
dbms->bs = bs;
- dbms->node_name = bs_name;
+ dbms->node_alias = g_strdup(node_alias);
+ dbms->bitmap_alias = g_strdup(bitmap_alias);
dbms->bitmap = bitmap;
dbms->total_sectors = bdrv_nb_sectors(bs);
dbms->sectors_per_chunk = CHUNK_SIZE * 8 *
@@ -356,43 +584,52 @@ static int init_dirty_bitmap_migration(DBMSaveState *s)
SaveBitmapState *dbms;
GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL);
BlockBackend *blk;
+ const MigrationParameters *mig_params = &migrate_get_current()->parameters;
+ GHashTable *alias_map = NULL;
+
+ if (mig_params->has_block_bitmap_mapping) {
+ alias_map = construct_alias_map(mig_params->block_bitmap_mapping, true,
+ &error_abort);
+ }
s->bulk_completed = false;
s->prev_bs = NULL;
s->prev_bitmap = NULL;
s->no_bitmaps = false;
- /*
- * Use blockdevice name for direct (or filtered) children of named block
- * backends.
- */
- for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
- const char *name = blk_name(blk);
-
- if (!name || strcmp(name, "") == 0) {
- continue;
- }
+ if (!alias_map) {
+ /*
+ * Use blockdevice name for direct (or filtered) children of named block
+ * backends.
+ */
+ for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+ const char *name = blk_name(blk);
- bs = blk_bs(blk);
+ if (!name || strcmp(name, "") == 0) {
+ continue;
+ }
- /* Skip filters without bitmaps */
- while (bs && bs->drv && bs->drv->is_filter &&
- !bdrv_has_named_bitmaps(bs))
- {
- if (bs->backing) {
- bs = bs->backing->bs;
- } else if (bs->file) {
- bs = bs->file->bs;
- } else {
- bs = NULL;
+ bs = blk_bs(blk);
+
+ /* Skip filters without bitmaps */
+ while (bs && bs->drv && bs->drv->is_filter &&
+ !bdrv_has_named_bitmaps(bs))
+ {
+ if (bs->backing) {
+ bs = bs->backing->bs;
+ } else if (bs->file) {
+ bs = bs->file->bs;
+ } else {
+ bs = NULL;
+ }
}
- }
- if (bs && bs->drv && !bs->drv->is_filter) {
- if (add_bitmaps_to_list(s, bs, name)) {
- goto fail;
+ if (bs && bs->drv && !bs->drv->is_filter) {
+ if (add_bitmaps_to_list(s, bs, name, NULL)) {
+ goto fail;
+ }
+ g_hash_table_add(handled_by_blk, bs);
}
- g_hash_table_add(handled_by_blk, bs);
}
}
@@ -401,7 +638,7 @@ static int init_dirty_bitmap_migration(DBMSaveState *s)
continue;
}
- if (add_bitmaps_to_list(s, bs, bdrv_get_node_name(bs))) {
+ if (add_bitmaps_to_list(s, bs, bdrv_get_node_name(bs), alias_map)) {
goto fail;
}
}
@@ -416,11 +653,17 @@ static int init_dirty_bitmap_migration(DBMSaveState *s)
}
g_hash_table_destroy(handled_by_blk);
+ if (alias_map) {
+ g_hash_table_destroy(alias_map);
+ }
return 0;
fail:
g_hash_table_destroy(handled_by_blk);
+ if (alias_map) {
+ g_hash_table_destroy(alias_map);
+ }
dirty_bitmap_do_save_cleanup(s);
return -1;
@@ -770,8 +1013,10 @@ static int dirty_bitmap_load_bits(QEMUFile *f, DBMLoadState *s)
return 0;
}
-static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s)
+static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s,
+ GHashTable *alias_map)
{
+ GHashTable *bitmap_alias_map = NULL;
Error *local_err = NULL;
bool nothing;
s->flags = qemu_get_bitmap_flags(f);
@@ -780,28 +1025,75 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s)
nothing = s->flags == (s->flags & DIRTY_BITMAP_MIG_FLAG_EOS);
if (s->flags & DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME) {
- if (!qemu_get_counted_string(f, s->node_name)) {
- error_report("Unable to read node name string");
+ if (!qemu_get_counted_string(f, s->node_alias)) {
+ error_report("Unable to read node alias string");
return -EINVAL;
}
+
if (!s->cancelled) {
- s->bs = bdrv_lookup_bs(s->node_name, s->node_name, &local_err);
+ if (alias_map) {
+ const AliasMapInnerNode *amin;
+
+ amin = g_hash_table_lookup(alias_map, s->node_alias);
+ if (!amin) {
+ error_setg(&local_err, "Error: Unknown node alias '%s'",
+ s->node_alias);
+ s->bs = NULL;
+ } else {
+ bitmap_alias_map = amin->subtree;
+ s->bs = bdrv_lookup_bs(NULL, amin->string, &local_err);
+ }
+ } else {
+ s->bs = bdrv_lookup_bs(s->node_alias, s->node_alias,
+ &local_err);
+ }
if (!s->bs) {
error_report_err(local_err);
cancel_incoming_locked(s);
}
}
- } else if (!s->bs && !nothing && !s->cancelled) {
+ } else if (s->bs) {
+ if (alias_map) {
+ const AliasMapInnerNode *amin;
+
+ /* Must be present in the map, or s->bs would not be set */
+ amin = g_hash_table_lookup(alias_map, s->node_alias);
+ assert(amin != NULL);
+
+ bitmap_alias_map = amin->subtree;
+ }
+ } else if (!nothing && !s->cancelled) {
error_report("Error: block device name is not set");
cancel_incoming_locked(s);
}
+ assert(nothing || s->cancelled || !!alias_map == !!bitmap_alias_map);
+
if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) {
- if (!qemu_get_counted_string(f, s->bitmap_name)) {
- error_report("Unable to read bitmap name string");
+ const char *bitmap_name;
+
+ if (!qemu_get_counted_string(f, s->bitmap_alias)) {
+ error_report("Unable to read bitmap alias string");
return -EINVAL;
}
+
+ if (!s->cancelled) {
+ if (bitmap_alias_map) {
+ bitmap_name = g_hash_table_lookup(bitmap_alias_map,
+ s->bitmap_alias);
+ if (!bitmap_name) {
+ error_report("Error: Unknown bitmap alias '%s' on node "
+ "'%s' (alias '%s')", s->bitmap_alias,
+ s->bs->node_name, s->node_alias);
+ cancel_incoming_locked(s);
+ }
+ } else {
+ bitmap_name = s->bitmap_alias;
+ }
+ }
+
if (!s->cancelled) {
+ g_strlcpy(s->bitmap_name, bitmap_name, sizeof(s->bitmap_name));
s->bitmap = bdrv_find_dirty_bitmap(s->bs, s->bitmap_name);
/*
@@ -811,7 +1103,7 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s)
if (!s->bitmap && !(s->flags & DIRTY_BITMAP_MIG_FLAG_START)) {
error_report("Error: unknown dirty bitmap "
"'%s' for block device '%s'",
- s->bitmap_name, s->node_name);
+ s->bitmap_name, s->bs->node_name);
cancel_incoming_locked(s);
}
}
@@ -835,6 +1127,8 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s)
*/
static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
{
+ GHashTable *alias_map = NULL;
+ const MigrationParameters *mig_params = &migrate_get_current()->parameters;
DBMLoadState *s = &((DBMState *)opaque)->load;
int ret = 0;
@@ -846,13 +1140,18 @@ static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
return -EINVAL;
}
+ if (mig_params->has_block_bitmap_mapping) {
+ alias_map = construct_alias_map(mig_params->block_bitmap_mapping,
+ false, &error_abort);
+ }
+
do {
QEMU_LOCK_GUARD(&s->lock);
- ret = dirty_bitmap_load_header(f, s);
+ ret = dirty_bitmap_load_header(f, s, alias_map);
if (ret < 0) {
cancel_incoming_locked(s);
- return ret;
+ goto fail;
}
if (s->flags & DIRTY_BITMAP_MIG_FLAG_START) {
@@ -869,12 +1168,17 @@ static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
if (ret) {
cancel_incoming_locked(s);
- return ret;
+ goto fail;
}
} while (!(s->flags & DIRTY_BITMAP_MIG_FLAG_EOS));
trace_dirty_bitmap_load_success();
- return 0;
+ ret = 0;
+fail:
+ if (alias_map) {
+ g_hash_table_destroy(alias_map);
+ }
+ return ret;
}
static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
diff --git a/migration/migration.c b/migration/migration.c
index bf684185b7..7a89ce39a7 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -36,6 +36,7 @@
#include "block/block.h"
#include "qapi/error.h"
#include "qapi/clone-visitor.h"
+#include "qapi/qapi-visit-migration.h"
#include "qapi/qapi-visit-sockets.h"
#include "qapi/qapi-commands-migration.h"
#include "qapi/qapi-events-migration.h"
@@ -845,6 +846,13 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
params->has_announce_step = true;
params->announce_step = s->parameters.announce_step;
+ if (s->parameters.has_block_bitmap_mapping) {
+ params->has_block_bitmap_mapping = true;
+ params->block_bitmap_mapping =
+ QAPI_CLONE(BitmapMigrationNodeAliasList,
+ s->parameters.block_bitmap_mapping);
+ }
+
return params;
}
@@ -1310,6 +1318,13 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp)
"is invalid, it must be in the range of 1 to 10000 ms");
return false;
}
+
+ if (params->has_block_bitmap_mapping &&
+ !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
+ error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
+ return false;
+ }
+
return true;
}
@@ -1404,6 +1419,11 @@ static void migrate_params_test_apply(MigrateSetParameters *params,
if (params->has_announce_step) {
dest->announce_step = params->announce_step;
}
+
+ if (params->has_block_bitmap_mapping) {
+ dest->has_block_bitmap_mapping = true;
+ dest->block_bitmap_mapping = params->block_bitmap_mapping;
+ }
}
static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
@@ -1516,6 +1536,16 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
if (params->has_announce_step) {
s->parameters.announce_step = params->announce_step;
}
+
+ if (params->has_block_bitmap_mapping) {
+ qapi_free_BitmapMigrationNodeAliasList(
+ s->parameters.block_bitmap_mapping);
+
+ s->parameters.has_block_bitmap_mapping = true;
+ s->parameters.block_bitmap_mapping =
+ QAPI_CLONE(BitmapMigrationNodeAliasList,
+ params->block_bitmap_mapping);
+ }
}
void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
diff --git a/migration/migration.h b/migration/migration.h
index 721e272713..4be42e8c11 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -337,6 +337,9 @@ void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value);
void dirty_bitmap_mig_before_vm_start(void);
void dirty_bitmap_mig_cancel_outgoing(void);
void dirty_bitmap_mig_cancel_incoming(void);
+bool check_dirty_bitmap_mig_alias_map(const BitmapMigrationNodeAliasList *bbm,
+ Error **errp);
+
void migrate_add_address(SocketAddress *address);
int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index ae4b6a4246..7711726fd2 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -469,6 +469,32 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "%s: '%s'\n",
MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
params->tls_authz);
+
+ if (params->has_block_bitmap_mapping) {
+ const BitmapMigrationNodeAliasList *bmnal;
+
+ monitor_printf(mon, "%s:\n",
+ MigrationParameter_str(
+ MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
+
+ for (bmnal = params->block_bitmap_mapping;
+ bmnal;
+ bmnal = bmnal->next)
+ {
+ const BitmapMigrationNodeAlias *bmna = bmnal->value;
+ const BitmapMigrationBitmapAliasList *bmbal;
+
+ monitor_printf(mon, " '%s' -> '%s'\n",
+ bmna->node_name, bmna->alias);
+
+ for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
+ const BitmapMigrationBitmapAlias *bmba = bmbal->value;
+
+ monitor_printf(mon, " '%s' -> '%s'\n",
+ bmba->name, bmba->alias);
+ }
+ }
+ }
}
qapi_free_MigrationParameters(params);
@@ -1384,6 +1410,10 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
p->has_announce_step = true;
visit_type_size(v, param, &p->announce_step, &err);
break;
+ case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING:
+ error_setg(&err, "The block-bitmap-mapping parameter can only be set "
+ "through QMP");
+ break;
default:
assert(0);
}
diff --git a/qapi/migration.json b/qapi/migration.json
index ea53b23dca..5f6b06172c 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -508,6 +508,44 @@
'data': [ 'none', 'zlib',
{ 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } ] }
+##
+# @BitmapMigrationBitmapAlias:
+#
+# @name: The name of the bitmap.
+#
+# @alias: An alias name for migration (for example the bitmap name on
+# the opposite site).
+#
+# Since: 5.2
+##
+{ 'struct': 'BitmapMigrationBitmapAlias',
+ 'data': {
+ 'name': 'str',
+ 'alias': 'str'
+ } }
+
+##
+# @BitmapMigrationNodeAlias:
+#
+# Maps a block node name and the bitmaps it has to aliases for dirty
+# bitmap migration.
+#
+# @node-name: A block node name.
+#
+# @alias: An alias block node name for migration (for example the
+# node name on the opposite site).
+#
+# @bitmaps: Mappings for the bitmaps on this node.
+#
+# Since: 5.2
+##
+{ 'struct': 'BitmapMigrationNodeAlias',
+ 'data': {
+ 'node-name': 'str',
+ 'alias': 'str',
+ 'bitmaps': [ 'BitmapMigrationBitmapAlias' ]
+ } }
+
##
# @MigrationParameter:
#
@@ -642,6 +680,25 @@
# will consume more CPU.
# Defaults to 1. (Since 5.0)
#
+# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
+# aliases for the purpose of dirty bitmap migration. Such
+# aliases may for example be the corresponding names on the
+# opposite site.
+# The mapping must be one-to-one, but not necessarily
+# complete: On the source, unmapped bitmaps and all bitmaps
+# on unmapped nodes will be ignored. On the destination,
+# encountering an unmapped alias in the incoming migration
+# stream will result in a report, and all further bitmap
+# migration data will then be discarded.
+# Note that the destination does not know about bitmaps it
+# does not receive, so there is no limitation or requirement
+# regarding the number of bitmaps received, or how they are
+# named, or on which nodes they are placed.
+# By default (when this parameter has never been set), bitmap
+# names are mapped to themselves. Nodes are mapped to their
+# block device name if there is one, and to their node name
+# otherwise. (Since 5.2)
+#
# Since: 2.4
##
{ 'enum': 'MigrationParameter',
@@ -656,7 +713,8 @@
'multifd-channels',
'xbzrle-cache-size', 'max-postcopy-bandwidth',
'max-cpu-throttle', 'multifd-compression',
- 'multifd-zlib-level' ,'multifd-zstd-level' ] }
+ 'multifd-zlib-level' ,'multifd-zstd-level',
+ 'block-bitmap-mapping' ] }
##
# @MigrateSetParameters:
@@ -782,6 +840,25 @@
# will consume more CPU.
# Defaults to 1. (Since 5.0)
#
+# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
+# aliases for the purpose of dirty bitmap migration. Such
+# aliases may for example be the corresponding names on the
+# opposite site.
+# The mapping must be one-to-one, but not necessarily
+# complete: On the source, unmapped bitmaps and all bitmaps
+# on unmapped nodes will be ignored. On the destination,
+# encountering an unmapped alias in the incoming migration
+# stream will result in a report, and all further bitmap
+# migration data will then be discarded.
+# Note that the destination does not know about bitmaps it
+# does not receive, so there is no limitation or requirement
+# regarding the number of bitmaps received, or how they are
+# named, or on which nodes they are placed.
+# By default (when this parameter has never been set), bitmap
+# names are mapped to themselves. Nodes are mapped to their
+# block device name if there is one, and to their node name
+# otherwise. (Since 5.2)
+#
# Since: 2.4
##
# TODO either fuse back into MigrationParameters, or make
@@ -812,7 +889,8 @@
'*max-cpu-throttle': 'int',
'*multifd-compression': 'MultiFDCompression',
'*multifd-zlib-level': 'int',
- '*multifd-zstd-level': 'int' } }
+ '*multifd-zstd-level': 'int',
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
##
# @migrate-set-parameters:
@@ -958,6 +1036,25 @@
# will consume more CPU.
# Defaults to 1. (Since 5.0)
#
+# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
+# aliases for the purpose of dirty bitmap migration. Such
+# aliases may for example be the corresponding names on the
+# opposite site.
+# The mapping must be one-to-one, but not necessarily
+# complete: On the source, unmapped bitmaps and all bitmaps
+# on unmapped nodes will be ignored. On the destination,
+# encountering an unmapped alias in the incoming migration
+# stream will result in a report, and all further bitmap
+# migration data will then be discarded.
+# Note that the destination does not know about bitmaps it
+# does not receive, so there is no limitation or requirement
+# regarding the number of bitmaps received, or how they are
+# named, or on which nodes they are placed.
+# By default (when this parameter has never been set), bitmap
+# names are mapped to themselves. Nodes are mapped to their
+# block device name if there is one, and to their node name
+# otherwise. (Since 5.2)
+#
# Since: 2.4
##
{ 'struct': 'MigrationParameters',
@@ -986,7 +1083,8 @@
'*max-cpu-throttle': 'uint8',
'*multifd-compression': 'MultiFDCompression',
'*multifd-zlib-level': 'uint8',
- '*multifd-zstd-level': 'uint8' } }
+ '*multifd-zstd-level': 'uint8',
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
##
# @query-migrate-parameters:
--
2.27.0

View File

@ -69,7 +69,7 @@ Obsoletes: %1-rhev
Summary: QEMU is a machine emulator and virtualizer Summary: QEMU is a machine emulator and virtualizer
Name: qemu-kvm Name: qemu-kvm
Version: 5.1.0 Version: 5.1.0
Release: 3%{?dist} Release: 4%{?dist}
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 15 Epoch: 15
License: GPLv2 and GPLv2+ and CC-BY License: GPLv2 and GPLv2+ and CC-BY
@ -146,6 +146,18 @@ Patch38: kvm-redhat-Update-hw_compat_8_2.patch
Patch39: kvm-redhat-update-pseries-rhel8.2.0-machine-type.patch Patch39: kvm-redhat-update-pseries-rhel8.2.0-machine-type.patch
# For bz#1801242 - [aarch64] vTPM support in machvirt # For bz#1801242 - [aarch64] vTPM support in machvirt
Patch40: kvm-Disable-TPM-passthrough-backend-on-ARM.patch Patch40: kvm-Disable-TPM-passthrough-backend-on-ARM.patch
# For bz#1867075 - CVE-2020-10756 virt:8.3/qemu-kvm: QEMU: slirp: networking out-of-bounds read information disclosure vulnerability [rhel-av-8]
Patch41: kvm-Drop-bogus-IPv6-messages.patch
# For bz#1849707 - 8.3 machine types for x86 - 5.1 update
Patch42: kvm-machine-types-numa-set-numa_mem_supported-on-old-mac.patch
# For bz#1849707 - 8.3 machine types for x86 - 5.1 update
Patch43: kvm-machine_types-numa-compatibility-for-auto_enable_num.patch
# For bz#1790492 - 'dirty-bitmaps' migration capability should allow configuring target nodenames
Patch44: kvm-migration-Add-block-bitmap-mapping-parameter.patch
# For bz#1790492 - 'dirty-bitmaps' migration capability should allow configuring target nodenames
Patch45: kvm-iotests.py-Let-wait_migration-return-on-failure.patch
# For bz#1790492 - 'dirty-bitmaps' migration capability should allow configuring target nodenames
Patch46: kvm-iotests-Test-node-bitmap-aliases-during-migration.patch
BuildRequires: wget BuildRequires: wget
BuildRequires: rpm-build BuildRequires: rpm-build
@ -1114,6 +1126,20 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%changelog %changelog
* Thu Aug 27 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 5.1.0-4.el8
- kvm-Drop-bogus-IPv6-messages.patch [bz#1867075]
- kvm-machine-types-numa-set-numa_mem_supported-on-old-mac.patch [bz#1849707]
- kvm-machine_types-numa-compatibility-for-auto_enable_num.patch [bz#1849707]
- kvm-migration-Add-block-bitmap-mapping-parameter.patch [bz#1790492]
- kvm-iotests.py-Let-wait_migration-return-on-failure.patch [bz#1790492]
- kvm-iotests-Test-node-bitmap-aliases-during-migration.patch [bz#1790492]
- Resolves: bz#1790492
('dirty-bitmaps' migration capability should allow configuring target nodenames)
- Resolves: bz#1849707
(8.3 machine types for x86 - 5.1 update)
- Resolves: bz#1867075
(CVE-2020-10756 virt:8.3/qemu-kvm: QEMU: slirp: networking out-of-bounds read information disclosure vulnerability [rhel-av-8])
* Wed Aug 19 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 5.1.0-3.el8 * Wed Aug 19 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 5.1.0-3.el8
- kvm-redhat-Update-hw_compat_8_2.patch [bz#1843348] - kvm-redhat-Update-hw_compat_8_2.patch [bz#1843348]
- kvm-redhat-update-pseries-rhel8.2.0-machine-type.patch [bz#1843348] - kvm-redhat-update-pseries-rhel8.2.0-machine-type.patch [bz#1843348]