--- /dev/null
+/**
+ * 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@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;
+ }
+
+ /* filter by existence of managed save state */
+ 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;
+}
--- /dev/null
+/**
+ * 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@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__ */