mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Introduce a new event emitted when a virtualization failure occurs
This introduces a new domain VIR_DOMAIN_EVENT_ID_CONTROL_ERROR Which uses the existing generic callback typedef void (*virConnectDomainEventGenericCallback)(virConnectPtr conn, virDomainPtr dom, void *opaque); This event is intended to be emitted when there is a failure in some part of the domain virtualization system. Whether the domain continues to run/exist after the failure is an implementation detail specific to the hypervisor. The idea is that with some types of failure, hypervisors may prefer to leave the domain running in a "degraded" mode of operation. For example, if something goes wrong with the QEMU monitor, it is possible to leave the guest OS running quite happily. The mgmt app will simply loose the ability todo various tasks. The mgmt app can then choose how/when to deal with the failure that occured. * daemon/remote.c: Dispatch of new event * examples/domain-events/events-c/event-test.c: Demo catch of event * include/libvirt/libvirt.h.in: Define event ID and callback * src/conf/domain_event.c, src/conf/domain_event.h: Internal event handling * src/remote/remote_driver.c: Receipt of new event from daemon * src/remote/remote_protocol.x: Wire protocol for new event * src/remote_protocol-structs: add new event for checks
This commit is contained in:
parent
bb6cb66fde
commit
a6135ec1e6
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -167,6 +167,8 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
|
||||
virDomainEventGraphicsAddressPtr remote,
|
||||
const char *authScheme,
|
||||
virDomainEventGraphicsSubjectPtr subject);
|
||||
virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom);
|
||||
virDomainEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj);
|
||||
|
||||
|
||||
|
||||
|
@ -375,6 +375,8 @@ virDomainEventCallbackListPurgeMarked;
|
||||
virDomainEventCallbackListRemove;
|
||||
virDomainEventCallbackListRemoveConn;
|
||||
virDomainEventCallbackListRemoveID;
|
||||
virDomainEventControlErrorNewFromDom;
|
||||
virDomainEventControlErrorNewFromObj;
|
||||
virDomainEventDispatch;
|
||||
virDomainEventDispatchDefaultFunc;
|
||||
virDomainEventFree;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user