1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-20 07:59:00 +00:00

Convert virDomainObjListPtr to use a hash of domain objects

The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.

The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.

In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c

* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
  virDomainObjListPtr to use virHashTable. Add a initializer
  method virDomainObjListInit, and rename virDomainObjListFree
  to virDomainObjListDeinit, since its not actually freeing
  the container, only its contents. Also add some convenient
  methods virDomainObjListGetInactiveNames,
  virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
  which can be used to implement the correspondingly named
  public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
  src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
  src/qemu/qemu_driver.c, src/test/test_driver.c,
  src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
  to deal with hash tables instead of arrays for domains
This commit is contained in:
Daniel P. Berrange 2009-10-09 12:33:51 +01:00
parent 1acef95a81
commit a3adcce795
11 changed files with 520 additions and 536 deletions

View File

@ -205,51 +205,93 @@ VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST,
#ifndef PROXY #ifndef PROXY
int virDomainObjListInit(virDomainObjListPtr doms)
{
doms->objs = virHashCreate(50);
if (!doms->objs) {
virReportOOMError(NULL);
return -1;
}
return 0;
}
static void virDomainObjListDeallocator(void *payload, const char *name ATTRIBUTE_UNUSED)
{
virDomainObjPtr obj = payload;
virDomainObjFree(obj);
}
void virDomainObjListDeinit(virDomainObjListPtr doms)
{
if (doms->objs)
virHashFree(doms->objs, virDomainObjListDeallocator);
}
static int virDomainObjListSearchID(const void *payload,
const char *name ATTRIBUTE_UNUSED,
const void *data)
{
virDomainObjPtr obj = (virDomainObjPtr)payload;
const int *id = data;
int want = 0;
virDomainObjLock(obj);
if (virDomainIsActive(obj) &&
obj->def->id == *id)
want = 1;
virDomainObjUnlock(obj);
return want;
}
virDomainObjPtr virDomainFindByID(const virDomainObjListPtr doms, virDomainObjPtr virDomainFindByID(const virDomainObjListPtr doms,
int id) int id)
{ {
unsigned int i; virDomainObjPtr obj;
obj = virHashSearch(doms->objs, virDomainObjListSearchID, &id);
for (i = 0 ; i < doms->count ; i++) { if (obj)
virDomainObjLock(doms->objs[i]); virDomainObjLock(obj);
if (virDomainIsActive(doms->objs[i]) && return obj;
doms->objs[i]->def->id == id)
return doms->objs[i];
virDomainObjUnlock(doms->objs[i]);
}
return NULL;
} }
virDomainObjPtr virDomainFindByUUID(const virDomainObjListPtr doms, virDomainObjPtr virDomainFindByUUID(const virDomainObjListPtr doms,
const unsigned char *uuid) const unsigned char *uuid)
{ {
unsigned int i; char uuidstr[VIR_UUID_STRING_BUFLEN];
virDomainObjPtr obj;
for (i = 0 ; i < doms->count ; i++) { virUUIDFormat(uuid, uuidstr);
virDomainObjLock(doms->objs[i]);
if (!memcmp(doms->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
return doms->objs[i];
virDomainObjUnlock(doms->objs[i]);
}
return NULL; obj = virHashLookup(doms->objs, uuidstr);
if (obj)
virDomainObjLock(obj);
return obj;
}
static int virDomainObjListSearchName(const void *payload,
const char *name ATTRIBUTE_UNUSED,
const void *data)
{
virDomainObjPtr obj = (virDomainObjPtr)payload;
int want = 0;
virDomainObjLock(obj);
if (STREQ(obj->def->name, (const char *)data))
want = 1;
virDomainObjUnlock(obj);
return want;
} }
virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms, virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms,
const char *name) const char *name)
{ {
unsigned int i; virDomainObjPtr obj;
obj = virHashSearch(doms->objs, virDomainObjListSearchName, name);
for (i = 0 ; i < doms->count ; i++) { if (obj)
virDomainObjLock(doms->objs[i]); virDomainObjLock(obj);
if (STREQ(doms->objs[i]->def->name, name)) return obj;
return doms->objs[i];
virDomainObjUnlock(doms->objs[i]);
}
return NULL;
} }
#endif /* !PROXY */ #endif /* !PROXY */
@ -557,21 +599,6 @@ void virDomainObjFree(virDomainObjPtr dom)
VIR_FREE(dom); VIR_FREE(dom);
} }
void virDomainObjListFree(virDomainObjListPtr vms)
{
unsigned int i;
if (!vms)
return;
for (i = 0 ; i < vms->count ; i++)
virDomainObjFree(vms->objs[i]);
VIR_FREE(vms->objs);
vms->count = 0;
}
static virDomainObjPtr virDomainObjNew(virConnectPtr conn) static virDomainObjPtr virDomainObjNew(virConnectPtr conn)
{ {
virDomainObjPtr domain; virDomainObjPtr domain;
@ -601,6 +628,7 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
const virDomainDefPtr def) const virDomainDefPtr def)
{ {
virDomainObjPtr domain; virDomainObjPtr domain;
char uuidstr[VIR_UUID_STRING_BUFLEN];
if ((domain = virDomainFindByUUID(doms, def->uuid))) { if ((domain = virDomainFindByUUID(doms, def->uuid))) {
if (!virDomainIsActive(domain)) { if (!virDomainIsActive(domain)) {
@ -615,49 +643,34 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
return domain; return domain;
} }
if (VIR_REALLOC_N(doms->objs, doms->count + 1) < 0) { if (!(domain = virDomainObjNew(conn)))
return NULL;
domain->def = def;
virUUIDFormat(def->uuid, uuidstr);
if (virHashAddEntry(doms->objs, uuidstr, domain) < 0) {
VIR_FREE(domain);
virReportOOMError(conn); virReportOOMError(conn);
return NULL; return NULL;
} }
if (!(domain = virDomainObjNew(conn)))
return NULL;
domain->def = def;
doms->objs[doms->count] = domain;
doms->count++;
return domain; return domain;
} }
/*
* The caller must hold a lock on the driver owning 'doms',
* and must also have locked 'dom', to ensure no one else
* is either waiting for 'dom' or still usingn it
*/
void virDomainRemoveInactive(virDomainObjListPtr doms, void virDomainRemoveInactive(virDomainObjListPtr doms,
virDomainObjPtr dom) virDomainObjPtr dom)
{ {
unsigned int i; char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->def->uuid, uuidstr);
virDomainObjUnlock(dom); virDomainObjUnlock(dom);
for (i = 0 ; i < doms->count ; i++) { virHashRemoveEntry(doms->objs, uuidstr, virDomainObjListDeallocator);
virDomainObjLock(doms->objs[i]);
if (doms->objs[i] == dom) {
virDomainObjUnlock(doms->objs[i]);
virDomainObjFree(doms->objs[i]);
if (i < (doms->count - 1))
memmove(doms->objs + i, doms->objs + i + 1,
sizeof(*(doms->objs)) * (doms->count - (i + 1)));
if (VIR_REALLOC_N(doms->objs, doms->count - 1) < 0) {
; /* Failure to reduce memory allocation isn't fatal */
}
doms->count--;
break;
}
virDomainObjUnlock(doms->objs[i]);
}
} }
@ -4784,7 +4797,7 @@ static virDomainObjPtr virDomainLoadStatus(virConnectPtr conn,
{ {
char *statusFile = NULL; char *statusFile = NULL;
virDomainObjPtr obj = NULL; virDomainObjPtr obj = NULL;
virDomainObjPtr tmp = NULL; char uuidstr[VIR_UUID_STRING_BUFLEN];
if ((statusFile = virDomainConfigFile(conn, statusDir, name)) == NULL) if ((statusFile = virDomainConfigFile(conn, statusDir, name)) == NULL)
goto error; goto error;
@ -4792,23 +4805,20 @@ static virDomainObjPtr virDomainLoadStatus(virConnectPtr conn,
if (!(obj = virDomainObjParseFile(conn, caps, statusFile))) if (!(obj = virDomainObjParseFile(conn, caps, statusFile)))
goto error; goto error;
tmp = virDomainFindByName(doms, obj->def->name); virUUIDFormat(obj->def->uuid, uuidstr);
if (tmp) {
virDomainObjUnlock(obj); if (virHashLookup(doms->objs, uuidstr) != NULL) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unexpected domain %s already exists"), _("unexpected domain %s already exists"),
obj->def->name); obj->def->name);
goto error; goto error;
} }
if (VIR_REALLOC_N(doms->objs, doms->count + 1) < 0) { if (virHashAddEntry(doms->objs, uuidstr, obj) < 0) {
virReportOOMError(conn); virReportOOMError(conn);
goto error; goto error;
} }
doms->objs[doms->count] = obj;
doms->count++;
if (notify) if (notify)
(*notify)(obj, 1, opaque); (*notify)(obj, 1, opaque);
@ -4995,4 +5005,106 @@ void virDomainObjUnlock(virDomainObjPtr obj)
virMutexUnlock(&obj->lock); virMutexUnlock(&obj->lock);
} }
static void virDomainObjListCountActive(void *payload, const char *name ATTRIBUTE_UNUSED, void *data)
{
virDomainObjPtr obj = payload;
int *count = data;
virDomainObjLock(obj);
if (virDomainIsActive(obj))
(*count)++;
virDomainObjUnlock(obj);
}
static void virDomainObjListCountInactive(void *payload, const char *name ATTRIBUTE_UNUSED, void *data)
{
virDomainObjPtr obj = payload;
int *count = data;
virDomainObjLock(obj);
if (!virDomainIsActive(obj))
(*count)++;
virDomainObjUnlock(obj);
}
int virDomainObjListNumOfDomains(virDomainObjListPtr doms, int active)
{
int count = 0;
if (active)
virHashForEach(doms->objs, virDomainObjListCountActive, &count);
else
virHashForEach(doms->objs, virDomainObjListCountInactive, &count);
return count;
}
struct virDomainIDData {
int numids;
int maxids;
int *ids;
};
static void virDomainObjListCopyActiveIDs(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr obj = payload;
struct virDomainIDData *data = opaque;
virDomainObjLock(obj);
if (virDomainIsActive(obj) && data->numids < data->maxids)
data->ids[data->numids++] = obj->def->id;
virDomainObjUnlock(obj);
}
int virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
int *ids,
int maxids)
{
struct virDomainIDData data = { 0, maxids, ids };
virHashForEach(doms->objs, virDomainObjListCopyActiveIDs, &data);
return data.numids;
}
struct virDomainNameData {
int oom;
int numnames;
int maxnames;
char **const names;
};
static void virDomainObjListCopyInactiveNames(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr obj = payload;
struct virDomainNameData *data = opaque;
if (data->oom)
return;
virDomainObjLock(obj);
if (!virDomainIsActive(obj) && data->numnames < data->maxnames) {
if (!(data->names[data->numnames] = strdup(obj->def->name)))
data->oom = 1;
else
data->numnames++;
}
virDomainObjUnlock(obj);
}
int virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
char **const names,
int maxnames)
{
struct virDomainNameData data = { 0, 0, maxnames, names };
int i;
virHashForEach(doms->objs, virDomainObjListCopyInactiveNames, &data);
if (data.oom) {
virReportOOMError(NULL);
goto cleanup;
}
return data.numnames;
cleanup:
for (i = 0 ; i < data.numnames ; i++)
VIR_FREE(data.names[i]);
return -1;
}
#endif /* ! PROXY */ #endif /* ! PROXY */

View File

@ -33,6 +33,7 @@
#include "storage_encryption_conf.h" #include "storage_encryption_conf.h"
#include "util.h" #include "util.h"
#include "threads.h" #include "threads.h"
#include "hash.h"
/* Private component of virDomainXMLFlags */ /* Private component of virDomainXMLFlags */
typedef enum { typedef enum {
@ -640,8 +641,9 @@ struct _virDomainObj {
typedef struct _virDomainObjList virDomainObjList; typedef struct _virDomainObjList virDomainObjList;
typedef virDomainObjList *virDomainObjListPtr; typedef virDomainObjList *virDomainObjListPtr;
struct _virDomainObjList { struct _virDomainObjList {
unsigned int count; /* uuid string -> virDomainObj mapping
virDomainObjPtr *objs; * for O(1), lockless lookup-by-uuid */
virHashTable *objs;
}; };
static inline int static inline int
@ -650,6 +652,8 @@ virDomainIsActive(virDomainObjPtr dom)
return dom->def->id != -1; return dom->def->id != -1;
} }
int virDomainObjListInit(virDomainObjListPtr objs);
void virDomainObjListDeinit(virDomainObjListPtr objs);
virDomainObjPtr virDomainFindByID(const virDomainObjListPtr doms, virDomainObjPtr virDomainFindByID(const virDomainObjListPtr doms,
int id); int id);
@ -672,7 +676,6 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
void virDomainDeviceDefFree(virDomainDeviceDefPtr def); void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
void virDomainDefFree(virDomainDefPtr vm); void virDomainDefFree(virDomainDefPtr vm);
void virDomainObjFree(virDomainObjPtr vm); void virDomainObjFree(virDomainObjPtr vm);
void virDomainObjListFree(virDomainObjListPtr vms);
virDomainObjPtr virDomainAssignDef(virConnectPtr conn, virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
virDomainObjListPtr doms, virDomainObjListPtr doms,
@ -784,6 +787,16 @@ int virDomainVideoDefaultRAM(virDomainDefPtr def, int type);
void virDomainObjLock(virDomainObjPtr obj); void virDomainObjLock(virDomainObjPtr obj);
void virDomainObjUnlock(virDomainObjPtr obj); void virDomainObjUnlock(virDomainObjPtr obj);
int virDomainObjListNumOfDomains(virDomainObjListPtr doms, int active);
int virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
int *ids,
int maxids);
int virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
char **const names,
int maxnames);
VIR_ENUM_DECL(virDomainVirt) VIR_ENUM_DECL(virDomainVirt)
VIR_ENUM_DECL(virDomainBoot) VIR_ENUM_DECL(virDomainBoot)
VIR_ENUM_DECL(virDomainFeature) VIR_ENUM_DECL(virDomainFeature)

View File

@ -124,7 +124,6 @@ virDomainLoadAllConfigs;
virDomainNetDefFree; virDomainNetDefFree;
virDomainNetTypeToString; virDomainNetTypeToString;
virDomainObjFree; virDomainObjFree;
virDomainObjListFree;
virDomainRemoveInactive; virDomainRemoveInactive;
virDomainSaveXML; virDomainSaveXML;
virDomainSaveConfig; virDomainSaveConfig;
@ -147,6 +146,11 @@ virDomainObjLock;
virDomainObjUnlock; virDomainObjUnlock;
virDomainStateTypeToString; virDomainStateTypeToString;
virDomainStateTypeFromString; virDomainStateTypeFromString;
virDomainObjListGetInactiveNames;
virDomainObjListGetActiveIDs;
virDomainObjListNumOfDomains;
virDomainObjListInit;
virDomainObjListDeinit;
# domain_event.h # domain_event.h

View File

@ -220,31 +220,21 @@ cleanup:
static int lxcListDomains(virConnectPtr conn, int *ids, int nids) { static int lxcListDomains(virConnectPtr conn, int *ids, int nids) {
lxc_driver_t *driver = conn->privateData; lxc_driver_t *driver = conn->privateData;
int got = 0, i; int n;
lxcDriverLock(driver); lxcDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nids ; i++) { n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id;
virDomainObjUnlock(driver->domains.objs[i]);
}
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return got; return n;
} }
static int lxcNumDomains(virConnectPtr conn) { static int lxcNumDomains(virConnectPtr conn) {
lxc_driver_t *driver = conn->privateData; lxc_driver_t *driver = conn->privateData;
int n = 0, i; int n;
lxcDriverLock(driver); lxcDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { n = virDomainObjListNumOfDomains(&driver->domains, 1);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return n; return n;
@ -253,43 +243,22 @@ static int lxcNumDomains(virConnectPtr conn) {
static int lxcListDefinedDomains(virConnectPtr conn, static int lxcListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) { char **const names, int nnames) {
lxc_driver_t *driver = conn->privateData; lxc_driver_t *driver = conn->privateData;
int got = 0, i; int n;
lxcDriverLock(driver); lxcDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) { n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
virReportOOMError(conn);
virDomainObjUnlock(driver->domains.objs[i]);
goto cleanup;
}
}
virDomainObjUnlock(driver->domains.objs[i]);
}
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return got; return n;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
lxcDriverUnlock(driver);
return -1;
} }
static int lxcNumDefinedDomains(virConnectPtr conn) { static int lxcNumDefinedDomains(virConnectPtr conn) {
lxc_driver_t *driver = conn->privateData; lxc_driver_t *driver = conn->privateData;
int n = 0, i; int n;
lxcDriverLock(driver); lxcDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { n = virDomainObjListNumOfDomains(&driver->domains, 0);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return n; return n;
@ -898,27 +867,15 @@ static void lxcMonitorEvent(int watch,
int events ATTRIBUTE_UNUSED, int events ATTRIBUTE_UNUSED,
void *data) void *data)
{ {
lxc_driver_t *driver = data; lxc_driver_t *driver = lxc_driver;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = data;
virDomainEventPtr event = NULL; virDomainEventPtr event = NULL;
unsigned int i;
lxcDriverLock(driver); lxcDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { virDomainObjLock(vm);
virDomainObjPtr tmpvm = driver->domains.objs[i]; lxcDriverUnlock(driver);
virDomainObjLock(tmpvm);
if (tmpvm->monitorWatch == watch) {
vm = tmpvm;
break;
}
virDomainObjUnlock(tmpvm);
}
if (!vm) {
virEventRemoveHandle(watch);
goto cleanup;
}
if (vm->monitor != fd) { if (vm->monitor != fd || vm->monitorWatch != watch) {
virEventRemoveHandle(watch); virEventRemoveHandle(watch);
goto cleanup; goto cleanup;
} }
@ -936,11 +893,12 @@ static void lxcMonitorEvent(int watch,
} }
cleanup: cleanup:
if (vm) virDomainObjUnlock(vm);
virDomainObjUnlock(vm); if (event) {
if (event) lxcDriverLock(driver);
lxcDomainEventQueue(driver, event); lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
}
} }
@ -1572,9 +1530,40 @@ static int lxcCheckNetNsSupport(void)
} }
struct lxcAutostartData {
lxc_driver_t *driver;
virConnectPtr conn;
};
static void
lxcAutostartDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
const struct lxcAutostartData *data = opaque;
virDomainObjLock(vm);
if (vm->autostart &&
!virDomainIsActive(vm)) {
int ret = lxcVmStart(data->conn, data->driver, vm);
if (ret < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s\n"),
vm->def->name,
err ? err->message : "");
} else {
virDomainEventPtr event =
virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_BOOTED);
if (event)
lxcDomainEventQueue(data->driver, event);
}
}
virDomainObjUnlock(vm);
}
static void static void
lxcAutostartConfigs(lxc_driver_t *driver) { lxcAutostartConfigs(lxc_driver_t *driver) {
unsigned int i;
/* XXX: Figure out a better way todo this. The domain /* XXX: Figure out a better way todo this. The domain
* startup code needs a connection handle in order * startup code needs a connection handle in order
* to lookup the bridge associated with a virtual * to lookup the bridge associated with a virtual
@ -1583,39 +1572,65 @@ lxcAutostartConfigs(lxc_driver_t *driver) {
virConnectPtr conn = virConnectOpen("lxc:///"); virConnectPtr conn = virConnectOpen("lxc:///");
/* Ignoring NULL conn which is mostly harmless here */ /* Ignoring NULL conn which is mostly harmless here */
struct lxcAutostartData data = { driver, conn };
lxcDriverLock(driver); lxcDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { virHashForEach(driver->domains.objs, lxcAutostartDomain, &data);
virDomainObjPtr vm = driver->domains.objs[i];
virDomainObjLock(vm);
if (vm->autostart &&
!virDomainIsActive(vm)) {
int ret = lxcVmStart(conn, driver, vm);
if (ret < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s\n"),
vm->def->name,
err ? err->message : "");
} else {
virDomainEventPtr event =
virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_BOOTED);
if (event)
lxcDomainEventQueue(driver, event);
}
}
virDomainObjUnlock(vm);
}
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
if (conn) if (conn)
virConnectClose(conn); virConnectClose(conn);
} }
static void
lxcReconnectVM(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
lxc_driver_t *driver = opaque;
char *config = NULL;
virDomainDefPtr tmp;
virDomainObjLock(vm);
if ((vm->monitor = lxcMonitorClient(NULL, driver, vm)) < 0) {
goto cleanup;
}
/* Read pid from controller */
if ((virFileReadPid(lxc_driver->stateDir, vm->def->name, &vm->pid)) != 0) {
close(vm->monitor);
vm->monitor = -1;
goto cleanup;
}
if ((config = virDomainConfigFile(NULL,
driver->stateDir,
vm->def->name)) == NULL)
goto cleanup;
/* Try and load the live config */
tmp = virDomainDefParseFile(NULL, driver->caps, config, 0);
VIR_FREE(config);
if (tmp) {
vm->newDef = vm->def;
vm->def = tmp;
}
if (vm->pid != 0) {
vm->def->id = vm->pid;
vm->state = VIR_DOMAIN_RUNNING;
} else {
vm->def->id = -1;
close(vm->monitor);
vm->monitor = -1;
}
cleanup:
virDomainObjUnlock(vm);
}
static int lxcStartup(int privileged) static int lxcStartup(int privileged)
{ {
unsigned int i;
char *ld; char *ld;
int rc; int rc;
@ -1647,6 +1662,9 @@ static int lxcStartup(int privileged)
goto cleanup; goto cleanup;
} }
if (virDomainObjListInit(&lxc_driver->domains) < 0)
goto cleanup;
if (VIR_ALLOC(lxc_driver->domainEventCallbacks) < 0) if (VIR_ALLOC(lxc_driver->domainEventCallbacks) < 0)
goto cleanup; goto cleanup;
if (!(lxc_driver->domainEventQueue = virDomainEventQueueNew())) if (!(lxc_driver->domainEventQueue = virDomainEventQueueNew()))
@ -1681,50 +1699,7 @@ static int lxcStartup(int privileged)
0, NULL, NULL) < 0) 0, NULL, NULL) < 0)
goto cleanup; goto cleanup;
for (i = 0 ; i < lxc_driver->domains.count ; i++) { virHashForEach(lxc_driver->domains.objs, lxcReconnectVM, lxc_driver);
virDomainObjPtr vm = lxc_driver->domains.objs[i];
char *config = NULL;
virDomainDefPtr tmp;
virDomainObjLock(vm);
if ((vm->monitor = lxcMonitorClient(NULL, lxc_driver, vm)) < 0) {
virDomainObjUnlock(vm);
continue;
}
/* Read pid from controller */
if ((rc = virFileReadPid(lxc_driver->stateDir, vm->def->name, &vm->pid)) != 0) {
close(vm->monitor);
vm->monitor = -1;
virDomainObjUnlock(vm);
continue;
}
if ((config = virDomainConfigFile(NULL,
lxc_driver->stateDir,
vm->def->name)) == NULL) {
virDomainObjUnlock(vm);
continue;
}
/* Try and load the live config */
tmp = virDomainDefParseFile(NULL, lxc_driver->caps, config, 0);
VIR_FREE(config);
if (tmp) {
vm->newDef = vm->def;
vm->def = tmp;
}
if (vm->pid != 0) {
vm->def->id = vm->pid;
vm->state = VIR_DOMAIN_RUNNING;
} else {
vm->def->id = -1;
close(vm->monitor);
vm->monitor = -1;
}
virDomainObjUnlock(vm);
}
lxcDriverUnlock(lxc_driver); lxcDriverUnlock(lxc_driver);
return 0; return 0;
@ -1780,7 +1755,7 @@ static int lxcShutdown(void)
return(-1); return(-1);
lxcDriverLock(lxc_driver); lxcDriverLock(lxc_driver);
virDomainObjListFree(&lxc_driver->domains); virDomainObjListDeinit(&lxc_driver->domains);
virDomainEventCallbackListFree(lxc_driver->domainEventCallbacks); virDomainEventCallbackListFree(lxc_driver->domainEventCallbacks);
virDomainEventQueueFree(lxc_driver->domainEventQueue); virDomainEventQueueFree(lxc_driver->domainEventQueue);
@ -1809,19 +1784,13 @@ static int lxcShutdown(void)
*/ */
static int static int
lxcActive(void) { lxcActive(void) {
unsigned int i; int active;
int active = 0;
if (lxc_driver == NULL) if (lxc_driver == NULL)
return(0); return(0);
lxcDriverLock(lxc_driver); lxcDriverLock(lxc_driver);
for (i = 0 ; i < lxc_driver->domains.count ; i++) { active = virDomainObjListNumOfDomains(&lxc_driver->domains, 1);
virDomainObjLock(lxc_driver->domains.objs[i]);
if (virDomainIsActive(lxc_driver->domains.objs[i]))
active = 1;
virDomainObjUnlock(lxc_driver->domains.objs[i]);
}
lxcDriverUnlock(lxc_driver); lxcDriverUnlock(lxc_driver);
return active; return active;

View File

@ -178,32 +178,22 @@ return_point:
static int oneListDomains(virConnectPtr conn, int *ids, int nids) static int oneListDomains(virConnectPtr conn, int *ids, int nids)
{ {
one_driver_t *driver = (one_driver_t *)conn->privateData; one_driver_t *driver = (one_driver_t *)conn->privateData;
int got = 0, i; int n;
oneDriverLock(driver); oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nids ; i++){ n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id;
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver); oneDriverUnlock(driver);
return got; return n;
} }
static int oneNumDomains(virConnectPtr conn) static int oneNumDomains(virConnectPtr conn)
{ {
one_driver_t *driver = (one_driver_t *)conn->privateData; one_driver_t *driver = (one_driver_t *)conn->privateData;
int n = 0, i; int n;
oneDriverLock(driver); oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++){ n = virDomainObjListNumOfDomains(&driver->domains, 1);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver); oneDriverUnlock(driver);
return n; return n;
@ -212,44 +202,22 @@ static int oneNumDomains(virConnectPtr conn)
static int oneListDefinedDomains(virConnectPtr conn, static int oneListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) { char **const names, int nnames) {
one_driver_t *driver = (one_driver_t *)conn->privateData; one_driver_t *driver = (one_driver_t *)conn->privateData;
int got = 0, i; int n;
oneDriverLock(driver); oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) { n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
virReportOOMError(conn);
virDomainObjUnlock(driver->domains.objs[i]);
goto cleanup;
}
}
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver); oneDriverUnlock(driver);
return got; return n;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
oneDriverUnlock(driver);
return -1;
} }
static int oneNumDefinedDomains(virConnectPtr conn) static int oneNumDefinedDomains(virConnectPtr conn)
{ {
one_driver_t *driver = (one_driver_t *)conn->privateData; one_driver_t *driver = (one_driver_t *)conn->privateData;
int n = 0, i; int n;
oneDriverLock(driver); oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++){ n = virDomainObjListNumOfDomains(&driver->domains, 0);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver); oneDriverUnlock(driver);
return n; return n;
@ -647,6 +615,12 @@ static int oneStartup(int privileged ATTRIBUTE_UNUSED){
return -1; return -1;
} }
if (virDomainObjListInit(&one_driver->domains) < 0) {
virMutexDestroy(&one_driver->lock);
VIR_FREE(one_driver);
return -1;
}
c_oneStart(); c_oneStart();
oneDriverLock(one_driver); oneDriverLock(one_driver);
one_driver->nextid=1; one_driver->nextid=1;
@ -665,7 +639,7 @@ static int oneShutdown(void){
return(-1); return(-1);
oneDriverLock(one_driver); oneDriverLock(one_driver);
virDomainObjListFree(&one_driver->domains); virDomainObjListDeinit(&one_driver->domains);
virCapabilitiesFree(one_driver->caps); virCapabilitiesFree(one_driver->caps);
oneDriverUnlock(one_driver); oneDriverUnlock(one_driver);
@ -677,19 +651,13 @@ static int oneShutdown(void){
} }
static int oneActive(void){ static int oneActive(void){
unsigned int i;
int active = 0; int active = 0;
if (one_driver == NULL) if (one_driver == NULL)
return(0); return(0);
oneDriverLock(one_driver); oneDriverLock(one_driver);
for (i = 0 ; i < one_driver->domains.count ; i++) { active = virDomainObjListNumOfDomains(&one_driver->domains, 1);
virDomainObjLock(one_driver->domains.objs[i]);
if (virDomainIsActive(one_driver->domains.objs[i]))
active = 1;
virDomainObjUnlock(one_driver->domains.objs[i]);
}
oneDriverUnlock(one_driver); oneDriverUnlock(one_driver);
return active; return active;

View File

@ -421,7 +421,7 @@ openvzFreeDriver(struct openvz_driver *driver)
if (!driver) if (!driver)
return; return;
virDomainObjListFree(&driver->domains); virDomainObjListDeinit(&driver->domains);
virCapabilitiesFree(driver->caps); virCapabilitiesFree(driver->caps);
} }
@ -509,11 +509,10 @@ int openvzLoadDomains(struct openvz_driver *driver) {
openvzReadNetworkConf(NULL, dom->def, veid); openvzReadNetworkConf(NULL, dom->def, veid);
openvzReadFSConf(NULL, dom->def, veid); openvzReadFSConf(NULL, dom->def, veid);
if (VIR_REALLOC_N(driver->domains.objs, virUUIDFormat(dom->def->uuid, uuidstr);
driver->domains.count + 1) < 0) if (virHashAddEntry(driver->domains.objs, uuidstr, dom) < 0)
goto no_memory; goto no_memory;
driver->domains.objs[driver->domains.count++] = dom;
dom = NULL; dom = NULL;
} }

View File

@ -1168,6 +1168,9 @@ static virDrvOpenStatus openvzOpen(virConnectPtr conn,
return VIR_DRV_OPEN_ERROR; return VIR_DRV_OPEN_ERROR;
} }
if (virDomainObjListInit(&driver->domains) < 0)
goto cleanup;
if (!(driver->caps = openvzCapsInit())) if (!(driver->caps = openvzCapsInit()))
goto cleanup; goto cleanup;
@ -1247,18 +1250,13 @@ static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
static int openvzNumDomains(virConnectPtr conn) { static int openvzNumDomains(virConnectPtr conn) {
struct openvz_driver *driver = conn->privateData; struct openvz_driver *driver = conn->privateData;
int nactive = 0, i; int n;
openvzDriverLock(driver); openvzDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { n = virDomainObjListNumOfDomains(&driver->domains, 1);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
nactive++;
virDomainObjUnlock(driver->domains.objs[i]);
}
openvzDriverUnlock(driver); openvzDriverUnlock(driver);
return nactive; return n;
} }
static int openvzListDefinedDomains(virConnectPtr conn, static int openvzListDefinedDomains(virConnectPtr conn,
@ -1350,18 +1348,13 @@ Version: 2.2
static int openvzNumDefinedDomains(virConnectPtr conn) { static int openvzNumDefinedDomains(virConnectPtr conn) {
struct openvz_driver *driver = conn->privateData; struct openvz_driver *driver = conn->privateData;
int ninactive = 0, i; int n;
openvzDriverLock(driver); openvzDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { n = virDomainObjListNumOfDomains(&driver->domains, 0);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i]))
ninactive++;
virDomainObjUnlock(driver->domains.objs[i]);
}
openvzDriverUnlock(driver); openvzDriverUnlock(driver);
return ninactive; return n;
} }
static virDriver openvzDriver = { static virDriver openvzDriver = {

View File

@ -201,9 +201,42 @@ qemudLogReadFD(virConnectPtr conn, const char* logDir, const char* name, off_t p
} }
struct qemuAutostartData {
struct qemud_driver *driver;
virConnectPtr conn;
};
static void
qemuAutostartDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
struct qemuAutostartData *data = opaque;
virDomainObjLock(vm);
if (vm->autostart &&
!virDomainIsActive(vm)) {
int ret;
virResetLastError();
ret = qemudStartVMDaemon(data->conn, data->driver, vm, NULL, -1);
if (ret < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s\n"),
vm->def->name,
err ? err->message : "");
} else {
virDomainEventPtr event =
virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_BOOTED);
if (event)
qemuDomainEventQueue(data->driver, event);
}
}
virDomainObjUnlock(vm);
}
static void static void
qemudAutostartConfigs(struct qemud_driver *driver) { qemudAutostartConfigs(struct qemud_driver *driver) {
unsigned int i;
/* XXX: Figure out a better way todo this. The domain /* XXX: Figure out a better way todo this. The domain
* startup code needs a connection handle in order * startup code needs a connection handle in order
* to lookup the bridge associated with a virtual * to lookup the bridge associated with a virtual
@ -213,33 +246,10 @@ qemudAutostartConfigs(struct qemud_driver *driver) {
"qemu:///system" : "qemu:///system" :
"qemu:///session"); "qemu:///session");
/* Ignoring NULL conn which is mostly harmless here */ /* Ignoring NULL conn which is mostly harmless here */
struct qemuAutostartData data = { driver, conn };
qemuDriverLock(driver); qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { virHashForEach(driver->domains.objs, qemuAutostartDomain, &data);
virDomainObjPtr vm = driver->domains.objs[i];
virDomainObjLock(vm);
if (vm->autostart &&
!virDomainIsActive(vm)) {
int ret;
virResetLastError();
ret = qemudStartVMDaemon(conn, driver, vm, NULL, -1);
if (ret < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s\n"),
vm->def->name,
err ? err->message : "");
} else {
virDomainEventPtr event =
virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_BOOTED);
if (event)
qemuDomainEventQueue(driver, event);
}
}
virDomainObjUnlock(vm);
}
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
if (conn) if (conn)
@ -284,7 +294,6 @@ cleanup:
static int qemudOpenMonitor(virConnectPtr conn, static int qemudOpenMonitor(virConnectPtr conn,
struct qemud_driver* driver,
virDomainObjPtr vm, virDomainObjPtr vm,
int reconnect); int reconnect);
@ -293,13 +302,16 @@ static int qemudOpenMonitor(virConnectPtr conn,
* Open an existing VM's monitor, re-detect VCPU threads * Open an existing VM's monitor, re-detect VCPU threads
* and re-reserve the security labels in use * and re-reserve the security labels in use
*/ */
static int static void
qemuReconnectDomain(struct qemud_driver *driver, qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
virDomainObjPtr obj)
{ {
int rc; int rc;
virDomainObjPtr obj = payload;
struct qemud_driver *driver = opaque;
if ((rc = qemudOpenMonitor(NULL, driver, obj, 1)) != 0) { virDomainObjLock(obj);
if ((rc = qemudOpenMonitor(NULL, obj, 1)) != 0) {
VIR_ERROR(_("Failed to reconnect monitor for %s: %d\n"), VIR_ERROR(_("Failed to reconnect monitor for %s: %d\n"),
obj->def->name, rc); obj->def->name, rc);
goto error; goto error;
@ -313,15 +325,20 @@ qemuReconnectDomain(struct qemud_driver *driver,
driver->securityDriver && driver->securityDriver &&
driver->securityDriver->domainReserveSecurityLabel && driver->securityDriver->domainReserveSecurityLabel &&
driver->securityDriver->domainReserveSecurityLabel(NULL, obj) < 0) driver->securityDriver->domainReserveSecurityLabel(NULL, obj) < 0)
return -1; goto error;
if (obj->def->id >= driver->nextvmid) if (obj->def->id >= driver->nextvmid)
driver->nextvmid = obj->def->id + 1; driver->nextvmid = obj->def->id + 1;
return 0; virDomainObjUnlock(obj);
return;
error: error:
return -1; /* We can't get the monitor back, so must kill the VM
* to remove danger of it ending up running twice if
* user tries to start it again later */
qemudShutdownVMDaemon(NULL, driver, obj);
virDomainObjUnlock(obj);
} }
/** /**
@ -333,20 +350,7 @@ error:
static void static void
qemuReconnectDomains(struct qemud_driver *driver) qemuReconnectDomains(struct qemud_driver *driver)
{ {
int i; virHashForEach(driver->domains.objs, qemuReconnectDomain, driver);
for (i = 0 ; i < driver->domains.count ; i++) {
virDomainObjPtr obj = driver->domains.objs[i];
virDomainObjLock(obj);
if (qemuReconnectDomain(driver, obj) < 0) {
/* If we can't get the monitor back, then kill the VM
* so user has ability to start it again later without
* danger of ending up running twice */
qemudShutdownVMDaemon(NULL, driver, obj);
}
virDomainObjUnlock(obj);
}
} }
@ -438,8 +442,11 @@ qemudStartup(int privileged) {
/* Don't have a dom0 so start from 1 */ /* Don't have a dom0 so start from 1 */
qemu_driver->nextvmid = 1; qemu_driver->nextvmid = 1;
if (virDomainObjListInit(&qemu_driver->domains) < 0)
goto out_of_memory;
/* Init callback list */ /* Init callback list */
if(VIR_ALLOC(qemu_driver->domainEventCallbacks) < 0) if (VIR_ALLOC(qemu_driver->domainEventCallbacks) < 0)
goto out_of_memory; goto out_of_memory;
if (!(qemu_driver->domainEventQueue = virDomainEventQueueNew())) if (!(qemu_driver->domainEventQueue = virDomainEventQueueNew()))
goto out_of_memory; goto out_of_memory;
@ -679,21 +686,14 @@ qemudReload(void) {
*/ */
static int static int
qemudActive(void) { qemudActive(void) {
unsigned int i;
int active = 0; int active = 0;
if (!qemu_driver) if (!qemu_driver)
return 0; return 0;
/* XXX having to iterate here is not great because it requires many locks */
qemuDriverLock(qemu_driver); qemuDriverLock(qemu_driver);
for (i = 0 ; i < qemu_driver->domains.count ; i++) { active = virDomainObjListNumOfDomains(&qemu_driver->domains, 1);
virDomainObjPtr vm = qemu_driver->domains.objs[i];
virDomainObjLock(vm);
if (virDomainIsActive(vm))
active = 1;
virDomainObjUnlock(vm);
}
qemuDriverUnlock(qemu_driver); qemuDriverUnlock(qemu_driver);
return active; return active;
} }
@ -713,7 +713,7 @@ qemudShutdown(void) {
pciDeviceListFree(NULL, qemu_driver->activePciHostdevs); pciDeviceListFree(NULL, qemu_driver->activePciHostdevs);
virCapabilitiesFree(qemu_driver->caps); virCapabilitiesFree(qemu_driver->caps);
virDomainObjListFree(&qemu_driver->domains); virDomainObjListDeinit(&qemu_driver->domains);
VIR_FREE(qemu_driver->securityDriverName); VIR_FREE(qemu_driver->securityDriverName);
VIR_FREE(qemu_driver->logDir); VIR_FREE(qemu_driver->logDir);
@ -913,7 +913,6 @@ qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
static int static int
qemudOpenMonitorCommon(virConnectPtr conn, qemudOpenMonitorCommon(virConnectPtr conn,
struct qemud_driver* driver,
virDomainObjPtr vm, virDomainObjPtr vm,
int monfd, int monfd,
int reconnect) int reconnect)
@ -952,7 +951,7 @@ qemudOpenMonitorCommon(virConnectPtr conn,
if ((vm->monitorWatch = virEventAddHandle(vm->monitor, if ((vm->monitorWatch = virEventAddHandle(vm->monitor,
VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR, VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR,
qemudDispatchVMEvent, qemudDispatchVMEvent,
driver, NULL)) < 0) vm, NULL)) < 0)
return -1; return -1;
return 0; return 0;
@ -960,7 +959,6 @@ qemudOpenMonitorCommon(virConnectPtr conn,
static int static int
qemudOpenMonitorUnix(virConnectPtr conn, qemudOpenMonitorUnix(virConnectPtr conn,
struct qemud_driver* driver,
virDomainObjPtr vm, virDomainObjPtr vm,
const char *monitor, const char *monitor,
int reconnect) int reconnect)
@ -1008,7 +1006,7 @@ qemudOpenMonitorUnix(virConnectPtr conn,
goto error; goto error;
} }
if (qemudOpenMonitorCommon(conn, driver, vm, monfd, reconnect) < 0) if (qemudOpenMonitorCommon(conn, vm, monfd, reconnect) < 0)
goto error; goto error;
return 0; return 0;
@ -1020,7 +1018,6 @@ error:
static int static int
qemudOpenMonitorPty(virConnectPtr conn, qemudOpenMonitorPty(virConnectPtr conn,
struct qemud_driver* driver,
virDomainObjPtr vm, virDomainObjPtr vm,
const char *monitor, const char *monitor,
int reconnect) int reconnect)
@ -1033,7 +1030,7 @@ qemudOpenMonitorPty(virConnectPtr conn,
return -1; return -1;
} }
if (qemudOpenMonitorCommon(conn, driver, vm, monfd, reconnect) < 0) if (qemudOpenMonitorCommon(conn, vm, monfd, reconnect) < 0)
goto error; goto error;
return 0; return 0;
@ -1045,17 +1042,16 @@ error:
static int static int
qemudOpenMonitor(virConnectPtr conn, qemudOpenMonitor(virConnectPtr conn,
struct qemud_driver *driver,
virDomainObjPtr vm, virDomainObjPtr vm,
int reconnect) int reconnect)
{ {
switch (vm->monitor_chr->type) { switch (vm->monitor_chr->type) {
case VIR_DOMAIN_CHR_TYPE_UNIX: case VIR_DOMAIN_CHR_TYPE_UNIX:
return qemudOpenMonitorUnix(conn, driver, vm, return qemudOpenMonitorUnix(conn, vm,
vm->monitor_chr->data.nix.path, vm->monitor_chr->data.nix.path,
reconnect); reconnect);
case VIR_DOMAIN_CHR_TYPE_PTY: case VIR_DOMAIN_CHR_TYPE_PTY:
return qemudOpenMonitorPty(conn, driver, vm, return qemudOpenMonitorPty(conn, vm,
vm->monitor_chr->data.file.path, vm->monitor_chr->data.file.path,
reconnect); reconnect);
default: default:
@ -1177,7 +1173,7 @@ qemudWaitForMonitor(virConnectPtr conn,
return -1; return -1;
} }
if (qemudOpenMonitor(conn, driver, vm, 0) < 0) if (qemudOpenMonitor(conn, vm, 0) < 0)
return -1; return -1;
return 0; return 0;
@ -2255,28 +2251,22 @@ retry:
static void static void
qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) { qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
struct qemud_driver *driver = opaque; struct qemud_driver *driver = qemu_driver;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = opaque;
virDomainEventPtr event = NULL; virDomainEventPtr event = NULL;
unsigned int i;
int quit = 0, failed = 0; int quit = 0, failed = 0;
/* XXX Normally we have to lock the driver first, to protect
* against someone adding/removing the domain. We know,
* however, then if we're getting data in this callback
* the VM must be running. Nowhere is allowed to remove
* a domain while it is running, so it is safe to not
* lock the driver here... */
qemuDriverLock(driver); qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { virDomainObjLock(vm);
virDomainObjPtr tmpvm = driver->domains.objs[i]; qemuDriverUnlock(driver);
virDomainObjLock(tmpvm);
if (virDomainIsActive(tmpvm) &&
tmpvm->monitorWatch == watch) {
vm = tmpvm;
break;
}
virDomainObjUnlock(tmpvm);
}
if (!vm) if (vm->monitor != fd || vm->monitorWatch != watch) {
goto cleanup;
if (vm->monitor != fd) {
failed = 1; failed = 1;
} else { } else {
if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR)) if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
@ -2302,12 +2292,12 @@ qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
} }
} }
cleanup: virDomainObjUnlock(vm);
if (vm) if (event) {
virDomainObjUnlock(vm); qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
}
} }
@ -2637,31 +2627,21 @@ qemudGetHostname (virConnectPtr conn)
static int qemudListDomains(virConnectPtr conn, int *ids, int nids) { static int qemudListDomains(virConnectPtr conn, int *ids, int nids) {
struct qemud_driver *driver = conn->privateData; struct qemud_driver *driver = conn->privateData;
int got = 0, i; int n;
qemuDriverLock(driver); qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nids ; i++) { n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id;
virDomainObjUnlock(driver->domains.objs[i]);
}
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
return got; return n;
} }
static int qemudNumDomains(virConnectPtr conn) { static int qemudNumDomains(virConnectPtr conn) {
struct qemud_driver *driver = conn->privateData; struct qemud_driver *driver = conn->privateData;
int n = 0, i; int n;
qemuDriverLock(driver); qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { n = virDomainObjListNumOfDomains(&driver->domains, 1);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
return n; return n;
@ -4060,39 +4040,20 @@ cleanup:
static int qemudListDefinedDomains(virConnectPtr conn, static int qemudListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) { char **const names, int nnames) {
struct qemud_driver *driver = conn->privateData; struct qemud_driver *driver = conn->privateData;
int got = 0, i; int n;
qemuDriverLock(driver); qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) { n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
virReportOOMError(conn);
virDomainObjUnlock(driver->domains.objs[i]);
goto cleanup;
}
}
virDomainObjUnlock(driver->domains.objs[i]);
}
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
return got; return n;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
qemuDriverUnlock(driver);
return -1;
} }
static int qemudNumDefinedDomains(virConnectPtr conn) { static int qemudNumDefinedDomains(virConnectPtr conn) {
struct qemud_driver *driver = conn->privateData; struct qemud_driver *driver = conn->privateData;
int n = 0, i; int n;
qemuDriverLock(driver); qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) n = virDomainObjListNumOfDomains(&driver->domains, 0);
if (!virDomainIsActive(driver->domains.objs[i]))
n++;
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
return n; return n;

View File

@ -361,6 +361,9 @@ static int testOpenDefault(virConnectPtr conn) {
goto error; goto error;
} }
if (virDomainObjListInit(&privconn->domains) < 0)
goto error;
memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo)); memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
// Numa setup // Numa setup
@ -442,7 +445,7 @@ static int testOpenDefault(virConnectPtr conn) {
return VIR_DRV_OPEN_SUCCESS; return VIR_DRV_OPEN_SUCCESS;
error: error:
virDomainObjListFree(&privconn->domains); virDomainObjListDeinit(&privconn->domains);
virNetworkObjListFree(&privconn->networks); virNetworkObjListFree(&privconn->networks);
virInterfaceObjListFree(&privconn->ifaces); virInterfaceObjListFree(&privconn->ifaces);
virStoragePoolObjListFree(&privconn->pools); virStoragePoolObjListFree(&privconn->pools);
@ -592,6 +595,9 @@ static int testOpenFromFile(virConnectPtr conn,
testDriverLock(privconn); testDriverLock(privconn);
conn->privateData = privconn; conn->privateData = privconn;
if (virDomainObjListInit(&privconn->domains) < 0)
goto error;
if (!(privconn->caps = testBuildCapabilities(conn))) if (!(privconn->caps = testBuildCapabilities(conn)))
goto error; goto error;
@ -920,7 +926,7 @@ static int testOpenFromFile(virConnectPtr conn,
VIR_FREE(pools); VIR_FREE(pools);
if (fd != -1) if (fd != -1)
close(fd); close(fd);
virDomainObjListFree(&privconn->domains); virDomainObjListDeinit(&privconn->domains);
virNetworkObjListFree(&privconn->networks); virNetworkObjListFree(&privconn->networks);
virInterfaceObjListFree(&privconn->ifaces); virInterfaceObjListFree(&privconn->ifaces);
virStoragePoolObjListFree(&privconn->pools); virStoragePoolObjListFree(&privconn->pools);
@ -989,7 +995,7 @@ static int testClose(virConnectPtr conn)
testConnPtr privconn = conn->privateData; testConnPtr privconn = conn->privateData;
testDriverLock(privconn); testDriverLock(privconn);
virCapabilitiesFree(privconn->caps); virCapabilitiesFree(privconn->caps);
virDomainObjListFree(&privconn->domains); virDomainObjListDeinit(&privconn->domains);
virNetworkObjListFree(&privconn->networks); virNetworkObjListFree(&privconn->networks);
virInterfaceObjListFree(&privconn->ifaces); virInterfaceObjListFree(&privconn->ifaces);
virStoragePoolObjListFree(&privconn->pools); virStoragePoolObjListFree(&privconn->pools);
@ -1059,15 +1065,13 @@ static char *testGetCapabilities (virConnectPtr conn)
static int testNumOfDomains(virConnectPtr conn) static int testNumOfDomains(virConnectPtr conn)
{ {
testConnPtr privconn = conn->privateData; testConnPtr privconn = conn->privateData;
unsigned int numActive = 0, i; int count;
testDriverLock(privconn); testDriverLock(privconn);
for (i = 0 ; i < privconn->domains.count ; i++) count = virDomainObjListNumOfDomains(&privconn->domains, 1);
if (virDomainIsActive(privconn->domains.objs[i]))
numActive++;
testDriverUnlock(privconn); testDriverUnlock(privconn);
return numActive; return count;
} }
static virDomainPtr static virDomainPtr
@ -1196,15 +1200,10 @@ static int testListDomains (virConnectPtr conn,
int maxids) int maxids)
{ {
testConnPtr privconn = conn->privateData; testConnPtr privconn = conn->privateData;
unsigned int n = 0, i; int n;
testDriverLock(privconn); testDriverLock(privconn);
for (i = 0 ; i < privconn->domains.count && n < maxids ; i++) { n = virDomainObjListGetActiveIDs(&privconn->domains, ids, maxids);
virDomainObjLock(privconn->domains.objs[i]);
if (virDomainIsActive(privconn->domains.objs[i]))
ids[n++] = privconn->domains.objs[i]->def->id;
virDomainObjUnlock(privconn->domains.objs[i]);
}
testDriverUnlock(privconn); testDriverUnlock(privconn);
return n; return n;
@ -1875,47 +1874,28 @@ cleanup:
static int testNumOfDefinedDomains(virConnectPtr conn) { static int testNumOfDefinedDomains(virConnectPtr conn) {
testConnPtr privconn = conn->privateData; testConnPtr privconn = conn->privateData;
unsigned int numInactive = 0, i; int count;
testDriverLock(privconn); testDriverLock(privconn);
for (i = 0 ; i < privconn->domains.count ; i++) { count = virDomainObjListNumOfDomains(&privconn->domains, 0);
virDomainObjLock(privconn->domains.objs[i]);
if (!virDomainIsActive(privconn->domains.objs[i]))
numInactive++;
virDomainObjUnlock(privconn->domains.objs[i]);
}
testDriverUnlock(privconn); testDriverUnlock(privconn);
return numInactive; return count;
} }
static int testListDefinedDomains(virConnectPtr conn, static int testListDefinedDomains(virConnectPtr conn,
char **const names, char **const names,
int maxnames) { int maxnames) {
testConnPtr privconn = conn->privateData; testConnPtr privconn = conn->privateData;
unsigned int n = 0, i; int n;
testDriverLock(privconn); testDriverLock(privconn);
memset(names, 0, sizeof(*names)*maxnames); memset(names, 0, sizeof(*names)*maxnames);
for (i = 0 ; i < privconn->domains.count && n < maxnames ; i++) { n = virDomainObjListGetInactiveNames(&privconn->domains, names, maxnames);
virDomainObjLock(privconn->domains.objs[i]);
if (!virDomainIsActive(privconn->domains.objs[i]) &&
!(names[n++] = strdup(privconn->domains.objs[i]->def->name))) {
virDomainObjUnlock(privconn->domains.objs[i]);
goto no_memory;
}
virDomainObjUnlock(privconn->domains.objs[i]);
}
testDriverUnlock(privconn); testDriverUnlock(privconn);
return n; return n;
no_memory:
virReportOOMError(conn);
for (n = 0 ; n < maxnames ; n++)
VIR_FREE(names[n]);
testDriverUnlock(privconn);
return -1;
} }
static virDomainPtr testDomainDefineXML(virConnectPtr conn, static virDomainPtr testDomainDefineXML(virConnectPtr conn,

View File

@ -114,10 +114,32 @@ static int umlMonitorCommand (virConnectPtr conn,
static struct uml_driver *uml_driver = NULL; static struct uml_driver *uml_driver = NULL;
struct umlAutostartData {
struct uml_driver *driver;
virConnectPtr conn;
};
static void
umlAutostartDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
const struct umlAutostartData *data = opaque;
virDomainObjLock(vm);
if (vm->autostart &&
!virDomainIsActive(vm)) {
virResetLastError();
if (umlStartVMDaemon(data->conn, data->driver, vm) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
vm->def->name, err->message);
}
}
virDomainObjUnlock(vm);
}
static void static void
umlAutostartConfigs(struct uml_driver *driver) { umlAutostartConfigs(struct uml_driver *driver) {
unsigned int i;
/* XXX: Figure out a better way todo this. The domain /* XXX: Figure out a better way todo this. The domain
* startup code needs a connection handle in order * startup code needs a connection handle in order
* to lookup the bridge associated with a virtual * to lookup the bridge associated with a virtual
@ -128,15 +150,9 @@ umlAutostartConfigs(struct uml_driver *driver) {
"uml:///session"); "uml:///session");
/* Ignoring NULL conn which is mostly harmless here */ /* Ignoring NULL conn which is mostly harmless here */
for (i = 0 ; i < driver->domains.count ; i++) { struct umlAutostartData data = { driver, conn };
if (driver->domains.objs[i]->autostart &&
!virDomainIsActive(driver->domains.objs[i]) && virHashForEach(driver->domains.objs, umlAutostartDomain, &data);
umlStartVMDaemon(conn, driver, driver->domains.objs[i]) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
driver->domains.objs[i]->def->name, err->message);
}
}
if (conn) if (conn)
virConnectClose(conn); virConnectClose(conn);
@ -320,6 +336,9 @@ umlStartup(int privileged) {
uml_driver->nextvmid = 1; uml_driver->nextvmid = 1;
uml_driver->inotifyWatch = -1; uml_driver->inotifyWatch = -1;
if (virDomainObjListInit(&uml_driver->domains) < 0)
goto error;
userdir = virGetUserDirectory(NULL, uid); userdir = virGetUserDirectory(NULL, uid);
if (!userdir) if (!userdir)
goto error; goto error;
@ -449,24 +468,30 @@ umlReload(void) {
*/ */
static int static int
umlActive(void) { umlActive(void) {
unsigned int i;
int active = 0; int active = 0;
if (!uml_driver) if (!uml_driver)
return 0; return 0;
umlDriverLock(uml_driver); umlDriverLock(uml_driver);
for (i = 0 ; i < uml_driver->domains.count ; i++) { active = virDomainObjListNumOfDomains(&uml_driver->domains, 1);
virDomainObjLock(uml_driver->domains.objs[i]);
if (virDomainIsActive(uml_driver->domains.objs[i]))
active = 1;
virDomainObjUnlock(uml_driver->domains.objs[i]);
}
umlDriverUnlock(uml_driver); umlDriverUnlock(uml_driver);
return active; return active;
} }
static void
umlShutdownOneVM(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr dom = payload;
struct uml_driver *driver = opaque;
virDomainObjLock(dom);
if (virDomainIsActive(dom))
umlShutdownVMDaemon(NULL, driver, dom);
virDomainObjUnlock(dom);
}
/** /**
* umlShutdown: * umlShutdown:
* *
@ -474,8 +499,6 @@ umlActive(void) {
*/ */
static int static int
umlShutdown(void) { umlShutdown(void) {
unsigned int i;
if (!uml_driver) if (!uml_driver)
return -1; return -1;
@ -485,16 +508,11 @@ umlShutdown(void) {
close(uml_driver->inotifyFD); close(uml_driver->inotifyFD);
virCapabilitiesFree(uml_driver->caps); virCapabilitiesFree(uml_driver->caps);
/* shutdown active VMs */ /* shutdown active VMs
for (i = 0 ; i < uml_driver->domains.count ; i++) { * XXX allow them to stay around & reconnect */
virDomainObjPtr dom = uml_driver->domains.objs[i]; virHashForEach(uml_driver->domains.objs, umlShutdownOneVM, uml_driver);
virDomainObjLock(dom);
if (virDomainIsActive(dom))
umlShutdownVMDaemon(NULL, uml_driver, dom);
virDomainObjUnlock(dom);
}
virDomainObjListFree(&uml_driver->domains); virDomainObjListDeinit(&uml_driver->domains);
VIR_FREE(uml_driver->logDir); VIR_FREE(uml_driver->logDir);
VIR_FREE(uml_driver->configDir); VIR_FREE(uml_driver->configDir);
@ -1145,30 +1163,20 @@ umlGetHostname (virConnectPtr conn)
static int umlListDomains(virConnectPtr conn, int *ids, int nids) { static int umlListDomains(virConnectPtr conn, int *ids, int nids) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int got = 0, i; int n;
umlDriverLock(driver); umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nids ; i++) { n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id;
virDomainObjUnlock(driver->domains.objs[i]);
}
umlDriverUnlock(driver); umlDriverUnlock(driver);
return got; return n;
} }
static int umlNumDomains(virConnectPtr conn) { static int umlNumDomains(virConnectPtr conn) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int n = 0, i; int n;
umlDriverLock(driver); umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { n = virDomainObjListNumOfDomains(&driver->domains, 1);
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
umlDriverUnlock(driver); umlDriverUnlock(driver);
return n; return n;
@ -1481,42 +1489,21 @@ cleanup:
static int umlListDefinedDomains(virConnectPtr conn, static int umlListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) { char **const names, int nnames) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int got = 0, i; int n;
umlDriverLock(driver); umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) { n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
virReportOOMError(conn);
virDomainObjUnlock(driver->domains.objs[i]);
goto cleanup;
}
}
virDomainObjUnlock(driver->domains.objs[i]);
}
umlDriverUnlock(driver); umlDriverUnlock(driver);
return got; return n;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
umlDriverUnlock(driver);
return -1;
} }
static int umlNumDefinedDomains(virConnectPtr conn) { static int umlNumDefinedDomains(virConnectPtr conn) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int n = 0, i; int n;
umlDriverLock(driver); umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) { n = virDomainObjListNumOfDomains(&driver->domains, 0);
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
umlDriverUnlock(driver); umlDriverUnlock(driver);
return n; return n;

View File

@ -103,7 +103,6 @@ typedef struct {
virMutex lock; virMutex lock;
int version; int version;
virDomainObjList domains;
virCapsPtr caps; virCapsPtr caps;
IVirtualBox *vboxObj; IVirtualBox *vboxObj;
@ -485,7 +484,6 @@ static void vboxUninitialize(vboxGlobalData *data) {
if (data->pFuncs) if (data->pFuncs)
data->pFuncs->pfnComUninitialize(); data->pFuncs->pfnComUninitialize();
virDomainObjListFree(&data->domains);
virCapabilitiesFree(data->caps); virCapabilitiesFree(data->caps);
#if VBOX_API_VERSION == 2002 #if VBOX_API_VERSION == 2002
/* No domainEventCallbacks in 2.2.* version */ /* No domainEventCallbacks in 2.2.* version */