提交 1a460910 编写于 作者: P Peter Krempa

event: Add guest agent lifecycle event

As qemu is now able to notify us about change of the channel state used
for communication with the guest agent we now can more precisely track
the state of the guest agent.

To allow notifying management apps this patch implements a new event
that will be triggered on changes of the guest agent state.
上级 1fd83607
...@@ -1008,6 +1008,41 @@ remoteRelayDomainEventTunable(virConnectPtr conn, ...@@ -1008,6 +1008,41 @@ remoteRelayDomainEventTunable(virConnectPtr conn,
} }
static int
remoteRelayDomainEventAgentLifecycle(virConnectPtr conn,
virDomainPtr dom,
int state,
int reason,
void *opaque)
{
daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_callback_agent_lifecycle_msg data;
if (callback->callbackID < 0 ||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain agent lifecycle event %s %d, callback %d, "
" state %d, reason %d",
dom->name, dom->id, callback->callbackID, state, reason);
/* build return data */
memset(&data, 0, sizeof(data));
data.callbackID = callback->callbackID;
make_nonnull_domain(&data.dom, dom);
data.state = state;
data.reason = reason;
remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE,
(xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg,
&data);
return 0;
}
static virConnectDomainEventGenericCallback domainEventCallbacks[] = { static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
...@@ -1027,6 +1062,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { ...@@ -1027,6 +1062,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemoved), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemoved),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob2), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob2),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventAgentLifecycle),
}; };
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST); verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
......
...@@ -3332,6 +3332,46 @@ typedef void (*virConnectDomainEventTunableCallback)(virConnectPtr conn, ...@@ -3332,6 +3332,46 @@ typedef void (*virConnectDomainEventTunableCallback)(virConnectPtr conn,
void *opaque); void *opaque);
typedef enum {
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED = 1, /* agent connected */
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED = 2, /* agent disconnected */
# ifdef VIR_ENUM_SENTINELS
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_LAST
# endif
} virConnectDomainEventAgentLifecycleState;
typedef enum {
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN = 0, /* unknown state change reason */
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED = 1, /* state changed due to domain start */
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL = 2, /* channel state changed */
# ifdef VIR_ENUM_SENTINELS
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_LAST
# endif
} virConnectDomainEventAgentLifecycleReason;
/**
* virConnectDomainEventAgentLifecycleCallback:
* @conn: connection object
* @dom: domain on which the event occurred
* @state: new state of the guest agent, one of virConnectDomainEventAgentLifecycleState
* @reason: reason for state change; one of virConnectDomainEventAgentLifecycleReason
* @opaque: application specified data
*
* This callback occurs when libvirt detects a change in the state of a guest
* agent.
*
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE with virConnectDomainEventRegisterAny()
*/
typedef void (*virConnectDomainEventAgentLifecycleCallback)(virConnectPtr conn,
virDomainPtr dom,
int state,
int reason,
void *opaque);
/** /**
* VIR_DOMAIN_EVENT_CALLBACK: * VIR_DOMAIN_EVENT_CALLBACK:
* *
...@@ -3367,6 +3407,7 @@ typedef enum { ...@@ -3367,6 +3407,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED = 15, /* virConnectDomainEventDeviceRemovedCallback */ VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED = 15, /* virConnectDomainEventDeviceRemovedCallback */
VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 = 16, /* virConnectDomainEventBlockJobCallback */ VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 = 16, /* virConnectDomainEventBlockJobCallback */
VIR_DOMAIN_EVENT_ID_TUNABLE = 17, /* virConnectDomainEventTunableCallback */ VIR_DOMAIN_EVENT_ID_TUNABLE = 17, /* virConnectDomainEventTunableCallback */
VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE = 18,/* virConnectDomainEventAgentLifecycleCallback */
# ifdef VIR_ENUM_SENTINELS # ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST VIR_DOMAIN_EVENT_ID_LAST
......
...@@ -54,6 +54,7 @@ static virClassPtr virDomainEventDeviceRemovedClass; ...@@ -54,6 +54,7 @@ static virClassPtr virDomainEventDeviceRemovedClass;
static virClassPtr virDomainEventPMClass; static virClassPtr virDomainEventPMClass;
static virClassPtr virDomainQemuMonitorEventClass; static virClassPtr virDomainQemuMonitorEventClass;
static virClassPtr virDomainEventTunableClass; static virClassPtr virDomainEventTunableClass;
static virClassPtr virDomainEventAgentLifecycleClass;
static void virDomainEventDispose(void *obj); static void virDomainEventDispose(void *obj);
...@@ -70,6 +71,7 @@ static void virDomainEventDeviceRemovedDispose(void *obj); ...@@ -70,6 +71,7 @@ static void virDomainEventDeviceRemovedDispose(void *obj);
static void virDomainEventPMDispose(void *obj); static void virDomainEventPMDispose(void *obj);
static void virDomainQemuMonitorEventDispose(void *obj); static void virDomainQemuMonitorEventDispose(void *obj);
static void virDomainEventTunableDispose(void *obj); static void virDomainEventTunableDispose(void *obj);
static void virDomainEventAgentLifecycleDispose(void *obj);
static void static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn, virDomainEventDispatchDefaultFunc(virConnectPtr conn,
...@@ -215,6 +217,15 @@ struct _virDomainEventTunable { ...@@ -215,6 +217,15 @@ struct _virDomainEventTunable {
typedef struct _virDomainEventTunable virDomainEventTunable; typedef struct _virDomainEventTunable virDomainEventTunable;
typedef virDomainEventTunable *virDomainEventTunablePtr; typedef virDomainEventTunable *virDomainEventTunablePtr;
struct _virDomainEventAgentLifecycle {
virDomainEvent parent;
int state;
int reason;
};
typedef struct _virDomainEventAgentLifecycle virDomainEventAgentLifecycle;
typedef virDomainEventAgentLifecycle *virDomainEventAgentLifecyclePtr;
static int static int
virDomainEventsOnceInit(void) virDomainEventsOnceInit(void)
...@@ -303,6 +314,12 @@ virDomainEventsOnceInit(void) ...@@ -303,6 +314,12 @@ virDomainEventsOnceInit(void)
sizeof(virDomainEventTunable), sizeof(virDomainEventTunable),
virDomainEventTunableDispose))) virDomainEventTunableDispose)))
return -1; return -1;
if (!(virDomainEventAgentLifecycleClass =
virClassNew(virDomainEventClass,
"virDomainEventAgentLifecycle",
sizeof(virDomainEventAgentLifecycle),
virDomainEventAgentLifecycleDispose)))
return -1;
return 0; return 0;
} }
...@@ -447,6 +464,13 @@ virDomainEventTunableDispose(void *obj) ...@@ -447,6 +464,13 @@ virDomainEventTunableDispose(void *obj)
virTypedParamsFree(event->params, event->nparams); virTypedParamsFree(event->params, event->nparams);
} }
static void
virDomainEventAgentLifecycleDispose(void *obj)
{
virDomainEventAgentLifecyclePtr event = obj;
VIR_DEBUG("obj=%p", event);
};
static void * static void *
virDomainEventNew(virClassPtr klass, virDomainEventNew(virClassPtr klass,
...@@ -1202,6 +1226,49 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom, ...@@ -1202,6 +1226,49 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
devAlias); devAlias);
} }
static virObjectEventPtr
virDomainEventAgentLifecycleNew(int id,
const char *name,
const unsigned char *uuid,
int state,
int reason)
{
virDomainEventAgentLifecyclePtr ev;
if (virDomainEventsInitialize() < 0)
return NULL;
if (!(ev = virDomainEventNew(virDomainEventAgentLifecycleClass,
VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE,
id, name, uuid)))
return NULL;
ev->state = state;
ev->reason = reason;
return (virObjectEventPtr)ev;
}
virObjectEventPtr
virDomainEventAgentLifecycleNewFromObj(virDomainObjPtr obj,
int state,
int reason)
{
return virDomainEventAgentLifecycleNew(obj->def->id, obj->def->name,
obj->def->uuid, state, reason);
}
virObjectEventPtr
virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,
int state,
int reason)
{
return virDomainEventAgentLifecycleNew(dom->id, dom->name, dom->uuid,
state, reason);
}
/* This function consumes the params so caller don't have to care about /* This function consumes the params so caller don't have to care about
* freeing it even if error occurs. The reason is to not have to do deep * freeing it even if error occurs. The reason is to not have to do deep
* copy of params. * copy of params.
...@@ -1459,6 +1526,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, ...@@ -1459,6 +1526,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
case VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE:
{
virDomainEventAgentLifecyclePtr agentLifecycleEvent;
agentLifecycleEvent = (virDomainEventAgentLifecyclePtr)event;
((virConnectDomainEventAgentLifecycleCallback)cb)(conn, dom,
agentLifecycleEvent->state,
agentLifecycleEvent->reason,
cbopaque);
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_LAST: case VIR_DOMAIN_EVENT_ID_LAST:
break; break;
} }
......
...@@ -193,6 +193,15 @@ virDomainEventTunableNewFromDom(virDomainPtr dom, ...@@ -193,6 +193,15 @@ virDomainEventTunableNewFromDom(virDomainPtr dom,
virTypedParameterPtr params, virTypedParameterPtr params,
int nparams); int nparams);
virObjectEventPtr
virDomainEventAgentLifecycleNewFromObj(virDomainObjPtr obj,
int state,
int reason);
virObjectEventPtr
virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,
int state,
int reason);
int int
virDomainEventStateRegister(virConnectPtr conn, virDomainEventStateRegister(virConnectPtr conn,
......
...@@ -437,6 +437,8 @@ virDomainXMLOptionNew; ...@@ -437,6 +437,8 @@ virDomainXMLOptionNew;
# conf/domain_event.h # conf/domain_event.h
virDomainEventAgentLifecycleNewFromDom;
virDomainEventAgentLifecycleNewFromObj;
virDomainEventBalloonChangeNewFromDom; virDomainEventBalloonChangeNewFromDom;
virDomainEventBalloonChangeNewFromObj; virDomainEventBalloonChangeNewFromObj;
virDomainEventBlockJob2NewFromDom; virDomainEventBlockJob2NewFromDom;
......
...@@ -334,6 +334,11 @@ remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog, ...@@ -334,6 +334,11 @@ remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog,
virNetClientPtr client, virNetClientPtr client,
void *evdata, void *opaque); void *evdata, void *opaque);
static void
remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void static void
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED, virNetClientPtr client ATTRIBUTE_UNUSED,
...@@ -489,6 +494,10 @@ static virNetClientProgramEvent remoteEvents[] = { ...@@ -489,6 +494,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventCallbackTunable, remoteDomainBuildEventCallbackTunable,
sizeof(remote_domain_event_callback_tunable_msg), sizeof(remote_domain_event_callback_tunable_msg),
(xdrproc_t)xdr_remote_domain_event_callback_tunable_msg }, (xdrproc_t)xdr_remote_domain_event_callback_tunable_msg },
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE,
remoteDomainBuildEventCallbackAgentLifecycle,
sizeof(remote_domain_event_callback_agent_lifecycle_msg),
(xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg },
}; };
...@@ -5482,6 +5491,28 @@ remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUS ...@@ -5482,6 +5491,28 @@ remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUS
} }
static void
remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
remote_domain_event_callback_agent_lifecycle_msg *msg = evdata;
struct private_data *priv = conn->privateData;
virDomainPtr dom;
virObjectEventPtr event = NULL;
if (!(dom = get_nonnull_domain(conn, msg->dom)))
return;
event = virDomainEventAgentLifecycleNewFromDom(dom, msg->state,
msg->reason);
virDomainFree(dom);
remoteEventQueue(priv, event, msg->callbackID);
}
static void static void
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED, virNetClientPtr client ATTRIBUTE_UNUSED,
......
...@@ -3108,6 +3108,14 @@ struct remote_connect_get_all_domain_stats_args { ...@@ -3108,6 +3108,14 @@ struct remote_connect_get_all_domain_stats_args {
unsigned int flags; unsigned int flags;
}; };
struct remote_domain_event_callback_agent_lifecycle_msg {
int callbackID;
remote_nonnull_domain dom;
int state;
int reason;
};
struct remote_connect_get_all_domain_stats_ret { struct remote_connect_get_all_domain_stats_ret {
remote_domain_stats_record retStats<REMOTE_DOMAIN_LIST_MAX>; remote_domain_stats_record retStats<REMOTE_DOMAIN_LIST_MAX>;
}; };
...@@ -5506,5 +5514,11 @@ enum remote_procedure { ...@@ -5506,5 +5514,11 @@ enum remote_procedure {
* @generate: none * @generate: none
* @acl: connect:write * @acl: connect:write
*/ */
REMOTE_PROC_NODE_ALLOC_PAGES = 347 REMOTE_PROC_NODE_ALLOC_PAGES = 347,
/**
* @generate: both
* @acl: none
*/
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE = 348
}; };
...@@ -2573,6 +2573,12 @@ struct remote_connect_get_all_domain_stats_args { ...@@ -2573,6 +2573,12 @@ struct remote_connect_get_all_domain_stats_args {
u_int stats; u_int stats;
u_int flags; u_int flags;
}; };
struct remote_domain_event_callback_agent_lifecycle_msg {
int callbackID;
remote_nonnull_domain dom;
int state;
int reason;
};
struct remote_connect_get_all_domain_stats_ret { struct remote_connect_get_all_domain_stats_ret {
struct { struct {
u_int retStats_len; u_int retStats_len;
...@@ -2927,4 +2933,5 @@ enum remote_procedure { ...@@ -2927,4 +2933,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_BLOCK_COPY = 345, REMOTE_PROC_DOMAIN_BLOCK_COPY = 345,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE = 346, REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE = 346,
REMOTE_PROC_NODE_ALLOC_PAGES = 347, REMOTE_PROC_NODE_ALLOC_PAGES = 347,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE = 348,
}; };
...@@ -11672,6 +11672,43 @@ vshEventTunablePrint(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -11672,6 +11672,43 @@ vshEventTunablePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
vshEventDone(data->ctl); vshEventDone(data->ctl);
} }
VIR_ENUM_DECL(vshEventAgentLifecycleState)
VIR_ENUM_IMPL(vshEventAgentLifecycleState,
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_LAST,
N_("unknown"),
N_("connected"),
N_("disconnected"))
VIR_ENUM_DECL(vshEventAgentLifecycleReason)
VIR_ENUM_IMPL(vshEventAgentLifecycleReason,
VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_LAST,
N_("unknown"),
N_("domain started"),
N_("channel event"))
#define UNKNOWNSTR(str) (str ? str : N_("unsupported value"))
static void
vshEventAgentLifecyclePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
int state,
int reason,
void *opaque)
{
vshDomEventData *data = opaque;
if (!data->loop && *data->count)
return;
vshPrint(data->ctl,
_("event 'agent-lifecycle' for domain %s: state: '%s' reason: '%s'\n"),
virDomainGetName(dom),
UNKNOWNSTR(vshEventAgentLifecycleStateTypeToString(state)),
UNKNOWNSTR(vshEventAgentLifecycleReasonTypeToString(reason)));
(*data->count)++;
if (!data->loop)
vshEventDone(data->ctl);
}
static vshEventCallback vshEventCallbacks[] = { static vshEventCallback vshEventCallbacks[] = {
{ "lifecycle", { "lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(vshEventLifecyclePrint), }, VIR_DOMAIN_EVENT_CALLBACK(vshEventLifecyclePrint), },
...@@ -11707,6 +11744,8 @@ static vshEventCallback vshEventCallbacks[] = { ...@@ -11707,6 +11744,8 @@ static vshEventCallback vshEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(vshEventBlockJobPrint), }, VIR_DOMAIN_EVENT_CALLBACK(vshEventBlockJobPrint), },
{ "tunable", { "tunable",
VIR_DOMAIN_EVENT_CALLBACK(vshEventTunablePrint), }, VIR_DOMAIN_EVENT_CALLBACK(vshEventTunablePrint), },
{ "agent-lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(vshEventAgentLifecyclePrint), },
}; };
verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks)); verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册