mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: Move close callbacks handling into util/virclosecallbacks.c
This commit is contained in:
parent
166db595c3
commit
272769becc
@ -146,6 +146,7 @@ src/util/viraudit.c
|
|||||||
src/util/virauth.c
|
src/util/virauth.c
|
||||||
src/util/virauthconfig.c
|
src/util/virauthconfig.c
|
||||||
src/util/vircgroup.c
|
src/util/vircgroup.c
|
||||||
|
src/util/virclosecallbacks.c
|
||||||
src/util/vircommand.c
|
src/util/vircommand.c
|
||||||
src/util/virconf.c
|
src/util/virconf.c
|
||||||
src/util/virdbus.c
|
src/util/virdbus.c
|
||||||
|
@ -83,6 +83,7 @@ UTIL_SOURCES = \
|
|||||||
util/virbitmap.c util/virbitmap.h \
|
util/virbitmap.c util/virbitmap.h \
|
||||||
util/virbuffer.c util/virbuffer.h \
|
util/virbuffer.c util/virbuffer.h \
|
||||||
util/vircgroup.c util/vircgroup.h util/vircgrouppriv.h \
|
util/vircgroup.c util/vircgroup.h util/vircgrouppriv.h \
|
||||||
|
util/virclosecallbacks.c util/virclosecallbacks.h \
|
||||||
util/vircommand.c util/vircommand.h \
|
util/vircommand.c util/vircommand.h \
|
||||||
util/virconf.c util/virconf.h \
|
util/virconf.c util/virconf.h \
|
||||||
util/virdbus.c util/virdbus.h \
|
util/virdbus.c util/virdbus.h \
|
||||||
@ -882,7 +883,8 @@ libvirt_util_la_SOURCES = \
|
|||||||
$(UTIL_SOURCES)
|
$(UTIL_SOURCES)
|
||||||
libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS) $(YAJL_CFLAGS) $(LIBNL_CFLAGS) \
|
libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS) $(YAJL_CFLAGS) $(LIBNL_CFLAGS) \
|
||||||
$(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS) \
|
$(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS) \
|
||||||
$(DBUS_CFLAGS) $(LDEXP_LIBM) $(NUMACTL_CFLAGS)
|
$(DBUS_CFLAGS) $(LDEXP_LIBM) $(NUMACTL_CFLAGS) \
|
||||||
|
-I$(top_srcdir)/src/conf
|
||||||
libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \
|
libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \
|
||||||
$(THREAD_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \
|
$(THREAD_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \
|
||||||
$(LIB_CLOCK_GETTIME) $(DBUS_LIBS) $(MSCOM_LIBS) $(LIBXML_LIBS) \
|
$(LIB_CLOCK_GETTIME) $(DBUS_LIBS) $(MSCOM_LIBS) $(LIBXML_LIBS) \
|
||||||
|
@ -1204,6 +1204,13 @@ virCgroupSetMemorySoftLimit;
|
|||||||
virCgroupSetMemSwapHardLimit;
|
virCgroupSetMemSwapHardLimit;
|
||||||
|
|
||||||
|
|
||||||
|
# util/virclosecallbacks.h
|
||||||
|
virCloseCallbacksGet;
|
||||||
|
virCloseCallbacksNew;
|
||||||
|
virCloseCallbacksRun;
|
||||||
|
virCloseCallbacksSet;
|
||||||
|
virCloseCallbacksUnset;
|
||||||
|
|
||||||
# util/vircommand.h
|
# util/vircommand.h
|
||||||
virCommandAbort;
|
virCommandAbort;
|
||||||
virCommandAddArg;
|
virCommandAddArg;
|
||||||
|
@ -56,25 +56,8 @@
|
|||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
|
|
||||||
typedef struct _qemuDriverCloseDef qemuDriverCloseDef;
|
|
||||||
typedef qemuDriverCloseDef *qemuDriverCloseDefPtr;
|
|
||||||
struct _qemuDriverCloseDef {
|
|
||||||
virConnectPtr conn;
|
|
||||||
virQEMUCloseCallback cb;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _virQEMUCloseCallbacks {
|
|
||||||
virObjectLockable parent;
|
|
||||||
|
|
||||||
/* UUID string to qemuDriverCloseDef mapping */
|
|
||||||
virHashTablePtr list;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static virClassPtr virQEMUDriverConfigClass;
|
static virClassPtr virQEMUDriverConfigClass;
|
||||||
static virClassPtr virQEMUCloseCallbacksClass;
|
|
||||||
static void virQEMUDriverConfigDispose(void *obj);
|
static void virQEMUDriverConfigDispose(void *obj);
|
||||||
static void virQEMUCloseCallbacksDispose(void *obj);
|
|
||||||
|
|
||||||
static int virQEMUConfigOnceInit(void)
|
static int virQEMUConfigOnceInit(void)
|
||||||
{
|
{
|
||||||
@ -83,12 +66,7 @@ static int virQEMUConfigOnceInit(void)
|
|||||||
sizeof(virQEMUDriverConfig),
|
sizeof(virQEMUDriverConfig),
|
||||||
virQEMUDriverConfigDispose);
|
virQEMUDriverConfigDispose);
|
||||||
|
|
||||||
virQEMUCloseCallbacksClass = virClassNew(virClassForObjectLockable(),
|
if (!virQEMUDriverConfigClass)
|
||||||
"virQEMUCloseCallbacks",
|
|
||||||
sizeof(virQEMUCloseCallbacks),
|
|
||||||
virQEMUCloseCallbacksDispose);
|
|
||||||
|
|
||||||
if (!virQEMUDriverConfigClass || !virQEMUCloseCallbacksClass)
|
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@ -662,277 +640,6 @@ virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
virQEMUCloseCallbacksFreeData(void *payload,
|
|
||||||
const void *name ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
VIR_FREE(payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
virQEMUCloseCallbacksPtr
|
|
||||||
virQEMUCloseCallbacksNew(void)
|
|
||||||
{
|
|
||||||
virQEMUCloseCallbacksPtr closeCallbacks;
|
|
||||||
|
|
||||||
if (virQEMUConfigInitialize() < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!(closeCallbacks = virObjectLockableNew(virQEMUCloseCallbacksClass)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
closeCallbacks->list = virHashCreate(5, virQEMUCloseCallbacksFreeData);
|
|
||||||
if (!closeCallbacks->list) {
|
|
||||||
virObjectUnref(closeCallbacks);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return closeCallbacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
virQEMUCloseCallbacksDispose(void *obj)
|
|
||||||
{
|
|
||||||
virQEMUCloseCallbacksPtr closeCallbacks = obj;
|
|
||||||
|
|
||||||
virHashFree(closeCallbacks->list);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
virQEMUCloseCallbacksSet(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virConnectPtr conn,
|
|
||||||
virQEMUCloseCallback cb)
|
|
||||||
{
|
|
||||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
||||||
qemuDriverCloseDefPtr closeDef;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
virUUIDFormat(vm->def->uuid, uuidstr);
|
|
||||||
VIR_DEBUG("vm=%s, uuid=%s, conn=%p, cb=%p",
|
|
||||||
vm->def->name, uuidstr, conn, cb);
|
|
||||||
|
|
||||||
virObjectLock(closeCallbacks);
|
|
||||||
|
|
||||||
closeDef = virHashLookup(closeCallbacks->list, uuidstr);
|
|
||||||
if (closeDef) {
|
|
||||||
if (closeDef->conn != conn) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Close callback for domain %s already registered"
|
|
||||||
" with another connection %p"),
|
|
||||||
vm->def->name, closeDef->conn);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (closeDef->cb && closeDef->cb != cb) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Another close callback is already defined for"
|
|
||||||
" domain %s"), vm->def->name);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
closeDef->cb = cb;
|
|
||||||
} else {
|
|
||||||
if (VIR_ALLOC(closeDef) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
closeDef->conn = conn;
|
|
||||||
closeDef->cb = cb;
|
|
||||||
if (virHashAddEntry(closeCallbacks->list, uuidstr, closeDef) < 0) {
|
|
||||||
VIR_FREE(closeDef);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(closeCallbacks);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
virQEMUCloseCallbacksUnset(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virQEMUCloseCallback cb)
|
|
||||||
{
|
|
||||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
||||||
qemuDriverCloseDefPtr closeDef;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
virUUIDFormat(vm->def->uuid, uuidstr);
|
|
||||||
VIR_DEBUG("vm=%s, uuid=%s, cb=%p",
|
|
||||||
vm->def->name, uuidstr, cb);
|
|
||||||
|
|
||||||
virObjectLock(closeCallbacks);
|
|
||||||
|
|
||||||
closeDef = virHashLookup(closeCallbacks->list, uuidstr);
|
|
||||||
if (!closeDef)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (closeDef->cb && closeDef->cb != cb) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Trying to remove mismatching close callback for"
|
|
||||||
" domain %s"), vm->def->name);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = virHashRemoveEntry(closeCallbacks->list, uuidstr);
|
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(closeCallbacks);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virQEMUCloseCallback
|
|
||||||
virQEMUCloseCallbacksGet(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virConnectPtr conn)
|
|
||||||
{
|
|
||||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
||||||
qemuDriverCloseDefPtr closeDef;
|
|
||||||
virQEMUCloseCallback cb = NULL;
|
|
||||||
|
|
||||||
virUUIDFormat(vm->def->uuid, uuidstr);
|
|
||||||
VIR_DEBUG("vm=%s, uuid=%s, conn=%p",
|
|
||||||
vm->def->name, uuidstr, conn);
|
|
||||||
|
|
||||||
virObjectLock(closeCallbacks);
|
|
||||||
|
|
||||||
closeDef = virHashLookup(closeCallbacks->list, uuidstr);
|
|
||||||
if (closeDef && (!conn || closeDef->conn == conn))
|
|
||||||
cb = closeDef->cb;
|
|
||||||
|
|
||||||
virObjectUnlock(closeCallbacks);
|
|
||||||
|
|
||||||
VIR_DEBUG("cb=%p", cb);
|
|
||||||
return cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _virQEMUCloseCallbacksListEntry virQEMUCloseCallbacksListEntry;
|
|
||||||
typedef virQEMUCloseCallbacksListEntry *virQEMUCloseCallbacksListEntryPtr;
|
|
||||||
struct _virQEMUCloseCallbacksListEntry {
|
|
||||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
||||||
virQEMUCloseCallback callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _virQEMUCloseCallbacksList virQEMUCloseCallbacksList;
|
|
||||||
typedef virQEMUCloseCallbacksList *virQEMUCloseCallbacksListPtr;
|
|
||||||
struct _virQEMUCloseCallbacksList {
|
|
||||||
size_t nentries;
|
|
||||||
virQEMUCloseCallbacksListEntryPtr entries;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct virQEMUCloseCallbacksData {
|
|
||||||
virConnectPtr conn;
|
|
||||||
virQEMUCloseCallbacksListPtr list;
|
|
||||||
bool oom;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
virQEMUCloseCallbacksGetOne(void *payload,
|
|
||||||
const void *key,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
struct virQEMUCloseCallbacksData *data = opaque;
|
|
||||||
qemuDriverCloseDefPtr closeDef = payload;
|
|
||||||
const char *uuidstr = key;
|
|
||||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
||||||
|
|
||||||
if (virUUIDParse(uuidstr, uuid) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
VIR_DEBUG("conn=%p, thisconn=%p, uuid=%s, cb=%p",
|
|
||||||
closeDef->conn, data->conn, uuidstr, closeDef->cb);
|
|
||||||
|
|
||||||
if (data->conn != closeDef->conn || !closeDef->cb)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (VIR_EXPAND_N(data->list->entries,
|
|
||||||
data->list->nentries, 1) < 0) {
|
|
||||||
data->oom = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data->list->entries[data->list->nentries - 1].uuid,
|
|
||||||
uuid, VIR_UUID_BUFLEN);
|
|
||||||
data->list->entries[data->list->nentries - 1].callback = closeDef->cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static virQEMUCloseCallbacksListPtr
|
|
||||||
virQEMUCloseCallbacksGetForConn(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virConnectPtr conn)
|
|
||||||
{
|
|
||||||
virQEMUCloseCallbacksListPtr list = NULL;
|
|
||||||
struct virQEMUCloseCallbacksData data;
|
|
||||||
|
|
||||||
if (VIR_ALLOC(list) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
data.conn = conn;
|
|
||||||
data.list = list;
|
|
||||||
data.oom = false;
|
|
||||||
|
|
||||||
virHashForEach(closeCallbacks->list, virQEMUCloseCallbacksGetOne, &data);
|
|
||||||
|
|
||||||
if (data.oom) {
|
|
||||||
VIR_FREE(list->entries);
|
|
||||||
VIR_FREE(list);
|
|
||||||
virReportOOMError();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
virQEMUCloseCallbacksRun(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virConnectPtr conn,
|
|
||||||
virQEMUDriverPtr driver)
|
|
||||||
{
|
|
||||||
virQEMUCloseCallbacksListPtr list;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
VIR_DEBUG("conn=%p", conn);
|
|
||||||
|
|
||||||
/* We must not hold the lock while running the callbacks,
|
|
||||||
* so first we obtain the list of callbacks, then remove
|
|
||||||
* them all from the hash. At that point we can release
|
|
||||||
* the lock and run the callbacks safely. */
|
|
||||||
|
|
||||||
virObjectLock(closeCallbacks);
|
|
||||||
list = virQEMUCloseCallbacksGetForConn(closeCallbacks, conn);
|
|
||||||
if (!list)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < list->nentries; i++) {
|
|
||||||
virHashRemoveEntry(closeCallbacks->list,
|
|
||||||
list->entries[i].uuid);
|
|
||||||
}
|
|
||||||
virObjectUnlock(closeCallbacks);
|
|
||||||
|
|
||||||
for (i = 0; i < list->nentries; i++) {
|
|
||||||
virDomainObjPtr vm;
|
|
||||||
|
|
||||||
if (!(vm = virDomainObjListFindByUUID(driver->domains,
|
|
||||||
list->entries[i].uuid))) {
|
|
||||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
||||||
virUUIDFormat(list->entries[i].uuid, uuidstr);
|
|
||||||
VIR_DEBUG("No domain object with UUID %s", uuidstr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
vm = list->entries[i].callback(driver, vm, conn);
|
|
||||||
if (vm)
|
|
||||||
virObjectUnlock(vm);
|
|
||||||
}
|
|
||||||
VIR_FREE(list->entries);
|
|
||||||
VIR_FREE(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _qemuSharedDeviceEntry {
|
struct _qemuSharedDeviceEntry {
|
||||||
size_t ref;
|
size_t ref;
|
||||||
char **domains; /* array of domain names */
|
char **domains; /* array of domain names */
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
# include "virthreadpool.h"
|
# include "virthreadpool.h"
|
||||||
# include "locking/lock_manager.h"
|
# include "locking/lock_manager.h"
|
||||||
# include "qemu_capabilities.h"
|
# include "qemu_capabilities.h"
|
||||||
|
# include "virclosecallbacks.h"
|
||||||
|
|
||||||
# ifdef CPU_SETSIZE /* Linux */
|
# ifdef CPU_SETSIZE /* Linux */
|
||||||
# define QEMUD_CPUMASK_LEN CPU_SETSIZE
|
# define QEMUD_CPUMASK_LEN CPU_SETSIZE
|
||||||
@ -51,9 +52,6 @@
|
|||||||
# error "Port me"
|
# error "Port me"
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
typedef struct _virQEMUCloseCallbacks virQEMUCloseCallbacks;
|
|
||||||
typedef virQEMUCloseCallbacks *virQEMUCloseCallbacksPtr;
|
|
||||||
|
|
||||||
typedef struct _virQEMUDriver virQEMUDriver;
|
typedef struct _virQEMUDriver virQEMUDriver;
|
||||||
typedef virQEMUDriver *virQEMUDriverPtr;
|
typedef virQEMUDriver *virQEMUDriverPtr;
|
||||||
|
|
||||||
@ -229,7 +227,7 @@ struct _virQEMUDriver {
|
|||||||
virLockManagerPluginPtr lockManager;
|
virLockManagerPluginPtr lockManager;
|
||||||
|
|
||||||
/* Immutable pointer, self-clocking APIs */
|
/* Immutable pointer, self-clocking APIs */
|
||||||
virQEMUCloseCallbacksPtr closeCallbacks;
|
virCloseCallbacksPtr closeCallbacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _qemuDomainCmdlineDef qemuDomainCmdlineDef;
|
typedef struct _qemuDomainCmdlineDef qemuDomainCmdlineDef;
|
||||||
@ -266,25 +264,6 @@ struct qemuDomainDiskInfo {
|
|||||||
int io_status;
|
int io_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef virDomainObjPtr (*virQEMUCloseCallback)(virQEMUDriverPtr driver,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virConnectPtr conn);
|
|
||||||
virQEMUCloseCallbacksPtr virQEMUCloseCallbacksNew(void);
|
|
||||||
int virQEMUCloseCallbacksSet(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virConnectPtr conn,
|
|
||||||
virQEMUCloseCallback cb);
|
|
||||||
int virQEMUCloseCallbacksUnset(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virQEMUCloseCallback cb);
|
|
||||||
virQEMUCloseCallback
|
|
||||||
virQEMUCloseCallbacksGet(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virConnectPtr conn);
|
|
||||||
void virQEMUCloseCallbacksRun(virQEMUCloseCallbacksPtr closeCallbacks,
|
|
||||||
virConnectPtr conn,
|
|
||||||
virQEMUDriverPtr driver);
|
|
||||||
|
|
||||||
typedef struct _qemuSharedDeviceEntry qemuSharedDeviceEntry;
|
typedef struct _qemuSharedDeviceEntry qemuSharedDeviceEntry;
|
||||||
typedef qemuSharedDeviceEntry *qemuSharedDeviceEntryPtr;
|
typedef qemuSharedDeviceEntry *qemuSharedDeviceEntryPtr;
|
||||||
|
|
||||||
|
@ -776,7 +776,7 @@ qemuStateInitialize(bool privileged,
|
|||||||
cfg->hugepagePath = mempath;
|
cfg->hugepagePath = mempath;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(qemu_driver->closeCallbacks = virQEMUCloseCallbacksNew()))
|
if (!(qemu_driver->closeCallbacks = virCloseCallbacksNew()))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Get all the running persistent or transient configs first */
|
/* Get all the running persistent or transient configs first */
|
||||||
@ -1076,7 +1076,7 @@ static int qemuConnectClose(virConnectPtr conn)
|
|||||||
virQEMUDriverPtr driver = conn->privateData;
|
virQEMUDriverPtr driver = conn->privateData;
|
||||||
|
|
||||||
/* Get rid of callbacks registered for this conn */
|
/* Get rid of callbacks registered for this conn */
|
||||||
virQEMUCloseCallbacksRun(driver->closeCallbacks, conn, driver);
|
virCloseCallbacksRun(driver->closeCallbacks, conn, driver->domains, driver);
|
||||||
|
|
||||||
conn->privateData = NULL;
|
conn->privateData = NULL;
|
||||||
|
|
||||||
|
@ -1896,11 +1896,12 @@ cleanup:
|
|||||||
* qemuDomainMigrateBegin3 and qemuDomainMigratePerform3 or
|
* qemuDomainMigrateBegin3 and qemuDomainMigratePerform3 or
|
||||||
* qemuDomainMigratePerform3 and qemuDomainMigrateConfirm3.
|
* qemuDomainMigratePerform3 and qemuDomainMigrateConfirm3.
|
||||||
*/
|
*/
|
||||||
virDomainObjPtr
|
static virDomainObjPtr
|
||||||
qemuMigrationCleanup(virQEMUDriverPtr driver,
|
qemuMigrationCleanup(virDomainObjPtr vm,
|
||||||
virDomainObjPtr vm,
|
virConnectPtr conn,
|
||||||
virConnectPtr conn)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
virQEMUDriverPtr driver = opaque;
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
|
||||||
VIR_DEBUG("vm=%s, conn=%p, asyncJob=%s, phase=%s",
|
VIR_DEBUG("vm=%s, conn=%p, asyncJob=%s, phase=%s",
|
||||||
@ -2100,8 +2101,8 @@ qemuMigrationBegin(virConnectPtr conn,
|
|||||||
* This prevents any other APIs being invoked while migration is taking
|
* This prevents any other APIs being invoked while migration is taking
|
||||||
* place.
|
* place.
|
||||||
*/
|
*/
|
||||||
if (virQEMUCloseCallbacksSet(driver->closeCallbacks, vm, conn,
|
if (virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
|
||||||
qemuMigrationCleanup) < 0)
|
qemuMigrationCleanup) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
if (qemuMigrationJobContinue(vm) == 0) {
|
if (qemuMigrationJobContinue(vm) == 0) {
|
||||||
vm = NULL;
|
vm = NULL;
|
||||||
@ -2750,8 +2751,8 @@ qemuMigrationConfirm(virConnectPtr conn,
|
|||||||
phase = QEMU_MIGRATION_PHASE_CONFIRM3;
|
phase = QEMU_MIGRATION_PHASE_CONFIRM3;
|
||||||
|
|
||||||
qemuMigrationJobStartPhase(driver, vm, phase);
|
qemuMigrationJobStartPhase(driver, vm, phase);
|
||||||
virQEMUCloseCallbacksUnset(driver->closeCallbacks, vm,
|
virCloseCallbacksUnset(driver->closeCallbacks, vm,
|
||||||
qemuMigrationCleanup);
|
qemuMigrationCleanup);
|
||||||
|
|
||||||
ret = qemuMigrationConfirmPhase(driver, conn, vm,
|
ret = qemuMigrationConfirmPhase(driver, conn, vm,
|
||||||
cookiein, cookieinlen,
|
cookiein, cookieinlen,
|
||||||
@ -4123,8 +4124,8 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
qemuMigrationJobStartPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3);
|
qemuMigrationJobStartPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3);
|
||||||
virQEMUCloseCallbacksUnset(driver->closeCallbacks, vm,
|
virCloseCallbacksUnset(driver->closeCallbacks, vm,
|
||||||
qemuMigrationCleanup);
|
qemuMigrationCleanup);
|
||||||
|
|
||||||
resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;
|
resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;
|
||||||
ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen,
|
ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen,
|
||||||
@ -4155,8 +4156,8 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3_DONE);
|
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3_DONE);
|
||||||
|
|
||||||
if (virQEMUCloseCallbacksSet(driver->closeCallbacks, vm, conn,
|
if (virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
|
||||||
qemuMigrationCleanup) < 0)
|
qemuMigrationCleanup) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
endjob:
|
endjob:
|
||||||
|
@ -90,10 +90,6 @@ bool qemuMigrationJobFinish(virQEMUDriverPtr driver, virDomainObjPtr obj)
|
|||||||
int qemuMigrationSetOffline(virQEMUDriverPtr driver,
|
int qemuMigrationSetOffline(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm);
|
virDomainObjPtr vm);
|
||||||
|
|
||||||
virDomainObjPtr qemuMigrationCleanup(virQEMUDriverPtr driver,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virConnectPtr conn);
|
|
||||||
|
|
||||||
char *qemuMigrationBegin(virConnectPtr conn,
|
char *qemuMigrationBegin(virConnectPtr conn,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *xmlin,
|
const char *xmlin,
|
||||||
|
@ -4470,10 +4470,11 @@ cleanup:
|
|||||||
|
|
||||||
|
|
||||||
static virDomainObjPtr
|
static virDomainObjPtr
|
||||||
qemuProcessAutoDestroy(virQEMUDriverPtr driver,
|
qemuProcessAutoDestroy(virDomainObjPtr dom,
|
||||||
virDomainObjPtr dom,
|
virConnectPtr conn,
|
||||||
virConnectPtr conn)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
virQEMUDriverPtr driver = opaque;
|
||||||
qemuDomainObjPrivatePtr priv = dom->privateData;
|
qemuDomainObjPrivatePtr priv = dom->privateData;
|
||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
|
|
||||||
@ -4517,23 +4518,23 @@ int qemuProcessAutoDestroyAdd(virQEMUDriverPtr driver,
|
|||||||
virConnectPtr conn)
|
virConnectPtr conn)
|
||||||
{
|
{
|
||||||
VIR_DEBUG("vm=%s, conn=%p", vm->def->name, conn);
|
VIR_DEBUG("vm=%s, conn=%p", vm->def->name, conn);
|
||||||
return virQEMUCloseCallbacksSet(driver->closeCallbacks, vm, conn,
|
return virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
|
||||||
qemuProcessAutoDestroy);
|
qemuProcessAutoDestroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemuProcessAutoDestroyRemove(virQEMUDriverPtr driver,
|
int qemuProcessAutoDestroyRemove(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
VIR_DEBUG("vm=%s", vm->def->name);
|
VIR_DEBUG("vm=%s", vm->def->name);
|
||||||
return virQEMUCloseCallbacksUnset(driver->closeCallbacks, vm,
|
return virCloseCallbacksUnset(driver->closeCallbacks, vm,
|
||||||
qemuProcessAutoDestroy);
|
qemuProcessAutoDestroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver,
|
bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
virQEMUCloseCallback cb;
|
virCloseCallback cb;
|
||||||
VIR_DEBUG("vm=%s", vm->def->name);
|
VIR_DEBUG("vm=%s", vm->def->name);
|
||||||
cb = virQEMUCloseCallbacksGet(driver->closeCallbacks, vm, NULL);
|
cb = virCloseCallbacksGet(driver->closeCallbacks, vm, NULL);
|
||||||
return cb == qemuProcessAutoDestroy;
|
return cb == qemuProcessAutoDestroy;
|
||||||
}
|
}
|
||||||
|
332
src/util/virclosecallbacks.c
Normal file
332
src/util/virclosecallbacks.c
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*
|
||||||
|
* virclosecallbacks.c: Connection close callbacks routines
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
* Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "viralloc.h"
|
||||||
|
#include "virclosecallbacks.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
#include "virobject.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
typedef struct _virDriverCloseDef virDriverCloseDef;
|
||||||
|
typedef virDriverCloseDef *virDriverCloseDefPtr;
|
||||||
|
struct _virDriverCloseDef {
|
||||||
|
virConnectPtr conn;
|
||||||
|
virCloseCallback cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _virCloseCallbacks {
|
||||||
|
virObjectLockable parent;
|
||||||
|
|
||||||
|
/* UUID string to qemuDriverCloseDef mapping */
|
||||||
|
virHashTablePtr list;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static virClassPtr virCloseCallbacksClass;
|
||||||
|
static void virCloseCallbacksDispose(void *obj);
|
||||||
|
|
||||||
|
static int virCloseCallbacksOnceInit(void)
|
||||||
|
{
|
||||||
|
virCloseCallbacksClass = virClassNew(virClassForObjectLockable(),
|
||||||
|
"virCloseCallbacks",
|
||||||
|
sizeof(virCloseCallbacks),
|
||||||
|
virCloseCallbacksDispose);
|
||||||
|
|
||||||
|
if (!virCloseCallbacksClass)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_ONCE_GLOBAL_INIT(virCloseCallbacks)
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virCloseCallbacksFreeData(void *payload,
|
||||||
|
const void *name ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
VIR_FREE(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
virCloseCallbacksPtr
|
||||||
|
virCloseCallbacksNew(void)
|
||||||
|
{
|
||||||
|
virCloseCallbacksPtr closeCallbacks;
|
||||||
|
|
||||||
|
if (virCloseCallbacksInitialize() < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(closeCallbacks = virObjectLockableNew(virCloseCallbacksClass)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
closeCallbacks->list = virHashCreate(5, virCloseCallbacksFreeData);
|
||||||
|
if (!closeCallbacks->list) {
|
||||||
|
virObjectUnref(closeCallbacks);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return closeCallbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
virCloseCallbacksDispose(void *obj)
|
||||||
|
{
|
||||||
|
virCloseCallbacksPtr closeCallbacks = obj;
|
||||||
|
|
||||||
|
virHashFree(closeCallbacks->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virCloseCallbacksSet(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virConnectPtr conn,
|
||||||
|
virCloseCallback cb)
|
||||||
|
{
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virDriverCloseDefPtr closeDef;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
virUUIDFormat(vm->def->uuid, uuidstr);
|
||||||
|
VIR_DEBUG("vm=%s, uuid=%s, conn=%p, cb=%p",
|
||||||
|
vm->def->name, uuidstr, conn, cb);
|
||||||
|
|
||||||
|
virObjectLock(closeCallbacks);
|
||||||
|
|
||||||
|
closeDef = virHashLookup(closeCallbacks->list, uuidstr);
|
||||||
|
if (closeDef) {
|
||||||
|
if (closeDef->conn != conn) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Close callback for domain %s already registered"
|
||||||
|
" with another connection %p"),
|
||||||
|
vm->def->name, closeDef->conn);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (closeDef->cb && closeDef->cb != cb) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Another close callback is already defined for"
|
||||||
|
" domain %s"), vm->def->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeDef->cb = cb;
|
||||||
|
} else {
|
||||||
|
if (VIR_ALLOC(closeDef) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
closeDef->conn = conn;
|
||||||
|
closeDef->cb = cb;
|
||||||
|
if (virHashAddEntry(closeCallbacks->list, uuidstr, closeDef) < 0) {
|
||||||
|
VIR_FREE(closeDef);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virObjectUnlock(closeCallbacks);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virCloseCallbacksUnset(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virCloseCallback cb)
|
||||||
|
{
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virDriverCloseDefPtr closeDef;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
virUUIDFormat(vm->def->uuid, uuidstr);
|
||||||
|
VIR_DEBUG("vm=%s, uuid=%s, cb=%p",
|
||||||
|
vm->def->name, uuidstr, cb);
|
||||||
|
|
||||||
|
virObjectLock(closeCallbacks);
|
||||||
|
|
||||||
|
closeDef = virHashLookup(closeCallbacks->list, uuidstr);
|
||||||
|
if (!closeDef)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (closeDef->cb && closeDef->cb != cb) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Trying to remove mismatching close callback for"
|
||||||
|
" domain %s"), vm->def->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = virHashRemoveEntry(closeCallbacks->list, uuidstr);
|
||||||
|
cleanup:
|
||||||
|
virObjectUnlock(closeCallbacks);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virCloseCallback
|
||||||
|
virCloseCallbacksGet(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virConnectPtr conn)
|
||||||
|
{
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virDriverCloseDefPtr closeDef;
|
||||||
|
virCloseCallback cb = NULL;
|
||||||
|
|
||||||
|
virUUIDFormat(vm->def->uuid, uuidstr);
|
||||||
|
VIR_DEBUG("vm=%s, uuid=%s, conn=%p",
|
||||||
|
vm->def->name, uuidstr, conn);
|
||||||
|
|
||||||
|
virObjectLock(closeCallbacks);
|
||||||
|
|
||||||
|
closeDef = virHashLookup(closeCallbacks->list, uuidstr);
|
||||||
|
if (closeDef && (!conn || closeDef->conn == conn))
|
||||||
|
cb = closeDef->cb;
|
||||||
|
|
||||||
|
virObjectUnlock(closeCallbacks);
|
||||||
|
|
||||||
|
VIR_DEBUG("cb=%p", cb);
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _virCloseCallbacksListEntry virCloseCallbacksListEntry;
|
||||||
|
typedef virCloseCallbacksListEntry *virCloseCallbacksListEntryPtr;
|
||||||
|
struct _virCloseCallbacksListEntry {
|
||||||
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
virCloseCallback callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _virCloseCallbacksList virCloseCallbacksList;
|
||||||
|
typedef virCloseCallbacksList *virCloseCallbacksListPtr;
|
||||||
|
struct _virCloseCallbacksList {
|
||||||
|
size_t nentries;
|
||||||
|
virCloseCallbacksListEntryPtr entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct virCloseCallbacksData {
|
||||||
|
virConnectPtr conn;
|
||||||
|
virCloseCallbacksListPtr list;
|
||||||
|
bool oom;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
virCloseCallbacksGetOne(void *payload,
|
||||||
|
const void *key,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
struct virCloseCallbacksData *data = opaque;
|
||||||
|
virDriverCloseDefPtr closeDef = payload;
|
||||||
|
const char *uuidstr = key;
|
||||||
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
|
||||||
|
if (virUUIDParse(uuidstr, uuid) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VIR_DEBUG("conn=%p, thisconn=%p, uuid=%s, cb=%p",
|
||||||
|
closeDef->conn, data->conn, uuidstr, closeDef->cb);
|
||||||
|
|
||||||
|
if (data->conn != closeDef->conn || !closeDef->cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (VIR_EXPAND_N(data->list->entries,
|
||||||
|
data->list->nentries, 1) < 0) {
|
||||||
|
data->oom = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(data->list->entries[data->list->nentries - 1].uuid,
|
||||||
|
uuid, VIR_UUID_BUFLEN);
|
||||||
|
data->list->entries[data->list->nentries - 1].callback = closeDef->cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virCloseCallbacksListPtr
|
||||||
|
virCloseCallbacksGetForConn(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virConnectPtr conn)
|
||||||
|
{
|
||||||
|
virCloseCallbacksListPtr list = NULL;
|
||||||
|
struct virCloseCallbacksData data;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(list) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
data.conn = conn;
|
||||||
|
data.list = list;
|
||||||
|
data.oom = false;
|
||||||
|
|
||||||
|
virHashForEach(closeCallbacks->list, virCloseCallbacksGetOne, &data);
|
||||||
|
|
||||||
|
if (data.oom) {
|
||||||
|
VIR_FREE(list->entries);
|
||||||
|
VIR_FREE(list);
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
virCloseCallbacksRun(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virConnectPtr conn,
|
||||||
|
virDomainObjListPtr domains,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virCloseCallbacksListPtr list;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
VIR_DEBUG("conn=%p", conn);
|
||||||
|
|
||||||
|
/* We must not hold the lock while running the callbacks,
|
||||||
|
* so first we obtain the list of callbacks, then remove
|
||||||
|
* them all from the hash. At that point we can release
|
||||||
|
* the lock and run the callbacks safely. */
|
||||||
|
|
||||||
|
virObjectLock(closeCallbacks);
|
||||||
|
list = virCloseCallbacksGetForConn(closeCallbacks, conn);
|
||||||
|
if (!list)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < list->nentries; i++) {
|
||||||
|
virHashRemoveEntry(closeCallbacks->list,
|
||||||
|
list->entries[i].uuid);
|
||||||
|
}
|
||||||
|
virObjectUnlock(closeCallbacks);
|
||||||
|
|
||||||
|
for (i = 0; i < list->nentries; i++) {
|
||||||
|
virDomainObjPtr vm;
|
||||||
|
|
||||||
|
if (!(vm = virDomainObjListFindByUUID(domains,
|
||||||
|
list->entries[i].uuid))) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(list->entries[i].uuid, uuidstr);
|
||||||
|
VIR_DEBUG("No domain object with UUID %s", uuidstr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm = list->entries[i].callback(vm, conn, opaque);
|
||||||
|
if (vm)
|
||||||
|
virObjectUnlock(vm);
|
||||||
|
}
|
||||||
|
VIR_FREE(list->entries);
|
||||||
|
VIR_FREE(list);
|
||||||
|
}
|
53
src/util/virclosecallbacks.h
Normal file
53
src/util/virclosecallbacks.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* virclosecallbacks.h: Connection close callbacks routines
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
* Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_CLOSE_CALLBACKS__
|
||||||
|
# define __VIR_CLOSE_CALLBACKS__
|
||||||
|
|
||||||
|
# include "domain_conf.h"
|
||||||
|
|
||||||
|
typedef struct _virCloseCallbacks virCloseCallbacks;
|
||||||
|
typedef virCloseCallbacks *virCloseCallbacksPtr;
|
||||||
|
|
||||||
|
typedef virDomainObjPtr (*virCloseCallback)(virDomainObjPtr vm,
|
||||||
|
virConnectPtr conn,
|
||||||
|
void *opaque);
|
||||||
|
virCloseCallbacksPtr virCloseCallbacksNew(void);
|
||||||
|
int virCloseCallbacksSet(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virConnectPtr conn,
|
||||||
|
virCloseCallback cb);
|
||||||
|
int virCloseCallbacksUnset(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virCloseCallback cb);
|
||||||
|
virCloseCallback
|
||||||
|
virCloseCallbacksGet(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virConnectPtr conn);
|
||||||
|
void
|
||||||
|
virCloseCallbacksRun(virCloseCallbacksPtr closeCallbacks,
|
||||||
|
virConnectPtr conn,
|
||||||
|
virDomainObjListPtr domains,
|
||||||
|
void *opaque);
|
||||||
|
#endif /* __VIR_CLOSE_CALLBACKS__ */
|
Loading…
Reference in New Issue
Block a user