Handle libvirt events in qubesd

This is required to get shutdown notification, when it wasn't initiated
by qubesd (for example 'poweroff' command inside of VM).
Libvirt event loop implementation must be registered before making
connection to libvirt, so move it to the beginning of main().
For now, only 'domain-shutdown' event is emited.
Tento commit je obsažen v:
Marek Marczykowski-Górecki 2017-04-27 00:40:55 +02:00
rodič 3e067a3ef5
revize 0dfcaa63c9
V databázi nebyl nalezen žádný známý klíč pro tento podpis
ID GPG klíče: 063938BA42CFA724
3 změnil soubory, kde provedl 44 přidání a 3 odebrání

Zobrazit soubor

@ -106,6 +106,7 @@ class VirConnectWrapper(object):
is_dead = not self._conn.isAlive()
if is_dead:
self._conn = libvirt.open(self._conn.getURI())
# TODO: re-register event handlers
return is_dead
def _wrap_domain(self, ret):
@ -213,6 +214,33 @@ class VMMConnection(object):
self.init_vmm_connection()
return self._xs
def register_event_handlers(self, app):
'''Register libvirt event handlers, which will translate libvirt
events into qubes.events. This function should be called only in
'qubesd' process and only when mainloop has been already set.
'''
self._libvirt_conn.domainEventRegisterAny(
None, # any domain
libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
self._domain_event_callback,
app
)
@staticmethod
def _domain_event_callback(_conn, domain, event, _detail, opaque):
'''Generic libvirt event handler (virConnectDomainEventCallback),
translate libvirt event into qubes.events.
'''
app = opaque
try:
vm = app.domains[domain.name()]
except KeyError:
# ignore events for unknown domains
return
if event == libvirt.VIR_DOMAIN_EVENT_STOPPED:
vm.fire_event('domain-shutdown')
def __del__(self):
if self._libvirt_conn:
self._libvirt_conn.close()

Zobrazit soubor

@ -176,11 +176,17 @@ def sighandler(loop, signame, server, server_internal):
parser = qubes.tools.QubesArgumentParser(description='Qubes OS daemon')
def main(args=None):
args = parser.parse_args(args)
loop = asyncio.get_event_loop()
def main(args=None):
loop = asyncio.get_event_loop()
libvirtaio.virEventRegisterAsyncIOImpl(loop=loop)
try:
args = parser.parse_args(args)
except:
loop.close()
raise
args.app.vmm.register_event_handlers(args.app)
try:
os.unlink(QUBESD_SOCK)

Zobrazit soubor

@ -195,6 +195,13 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
*other arguments are as in :py:meth:`start`*
.. event:: domain-shutdown (subject, event)
Fired when domain has been shut down.
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-shutdown'``)
.. event:: domain-pre-shutdown (subject, event, force)
Fired at the beginning of :py:meth:`shutdown` method.