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;