From 2c6808044408fba9ff9547ad88bb8a0f44ee21a0 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 5 Jun 2012 14:00:52 +0200 Subject: [PATCH] conf: Add helper for listing domains on drivers supporting virDomainObj 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. --- 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 deletion(-) 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 2bcebcfb2e..e40909bbb4 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 0000000000..107e693ec6 --- /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 + */ + +#include + +#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; +} diff --git a/src/conf/virdomainlist.h b/src/conf/virdomainlist.h new file mode 100644 index 0000000000..caee592795 --- /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 + */ +#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 ea0e59b659..5a94b8bd64 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1239,6 +1239,10 @@ virConsoleOpen; virDBusGetSystemBus; +# virdomainlist.h +virDomainList; + + # virfile.h virFileClose; virFileDirectFdFlag;