mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
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
This commit is contained in:
parent
71d793faaf
commit
987e31edc9
@ -251,12 +251,77 @@ static int remoteRelayDomainEventIOError(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
int phase,
|
||||
virDomainEventGraphicsAddressPtr local,
|
||||
virDomainEventGraphicsAddressPtr remote,
|
||||
const char *authScheme,
|
||||
virDomainEventGraphicsSubjectPtr subject,
|
||||
void *opaque)
|
||||
{
|
||||
struct qemud_client *client = opaque;
|
||||
remote_domain_event_graphics_msg data;
|
||||
int i;
|
||||
|
||||
if (!client)
|
||||
return -1;
|
||||
|
||||
REMOTE_DEBUG("Relaying domain graphics event %s %d %d - %d %s %s - %d %s %s - %s", dom->name, dom->id, phase,
|
||||
local->family, local->service, local->node,
|
||||
remote->family, remote->service, remote->node,
|
||||
authScheme);
|
||||
|
||||
REMOTE_DEBUG("Subject %d", subject->nidentity);
|
||||
for (i = 0 ; i < subject->nidentity ; i++) {
|
||||
REMOTE_DEBUG(" %s=%s", subject->identities[i].type, subject->identities[i].name);
|
||||
}
|
||||
|
||||
virMutexLock(&client->lock);
|
||||
|
||||
/* build return data */
|
||||
memset(&data, 0, sizeof data);
|
||||
make_nonnull_domain (&data.dom, dom);
|
||||
data.phase = phase;
|
||||
data.authScheme = (char*)authScheme;
|
||||
|
||||
data.local.family = local->family;
|
||||
data.local.node = (char *)local->node;
|
||||
data.local.service = (char *)local->service;
|
||||
|
||||
data.remote.family = remote->family;
|
||||
data.remote.node = (char*)remote->node;
|
||||
data.remote.service = (char*)remote->service;
|
||||
|
||||
data.subject.subject_len = subject->nidentity;
|
||||
if (VIR_ALLOC_N(data.subject.subject_val, data.subject.subject_len) < 0) {
|
||||
VIR_WARN0("cannot allocate memory for graphics event subject");
|
||||
return -1;
|
||||
}
|
||||
for (i = 0 ; i < data.subject.subject_len ; i++) {
|
||||
data.subject.subject_val[i].type = (char*)subject->identities[i].type;
|
||||
data.subject.subject_val[i].name = (char*)subject->identities[i].name;
|
||||
}
|
||||
|
||||
remoteDispatchDomainEventSend (client,
|
||||
REMOTE_PROC_DOMAIN_EVENT_GRAPHICS,
|
||||
(xdrproc_t)xdr_remote_domain_event_graphics_msg, &data);
|
||||
|
||||
VIR_FREE(data.subject.subject_val);
|
||||
|
||||
virMutexUnlock(&client->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventRTCChange),
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventWatchdog),
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventIOError),
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventGraphics),
|
||||
};
|
||||
|
||||
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
|
||||
|
@ -867,3 +867,8 @@
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* Async event DomainEventGraphics => 171 */
|
||||
.fn = NULL,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
|
@ -217,6 +217,47 @@ static int myDomainEventIOErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int myDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
int phase,
|
||||
virDomainEventGraphicsAddressPtr local,
|
||||
virDomainEventGraphicsAddressPtr remote,
|
||||
const char *authScheme,
|
||||
virDomainEventGraphicsSubjectPtr subject,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
printf("%s EVENT: Domain %s(%d) graphics ", __func__, virDomainGetName(dom),
|
||||
virDomainGetID(dom));
|
||||
|
||||
switch (phase) {
|
||||
case VIR_DOMAIN_EVENT_GRAPHICS_CONNECT:
|
||||
printf("connected ");
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE:
|
||||
printf("initialized ");
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT:
|
||||
printf("disconnected ");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("local: family=%d node=%s service=%s ",
|
||||
local->family, local->node, local->service);
|
||||
printf("remote: family=%d node=%s service=%s ",
|
||||
remote->family, remote->node, remote->service);
|
||||
|
||||
printf("auth: %s ", authScheme);
|
||||
for (i = 0 ; i < subject->nidentity ; i++) {
|
||||
printf(" identity: %s=%s",
|
||||
subject->identities[i].type,
|
||||
subject->identities[i].name);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void myFreeFunc(void *opaque)
|
||||
{
|
||||
char *str = opaque;
|
||||
@ -338,6 +379,7 @@ int main(int argc, char **argv)
|
||||
int callback4ret = -1;
|
||||
int callback5ret = -1;
|
||||
int callback6ret = -1;
|
||||
int callback7ret = -1;
|
||||
|
||||
struct sigaction action_stop = {
|
||||
.sa_handler = stop
|
||||
@ -395,13 +437,19 @@ int main(int argc, char **argv)
|
||||
VIR_DOMAIN_EVENT_ID_IO_ERROR,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventIOErrorCallback),
|
||||
strdup("callback io error"), myFreeFunc);
|
||||
callback7ret = virConnectDomainEventRegisterAny(dconn,
|
||||
NULL,
|
||||
VIR_DOMAIN_EVENT_ID_GRAPHICS,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventGraphicsCallback),
|
||||
strdup("callback graphics"), myFreeFunc);
|
||||
|
||||
if ((callback1ret != -1) &&
|
||||
(callback2ret != -1) &&
|
||||
(callback3ret != -1) &&
|
||||
(callback4ret != -1) &&
|
||||
(callback5ret != -1) &&
|
||||
(callback6ret != -1)) {
|
||||
(callback6ret != -1) &&
|
||||
(callback7ret != -1)) {
|
||||
while(run) {
|
||||
struct pollfd pfd = { .fd = h_fd,
|
||||
.events = h_event,
|
||||
@ -443,6 +491,7 @@ int main(int argc, char **argv)
|
||||
virConnectDomainEventDeregisterAny(dconn, callback4ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback5ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback6ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback7ret);
|
||||
}
|
||||
|
||||
DEBUG0("Closing connection");
|
||||
|
@ -1940,6 +1940,98 @@ typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
|
||||
int action,
|
||||
void *opaque);
|
||||
|
||||
/**
|
||||
* virDomainEventGraphicsPhase:
|
||||
*
|
||||
* The phase of the graphics client connection
|
||||
*/
|
||||
typedef enum {
|
||||
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0, /* Initial socket connection established */
|
||||
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE, /* Authentication & setup completed */
|
||||
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT, /* Final socket disconnection */
|
||||
} virDomainEventGraphicsPhase;
|
||||
|
||||
/**
|
||||
* virDomainEventGraphicsAddressType:
|
||||
*
|
||||
* The type of address for the connection
|
||||
*/
|
||||
typedef enum {
|
||||
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4, /* IPv4 address */
|
||||
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6, /* IPv6 address */
|
||||
} virDomainEventGraphicsAddressType;
|
||||
|
||||
|
||||
/**
|
||||
* virDomainEventGraphicsAddress:
|
||||
*
|
||||
* The data structure containing connection address details
|
||||
*
|
||||
*/
|
||||
struct _virDomainEventGraphicsAddress {
|
||||
int family; /* Address family, virDomainEventGraphicsAddressType */
|
||||
const char *node; /* Address of node (eg IP address) */
|
||||
const char *service; /* Service name/number (eg TCP port) */
|
||||
};
|
||||
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
|
||||
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
|
||||
|
||||
|
||||
/**
|
||||
* virDomainEventGraphicsSubjectIdentity:
|
||||
*
|
||||
* The data structure representing a single identity
|
||||
*
|
||||
* The types of identity differ according to the authentication scheme,
|
||||
* some examples are 'x509dname' and 'saslUsername'.
|
||||
*/
|
||||
struct _virDomainEventGraphicsSubjectIdentity {
|
||||
const char *type; /* Type of identity */
|
||||
const char *name; /* Identity value */
|
||||
};
|
||||
typedef struct _virDomainEventGraphicsSubjectIdentity virDomainEventGraphicsSubjectIdentity;
|
||||
typedef virDomainEventGraphicsSubjectIdentity *virDomainEventGraphicsSubjectIdentityPtr;
|
||||
|
||||
|
||||
/**
|
||||
* virDomainEventGraphicsSubject:
|
||||
*
|
||||
* The data structure representing an authenticated subject
|
||||
*
|
||||
* A subject will have zero or more identities. The types of
|
||||
* identity differ according to the authentication scheme
|
||||
*/
|
||||
struct _virDomainEventGraphicsSubject {
|
||||
int nidentity; /* Number of identities in array*/
|
||||
virDomainEventGraphicsSubjectIdentityPtr identities; /* Array of identities for subject */
|
||||
};
|
||||
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
|
||||
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
|
||||
|
||||
|
||||
/**
|
||||
* virConnectDomainEventGraphicsCallback:
|
||||
* @conn: connection object
|
||||
* @dom: domain on which the event occurred
|
||||
* @phase: the phase of the connection
|
||||
* @local: the local server address
|
||||
* @remote: the remote client address
|
||||
* @authScheme: the authentication scheme activated
|
||||
* @subject: the authenticated subject (user)
|
||||
* @opaque: application specified data
|
||||
*
|
||||
* The callback signature to use when registering for an event of type
|
||||
* VIR_DOMAIN_EVENT_ID_GRAPHICS with virConnectDomainEventRegisterAny()
|
||||
*/
|
||||
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
|
||||
virDomainPtr dom,
|
||||
int phase,
|
||||
virDomainEventGraphicsAddressPtr local,
|
||||
virDomainEventGraphicsAddressPtr remote,
|
||||
const char *authScheme,
|
||||
virDomainEventGraphicsSubjectPtr subject,
|
||||
void *opaque);
|
||||
|
||||
/**
|
||||
* VIR_DOMAIN_EVENT_CALLBACK:
|
||||
*
|
||||
@ -1955,6 +2047,7 @@ typedef enum {
|
||||
VIR_DOMAIN_EVENT_ID_RTC_CHANGE = 2, /* virConnectDomainEventRTCChangeCallback */
|
||||
VIR_DOMAIN_EVENT_ID_WATCHDOG = 3, /* virConnectDomainEventWatchdogCallback */
|
||||
VIR_DOMAIN_EVENT_ID_IO_ERROR = 4, /* virConnectDomainEventIOErrorCallback */
|
||||
VIR_DOMAIN_EVENT_ID_GRAPHICS = 5, /* virConnectDomainEventGraphicsCallback */
|
||||
|
||||
/*
|
||||
* NB: this enum value will increase over time as new events are
|
||||
|
@ -173,6 +173,7 @@ skipped_types = {
|
||||
'virConnectDomainEventRTCChangeCallback': "No function types in python",
|
||||
'virConnectDomainEventWatchdogCallback': "No function types in python",
|
||||
'virConnectDomainEventIOErrorCallback': "No function types in python",
|
||||
'virConnectDomainEventGraphicsCallback': "No function types in python",
|
||||
'virEventAddHandleFunc': "No function types in python",
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,13 @@ struct _virDomainEvent {
|
||||
char *devAlias;
|
||||
int action;
|
||||
} ioError;
|
||||
struct {
|
||||
int phase;
|
||||
virDomainEventGraphicsAddressPtr local;
|
||||
virDomainEventGraphicsAddressPtr remote;
|
||||
char *authScheme;
|
||||
virDomainEventGraphicsSubjectPtr subject;
|
||||
} graphics;
|
||||
} data;
|
||||
};
|
||||
|
||||
@ -463,9 +470,32 @@ void virDomainEventFree(virDomainEventPtr event)
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
if (event->eventID == VIR_DOMAIN_EVENT_ID_IO_ERROR) {
|
||||
switch (event->eventID) {
|
||||
case VIR_DOMAIN_EVENT_ID_IO_ERROR:
|
||||
VIR_FREE(event->data.ioError.srcPath);
|
||||
VIR_FREE(event->data.ioError.devAlias);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
|
||||
if (event->data.graphics.local) {
|
||||
VIR_FREE(event->data.graphics.local->node);
|
||||
VIR_FREE(event->data.graphics.local->service);
|
||||
VIR_FREE(event->data.graphics.local);
|
||||
}
|
||||
if (event->data.graphics.remote) {
|
||||
VIR_FREE(event->data.graphics.remote->node);
|
||||
VIR_FREE(event->data.graphics.remote->service);
|
||||
VIR_FREE(event->data.graphics.remote);
|
||||
}
|
||||
VIR_FREE(event->data.graphics.authScheme);
|
||||
if (event->data.graphics.subject) {
|
||||
int i;
|
||||
for (i = 0 ; i < event->data.graphics.subject->nidentity ; i++) {
|
||||
VIR_FREE(event->data.graphics.subject->identities[i].type);
|
||||
VIR_FREE(event->data.graphics.subject->identities[i].name);
|
||||
}
|
||||
VIR_FREE(event->data.graphics.subject);
|
||||
}
|
||||
}
|
||||
|
||||
VIR_FREE(event->dom.name);
|
||||
@ -641,6 +671,58 @@ virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
|
||||
return ev;
|
||||
}
|
||||
|
||||
|
||||
virDomainEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
|
||||
int phase,
|
||||
virDomainEventGraphicsAddressPtr local,
|
||||
virDomainEventGraphicsAddressPtr remote,
|
||||
const char *authScheme,
|
||||
virDomainEventGraphicsSubjectPtr subject)
|
||||
{
|
||||
virDomainEventPtr ev =
|
||||
virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_GRAPHICS,
|
||||
dom->id, dom->name, dom->uuid);
|
||||
|
||||
if (ev) {
|
||||
ev->data.graphics.phase = phase;
|
||||
if (!(ev->data.graphics.authScheme = strdup(authScheme))) {
|
||||
virDomainEventFree(ev);
|
||||
ev = NULL;
|
||||
}
|
||||
ev->data.graphics.local = local;
|
||||
ev->data.graphics.remote = remote;
|
||||
ev->data.graphics.subject = subject;
|
||||
}
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
|
||||
int phase,
|
||||
virDomainEventGraphicsAddressPtr local,
|
||||
virDomainEventGraphicsAddressPtr remote,
|
||||
const char *authScheme,
|
||||
virDomainEventGraphicsSubjectPtr subject)
|
||||
{
|
||||
virDomainEventPtr ev =
|
||||
virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_GRAPHICS,
|
||||
obj->def->id, obj->def->name, obj->def->uuid);
|
||||
|
||||
if (ev) {
|
||||
ev->data.graphics.phase = phase;
|
||||
if (!(ev->data.graphics.authScheme = strdup(authScheme))) {
|
||||
virDomainEventFree(ev);
|
||||
ev = NULL;
|
||||
}
|
||||
ev->data.graphics.local = local;
|
||||
ev->data.graphics.remote = remote;
|
||||
ev->data.graphics.subject = subject;
|
||||
}
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virDomainEventQueueFree:
|
||||
* @queue: pointer to the queue
|
||||
@ -771,6 +853,16 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
|
||||
cbopaque);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
|
||||
((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
|
||||
event->data.graphics.phase,
|
||||
event->data.graphics.local,
|
||||
event->data.graphics.remote,
|
||||
event->data.graphics.authScheme,
|
||||
event->data.graphics.subject,
|
||||
cbopaque);
|
||||
break;
|
||||
|
||||
default:
|
||||
VIR_WARN("Unexpected event ID %d", event->eventID);
|
||||
break;
|
||||
|
@ -130,6 +130,21 @@ virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
|
||||
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);
|
||||
|
||||
|
@ -222,6 +222,8 @@ virDomainEventWatchdogNewFromDom;
|
||||
virDomainEventWatchdogNewFromObj;
|
||||
virDomainEventIOErrorNewFromDom;
|
||||
virDomainEventIOErrorNewFromObj;
|
||||
virDomainEventGraphicsNewFromDom;
|
||||
virDomainEventGraphicsNewFromObj;
|
||||
virDomainEventFree;
|
||||
virDomainEventDispatchDefaultFunc;
|
||||
virDomainEventDispatch;
|
||||
|
@ -993,6 +993,98 @@ qemuHandleDomainIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuHandleDomainGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr vm,
|
||||
int phase,
|
||||
int localFamily,
|
||||
const char *localNode,
|
||||
const char *localService,
|
||||
int remoteFamily,
|
||||
const char *remoteNode,
|
||||
const char *remoteService,
|
||||
const char *authScheme,
|
||||
const char *x509dname,
|
||||
const char *saslUsername)
|
||||
{
|
||||
struct qemud_driver *driver = qemu_driver;
|
||||
virDomainEventPtr event;
|
||||
virDomainEventGraphicsAddressPtr localAddr = NULL;
|
||||
virDomainEventGraphicsAddressPtr remoteAddr = NULL;
|
||||
virDomainEventGraphicsSubjectPtr subject = NULL;
|
||||
int i;
|
||||
|
||||
virDomainObjLock(vm);
|
||||
|
||||
if (VIR_ALLOC(localAddr) < 0)
|
||||
goto no_memory;
|
||||
localAddr->family = localFamily;
|
||||
if (!(localAddr->service = strdup(localService)) ||
|
||||
!(localAddr->node = strdup(localNode)))
|
||||
goto no_memory;
|
||||
|
||||
if (VIR_ALLOC(remoteAddr) < 0)
|
||||
goto no_memory;
|
||||
remoteAddr->family = remoteFamily;
|
||||
if (!(remoteAddr->service = strdup(remoteService)) ||
|
||||
!(remoteAddr->node = strdup(remoteNode)))
|
||||
goto no_memory;
|
||||
|
||||
if (VIR_ALLOC(subject) < 0)
|
||||
goto no_memory;
|
||||
if (x509dname) {
|
||||
if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
|
||||
goto no_memory;
|
||||
if (!(subject->identities[subject->nidentity].type = strdup("x509dname")) ||
|
||||
!(subject->identities[subject->nidentity].name = strdup(x509dname)))
|
||||
goto no_memory;
|
||||
subject->nidentity++;
|
||||
}
|
||||
if (saslUsername) {
|
||||
if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
|
||||
goto no_memory;
|
||||
if (!(subject->identities[subject->nidentity].type = strdup("saslUsername")) ||
|
||||
!(subject->identities[subject->nidentity].name = strdup(saslUsername)))
|
||||
goto no_memory;
|
||||
subject->nidentity++;
|
||||
}
|
||||
|
||||
event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr, authScheme, subject);
|
||||
virDomainObjUnlock(vm);
|
||||
|
||||
if (event) {
|
||||
qemuDriverLock(driver);
|
||||
qemuDomainEventQueue(driver, event);
|
||||
qemuDriverUnlock(driver);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
no_memory:
|
||||
virReportOOMError();
|
||||
if (localAddr) {
|
||||
VIR_FREE(localAddr->service);
|
||||
VIR_FREE(localAddr->node);
|
||||
VIR_FREE(localAddr);
|
||||
}
|
||||
if (remoteAddr) {
|
||||
VIR_FREE(remoteAddr->service);
|
||||
VIR_FREE(remoteAddr->node);
|
||||
VIR_FREE(remoteAddr);
|
||||
}
|
||||
if (subject) {
|
||||
for (i = 0 ; i < subject->nidentity ; i++) {
|
||||
VIR_FREE(subject->identities[i].type);
|
||||
VIR_FREE(subject->identities[i].name);
|
||||
}
|
||||
VIR_FREE(subject->identities);
|
||||
VIR_FREE(subject);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static qemuMonitorCallbacks monitorCallbacks = {
|
||||
.eofNotify = qemuHandleMonitorEOF,
|
||||
.diskSecretLookup = findVolumeQcowPassphrase,
|
||||
@ -1000,6 +1092,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
|
||||
.domainRTCChange = qemuHandleDomainRTCChange,
|
||||
.domainWatchdog = qemuHandleDomainWatchdog,
|
||||
.domainIOError = qemuHandleDomainIOError,
|
||||
.domainGraphics = qemuHandleDomainGraphics,
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -838,6 +838,36 @@ int qemuMonitorEmitIOError(qemuMonitorPtr mon,
|
||||
}
|
||||
|
||||
|
||||
int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
|
||||
int phase,
|
||||
int localFamily,
|
||||
const char *localNode,
|
||||
const char *localService,
|
||||
int remoteFamily,
|
||||
const char *remoteNode,
|
||||
const char *remoteService,
|
||||
const char *authScheme,
|
||||
const char *x509dname,
|
||||
const char *saslUsername)
|
||||
{
|
||||
int ret = -1;
|
||||
VIR_DEBUG("mon=%p", mon);
|
||||
|
||||
qemuMonitorRef(mon);
|
||||
qemuMonitorUnlock(mon);
|
||||
if (mon->cb && mon->cb->domainGraphics)
|
||||
ret = mon->cb->domainGraphics(mon, mon->vm,
|
||||
phase,
|
||||
localFamily, localNode, localService,
|
||||
remoteFamily, remoteNode, remoteService,
|
||||
authScheme, x509dname, saslUsername);
|
||||
qemuMonitorLock(mon);
|
||||
qemuMonitorUnref(mon);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int qemuMonitorSetCapabilities(qemuMonitorPtr mon)
|
||||
{
|
||||
int ret;
|
||||
|
@ -96,6 +96,18 @@ struct _qemuMonitorCallbacks {
|
||||
virDomainObjPtr vm,
|
||||
const char *diskAlias,
|
||||
int action);
|
||||
int (*domainGraphics)(qemuMonitorPtr mon,
|
||||
virDomainObjPtr vm,
|
||||
int phase,
|
||||
int localFamily,
|
||||
const char *localNode,
|
||||
const char *localService,
|
||||
int remoteFamily,
|
||||
const char *remoteNode,
|
||||
const char *remoteService,
|
||||
const char *authScheme,
|
||||
const char *x509dname,
|
||||
const char *saslUsername);
|
||||
};
|
||||
|
||||
|
||||
@ -137,6 +149,18 @@ int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action);
|
||||
int qemuMonitorEmitIOError(qemuMonitorPtr mon,
|
||||
const char *diskAlias,
|
||||
int action);
|
||||
int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
|
||||
int phase,
|
||||
int localFamily,
|
||||
const char *localNode,
|
||||
const char *localService,
|
||||
int remoteFamily,
|
||||
const char *remoteNode,
|
||||
const char *remoteService,
|
||||
const char *authScheme,
|
||||
const char *x509dname,
|
||||
const char *saslUsername);
|
||||
|
||||
|
||||
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
|
||||
virConnectPtr conn);
|
||||
|
@ -52,6 +52,9 @@ static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
|
||||
struct {
|
||||
const char *type;
|
||||
@ -64,6 +67,9 @@ struct {
|
||||
{ "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
|
||||
{ "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
|
||||
{ "DISK_IO_ERROR", qemuMonitorJSONHandleIOError, },
|
||||
{ "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
|
||||
{ "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
|
||||
{ "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
|
||||
};
|
||||
|
||||
|
||||
@ -566,6 +572,74 @@ static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr dat
|
||||
}
|
||||
|
||||
|
||||
VIR_ENUM_DECL(qemuMonitorGraphicsAddressFamily)
|
||||
VIR_ENUM_IMPL(qemuMonitorGraphicsAddressFamily, VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6 + 1,
|
||||
"ipv4", "ipv6");
|
||||
|
||||
static void qemuMonitorJSONHandleVNC(qemuMonitorPtr mon, virJSONValuePtr data, int phase)
|
||||
{
|
||||
const char *localNode, *localService, *localFamily;
|
||||
const char *remoteNode, *remoteService, *remoteFamily;
|
||||
const char *authScheme, *saslUsername, *x509dname;
|
||||
int localFamilyID, remoteFamilyID;
|
||||
virJSONValuePtr client;
|
||||
virJSONValuePtr server;
|
||||
|
||||
if (!(client = virJSONValueObjectGet(data, "client"))) {
|
||||
VIR_WARN0("missing client info in VNC event");
|
||||
return;
|
||||
}
|
||||
if (!(server = virJSONValueObjectGet(data, "server"))) {
|
||||
VIR_WARN0("missing server info in VNC event");
|
||||
return;
|
||||
}
|
||||
|
||||
authScheme = virJSONValueObjectGetString(server, "auth");
|
||||
|
||||
localFamily = virJSONValueObjectGetString(server, "family");
|
||||
localNode = virJSONValueObjectGetString(server, "host");
|
||||
localService = virJSONValueObjectGetString(server, "service");
|
||||
|
||||
remoteFamily = virJSONValueObjectGetString(client, "family");
|
||||
remoteNode = virJSONValueObjectGetString(client, "host");
|
||||
remoteService = virJSONValueObjectGetString(client, "service");
|
||||
|
||||
saslUsername = virJSONValueObjectGetString(client, "sasl_username");
|
||||
x509dname = virJSONValueObjectGetString(client, "x509_dname");
|
||||
|
||||
if ((localFamilyID = qemuMonitorGraphicsAddressFamilyTypeFromString(localFamily)) < 0) {
|
||||
VIR_WARN("unknown address family '%s'", localFamily);
|
||||
localFamilyID = VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4;
|
||||
}
|
||||
if ((remoteFamilyID = qemuMonitorGraphicsAddressFamilyTypeFromString(remoteFamily)) < 0) {
|
||||
VIR_WARN("unknown address family '%s'", remoteFamily);
|
||||
remoteFamilyID = VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4;
|
||||
}
|
||||
|
||||
qemuMonitorEmitGraphics(mon, phase,
|
||||
localFamilyID, localNode, localService,
|
||||
remoteFamilyID, remoteNode, remoteService,
|
||||
authScheme, x509dname, saslUsername);
|
||||
}
|
||||
|
||||
static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data)
|
||||
{
|
||||
qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT);
|
||||
}
|
||||
|
||||
|
||||
static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data)
|
||||
{
|
||||
qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE);
|
||||
}
|
||||
|
||||
|
||||
static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data)
|
||||
{
|
||||
qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon)
|
||||
{
|
||||
|
@ -7024,6 +7024,94 @@ remoteDomainReadEventIOError(virConnectPtr conn, XDR *xdr)
|
||||
}
|
||||
|
||||
|
||||
static virDomainEventPtr
|
||||
remoteDomainReadEventGraphics(virConnectPtr conn, XDR *xdr)
|
||||
{
|
||||
remote_domain_event_graphics_msg msg;
|
||||
virDomainPtr dom;
|
||||
virDomainEventPtr event = NULL;
|
||||
virDomainEventGraphicsAddressPtr localAddr = NULL;
|
||||
virDomainEventGraphicsAddressPtr remoteAddr = NULL;
|
||||
virDomainEventGraphicsSubjectPtr subject = NULL;
|
||||
int i;
|
||||
|
||||
memset (&msg, 0, sizeof msg);
|
||||
|
||||
/* unmarshall parameters, and process it*/
|
||||
if (! xdr_remote_domain_event_graphics_msg(xdr, &msg) ) {
|
||||
error (conn, VIR_ERR_RPC,
|
||||
_("unable to demarshall reboot event"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dom = get_nonnull_domain(conn,msg.dom);
|
||||
if (!dom)
|
||||
return NULL;
|
||||
|
||||
if (VIR_ALLOC(localAddr) < 0)
|
||||
goto no_memory;
|
||||
localAddr->family = msg.local.family;
|
||||
if (!(localAddr->service = strdup(msg.local.service)) ||
|
||||
!(localAddr->node = strdup(msg.local.node)))
|
||||
goto no_memory;
|
||||
|
||||
if (VIR_ALLOC(remoteAddr) < 0)
|
||||
goto no_memory;
|
||||
remoteAddr->family = msg.remote.family;
|
||||
if (!(remoteAddr->service = strdup(msg.remote.service)) ||
|
||||
!(remoteAddr->node = strdup(msg.remote.node)))
|
||||
goto no_memory;
|
||||
|
||||
fprintf(stderr, "Got %d\n", msg.subject.subject_len);
|
||||
if (VIR_ALLOC(subject) < 0)
|
||||
goto no_memory;
|
||||
if (VIR_ALLOC_N(subject->identities, msg.subject.subject_len) < 0)
|
||||
goto no_memory;
|
||||
subject->nidentity = msg.subject.subject_len;
|
||||
for (i = 0 ; i < subject->nidentity ; i++) {
|
||||
fprintf(stderr, " %s=%s\n", msg.subject.subject_val[i].type,
|
||||
msg.subject.subject_val[i].name);
|
||||
if (!(subject->identities[i].type = strdup(msg.subject.subject_val[i].type)) ||
|
||||
!(subject->identities[i].name = strdup(msg.subject.subject_val[i].name)))
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
event = virDomainEventGraphicsNewFromDom(dom,
|
||||
msg.phase,
|
||||
localAddr,
|
||||
remoteAddr,
|
||||
msg.authScheme,
|
||||
subject);
|
||||
xdr_free ((xdrproc_t) &xdr_remote_domain_event_graphics_msg, (char *) &msg);
|
||||
|
||||
virDomainFree(dom);
|
||||
return event;
|
||||
|
||||
no_memory:
|
||||
xdr_free ((xdrproc_t) &xdr_remote_domain_event_graphics_msg, (char *) &msg);
|
||||
|
||||
if (localAddr) {
|
||||
VIR_FREE(localAddr->service);
|
||||
VIR_FREE(localAddr->node);
|
||||
VIR_FREE(localAddr);
|
||||
}
|
||||
if (remoteAddr) {
|
||||
VIR_FREE(remoteAddr->service);
|
||||
VIR_FREE(remoteAddr->node);
|
||||
VIR_FREE(remoteAddr);
|
||||
}
|
||||
if (subject) {
|
||||
for (i = 0 ; i < subject->nidentity ; i++) {
|
||||
VIR_FREE(subject->identities[i].type);
|
||||
VIR_FREE(subject->identities[i].name);
|
||||
}
|
||||
VIR_FREE(subject->identities);
|
||||
VIR_FREE(subject);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
|
||||
remoteSecretOpen (virConnectPtr conn,
|
||||
virConnectAuthPtr auth,
|
||||
@ -8583,6 +8671,10 @@ processCallDispatchMessage(virConnectPtr conn, struct private_data *priv,
|
||||
event = remoteDomainReadEventIOError(conn, xdr);
|
||||
break;
|
||||
|
||||
case REMOTE_PROC_DOMAIN_EVENT_GRAPHICS:
|
||||
event = remoteDomainReadEventGraphics(conn, xdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG("Unexpected event proc %d", hdr->proc);
|
||||
break;
|
||||
|
@ -3096,6 +3096,51 @@ xdr_remote_domain_event_io_error_msg (XDR *xdrs, remote_domain_event_io_error_ms
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_domain_event_graphics_address (XDR *xdrs, remote_domain_event_graphics_address *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->family))
|
||||
return FALSE;
|
||||
if (!xdr_remote_nonnull_string (xdrs, &objp->node))
|
||||
return FALSE;
|
||||
if (!xdr_remote_nonnull_string (xdrs, &objp->service))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_domain_event_graphics_identity (XDR *xdrs, remote_domain_event_graphics_identity *objp)
|
||||
{
|
||||
|
||||
if (!xdr_remote_nonnull_string (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_remote_nonnull_string (xdrs, &objp->name))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_domain_event_graphics_msg (XDR *xdrs, remote_domain_event_graphics_msg *objp)
|
||||
{
|
||||
char **objp_cpp0 = (char **) (void *) &objp->subject.subject_val;
|
||||
|
||||
if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->phase))
|
||||
return FALSE;
|
||||
if (!xdr_remote_domain_event_graphics_address (xdrs, &objp->local))
|
||||
return FALSE;
|
||||
if (!xdr_remote_domain_event_graphics_address (xdrs, &objp->remote))
|
||||
return FALSE;
|
||||
if (!xdr_remote_nonnull_string (xdrs, &objp->authScheme))
|
||||
return FALSE;
|
||||
if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->subject.subject_len, REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX,
|
||||
sizeof (remote_domain_event_graphics_identity), (xdrproc_t) xdr_remote_domain_event_graphics_identity))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_procedure (XDR *xdrs, remote_procedure *objp)
|
||||
{
|
||||
|
@ -1752,6 +1752,33 @@ struct remote_domain_event_io_error_msg {
|
||||
int action;
|
||||
};
|
||||
typedef struct remote_domain_event_io_error_msg remote_domain_event_io_error_msg;
|
||||
|
||||
struct remote_domain_event_graphics_address {
|
||||
int family;
|
||||
remote_nonnull_string node;
|
||||
remote_nonnull_string service;
|
||||
};
|
||||
typedef struct remote_domain_event_graphics_address remote_domain_event_graphics_address;
|
||||
#define REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX 20
|
||||
|
||||
struct remote_domain_event_graphics_identity {
|
||||
remote_nonnull_string type;
|
||||
remote_nonnull_string name;
|
||||
};
|
||||
typedef struct remote_domain_event_graphics_identity remote_domain_event_graphics_identity;
|
||||
|
||||
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;
|
||||
struct {
|
||||
u_int subject_len;
|
||||
remote_domain_event_graphics_identity *subject_val;
|
||||
} subject;
|
||||
};
|
||||
typedef struct remote_domain_event_graphics_msg remote_domain_event_graphics_msg;
|
||||
#define REMOTE_PROGRAM 0x20008086
|
||||
#define REMOTE_PROTOCOL_VERSION 1
|
||||
|
||||
@ -1928,6 +1955,7 @@ enum remote_procedure {
|
||||
REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE = 170,
|
||||
REMOTE_PROC_DOMAIN_EVENT_WATCHDOG = 171,
|
||||
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR = 172,
|
||||
REMOTE_PROC_DOMAIN_EVENT_GRAPHICS = 173,
|
||||
};
|
||||
typedef enum remote_procedure remote_procedure;
|
||||
|
||||
@ -2245,6 +2273,9 @@ extern bool_t xdr_remote_domain_event_reboot_msg (XDR *, remote_domain_event_re
|
||||
extern bool_t xdr_remote_domain_event_rtc_change_msg (XDR *, remote_domain_event_rtc_change_msg*);
|
||||
extern bool_t xdr_remote_domain_event_watchdog_msg (XDR *, remote_domain_event_watchdog_msg*);
|
||||
extern bool_t xdr_remote_domain_event_io_error_msg (XDR *, remote_domain_event_io_error_msg*);
|
||||
extern bool_t xdr_remote_domain_event_graphics_address (XDR *, remote_domain_event_graphics_address*);
|
||||
extern bool_t xdr_remote_domain_event_graphics_identity (XDR *, remote_domain_event_graphics_identity*);
|
||||
extern bool_t xdr_remote_domain_event_graphics_msg (XDR *, remote_domain_event_graphics_msg*);
|
||||
extern bool_t xdr_remote_procedure (XDR *, remote_procedure*);
|
||||
extern bool_t xdr_remote_message_type (XDR *, remote_message_type*);
|
||||
extern bool_t xdr_remote_message_status (XDR *, remote_message_status*);
|
||||
@ -2536,6 +2567,9 @@ extern bool_t xdr_remote_domain_event_reboot_msg ();
|
||||
extern bool_t xdr_remote_domain_event_rtc_change_msg ();
|
||||
extern bool_t xdr_remote_domain_event_watchdog_msg ();
|
||||
extern bool_t xdr_remote_domain_event_io_error_msg ();
|
||||
extern bool_t xdr_remote_domain_event_graphics_address ();
|
||||
extern bool_t xdr_remote_domain_event_graphics_identity ();
|
||||
extern bool_t xdr_remote_domain_event_graphics_msg ();
|
||||
extern bool_t xdr_remote_procedure ();
|
||||
extern bool_t xdr_remote_message_type ();
|
||||
extern bool_t xdr_remote_message_status ();
|
||||
|
@ -1557,6 +1557,28 @@ struct remote_domain_event_io_error_msg {
|
||||
int action;
|
||||
};
|
||||
|
||||
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>;
|
||||
};
|
||||
|
||||
/*----- Protocol. -----*/
|
||||
|
||||
/* Define the program number, protocol version and procedure numbers here. */
|
||||
@ -1752,7 +1774,8 @@ enum remote_procedure {
|
||||
REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE = 170,
|
||||
|
||||
REMOTE_PROC_DOMAIN_EVENT_WATCHDOG = 171,
|
||||
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR = 172
|
||||
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR = 172,
|
||||
REMOTE_PROC_DOMAIN_EVENT_GRAPHICS = 173
|
||||
|
||||
/*
|
||||
* Notice how the entries are grouped in sets of 10 ?
|
||||
|
Loading…
Reference in New Issue
Block a user