mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-06 20:00:05 +00:00
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: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
e2b86f580c
commit
0b50f4a025
@ -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));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user