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