aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--daemon/remote.c29
-rw-r--r--examples/domain-events/events-c/event-test.c19
-rw-r--r--include/libvirt/libvirt.h.in1
-rw-r--r--python/libvirt-override.c3
-rw-r--r--src/conf/domain_event.c23
-rw-r--r--src/conf/domain_event.h2
-rw-r--r--src/libvirt_private.syms2
-rw-r--r--src/remote/remote_driver.c31
-rw-r--r--src/remote/remote_protocol.x8
-rw-r--r--src/remote_protocol-structs3
10 files changed, 120 insertions, 1 deletions
diff --git a/daemon/remote.c b/daemon/remote.c
index bc9fd3b41..3f1324791 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -379,6 +379,34 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
}
+static int remoteRelayDomainEventControlError(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ void *opaque)
+{
+ struct qemud_client *client = opaque;
+ remote_domain_event_control_error_msg data;
+
+ if (!client)
+ return -1;
+
+ VIR_DEBUG("Relaying domain control error %s %d", dom->name, dom->id);
+
+ virMutexLock(&client->lock);
+
+ /* build return data */
+ memset(&data, 0, sizeof data);
+ make_nonnull_domain(&data.dom, dom);
+
+ remoteDispatchDomainEventSend(client,
+ REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR,
+ (xdrproc_t)xdr_remote_domain_event_control_error_msg, &data);
+
+ virMutexUnlock(&client->lock);
+
+ return 0;
+}
+
+
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@@ -387,6 +415,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventIOError),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventGraphics),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventIOErrorReason),
+ VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index 2da58b8f0..4766a0df3 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -245,6 +245,17 @@ static int myDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
return 0;
}
+static int myDomainEventControlErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) control error\n", __func__, virDomainGetName(dom),
+ virDomainGetID(dom));
+
+ return 0;
+}
+
+
static void myFreeFunc(void *opaque)
{
char *str = opaque;
@@ -278,6 +289,7 @@ int main(int argc, char **argv)
int callback5ret = -1;
int callback6ret = -1;
int callback7ret = -1;
+ int callback8ret = -1;
struct sigaction action_stop;
memset(&action_stop, 0, sizeof action_stop);
@@ -336,6 +348,11 @@ int main(int argc, char **argv)
VIR_DOMAIN_EVENT_ID_GRAPHICS,
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventGraphicsCallback),
strdup("callback graphics"), myFreeFunc);
+ callback8ret = virConnectDomainEventRegisterAny(dconn,
+ NULL,
+ VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
+ VIR_DOMAIN_EVENT_CALLBACK(myDomainEventControlErrorCallback),
+ strdup("callback control error"), myFreeFunc);
if ((callback1ret != -1) &&
(callback2ret != -1) &&
@@ -360,6 +377,8 @@ int main(int argc, char **argv)
virConnectDomainEventDeregisterAny(dconn, callback5ret);
virConnectDomainEventDeregisterAny(dconn, callback6ret);
virConnectDomainEventDeregisterAny(dconn, callback7ret);
+ if (callback8ret != -1)
+ virConnectDomainEventDeregisterAny(dconn, callback8ret);
}
VIR_DEBUG("Closing connection");
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index d304e72b5..cbd8dbb62 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2443,6 +2443,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_IO_ERROR = 4, /* virConnectDomainEventIOErrorCallback */
VIR_DOMAIN_EVENT_ID_GRAPHICS = 5, /* virConnectDomainEventGraphicsCallback */
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON = 6, /* virConnectDomainEventIOErrorReasonCallback */
+ VIR_DOMAIN_EVENT_ID_CONTROL_ERROR = 7, /* virConnectDomainEventGenericCallback */
/*
* NB: this enum value will increase over time as new events are
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 8676aba4e..763df0028 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -3480,6 +3480,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGraphicsCallback);
break;
+ case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
+ cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGenericCallback);
+ break;
}
if (!cb) {
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index b85765ebb..34a9d9118 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -875,6 +875,24 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
}
+virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom)
+{
+ virDomainEventPtr ev =
+ virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
+ dom->id, dom->name, dom->uuid);
+ return ev;
+}
+
+
+virDomainEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj)
+{
+ virDomainEventPtr ev =
+ virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
+ obj->def->id, obj->def->name, obj->def->uuid);
+ return ev;
+}
+
+
/**
* virDomainEventQueuePop:
* @evtQueue: the queue of events
@@ -1004,6 +1022,11 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
cbopaque);
break;
+ case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
+ (cb)(conn, dom,
+ cbopaque);
+ break;
+
default:
VIR_WARN("Unexpected event ID %d", event->eventID);
break;
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index efc05f935..68dc8a8d3 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -167,6 +167,8 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject);
+virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom);
+virDomainEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4bf8277d9..321df2a02 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -375,6 +375,8 @@ virDomainEventCallbackListPurgeMarked;
virDomainEventCallbackListRemove;
virDomainEventCallbackListRemoveConn;
virDomainEventCallbackListRemoveID;
+virDomainEventControlErrorNewFromDom;
+virDomainEventControlErrorNewFromObj;
virDomainEventDispatch;
virDomainEventDispatchDefaultFunc;
virDomainEventFree;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 870b3905c..d6bf7c3c5 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -3962,6 +3962,33 @@ no_memory:
}
+static virDomainEventPtr
+remoteDomainReadEventControlError(virConnectPtr conn, XDR *xdr)
+{
+ remote_domain_event_control_error_msg msg;
+ virDomainPtr dom;
+ virDomainEventPtr event = NULL;
+ memset (&msg, 0, sizeof msg);
+
+ /* unmarshall parameters, and process it*/
+ if (! xdr_remote_domain_event_control_error_msg(xdr, &msg) ) {
+ remoteError(VIR_ERR_RPC, "%s",
+ _("unable to demarshall reboot event"));
+ return NULL;
+ }
+
+ dom = get_nonnull_domain(conn,msg.dom);
+ if (!dom)
+ return NULL;
+
+ event = virDomainEventControlErrorNewFromDom(dom);
+ xdr_free ((xdrproc_t) &xdr_remote_domain_event_control_error_msg, (char *) &msg);
+
+ virDomainFree(dom);
+ return event;
+}
+
+
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags)
{
@@ -5569,6 +5596,10 @@ processCallDispatchMessage(virConnectPtr conn, struct private_data *priv,
event = remoteDomainReadEventGraphics(conn, xdr);
break;
+ case REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR:
+ event = remoteDomainReadEventControlError(conn, xdr);
+ break;
+
default:
VIR_DEBUG("Unexpected event proc %d", hdr->proc);
break;
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 89a8cd2e1..0602c2766 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2031,6 +2031,10 @@ struct remote_domain_migrate_confirm3_args {
int cancelled;
};
+struct remote_domain_event_control_error_msg {
+ remote_nonnull_domain dom;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -2292,7 +2296,9 @@ enum remote_procedure {
REMOTE_PROC_INTERFACE_CHANGE_COMMIT = 221, /* autogen autogen */
REMOTE_PROC_INTERFACE_CHANGE_ROLLBACK = 222, /* autogen autogen */
- REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS_FLAGS = 223 /* skipgen skipgen */
+ REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS_FLAGS = 223, /* skipgen skipgen */
+ REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR = 224 /* skipgen skipgen */
+
/*
* Notice how the entries are grouped in sets of 10 ?
* Nice isn't it. Please keep it this way when adding more.
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index b428bb207..1d90dd599 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1539,6 +1539,9 @@ struct remote_domain_migrate_confirm3_args {
uint64_t flags;
int cancelled;
};
+struct remote_domain_event_control_error_msg {
+ remote_nonnull_domain dom;
+};
struct remote_message_header {
u_int prog;
u_int vers;