From 49a012e83c44d28ee533aace22c42b1781b8e5e2 Mon Sep 17 00:00:00 2001 From: Claudiu Belu Date: Tue, 13 Jun 2017 16:07:58 +0300 Subject: [PATCH] Fixes cached old WMI service objects issue When using WMI, the resources passed to the Msvm_VirtualSystemManagementService are not cleaned up by the garbage collector if the Service object is still referenced (cached as a property in BaseUtilsVirt). PyMI doesn't have this issue, so the Service objects can be safely cached. This issue only affects Windows / Hyper-V Server 2012. Change-Id: If8df0bf0a2f13a9e94993dde8b2a18943f2e9f83 Closes-Bug: #1697389 --- .../unit/utils/compute/test_migrationutils.py | 1 - os_win/tests/unit/utils/test_baseutils.py | 2 ++ os_win/utils/baseutils.py | 14 ++++++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/os_win/tests/unit/utils/compute/test_migrationutils.py b/os_win/tests/unit/utils/compute/test_migrationutils.py index fcd10d81..43be8470 100644 --- a/os_win/tests/unit/utils/compute/test_migrationutils.py +++ b/os_win/tests/unit/utils/compute/test_migrationutils.py @@ -33,7 +33,6 @@ class MigrationUtilsTestCase(test_base.OsWinBaseTestCase): self._migrationutils = migrationutils.MigrationUtils() self._migrationutils._vmutils = mock.MagicMock() self._migrationutils._conn_attr = mock.MagicMock() - self._migrationutils._compat_conn_attr = mock.MagicMock() self._migrationutils._jobutils = mock.MagicMock() def test_get_export_setting_data(self): diff --git a/os_win/tests/unit/utils/test_baseutils.py b/os_win/tests/unit/utils/test_baseutils.py index 405a560a..0e158ef3 100644 --- a/os_win/tests/unit/utils/test_baseutils.py +++ b/os_win/tests/unit/utils/test_baseutils.py @@ -95,6 +95,7 @@ class BaseUtilsVirtTestCase(test_base.OsWinBaseTestCase): mock_os] expected = self.utils._conn.Msvm_VirtualSystemManagementService()[0] self.assertEqual(expected, self.utils._vs_man_svc) + self.assertEqual(expected, self.utils._vs_man_svc_attr) @mock.patch.object(baseutils, 'imp') @mock.patch.object(baseutils, 'wmi', create=True) @@ -108,6 +109,7 @@ class BaseUtilsVirtTestCase(test_base.OsWinBaseTestCase): expected = old_conn.Msvm_VirtualSystemManagementService()[0] self.assertEqual(expected, self.utils._vs_man_svc) + self.assertIsNone(self.utils._vs_man_svc_attr) mock_imp.load_source.assert_called_once_with( 'old_wmi', '%s.py' % fake_module_path) diff --git a/os_win/utils/baseutils.py b/os_win/utils/baseutils.py index 8eee4cb1..5aa304dc 100644 --- a/os_win/utils/baseutils.py +++ b/os_win/utils/baseutils.py @@ -91,10 +91,16 @@ class BaseUtilsVirt(BaseUtils): @property def _vs_man_svc(self): - if not self._vs_man_svc_attr: - self._vs_man_svc_attr = ( - self._compat_conn.Msvm_VirtualSystemManagementService()[0]) - return self._vs_man_svc_attr + if self._vs_man_svc_attr: + return self._vs_man_svc_attr + + vs_man_svc = self._compat_conn.Msvm_VirtualSystemManagementService()[0] + if BaseUtilsVirt._os_version >= [6, 3]: + # NOTE(claudiub): caching this property on Windows / Hyper-V Server + # 2012 (using the old WMI) can lead to memory leaks. PyMI doesn't + # have those issues, so we can safely cache it. + self._vs_man_svc_attr = vs_man_svc + return vs_man_svc def _get_wmi_compat_conn(self, moniker, **kwargs): # old WMI should be used on Windows / Hyper-V Server 2012 whenever