This patch adds common code to list domains in fashion used by
virListAllDomains with all currently supported flags. The header file
also contains macros that group filters together that are used to
shorten filter conditions.
---
Diff to v2:
-added macros grouping filter flags
-Added support for managed save filtering, now that virDomainObj holds this property
- Removed the now unneeded filtering function
- Changed allocation of the return list, now It's allocated before for the full
length and it's trimmed afterwards
- Added newline after the DOMAIN_LIST_SOURCES definition in Makefile.am
---
src/Makefile.am | 8 ++-
src/conf/virdomainlist.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++
src/conf/virdomainlist.h | 66 +++++++++++++++++
src/libvirt_private.syms | 4 +
4 files changed, 259 insertions(+), 1 deletions(-)
create mode 100644 src/conf/virdomainlist.c
create mode 100644 src/conf/virdomainlist.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 60f5442..7726e7e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -190,10 +190,15 @@ ENCRYPTION_CONF_SOURCES = \
CPU_CONF_SOURCES = \
conf/cpu_conf.c conf/cpu_conf.h
+
# Safe console handling helper APIs
CONSOLE_CONF_SOURCES = \
conf/virconsole.c conf/virconsole.h
+# Domain listing helpers
+DOMAIN_LIST_SOURCES = \
+ conf/virdomainlist.c conf/virdomainlist.h
+
CONF_SOURCES = \
$(NETDEV_CONF_SOURCES) \
$(DOMAIN_CONF_SOURCES) \
@@ -206,7 +211,8 @@ CONF_SOURCES = \
$(INTERFACE_CONF_SOURCES) \
$(SECRET_CONF_SOURCES) \
$(CPU_CONF_SOURCES) \
- $(CONSOLE_CONF_SOURCES)
+ $(CONSOLE_CONF_SOURCES) \
+ $(DOMAIN_LIST_SOURCES)
# The remote RPC driver, covering domains, storage, networks, etc
REMOTE_DRIVER_GENERATED = \
diff --git a/src/conf/virdomainlist.c b/src/conf/virdomainlist.c
new file mode 100644
index 0000000..8889fee
--- /dev/null
+++ b/src/conf/virdomainlist.c
@@ -0,0 +1,182 @@
+/**
+ * virdomainlist.c: Helpers for listing and filtering domains.
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Peter Krempa <pkrempa(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "virdomainlist.h"
+
+#include "internal.h"
+#include "virhash.h"
+#include "domain_conf.h"
+#include "memory.h"
+#include "datatypes.h"
+#include "virterror_internal.h"
+#include "ignore-value.h"
+
+#define VIR_FROM_THIS VIR_FROM_DOMAIN
+
+struct virDomainListData {
+ virConnectPtr conn;
+ virDomainPtr *domains;
+ unsigned int flags;
+ int ndomains;
+ bool error;
+};
+
+#define MATCH(FLAG) (data->flags & (FLAG))
+static void
+virDomainListPopulate(void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ struct virDomainListData *data = opaque;
+ virDomainObjPtr vm = payload;
+ virDomainPtr dom;
+
+ if (data->error)
+ return;
+
+ virDomainObjLock(vm);
+ /* check if the domain matches the filter */
+
+ /* filter by active state */
+ if (MATCH(VIR_CONNECT_LIST_FILTERS_ACTIVE) &&
+ !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) &&
+ virDomainObjIsActive(vm)) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) &&
+ !virDomainObjIsActive(vm))))
+ goto cleanup;
+
+ /* filter by persistence */
+ if (MATCH(VIR_CONNECT_LIST_FILTERS_PERSISTENT) &&
+ !((MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT) &&
+ vm->persistent) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
+ !vm->persistent)))
+ goto cleanup;
+
+ /* filter by domain state */
+ if (MATCH(VIR_CONNECT_LIST_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))))
+ goto cleanup;
+ }
+
+ /* managed save filter function is provided from the driver */
+ if (MATCH(VIR_CONNECT_LIST_FILTERS_MANAGEDSAVE) &&
+ !((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) &&
+ vm->hasManagedSave) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) &&
+ !vm->hasManagedSave)))
+ goto cleanup;
+
+ /* filter by autostart option */
+ if (MATCH(VIR_CONNECT_LIST_FILTERS_AUTOSTART) &&
+ !((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && vm->autostart) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && !vm->autostart)))
+ goto cleanup;
+
+ /* filter by snapshot existence */
+ if (MATCH(VIR_CONNECT_LIST_FILTERS_SNAPSHOT)) {
+ int nsnap = virDomainSnapshotObjListNum(&vm->snapshots, 0);
+ if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && nsnap > 0) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && nsnap <= 0)))
+ goto cleanup;
+ }
+
+ /* just count the machines */
+ if (!data->domains) {
+ data->ndomains++;
+ return;
+ }
+
+ if (!(dom = virGetDomain(data->conn, vm->def->name, vm->def->uuid)))
+ goto no_memory;
+
+ dom->id = vm->def->id;
+
+ data->domains[data->ndomains++] = dom;
+
+cleanup:
+ virDomainObjUnlock(vm);
+ return;
+
+no_memory:
+ virReportOOMError();
+ data->error = true;
+ goto cleanup;
+}
+#undef MATCH
+
+int
+virDomainList(virConnectPtr conn,
+ virHashTablePtr domobjs,
+ virDomainPtr **domains,
+ unsigned int flags)
+{
+ int ret = -1;
+ int i;
+
+ struct virDomainListData data = { conn, NULL, flags, 0, false };
+
+ if (domains) {
+ if (VIR_ALLOC_N(data.domains, virHashSize(domobjs) + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ virHashForEach(domobjs, virDomainListPopulate, &data);
+
+ if (data.error)
+ goto cleanup;
+
+ if (data.domains) {
+ /* trim the array to the final size */
+ ignore_value(VIR_REALLOC_N(data.domains, data.ndomains + 1));
+ *domains = data.domains;
+ data.domains = NULL;
+ }
+
+ ret = data.ndomains;
+
+cleanup:
+ if (data.domains) {
+ int count = virHashSize(domobjs);
+ for (i = 0; i < count; i++) {
+ if (data.domains[i])
+ virDomainFree(data.domains[i]);
+ }
+ }
+
+ VIR_FREE(data.domains);
+ return ret;
+}
diff --git a/src/conf/virdomainlist.h b/src/conf/virdomainlist.h
new file mode 100644
index 0000000..caee592
--- /dev/null
+++ b/src/conf/virdomainlist.h
@@ -0,0 +1,66 @@
+/**
+ * virdomainlist.h: Helpers for listing and filtering domains.
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Peter Krempa <pkrempa(a)redhat.com>
+ */
+#ifndef __VIR_DOMAIN_LIST_H__
+# define __VIR_DOMAIN_LIST_H__
+
+# include "internal.h"
+# include "virhash.h"
+# include "domain_conf.h"
+
+# define VIR_CONNECT_LIST_FILTERS_ACTIVE \
+ (VIR_CONNECT_LIST_DOMAINS_ACTIVE | \
+ VIR_CONNECT_LIST_DOMAINS_INACTIVE)
+
+# define VIR_CONNECT_LIST_FILTERS_PERSISTENT \
+ (VIR_CONNECT_LIST_DOMAINS_PERSISTENT | \
+ VIR_CONNECT_LIST_DOMAINS_TRANSIENT)
+
+# define VIR_CONNECT_LIST_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_FILTERS_MANAGEDSAVE \
+ (VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE | \
+ VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE)
+
+# define VIR_CONNECT_LIST_FILTERS_AUTOSTART \
+ (VIR_CONNECT_LIST_DOMAINS_AUTOSTART | \
+ VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)
+
+# define VIR_CONNECT_LIST_FILTERS_SNAPSHOT \
+ (VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT | \
+ VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT)
+
+# define VIR_CONNECT_LIST_FILTERS_ALL \
+ (VIR_CONNECT_LIST_FILTERS_ACTIVE | \
+ VIR_CONNECT_LIST_FILTERS_PERSISTENT | \
+ VIR_CONNECT_LIST_FILTERS_STATE | \
+ VIR_CONNECT_LIST_FILTERS_MANAGEDSAVE | \
+ VIR_CONNECT_LIST_FILTERS_AUTOSTART | \
+ VIR_CONNECT_LIST_FILTERS_SNAPSHOT)
+
+int virDomainList(virConnectPtr conn, virHashTablePtr domobjs,
+ virDomainPtr **domains, unsigned int flags);
+
+#endif /* __VIR_DOMAIN_LIST_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fdf2186..2e963f8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1237,6 +1237,10 @@ virConsoleOpen;
virDBusGetSystemBus;
+# virdomainlist.h
+virDomainList;
+
+
# virfile.h
virFileClose;
virFileDirectFdFlag;
--
1.7.3.4