/nova_hide_kvm.patch Secret
Created
May 24, 2017 19:19
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/nova/tests/unit/virt/libvirt/test_config.py b/nova/tests/unit/virt/libvirt/test_config.py | |
index 99382f5..04b056c 100644 | |
--- a/nova/tests/unit/virt/libvirt/test_config.py | |
+++ b/nova/tests/unit/virt/libvirt/test_config.py | |
@@ -1845,6 +1845,7 @@ class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest): | |
obj.relaxed = True | |
obj.vapic = True | |
obj.spinlocks = True | |
+ obj.vendor_id = True | |
xml = obj.to_xml() | |
self.assertXmlEqual(xml, """ | |
@@ -1852,8 +1853,20 @@ class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest): | |
<relaxed state="on"/> | |
<vapic state="on"/> | |
<spinlocks state="on" retries="4095"/> | |
+ <vendor_id state="on" value="MyFake_KVM"/> | |
</hyperv>""") | |
+ def test_feature_kvm_hidden(self): | |
+ | |
+ obj = config.LibvirtConfigGuestFeatureKVM() | |
+ obj.hidden = True | |
+ | |
+ xml = obj.to_xml() | |
+ self.assertXmlEqual(xml, """ | |
+ <kvm> | |
+ <hidden state="on"/> | |
+ </kvm>""") | |
+ | |
class LibvirtConfigGuestTest(LibvirtConfigBaseTest): | |
diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py | |
index 9ac130c..61857e0 100644 | |
--- a/nova/tests/unit/virt/libvirt/test_driver.py | |
+++ b/nova/tests/unit/virt/libvirt/test_driver.py | |
@@ -3159,6 +3159,53 @@ class LibvirtConnTestCase(test.NoDBTestCase): | |
self.assertEqual(8191, cfg.features[2].spinlock_retries) | |
self.assertTrue(cfg.features[2].vapic) | |
+ @mock.patch.object(host.Host, 'has_min_version') | |
+ def test_get_guest_config_windows_hide_kvm(self, mock_version): | |
+ mock_version.return_value = True | |
+ drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) | |
+ instance_ref = objects.Instance(**self.test_instance) | |
+ instance_ref['os_type'] = 'windows' | |
+ instance_ref.flavor.extra_specs = {'hw:hide_kvm': 'True'} | |
+ image_meta = objects.ImageMeta.from_dict(self.test_image_meta) | |
+ | |
+ disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type, | |
+ instance_ref, | |
+ image_meta) | |
+ cfg = drvr._get_guest_config(instance_ref, | |
+ _fake_network_info(self, 1), | |
+ image_meta, disk_info) | |
+ | |
+ self.assertEqual(4, len(cfg.features)) | |
+ self.assertIsInstance(cfg.features[2], | |
+ vconfig.LibvirtConfigGuestFeatureHyperV) | |
+ self.assertIsInstance(cfg.features[3], | |
+ vconfig.LibvirtConfigGuestFeatureKVM) | |
+ | |
+ self.assertTrue(cfg.features[2].vendor_id) | |
+ self.assertEqual('MyFake_KVM', cfg.features[2].vendor_id_name) | |
+ self.assertTrue(cfg.features[3].hidden) | |
+ | |
+ @mock.patch.object(host.Host, 'has_min_version') | |
+ def test_get_guest_config_non_windows_hide_kvm(self, mock_version): | |
+ mock_version.return_value = True | |
+ drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) | |
+ instance_ref = objects.Instance(**self.test_instance) | |
+ instance_ref.flavor.extra_specs = {'hw:hide_kvm': 'True'} | |
+ image_meta = objects.ImageMeta.from_dict(self.test_image_meta) | |
+ | |
+ disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type, | |
+ instance_ref, | |
+ image_meta) | |
+ cfg = drvr._get_guest_config(instance_ref, | |
+ _fake_network_info(self, 1), | |
+ image_meta, disk_info) | |
+ | |
+ self.assertEqual(3, len(cfg.features)) | |
+ self.assertIsInstance(cfg.features[2], | |
+ vconfig.LibvirtConfigGuestFeatureKVM) | |
+ | |
+ self.assertTrue(cfg.features[2].hidden) | |
+ | |
def test_get_guest_config_with_two_nics(self): | |
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) | |
instance_ref = objects.Instance(**self.test_instance) | |
diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py | |
index 1cf4d4f..ed98ee0 100644 | |
--- a/nova/virt/libvirt/config.py | |
+++ b/nova/virt/libvirt/config.py | |
@@ -2004,6 +2004,7 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature): | |
# QEMU requires at least this value to be set | |
MIN_SPINLOCK_RETRIES = 4095 | |
+ DEFAULT_VENDOR_ID = "MyFake_KVM" | |
def __init__(self, **kwargs): | |
super(LibvirtConfigGuestFeatureHyperV, self).__init__("hyperv", | |
@@ -2013,6 +2014,8 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature): | |
self.vapic = False | |
self.spinlocks = False | |
self.spinlock_retries = self.MIN_SPINLOCK_RETRIES | |
+ self.vendor_id = False | |
+ self.vendor_id_name = self.DEFAULT_VENDOR_ID | |
def format_dom(self): | |
root = super(LibvirtConfigGuestFeatureHyperV, self).format_dom() | |
@@ -2024,6 +2027,26 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature): | |
if self.spinlocks: | |
root.append(etree.Element("spinlocks", state="on", | |
retries=str(self.spinlock_retries))) | |
+ if self.vendor_id: | |
+ root.append(etree.Element("vendor_id", state="on", | |
+ value=self.vendor_id_name)) | |
+ | |
+ return root | |
+ | |
+ | |
+class LibvirtConfigGuestFeatureKVM(LibvirtConfigGuestFeature): | |
+ | |
+ def __init__(self, **kwargs): | |
+ super(LibvirtConfigGuestFeatureKVM, self).__init__("kvm", | |
+ **kwargs) | |
+ | |
+ self.hidden = True | |
+ | |
+ def format_dom(self): | |
+ root = super(LibvirtConfigGuestFeatureKVM, self).format_dom() | |
+ | |
+ if self.hidden: | |
+ root.append(etree.Element("hidden", state="on")) | |
return root | |
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py | |
index 3cc061d..e33bc3f 100644 | |
--- a/nova/virt/libvirt/driver.py | |
+++ b/nova/virt/libvirt/driver.py | |
@@ -4177,7 +4177,7 @@ class LibvirtDriver(driver.ComputeDriver): | |
tmhyperv.present = True | |
clk.add_timer(tmhyperv) | |
- def _set_features(self, guest, os_type, caps, virt_type): | |
+ def _set_features(self, guest, os_type, caps, virt_type, flavor): | |
if virt_type == "xen": | |
# PAE only makes sense in X86 | |
if caps.host.cpu.arch in (fields.Architecture.I686, | |
@@ -4189,6 +4189,11 @@ class LibvirtDriver(driver.ComputeDriver): | |
guest.features.append(vconfig.LibvirtConfigGuestFeatureACPI()) | |
guest.features.append(vconfig.LibvirtConfigGuestFeatureAPIC()) | |
+ # figure out if we are supposed to configure KVM so the | |
+ # guest is unaware running under it | |
+ hide_kvm = strutils.bool_from_string( | |
+ flavor.extra_specs.get('hw:hide_kvm', 'no')) | |
+ | |
if (virt_type in ("qemu", "kvm") and | |
os_type == 'windows'): | |
hv = vconfig.LibvirtConfigGuestFeatureHyperV() | |
@@ -4200,8 +4205,16 @@ class LibvirtDriver(driver.ComputeDriver): | |
# with Microsoft | |
hv.spinlock_retries = 8191 | |
hv.vapic = True | |
+ if hide_kvm: | |
+ hv.vendor_id = True | |
guest.features.append(hv) | |
+ if (virt_type in ("qemu", "kvm")) and hide_kvm: | |
+ kv = vconfig.LibvirtConfigGuestFeatureKVM() | |
+ kv.hidden = True # hide KVM from guest for NVidia GPU passthrough | |
+ guest.features.append(kv) | |
+ | |
+ | |
def _check_number_of_serial_console(self, num_ports): | |
virt_type = CONF.libvirt.virt_type | |
if (virt_type in ("kvm", "qemu") and | |
@@ -4716,7 +4729,7 @@ class LibvirtDriver(driver.ComputeDriver): | |
self._conf_non_lxc_uml(virt_type, guest, root_device_name, rescue, | |
instance, inst_path, image_meta, disk_info) | |
- self._set_features(guest, instance.os_type, caps, virt_type) | |
+ self._set_features(guest, instance.os_type, caps, virt_type, flavor) | |
self._set_clock(guest, instance.os_type, image_meta, virt_type) | |
storage_configs = self._get_guest_storage_config( |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment