Francesco Romani has uploaded a new change for review. Change subject: caps: report if QEMU supports live snapshots ......................................................................
caps: report if QEMU supports live snapshots Depending on QEMU version and configuration, live snapshotting may be not supported. In that case, a request sent by engine will of course fail. Libvirt until recently did not exposed any information about the live snapshot support, so VDSM, and then engine, had no option other than assume this was supported. Recently libvirt gained this functionality: https://www.redhat.com/archives/libvir-list/2014-March/msg01618.html This patch adds detection and reporting of QEMU live snapshot support, so engine can make informed choices like, for example, disable the relevant fields in the UI. The detection is fully backward-compatible. If the information is missing from the domain capabilities XML, the support is announced to be present. Change-Id: I78dd51fc72f1b6d7eadb5c18d3b768f42d8ee32b Bug-Url: https://bugzilla.redhat.com/1009100 Signed-off-by: Francesco Romani <[email protected]> --- M tests/capsTests.py A tests/caps_libvirt_intel_i73770.out A tests/caps_libvirt_intel_i73770_nosnap.out M vdsm/caps.py M vdsm_api/vdsmapi-schema.json 5 files changed, 310 insertions(+), 5 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/49/26149/1 diff --git a/tests/capsTests.py b/tests/capsTests.py index 942fed5..9083a20 100644 --- a/tests/capsTests.py +++ b/tests/capsTests.py @@ -28,6 +28,12 @@ class TestCaps(TestCaseBase): + def _readCaps(self, fileName): + testPath = os.path.realpath(__file__) + dirName = os.path.split(testPath)[0] + path = os.path.join(dirName, fileName) + with open(path) as f: + return f.read() @MonkeyPatch(platform, 'machine', lambda: caps.Architecture.X86_64) def testCpuInfo(self): @@ -97,11 +103,9 @@ self.assertEqual(t.sockets(), 1) def testEmulatedMachines(self): - testPath = os.path.realpath(__file__) - dirName = os.path.split(testPath)[0] - path = os.path.join(dirName, "caps_libvirt_amd_6274.out") + capsData = self._readCaps("caps_libvirt_amd_6274.out") machines = caps._getEmulatedMachines(caps.Architecture.X86_64, - file(path).read()) + capsData) expectedMachines = ['pc-0.15', 'pc', 'pc-1.0', 'pc-0.14', 'pc-0.13', 'pc-0.12', 'pc-0.11', 'pc-0.10', 'isapc'] @@ -114,3 +118,22 @@ sign = ["=", "&"] for res, s in zip(expectedRes, sign): self.assertEqual(res, caps._parseKeyVal(lines, s)) + + def testLiveSnapshotNoElement(self): + '''old libvirt, backward compatibility''' + capsData = self._readCaps("caps_libvirt_amd_6274.out") + support = caps._getLiveSnapshotSupport(caps.Architecture.X86_64, + capsData) + self.assertTrue(support) + + def testLiveSnapshot(self): + capsData = self._readCaps("caps_libvirt_intel_i73770.out") + support = caps._getLiveSnapshotSupport(caps.Architecture.X86_64, + capsData) + self.assertTrue(support) + + def testLiveSnapshotDisabled(self): + capsData = self._readCaps("caps_libvirt_intel_i73770_nosnap.out") + support = caps._getLiveSnapshotSupport(caps.Architecture.X86_64, + capsData) + self.assertFalse(support) diff --git a/tests/caps_libvirt_intel_i73770.out b/tests/caps_libvirt_intel_i73770.out new file mode 100644 index 0000000..fdeff64 --- /dev/null +++ b/tests/caps_libvirt_intel_i73770.out @@ -0,0 +1,127 @@ +<capabilities> + + <host> + <uuid>391bfa06-18ca-a3b5-2820-08951b92b806</uuid> + <cpu> + <arch>x86_64</arch> + <model>SandyBridge</model> + <vendor>Intel</vendor> + <topology sockets='1' cores='4' threads='2'/> + <feature name='erms'/> + <feature name='smep'/> + <feature name='fsgsbase'/> + <feature name='rdrand'/> + <feature name='f16c'/> + <feature name='osxsave'/> + <feature name='pcid'/> + <feature name='pdcm'/> + <feature name='xtpr'/> + <feature name='tm2'/> + <feature name='est'/> + <feature name='smx'/> + <feature name='vmx'/> + <feature name='ds_cpl'/> + <feature name='monitor'/> + <feature name='dtes64'/> + <feature name='pbe'/> + <feature name='tm'/> + <feature name='ht'/> + <feature name='ss'/> + <feature name='acpi'/> + <feature name='ds'/> + <feature name='vme'/> + </cpu> + <power_management> + <suspend_mem/> + <suspend_disk/> + </power_management> + <migration_features> + <live/> + <uri_transports> + <uri_transport>tcp</uri_transport> + </uri_transports> + </migration_features> + <topology> + <cells num='1'> + <cell id='0'> + <cpus num='8'> + <cpu id='0' socket_id='0' core_id='0' siblings='0,4'/> + <cpu id='1' socket_id='0' core_id='1' siblings='1,5'/> + <cpu id='2' socket_id='0' core_id='2' siblings='2,6'/> + <cpu id='3' socket_id='0' core_id='3' siblings='3,7'/> + <cpu id='4' socket_id='0' core_id='0' siblings='0,4'/> + <cpu id='5' socket_id='0' core_id='1' siblings='1,5'/> + <cpu id='6' socket_id='0' core_id='2' siblings='2,6'/> + <cpu id='7' socket_id='0' core_id='3' siblings='3,7'/> + </cpus> + </cell> + </cells> + </topology> + <secmodel> + <model>selinux</model> + <doi>0</doi> + </secmodel> + </host> + + <guest> + <os_type>hvm</os_type> + <arch name='i686'> + <wordsize>32</wordsize> + <emulator>/usr/libexec/qemu-kvm</emulator> + <machine>rhel6.5.0</machine> + <machine canonical='rhel6.5.0'>pc</machine> + <machine>rhel6.4.0</machine> + <machine>rhel6.3.0</machine> + <machine>rhel6.2.0</machine> + <machine>rhel6.1.0</machine> + <machine>rhel6.0.0</machine> + <machine>rhel5.5.0</machine> + <machine>rhel5.4.4</machine> + <machine>rhel5.4.0</machine> + <domain type='qemu'> + </domain> + <domain type='kvm'> + <emulator>/usr/libexec/qemu-kvm</emulator> + </domain> + </arch> + <features> + <cpuselection/> + <deviceboot/> + <acpi default='on' toggle='yes'/> + <apic default='on' toggle='no'/> + <pae/> + <nonpae/> + </features> + </guest> + + <guest> + <os_type>hvm</os_type> + <arch name='x86_64'> + <wordsize>64</wordsize> + <emulator>/usr/libexec/qemu-kvm</emulator> + <machine>rhel6.5.0</machine> + <machine canonical='rhel6.5.0'>pc</machine> + <machine>rhel6.4.0</machine> + <machine>rhel6.3.0</machine> + <machine>rhel6.2.0</machine> + <machine>rhel6.1.0</machine> + <machine>rhel6.0.0</machine> + <machine>rhel5.5.0</machine> + <machine>rhel5.4.4</machine> + <machine>rhel5.4.0</machine> + <domain type='qemu'> + </domain> + <domain type='kvm'> + <emulator>/usr/libexec/qemu-kvm</emulator> + </domain> + </arch> + <features> + <cpuselection/> + <deviceboot/> + <disksnapshot default='on' toggle='no'/> + <acpi default='on' toggle='yes'/> + <apic default='on' toggle='no'/> + </features> + </guest> + +</capabilities> diff --git a/tests/caps_libvirt_intel_i73770_nosnap.out b/tests/caps_libvirt_intel_i73770_nosnap.out new file mode 100644 index 0000000..b7a31d1 --- /dev/null +++ b/tests/caps_libvirt_intel_i73770_nosnap.out @@ -0,0 +1,127 @@ +<capabilities> + + <host> + <uuid>391bfa06-18ca-a3b5-2820-08951b92b806</uuid> + <cpu> + <arch>x86_64</arch> + <model>SandyBridge</model> + <vendor>Intel</vendor> + <topology sockets='1' cores='4' threads='2'/> + <feature name='erms'/> + <feature name='smep'/> + <feature name='fsgsbase'/> + <feature name='rdrand'/> + <feature name='f16c'/> + <feature name='osxsave'/> + <feature name='pcid'/> + <feature name='pdcm'/> + <feature name='xtpr'/> + <feature name='tm2'/> + <feature name='est'/> + <feature name='smx'/> + <feature name='vmx'/> + <feature name='ds_cpl'/> + <feature name='monitor'/> + <feature name='dtes64'/> + <feature name='pbe'/> + <feature name='tm'/> + <feature name='ht'/> + <feature name='ss'/> + <feature name='acpi'/> + <feature name='ds'/> + <feature name='vme'/> + </cpu> + <power_management> + <suspend_mem/> + <suspend_disk/> + </power_management> + <migration_features> + <live/> + <uri_transports> + <uri_transport>tcp</uri_transport> + </uri_transports> + </migration_features> + <topology> + <cells num='1'> + <cell id='0'> + <cpus num='8'> + <cpu id='0' socket_id='0' core_id='0' siblings='0,4'/> + <cpu id='1' socket_id='0' core_id='1' siblings='1,5'/> + <cpu id='2' socket_id='0' core_id='2' siblings='2,6'/> + <cpu id='3' socket_id='0' core_id='3' siblings='3,7'/> + <cpu id='4' socket_id='0' core_id='0' siblings='0,4'/> + <cpu id='5' socket_id='0' core_id='1' siblings='1,5'/> + <cpu id='6' socket_id='0' core_id='2' siblings='2,6'/> + <cpu id='7' socket_id='0' core_id='3' siblings='3,7'/> + </cpus> + </cell> + </cells> + </topology> + <secmodel> + <model>selinux</model> + <doi>0</doi> + </secmodel> + </host> + + <guest> + <os_type>hvm</os_type> + <arch name='i686'> + <wordsize>32</wordsize> + <emulator>/usr/libexec/qemu-kvm</emulator> + <machine>rhel6.5.0</machine> + <machine canonical='rhel6.5.0'>pc</machine> + <machine>rhel6.4.0</machine> + <machine>rhel6.3.0</machine> + <machine>rhel6.2.0</machine> + <machine>rhel6.1.0</machine> + <machine>rhel6.0.0</machine> + <machine>rhel5.5.0</machine> + <machine>rhel5.4.4</machine> + <machine>rhel5.4.0</machine> + <domain type='qemu'> + </domain> + <domain type='kvm'> + <emulator>/usr/libexec/qemu-kvm</emulator> + </domain> + </arch> + <features> + <cpuselection/> + <deviceboot/> + <acpi default='on' toggle='yes'/> + <apic default='on' toggle='no'/> + <pae/> + <nonpae/> + </features> + </guest> + + <guest> + <os_type>hvm</os_type> + <arch name='x86_64'> + <wordsize>64</wordsize> + <emulator>/usr/libexec/qemu-kvm</emulator> + <machine>rhel6.5.0</machine> + <machine canonical='rhel6.5.0'>pc</machine> + <machine>rhel6.4.0</machine> + <machine>rhel6.3.0</machine> + <machine>rhel6.2.0</machine> + <machine>rhel6.1.0</machine> + <machine>rhel6.0.0</machine> + <machine>rhel5.5.0</machine> + <machine>rhel5.4.4</machine> + <machine>rhel5.4.0</machine> + <domain type='qemu'> + </domain> + <domain type='kvm'> + <emulator>/usr/libexec/qemu-kvm</emulator> + </domain> + </arch> + <features> + <cpuselection/> + <deviceboot/> + <disksnapshot default='off' toggle='no'/> + <acpi default='on' toggle='yes'/> + <apic default='on' toggle='no'/> + </features> + </guest> + +</capabilities> diff --git a/vdsm/caps.py b/vdsm/caps.py index b260d29..4aca372 100644 --- a/vdsm/caps.py +++ b/vdsm/caps.py @@ -164,6 +164,30 @@ return topology +def _findLiveSnapshotSupport(guest): + features = guest.getElementsByTagName('features')[0] + for feature in features.childNodes: + if feature.nodeName == 'disksnapshot': + value = feature.getAttribute('default') + return value.lower() == 'on' + # libvirt < 1.2.2 does not export this information. + # we default as support present + return True + + [email protected] +def _getLiveSnapshotSupport(arch, capabilities=None): + if capabilities is None: + capabilities = _getCapsXMLStr() + caps = minidom.parseString(capabilities) + + for guestTag in caps.getElementsByTagName('guest'): + archTag = guestTag.getElementsByTagName('arch')[0] + if archTag.getAttribute('name') == arch: + return _findLiveSnapshotSupport(guestTag) + return False + + @utils.memoized def _getEmulatedMachines(arch, capabilities=None): if capabilities is None: @@ -386,6 +410,7 @@ config.getint('vars', 'extra_mem_reserve')) caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead') caps['rngSources'] = _getRngSources() + caps['liveSnapshot'] = _getLiveSnapshotSupport() return caps diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json index 0a2db11..5d05207 100644 --- a/vdsm_api/vdsmapi-schema.json +++ b/vdsm_api/vdsmapi-schema.json @@ -1045,6 +1045,9 @@ # # @rngSources: Sources of entropy available at this host # +# @liveSnapshot: Indicates if the host supports live snapshotting +# (new in version 4.15.0) +# # Since: 4.10.0 # # Notes: Since ovirt-engine cannot parse software versions in 'x.y.z' format, @@ -1065,7 +1068,7 @@ 'HBAInventory': 'HbaInventory', 'vmTypes': ['VmType'], 'memSize': 'uint', 'reservedMem': 'uint', 'guestOverhead': 'uint', 'netConfigDirty': 'bool', - 'rngSources': ['VmRngDeviceSource']}} + 'rngSources': ['VmRngDeviceSource'], 'liveSnapshot': 'bool'}} ## # @Host.getCapabilities: -- To view, visit http://gerrit.ovirt.org/26149 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I78dd51fc72f1b6d7eadb5c18d3b768f42d8ee32b Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Francesco Romani <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
