libvirt/src/conf/domain_event.h
Daniel P. Berrange 987e31edc9 Add domain events for graphics network clients
This introduces a new event type

   VIR_DOMAIN_EVENT_ID_GRAPHICS

The same event can be emitted in 3 scenarios

  typedef enum {
      VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
      VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
      VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
  } virDomainEventGraphicsPhase;

Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop

This event comes with *a lot* of potential information

 - IP address, port & address family of client
 - IP address, port & address family of server
 - Authentication scheme (arbitrary string)
 - Authenticated subject identity. A subject may have
   multiple identities with some authentication schemes.
   For example, vencrypt+sasl results in a x509dname
   and saslUsername identities.

This results in a very complicated callback :-(

   typedef enum {
      VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
      VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
   } virDomainEventGraphicsAddressType;

   struct _virDomainEventGraphicsAddress {
       int family;
       const char *node;
       const char *service;
   };
   typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
   typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;

   struct _virDomainEventGraphicsSubject {
      int nidentity;
      struct {
          const char *type;
          const char *name;
      } *identities;
   };
   typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
   typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;

   typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
                                                         virDomainPtr dom,
                                                         int phase,
                                                         virDomainEventGraphicsAddressPtr local,
                                                         virDomainEventGraphicsAddressPtr remote,
                                                         const char *authScheme,
                                                         virDomainEventGraphicsSubjectPtr subject,
                                                         void *opaque);

The wire protocol is similarly complex

   struct remote_domain_event_graphics_address {
     int family;
     remote_nonnull_string node;
     remote_nonnull_string service;
   };

   const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;

   struct remote_domain_event_graphics_identity {
     remote_nonnull_string type;
     remote_nonnull_string name;
   };

   struct remote_domain_event_graphics_msg {
     remote_nonnull_domain dom;
     int phase;
     remote_domain_event_graphics_address local;
     remote_domain_event_graphics_address remote;
     remote_nonnull_string authScheme;
     remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
   };

This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.

* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
  graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
  and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
  src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
  for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
  events to application
* src/remote/remote_protocol.x: Wire protocol definition for
  graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
  src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
  VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-26 13:53:20 +00:00

178 lines
8.0 KiB
C

/*
* domain_event.h: domain event queue processing helpers
*
* Copyright (C) 2008 VirtualIron
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Ben Guthro
*/
#include "internal.h"
#ifndef __DOMAIN_EVENT_H__
# define __DOMAIN_EVENT_H__
# include "domain_conf.h"
typedef struct _virDomainEventCallback virDomainEventCallback;
typedef virDomainEventCallback *virDomainEventCallbackPtr;
struct _virDomainEventCallbackList {
unsigned int nextID;
unsigned int count;
virDomainEventCallbackPtr *callbacks;
};
typedef struct _virDomainEventCallbackList virDomainEventCallbackList;
typedef virDomainEventCallbackList *virDomainEventCallbackListPtr;
void virDomainEventCallbackListFree(virDomainEventCallbackListPtr list);
int virDomainEventCallbackListAdd(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
virConnectDomainEventCallback callback,
void *opaque,
virFreeCallback freecb)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListAddID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
virDomainPtr dom,
int eventID,
virConnectDomainEventGenericCallback cb,
void *opaque,
virFreeCallback freecb)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(5);
int virDomainEventCallbackListRemove(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
virConnectDomainEventCallback callback)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListRemoveID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
int callbackID)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListRemoveConn(virConnectPtr conn,
virDomainEventCallbackListPtr cbList)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListMarkDelete(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
virConnectDomainEventCallback callback)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListMarkDeleteID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
int callbackID)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList);
int virDomainEventCallbackListCount(virDomainEventCallbackListPtr cbList);
int virDomainEventCallbackListCountID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
int eventID)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListEventID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
int callbackID)
ATTRIBUTE_NONNULL(1);
/**
* Dispatching domain events that come in while
* in a call / response rpc
*/
typedef struct _virDomainEvent virDomainEvent;
typedef virDomainEvent *virDomainEventPtr;
struct _virDomainEventQueue {
unsigned int count;
virDomainEventPtr *events;
};
typedef struct _virDomainEventQueue virDomainEventQueue;
typedef virDomainEventQueue *virDomainEventQueuePtr;
virDomainEventQueuePtr virDomainEventQueueNew(void);
virDomainEventPtr virDomainEventNew(int id, const char *name, const unsigned char *uuid, int type, int detail);
virDomainEventPtr virDomainEventNewFromDom(virDomainPtr dom, int type, int detail);
virDomainEventPtr virDomainEventNewFromObj(virDomainObjPtr obj, int type, int detail);
virDomainEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int detail);
virDomainEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom);
virDomainEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj);
virDomainEventPtr virDomainEventRTCChangeNewFromDom(virDomainPtr dom, long long offset);
virDomainEventPtr virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj, long long offset);
virDomainEventPtr virDomainEventWatchdogNewFromDom(virDomainPtr dom, int action);
virDomainEventPtr virDomainEventWatchdogNewFromObj(virDomainObjPtr obj, int action);
virDomainEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action);
virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
const char *srcPath,
const char *devAlias,
int action);
virDomainEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject);
virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject);
int virDomainEventQueuePush(virDomainEventQueuePtr evtQueue,
virDomainEventPtr event);
virDomainEventPtr
virDomainEventQueuePop(virDomainEventQueuePtr evtQueue);
void virDomainEventFree(virDomainEventPtr event);
void virDomainEventQueueFree(virDomainEventQueuePtr queue);
typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn,
virDomainEventPtr event,
virConnectDomainEventGenericCallback cb,
void *cbopaque,
void *opaque);
void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
virDomainEventPtr event,
virConnectDomainEventGenericCallback cb,
void *cbopaque,
void *opaque);
void virDomainEventDispatch(virDomainEventPtr event,
virDomainEventCallbackListPtr cbs,
virDomainEventDispatchFunc dispatch,
void *opaque);
void virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
virDomainEventCallbackListPtr cbs,
virDomainEventDispatchFunc dispatch,
void *opaque);
#endif