Francesco Romani has uploaded a new change for review.

Change subject: vm: add extra recovery checking for ppc
......................................................................

vm: add extra recovery checking for ppc

On recovery, VDSM checks each VM listed by libvirt
to see if it should take care of it.
The check is done by using some system properties
added in the smbios domain element, which is lacking
outside x86_64.

As result, recovery finds no VMs on PPC64.

This patch adds an extra checks in addition to the
existing one, based on the guest agent channels, to overcome
this limitation.

guest agent channels can be disabled by configuration,
but this is a rare and unlikely scenario; moreover,
this is still the most reliable indicator left of
a VM created by VDSM.

Change-Id: Ic0cc57129e9c8e6545f9a947329adf1f9e82648f
Bug-Url: https://bugzilla.redhat.com/1126887
Signed-off-by: Francesco Romani <[email protected]>
---
M tests/vmTests.py
M tests/vmTestsData.py
M vdsm/clientIF.py
M vdsm/virt/vm.py
4 files changed, 115 insertions(+), 14 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/41/31241/1

diff --git a/tests/vmTests.py b/tests/vmTests.py
index e43af8d..ddfab4a 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -25,6 +25,7 @@
 import shutil
 import tempfile
 import xml.etree.ElementTree as ET
+import xml.dom.minidom as MD
 
 import libvirt
 
@@ -42,6 +43,7 @@
 from monkeypatch import MonkeyPatch, MonkeyPatchScope
 from vmTestsData import CONF_TO_DOMXML_X86_64
 from vmTestsData import CONF_TO_DOMXML_PPC64
+from vmTestsData import DOMXML_NO_VDSM_CHANNEL
 
 
 class ConnectionMock:
@@ -105,6 +107,18 @@
         self._io_tune[name] = io_tune
         return 1
 
+    def testHasVDSMChannelsX86_64(self):
+        vmdom = MD.parseString(CONF_TO_DOMXML_X86_64[0][1])
+        self.assertTrue(vm.hasVDSMChannels(vmdom))
+
+    def testHasVDSMChannelsPPC64(self):
+        vmdom = MD.parseString(CONF_TO_DOMXML_PPC64[0][1])
+        self.assertTrue(vm.hasVDSMChannels(vmdom))
+
+    def testHasNotVdsmChannels(self):
+        vmdom = MD.parseString(DOMXML_NO_VDSM_CHANNEL)
+        self.assertFalse(vm.hasVDSMChannels(vmdom))
+
 
 class TestVm(TestCaseBase):
 
diff --git a/tests/vmTestsData.py b/tests/vmTestsData.py
index 3cee160..02959fd 100644
--- a/tests/vmTestsData.py
+++ b/tests/vmTestsData.py
@@ -143,3 +143,73 @@
                 </qemu:commandline>
             </domain>
 """, )]
+
+DOMXML_NO_VDSM_CHANNEL = """
+<domain type="kvm">
+    <name>SuperTiny_C0</name>
+    <uuid>%(vmId)s</uuid>
+    <memory>65536</memory>
+    <currentMemory>65536</currentMemory>
+    <vcpu current="1">160</vcpu>
+    <memtune>
+        <min_guarantee>16384</min_guarantee>
+    </memtune>
+    <devices>
+        <channel type="unix">
+            <target name="org.qemu.guest_agent.0" type="virtio"/>
+            <source mode="bind"
+    path="/var/lib/libvirt/qemu/channels/$(vmId)s.org.qemu.guest_agent.0"/>
+        </channel>
+        <input bus="ps2" type="mouse"/>
+        <memballoon model="none"/>
+        <controller index="0" model="virtio-scsi" type="scsi">
+            <address bus="0x00" domain="0x0000" function="0x0" slot="0x03"
+                type="pci"/>
+        </controller>
+        <video>
+            <address bus="0x00" domain="0x0000" function="0x0" slot="0x02"
+                type="pci"/>
+            <model heads="1" type="qxl" vram="32768"/>
+        </video>
+        <graphics autoport="yes" keymap="en-us" passwd="*****"
+    passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice">
+            <listen network="vdsm-ovirtmgmt" type="network"/>
+        </graphics>
+        <disk device="cdrom" snapshot="no" type="file">
+            <address bus="1" controller="0" target="0" type="drive" unit="0"/>
+            <source file="" startupPolicy="optional"/>
+            <target bus="ide" dev="hdc"/>
+            <readonly/>
+            <serial/>
+            <boot order="1"/>
+        </disk>
+        <channel type="spicevmc">
+            <target name="com.redhat.spice.0" type="virtio"/>
+        </channel>
+    </devices>
+    <os>
+        <type arch="x86_64" machine="rhel6.5.0">hvm</type>
+        <smbios mode="sysinfo"/>
+    </os>
+    <sysinfo type="smbios">
+        <system>
+            <entry name="manufacturer">oVirt</entry>
+            <entry name="product">oVirt Node</entry>
+            <entry name="version">6Server-6.5.0.1.el6</entry>
+            <entry name="uuid">b63bfabf-6be6-4273-b133-3f8a068f52ac</entry>
+        </system>
+    </sysinfo>
+    <clock adjustment="0" offset="variable">
+        <timer name="rtc" tickpolicy="catchup"/>
+        <timer name="pit" tickpolicy="delay"/>
+        <timer name="hpet" present="no"/>
+    </clock>
+    <features>
+        <acpi/>
+    </features>
+    <cpu match="exact">
+        <model>SandyBridge</model>
+        <topology cores="1" sockets="160" threads="1"/>
+    </cpu>
+</domain>
+"""
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index a2df805..0fe2d40 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -45,7 +45,7 @@
 from virt import sampling
 from virt import vm
 from virt import vmstatus
-from virt.vm import Vm
+from virt.vm import Vm, hasVDSMChannels
 from virt.vmchannels import Listener
 from virt.utils import isVdsmImage
 try:
@@ -484,25 +484,32 @@
         """
         try:
             vmdom = minidom.parseString(vm.XMLDesc(0))
-            sysinfo = vmdom.getElementsByTagName("sysinfo")[0]
         except libvirt.libvirtError as e:
             if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
                 self.log.error("domId: %s is dead", vm.UUIDString())
             else:
                 raise
-        except IndexError:
-            pass  # no sysinfo in xml
         else:
-            systype = sysinfo.getAttribute("type")
-            if systype == "smbios":
-                entries = sysinfo.getElementsByTagName("entry")
-                for entry in entries:
-                    if entry.getAttribute("name") == "product":
-                        prod = entry.firstChild.data
-                        if prod in (caps.OSName.RHEL, caps.OSName.OVIRT,
-                                    caps.OSName.RHEVH, caps.OSName.FEDORA,
-                                    caps.OSName.DEBIAN):
-                            return True
+            infos = vmdom.getElementsByTagName("sysinfo")
+            if infos:
+                sysinfo = infos[0]
+                systype = sysinfo.getAttribute("type")
+                if systype == "smbios":
+                    entries = sysinfo.getElementsByTagName("entry")
+                    for entry in entries:
+                        if entry.getAttribute("name") == "product":
+                            prod = entry.firstChild.data
+                            if prod in (caps.OSName.RHEL, caps.OSName.OVIRT,
+                                        caps.OSName.RHEVH, caps.OSName.FEDORA,
+                                        caps.OSName.DEBIAN):
+                                return True
+            # else no sysinfo in xml, fallback to less reliable guest agent
+            # channel detection (mostly PPC)
+            try:
+                return hasVDSMChannels(vmdom)
+            except IndexError:
+                # recovery must not fail
+                pass
         return False
 
     def _getVDSMVms(self):
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 9e93425..eef794a 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -101,6 +101,16 @@
 _NO_CPU_PERIOD = 0
 
 
+def hasVDSMChannels(vmdom):
+    devices = vmdom.getElementsByTagName('devices')[0]
+    for chan in devices.getElementsByTagName('channel'):
+        target = chan.getElementsByTagName('target')[0]
+        if target.getAttribute('name') == _VMCHANNEL_DEVICE_NAME:
+            return True
+
+    return False
+
+
 def _filterSnappableDiskDevices(diskDeviceXmlElements):
         return filter(lambda(x): not(x.getAttribute('device')) or
                       x.getAttribute('device') in ['disk', 'lun'],


-- 
To view, visit http://gerrit.ovirt.org/31241
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic0cc57129e9c8e6545f9a947329adf1f9e82648f
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

Reply via email to