提交 0b50f4a0 编写于 作者: J Jiri Denemark

Introduce migration iteration event

The VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION event will be triggered
whenever VIR_DOMAIN_JOB_MEMORY_ITERATION changes its value, i.e.,
whenever a new iteration over guest memory pages is started during
migration.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 e2b86f58
......@@ -1079,6 +1079,37 @@ remoteRelayDomainEventDeviceAdded(virConnectPtr conn,
}
static int
remoteRelayDomainEventMigrationIteration(virConnectPtr conn,
virDomainPtr dom,
int iteration,
void *opaque)
{
daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_callback_migration_iteration_msg data;
if (callback->callbackID < 0 ||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain migration pass event %s %d, "
"callback %d, iteration %d",
dom->name, dom->id, callback->callbackID, iteration);
/* build return data */
memset(&data, 0, sizeof(data));
data.callbackID = callback->callbackID;
make_nonnull_domain(&data.dom, dom);
data.iteration = iteration;
remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION,
(xdrproc_t)xdr_remote_domain_event_callback_migration_iteration_msg,
&data);
return 0;
}
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
......@@ -1102,6 +1133,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventAgentLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceAdded),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMigrationIteration),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
......
......@@ -3283,6 +3283,27 @@ typedef void (*virConnectDomainEventDeviceAddedCallback)(virConnectPtr conn,
const char *devAlias,
void *opaque);
/**
* virConnectDomainEventMigrationIterationCallback:
* @conn: connection object
* @dom: domain on which the event occurred
* @iteration: current iteration over domain's memory
* @opaque: application specific data
*
* This callback occurs during live migration when a new iteration over
* domain's memory starts. The @iteration value is increased by one every
* time a new iteration is started to transfer memory pages dirtied since
* the last iteration.
*
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION with
* virConnectDomainEventRegisterAny().
*/
typedef void (*virConnectDomainEventMigrationIterationCallback)(virConnectPtr conn,
virDomainPtr dom,
int iteration,
void *opaque);
/**
* VIR_DOMAIN_TUNABLE_CPU_VCPUPIN:
*
......@@ -3566,6 +3587,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_TUNABLE = 17, /* virConnectDomainEventTunableCallback */
VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE = 18,/* virConnectDomainEventAgentLifecycleCallback */
VIR_DOMAIN_EVENT_ID_DEVICE_ADDED = 19, /* virConnectDomainEventDeviceAddedCallback */
VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION = 20, /* virConnectDomainEventMigrationIterationCallback */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST
......
......@@ -56,6 +56,7 @@ static virClassPtr virDomainQemuMonitorEventClass;
static virClassPtr virDomainEventTunableClass;
static virClassPtr virDomainEventAgentLifecycleClass;
static virClassPtr virDomainEventDeviceAddedClass;
static virClassPtr virDomainEventMigrationIterationClass;
static void virDomainEventDispose(void *obj);
......@@ -74,6 +75,7 @@ static void virDomainQemuMonitorEventDispose(void *obj);
static void virDomainEventTunableDispose(void *obj);
static void virDomainEventAgentLifecycleDispose(void *obj);
static void virDomainEventDeviceAddedDispose(void *obj);
static void virDomainEventMigrationIterationDispose(void *obj);
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
......@@ -236,6 +238,14 @@ struct _virDomainEventAgentLifecycle {
typedef struct _virDomainEventAgentLifecycle virDomainEventAgentLifecycle;
typedef virDomainEventAgentLifecycle *virDomainEventAgentLifecyclePtr;
struct _virDomainEventMigrationIteration {
virDomainEvent parent;
int iteration;
};
typedef struct _virDomainEventMigrationIteration virDomainEventMigrationIteration;
typedef virDomainEventMigrationIteration *virDomainEventMigrationIterationPtr;
static int
virDomainEventsOnceInit(void)
......@@ -336,6 +346,12 @@ virDomainEventsOnceInit(void)
sizeof(virDomainEventAgentLifecycle),
virDomainEventAgentLifecycleDispose)))
return -1;
if (!(virDomainEventMigrationIterationClass =
virClassNew(virDomainEventClass,
"virDomainEventMigrationIteration",
sizeof(virDomainEventMigrationIteration),
virDomainEventMigrationIterationDispose)))
return -1;
return 0;
}
......@@ -496,6 +512,13 @@ virDomainEventAgentLifecycleDispose(void *obj)
VIR_DEBUG("obj=%p", event);
};
static void
virDomainEventMigrationIterationDispose(void *obj)
{
virDomainEventMigrationIterationPtr event = obj;
VIR_DEBUG("obj=%p", event);
};
static void *
virDomainEventNew(virClassPtr klass,
......@@ -1334,6 +1357,43 @@ virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,
state, reason);
}
static virObjectEventPtr
virDomainEventMigrationIterationNew(int id,
const char *name,
const unsigned char *uuid,
int iteration)
{
virDomainEventMigrationIterationPtr ev;
if (virDomainEventsInitialize() < 0)
return NULL;
if (!(ev = virDomainEventNew(virDomainEventMigrationIterationClass,
VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION,
id, name, uuid)))
return NULL;
ev->iteration = iteration;
return (virObjectEventPtr)ev;
}
virObjectEventPtr
virDomainEventMigrationIterationNewFromObj(virDomainObjPtr obj,
int iteration)
{
return virDomainEventMigrationIterationNew(obj->def->id, obj->def->name,
obj->def->uuid, iteration);
}
virObjectEventPtr
virDomainEventMigrationIterationNewFromDom(virDomainPtr dom,
int iteration)
{
return virDomainEventMigrationIterationNew(dom->id, dom->name, dom->uuid,
iteration);
}
/* 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
......@@ -1614,6 +1674,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION:
{
virDomainEventMigrationIterationPtr ev;
ev = (virDomainEventMigrationIterationPtr) event;
((virConnectDomainEventMigrationIterationCallback)cb)(conn, dom,
ev->iteration,
cbopaque);
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}
......
......@@ -209,6 +209,14 @@ virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,
int state,
int reason);
virObjectEventPtr
virDomainEventMigrationIterationNewFromObj(virDomainObjPtr obj,
int iteration);
virObjectEventPtr
virDomainEventMigrationIterationNewFromDom(virDomainPtr dom,
int iteration);
int
virDomainEventStateRegister(virConnectPtr conn,
virObjectEventStatePtr state,
......
......@@ -514,6 +514,8 @@ virDomainEventLifecycleNew;
virDomainEventLifecycleNewFromDef;
virDomainEventLifecycleNewFromDom;
virDomainEventLifecycleNewFromObj;
virDomainEventMigrationIterationNewFromDom;
virDomainEventMigrationIterationNewFromObj;
virDomainEventPMSuspendDiskNewFromDom;
virDomainEventPMSuspendDiskNewFromObj;
virDomainEventPMSuspendNewFromDom;
......
......@@ -341,6 +341,11 @@ remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void
remoteDomainBuildEventCallbackMigrationIteration(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
......@@ -504,6 +509,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventCallbackDeviceAdded,
sizeof(remote_domain_event_callback_device_added_msg),
(xdrproc_t)xdr_remote_domain_event_callback_device_added_msg },
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION,
remoteDomainBuildEventCallbackMigrationIteration,
sizeof(remote_domain_event_callback_migration_iteration_msg),
(xdrproc_t)xdr_remote_domain_event_callback_migration_iteration_msg },
};
......@@ -5513,6 +5522,30 @@ remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog ATTRIBU
remoteEventQueue(priv, event, msg->callbackID);
}
static void
remoteDomainBuildEventCallbackMigrationIteration(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata,
void *opaque)
{
virConnectPtr conn = opaque;
remote_domain_event_callback_migration_iteration_msg *msg = evdata;
struct private_data *priv = conn->privateData;
virDomainPtr dom;
virObjectEventPtr event = NULL;
if (!(dom = get_nonnull_domain(conn, msg->dom)))
return;
event = virDomainEventMigrationIterationNewFromDom(dom, msg->iteration);
virObjectUnref(dom);
remoteEventQueue(priv, event, msg->callbackID);
}
static void
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
......
......@@ -3222,6 +3222,12 @@ struct remote_domain_rename_ret {
int retcode;
};
struct remote_domain_event_callback_migration_iteration_msg {
int callbackID;
remote_nonnull_domain dom;
int iteration;
};
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
......@@ -5694,5 +5700,11 @@ enum remote_procedure {
* @acl: domain:write
* @acl: domain:save
*/
REMOTE_PROC_DOMAIN_RENAME = 358
REMOTE_PROC_DOMAIN_RENAME = 358,
/**
* @generate: both
* @acl: none
*/
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION = 359
};
......@@ -2692,6 +2692,11 @@ struct remote_domain_rename_args {
struct remote_domain_rename_ret {
int retcode;
};
struct remote_domain_event_callback_migration_iteration_msg {
int callbackID;
remote_nonnull_domain dom;
int iteration;
};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
......@@ -3051,4 +3056,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_DEL_IOTHREAD = 356,
REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357,
REMOTE_PROC_DOMAIN_RENAME = 358,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION = 359,
};
......@@ -11924,6 +11924,22 @@ virshEventAgentLifecyclePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virshEventPrint(opaque, &buf);
}
static void
virshEventMigrationIterationPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
int iteration,
void *opaque)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
virBufferAsprintf(&buf, _("event 'migration-iteration' for domain %s: "
"iteration: '%d'\n"),
virDomainGetName(dom),
iteration);
virshEventPrint(opaque, &buf);
}
static vshEventCallback vshEventCallbacks[] = {
{ "lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(virshEventLifecyclePrint), },
......@@ -11963,6 +11979,8 @@ static vshEventCallback vshEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(virshEventAgentLifecyclePrint), },
{ "device-added",
VIR_DOMAIN_EVENT_CALLBACK(virshEventDeviceAddedPrint), },
{ "migration-iteration",
VIR_DOMAIN_EVENT_CALLBACK(virshEventMigrationIterationPrint), },
};
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.
先完成此消息的编辑!
想要评论请 注册