Hello Bing Bu Cao,

I'd like you to do a code review.  Please visit

    http://gerrit.ovirt.org/9655

to review the following change.

Change subject: Add shutdown based on qemu-ga(qemu guest agent) in vdsm
......................................................................

Add shutdown based on qemu-ga(qemu guest agent) in vdsm

As previously what we agreed, the agent-assisted shutdown and fsfreeze
would be handled by the qemu guest agent while oVirt-specific functionality
such as Single-Sign-On would continue to be managed by the ovirt guest agent.

http://www.ovirt.org/wiki/Guest_agent_proposals

This patch changes the shutdown verb, add an shutdown approach by qemu guest
agent

Change-Id: I86977c1b717d63de21ba4818c6b66e43976d65de
Signed-off-by: ShaoHe Feng <[email protected]>
Signed-off-by: BingBu Cao <[email protected]>
---
M vdsm/libvirtvm.py
M vdsm/vm.py
2 files changed, 84 insertions(+), 28 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/55/9655/1

diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index f20968f..f1d82d7 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -1222,6 +1222,8 @@
         self._releaseLock = threading.Lock()
         self.saveState()
 
+        self.shutdownMethodUpdate()
+
     def _buildLease(self, domainID, volumeID, leasePath, leaseOffset):
         """
         Add a single SANLock lease.
@@ -2326,9 +2328,45 @@
                                   physical, alloc)
                     self.extendDriveVolume(d)
 
+    def shutdownMethodUpdate(self):
+        self._shutdownMethods = []
+        self._shutdownMethods.append({'qemugaShutdown':
+                                      self.qemugaShutdown})
+        self._shutdownMethods.append({'guestAgentShutdown':
+                                      self.guestAgentShutdown})
+        self._shutdownMethods.append({'acpiShutdown':
+                                      self.acpiShutdown})
+
     def _acpiShutdown(self):
         self._dom.shutdownFlags(libvirt.VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN)
 
+    def acpiShutdown(self, now, *args):
+        if utils.tobool(self.conf.get('acpiEnable', 'true')):
+            self.log.debug("acpiShutdown vm")
+            self._guestEventTime = now
+            self._guestEvent = 'Powering down'
+            self._acpiShutdown()
+        else:
+            return None
+
+        return {'status': {'code': doneCode['code'],
+                'message': 'Machine shut down'}}
+
+    def _qemugaShutdown(self):
+        self._dom.shutdownFlags(libvirt.VIR_DOMAIN_SHUTDOWN_GUEST_AGENT)
+
+    def qemugaShutdown(self, now, *args):
+        if utils.tobool(self.conf.get('qgaEnable', 'true')):
+            self.log.debug("qemugaShutdown vm")
+            self._guestEventTime = now
+            self._guestEvent = 'Powering down'
+            self._qemugaShutdown()
+        else:
+            return None
+
+        return {'status': {'code': doneCode['code'],
+                'message': 'Machine shut down'}}
+
     def _getPid(self):
         pid = '0'
         try:
diff --git a/vdsm/vm.py b/vdsm/vm.py
index cb0e552..bf6ee8b 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -364,6 +364,8 @@
                          CONTROLLER_DEVICES: [], GENERAL_DEVICES: [],
                          BALLOON_DEVICES: [], REDIR_DEVICES: [],
                          WATCHDOG_DEVICES: []}
+        self._shutdownMethods = []
+        self.shutdownMethodUpdate()
 
     def _get_lastStatus(self):
         PAUSED_STATES = ('Powering down', 'RebootInProgress', 'Up')
@@ -970,35 +972,51 @@
             if not guestCpuLocked:
                 self._guestCpuLock.release()
 
+    def shutdownMethodUpdate(self):
+        self._shutdownMethods = []
+        self._shutdownMethods.append({'guestAgentShutdown':
+                                      self._guestAgentShutdown})
+
     def shutdown(self, timeout, message):
-        try:
-            now = time.time()
-            if self.lastStatus == 'Down':
-                return
-            if self.guestAgent and self.guestAgent.isResponsive():
-                self._guestEventTime = now
-                self._guestEvent = 'Powering down'
-                self.log.debug('guestAgent shutdown called')
-                self.guestAgent.desktopShutdown(timeout, message)
-                agent_timeout = (int(timeout) +
-                                 config.getint('vars', 'sys_shutdown_timeout'))
-                timer = threading.Timer(agent_timeout, self._timedShutdown)
-                timer.start()
-            elif utils.tobool(self.conf.get('acpiEnable', 'true')):
-                self._guestEventTime = now
-                self._guestEvent = 'Powering down'
-                self._acpiShutdown()
-            # No tools, no ACPI
-            else:
-                return {
-                    'status': {
-                        'code': errCode['exist']['status']['code'],
-                        'message': 'VM without ACPI or active SolidICE tools. '
-                                   'Try Forced Shutdown.'}}
-        except:
-            self.log.error("Shutdown failed", exc_info=True)
-            return {'status': {'code': errCode['exist']['status']['code'],
-                    'message': 'Failed to shutdown VM. Try Forced Shutdown.'}}
+        if self.lastStatus == 'Down':
+            return
+        now = time.time()
+
+        status = None
+        for method, func in self._shutdownMethods:
+            try:
+                status = func(now, timeout, message)
+            except:
+                self.log.error("%s failed", method, exc_info=True)
+                status = {'status':
+                          {'code': errCode['exist']['status']['code'],
+                           'message': 'Failed to shutdown VM. '
+                           'Try Forced Shutdown.'}}
+            # if one shutdown method failed, will try another method
+            # the loop will stop once a shutdown method is successful
+            if doneCode['code'] == status['status']['code']:
+                return status
+        if not status:
+            return {'status':
+                    {'code': errCode['exist']['status']['code'],
+                     'message': 'VM without ACPI or active SolidICE tools. '
+                                'Try Forced Shutdown.'}}
+
+        return status
+
+    def guestAgentShutdown(self, now, timeout, message):
+        if self.guestAgent and self.guestAgent.isResponsive():
+            self._guestEventTime = time.time()
+            self._guestEvent = 'Powering down'
+            self.log.debug('guestAgent shutdown called')
+            self.guestAgent.desktopShutdown(timeout, message)
+            agent_timeout = (int(timeout) +
+                             config.getint('vars', 'sys_shutdown_timeout'))
+            timer = threading.Timer(agent_timeout, self._timedShutdown)
+            timer.start()
+        else:
+            return None
+
         return {'status': {'code': doneCode['code'],
                 'message': 'Machine shut down'}}
 


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

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

Reply via email to