mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 07:05:28 +00:00
qemu: Add support for domain cleanup callbacks
Add support for registering cleanup callbacks to be run when a domain transitions to shutoff state.
This commit is contained in:
parent
9f71368d06
commit
bf9f0a9726
@ -232,6 +232,7 @@ static void qemuDomainObjPrivateFree(void *data)
|
|||||||
VIR_ERROR(_("Unexpected QEMU agent still active during domain deletion"));
|
VIR_ERROR(_("Unexpected QEMU agent still active during domain deletion"));
|
||||||
qemuAgentClose(priv->agent);
|
qemuAgentClose(priv->agent);
|
||||||
}
|
}
|
||||||
|
VIR_FREE(priv->cleanupCallbacks);
|
||||||
VIR_FREE(priv);
|
VIR_FREE(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1769,3 +1770,75 @@ qemuDomainCheckDiskPresence(struct qemud_driver *driver,
|
|||||||
cleanup:
|
cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The vm must be locked when any of the following cleanup functions is
|
||||||
|
* called.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qemuDomainCleanupAdd(virDomainObjPtr vm,
|
||||||
|
qemuDomainCleanupCallback cb)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
VIR_DEBUG("vm=%s, cb=%p", vm->def->name, cb);
|
||||||
|
|
||||||
|
for (i = 0; i < priv->ncleanupCallbacks; i++) {
|
||||||
|
if (priv->cleanupCallbacks[i] == cb)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_RESIZE_N(priv->cleanupCallbacks,
|
||||||
|
priv->ncleanupCallbacks_max,
|
||||||
|
priv->ncleanupCallbacks, 1) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cleanupCallbacks[priv->ncleanupCallbacks++] = cb;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuDomainCleanupRemove(virDomainObjPtr vm,
|
||||||
|
qemuDomainCleanupCallback cb)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
VIR_DEBUG("vm=%s, cb=%p", vm->def->name, cb);
|
||||||
|
|
||||||
|
for (i = 0; i < priv->ncleanupCallbacks; i++) {
|
||||||
|
if (priv->cleanupCallbacks[i] == cb) {
|
||||||
|
memmove(priv->cleanupCallbacks + i,
|
||||||
|
priv->cleanupCallbacks + i + 1,
|
||||||
|
priv->ncleanupCallbacks - i - 1);
|
||||||
|
priv->ncleanupCallbacks--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_SHRINK_N(priv->cleanupCallbacks,
|
||||||
|
priv->ncleanupCallbacks_max,
|
||||||
|
priv->ncleanupCallbacks_max - priv->ncleanupCallbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuDomainCleanupRun(struct qemud_driver *driver,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
VIR_DEBUG("driver=%p, vm=%s", driver, vm->def->name);
|
||||||
|
|
||||||
|
/* run cleanup callbacks in reverse order */
|
||||||
|
for (i = priv->ncleanupCallbacks - 1; i >= 0; i--) {
|
||||||
|
if (priv->cleanupCallbacks[i])
|
||||||
|
priv->cleanupCallbacks[i](driver, vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(priv->cleanupCallbacks);
|
||||||
|
priv->ncleanupCallbacks = 0;
|
||||||
|
priv->ncleanupCallbacks_max = 0;
|
||||||
|
}
|
||||||
|
@ -101,6 +101,9 @@ struct qemuDomainJobObj {
|
|||||||
typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
|
typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
|
||||||
typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
|
typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
|
||||||
|
|
||||||
|
typedef void (*qemuDomainCleanupCallback)(struct qemud_driver *driver,
|
||||||
|
virDomainObjPtr vm);
|
||||||
|
|
||||||
typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
|
typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
|
||||||
typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
|
typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
|
||||||
struct _qemuDomainObjPrivate {
|
struct _qemuDomainObjPrivate {
|
||||||
@ -137,6 +140,10 @@ struct _qemuDomainObjPrivate {
|
|||||||
char *origname;
|
char *origname;
|
||||||
|
|
||||||
virConsolesPtr cons;
|
virConsolesPtr cons;
|
||||||
|
|
||||||
|
qemuDomainCleanupCallback *cleanupCallbacks;
|
||||||
|
size_t ncleanupCallbacks;
|
||||||
|
size_t ncleanupCallbacks_max;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qemuDomainWatchdogEvent
|
struct qemuDomainWatchdogEvent
|
||||||
@ -314,4 +321,12 @@ bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
|
|||||||
int qemuDomainCheckDiskPresence(struct qemud_driver *driver,
|
int qemuDomainCheckDiskPresence(struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
bool start_with_state);
|
bool start_with_state);
|
||||||
|
|
||||||
|
int qemuDomainCleanupAdd(virDomainObjPtr vm,
|
||||||
|
qemuDomainCleanupCallback cb);
|
||||||
|
void qemuDomainCleanupRemove(virDomainObjPtr vm,
|
||||||
|
qemuDomainCleanupCallback cb);
|
||||||
|
void qemuDomainCleanupRun(struct qemud_driver *driver,
|
||||||
|
virDomainObjPtr vm);
|
||||||
|
|
||||||
#endif /* __QEMU_DOMAIN_H__ */
|
#endif /* __QEMU_DOMAIN_H__ */
|
||||||
|
@ -3803,6 +3803,8 @@ void qemuProcessStop(struct qemud_driver *driver,
|
|||||||
/* shut it off for sure */
|
/* shut it off for sure */
|
||||||
ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE));
|
ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE));
|
||||||
|
|
||||||
|
qemuDomainCleanupRun(driver, vm);
|
||||||
|
|
||||||
/* Stop autodestroy in case guest is restarted */
|
/* Stop autodestroy in case guest is restarted */
|
||||||
qemuProcessAutoDestroyRemove(driver, vm);
|
qemuProcessAutoDestroyRemove(driver, vm);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user