]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Split virDomainObjList into a separate file
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 17 Jul 2015 09:11:23 +0000 (11:11 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 30 Nov 2015 12:55:10 +0000 (13:55 +0100)
Our domain_conf.* files are big enough. Not only they contain XML
parsing code, but they served as a storage of all functions whose
name is virDomain prefixed. This is just wrong as it gathers not
related functions (and modules) into one big file which is then
harder to maintain. Split virDomainObjList module into a separate
file called virdomainobjlist.[ch].

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
21 files changed:
po/POTFILES.in
src/Makefile.am
src/bhyve/bhyve_driver.c
src/bhyve/bhyve_utils.h
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/nwfilter_conf.h
src/conf/virdomainobjlist.c [new file with mode: 0644]
src/conf/virdomainobjlist.h [new file with mode: 0644]
src/esx/esx_driver.c
src/hyperv/hyperv_driver.c
src/libvirt_private.syms
src/libxl/libxl_conf.h
src/openvz/openvz_conf.h
src/test/test_driver.c
src/uml/uml_conf.h
src/util/virclosecallbacks.h
src/vbox/vbox_common.c
src/vmware/vmware_conf.h
src/vz/vz_utils.h
tools/virsh-domain-monitor.c

index 9cc129f06f98ee6f0f974fcfbe1f29f275b3d879..82e8d3e814cac575556d668f25e7dc1521e89b0f 100644 (file)
@@ -37,6 +37,7 @@ src/conf/secret_conf.c
 src/conf/snapshot_conf.c
 src/conf/storage_conf.c
 src/conf/virchrdev.c
+src/conf/virdomainobjlist.c
 src/cpu/cpu.c
 src/cpu/cpu_generic.c
 src/cpu/cpu_map.c
index 52552fea2c8dddcb40ce7d5bec6c7a9aefe3470a..bcbee9de11d66767da456df929b4868df81b6fee 100644 (file)
@@ -319,7 +319,8 @@ DOMAIN_CONF_SOURCES =                                               \
                conf/domain_audit.c conf/domain_audit.h         \
                conf/domain_nwfilter.c conf/domain_nwfilter.h   \
                conf/snapshot_conf.c conf/snapshot_conf.h       \
-               conf/numa_conf.c conf/numa_conf.h
+               conf/numa_conf.c conf/numa_conf.h       \
+               conf/virdomainobjlist.c conf/virdomainobjlist.h
 
 OBJECT_EVENT_SOURCES =                                         \
                conf/object_event.c conf/object_event.h \
index 4840a0eb8c534076dcebd62118687ebd566c2f90..fa1cdea24ae1f81779f394c7a41bd3136db997a0 100644 (file)
 #include "interface_conf.h"
 #include "domain_audit.h"
 #include "domain_event.h"
-#include "domain_conf.h"
 #include "snapshot_conf.h"
 #include "fdstream.h"
 #include "storage_conf.h"
 #include "node_device_conf.h"
+#include "virdomainobjlist.h"
 #include "virxml.h"
 #include "virthread.h"
 #include "virlog.h"
index 4bccdccd970528fcebfb80bf28b58f83b2453e06..9a911608ccb42c9bf57e704e156d32b5e6be74f2 100644 (file)
@@ -24,8 +24,8 @@
 
 # include "driver.h"
 # include "domain_event.h"
-# include "domain_conf.h"
 # include "configmake.h"
+# include "virdomainobjlist.h"
 # include "virthread.h"
 # include "virclosecallbacks.h"
 
index 99ca81f3a913b7c48486ce5bb5fae2c465441235..e6102a0b4254f4e88fc454c2d49642f2ad896c74 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <config.h>
 
-#include <dirent.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
 VIR_LOG_INIT("conf.domain_conf");
 
-struct _virDomainObjList {
-    virObjectLockable parent;
-
-    /* uuid string -> virDomainObj  mapping
-     * for O(1), lockless lookup-by-uuid */
-    virHashTable *objs;
-
-    /* name -> virDomainObj mapping for O(1),
-     * lockless lookup-by-name */
-    virHashTable *objsName;
-};
-
-
 /* This structure holds various callbacks and data needed
  * while parsing and creating domain XMLs */
 struct _virDomainXMLOption {
@@ -827,10 +813,8 @@ VIR_ENUM_IMPL(virDomainMemoryModel, VIR_DOMAIN_MEMORY_MODEL_LAST,
               "", "dimm")
 
 static virClassPtr virDomainObjClass;
-static virClassPtr virDomainObjListClass;
 static virClassPtr virDomainXMLOptionClass;
 static void virDomainObjDispose(void *obj);
-static void virDomainObjListDispose(void *obj);
 static void virDomainXMLOptionClassDispose(void *obj);
 
 static int virDomainObjOnceInit(void)
@@ -841,12 +825,6 @@ static int virDomainObjOnceInit(void)
                                           virDomainObjDispose)))
         return -1;
 
-    if (!(virDomainObjListClass = virClassNew(virClassForObjectLockable(),
-                                              "virDomainObjList",
-                                              sizeof(virDomainObjList),
-                                              virDomainObjListDispose)))
-        return -1;
-
     if (!(virDomainXMLOptionClass = virClassNew(virClassForObject(),
                                                 "virDomainXMLOption",
                                                 sizeof(virDomainXMLOption),
@@ -1196,134 +1174,6 @@ virDomainDeviceDefCheckUnsupportedMemoryDevice(virDomainDeviceDefPtr dev)
 }
 
 
-virDomainObjListPtr virDomainObjListNew(void)
-{
-    virDomainObjListPtr doms;
-
-    if (virDomainObjInitialize() < 0)
-        return NULL;
-
-    if (!(doms = virObjectLockableNew(virDomainObjListClass)))
-        return NULL;
-
-    if (!(doms->objs = virHashCreate(50, virObjectFreeHashData)) ||
-        !(doms->objsName = virHashCreate(50, virObjectFreeHashData))) {
-        virObjectUnref(doms);
-        return NULL;
-    }
-
-    return doms;
-}
-
-
-static void virDomainObjListDispose(void *obj)
-{
-    virDomainObjListPtr doms = obj;
-
-    virHashFree(doms->objs);
-    virHashFree(doms->objsName);
-}
-
-
-static int virDomainObjListSearchID(const void *payload,
-                                    const void *name ATTRIBUTE_UNUSED,
-                                    const void *data)
-{
-    virDomainObjPtr obj = (virDomainObjPtr)payload;
-    const int *id = data;
-    int want = 0;
-
-    virObjectLock(obj);
-    if (virDomainObjIsActive(obj) &&
-        obj->def->id == *id)
-        want = 1;
-    virObjectUnlock(obj);
-    return want;
-}
-
-virDomainObjPtr virDomainObjListFindByID(virDomainObjListPtr doms,
-                                         int id)
-{
-    virDomainObjPtr obj;
-    virObjectLock(doms);
-    obj = virHashSearch(doms->objs, virDomainObjListSearchID, &id);
-    if (obj) {
-        virObjectLock(obj);
-        if (obj->removing) {
-            virObjectUnlock(obj);
-            obj = NULL;
-        }
-    }
-    virObjectUnlock(doms);
-    return obj;
-}
-
-
-static virDomainObjPtr
-virDomainObjListFindByUUIDInternal(virDomainObjListPtr doms,
-                                   const unsigned char *uuid,
-                                   bool ref)
-{
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-    virDomainObjPtr obj;
-
-    virObjectLock(doms);
-    virUUIDFormat(uuid, uuidstr);
-
-    obj = virHashLookup(doms->objs, uuidstr);
-    if (ref) {
-        virObjectRef(obj);
-        virObjectUnlock(doms);
-    }
-    if (obj) {
-        virObjectLock(obj);
-        if (obj->removing) {
-            virObjectUnlock(obj);
-            if (ref)
-                virObjectUnref(obj);
-            obj = NULL;
-        }
-    }
-    if (!ref)
-        virObjectUnlock(doms);
-    return obj;
-}
-
-virDomainObjPtr
-virDomainObjListFindByUUID(virDomainObjListPtr doms,
-                           const unsigned char *uuid)
-{
-    return virDomainObjListFindByUUIDInternal(doms, uuid, false);
-}
-
-virDomainObjPtr
-virDomainObjListFindByUUIDRef(virDomainObjListPtr doms,
-                              const unsigned char *uuid)
-{
-    return virDomainObjListFindByUUIDInternal(doms, uuid, true);
-}
-
-virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
-                                           const char *name)
-{
-    virDomainObjPtr obj;
-
-    virObjectLock(doms);
-    obj = virHashLookup(doms->objsName, name);
-    virObjectRef(obj);
-    virObjectUnlock(doms);
-    if (obj) {
-        virObjectLock(obj);
-        if (obj->removing) {
-            virObjectUnlock(obj);
-            virObjectUnref(obj);
-            obj = NULL;
-        }
-    }
-    return obj;
-}
-
-
 bool virDomainObjTaint(virDomainObjPtr obj,
                        virDomainTaintFlags taint)
 {
@@ -2821,153 +2671,6 @@ virDomainObjWaitUntil(virDomainObjPtr vm,
 }
 
 
-/*
- *
- * If flags & VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE then
- * this will refuse updating an existing def if the
- * current def is Live
- *
- * If flags & VIR_DOMAIN_OBJ_LIST_ADD_LIVE then
- * the @def being added is assumed to represent a
- * live config, not a future inactive config
- *
- */
-static virDomainObjPtr
-virDomainObjListAddLocked(virDomainObjListPtr doms,
-                          virDomainDefPtr def,
-                          virDomainXMLOptionPtr xmlopt,
-                          unsigned int flags,
-                          virDomainDefPtr *oldDef)
-{
-    virDomainObjPtr vm;
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-
-    if (oldDef)
-        *oldDef = NULL;
-
-    virUUIDFormat(def->uuid, uuidstr);
-
-    /* See if a VM with matching UUID already exists */
-    if ((vm = virHashLookup(doms->objs, uuidstr))) {
-        virObjectLock(vm);
-        /* UUID matches, but if names don't match, refuse it */
-        if (STRNEQ(vm->def->name, def->name)) {
-            virUUIDFormat(vm->def->uuid, uuidstr);
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           _("domain '%s' is already defined with uuid %s"),
-                           vm->def->name, uuidstr);
-            goto error;
-        }
-
-        if (flags & VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE) {
-            /* UUID & name match, but if VM is already active, refuse it */
-            if (virDomainObjIsActive(vm)) {
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("domain '%s' is already active"),
-                               vm->def->name);
-                goto error;
-            }
-            if (!vm->persistent) {
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("domain '%s' is already being started"),
-                               vm->def->name);
-                goto error;
-            }
-        }
-
-        virDomainObjAssignDef(vm,
-                              def,
-                              !!(flags & VIR_DOMAIN_OBJ_LIST_ADD_LIVE),
-                              oldDef);
-    } else {
-        /* UUID does not match, but if a name matches, refuse it */
-        if ((vm = virHashLookup(doms->objsName, def->name))) {
-            virObjectLock(vm);
-            virUUIDFormat(vm->def->uuid, uuidstr);
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           _("domain '%s' already exists with uuid %s"),
-                           def->name, uuidstr);
-            goto error;
-        }
-
-        if (!(vm = virDomainObjNew(xmlopt)))
-            goto cleanup;
-        vm->def = def;
-
-        virUUIDFormat(def->uuid, uuidstr);
-        if (virHashAddEntry(doms->objs, uuidstr, vm) < 0) {
-            virObjectUnref(vm);
-            return NULL;
-        }
-
-        if (virHashAddEntry(doms->objsName, def->name, vm) < 0) {
-            virHashRemoveEntry(doms->objs, uuidstr);
-            return NULL;
-        }
-
-        /* Since domain is in two hash tables, increment the
-         * reference counter */
-        virObjectRef(vm);
-    }
- cleanup:
-    return vm;
-
- error:
-    virObjectUnlock(vm);
-    vm = NULL;
-    goto cleanup;
-}
-
-
-virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
-                                    virDomainDefPtr def,
-                                    virDomainXMLOptionPtr xmlopt,
-                                    unsigned int flags,
-                                    virDomainDefPtr *oldDef)
-{
-    virDomainObjPtr ret;
-
-    virObjectLock(doms);
-    ret = virDomainObjListAddLocked(doms, def, xmlopt, flags, oldDef);
-    virObjectUnlock(doms);
-    return ret;
-}
-
-
-int
-virDomainObjListRenameAddNew(virDomainObjListPtr doms,
-                             virDomainObjPtr vm,
-                             const char *name)
-{
-    int ret = -1;
-    virObjectLock(doms);
-
-    /* Add new name into the hash table of domain names. */
-    if (virHashAddEntry(doms->objsName, name, vm) < 0)
-        goto cleanup;
-
-    /* Okay, this is crazy. virHashAddEntry() does not increment
-     * the refcounter of @vm, but virHashRemoveEntry() does
-     * decrement it. We need to work around it. */
-    virObjectRef(vm);
-
-    ret = 0;
- cleanup:
-    virObjectUnlock(doms);
-    return ret;
-}
-
-
-int
-virDomainObjListRenameRemove(virDomainObjListPtr doms, const char *name)
-{
-    virObjectLock(doms);
-    virHashRemoveEntry(doms->objsName, name);
-    virObjectUnlock(doms);
-    return 0;
-}
-
-
 /*
  * Mark the running VM config as transient. Ensures transient hotplug
  * operations do not persist past shutdown.
@@ -3189,48 +2892,6 @@ virDomainObjGetOneDef(virDomainObjPtr vm,
 }
 
 
-/*
- * 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 using it
- */
-void virDomainObjListRemove(virDomainObjListPtr doms,
-                            virDomainObjPtr dom)
-{
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-
-    dom->removing = true;
-    virUUIDFormat(dom->def->uuid, uuidstr);
-    virObjectRef(dom);
-    virObjectUnlock(dom);
-
-    virObjectLock(doms);
-    virObjectLock(dom);
-    virHashRemoveEntry(doms->objs, uuidstr);
-    virHashRemoveEntry(doms->objsName, dom->def->name);
-    virObjectUnlock(dom);
-    virObjectUnref(dom);
-    virObjectUnlock(doms);
-}
-
-/* The caller must hold lock on 'doms' in addition to 'virDomainObjListRemove'
- * requirements
- *
- * Can be used to remove current element while iterating with
- * virDomainObjListForEach
- */
-void virDomainObjListRemoveLocked(virDomainObjListPtr doms,
-                                  virDomainObjPtr dom)
-{
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-
-    virUUIDFormat(dom->def->uuid, uuidstr);
-
-    virHashRemoveEntry(doms->objs, uuidstr);
-    virHashRemoveEntry(doms->objsName, dom->def->name);
-    virObjectUnlock(dom);
-}
-
 static int
 virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddressPtr addr)
 {
@@ -22832,179 +22493,6 @@ virDomainSaveStatus(virDomainXMLOptionPtr xmlopt,
 }
 
 
-static virDomainObjPtr
-virDomainObjListLoadConfig(virDomainObjListPtr doms,
-                           virCapsPtr caps,
-                           virDomainXMLOptionPtr xmlopt,
-                           const char *configDir,
-                           const char *autostartDir,
-                           const char *name,
-                           virDomainLoadConfigNotify notify,
-                           void *opaque)
-{
-    char *configFile = NULL, *autostartLink = NULL;
-    virDomainDefPtr def = NULL;
-    virDomainObjPtr dom;
-    int autostart;
-    virDomainDefPtr oldDef = NULL;
-
-    if ((configFile = virDomainConfigFile(configDir, name)) == NULL)
-        goto error;
-    if (!(def = virDomainDefParseFile(configFile, caps, xmlopt,
-                                      VIR_DOMAIN_DEF_PARSE_INACTIVE |
-                                      VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS)))
-        goto error;
-
-    if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL)
-        goto error;
-
-    if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0)
-        goto error;
-
-    if (!(dom = virDomainObjListAddLocked(doms, def, xmlopt, 0, &oldDef)))
-        goto error;
-
-    dom->autostart = autostart;
-
-    if (notify)
-        (*notify)(dom, oldDef == NULL, opaque);
-
-    virDomainDefFree(oldDef);
-    VIR_FREE(configFile);
-    VIR_FREE(autostartLink);
-    return dom;
-
- error:
-    VIR_FREE(configFile);
-    VIR_FREE(autostartLink);
-    virDomainDefFree(def);
-    return NULL;
-}
-
-static virDomainObjPtr
-virDomainObjListLoadStatus(virDomainObjListPtr doms,
-                           const char *statusDir,
-                           const char *name,
-                           virCapsPtr caps,
-                           virDomainXMLOptionPtr xmlopt,
-                           virDomainLoadConfigNotify notify,
-                           void *opaque)
-{
-    char *statusFile = NULL;
-    virDomainObjPtr obj = NULL;
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-
-    if ((statusFile = virDomainConfigFile(statusDir, name)) == NULL)
-        goto error;
-
-    if (!(obj = virDomainObjParseFile(statusFile, caps, xmlopt,
-                                      VIR_DOMAIN_DEF_PARSE_STATUS |
-                                      VIR_DOMAIN_DEF_PARSE_ACTUAL_NET |
-                                      VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES |
-                                      VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS)))
-        goto error;
-
-    virUUIDFormat(obj->def->uuid, uuidstr);
-
-    if (virHashLookup(doms->objs, uuidstr) != NULL) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("unexpected domain %s already exists"),
-                       obj->def->name);
-        goto error;
-    }
-
-    if (virHashAddEntry(doms->objs, uuidstr, obj) < 0)
-        goto error;
-
-    if (virHashAddEntry(doms->objsName, obj->def->name, obj) < 0) {
-        virHashRemoveEntry(doms->objs, uuidstr);
-        goto error;
-    }
-
-    /* Since domain is in two hash tables, increment the
-     * reference counter */
-    virObjectRef(obj);
-
-    if (notify)
-        (*notify)(obj, 1, opaque);
-
-    VIR_FREE(statusFile);
-    return obj;
-
- error:
-    virObjectUnref(obj);
-    VIR_FREE(statusFile);
-    return NULL;
-}
-
-int
-virDomainObjListLoadAllConfigs(virDomainObjListPtr doms,
-                               const char *configDir,
-                               const char *autostartDir,
-                               int liveStatus,
-                               virCapsPtr caps,
-                               virDomainXMLOptionPtr xmlopt,
-                               virDomainLoadConfigNotify notify,
-                               void *opaque)
-{
-    DIR *dir;
-    struct dirent *entry;
-    int ret = -1;
-
-    VIR_INFO("Scanning for configs in %s", configDir);
-
-    if (!(dir = opendir(configDir))) {
-        if (errno == ENOENT)
-            return 0;
-        virReportSystemError(errno,
-                             _("Failed to open dir '%s'"),
-                             configDir);
-        return -1;
-    }
-
-    virObjectLock(doms);
-
-    while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
-        virDomainObjPtr dom;
-
-        if (entry->d_name[0] == '.')
-            continue;
-
-        if (!virFileStripSuffix(entry->d_name, ".xml"))
-            continue;
-
-        /* NB: ignoring errors, so one malformed config doesn't
-           kill the whole process */
-        VIR_INFO("Loading config file '%s.xml'", entry->d_name);
-        if (liveStatus)
-            dom = virDomainObjListLoadStatus(doms,
-                                             configDir,
-                                             entry->d_name,
-                                             caps,
-                                             xmlopt,
-                                             notify,
-                                             opaque);
-        else
-            dom = virDomainObjListLoadConfig(doms,
-                                             caps,
-                                             xmlopt,
-                                             configDir,
-                                             autostartDir,
-                                             entry->d_name,
-                                             notify,
-                                             opaque);
-        if (dom) {
-            if (!liveStatus)
-                dom->persistent = 1;
-            virObjectUnlock(dom);
-        }
-    }
-
-    closedir(dir);
-    virObjectUnlock(doms);
-    return ret;
-}
-
 int
 virDomainDeleteConfig(const char *configDir,
                       const char *autostartDir,
@@ -23121,178 +22609,6 @@ virDomainGetFilesystemForTarget(virDomainDefPtr def,
 }
 
 
-struct virDomainObjListData {
-    virDomainObjListACLFilter filter;
-    virConnectPtr conn;
-    bool active;
-    int count;
-};
-
-static void
-virDomainObjListCount(void *payload,
-                      const void *name ATTRIBUTE_UNUSED,
-                      void *opaque)
-{
-    virDomainObjPtr obj = payload;
-    struct virDomainObjListData *data = opaque;
-    virObjectLock(obj);
-    if (data->filter &&
-        !data->filter(data->conn, obj->def))
-        goto cleanup;
-    if (virDomainObjIsActive(obj)) {
-        if (data->active)
-            data->count++;
-    } else {
-        if (!data->active)
-            data->count++;
-    }
- cleanup:
-    virObjectUnlock(obj);
-}
-
-int
-virDomainObjListNumOfDomains(virDomainObjListPtr doms,
-                             bool active,
-                             virDomainObjListACLFilter filter,
-                             virConnectPtr conn)
-{
-    struct virDomainObjListData data = { filter, conn, active, 0 };
-    virObjectLock(doms);
-    virHashForEach(doms->objs, virDomainObjListCount, &data);
-    virObjectUnlock(doms);
-    return data.count;
-}
-
-struct virDomainIDData {
-    virDomainObjListACLFilter filter;
-    virConnectPtr conn;
-    int numids;
-    int maxids;
-    int *ids;
-};
-
-static void
-virDomainObjListCopyActiveIDs(void *payload,
-                              const void *name ATTRIBUTE_UNUSED,
-                              void *opaque)
-{
-    virDomainObjPtr obj = payload;
-    struct virDomainIDData *data = opaque;
-    virObjectLock(obj);
-    if (data->filter &&
-        !data->filter(data->conn, obj->def))
-        goto cleanup;
-    if (virDomainObjIsActive(obj) && data->numids < data->maxids)
-        data->ids[data->numids++] = obj->def->id;
- cleanup:
-    virObjectUnlock(obj);
-}
-
-int
-virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
-                             int *ids,
-                             int maxids,
-                             virDomainObjListACLFilter filter,
-                             virConnectPtr conn)
-{
-    struct virDomainIDData data = { filter, conn,
-                                    0, maxids, ids };
-    virObjectLock(doms);
-    virHashForEach(doms->objs, virDomainObjListCopyActiveIDs, &data);
-    virObjectUnlock(doms);
-    return data.numids;
-}
-
-struct virDomainNameData {
-    virDomainObjListACLFilter filter;
-    virConnectPtr conn;
-    int oom;
-    int numnames;
-    int maxnames;
-    char **const names;
-};
-
-static void
-virDomainObjListCopyInactiveNames(void *payload,
-                                  const void *name ATTRIBUTE_UNUSED,
-                                  void *opaque)
-{
-    virDomainObjPtr obj = payload;
-    struct virDomainNameData *data = opaque;
-
-    if (data->oom)
-        return;
-
-    virObjectLock(obj);
-    if (data->filter &&
-        !data->filter(data->conn, obj->def))
-        goto cleanup;
-    if (!virDomainObjIsActive(obj) && data->numnames < data->maxnames) {
-        if (VIR_STRDUP(data->names[data->numnames], obj->def->name) < 0)
-            data->oom = 1;
-        else
-            data->numnames++;
-    }
- cleanup:
-    virObjectUnlock(obj);
-}
-
-
-int
-virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
-                                 char **const names,
-                                 int maxnames,
-                                 virDomainObjListACLFilter filter,
-                                 virConnectPtr conn)
-{
-    struct virDomainNameData data = { filter, conn,
-                                      0, 0, maxnames, names };
-    size_t i;
-    virObjectLock(doms);
-    virHashForEach(doms->objs, virDomainObjListCopyInactiveNames, &data);
-    virObjectUnlock(doms);
-    if (data.oom) {
-        for (i = 0; i < data.numnames; i++)
-            VIR_FREE(data.names[i]);
-        return -1;
-    }
-
-    return data.numnames;
-}
-
-
-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,
-    };
-    virObjectLock(doms);
-    virHashForEach(doms->objs, virDomainObjListHelper, &data);
-    virObjectUnlock(doms);
-    return data.ret;
-}
-
-
 int
 virDomainChrDefForeach(virDomainDefPtr def,
                        bool abortOnError,
@@ -24007,258 +23323,6 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
 }
 
 
-#define MATCH(FLAG) (filter & (FLAG))
-static bool
-virDomainObjMatchFilter(virDomainObjPtr vm,
-                        unsigned int filter)
-{
-    /* filter by active state */
-    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) &&
-        !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) &&
-           virDomainObjIsActive(vm)) ||
-          (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) &&
-           !virDomainObjIsActive(vm))))
-        return false;
-
-    /* filter by persistence */
-    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT) &&
-        !((MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT) &&
-           vm->persistent) ||
-          (MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
-           !vm->persistent)))
-        return false;
-
-    /* filter by domain state */
-    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE)) {
-        int st = virDomainObjGetState(vm, NULL);
-        if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
-               st == VIR_DOMAIN_RUNNING) ||
-              (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
-               st == VIR_DOMAIN_PAUSED) ||
-              (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
-               st == VIR_DOMAIN_SHUTOFF) ||
-              (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
-               (st != VIR_DOMAIN_RUNNING &&
-                st != VIR_DOMAIN_PAUSED &&
-                st != VIR_DOMAIN_SHUTOFF))))
-            return false;
-    }
-
-    /* filter by existence of managed save state */
-    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE) &&
-        !((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) &&
-           vm->hasManagedSave) ||
-          (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) &&
-           !vm->hasManagedSave)))
-        return false;
-
-    /* filter by autostart option */
-    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART) &&
-        !((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && vm->autostart) ||
-          (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && !vm->autostart)))
-        return false;
-
-    /* filter by snapshot existence */
-    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)) {
-        int nsnap = virDomainSnapshotObjListNum(vm->snapshots, NULL, 0);
-        if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && nsnap > 0) ||
-              (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && nsnap <= 0)))
-            return false;
-    }
-
-    return true;
-}
-#undef MATCH
-
-
-struct virDomainListData {
-    virDomainObjPtr *vms;
-    size_t nvms;
-};
-
-
-static void
-virDomainObjListCollectIterator(void *payload,
-                                const void *name ATTRIBUTE_UNUSED,
-                                void *opaque)
-{
-    struct virDomainListData *data = opaque;
-
-    data->vms[data->nvms++] = virObjectRef(payload);
-}
-
-
-static void
-virDomainObjListFilter(virDomainObjPtr **list,
-                       size_t *nvms,
-                       virConnectPtr conn,
-                       virDomainObjListACLFilter filter,
-                       unsigned int flags)
-{
-    size_t i = 0;
-
-    while (i < *nvms) {
-        virDomainObjPtr vm = (*list)[i];
-
-        virObjectLock(vm);
-
-        /* do not list the object if:
-         * 1) it's being removed.
-         * 2) connection does not have ACL to see it
-         * 3) it doesn't match the filter
-         */
-        if (vm->removing ||
-            (filter && !filter(conn, vm->def)) ||
-            !virDomainObjMatchFilter(vm, flags)) {
-            virObjectUnlock(vm);
-            virObjectUnref(vm);
-            VIR_DELETE_ELEMENT(*list, i, *nvms);
-            continue;
-        }
-
-        virObjectUnlock(vm);
-        i++;
-    }
-}
-
-
-int
-virDomainObjListCollect(virDomainObjListPtr domlist,
-                        virConnectPtr conn,
-                        virDomainObjPtr **vms,
-                        size_t *nvms,
-                        virDomainObjListACLFilter filter,
-                        unsigned int flags)
-{
-    struct virDomainListData data = { NULL, 0 };
-    ssize_t hash_size;
-
-    virObjectLock(domlist);
-    if ((hash_size = virHashSize(domlist->objs)) < 0 ||
-        (VIR_ALLOC_N(data.vms, hash_size) < 0)) {
-        virObjectUnlock(domlist);
-        return -1;
-    }
-
-    virHashForEach(domlist->objs, virDomainObjListCollectIterator, &data);
-    virObjectUnlock(domlist);
-
-    virDomainObjListFilter(&data.vms, &data.nvms, conn, filter, flags);
-
-    *nvms = data.nvms;
-    *vms = data.vms;
-
-    return 0;
-}
-
-
-int
-virDomainObjListConvert(virDomainObjListPtr domlist,
-                        virConnectPtr conn,
-                        virDomainPtr *doms,
-                        size_t ndoms,
-                        virDomainObjPtr **vms,
-                        size_t *nvms,
-                        virDomainObjListACLFilter filter,
-                        unsigned int flags,
-                        bool skip_missing)
-{
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-    virDomainObjPtr vm;
-    size_t i;
-
-    *nvms = 0;
-    *vms = NULL;
-
-    virObjectLock(domlist);
-    for (i = 0; i < ndoms; i++) {
-        virDomainPtr dom = doms[i];
-
-        virUUIDFormat(dom->uuid, uuidstr);
-
-        if (!(vm = virHashLookup(domlist->objs, uuidstr))) {
-            if (skip_missing)
-                continue;
-
-            virObjectUnlock(domlist);
-            virReportError(VIR_ERR_NO_DOMAIN,
-                           _("no domain with matching uuid '%s' (%s)"),
-                           uuidstr, dom->name);
-            goto error;
-        }
-
-        virObjectRef(vm);
-
-        if (VIR_APPEND_ELEMENT(*vms, *nvms, vm) < 0) {
-            virObjectUnlock(domlist);
-            virObjectUnref(vm);
-            goto error;
-        }
-    }
-    virObjectUnlock(domlist);
-
-    if (*vms)
-        virDomainObjListFilter(vms, nvms, conn, filter, flags);
-
-    return 0;
-
- error:
-    virObjectListFreeCount(*vms, *nvms);
-    *vms = NULL;
-    *nvms = 0;
-
-    return -1;
-}
-
-
-int
-virDomainObjListExport(virDomainObjListPtr domlist,
-                       virConnectPtr conn,
-                       virDomainPtr **domains,
-                       virDomainObjListACLFilter filter,
-                       unsigned int flags)
-{
-    virDomainObjPtr *vms = NULL;
-    virDomainPtr *doms = NULL;
-    size_t nvms = 0;
-    size_t i;
-    int ret = -1;
-
-    if (virDomainObjListCollect(domlist, conn, &vms, &nvms, filter, flags) < 0)
-        return -1;
-
-    if (domains) {
-        if (VIR_ALLOC_N(doms, nvms + 1) < 0)
-            goto cleanup;
-
-        for (i = 0; i < nvms; i++) {
-            virDomainObjPtr vm = vms[i];
-
-            virObjectLock(vm);
-
-            if (!(doms[i] = virGetDomain(conn, vm->def->name, vm->def->uuid))) {
-                virObjectUnlock(vm);
-                goto cleanup;
-            }
-
-            doms[i]->id = vm->def->id;
-
-            virObjectUnlock(vm);
-        }
-
-        *domains = doms;
-        doms = NULL;
-    }
-
-    ret = nvms;
-
- cleanup:
-    virObjectListFree(doms);
-    virObjectListFreeCount(vms, nvms);
-    return ret;
-}
-
-
 virSecurityLabelDefPtr
 virDomainDefGetSecurityLabelDef(virDomainDefPtr def, const char *model)
 {
index 315036768ef85ec78988c37337884637500020f2..90d8e13638c2310497d8dbe8a38b5d8bec6e71f3 100644 (file)
@@ -2406,9 +2406,6 @@ struct _virDomainObj {
     int taint;
 };
 
-typedef struct _virDomainObjList virDomainObjList;
-typedef virDomainObjList *virDomainObjListPtr;
-
 typedef bool (*virDomainObjListACLFilter)(virConnectPtr conn,
                                           virDomainDefPtr def);
 
@@ -2490,17 +2487,6 @@ virDomainObjIsActive(virDomainObjPtr dom)
 virDomainObjPtr virDomainObjNew(virDomainXMLOptionPtr caps)
     ATTRIBUTE_NONNULL(1);
 
-virDomainObjListPtr virDomainObjListNew(void);
-
-virDomainObjPtr virDomainObjListFindByID(virDomainObjListPtr doms,
-                                         int id);
-virDomainObjPtr virDomainObjListFindByUUID(virDomainObjListPtr doms,
-                                           const unsigned char *uuid);
-virDomainObjPtr virDomainObjListFindByUUIDRef(virDomainObjListPtr doms,
-                                              const unsigned char *uuid);
-virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
-                                           const char *name);
-
 void virDomainObjEndAPI(virDomainObjPtr *vm);
 
 bool virDomainObjTaint(virDomainObjPtr obj,
@@ -2597,20 +2583,6 @@ virDomainDefPtr virDomainDefNewFull(const char *name,
                                     const unsigned char *uuid,
                                     int id);
 
-enum {
-    VIR_DOMAIN_OBJ_LIST_ADD_LIVE = (1 << 0),
-    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE = (1 << 1),
-};
-virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
-                                    virDomainDefPtr def,
-                                    virDomainXMLOptionPtr xmlopt,
-                                    unsigned int flags,
-                                    virDomainDefPtr *oldDef);
-int virDomainObjListRenameAddNew(virDomainObjListPtr doms,
-                                 virDomainObjPtr vm,
-                                 const char *name);
-int virDomainObjListRenameRemove(virDomainObjListPtr doms,
-                                 const char *name);
 void virDomainObjAssignDef(virDomainObjPtr domain,
                            virDomainDefPtr def,
                            bool live,
@@ -2648,11 +2620,6 @@ virDomainDefPtr virDomainObjCopyPersistentDef(virDomainObjPtr dom,
                                               virCapsPtr caps,
                                               virDomainXMLOptionPtr xmlopt);
 
-void virDomainObjListRemove(virDomainObjListPtr doms,
-                            virDomainObjPtr dom);
-void virDomainObjListRemoveLocked(virDomainObjListPtr doms,
-                                  virDomainObjPtr dom);
-
 typedef enum {
     /* parse internal domain status information */
     VIR_DOMAIN_DEF_PARSE_STATUS          = 1 << 0,
@@ -2923,15 +2890,6 @@ typedef void (*virDomainLoadConfigNotify)(virDomainObjPtr dom,
                                           int newDomain,
                                           void *opaque);
 
-int virDomainObjListLoadAllConfigs(virDomainObjListPtr doms,
-                                   const char *configDir,
-                                   const char *autostartDir,
-                                   int liveStatus,
-                                   virCapsPtr caps,
-                                   virDomainXMLOptionPtr xmlopt,
-                                   virDomainLoadConfigNotify notify,
-                                   void *opaque);
-
 int virDomainDeleteConfig(const char *configDir,
                           const char *autostartDir,
                           virDomainObjPtr dom);
@@ -2953,29 +2911,6 @@ int virDomainVideoDefaultType(const virDomainDef *def);
 unsigned int virDomainVideoDefaultRAM(const virDomainDef *def,
                                       const virDomainVideoType type);
 
-int virDomainObjListNumOfDomains(virDomainObjListPtr doms,
-                                 bool active,
-                                 virDomainObjListACLFilter filter,
-                                 virConnectPtr conn);
-
-int virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
-                                 int *ids,
-                                 int maxids,
-                                 virDomainObjListACLFilter filter,
-                                 virConnectPtr conn);
-int virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
-                                     char **const names,
-                                     int maxnames,
-                                     virDomainObjListACLFilter filter,
-                                     virConnectPtr conn);
-
-typedef int (*virDomainObjListIterator)(virDomainObjPtr dom,
-                                        void *opaque);
-
-int virDomainObjListForEach(virDomainObjListPtr doms,
-                            virDomainObjListIterator callback,
-                            void *opaque);
-
 typedef int (*virDomainSmartcardDefIterator)(virDomainDefPtr def,
                                              virDomainSmartcardDefPtr dev,
                                              void *opaque);
@@ -3132,61 +3067,6 @@ VIR_ENUM_DECL(virDomainCpuPlacementMode)
 
 VIR_ENUM_DECL(virDomainStartupPolicy)
 
-# define VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE   \
-                (VIR_CONNECT_LIST_DOMAINS_ACTIVE | \
-                 VIR_CONNECT_LIST_DOMAINS_INACTIVE)
-
-# define VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT   \
-                (VIR_CONNECT_LIST_DOMAINS_PERSISTENT | \
-                 VIR_CONNECT_LIST_DOMAINS_TRANSIENT)
-
-# define VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE     \
-                (VIR_CONNECT_LIST_DOMAINS_RUNNING | \
-                 VIR_CONNECT_LIST_DOMAINS_PAUSED  | \
-                 VIR_CONNECT_LIST_DOMAINS_SHUTOFF | \
-                 VIR_CONNECT_LIST_DOMAINS_OTHER)
-
-# define VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE   \
-                (VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE | \
-                 VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE)
-
-# define VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART   \
-                (VIR_CONNECT_LIST_DOMAINS_AUTOSTART | \
-                 VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)
-
-# define VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT       \
-                (VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT | \
-                 VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT)
-
-# define VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL                   \
-                (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE      | \
-                 VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT  | \
-                 VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE       | \
-                 VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE | \
-                 VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART   | \
-                 VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)
-
-int virDomainObjListCollect(virDomainObjListPtr doms,
-                            virConnectPtr conn,
-                            virDomainObjPtr **vms,
-                            size_t *nvms,
-                            virDomainObjListACLFilter filter,
-                            unsigned int flags);
-int virDomainObjListExport(virDomainObjListPtr doms,
-                           virConnectPtr conn,
-                           virDomainPtr **domains,
-                           virDomainObjListACLFilter filter,
-                           unsigned int flags);
-int virDomainObjListConvert(virDomainObjListPtr domlist,
-                            virConnectPtr conn,
-                            virDomainPtr *doms,
-                            size_t ndoms,
-                            virDomainObjPtr **vms,
-                            size_t *nvms,
-                            virDomainObjListACLFilter filter,
-                            unsigned int flags,
-                            bool skip_missing);
-
 int
 virDomainDefMaybeAddController(virDomainDefPtr def,
                                int type,
index 6e68ecc8577c46a0079ba58c7120ec66932d0998..02118616fa887e063f23ad73785f1a0796656e87 100644 (file)
@@ -33,7 +33,7 @@
 # include "virbuffer.h"
 # include "virsocketaddr.h"
 # include "virmacaddr.h"
-# include "domain_conf.h"
+# include "virdomainobjlist.h"
 
 /* XXX
  * The config parser/structs should not be using platform specific
diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c
new file mode 100644 (file)
index 0000000..7568f93
--- /dev/null
@@ -0,0 +1,999 @@
+/*
+ * virdomainobjlist.c: domain objects list utilities
+ *
+ * Copyright (C) 2006-2015 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "virdomainobjlist.h"
+#include "snapshot_conf.h"
+#include "viralloc.h"
+#include "virfile.h"
+#include "virlog.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_DOMAIN
+
+VIR_LOG_INIT("conf.virdomainobjlist");
+
+static virClassPtr virDomainObjListClass;
+static void virDomainObjListDispose(void *obj);
+
+
+struct _virDomainObjList {
+    virObjectLockable parent;
+
+    /* uuid string -> virDomainObj  mapping
+     * for O(1), lockless lookup-by-uuid */
+    virHashTable *objs;
+
+    /* name -> virDomainObj mapping for O(1),
+     * lockless lookup-by-name */
+    virHashTable *objsName;
+};
+
+
+static int virDomainObjListOnceInit(void)
+{
+    if (!(virDomainObjListClass = virClassNew(virClassForObjectLockable(),
+                                              "virDomainObjList",
+                                              sizeof(virDomainObjList),
+                                              virDomainObjListDispose)))
+        return -1;
+
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virDomainObjList)
+
+virDomainObjListPtr virDomainObjListNew(void)
+{
+    virDomainObjListPtr doms;
+
+    if (virDomainObjListInitialize() < 0)
+        return NULL;
+
+    if (!(doms = virObjectLockableNew(virDomainObjListClass)))
+        return NULL;
+
+    if (!(doms->objs = virHashCreate(50, virObjectFreeHashData)) ||
+        !(doms->objsName = virHashCreate(50, virObjectFreeHashData))) {
+        virObjectUnref(doms);
+        return NULL;
+    }
+
+    return doms;
+}
+
+
+static void virDomainObjListDispose(void *obj)
+{
+    virDomainObjListPtr doms = obj;
+
+    virHashFree(doms->objs);
+    virHashFree(doms->objsName);
+}
+
+
+static int virDomainObjListSearchID(const void *payload,
+                                    const void *name ATTRIBUTE_UNUSED,
+                                    const void *data)
+{
+    virDomainObjPtr obj = (virDomainObjPtr)payload;
+    const int *id = data;
+    int want = 0;
+
+    virObjectLock(obj);
+    if (virDomainObjIsActive(obj) &&
+        obj->def->id == *id)
+        want = 1;
+    virObjectUnlock(obj);
+    return want;
+}
+
+
+virDomainObjPtr virDomainObjListFindByID(virDomainObjListPtr doms,
+                                         int id)
+{
+    virDomainObjPtr obj;
+    virObjectLock(doms);
+    obj = virHashSearch(doms->objs, virDomainObjListSearchID, &id);
+    if (obj) {
+        virObjectLock(obj);
+        if (obj->removing) {
+            virObjectUnlock(obj);
+            obj = NULL;
+        }
+    }
+    virObjectUnlock(doms);
+    return obj;
+}
+
+
+static virDomainObjPtr
+virDomainObjListFindByUUIDInternal(virDomainObjListPtr doms,
+                                   const unsigned char *uuid,
+                                   bool ref)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    virDomainObjPtr obj;
+
+    virObjectLock(doms);
+    virUUIDFormat(uuid, uuidstr);
+
+    obj = virHashLookup(doms->objs, uuidstr);
+    if (ref) {
+        virObjectRef(obj);
+        virObjectUnlock(doms);
+    }
+    if (obj) {
+        virObjectLock(obj);
+        if (obj->removing) {
+            virObjectUnlock(obj);
+            if (ref)
+                virObjectUnref(obj);
+            obj = NULL;
+        }
+    }
+    if (!ref)
+        virObjectUnlock(doms);
+    return obj;
+}
+
+
+virDomainObjPtr
+virDomainObjListFindByUUID(virDomainObjListPtr doms,
+                           const unsigned char *uuid)
+{
+    return virDomainObjListFindByUUIDInternal(doms, uuid, false);
+}
+
+
+virDomainObjPtr
+virDomainObjListFindByUUIDRef(virDomainObjListPtr doms,
+                              const unsigned char *uuid)
+{
+    return virDomainObjListFindByUUIDInternal(doms, uuid, true);
+}
+
+
+virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
+                                           const char *name)
+{
+    virDomainObjPtr obj;
+
+    virObjectLock(doms);
+    obj = virHashLookup(doms->objsName, name);
+    virObjectRef(obj);
+    virObjectUnlock(doms);
+    if (obj) {
+        virObjectLock(obj);
+        if (obj->removing) {
+            virObjectUnlock(obj);
+            virObjectUnref(obj);
+            obj = NULL;
+        }
+    }
+    return obj;
+}
+
+
+/*
+ * virDomainObjListAddLocked:
+ *
+ * If flags & VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE then
+ * this will refuse updating an existing def if the
+ * current def is Live
+ *
+ * If flags & VIR_DOMAIN_OBJ_LIST_ADD_LIVE then
+ * the @def being added is assumed to represent a
+ * live config, not a future inactive config
+ *
+ */
+static virDomainObjPtr
+virDomainObjListAddLocked(virDomainObjListPtr doms,
+                          virDomainDefPtr def,
+                          virDomainXMLOptionPtr xmlopt,
+                          unsigned int flags,
+                          virDomainDefPtr *oldDef)
+{
+    virDomainObjPtr vm;
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    if (oldDef)
+        *oldDef = NULL;
+
+    virUUIDFormat(def->uuid, uuidstr);
+
+    /* See if a VM with matching UUID already exists */
+    if ((vm = virHashLookup(doms->objs, uuidstr))) {
+        virObjectLock(vm);
+        /* UUID matches, but if names don't match, refuse it */
+        if (STRNEQ(vm->def->name, def->name)) {
+            virUUIDFormat(vm->def->uuid, uuidstr);
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                           _("domain '%s' is already defined with uuid %s"),
+                           vm->def->name, uuidstr);
+            goto error;
+        }
+
+        if (flags & VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE) {
+            /* UUID & name match, but if VM is already active, refuse it */
+            if (virDomainObjIsActive(vm)) {
+                virReportError(VIR_ERR_OPERATION_INVALID,
+                               _("domain '%s' is already active"),
+                               vm->def->name);
+                goto error;
+            }
+            if (!vm->persistent) {
+                virReportError(VIR_ERR_OPERATION_INVALID,
+                               _("domain '%s' is already being started"),
+                               vm->def->name);
+                goto error;
+            }
+        }
+
+        virDomainObjAssignDef(vm,
+                              def,
+                              !!(flags & VIR_DOMAIN_OBJ_LIST_ADD_LIVE),
+                              oldDef);
+    } else {
+        /* UUID does not match, but if a name matches, refuse it */
+        if ((vm = virHashLookup(doms->objsName, def->name))) {
+            virObjectLock(vm);
+            virUUIDFormat(vm->def->uuid, uuidstr);
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                           _("domain '%s' already exists with uuid %s"),
+                           def->name, uuidstr);
+            goto error;
+        }
+
+        if (!(vm = virDomainObjNew(xmlopt)))
+            goto cleanup;
+        vm->def = def;
+
+        virUUIDFormat(def->uuid, uuidstr);
+        if (virHashAddEntry(doms->objs, uuidstr, vm) < 0) {
+            virObjectUnref(vm);
+            return NULL;
+        }
+
+        if (virHashAddEntry(doms->objsName, def->name, vm) < 0) {
+            virHashRemoveEntry(doms->objs, uuidstr);
+            return NULL;
+        }
+
+        /* Since domain is in two hash tables, increment the
+         * reference counter */
+        virObjectRef(vm);
+    }
+ cleanup:
+    return vm;
+
+ error:
+    virObjectUnlock(vm);
+    vm = NULL;
+    goto cleanup;
+}
+
+
+virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
+                                    virDomainDefPtr def,
+                                    virDomainXMLOptionPtr xmlopt,
+                                    unsigned int flags,
+                                    virDomainDefPtr *oldDef)
+{
+    virDomainObjPtr ret;
+
+    virObjectLock(doms);
+    ret = virDomainObjListAddLocked(doms, def, xmlopt, flags, oldDef);
+    virObjectUnlock(doms);
+    return ret;
+}
+
+
+int
+virDomainObjListRenameAddNew(virDomainObjListPtr doms,
+                             virDomainObjPtr vm,
+                             const char *name)
+{
+    int ret = -1;
+    virObjectLock(doms);
+
+    /* Add new name into the hash table of domain names. */
+    if (virHashAddEntry(doms->objsName, name, vm) < 0)
+        goto cleanup;
+
+    /* Okay, this is crazy. virHashAddEntry() does not increment
+     * the refcounter of @vm, but virHashRemoveEntry() does
+     * decrement it. We need to work around it. */
+    virObjectRef(vm);
+
+    ret = 0;
+ cleanup:
+    virObjectUnlock(doms);
+    return ret;
+}
+
+
+int
+virDomainObjListRenameRemove(virDomainObjListPtr doms, const char *name)
+{
+    virObjectLock(doms);
+    virHashRemoveEntry(doms->objsName, name);
+    virObjectUnlock(doms);
+    return 0;
+}
+
+
+/*
+ * 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 using it
+ */
+void virDomainObjListRemove(virDomainObjListPtr doms,
+                            virDomainObjPtr dom)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    dom->removing = true;
+    virUUIDFormat(dom->def->uuid, uuidstr);
+    virObjectRef(dom);
+    virObjectUnlock(dom);
+
+    virObjectLock(doms);
+    virObjectLock(dom);
+    virHashRemoveEntry(doms->objs, uuidstr);
+    virHashRemoveEntry(doms->objsName, dom->def->name);
+    virObjectUnlock(dom);
+    virObjectUnref(dom);
+    virObjectUnlock(doms);
+}
+
+
+/* The caller must hold lock on 'doms' in addition to 'virDomainObjListRemove'
+ * requirements
+ *
+ * Can be used to remove current element while iterating with
+ * virDomainObjListForEach
+ */
+void virDomainObjListRemoveLocked(virDomainObjListPtr doms,
+                                  virDomainObjPtr dom)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    virUUIDFormat(dom->def->uuid, uuidstr);
+
+    virHashRemoveEntry(doms->objs, uuidstr);
+    virHashRemoveEntry(doms->objsName, dom->def->name);
+    virObjectUnlock(dom);
+}
+
+
+static virDomainObjPtr
+virDomainObjListLoadConfig(virDomainObjListPtr doms,
+                           virCapsPtr caps,
+                           virDomainXMLOptionPtr xmlopt,
+                           const char *configDir,
+                           const char *autostartDir,
+                           const char *name,
+                           virDomainLoadConfigNotify notify,
+                           void *opaque)
+{
+    char *configFile = NULL, *autostartLink = NULL;
+    virDomainDefPtr def = NULL;
+    virDomainObjPtr dom;
+    int autostart;
+    virDomainDefPtr oldDef = NULL;
+
+    if ((configFile = virDomainConfigFile(configDir, name)) == NULL)
+        goto error;
+    if (!(def = virDomainDefParseFile(configFile, caps, xmlopt,
+                                      VIR_DOMAIN_DEF_PARSE_INACTIVE |
+                                      VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS)))
+        goto error;
+
+    if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL)
+        goto error;
+
+    if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0)
+        goto error;
+
+    if (!(dom = virDomainObjListAddLocked(doms, def, xmlopt, 0, &oldDef)))
+        goto error;
+
+    dom->autostart = autostart;
+
+    if (notify)
+        (*notify)(dom, oldDef == NULL, opaque);
+
+    virDomainDefFree(oldDef);
+    VIR_FREE(configFile);
+    VIR_FREE(autostartLink);
+    return dom;
+
+ error:
+    VIR_FREE(configFile);
+    VIR_FREE(autostartLink);
+    virDomainDefFree(def);
+    return NULL;
+}
+
+
+static virDomainObjPtr
+virDomainObjListLoadStatus(virDomainObjListPtr doms,
+                           const char *statusDir,
+                           const char *name,
+                           virCapsPtr caps,
+                           virDomainXMLOptionPtr xmlopt,
+                           virDomainLoadConfigNotify notify,
+                           void *opaque)
+{
+    char *statusFile = NULL;
+    virDomainObjPtr obj = NULL;
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    if ((statusFile = virDomainConfigFile(statusDir, name)) == NULL)
+        goto error;
+
+    if (!(obj = virDomainObjParseFile(statusFile, caps, xmlopt,
+                                      VIR_DOMAIN_DEF_PARSE_STATUS |
+                                      VIR_DOMAIN_DEF_PARSE_ACTUAL_NET |
+                                      VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES |
+                                      VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS)))
+        goto error;
+
+    virUUIDFormat(obj->def->uuid, uuidstr);
+
+    if (virHashLookup(doms->objs, uuidstr) != NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unexpected domain %s already exists"),
+                       obj->def->name);
+        goto error;
+    }
+
+    if (virHashAddEntry(doms->objs, uuidstr, obj) < 0)
+        goto error;
+
+    if (virHashAddEntry(doms->objsName, obj->def->name, obj) < 0) {
+        virHashRemoveEntry(doms->objs, uuidstr);
+        goto error;
+    }
+
+    /* Since domain is in two hash tables, increment the
+     * reference counter */
+    virObjectRef(obj);
+
+    if (notify)
+        (*notify)(obj, 1, opaque);
+
+    VIR_FREE(statusFile);
+    return obj;
+
+ error:
+    virObjectUnref(obj);
+    VIR_FREE(statusFile);
+    return NULL;
+}
+
+
+int
+virDomainObjListLoadAllConfigs(virDomainObjListPtr doms,
+                               const char *configDir,
+                               const char *autostartDir,
+                               int liveStatus,
+                               virCapsPtr caps,
+                               virDomainXMLOptionPtr xmlopt,
+                               virDomainLoadConfigNotify notify,
+                               void *opaque)
+{
+    DIR *dir;
+    struct dirent *entry;
+    int ret = -1;
+
+    VIR_INFO("Scanning for configs in %s", configDir);
+
+    if (!(dir = opendir(configDir))) {
+        if (errno == ENOENT)
+            return 0;
+        virReportSystemError(errno,
+                             _("Failed to open dir '%s'"),
+                             configDir);
+        return -1;
+    }
+
+    virObjectLock(doms);
+
+    while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
+        virDomainObjPtr dom;
+
+        if (entry->d_name[0] == '.')
+            continue;
+
+        if (!virFileStripSuffix(entry->d_name, ".xml"))
+            continue;
+
+        /* NB: ignoring errors, so one malformed config doesn't
+           kill the whole process */
+        VIR_INFO("Loading config file '%s.xml'", entry->d_name);
+        if (liveStatus)
+            dom = virDomainObjListLoadStatus(doms,
+                                             configDir,
+                                             entry->d_name,
+                                             caps,
+                                             xmlopt,
+                                             notify,
+                                             opaque);
+        else
+            dom = virDomainObjListLoadConfig(doms,
+                                             caps,
+                                             xmlopt,
+                                             configDir,
+                                             autostartDir,
+                                             entry->d_name,
+                                             notify,
+                                             opaque);
+        if (dom) {
+            if (!liveStatus)
+                dom->persistent = 1;
+            virObjectUnlock(dom);
+        }
+    }
+
+    closedir(dir);
+    virObjectUnlock(doms);
+    return ret;
+}
+
+
+struct virDomainObjListData {
+    virDomainObjListACLFilter filter;
+    virConnectPtr conn;
+    bool active;
+    int count;
+};
+
+
+static void
+virDomainObjListCount(void *payload,
+                      const void *name ATTRIBUTE_UNUSED,
+                      void *opaque)
+{
+    virDomainObjPtr obj = payload;
+    struct virDomainObjListData *data = opaque;
+    virObjectLock(obj);
+    if (data->filter &&
+        !data->filter(data->conn, obj->def))
+        goto cleanup;
+    if (virDomainObjIsActive(obj)) {
+        if (data->active)
+            data->count++;
+    } else {
+        if (!data->active)
+            data->count++;
+    }
+ cleanup:
+    virObjectUnlock(obj);
+}
+
+
+int
+virDomainObjListNumOfDomains(virDomainObjListPtr doms,
+                             bool active,
+                             virDomainObjListACLFilter filter,
+                             virConnectPtr conn)
+{
+    struct virDomainObjListData data = { filter, conn, active, 0 };
+    virObjectLock(doms);
+    virHashForEach(doms->objs, virDomainObjListCount, &data);
+    virObjectUnlock(doms);
+    return data.count;
+}
+
+
+struct virDomainIDData {
+    virDomainObjListACLFilter filter;
+    virConnectPtr conn;
+    int numids;
+    int maxids;
+    int *ids;
+};
+
+
+static void
+virDomainObjListCopyActiveIDs(void *payload,
+                              const void *name ATTRIBUTE_UNUSED,
+                              void *opaque)
+{
+    virDomainObjPtr obj = payload;
+    struct virDomainIDData *data = opaque;
+    virObjectLock(obj);
+    if (data->filter &&
+        !data->filter(data->conn, obj->def))
+        goto cleanup;
+    if (virDomainObjIsActive(obj) && data->numids < data->maxids)
+        data->ids[data->numids++] = obj->def->id;
+ cleanup:
+    virObjectUnlock(obj);
+}
+
+
+int
+virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
+                             int *ids,
+                             int maxids,
+                             virDomainObjListACLFilter filter,
+                             virConnectPtr conn)
+{
+    struct virDomainIDData data = { filter, conn,
+                                    0, maxids, ids };
+    virObjectLock(doms);
+    virHashForEach(doms->objs, virDomainObjListCopyActiveIDs, &data);
+    virObjectUnlock(doms);
+    return data.numids;
+}
+
+
+struct virDomainNameData {
+    virDomainObjListACLFilter filter;
+    virConnectPtr conn;
+    int oom;
+    int numnames;
+    int maxnames;
+    char **const names;
+};
+
+
+static void
+virDomainObjListCopyInactiveNames(void *payload,
+                                  const void *name ATTRIBUTE_UNUSED,
+                                  void *opaque)
+{
+    virDomainObjPtr obj = payload;
+    struct virDomainNameData *data = opaque;
+
+    if (data->oom)
+        return;
+
+    virObjectLock(obj);
+    if (data->filter &&
+        !data->filter(data->conn, obj->def))
+        goto cleanup;
+    if (!virDomainObjIsActive(obj) && data->numnames < data->maxnames) {
+        if (VIR_STRDUP(data->names[data->numnames], obj->def->name) < 0)
+            data->oom = 1;
+        else
+            data->numnames++;
+    }
+ cleanup:
+    virObjectUnlock(obj);
+}
+
+
+int
+virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
+                                 char **const names,
+                                 int maxnames,
+                                 virDomainObjListACLFilter filter,
+                                 virConnectPtr conn)
+{
+    struct virDomainNameData data = { filter, conn,
+                                      0, 0, maxnames, names };
+    size_t i;
+    virObjectLock(doms);
+    virHashForEach(doms->objs, virDomainObjListCopyInactiveNames, &data);
+    virObjectUnlock(doms);
+    if (data.oom) {
+        for (i = 0; i < data.numnames; i++)
+            VIR_FREE(data.names[i]);
+        return -1;
+    }
+
+    return data.numnames;
+}
+
+
+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,
+    };
+    virObjectLock(doms);
+    virHashForEach(doms->objs, virDomainObjListHelper, &data);
+    virObjectUnlock(doms);
+    return data.ret;
+}
+
+
+#define MATCH(FLAG) (filter & (FLAG))
+static bool
+virDomainObjMatchFilter(virDomainObjPtr vm,
+                        unsigned int filter)
+{
+    /* filter by active state */
+    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) &&
+        !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) &&
+           virDomainObjIsActive(vm)) ||
+          (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) &&
+           !virDomainObjIsActive(vm))))
+        return false;
+
+    /* filter by persistence */
+    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT) &&
+        !((MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT) &&
+           vm->persistent) ||
+          (MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
+           !vm->persistent)))
+        return false;
+
+    /* filter by domain state */
+    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE)) {
+        int st = virDomainObjGetState(vm, NULL);
+        if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
+               st == VIR_DOMAIN_RUNNING) ||
+              (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
+               st == VIR_DOMAIN_PAUSED) ||
+              (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
+               st == VIR_DOMAIN_SHUTOFF) ||
+              (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
+               (st != VIR_DOMAIN_RUNNING &&
+                st != VIR_DOMAIN_PAUSED &&
+                st != VIR_DOMAIN_SHUTOFF))))
+            return false;
+    }
+
+    /* filter by existence of managed save state */
+    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE) &&
+        !((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) &&
+           vm->hasManagedSave) ||
+          (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) &&
+           !vm->hasManagedSave)))
+        return false;
+
+    /* filter by autostart option */
+    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART) &&
+        !((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && vm->autostart) ||
+          (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && !vm->autostart)))
+        return false;
+
+    /* filter by snapshot existence */
+    if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)) {
+        int nsnap = virDomainSnapshotObjListNum(vm->snapshots, NULL, 0);
+        if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && nsnap > 0) ||
+              (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && nsnap <= 0)))
+            return false;
+    }
+
+    return true;
+}
+#undef MATCH
+
+
+struct virDomainListData {
+    virDomainObjPtr *vms;
+    size_t nvms;
+};
+
+
+static void
+virDomainObjListCollectIterator(void *payload,
+                                const void *name ATTRIBUTE_UNUSED,
+                                void *opaque)
+{
+    struct virDomainListData *data = opaque;
+
+    data->vms[data->nvms++] = virObjectRef(payload);
+}
+
+
+static void
+virDomainObjListFilter(virDomainObjPtr **list,
+                       size_t *nvms,
+                       virConnectPtr conn,
+                       virDomainObjListACLFilter filter,
+                       unsigned int flags)
+{
+    size_t i = 0;
+
+    while (i < *nvms) {
+        virDomainObjPtr vm = (*list)[i];
+
+        virObjectLock(vm);
+
+        /* do not list the object if:
+         * 1) it's being removed.
+         * 2) connection does not have ACL to see it
+         * 3) it doesn't match the filter
+         */
+        if (vm->removing ||
+            (filter && !filter(conn, vm->def)) ||
+            !virDomainObjMatchFilter(vm, flags)) {
+            virObjectUnlock(vm);
+            virObjectUnref(vm);
+            VIR_DELETE_ELEMENT(*list, i, *nvms);
+            continue;
+        }
+
+        virObjectUnlock(vm);
+        i++;
+    }
+}
+
+
+int
+virDomainObjListCollect(virDomainObjListPtr domlist,
+                        virConnectPtr conn,
+                        virDomainObjPtr **vms,
+                        size_t *nvms,
+                        virDomainObjListACLFilter filter,
+                        unsigned int flags)
+{
+    struct virDomainListData data = { NULL, 0 };
+
+    virObjectLock(domlist);
+    sa_assert(domlist->objs);
+    if (VIR_ALLOC_N(data.vms, virHashSize(domlist->objs)) < 0) {
+        virObjectUnlock(domlist);
+        return -1;
+    }
+
+    virHashForEach(domlist->objs, virDomainObjListCollectIterator, &data);
+    virObjectUnlock(domlist);
+
+    virDomainObjListFilter(&data.vms, &data.nvms, conn, filter, flags);
+
+    *nvms = data.nvms;
+    *vms = data.vms;
+
+    return 0;
+}
+
+
+int
+virDomainObjListConvert(virDomainObjListPtr domlist,
+                        virConnectPtr conn,
+                        virDomainPtr *doms,
+                        size_t ndoms,
+                        virDomainObjPtr **vms,
+                        size_t *nvms,
+                        virDomainObjListACLFilter filter,
+                        unsigned int flags,
+                        bool skip_missing)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    virDomainObjPtr vm;
+    size_t i;
+
+    *nvms = 0;
+    *vms = NULL;
+
+    virObjectLock(domlist);
+    for (i = 0; i < ndoms; i++) {
+        virDomainPtr dom = doms[i];
+
+        virUUIDFormat(dom->uuid, uuidstr);
+
+        if (!(vm = virHashLookup(domlist->objs, uuidstr))) {
+            if (skip_missing)
+                continue;
+
+            virObjectUnlock(domlist);
+            virReportError(VIR_ERR_NO_DOMAIN,
+                           _("no domain with matching uuid '%s' (%s)"),
+                           uuidstr, dom->name);
+            goto error;
+        }
+
+        virObjectRef(vm);
+
+        if (VIR_APPEND_ELEMENT(*vms, *nvms, vm) < 0) {
+            virObjectUnlock(domlist);
+            virObjectUnref(vm);
+            goto error;
+        }
+    }
+    virObjectUnlock(domlist);
+
+    sa_assert(*vms);
+    virDomainObjListFilter(vms, nvms, conn, filter, flags);
+
+    return 0;
+
+ error:
+    virObjectListFreeCount(*vms, *nvms);
+    *vms = NULL;
+    *nvms = 0;
+
+    return -1;
+}
+
+
+int
+virDomainObjListExport(virDomainObjListPtr domlist,
+                       virConnectPtr conn,
+                       virDomainPtr **domains,
+                       virDomainObjListACLFilter filter,
+                       unsigned int flags)
+{
+    virDomainObjPtr *vms = NULL;
+    virDomainPtr *doms = NULL;
+    size_t nvms = 0;
+    size_t i;
+    int ret = -1;
+
+    if (virDomainObjListCollect(domlist, conn, &vms, &nvms, filter, flags) < 0)
+        return -1;
+
+    if (domains) {
+        if (VIR_ALLOC_N(doms, nvms + 1) < 0)
+            goto cleanup;
+
+        for (i = 0; i < nvms; i++) {
+            virDomainObjPtr vm = vms[i];
+
+            virObjectLock(vm);
+
+            if (!(doms[i] = virGetDomain(conn, vm->def->name, vm->def->uuid))) {
+                virObjectUnlock(vm);
+                goto cleanup;
+            }
+
+            doms[i]->id = vm->def->id;
+
+            virObjectUnlock(vm);
+        }
+
+        *domains = doms;
+        doms = NULL;
+    }
+
+    ret = nvms;
+
+ cleanup:
+    virObjectListFree(doms);
+    virObjectListFreeCount(vms, nvms);
+    return ret;
+}
diff --git a/src/conf/virdomainobjlist.h b/src/conf/virdomainobjlist.h
new file mode 100644 (file)
index 0000000..f479598
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * virdomainobjlist.h: domain objects list utilities
+ *
+ * Copyright (C) 2006-2015 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+
+#ifndef __VIRDOMAINOBJLIST_H__
+# define __VIRDOMAINOBJLIST_H__
+
+# include "domain_conf.h"
+
+typedef struct _virDomainObjList virDomainObjList;
+typedef virDomainObjList *virDomainObjListPtr;
+
+virDomainObjListPtr virDomainObjListNew(void);
+
+virDomainObjPtr virDomainObjListFindByID(virDomainObjListPtr doms,
+                                         int id);
+virDomainObjPtr virDomainObjListFindByUUID(virDomainObjListPtr doms,
+                                           const unsigned char *uuid);
+virDomainObjPtr virDomainObjListFindByUUIDRef(virDomainObjListPtr doms,
+                                              const unsigned char *uuid);
+virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
+                                           const char *name);
+
+enum {
+    VIR_DOMAIN_OBJ_LIST_ADD_LIVE = (1 << 0),
+    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE = (1 << 1),
+};
+virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
+                                    virDomainDefPtr def,
+                                    virDomainXMLOptionPtr xmlopt,
+                                    unsigned int flags,
+                                    virDomainDefPtr *oldDef);
+
+int virDomainObjListRenameAddNew(virDomainObjListPtr doms,
+                                 virDomainObjPtr vm,
+                                 const char *name);
+int virDomainObjListRenameRemove(virDomainObjListPtr doms,
+                                 const char *name);
+void virDomainObjListRemove(virDomainObjListPtr doms,
+                            virDomainObjPtr dom);
+void virDomainObjListRemoveLocked(virDomainObjListPtr doms,
+                                  virDomainObjPtr dom);
+
+int virDomainObjListLoadAllConfigs(virDomainObjListPtr doms,
+                                   const char *configDir,
+                                   const char *autostartDir,
+                                   int liveStatus,
+                                   virCapsPtr caps,
+                                   virDomainXMLOptionPtr xmlopt,
+                                   virDomainLoadConfigNotify notify,
+                                   void *opaque);
+
+int virDomainObjListNumOfDomains(virDomainObjListPtr doms,
+                                 bool active,
+                                 virDomainObjListACLFilter filter,
+                                 virConnectPtr conn);
+
+int virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
+                                 int *ids,
+                                 int maxids,
+                                 virDomainObjListACLFilter filter,
+                                 virConnectPtr conn);
+int virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
+                                     char **const names,
+                                     int maxnames,
+                                     virDomainObjListACLFilter filter,
+                                     virConnectPtr conn);
+
+typedef int (*virDomainObjListIterator)(virDomainObjPtr dom,
+                                        void *opaque);
+
+int virDomainObjListForEach(virDomainObjListPtr doms,
+                            virDomainObjListIterator callback,
+                            void *opaque);
+
+# define VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE   \
+                (VIR_CONNECT_LIST_DOMAINS_ACTIVE | \
+                 VIR_CONNECT_LIST_DOMAINS_INACTIVE)
+
+# define VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT   \
+                (VIR_CONNECT_LIST_DOMAINS_PERSISTENT | \
+                 VIR_CONNECT_LIST_DOMAINS_TRANSIENT)
+
+# define VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE     \
+                (VIR_CONNECT_LIST_DOMAINS_RUNNING | \
+                 VIR_CONNECT_LIST_DOMAINS_PAUSED  | \
+                 VIR_CONNECT_LIST_DOMAINS_SHUTOFF | \
+                 VIR_CONNECT_LIST_DOMAINS_OTHER)
+
+# define VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE   \
+                (VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE | \
+                 VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE)
+
+# define VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART   \
+                (VIR_CONNECT_LIST_DOMAINS_AUTOSTART | \
+                 VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)
+
+# define VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT       \
+                (VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT | \
+                 VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT)
+
+# define VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL                   \
+                (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE      | \
+                 VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT  | \
+                 VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE       | \
+                 VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE | \
+                 VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART   | \
+                 VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)
+
+int virDomainObjListCollect(virDomainObjListPtr doms,
+                            virConnectPtr conn,
+                            virDomainObjPtr **vms,
+                            size_t *nvms,
+                            virDomainObjListACLFilter filter,
+                            unsigned int flags);
+int virDomainObjListExport(virDomainObjListPtr doms,
+                           virConnectPtr conn,
+                           virDomainPtr **domains,
+                           virDomainObjListACLFilter filter,
+                           unsigned int flags);
+int virDomainObjListConvert(virDomainObjListPtr domlist,
+                            virConnectPtr conn,
+                            virDomainPtr *doms,
+                            size_t ndoms,
+                            virDomainObjPtr **vms,
+                            size_t *nvms,
+                            virDomainObjListACLFilter filter,
+                            unsigned int flags,
+                            bool skip_missing);
+
+#endif /* __VIRDOMAINOBJLIST_H__ */
index 5944947d93c416b8b5c22a2a9a14ef968cf11579..ebf23be6d04ad338f26d9b8fe78ca3d56c58f0c1 100644 (file)
@@ -24,7 +24,7 @@
 #include <config.h>
 
 #include "internal.h"
-#include "domain_conf.h"
+#include "virdomainobjlist.h"
 #include "snapshot_conf.h"
 #include "virauth.h"
 #include "viralloc.h"
index 72261dfa3257b2357f2eb49b1cb94ce533656963..719539c730454d77287ac46b7fe7d0fcc6bd84aa 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "internal.h"
 #include "datatypes.h"
-#include "domain_conf.h"
+#include "virdomainobjlist.h"
 #include "virauth.h"
 #include "viralloc.h"
 #include "virlog.h"
index 360fb2dd9bbabc9174f5d7e6b8baf0649d5b335f..dd085c3487bf523cd89b9f4ee8fd4c78f600ba9a 100644 (file)
@@ -396,24 +396,6 @@ virDomainObjGetMetadata;
 virDomainObjGetOneDef;
 virDomainObjGetPersistentDef;
 virDomainObjGetState;
-virDomainObjListAdd;
-virDomainObjListCollect;
-virDomainObjListConvert;
-virDomainObjListExport;
-virDomainObjListFindByID;
-virDomainObjListFindByName;
-virDomainObjListFindByUUID;
-virDomainObjListFindByUUIDRef;
-virDomainObjListForEach;
-virDomainObjListGetActiveIDs;
-virDomainObjListGetInactiveNames;
-virDomainObjListLoadAllConfigs;
-virDomainObjListNew;
-virDomainObjListNumOfDomains;
-virDomainObjListRemove;
-virDomainObjListRemoveLocked;
-virDomainObjListRenameAddNew;
-virDomainObjListRenameRemove;
 virDomainObjNew;
 virDomainObjParseNode;
 virDomainObjSetDefTransient;
@@ -885,6 +867,27 @@ virChrdevFree;
 virChrdevOpen;
 
 
+# conf/virdomainobjlist.h
+virDomainObjListAdd;
+virDomainObjListCollect;
+virDomainObjListConvert;
+virDomainObjListExport;
+virDomainObjListFindByID;
+virDomainObjListFindByName;
+virDomainObjListFindByUUID;
+virDomainObjListFindByUUIDRef;
+virDomainObjListForEach;
+virDomainObjListGetActiveIDs;
+virDomainObjListGetInactiveNames;
+virDomainObjListLoadAllConfigs;
+virDomainObjListNew;
+virDomainObjListNumOfDomains;
+virDomainObjListRemove;
+virDomainObjListRemoveLocked;
+virDomainObjListRenameAddNew;
+virDomainObjListRenameRemove;
+
+
 # cpu/cpu.h
 cpuBaseline;
 cpuBaselineXML;
index 9c29b1e2894d1bbb88cd0d4f4979f119fa1c2280..7c68b2bcedf59ff49056e15ae05d92898fc09441 100644 (file)
@@ -30,7 +30,7 @@
 
 # include "internal.h"
 # include "libvirt_internal.h"
-# include "domain_conf.h"
+# include "virdomainobjlist.h"
 # include "domain_event.h"
 # include "capabilities.h"
 # include "configmake.h"
index a5c58062d68faa433487501c0cd7b2e2e2767425..fc36740d26c68cb2e4ef01b1b64c2fad3223febb 100644 (file)
@@ -30,7 +30,7 @@
 # define OPENVZ_CONF_H
 
 # include "internal.h"
-# include "domain_conf.h"
+# include "virdomainobjlist.h"
 # include "virthread.h"
 
 
index 9ccd567868f119a5e0ef977178ccae1cd316f502..3b273963db0e1b1e6cba731c72745df9ac2bc51f 100644 (file)
@@ -60,6 +60,7 @@
 #include "cpu/cpu.h"
 #include "virauth.h"
 #include "viratomic.h"
+#include "virdomainobjlist.h"
 
 #define VIR_FROM_THIS VIR_FROM_TEST
 
index 05e19ff27b7a7ee5750b612ac9110227bb18fbb0..9a45d102893ee703e4a32e3565a05f10bdc3c369 100644 (file)
@@ -28,7 +28,7 @@
 # include "libvirt_internal.h"
 # include "capabilities.h"
 # include "network_conf.h"
-# include "domain_conf.h"
+# include "virdomainobjlist.h"
 # include "domain_event.h"
 # include "virerror.h"
 # include "virthread.h"
index e6b8a9e3e095ea84ca543d25ab9e0b98d1f404b2..4df0a00602157a1a38e3ec4946241f9875dd1211 100644 (file)
@@ -25,7 +25,7 @@
 #ifndef __VIR_CLOSE_CALLBACKS__
 # define __VIR_CLOSE_CALLBACKS__
 
-# include "domain_conf.h"
+# include "virdomainobjlist.h"
 
 typedef struct _virCloseCallbacks virCloseCallbacks;
 typedef virCloseCallbacks *virCloseCallbacksPtr;
index 0e84f30ffb3179e57047364ec5becde8aa6d7795..93693671d6f6b381aeca4cd92e71109a6b9e7402 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "internal.h"
 #include "datatypes.h"
-#include "domain_conf.h"
+#include "virdomainobjlist.h"
 #include "domain_event.h"
 #include "virlog.h"
 #include "viralloc.h"
index 1f3c41aa83d1df71232adcfa263398d3ba356850..b3f8cdf253eb93a603a50e1b24e4d324cbb18676 100644 (file)
@@ -26,7 +26,7 @@
 # define NOGUI "nogui"
 
 # include "internal.h"
-# include "domain_conf.h"
+# include "virdomainobjlist.h"
 # include "virthread.h"
 
 # define VIR_FROM_THIS VIR_FROM_VMWARE
index 84cf08f6ebec50273e114c94262dff858e6e8a1e..b7a4c816d8556b96e8113353d6fe3dee56cce37b 100644 (file)
@@ -27,6 +27,7 @@
 
 # include "driver.h"
 # include "conf/domain_conf.h"
+# include "conf/virdomainobjlist.h"
 # include "conf/domain_event.h"
 # include "virthread.h"
 
index d4e500b2122520a64d731a31db0ec9d05972e927..abc18e5c4d671e60d5441775c11d22aa34a3a609 100644 (file)
@@ -32,7 +32,7 @@
 #include <libxml/xmlsave.h>
 
 #include "internal.h"
-#include "conf/domain_conf.h"
+#include "conf/virdomainobjlist.h"
 #include "intprops.h"
 #include "viralloc.h"
 #include "virmacaddr.h"