Change in vdsm[master]: caps: report if QEMU supports live snapshots

fromani at redhat.com fromani at redhat.com
Thu Mar 27 10:45:33 UTC 2014


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 <fromani at redhat.com>
---
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
+
+
+ at utils.memoized
+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 <fromani at redhat.com>


More information about the vdsm-patches mailing list