ShaoHe Feng has uploaded a new change for review.

Change subject: Added an option to create a watchdog device.
......................................................................

Added an option to create a watchdog device.

A support for a watchdog device was added to the "devices"
configuration.

Also add the watchdog event callback.

model of watchdog:
    'i6300esb' default model, emulating a PCI Intel 6300ESB
    'ib700'    emulating an ISA iBase IB700

action of watchdog:
    'reset'     default, forcefully reset the guest
    'shutdown'  gracefully shutdown the guest (not recommended)
    'poweroff'  forcefully power off the guest
    'pause'     pause the guest
    'none'      do nothing
    'dump'      automatically dump the guest

The watchdog device can used to detect guest crash, and if choose
'dump' action, the libvirt will dump the guest automatically.
The directory to save dump files can be configured by auto_dump_path
in file /etc/libvirt/qemu.conf.

The watchdog device requires an additional driver and management
daemon in the guest. Just enabling the watchdog in the vdsm
"devices" configuration does not do anything useful on its own.

Change-Id: I2b7970a9050ab0279fe03371b9a77692fba30af8
Signed-off-by: ShaoHe Feng <[email protected]>
---
M vdsm/libvirtconnection.py
M vdsm/libvirtev.py
M vdsm/libvirtvm.py
M vdsm/vm.py
4 files changed, 102 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/35/7535/1

diff --git a/vdsm/libvirtconnection.py b/vdsm/libvirtconnection.py
index e525996..25e2494 100644
--- a/vdsm/libvirtconnection.py
+++ b/vdsm/libvirtconnection.py
@@ -63,6 +63,12 @@
         elif eventid == libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
             path, type, status = args[:-1]
             v._onBlockJobEvent(path, type, status)
+        elif eventid == libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG:
+            wdargs = args[:-1]
+            action = libvirtev.watchdogActionToString(wdargs[0])
+            cif.log.debug("watchdog event: Domain %s(%s). Action: %s",
+                         dom.name(), dom.ID(), action)
+            v._onWatchdogEvent(dom.name(), dom.ID(), action)
         else:
             v.log.warning('unknown eventid %s args %s', eventid, args)
     except:
@@ -118,7 +124,8 @@
                            libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
                            libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
                            libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS,
-                           libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB):
+                           libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
+                           libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG):
                     conn.domainEventRegisterAny(None, ev,
                                                 __eventCallback, (cif, ev))
                 for name in dir(libvirt.virConnect):
diff --git a/vdsm/libvirtev.py b/vdsm/libvirtev.py
index 92a7a0e..b12b916 100644
--- a/vdsm/libvirtev.py
+++ b/vdsm/libvirtev.py
@@ -444,6 +444,16 @@
     return eventStrings[event]
 
 
+def watchdogActionToString(action):
+    actionStrings = ("No action, watchdog ignored",
+                     "Guest CPUs are paused",
+                     "Guest CPUs are reset",
+                     "Guest is forcably powered off",
+                     "Guest is requested to gracefully shutdown",
+                     "No action, a debug message logged")
+    return actionStrings[action]
+
+
 def myDomainEventCallback1(conn, dom, event, detail, opaque):
     print ("myDomainEventCallback1 EVENT: Domain %s(%s) %s %d" %
            (dom.name(), dom.ID(), eventToString(event), detail))
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index e95e94b..cc75d78 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -1188,6 +1188,20 @@
         m.setAttribute('model', self.specParams['model'])
         return m
 
+class WatchdogDevice(LibvirtVmDevice):
+    def getXML(self):
+        """
+        Create domxml for a watchdog device.
+
+        <watchdog model='i6300esb' action='dump'>
+          <address type='pci' domain='0x0000' bus='0x00' slot='0x07' 
function='0x0'/>
+        </watchdog>
+        """
+        m = self.createXmlElem(self.type, None, ['address'])
+        m.setAttribute('model', self.specParams['model'])
+        if 'action' in self.specParams:
+            m.setAttribute('action', self.specParams['action'])
+        return m
 
 class RedirDevice(LibvirtVmDevice):
     def getXML(self):
@@ -1331,6 +1345,7 @@
         self._getUnderlyingVideoDeviceInfo()
         self._getUnderlyingControllerDeviceInfo()
         self._getUnderlyingBalloonDeviceInfo()
+        self._getUnderlyingWatchdogDeviceInfo()
         # Obtain info of all unknown devices. Must be last!
         self._getUnderlyingUnknownDeviceInfo()
 
@@ -1420,6 +1435,7 @@
                   vm.CONTROLLER_DEVICES: ControllerDevice,
                   vm.GENERAL_DEVICES: GeneralDevice,
                   vm.BALLOON_DEVICES: BalloonDevice,
+                  vm.WATCHDOG_DEVICES: WatchdogDevice,
                   vm.REDIR_DEVICES: RedirDevice}
 
         for devType, devClass in devMap.items():
@@ -2031,6 +2047,10 @@
 
         self.saveState()
 
+    def _onWatchdogEvent(self, name, vmid, action):
+        self.log.debug("Watchdog event comes from guest %s(%s). "
+                       "Action: %s", name, vmid, action)
+
     def changeCD(self, drivespec):
         return self._changeBlockDev('cdrom', 'hdc', drivespec)
 
@@ -2374,6 +2394,38 @@
                     dev['address'] = address
                     dev['alias'] = alias
 
+    def _getUnderlyingWatchdogDeviceInfo(self):
+        """
+        Obtain watchdog device info from libvirt.
+        """
+        watchdogxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
+                                 getElementsByTagName('devices')[0]. \
+                                 getElementsByTagName('watchdog')
+        for x in watchdogxml:
+            action = x.getAttribute('action')
+            # Ignore watchdog device without address.
+            if not x.getElementsByTagName('address'):
+                continue
+
+            address = self._getUnderlyingDeviceAddress(x)
+            alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+
+            for dev in self._devices[vm.WATCHDOG_DEVICES]:
+                if not hasattr(dev, 'address'):
+                    dev.address = address
+                    dev.alias = alias
+                if not "action" in dev.specParams:
+                    dev.specParams['action'] = action
+
+            for dev in self.conf['devices']:
+                if ((dev['type'] == vm.WATCHDOG_DEVICES) and
+                    not dev.get('address')):
+                    dev['address'] = address
+                    dev['alias'] = alias
+                if ((dev['type'] == vm.WATCHDOG_DEVICES) and
+                    not "action" in dev['specParams']):
+                    dev['specParams']['action'] = action
+
     def _getUnderlyingVideoDeviceInfo(self):
         """
         Obtain video devices info from libvirt.
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 949a3ee..d24d1a4 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -45,6 +45,7 @@
 GENERAL_DEVICES = 'general'
 BALLOON_DEVICES = 'balloon'
 REDIR_DEVICES = 'redir'
+WATCHDOG_DEVICES = 'watchdog'
 
 """
 A module containing classes needed for VM communication.
@@ -310,7 +311,8 @@
         self._devices = {DISK_DEVICES: [], NIC_DEVICES: [],
                          SOUND_DEVICES: [], VIDEO_DEVICES: [],
                          CONTROLLER_DEVICES: [], GENERAL_DEVICES: [],
-                         BALLOON_DEVICES: [], REDIR_DEVICES: []}
+                         BALLOON_DEVICES: [], REDIR_DEVICES: [],
+                         WATCHDOG_DEVICES: [],}
 
     def _get_lastStatus(self):
         SHOW_PAUSED_STATES = ('Powering down', 'RebootInProgress', 'Up')
@@ -381,11 +383,24 @@
                                'index': 0, 'truesize': 0})
         return removables
 
+    def _removeRedundantDevices(self, devices):
+        counters = 0
+        for dev in self.conf['devices']:
+            if (dev['type'] == devices):
+                counters += 1
+            if (counters > 1):
+                self.conf['devices'].remove(dev)
+        if (counters > 1):
+            self.log.warning("%d redundant %s devices are removed",
+                             counters-1, devices)
+        return counters
+
     def getConfDevices(self):
         devices = {DISK_DEVICES: [], NIC_DEVICES: [],
                    SOUND_DEVICES: [], VIDEO_DEVICES: [],
                    CONTROLLER_DEVICES: [], GENERAL_DEVICES: [],
-                   BALLOON_DEVICES: [], REDIR_DEVICES: []}
+                   BALLOON_DEVICES: [], REDIR_DEVICES: [],
+                   WATCHDOG_DEVICES: []}
         for dev in self.conf.get('devices'):
             try:
                 devices[dev['type']].append(dev)
@@ -417,8 +432,23 @@
             devices[CONTROLLER_DEVICES] = self.getConfController()
             devices[GENERAL_DEVICES] = []
             devices[BALLOON_DEVICES] = []
+            devices[WATCHDOG_DEVICES] = []
             devices[REDIR_DEVICES] = []
         else:
+            # libvirt only support one watchdog device
+            # before getting devices list, check WATCHDOG_DEVICES and
+            # try to remove redundant watchdog devices
+            self._removeRedundantDevices(WATCHDOG_DEVICES)
+            # must assign the model for watchdog device to libvirt
+            # but the action can be assigned default by libvirt
+            # so ignore the action
+            for dev in self.conf['devices']:
+                if (dev['type'] == WATCHDOG_DEVICES):
+                    if not 'specParams' in dev:
+                        dev['specParams'] = {}
+                    if not 'model' in dev['specParams']:
+                        dev['specParams']['model'] = 'i6300esb'
+
             devices = self.getConfDevices()
 
         # Normalize vdsm images


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2b7970a9050ab0279fe03371b9a77692fba30af8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: ShaoHe Feng <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to