mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 22:55:23 +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"));
|
||||
qemuAgentClose(priv->agent);
|
||||
}
|
||||
VIR_FREE(priv->cleanupCallbacks);
|
||||
VIR_FREE(priv);
|
||||
}
|
||||
|
||||
@ -1769,3 +1770,75 @@ qemuDomainCheckDiskPresence(struct qemud_driver *driver,
|
||||
cleanup:
|
||||
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 qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
|
||||
|
||||
typedef void (*qemuDomainCleanupCallback)(struct qemud_driver *driver,
|
||||
virDomainObjPtr vm);
|
||||
|
||||
typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
|
||||
typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
|
||||
struct _qemuDomainObjPrivate {
|
||||
@ -137,6 +140,10 @@ struct _qemuDomainObjPrivate {
|
||||
char *origname;
|
||||
|
||||
virConsolesPtr cons;
|
||||
|
||||
qemuDomainCleanupCallback *cleanupCallbacks;
|
||||
size_t ncleanupCallbacks;
|
||||
size_t ncleanupCallbacks_max;
|
||||
};
|
||||
|
||||
struct qemuDomainWatchdogEvent
|
||||
@ -314,4 +321,12 @@ bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
|
||||
int qemuDomainCheckDiskPresence(struct qemud_driver *driver,
|
||||
virDomainObjPtr vm,
|
||||
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__ */
|
||||
|
@ -3803,6 +3803,8 @@ void qemuProcessStop(struct qemud_driver *driver,
|
||||
/* shut it off for sure */
|
||||
ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE));
|
||||
|
||||
qemuDomainCleanupRun(driver, vm);
|
||||
|
||||
/* Stop autodestroy in case guest is restarted */
|
||||
qemuProcessAutoDestroyRemove(driver, vm);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user