From 37abd471656957c76eac687ce2ef94d79c8e2731 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 11 Jan 2013 13:54:15 +0000 Subject: [PATCH] Turn virDomainObjList into an opaque virObject As a step towards making virDomainObjList thread-safe turn it into an opaque virObject, preventing any direct access to its internals. As part of this a new method virDomainObjListForEach is introduced to replace all existing usage of virHashForEach --- src/conf/domain_conf.c | 70 +++++++++++++++++---- src/conf/domain_conf.h | 14 ++--- src/conf/nwfilter_conf.c | 22 +++---- src/conf/nwfilter_conf.h | 7 ++- src/libvirt_private.syms | 2 +- src/libxl/libxl_driver.c | 51 +++++++++------- src/lxc/lxc_driver.c | 9 ++- src/lxc/lxc_process.c | 28 +++++---- src/nwfilter/nwfilter_gentech_driver.c | 36 +++++------ src/nwfilter/nwfilter_gentech_driver.h | 7 ++- src/openvz/openvz_conf.c | 74 +++++++++++------------ src/parallels/parallels_driver.c | 4 +- src/parallels/parallels_storage.c | 34 +++-------- src/qemu/qemu_driver.c | 84 +++++++++++++------------- src/qemu/qemu_process.c | 15 +++-- src/test/test_driver.c | 6 +- src/uml/uml_driver.c | 29 +++++---- src/vmware/vmware_conf.c | 2 +- src/vmware/vmware_driver.c | 12 ++-- 19 files changed, 273 insertions(+), 233 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e10395851c..7830b3a824 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -58,6 +58,15 @@ * verify that it doesn't overflow an unsigned int when shifting */ verify(VIR_DOMAIN_VIRT_LAST <= 32); + +struct _virDomainObjList { + virObjectLockable parent; + + /* uuid string -> virDomainObj mapping + * for O(1), lockless lookup-by-uuid */ + virHashTable *objs; +}; + /* Private flags used internally by virDomainSaveStatus and * virDomainLoadStatus. */ typedef enum { @@ -694,7 +703,9 @@ VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode, #define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE static virClassPtr virDomainObjClass; +static virClassPtr virDomainObjListClass; static void virDomainObjDispose(void *obj); +static void virDomainObjListDispose(void *obj); static int virDomainObjOnceInit(void) { @@ -704,6 +715,12 @@ static int virDomainObjOnceInit(void) virDomainObjDispose))) return -1; + if (!(virDomainObjListClass = virClassNew(virClassForObjectLockable(), + "virDomainObjList", + sizeof(virDomainObjList), + virDomainObjListDispose))) + return -1; + return 0; } @@ -780,26 +797,26 @@ virDomainObjListPtr virDomainObjListNew(void) { virDomainObjListPtr doms; - if (VIR_ALLOC(doms) < 0) { - virReportOOMError(); + if (virDomainObjInitialize() < 0) + return NULL; + + if (!(doms = virObjectLockableNew(virDomainObjListClass))) + return NULL; + + if (!(doms->objs = virHashCreate(50, virDomainObjListDataFree))) { + virObjectUnref(doms); return NULL; } - doms->objs = virHashCreate(50, virDomainObjListDataFree); - if (!doms->objs) { - VIR_FREE(doms); - return NULL; - } return doms; } -void virDomainObjListFree(virDomainObjListPtr doms) +static void virDomainObjListDispose(void *obj) { - if (!doms) - return; + virDomainObjListPtr doms = obj; + virHashFree(doms->objs); - VIR_FREE(doms); } @@ -15231,6 +15248,37 @@ cleanup: return -1; } + +struct virDomainListIterData { + virDomainObjListIterator callback; + void *opaque; + int ret; +}; + +static void +virDomainObjListHelper(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + struct virDomainListIterData *data = opaque; + + if (data->callback(payload, data->opaque) < 0) + data->ret = -1; +} + +int virDomainObjListForEach(virDomainObjListPtr doms, + virDomainObjListIterator callback, + void *opaque) +{ + struct virDomainListIterData data = { + callback, opaque, 0, + }; + virHashForEach(doms->objs, virDomainObjListHelper, &data); + + return data.ret; +} + + int virDomainChrDefForeach(virDomainDefPtr def, bool abortOnError, virDomainChrDefIterator iter, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index fab04a201b..3ad117344a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -37,7 +37,6 @@ # include "virhash.h" # include "virsocketaddr.h" # include "nwfilter_params.h" -# include "nwfilter_conf.h" # include "virnetdevmacvlan.h" # include "virsysinfo.h" # include "virnetdevvportprofile.h" @@ -1893,11 +1892,6 @@ struct _virDomainObj { typedef struct _virDomainObjList virDomainObjList; typedef virDomainObjList *virDomainObjListPtr; -struct _virDomainObjList { - /* uuid string -> virDomainObj mapping - * for O(1), lockless lookup-by-uuid */ - virHashTable *objs; -}; static inline bool virDomainObjIsActive(virDomainObjPtr dom) @@ -1908,7 +1902,6 @@ virDomainObjIsActive(virDomainObjPtr dom) virDomainObjPtr virDomainObjNew(virCapsPtr caps); virDomainObjListPtr virDomainObjListNew(void); -void virDomainObjListFree(virDomainObjListPtr objs); virDomainObjPtr virDomainObjListFindByID(const virDomainObjListPtr doms, int id); @@ -2176,6 +2169,13 @@ int virDomainObjListGetInactiveNames(virDomainObjListPtr doms, char **const names, int maxnames); +typedef int (*virDomainObjListIterator)(virDomainObjPtr dom, + void *opaque); + +int virDomainObjListForEach(virDomainObjListPtr doms, + virDomainObjListIterator callback, + void *opaque); + typedef int (*virDomainSmartcardDefIterator)(virDomainDefPtr def, virDomainSmartcardDefPtr dev, void *opaque); diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index ca22411634..e63a04b52a 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -2867,7 +2867,7 @@ virNWFilterCallbackDriversUnlock(void) } -static virHashIterator virNWFilterDomainFWUpdateCB; +static virDomainObjListIterator virNWFilterDomainFWUpdateCB; /** * virNWFilterInstFiltersOnAllVMs: @@ -2880,7 +2880,6 @@ virNWFilterInstFiltersOnAllVMs(virConnectPtr conn) int i; struct domUpdateCBStruct cb = { .conn = conn, - .err = 0, /* ignored here */ .step = STEP_APPLY_CURRENT, .skipInterfaces = NULL, /* not needed */ }; @@ -2897,10 +2896,9 @@ static int virNWFilterTriggerVMFilterRebuild(virConnectPtr conn) { int i; - int err; + int ret = 0; struct domUpdateCBStruct cb = { .conn = conn, - .err = 0, .step = STEP_APPLY_NEW, .skipInterfaces = virHashCreate(0, NULL), }; @@ -2909,16 +2907,14 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn) return -1; for (i = 0; i < nCallbackDriver; i++) { - callbackDrvArray[i]->vmFilterRebuild(conn, - virNWFilterDomainFWUpdateCB, - &cb); + if (callbackDrvArray[i]->vmFilterRebuild(conn, + virNWFilterDomainFWUpdateCB, + &cb) < 0) + ret = -1; } - err = cb.err; - - if (err) { + if (ret < 0) { cb.step = STEP_TEAR_NEW; /* rollback */ - cb.err = 0; for (i = 0; i < nCallbackDriver; i++) callbackDrvArray[i]->vmFilterRebuild(conn, @@ -2935,7 +2931,7 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn) virHashFree(cb.skipInterfaces); - return err; + return ret; } @@ -3503,7 +3499,7 @@ char *virNWFilterConfigFile(const char *dir, } -int virNWFilterConfLayerInit(virHashIterator domUpdateCB) +int virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB) { virNWFilterDomainFWUpdateCB = domUpdateCB; diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 35f8ddec78..48998ec7f0 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -34,6 +34,7 @@ # include "virbuffer.h" # include "virsocketaddr.h" # include "virmacaddr.h" +# include "domain_conf.h" /* XXX * The config parser/structs should not be using platform specific @@ -588,7 +589,6 @@ enum UpdateStep { struct domUpdateCBStruct { virConnectPtr conn; enum UpdateStep step; - int err; virHashTablePtr skipInterfaces; }; @@ -725,14 +725,15 @@ void virNWFilterObjUnlock(virNWFilterObjPtr obj); void virNWFilterLockFilterUpdates(void); void virNWFilterUnlockFilterUpdates(void); -int virNWFilterConfLayerInit(virHashIterator domUpdateCB); +int virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB); void virNWFilterConfLayerShutdown(void); int virNWFilterInstFiltersOnAllVMs(virConnectPtr conn); typedef int (*virNWFilterRebuild)(virConnectPtr conn, - virHashIterator, void *data); + virDomainObjListIterator domUpdateCB, + void *data); typedef void (*virNWFilterVoidCall)(void); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1fbcb95757..afa2b5e680 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -476,7 +476,7 @@ virDomainObjListExport; virDomainObjListFindByID; virDomainObjListFindByName; virDomainObjListFindByUUID; -virDomainObjListFree; +virDomainObjListForEach; virDomainObjListGetActiveIDs; virDomainObjListGetInactiveNames; virDomainObjListIsDuplicate; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index b6dce0dcfa..1ce305771c 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -98,12 +98,12 @@ struct _libxlEventHookInfo { }; static virClassPtr libxlDomainObjPrivateClass; + static libxlDriverPrivatePtr libxl_driver = NULL; /* Function declarations */ -static void -libxlDomainManagedSaveLoad(void *payload, - const void *n ATTRIBUTE_UNUSED, +static int +libxlDomainManagedSaveLoad(virDomainObjPtr vm, void *opaque); static int @@ -433,13 +433,13 @@ libxlDomainEventQueue(libxlDriverPrivatePtr driver, virDomainEventPtr event) virDomainEventStateQueue(driver->domainEventState, event); } -static void -libxlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, +static int +libxlAutostartDomain(virDomainObjPtr vm, void *opaque) { libxlDriverPrivatePtr driver = opaque; - virDomainObjPtr vm = payload; virErrorPtr err; + int ret = -1; virObjectLock(vm); virResetLastError(); @@ -450,10 +450,14 @@ libxlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, VIR_ERROR(_("Failed to autostart VM '%s': %s"), vm->def->name, err ? err->message : _("unknown error")); + goto cleanup; } + ret = 0; +cleanup: if (vm) virObjectUnlock(vm); + return ret; } static int @@ -1005,12 +1009,10 @@ error: * Reconnect to running domains that were previously started/created * with libxenlight driver. */ -static void -libxlReconnectDomain(void *payload, - const void *name ATTRIBUTE_UNUSED, +static int +libxlReconnectDomain(virDomainObjPtr vm, void *opaque) { - virDomainObjPtr vm = payload; libxlDriverPrivatePtr driver = opaque; int rc; libxl_dominfo d_info; @@ -1047,7 +1049,7 @@ libxlReconnectDomain(void *payload, /* Recreate domain death et. al. events */ libxlCreateDomEvents(vm); virObjectUnlock(vm); - return; + return 0; out: libxlVmCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_UNKNOWN); @@ -1055,12 +1057,14 @@ out: virDomainObjListRemove(driver->domains, vm); else virObjectUnlock(vm); + + return -1; } static void libxlReconnectDomains(libxlDriverPrivatePtr driver) { - virHashForEach(driver->domains->objs, libxlReconnectDomain, driver); + virDomainObjListForEach(driver->domains, libxlReconnectDomain, driver); } static int @@ -1071,7 +1075,7 @@ libxlShutdown(void) libxlDriverLock(libxl_driver); virCapabilitiesFree(libxl_driver->caps); - virDomainObjListFree(libxl_driver->domains); + virObjectUnref(libxl_driver->domains); libxl_ctx_free(libxl_driver->ctx); xtl_logger_destroy(libxl_driver->logger); if (libxl_driver->logger_file) @@ -1252,11 +1256,11 @@ libxlStartup(bool privileged, NULL, NULL) < 0) goto error; - virHashForEach(libxl_driver->domains->objs, libxlAutostartDomain, - libxl_driver); + virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain, + libxl_driver); - virHashForEach(libxl_driver->domains->objs, libxlDomainManagedSaveLoad, - libxl_driver); + virDomainObjListForEach(libxl_driver->domains, libxlDomainManagedSaveLoad, + libxl_driver); libxlDriverUnlock(libxl_driver); @@ -1288,8 +1292,8 @@ libxlReload(void) 1, 1 << VIR_DOMAIN_VIRT_XEN, NULL, libxl_driver); - virHashForEach(libxl_driver->domains->objs, libxlAutostartDomain, - libxl_driver); + virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain, + libxl_driver); libxlDriverUnlock(libxl_driver); @@ -2406,14 +2410,13 @@ cleanup: return ret; } -static void -libxlDomainManagedSaveLoad(void *payload, - const void *n ATTRIBUTE_UNUSED, +static int +libxlDomainManagedSaveLoad(virDomainObjPtr vm, void *opaque) { - virDomainObjPtr vm = payload; libxlDriverPrivatePtr driver = opaque; char *name; + int ret = -1; virObjectLock(vm); @@ -2422,9 +2425,11 @@ libxlDomainManagedSaveLoad(void *payload, vm->hasManagedSave = virFileExists(name); + ret = 0; cleanup: virObjectUnlock(vm); VIR_FREE(name); + return ret; } static int diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 361182103c..9dbab67cc8 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -58,6 +58,7 @@ #include "fdstream.h" #include "domain_audit.h" #include "domain_nwfilter.h" +#include "nwfilter_conf.h" #include "network/bridge_driver.h" #include "virinitctl.h" #include "virnetdev.h" @@ -82,11 +83,9 @@ virLXCDriverPtr lxc_driver = NULL; /* callbacks for nwfilter */ static int lxcVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED, - virHashIterator iter, void *data) + virDomainObjListIterator iter, void *data) { - virHashForEach(lxc_driver->domains->objs, iter, data); - - return 0; + return virDomainObjListForEach(lxc_driver->domains, iter, data); } static void @@ -1556,7 +1555,7 @@ static int lxcShutdown(void) lxcDriverLock(lxc_driver); virNWFilterUnRegisterCallbackDriver(&lxcCallbackDriver); - virDomainObjListFree(lxc_driver->domains); + virObjectUnref(lxc_driver->domains); virDomainEventStateFree(lxc_driver->domainEventState); virLXCProcessAutoDestroyShutdown(lxc_driver); diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 0c943ea578..aaa81a7837 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1246,17 +1246,18 @@ struct virLXCProcessAutostartData { virConnectPtr conn; }; -static void -virLXCProcessAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) +static int +virLXCProcessAutostartDomain(virDomainObjPtr vm, + void *opaque) { - virDomainObjPtr vm = payload; const struct virLXCProcessAutostartData *data = opaque; + int ret = 0; virObjectLock(vm); if (vm->autostart && !virDomainObjIsActive(vm)) { - int ret = virLXCProcessStart(data->conn, data->driver, vm, false, - VIR_DOMAIN_RUNNING_BOOTED); + ret = virLXCProcessStart(data->conn, data->driver, vm, false, + VIR_DOMAIN_RUNNING_BOOTED); virDomainAuditStart(vm, "booted", ret >= 0); if (ret < 0) { virErrorPtr err = virGetLastError(); @@ -1273,6 +1274,7 @@ virLXCProcessAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, v } } virObjectUnlock(vm); + return ret; } @@ -1290,19 +1292,22 @@ virLXCProcessAutostartAll(virLXCDriverPtr driver) struct virLXCProcessAutostartData data = { driver, conn }; lxcDriverLock(driver); - virHashForEach(driver->domains->objs, virLXCProcessAutostartDomain, &data); + virDomainObjListForEach(driver->domains, + virLXCProcessAutostartDomain, + &data); lxcDriverUnlock(driver); if (conn) virConnectClose(conn); } -static void -virLXCProcessReconnectDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) +static int +virLXCProcessReconnectDomain(virDomainObjPtr vm, + void *opaque) { - virDomainObjPtr vm = payload; virLXCDriverPtr driver = opaque; virLXCDomainObjPrivatePtr priv; + int ret = -1; virObjectLock(vm); VIR_DEBUG("Reconnect id=%d pid=%d state=%d", vm->def->id, vm->pid, vm->state.state); @@ -1346,9 +1351,10 @@ virLXCProcessReconnectDomain(void *payload, const void *name ATTRIBUTE_UNUSED, v vm->def->id = -1; } + ret = 0; cleanup: virObjectUnlock(vm); - return; + return ret; error: virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED); @@ -1360,6 +1366,6 @@ error: int virLXCProcessReconnectAll(virLXCDriverPtr driver, virDomainObjListPtr doms) { - virHashForEach(doms->objs, virLXCProcessReconnectDomain, driver); + virDomainObjListForEach(doms, virLXCProcessReconnectDomain, driver); return 0; } diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 8508f06281..958f47a0c2 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -1150,16 +1150,15 @@ virNWFilterTeardownFilter(const virDomainNetDefPtr net) } -void -virNWFilterDomainFWUpdateCB(void *payload, - const void *name ATTRIBUTE_UNUSED, +int +virNWFilterDomainFWUpdateCB(virDomainObjPtr obj, void *data) { - virDomainObjPtr obj = payload; virDomainDefPtr vm = obj->def; struct domUpdateCBStruct *cb = data; - int i, err; + int i; bool skipIface; + int ret = 0; virObjectLock(obj); @@ -1169,45 +1168,46 @@ virNWFilterDomainFWUpdateCB(void *payload, if ((net->filter) && (net->ifname)) { switch (cb->step) { case STEP_APPLY_NEW: - cb->err = virNWFilterUpdateInstantiateFilter(cb->conn, - vm->uuid, - net, - &skipIface); - if (cb->err == 0 && skipIface) { + ret = virNWFilterUpdateInstantiateFilter(cb->conn, + vm->uuid, + net, + &skipIface); + if (ret == 0 && skipIface) { /* filter tree unchanged -- no update needed */ - cb->err = virHashAddEntry(cb->skipInterfaces, - net->ifname, - (void *)~0); + ret = virHashAddEntry(cb->skipInterfaces, + net->ifname, + (void *)~0); } break; case STEP_TEAR_NEW: if (!virHashLookup(cb->skipInterfaces, net->ifname)) { - cb->err = virNWFilterRollbackUpdateFilter(net); + ret = virNWFilterRollbackUpdateFilter(net); } break; case STEP_TEAR_OLD: if (!virHashLookup(cb->skipInterfaces, net->ifname)) { - cb->err = virNWFilterTearOldFilter(net); + ret = virNWFilterTearOldFilter(net); } break; case STEP_APPLY_CURRENT: - err = virNWFilterInstantiateFilter(cb->conn, + ret = virNWFilterInstantiateFilter(cb->conn, vm->uuid, net); - if (err) + if (ret) virReportError(VIR_ERR_INTERNAL_ERROR, _("Failure while applying current filter on " "VM %s"), vm->name); break; } - if (cb->err) + if (ret) break; } } } virObjectUnlock(obj); + return ret; } diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h index a632ca624a..4b47b4a706 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -23,6 +23,8 @@ #ifndef __NWFILTER_GENTECH_DRIVER_H # define __NWFILTER_GENTECH_DRIVER_H +# include "nwfilter_conf.h" + virNWFilterTechDriverPtr virNWFilterTechDriverForName(const char *name); int virNWFilterRuleInstAddData(virNWFilterRuleInstPtr res, @@ -60,8 +62,7 @@ int virNWFilterTeardownFilter(const virDomainNetDefPtr net); virNWFilterHashTablePtr virNWFilterCreateVarHashmap(char *macaddr, const virNWFilterVarValuePtr); -void virNWFilterDomainFWUpdateCB(void *payload, - const void *name, - void *data); +int virNWFilterDomainFWUpdateCB(virDomainObjPtr vm, + void *data); #endif diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 46f30ca6a6..8752d98611 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -558,7 +558,7 @@ openvzFreeDriver(struct openvz_driver *driver) if (!driver) return; - virDomainObjListFree(driver->domains); + virObjectUnref(driver->domains); virCapabilitiesFree(driver->caps); VIR_FREE(driver); } @@ -570,6 +570,7 @@ int openvzLoadDomains(struct openvz_driver *driver) { char *status; char uuidstr[VIR_UUID_STRING_BUFLEN]; virDomainObjPtr dom = NULL; + virDomainDefPtr def = NULL; char *temp = NULL; char *outbuf = NULL; char *line; @@ -594,35 +595,20 @@ int openvzLoadDomains(struct openvz_driver *driver) { } *line++ = '\0'; - if (!(dom = virDomainObjNew(driver->caps))) - goto cleanup; - - if (VIR_ALLOC(dom->def) < 0) + if (VIR_ALLOC(def) < 0) goto no_memory; - dom->def->virtType = VIR_DOMAIN_VIRT_OPENVZ; + def->virtType = VIR_DOMAIN_VIRT_OPENVZ; - if (STREQ(status, "stopped")) { - virDomainObjSetState(dom, VIR_DOMAIN_SHUTOFF, - VIR_DOMAIN_SHUTOFF_UNKNOWN); - } else { - virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, - VIR_DOMAIN_RUNNING_UNKNOWN); - } - - dom->pid = veid; - if (virDomainObjGetState(dom, NULL) == VIR_DOMAIN_SHUTOFF) - dom->def->id = -1; + if (STREQ(status, "stopped")) + def->id = -1; else - dom->def->id = veid; - /* XXX OpenVZ doesn't appear to have concept of a transient domain */ - dom->persistent = 1; - - if (virAsprintf(&dom->def->name, "%i", veid) < 0) + def->id = veid; + if (virAsprintf(&def->name, "%i", veid) < 0) goto no_memory; openvzGetVPSUUID(veid, uuidstr, sizeof(uuidstr)); - ret = virUUIDParse(uuidstr, dom->def->uuid); + ret = virUUIDParse(uuidstr, def->uuid); if (ret == -1) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -630,9 +616,9 @@ int openvzLoadDomains(struct openvz_driver *driver) { goto cleanup; } - if (!(dom->def->os.type = strdup("exe"))) + if (!(def->os.type = strdup("exe"))) goto no_memory; - if (!(dom->def->os.init = strdup("/sbin/init"))) + if (!(def->os.init = strdup("/sbin/init"))) goto no_memory; ret = openvzReadVPSConfigParam(veid, "CPUS", &temp); @@ -642,35 +628,48 @@ int openvzLoadDomains(struct openvz_driver *driver) { veid); goto cleanup; } else if (ret > 0) { - dom->def->maxvcpus = strtoI(temp); + def->maxvcpus = strtoI(temp); } - if (ret == 0 || dom->def->maxvcpus == 0) - dom->def->maxvcpus = openvzGetNodeCPUs(); - dom->def->vcpus = dom->def->maxvcpus; + if (ret == 0 || def->maxvcpus == 0) + def->maxvcpus = openvzGetNodeCPUs(); + def->vcpus = def->maxvcpus; /* XXX load rest of VM config data .... */ - openvzReadNetworkConf(dom->def, veid); - openvzReadFSConf(dom->def, veid); - openvzReadMemConf(dom->def, veid); + openvzReadNetworkConf(def, veid); + openvzReadFSConf(def, veid); + openvzReadMemConf(def, veid); - virUUIDFormat(dom->def->uuid, uuidstr); - if (virHashLookup(driver->domains->objs, uuidstr)) { + virUUIDFormat(def->uuid, uuidstr); + if (virDomainObjListIsDuplicate(driver->domains, def, true)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Duplicate container UUID %s detected for %d"), uuidstr, veid); goto cleanup; } - if (virHashAddEntry(driver->domains->objs, uuidstr, dom) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not add UUID for container %d"), veid); + if (!(dom = virDomainObjListAdd(driver->domains, + driver->caps, + def, + STRNEQ(status, "stopped")))) goto cleanup; + + if (STREQ(status, "stopped")) { + virDomainObjSetState(dom, VIR_DOMAIN_SHUTOFF, + VIR_DOMAIN_SHUTOFF_UNKNOWN); + dom->pid = -1; + } else { + virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNKNOWN); + dom->pid = veid; } + /* XXX OpenVZ doesn't appear to have concept of a transient domain */ + dom->persistent = 1; virObjectUnlock(dom); dom = NULL; + def = NULL; } virCommandFree(cmd); @@ -687,6 +686,7 @@ int openvzLoadDomains(struct openvz_driver *driver) { VIR_FREE(temp); VIR_FREE(outbuf); virObjectUnref(dom); + virDomainDefFree(def); return -1; } diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index 6f3e9951ff..bc05a512e2 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -940,7 +940,7 @@ parallelsOpenDefault(virConnectPtr conn) return VIR_DRV_OPEN_SUCCESS; error: - virDomainObjListFree(privconn->domains); + virObjectUnref(privconn->domains); virCapabilitiesFree(privconn->caps); virStoragePoolObjListFree(&privconn->pools); VIR_FREE(privconn); @@ -987,7 +987,7 @@ parallelsClose(virConnectPtr conn) parallelsDriverLock(privconn); virCapabilitiesFree(privconn->caps); - virDomainObjListFree(privconn->domains); + virObjectUnref(privconn->domains); conn->privateData = NULL; parallelsDriverUnlock(privconn); diff --git a/src/parallels/parallels_storage.c b/src/parallels/parallels_storage.c index 612168e375..1186296348 100644 --- a/src/parallels/parallels_storage.c +++ b/src/parallels/parallels_storage.c @@ -122,11 +122,6 @@ cleanup: } -struct parallelsPoolsAddData { - virConnectPtr conn; - bool failed; -}; - /* * Generate unique pool name by path */ @@ -404,26 +399,20 @@ cleanup: } -static void -parallelsPoolsAdd(void *payload, - const void *name ATTRIBUTE_UNUSED, +static int +parallelsPoolsAdd(virDomainObjPtr dom, void *opaque) { - struct parallelsPoolsAddData *data = (struct parallelsPoolsAddData *)opaque; - virDomainObjPtr dom = payload; + virConnectPtr conn = opaque; virStoragePoolObjPtr pool; - if (!(pool = parallelsPoolAddByDomain(data->conn, dom))) { - data->failed = true; - return; - } + if (!(pool = parallelsPoolAddByDomain(conn, dom))) + return -1; - if (parallelsFindVmVolumes(pool, dom)) { - data->failed = true; - return; - } + if (parallelsFindVmVolumes(pool, dom)) + return -1; - return; + return 0; } static int parallelsLoadPools(virConnectPtr conn) @@ -432,7 +421,6 @@ static int parallelsLoadPools(virConnectPtr conn) virStorageDriverStatePtr storageState = conn->storagePrivateData; char *base = NULL; size_t i; - struct parallelsPoolsAddData data; if ((base = strdup(SYSCONFDIR "/libvirt")) == NULL) goto out_of_memory; @@ -456,11 +444,7 @@ static int parallelsLoadPools(virConnectPtr conn) goto error; } - data.conn = conn; - data.failed = false; - virHashForEach(privconn->domains->objs, parallelsPoolsAdd, &data); - - if (data.failed) + if (virDomainObjListForEach(privconn->domains, parallelsPoolsAdd, conn) < 0) goto error; for (i = 0; i < privconn->pools.count; i++) { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 264a146902..8481dc2d75 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -79,6 +79,7 @@ #include "cpu/cpu.h" #include "virsysinfo.h" #include "domain_nwfilter.h" +#include "nwfilter_conf.h" #include "virhook.h" #include "virstoragefile.h" #include "virfile.h" @@ -144,9 +145,8 @@ static int qemuDomainObjStart(virConnectPtr conn, static int qemuDomainGetMaxVcpus(virDomainPtr dom); -static void qemuDomainManagedSaveLoad(void *payload, - const void *n ATTRIBUTE_UNUSED, - void *opaque); +static int qemuDomainManagedSaveLoad(virDomainObjPtr vm, + void *opaque); virQEMUDriverPtr qemu_driver = NULL; @@ -166,11 +166,9 @@ qemuVMDriverUnlock(void) { static int qemuVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED, - virHashIterator iter, void *data) + virDomainObjListIterator iter, void *data) { - virHashForEach(qemu_driver->domains->objs, iter, data); - - return 0; + return virDomainObjListForEach(qemu_driver->domains, iter, data); } static virNWFilterCallbackDriver qemuCallbackDriver = { @@ -278,15 +276,15 @@ qemuSnapObjFromSnapshot(virDomainObjPtr vm, return qemuSnapObjFromName(vm, snapshot->name); } -static void -qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, +static int +qemuAutostartDomain(virDomainObjPtr vm, void *opaque) { - virDomainObjPtr vm = payload; struct qemuAutostartData *data = opaque; virErrorPtr err; int flags = 0; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(data->driver); + int ret = -1; if (cfg->autoStartBypassCache) flags |= VIR_DOMAIN_START_BYPASS_CACHE; @@ -315,10 +313,12 @@ qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, vm = NULL; } + ret = 0; cleanup: if (vm) virObjectUnlock(vm); virObjectUnref(cfg); + return ret; } @@ -336,7 +336,7 @@ qemuAutostartDomains(virQEMUDriverPtr driver) struct qemuAutostartData data = { driver, conn }; qemuDriverLock(driver); - virHashForEach(driver->domains->objs, qemuAutostartDomain, &data); + virDomainObjListForEach(driver->domains, qemuAutostartDomain, &data); qemuDriverUnlock(driver); if (conn) @@ -489,18 +489,15 @@ err_exit: } -static void -qemuDomainSnapshotLoad(void *payload, - const void *name ATTRIBUTE_UNUSED, +static int +qemuDomainSnapshotLoad(virDomainObjPtr vm, void *data) { - virDomainObjPtr vm = (virDomainObjPtr)payload; char *baseDir = (char *)data; char *snapDir = NULL; DIR *dir = NULL; struct dirent *entry; char *xmlStr; - int ret; char *fullpath; virDomainSnapshotDefPtr def = NULL; virDomainSnapshotObjPtr snap = NULL; @@ -509,6 +506,7 @@ qemuDomainSnapshotLoad(void *payload, unsigned int flags = (VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE | VIR_DOMAIN_SNAPSHOT_PARSE_DISKS | VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL); + int ret = -1; virObjectLock(vm); if (virAsprintf(&snapDir, "%s/%s", baseDir, vm->def->name) < 0) { @@ -541,8 +539,7 @@ qemuDomainSnapshotLoad(void *payload, continue; } - ret = virFileReadAll(fullpath, 1024*1024*1, &xmlStr); - if (ret < 0) { + if (virFileReadAll(fullpath, 1024*1024*1, &xmlStr) < 0) { /* Nothing we can do here, skip this one */ VIR_ERROR(_("Failed to read snapshot file %s: %s"), fullpath, virStrerror(errno, ebuf, sizeof(ebuf))); @@ -596,21 +593,21 @@ qemuDomainSnapshotLoad(void *payload, virResetLastError(); + ret = 0; cleanup: if (dir) closedir(dir); VIR_FREE(snapDir); virObjectUnlock(vm); + return ret; } -static void -qemuDomainNetsRestart(void *payload, - const void *name ATTRIBUTE_UNUSED, +static int +qemuDomainNetsRestart(virDomainObjPtr vm, void *data ATTRIBUTE_UNUSED) { int i; - virDomainObjPtr vm = (virDomainObjPtr)payload; virDomainDefPtr def = vm->def; virObjectLock(vm); @@ -631,19 +628,20 @@ qemuDomainNetsRestart(void *payload, } virObjectUnlock(vm); + return 0; } -static void -qemuDomainFindMaxID(void *payload, - const void *name ATTRIBUTE_UNUSED, +static int +qemuDomainFindMaxID(virDomainObjPtr vm, void *data) { - virDomainObjPtr vm = payload; int *driver_maxid = data; if (vm->def->id >= *driver_maxid) *driver_maxid = vm->def->id + 1; + + return 0; } @@ -874,11 +872,13 @@ qemuStartup(bool privileged, /* find the maximum ID from active and transient configs to initialize * the driver with. This is to avoid race between autostart and reconnect * threads */ - virHashForEach(qemu_driver->domains->objs, - qemuDomainFindMaxID, - &qemu_driver->nextvmid); + virDomainObjListForEach(qemu_driver->domains, + qemuDomainFindMaxID, + &qemu_driver->nextvmid); - virHashForEach(qemu_driver->domains->objs, qemuDomainNetsRestart, NULL); + virDomainObjListForEach(qemu_driver->domains, + qemuDomainNetsRestart, + NULL); conn = virConnectOpen(cfg->uri); @@ -894,13 +894,13 @@ qemuStartup(bool privileged, goto error; - virHashForEach(qemu_driver->domains->objs, - qemuDomainSnapshotLoad, - cfg->snapshotDir); + virDomainObjListForEach(qemu_driver->domains, + qemuDomainSnapshotLoad, + cfg->snapshotDir); - virHashForEach(qemu_driver->domains->objs, - qemuDomainManagedSaveLoad, - qemu_driver); + virDomainObjListForEach(qemu_driver->domains, + qemuDomainManagedSaveLoad, + qemu_driver); qemu_driver->workerPool = virThreadPoolNew(0, 1, 0, processWatchdogEvent, qemu_driver); if (!qemu_driver->workerPool) @@ -1054,7 +1054,7 @@ qemuShutdown(void) { virCapabilitiesFree(qemu_driver->caps); qemuCapsCacheFree(qemu_driver->capsCache); - virDomainObjListFree(qemu_driver->domains); + virObjectUnref(qemu_driver->domains); virObjectUnref(qemu_driver->remotePorts); virSysinfoDefFree(qemu_driver->hostsysinfo); @@ -3128,14 +3128,13 @@ cleanup: return ret; } -static void -qemuDomainManagedSaveLoad(void *payload, - const void *n ATTRIBUTE_UNUSED, +static int +qemuDomainManagedSaveLoad(virDomainObjPtr vm, void *opaque) { - virDomainObjPtr vm = payload; virQEMUDriverPtr driver = opaque; char *name; + int ret = -1; virObjectLock(vm); @@ -3144,11 +3143,14 @@ qemuDomainManagedSaveLoad(void *payload, vm->hasManagedSave = virFileExists(name); + ret = 0; cleanup: virObjectUnlock(vm); VIR_FREE(name); + return ret; } + static int qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) { diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fff7e46440..9c777ce140 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3353,23 +3353,21 @@ error: virObjectUnref(cfg); } -static void -qemuProcessReconnectHelper(void *payload, - const void *name ATTRIBUTE_UNUSED, +static int +qemuProcessReconnectHelper(virDomainObjPtr obj, void *opaque) { virThread thread; struct qemuProcessReconnectData *src = opaque; struct qemuProcessReconnectData *data; - virDomainObjPtr obj = payload; if (VIR_ALLOC(data) < 0) { virReportOOMError(); - return; + return -1; } memcpy(data, src, sizeof(*data)); - data->payload = payload; + data->payload = obj; /* This iterator is called with driver being locked. * We create a separate thread to run qemuProcessReconnect in it. @@ -3430,10 +3428,11 @@ qemuProcessReconnectHelper(void *payload, virObjectUnlock(obj); - return; + return 0; error: VIR_FREE(data); + return -1; } /** @@ -3446,7 +3445,7 @@ void qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver) { struct qemuProcessReconnectData data = {.conn = conn, .driver = driver}; - virHashForEach(driver->domains->objs, qemuProcessReconnectHelper, &data); + virDomainObjListForEach(driver->domains, qemuProcessReconnectHelper, &data); } int diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 505570f1c9..cd47862ae9 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -646,7 +646,7 @@ static int testOpenDefault(virConnectPtr conn) { return VIR_DRV_OPEN_SUCCESS; error: - virDomainObjListFree(privconn->domains); + virObjectUnref(privconn->domains); virNetworkObjListFree(&privconn->networks); virInterfaceObjListFree(&privconn->ifaces); virStoragePoolObjListFree(&privconn->pools); @@ -1115,7 +1115,7 @@ static int testOpenFromFile(virConnectPtr conn, VIR_FREE(ifaces); VIR_FREE(pools); VIR_FREE(devs); - virDomainObjListFree(privconn->domains); + virObjectUnref(privconn->domains); virNetworkObjListFree(&privconn->networks); virInterfaceObjListFree(&privconn->ifaces); virStoragePoolObjListFree(&privconn->pools); @@ -1184,7 +1184,7 @@ static int testClose(virConnectPtr conn) testConnPtr privconn = conn->privateData; testDriverLock(privconn); virCapabilitiesFree(privconn->caps); - virDomainObjListFree(privconn->domains); + virObjectUnref(privconn->domains); virNodeDeviceObjListFree(&privconn->devs); virNetworkObjListFree(&privconn->networks); virInterfaceObjListFree(&privconn->ifaces); diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 591d3e4ad6..27f5118734 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -58,6 +58,7 @@ #include "datatypes.h" #include "virlog.h" #include "domain_nwfilter.h" +#include "nwfilter_conf.h" #include "virfile.h" #include "fdstream.h" #include "configmake.h" @@ -148,11 +149,9 @@ static struct uml_driver *uml_driver = NULL; static int umlVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED, - virHashIterator iter, void *data) + virDomainObjListIterator iter, void *data) { - virHashForEach(uml_driver->domains->objs, iter, data); - - return 0; + return virDomainObjListForEach(uml_driver->domains, iter, data); } static void @@ -179,16 +178,15 @@ struct umlAutostartData { virConnectPtr conn; }; -static void -umlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) +static int +umlAutostartDomain(virDomainObjPtr vm, + void *opaque) { - virDomainObjPtr vm = payload; const struct umlAutostartData *data = opaque; - + int ret = 0; virObjectLock(vm); if (vm->autostart && !virDomainObjIsActive(vm)) { - int ret; virResetLastError(); ret = umlStartVMDaemon(data->conn, data->driver, vm, false); virDomainAuditStart(vm, "booted", ret >= 0); @@ -206,6 +204,7 @@ umlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu } } virObjectUnlock(vm); + return ret; } static void @@ -223,7 +222,7 @@ umlAutostartConfigs(struct uml_driver *driver) { struct umlAutostartData data = { driver, conn }; umlDriverLock(driver); - virHashForEach(driver->domains->objs, umlAutostartDomain, &data); + virDomainObjListForEach(driver->domains, umlAutostartDomain, &data); umlDriverUnlock(driver); if (conn) @@ -602,10 +601,9 @@ umlReload(void) { } -static void -umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) +static int +umlShutdownOneVM(virDomainObjPtr dom, void *opaque) { - virDomainObjPtr dom = payload; struct uml_driver *driver = opaque; virObjectLock(dom); @@ -614,6 +612,7 @@ umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) virDomainAuditStop(dom, "shutdown"); } virObjectUnlock(dom); + return 0; } /** @@ -635,9 +634,9 @@ umlShutdown(void) { /* shutdown active VMs * XXX allow them to stay around & reconnect */ - virHashForEach(uml_driver->domains->objs, umlShutdownOneVM, uml_driver); + virDomainObjListForEach(uml_driver->domains, umlShutdownOneVM, uml_driver); - virDomainObjListFree(uml_driver->domains); + virObjectUnref(uml_driver->domains); virDomainEventStateFree(uml_driver->domainEventState); diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c index d2afce3226..b616c1bc35 100644 --- a/src/vmware/vmware_conf.c +++ b/src/vmware/vmware_conf.c @@ -43,7 +43,7 @@ vmwareFreeDriver(struct vmware_driver *driver) return; virMutexDestroy(&driver->lock); - virDomainObjListFree(driver->domains); + virObjectUnref(driver->domains); virCapabilitiesFree(driver->caps); VIR_FREE(driver); } diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 3b2d1e57a6..b99fca3d8f 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -946,19 +946,19 @@ vmwareDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat, return xml; } -static void vmwareDomainObjListUpdateDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *data) +static int vmwareDomainObjListUpdateDomain(virDomainObjPtr dom, void *data) { struct vmware_driver *driver = data; - virDomainObjPtr vm = payload; - virObjectLock(vm); - ignore_value(vmwareUpdateVMStatus(driver, vm)); - virObjectUnlock(vm); + virObjectLock(dom); + ignore_value(vmwareUpdateVMStatus(driver, dom)); + virObjectUnlock(dom); + return 0; } static void vmwareDomainObjListUpdateAll(virDomainObjListPtr doms, struct vmware_driver *driver) { - virHashForEach(doms->objs, vmwareDomainObjListUpdateDomain, driver); + virDomainObjListForEach(doms, vmwareDomainObjListUpdateDomain, driver); } static int