[libvirt] [PATCHv3 00/12] Add api for atomic listing of domains

This is the third respin of the series. I've incorporated suggestions from Eric's review and cleaned up some nits that I found while polishing the series. This respin also contains two new cleanup patches: driver: Clean up driver header to space indentation maint: include ignore-value in internal.h Peter Krempa (12): lib: Add public api to enable atomic listing of guest virsh: add support for virConnectListAllDomains and clean up cmdList python: add API exports for virConnectListAllDomains() remote: implement remote protocol for virConnectListAllDomains() conf: Store managed save image existence in virDomainObj conf: Add helper for listing domains on drivers supporting virDomainObj drivers: Implement virListAllDomains for drivers using virDomainObj vbox: Add support for virConnectListAllDomains() hyperv: Add implementation for virConnectListAllDomains() esx: Add implementation for virConnectListAllDomains() driver: Clean up driver header to space indentation maint: include ignore-value in internal.h daemon/remote.c | 54 +++ include/libvirt/libvirt.h.in | 36 ++- python/generator.py | 1 + python/libvirt-override-api.xml | 12 +- python/libvirt-override-virConnect.py | 12 + python/libvirt-override.c | 50 +++- src/Makefile.am | 8 +- src/conf/domain_audit.c | 1 - src/conf/domain_conf.c | 1 - src/conf/domain_conf.h | 2 + src/conf/virdomainlist.c | 181 ++++++++ src/conf/virdomainlist.h | 66 +++ src/driver.h | 729 +++++++++++++++++---------------- src/esx/esx_driver.c | 194 +++++++++ src/hyperv/hyperv_driver.c | 136 ++++++ src/internal.h | 1 + src/libvirt.c | 124 ++++++- src/libvirt_private.syms | 4 + src/libvirt_public.syms | 1 + src/libxl/libxl_driver.c | 61 +++- src/lxc/lxc_driver.c | 19 + src/network/bridge_driver.c | 1 - src/node_device/node_device_hal.c | 1 - src/openvz/openvz_conf.c | 1 - src/openvz/openvz_driver.c | 19 + src/qemu/qemu_domain.c | 1 - src/qemu/qemu_driver.c | 67 +++- src/qemu/qemu_monitor_json.c | 1 - src/remote/remote_driver.c | 64 +++ src/remote/remote_protocol.x | 14 +- src/remote_protocol-structs | 12 + src/test/test_driver.c | 19 + src/uml/uml_driver.c | 18 + src/util/command.c | 1 - src/util/event_poll.c | 1 - src/util/logging.c | 1 - src/util/memory.c | 1 - src/util/threadpool.c | 1 - src/util/virfile.h | 1 - src/util/virnetdevbandwidth.c | 1 - src/vbox/vbox_tmpl.c | 170 ++++++++ src/vmware/vmware_driver.c | 20 + src/xenapi/xenapi_driver.c | 1 - tests/shunloadtest.c | 1 - tools/virsh.c | 555 +++++++++++++++++-------- tools/virsh.pod | 91 +++-- 46 files changed, 2155 insertions(+), 601 deletions(-) create mode 100644 src/conf/virdomainlist.c create mode 100644 src/conf/virdomainlist.h -- 1.7.3.4

This patch adds a new public api that lists domains. The new approach is different from those used before. There are key points to this: 1) The list is acquired atomically and contains both active and inactive domains (guests). This eliminates the need to call two different list APIs, where the state might change in between the calls. 2) The returned list consists of virDomainPtrs instead of names or ID's that have to be converted to virDomainPtrs anyways using separate calls for each one of them. This is more convenient and saves hypervisor calls. 3) The returned list is auto-allocated. This saves a lot of hassle for the users. 4) Built in support for filtering. The API call supports various filtering flags that modify the output list according to user needs. Available filter groups: Domain status: VIR_CONNECT_LIST_DOMAINS_ACTIVE, VIR_CONNECT_LIST_DOMAINS_INACTIVE Domain persistence: VIR_CONNECT_LIST_DOMAINS_PERSISTENT, VIR_CONNECT_LIST_DOMAINS_TRANSIENT Domain state: VIR_CONNECT_LIST_DOMAINS_RUNNING, VIR_CONNECT_LIST_DOMAINS_PAUSED, VIR_CONNECT_LIST_DOMAINS_SHUTOFF, VIR_CONNECT_LIST_DOMAINS_OTHER Existence of managed save image: VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE, VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE Auto-start option: VIR_CONNECT_LIST_DOMAINS_AUTOSTART, VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART Existence of snapshot: VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT, VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT 5) The python binding returns a list of domain objects that is very neat to work with. The only problem with this approach is no support from code generators so both RPC code and python bindings had to be written manually. *include/libvirt/libvirt.h.in: - add API prototype - clean up whitespace mistakes nearby *python/generator.py: - inhibit generation of the bindings for the new api *src/driver.h: - add driver prototype - clean up some whitespace mistakes nearby *src/libvirt.c: - add public implementation *src/libvirt_public.syms: - export the new symbol --- Diff to v2: - doc tweaks and spelling corrections - return NULL in the return array on error --- include/libvirt/libvirt.h.in | 36 ++++++++++++- python/generator.py | 1 + src/driver.h | 11 +++- src/libvirt.c | 124 +++++++++++++++++++++++++++++++++++++++++- src/libvirt_public.syms | 1 + 5 files changed, 166 insertions(+), 7 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index fcb6695..48b6516 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1759,8 +1759,40 @@ int virDomainUndefineFlags (virDomainPtr domain, unsigned int flags); int virConnectNumOfDefinedDomains (virConnectPtr conn); int virConnectListDefinedDomains (virConnectPtr conn, - char **const names, - int maxnames); + char **const names, + int maxnames); +/** + * virConnectListAllDomainsFlags: + * + * Flags used to tune which domains are listed by virConnectListAllDomains(). + * Note that these flags come in groups; if all bits from a group are 0, + * then that group is not used to filter results. + */ +typedef enum { + VIR_CONNECT_LIST_DOMAINS_ACTIVE = 1 << 0, + VIR_CONNECT_LIST_DOMAINS_INACTIVE = 1 << 1, + + VIR_CONNECT_LIST_DOMAINS_PERSISTENT = 1 << 2, + VIR_CONNECT_LIST_DOMAINS_TRANSIENT = 1 << 3, + + VIR_CONNECT_LIST_DOMAINS_RUNNING = 1 << 4, + VIR_CONNECT_LIST_DOMAINS_PAUSED = 1 << 5, + VIR_CONNECT_LIST_DOMAINS_SHUTOFF = 1 << 6, + VIR_CONNECT_LIST_DOMAINS_OTHER = 1 << 7, + + VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE = 1 << 8, + VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE = 1 << 9, + + VIR_CONNECT_LIST_DOMAINS_AUTOSTART = 1 << 10, + VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART = 1 << 11, + + VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT = 1 << 12, + VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT = 1 << 13, +} virConnectListAllDomainsFlags; + +int virConnectListAllDomains (virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags); int virDomainCreate (virDomainPtr domain); int virDomainCreateWithFlags (virDomainPtr domain, unsigned int flags); diff --git a/python/generator.py b/python/generator.py index 9530867..0b6ac7c 100755 --- a/python/generator.py +++ b/python/generator.py @@ -453,6 +453,7 @@ skip_function = ( 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py 'virSaveLastError', # We have our own python error wrapper 'virFreeError', # Only needed if we use virSaveLastError + 'virConnectListAllDomains', #overridden in virConnect.py 'virStreamRecvAll', # Pure python libvirt-override-virStream.py 'virStreamSendAll', # Pure python libvirt-override-virStream.py diff --git a/src/driver.h b/src/driver.h index aa7a377..c4e558f 100644 --- a/src/driver.h +++ b/src/driver.h @@ -251,9 +251,13 @@ typedef char * const char *domainXml, unsigned int flags); typedef int - (*virDrvListDefinedDomains) (virConnectPtr conn, - char **const names, - int maxnames); + (*virDrvListDefinedDomains) (virConnectPtr conn, + char **const names, + int maxnames); +typedef int + (*virDrvListAllDomains) (virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags); typedef int (*virDrvNumOfDefinedDomains) (virConnectPtr conn); typedef int @@ -866,6 +870,7 @@ struct _virDriver { virDrvGetCapabilities getCapabilities; virDrvListDomains listDomains; virDrvNumOfDomains numOfDomains; + virDrvListAllDomains listAllDomains; virDrvDomainCreateXML domainCreateXML; virDrvDomainLookupByID domainLookupByID; virDrvDomainLookupByUUID domainLookupByUUID; diff --git a/src/libvirt.c b/src/libvirt.c index 00358d6..e390f39 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -1780,7 +1780,14 @@ error: * * Collect the list of active domains, and store their IDs in array @ids * - * Returns the number of domains found or -1 in case of error + * For inactive domains, see virConnectListDefinedDomains(). For more + * control over the results, see virConnectListAllDomains(). + * + * Returns the number of domains found or -1 in case of error. Note that + * this command is inherently racy; a domain can be started between a + * call to virConnectNumOfDomains() and this call; you are only guaranteed + * that all currently active domains were listed if the return is less + * than @maxids. */ int virConnectListDomains(virConnectPtr conn, int *ids, int maxids) @@ -7953,7 +7960,14 @@ error: * list the defined but inactive domains, stores the pointers to the names * in @names * - * Returns the number of names provided in the array or -1 in case of error + * For active domains, see virConnectListDomains(). For more control over + * the results, see virConnectListAllDomains(). + * + * Returns the number of names provided in the array or -1 in case of error. + * Note that this command is inherently racy; a domain can be defined between + * a call to virConnectNumOfDefinedDomains() and this call; you are only + * guaranteed that all currently defined domains were listed if the return + * is less than @maxids. The client must call free() on each returned name. */ int virConnectListDefinedDomains(virConnectPtr conn, char **const names, @@ -7987,6 +8001,112 @@ error: } /** + * virConnectListAllDomains: + * @conn: Pointer to the hypervisor connection. + * @domains: Pointer to a variable to store the array containing domain objects + * or NULL if the list is not required (just returns number of guests). + * @flags: bitwise-OR of virConnectListAllDomainsFlags + * + * Collect a possibly-filtered list of all domains, and return an allocated + * array of information for each. This API solves the race inherent in + * virConnectListDomains() and virConnectListDefinedDomains(). + * + * Normally, all domains are returned; however, @flags can be used to + * filter the results for a smaller list of targeted domains. The valid + * flags are divided into groups, where each group contains bits that + * describe mutually exclusive attributes of a domain, and where all bits + * within a group describe all possible domains. Some hypervisors might + * reject explicit bits from a group where the hypervisor cannot make a + * distinction (for example, not all hypervisors can tell whether domains + * have snapshots). For a group supported by a given hypervisor, the + * behavior when no bits of a group are set is identical to the behavior + * when all bits in that group are set. When setting bits from more than + * one group, it is possible to select an impossible combination (such + * as an inactive transient domain), in that case a hypervisor may return + * either 0 or an error. + * + * The first group of @flags is VIR_CONNECT_LIST_DOMAINS_ACTIVE (online + * domains) and VIR_CONNECT_LIST_DOMAINS_INACTIVE (offline domains). + * + * The next group of @flags is VIR_CONNECT_LIST_DOMAINS_PERSISTENT (defined + * domains) and VIR_CONNECT_LIST_DOMAINS_TRANSIENT (running but not defined). + * + * The next group of @flags covers various domain states: + * VIR_CONNECT_LIST_DOMAINS_RUNNING, VIR_CONNECT_LIST_DOMAINS_PAUSED, + * VIR_CONNECT_LIST_DOMAINS_SHUTOFF, and a catch-all for all other states + * (such as crashed, this catch-all covers the possibility of adding new + * states). + * + * The remaining groups cover boolean attributes commonly asked about + * domains; they include VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE and + * VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE, for filtering based on whether + * a managed save image exists; VIR_CONNECT_LIST_DOMAINS_AUTOSTART and + * VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART, for filtering based on autostart; + * VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT and + * VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT, for filtering based on whether + * a domain has snapshots. + * + * Returns the number of domains found or -1 and sets domains to NULL in case + * of error. On success, the array stored into @doms is guaranteed to have an + * extra allocated element set to NULL but not included in the return count, to + * make iteration easier. The caller is responsible for calling virDomainFree() + * on each array element, then calling free() on @doms. + * + * Example of usage: + * virDomainPtr *domains; + * virDomainPtr dom; + * int i; + * int ret; + * unsigned int flags = VIR_CONNECT_LIST_RUNNING | + * VIR_CONNECT_LIST_PERSISTENT; + * + * ret = virConnectListAllDomains(conn, &domains, flags); + * if (ret < 0) + * error(); + * + * for (i = 0; i < ret; i++) { + * do_something_with_domain(domains[i]); + * + * //here or in a separate loop if needed + * virDomainFree(domains[i]); + * } + * + * free(domains); + */ +int +virConnectListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, domains=%p, flags=%x", conn, domains, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (domains) + *domains = NULL; + + if (conn->driver->listAllDomains) { + int ret; + ret = conn->driver->listAllDomains(conn, domains, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(conn); + return -1; +} + +/** * virDomainCreate: * @domain: pointer to a defined domain * diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index ba61595..912f7ca 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -536,6 +536,7 @@ LIBVIRT_0.9.11 { LIBVIRT_0.9.13 { global: + virConnectListAllDomains; virDomainSnapshotRef; } LIBVIRT_0.9.11; -- 1.7.3.4

On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch adds a new public api that lists domains. The new approach is different from those used before. There are key points to this:
1) The list is acquired atomically and contains both active and inactive domains (guests). This eliminates the need to call two different list APIs, where the state might change in between the calls.
2) The returned list consists of virDomainPtrs instead of names or ID's that have to be converted to virDomainPtrs anyways using separate calls for each one of them. This is more convenient and saves hypervisor calls.
3) The returned list is auto-allocated. This saves a lot of hassle for the users.
4) Built in support for filtering. The API call supports various filtering flags that modify the output list according to user needs.
--- Diff to v2: - doc tweaks and spelling corrections - return NULL in the return array on error
Looks good. ACK to this patch (although you'll have to rebase it now for a minor conflict resolution), to commit to the interface, while we hash out any details in the remainder of the series. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch adds a new public api that lists domains. The new approach is different from those used before. There are key points to this:
+int +virConnectListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, domains=%p, flags=%x", conn, domains, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (domains) + *domains = NULL;
If we are going to guarantee that *domains is NULL on error, then you need to hoist this statement above the !VIR_IS_CONNECT(conn) clause. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/14/12 17:35, Eric Blake wrote:
On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch adds a new public api that lists domains. The new approach is different from those used before. There are key points to this:
+int +virConnectListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, domains=%p, flags=%x", conn, domains, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (domains) + *domains = NULL;
If we are going to guarantee that *domains is NULL on error, then you need to hoist this statement above the !VIR_IS_CONNECT(conn) clause.
Moved and pushed; Thanks. Peter

This patch makes use of the newly added api virConnectListAllDomains() to list domains in virsh. Virsh now represents lists of domains using an internal structure vshDomainList. This structure contains the virDomainPtr list as provided by virConnectListAllDomains() and the count of domains in the list. For backwards compatiblity function vshDomList was added that tries to enumerate the domains using the new API and if the API is not supported falls back to the older approach with the two list functions. The helper function also simulates filtering by all currently supported flags added with virConnectListAllDomains(). This patch also cleans up the "list" command handler to use the new helpers and adds new command line flags to make use of filtering. --- Diff to v2: - moved this patch right after API implementation to make testing fallback easier - added support for all filtering flags both in fallback code and in "list" command - fixed messed up syntax check silencing :) - fixed spelling errors but probably introduced a ton of new as I've added new docs --- tools/virsh.c | 555 ++++++++++++++++++++++++++++++++++++++----------------- tools/virsh.pod | 91 +++++++--- 2 files changed, 449 insertions(+), 197 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index abcfbff..8d86cb0 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -64,6 +64,7 @@ #include "util/bitmap.h" #include "conf/domain_conf.h" #include "virtypedparam.h" +#include "intprops.h" static char *progname; @@ -490,22 +491,307 @@ _vshStrdup(vshControl *ctl, const char *s, const char *filename, int line) #define realloc use_vshRealloc_instead_of_realloc #define strdup use_vshStrdup_instead_of_strdup -static int idsorter(const void *a, const void *b) { - const int *ia = (const int *)a; - const int *ib = (const int *)b; +static int +namesorter(const void *a, const void *b) +{ + const char **sa = (const char**)a; + const char **sb = (const char**)b; - if (*ia > *ib) - return 1; - else if (*ia < *ib) - return -1; - return 0; + /* User visible sort, so we want locale-specific case comparison. */ + return strcasecmp(*sa, *sb); +} + +static int +domsorter(const void *a, const void *b) +{ + virDomainPtr *da = (virDomainPtr *) a; + virDomainPtr *db = (virDomainPtr *) b; + unsigned int ida = virDomainGetID(*da); + unsigned int idb = virDomainGetID(*db); + unsigned int inactive = (unsigned int) -1; + + if (ida == inactive && idb == inactive) + return strcasecmp(virDomainGetName(*da), virDomainGetName(*db)); + + if (ida != inactive && idb != inactive) { + if (ida > idb) + return 1; + else if (ida < idb) + return -1; + } + + if (ida != inactive) + return -1; + else + return 1; +} + +struct vshDomainList { + virDomainPtr *domains; + int ndomains; +}; +typedef struct vshDomainList *vshDomainListPtr; + +#define MATCH(FLAG) (flags & (FLAG)) +static int +vshDomList(vshControl *ctl, vshDomainListPtr domlist, unsigned int flags) +{ + int rv = -1; + virErrorPtr err = NULL; + int i; + int *ids = NULL; + int nids = 0; + char **names = NULL; + int nnames = 0; + virDomainPtr dom; + virDomainPtr *doms = NULL; + int ndoms = 0; + int count = 0; + int active; + int persistent; + int autostart; + int state; + int nsnap; + int mansave; + + domlist->domains = NULL; + domlist->ndomains = 0; + + /* try the list with flags support */ + if ((ndoms = virConnectListAllDomains(ctl->conn, &doms, flags)) >= 0) { + domlist->ndomains = ndoms; + domlist->domains = doms; + doms = NULL; + goto finished; + } + + /* check if the command is actualy supported */ + if ((err = virGetLastError()) && + err->code == VIR_ERR_NO_SUPPORT) + goto fallback; + + if ((err= virGetLastError()) && + err->code == VIR_ERR_INVALID_ARG) { + /* try again the new API but without flags this time */ + if ((ndoms = virConnectListAllDomains(ctl->conn, &doms, 0)) >= 0) + goto filter; + } + + /* there was an error during the first or second call */ + vshError(ctl, "%s", _("Failed to list domains")); + goto cleanup; + + +fallback: + /* fall back to old method */ + virResetLastError(); + + /* list active domains, if necessary */ + if (!MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_INACTIVE) || + MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE)) { + + if ((nids = virConnectNumOfDomains(ctl->conn)) < 0) { + vshError(ctl, "%s", _("Failed to list active domains")); + goto cleanup; + } + + if (nids) { + ids = vshMalloc(ctl, sizeof(int) * nids); + + if ((nids = virConnectListDomains(ctl->conn, ids, nids)) < 0) { + vshError(ctl, "%s", _("Failed to list active domains")); + goto cleanup; + } + } + } + + if (!MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_INACTIVE) || + MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE)) { + + if ((nnames = virConnectNumOfDefinedDomains(ctl->conn)) < 0) { + vshError(ctl, "%s", _("Failed to list inactive domains")); + goto cleanup; + } + + if (nnames) { + names = vshMalloc(ctl, sizeof(char *) * nnames); + + if ((nnames = virConnectListDefinedDomains(ctl->conn, names, + nnames)) < 0) { + vshError(ctl, "%s", _("Failed to list inactive domains")); + goto cleanup; + } + } + } + + doms = vshMalloc(ctl, sizeof(virDomainPtr) * (nids + nnames)); + ndoms = 0; + + /* get active domains */ + for (i = 0; i < nids; i++) { + if (!(dom = virDomainLookupByID(ctl->conn, ids[i]))) + continue; + doms[ndoms++] = dom; + } + + /* get inctive domains */ + for (i = 0; i < nnames; i++) { + if (!(dom = virDomainLookupByName(ctl->conn, names[i]))) + continue; + doms[ndoms++] = dom; + } + +filter: + /* filter list the list if the list was acquired by fallback means */ + for (i = 0; i < ndoms; i++) { + dom = doms[i]; + + /* active state filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_INACTIVE)) { + if ((active = virDomainIsActive(dom)) < 0) { + vshError(ctl, "%s", _("Failed to get domain active state")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && active) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) && !active))) + goto remove_entry; + } + + /* persistence filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_TRANSIENT)) { + if ((persistent = virDomainIsPersistent(dom)) < 0) { + vshError(ctl, "%s", _("Failed to get domain persistence info")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT) && persistent) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && !persistent))) + goto remove_entry; + } + + /* domain state filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING | + VIR_CONNECT_LIST_DOMAINS_PAUSED | + VIR_CONNECT_LIST_DOMAINS_SHUTOFF | + VIR_CONNECT_LIST_DOMAINS_OTHER)) { + if (virDomainGetState(dom, &state, NULL, 0) < 0) { + vshError(ctl, "%s", _("Failed to get domain state")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) && + state == VIR_DOMAIN_RUNNING) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) && + state == VIR_DOMAIN_PAUSED) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) && + state == VIR_DOMAIN_SHUTOFF) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) && + (state != VIR_DOMAIN_RUNNING && + state != VIR_DOMAIN_PAUSED && + state != VIR_DOMAIN_SHUTOFF)))) + goto remove_entry; + } + + /* autostart filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART | + VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) { + if (virDomainGetAutostart(dom, &autostart) < 0) { + vshError(ctl, "%s", _("Failed to get domain autostart state")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && autostart) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && autostart))) + goto remove_entry; + } + + /* managed save filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE | + VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE)) { + if ((mansave = virDomainHasManagedSaveImage(dom, 0)) < 0) { + vshError(ctl, "%s", + _("Failed to check for managed save image")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && mansave) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) && !mansave))) + goto remove_entry; + } + + /* snapshot filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT | + VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT)) { + if ((nsnap = virDomainSnapshotNum(dom, 0)) < 0) { + vshError(ctl, "%s", _("Failed to get snapshot count")); + goto cleanup; + } + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && nsnap > 0) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && nsnap == 0))) + goto remove_entry; + } + + /* the domain matched all filters, pack them at the front */ + doms[count++] = dom; + continue; + +remove_entry: + /* the domain has to be removed as it failed one of the filters */ + virDomainFree(doms[i]); + doms[i] = NULL; + } + + /* we're shortening the array, so it's safe to ignore value */ + ignore_value(VIR_REALLOC_N(doms, count)); + + domlist->domains = doms; + domlist->ndomains = count; + doms = NULL; + +finished: + /* sort the list */ + if (domlist->domains && domlist->ndomains > 0) + qsort(domlist->domains, domlist->ndomains, + sizeof(*domlist->domains), domsorter); + + rv = domlist->ndomains; + +cleanup: + for (i = 0; i < nnames; i++) + VIR_FREE(names[i]); + if (doms) { + for (i = 0; i < ndoms; i++) { + if (doms[i]) + virDomainFree(doms[i]); + } + } + VIR_FREE(doms); + VIR_FREE(names); + VIR_FREE(ids); + return rv; } -static int namesorter(const void *a, const void *b) { - const char **sa = (const char**)a; - const char **sb = (const char**)b; +#undef MATCH + +static void +vshDomListFree(vshDomainListPtr domlist) +{ + int i; + + if (!domlist || !domlist->domains) + return; - /* User visible sort, so we want locale-specific case comparison. */ - return strcasecmp(*sa, *sb); + for (i = 0; i < domlist->ndomains; i++) { + if (domlist->domains[i]) + virDomainFree(domlist->domains[i]); + } + + domlist->ndomains = 0; + VIR_FREE(domlist->domains); } static double @@ -977,6 +1263,21 @@ static const vshCmdOptDef opts_list[] = { {"all", VSH_OT_BOOL, 0, N_("list inactive & active domains")}, {"transient", VSH_OT_BOOL, 0, N_("list transient domains")}, {"persistent", VSH_OT_BOOL, 0, N_("list persistent domains")}, + {"snapshot-yes", VSH_OT_BOOL, 0, + N_("list domains with existing snapshot")}, + {"snapshot-no", VSH_OT_BOOL, 0, N_("list domains without a snapshot")}, + {"state-running", VSH_OT_BOOL, 0, N_("list domains in running state")}, + {"state-paused", VSH_OT_BOOL, 0, N_("list domains in paused state")}, + {"state-shutoff", VSH_OT_BOOL, 0, N_("list domains in shutoff state")}, + {"state-other", VSH_OT_BOOL, 0, N_("list domains in other states")}, + {"autostart-yes", VSH_OT_BOOL, 0, + N_("list domains with autostart enabled")}, + {"autostart-no", VSH_OT_BOOL, 0, + N_("list domains with autostart disabled")}, + {"managedsave-yes", VSH_OT_BOOL, 0, + N_("list domains with managed save state")}, + {"managedsave-no", VSH_OT_BOOL, 0, + N_("list domains without managed save")}, {"uuid", VSH_OT_BOOL, 0, N_("list uuid's only")}, {"name", VSH_OT_BOOL, 0, N_("list domain names only")}, {"table", VSH_OT_BOOL, 0, N_("list table (default)")}, @@ -987,38 +1288,50 @@ static const vshCmdOptDef opts_list[] = { }; +#define FILTER(NAME, FLAG) \ + if (vshCommandOptBool(cmd, NAME)) \ + flags |= (FLAG) static bool cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { - bool inactive = vshCommandOptBool(cmd, "inactive"); - bool all = vshCommandOptBool(cmd, "all"); - bool active = !inactive || all; - int *ids = NULL, maxid = 0, i; - char **names = NULL; - int maxname = 0; bool managed = vshCommandOptBool(cmd, "managed-save"); bool optTitle = vshCommandOptBool(cmd, "title"); bool optTable = vshCommandOptBool(cmd, "table"); bool optUUID = vshCommandOptBool(cmd, "uuid"); bool optName = vshCommandOptBool(cmd, "name"); - bool optPersistent = vshCommandOptBool(cmd, "persistent"); - bool optTransient = vshCommandOptBool(cmd, "transient"); - bool persistUsed = true; - virDomainPtr dom = NULL; + int i; char *title; char uuid[VIR_UUID_STRING_BUFLEN]; int state; - int persistent; bool ret = false; + struct vshDomainList list; + char id[INT_BUFSIZE_BOUND(unsigned int)]; + unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE; - inactive |= all; + /* construct filter flags */ + if (vshCommandOptBool(cmd, "inactive")) + flags = VIR_CONNECT_LIST_DOMAINS_INACTIVE; - /* process arguments */ - if (!optPersistent && !optTransient) { - optPersistent = true; - optTransient = true; - persistUsed = false; - } + if (vshCommandOptBool(cmd, "all")) + flags = VIR_CONNECT_LIST_DOMAINS_INACTIVE | + VIR_CONNECT_LIST_DOMAINS_ACTIVE; + + FILTER("persistent", VIR_CONNECT_LIST_DOMAINS_PERSISTENT); + FILTER("transient", VIR_CONNECT_LIST_DOMAINS_TRANSIENT); + + FILTER("managedsave-yes", VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE); + FILTER("managedsave-no", VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE); + + FILTER("autostart-yes", VIR_CONNECT_LIST_DOMAINS_AUTOSTART); + FILTER("autostart-no", VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART); + + FILTER("snapshot-yes", VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT); + FILTER("snapshot-no", VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT); + + FILTER("state-running", VIR_CONNECT_LIST_DOMAINS_RUNNING); + FILTER("state-paused", VIR_CONNECT_LIST_DOMAINS_PAUSED); + FILTER("state-shutoff", VIR_CONNECT_LIST_DOMAINS_SHUTOFF); + FILTER("state-other", VIR_CONNECT_LIST_DOMAINS_OTHER); if (optTable + optName + optUUID > 1) { vshError(ctl, "%s", @@ -1033,169 +1346,67 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) if (!vshConnectionUsability(ctl, ctl->conn)) return false; - if (active) { - maxid = virConnectNumOfDomains(ctl->conn); - if (maxid < 0) { - vshError(ctl, "%s", _("Failed to list active domains")); - return false; - } - if (maxid) { - ids = vshMalloc(ctl, sizeof(int) * maxid); - - if ((maxid = virConnectListDomains(ctl->conn, ids, maxid)) < 0) { - vshError(ctl, "%s", _("Failed to list active domains")); - goto cleanup; - } - - qsort(ids, maxid, sizeof(int), idsorter); - } - } - - if (inactive) { - maxname = virConnectNumOfDefinedDomains(ctl->conn); - if (maxname < 0) { - vshError(ctl, "%s", _("Failed to list inactive domains")); - goto cleanup; - } - if (maxname) { - names = vshMalloc(ctl, sizeof(char *) * maxname); - - if ((maxname = virConnectListDefinedDomains(ctl->conn, - names, - maxname)) < 0) { - vshError(ctl, "%s", _("Failed to list inactive domains")); - goto cleanup; - } - - qsort(&names[0], maxname, sizeof(char*), namesorter); - } - } + if (vshDomList(ctl, &list, flags) < 0) + goto cleanup; /* print table header in legacy mode */ if (optTable) { - if (optTitle) { + if (optTitle) vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n", _("Id"), _("Name"), _("State"), _("Title"), "-----------------------------------------" "-----------------------------------------"); - } else { + else vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n", _("Id"), _("Name"), _("State"), "-----------------------------------------" "-----------"); - } } - for (i = 0; i < maxid; i++) { - dom = virDomainLookupByID(ctl->conn, ids[i]); - - /* this kind of work with domains is not atomic operation */ - if (!dom) - continue; + for (i = 0; i < list.ndomains; i++) { + if (virDomainGetID(list.domains[i]) != (unsigned int) -1) + snprintf(id, sizeof(id), "%d", virDomainGetID(list.domains[i])); + else + ignore_value(virStrcpyStatic(id, "-")); - if (persistUsed) { - persistent = virDomainIsPersistent(dom); - if (persistent < 0) { - vshError(ctl, "%s", - _("Failed to determine domain's persistent state")); - goto cleanup; - } + state = vshDomainState(ctl, list.domains[i], NULL); + if (optTable && managed && state == VIR_DOMAIN_SHUTOFF && + virDomainHasManagedSaveImage(list.domains[i], 0) > 0) + state = -2; - if (!(persistent ? optPersistent : optTransient)) { - virDomainFree(dom); - dom = NULL; - continue; - } - } - - if (optTable) { - if (optTitle) { - if (!(title = vshGetDomainDescription(ctl, dom, true, 0))) - goto cleanup; - - vshPrint(ctl, " %-5d %-30s %-10s %-20s\n", - virDomainGetID(dom), - virDomainGetName(dom), - _(vshDomainStateToString(vshDomainState(ctl, dom, NULL))), - title); - VIR_FREE(title); - } else { - vshPrint(ctl, " %-5d %-30s %s\n", - virDomainGetID(dom), - virDomainGetName(dom), - _(vshDomainStateToString(vshDomainState(ctl, dom, NULL)))); - } - } else if (optUUID) { - if (virDomainGetUUIDString(dom, uuid) < 0) { - vshError(ctl, "%s", - _("Failed to get domain's UUID")); - goto cleanup; - } - vshPrint(ctl, "%s\n", uuid); - } else if (optName) { - vshPrint(ctl, "%s\n", virDomainGetName(dom)); - } - - virDomainFree(dom); - dom = NULL; - } - - if (optPersistent) { - for (i = 0; i < maxname; i++) { - dom = virDomainLookupByName(ctl->conn, names[i]); - - /* this kind of work with domains is not atomic operation */ - if (!dom) - continue; + if (optTable) { + if (optTitle) { + if (!(title = vshGetDomainDescription(ctl, list.domains[i], true, 0))) + goto cleanup; - if (optTable) { - state = vshDomainState(ctl, dom, NULL); - if (managed && state == VIR_DOMAIN_SHUTOFF && - virDomainHasManagedSaveImage(dom, 0) > 0) - state = -2; - - if (optTitle) { - if (!(title = vshGetDomainDescription(ctl, dom, true, 0))) - goto cleanup; - - vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", - "-", - names[i], - state == -2 ? _("saved") : _(vshDomainStateToString(state)), - title); - VIR_FREE(title); - } else { - vshPrint(ctl, " %-5s %-30s %s\n", - "-", - names[i], - state == -2 ? _("saved") : _(vshDomainStateToString(state))); - } - } else if (optUUID) { - if (virDomainGetUUIDString(dom, uuid) < 0) { - vshError(ctl, "%s", - _("Failed to get domain's UUID")); - goto cleanup; - } - vshPrint(ctl, "%s\n", uuid); - } else if (optName) { - vshPrint(ctl, "%s\n", names[i]); - } + vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id, + virDomainGetName(list.domains[i]), + state == -2 ? _("saved") : _(vshDomainStateToString(state)), + title); - virDomainFree(dom); - dom = NULL; + VIR_FREE(title); + } else { + vshPrint(ctl, " %-5s %-30s %s\n", id, + virDomainGetName(list.domains[i]), + state == -2 ? _("saved") : _(vshDomainStateToString(state))); + } + } else if (optUUID) { + if (virDomainGetUUIDString(list.domains[i], uuid) < 0) { + vshError(ctl, "%s", _("Failed to get domain's UUID")); + goto cleanup; + } + vshPrint(ctl, "%s\n", uuid); + } else if (optName) { + vshPrint(ctl, "%s\n", virDomainGetName(list.domains[i])); } } ret = true; cleanup: - if (dom) - virDomainFree(dom); - VIR_FREE(ids); - for (i = 0; i < maxname; i++) - VIR_FREE(names[i]); - VIR_FREE(names); + vshDomListFree(&list); return ret; } +#undef FILTER /* * "desc" command for managing domain description and title diff --git a/tools/virsh.pod b/tools/virsh.pod index ef71717..7e7309d 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -306,9 +306,15 @@ The XML also show the NUMA topology information if available. Inject NMI to the guest. -=item B<list> [I<--inactive> | I<--all>] [I<--managed-save>] [I<--title>] - { [I<--table>] | I<--name> | I<--uuid> } [I<--persistent>] - [I<--transient>] +=item B<list> [I<--inactive> | I<--all>] + [I<--managed-save>] [I<--title>] + { [I<--table>] | I<--name> | I<--uuid> } + [I<--persistent>] [I<--transient>] + [I<--managedsave-yes>] [I<--managedsave-no>] + [I<--autostart-yes>] [I<--autostart-no>] + [I<--snapshot-yes>] [I<--snapshot-no>] + [I<--state-running>] [I<--state-paused>] + [I<--state-shutoff>] [I<--state-other>] Prints information about existing domains. If no options are specified it prints out information about running domains. @@ -316,13 +322,10 @@ specified it prints out information about running domains. An example format for the list is as follows: B<virsh> list - Id Name State - ----------------------------------- - - 0 Domain-0 running - 2 fedora paused - + Id Name State + ---------------------------------------------------- + 0 Domain-0 running + 2 fedora paused Name is the name of the domain. ID the domain numeric id. State is the run state (see below). @@ -380,11 +383,55 @@ into s3 state. =back -If I<--managed-save> is specified, then domains that have managed save -state (only possible if they are in the B<shut off> state, so you need to -specify I<--inactive> or I<--all> to actually list them) will instead -show as B<saved> in the listing. This flag is usable only with the -default I<--table> output. +Normally only active domains are listed. To list inactive domains specify +I<--inactive> or I<--all> to list both active and inactive domains. + +To filter the list of domains present on the hypervisor you may specify one or +more of filtering flags supported by the B<list> command. These flags are +grouped by function. Specifying one or more of flags from a group enables the +filter group. Supported filtering flags and groups: + +=over 4 + +=item B<Persistence> + +Flag I<--persistent> is used to include persistent domains in the returned +list. To include transient domains specify I<--transient>. + +=item B<Existence of managed save image> + +To list domains having a managed save image specify flag I<--managedsave-yes>. +For domains that don't have a managed save image specify I<--managedsave-no>. + +=item B<Domain state> + +Following filter flags to select domains by its state are available: +I<--state-running> for runnign domains, I<--state-paused> for paused domains, +I<--state-shutoff> for turned off domains and I<--state-other> for all +other states as a fallback. + +=item B<Autostarting domains> + +To list autostarting domains use the flag I<--autostart-yes>. To list domains +with this feature disabled use I<--autostart-no>. + +=item B<Snapshot existence> + +Domains that have snapshot images can be listed using flagI<--snapshot-yes>, +domains without a snapshot I<--snapshot-no>. + +=back + +First attempt to acquire the domain list is done by the non-racy listing API. +If this API is not available for the current connection the list is constructed +using fallback code that might miss domains transitioning states when the +fallback code is executed. + +If I<--managed-save> is specified, then domains that have managed save state +(only possible if they are in the B<shut off> state, so you need to specify +I<--inactive> or I<--all> to actually list them) will instead show as B<saved> +in the listing. This flag is usable only with the default I<--table> output. +Note that this flag does not filter the list of domains. If I<--name> is specified, domain names are printed instead of the table formatted one per line. If I<--uuid> is specified domain's UUID's are printed @@ -392,12 +439,6 @@ instead of names. Flag I<--table> specifies that the legacy table-formatted output should be used. This is the default. All of these are mutually exclusive. -Flag I<--persistent> specifies that persistent domains should be printed. -Similarly I<--transient> enables output of transient domains. These flags -may be combined. Default behavior is as though both were specified. (Note that -if any of these flags is specified, the check for the persistence state is done -and may fail. If none of these flags is specified, the check is skipped.) - If I<--title> is specified, then the short domain description (title) is printed in an extra column. This flag is usable only with the default I<--table> output. @@ -405,10 +446,10 @@ I<--table> output. Example: B<virsh> list --title - Id Name State Title - ----------------------------------------------- - 0 Domain-0 running Mailserver 1 - 2 fedora paused + Id Name State Title + -------------------------------------------------------------------------- + 0 Domain-0 running Mailserver 1 + 2 fedora paused =item B<freecell> [{ [I<--cellno>] B<cellno> | I<--all> }] -- 1.7.3.4

On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch makes use of the newly added api virConnectListAllDomains() to list domains in virsh.
Virsh now represents lists of domains using an internal structure vshDomainList. This structure contains the virDomainPtr list as provided by virConnectListAllDomains() and the count of domains in the list.
For backwards compatiblity function vshDomList was added that tries to
s/compatiblity/compatibility, the/
enumerate the domains using the new API and if the API is not supported falls back to the older approach with the two list functions. The helper function also simulates filtering by all currently supported flags added with virConnectListAllDomains().
This patch also cleans up the "list" command handler to use the new helpers and adds new command line flags to make use of filtering. --- Diff to v2: - moved this patch right after API implementation to make testing fallback easier - added support for all filtering flags both in fallback code and in "list" command - fixed messed up syntax check silencing :) - fixed spelling errors but probably introduced a ton of new as I've added new docs --- tools/virsh.c | 555 ++++++++++++++++++++++++++++++++++++++----------------- tools/virsh.pod | 91 +++++++--- 2 files changed, 449 insertions(+), 197 deletions(-)
This turned into a rather large patch; I'm not sure if it is worth trying to subdivide it at all, but in the interest of getting this in sooner rather than later, I'll go ahead and review it as-is.
@@ -490,22 +491,307 @@ _vshStrdup(vshControl *ctl, const char *s, const char *filename, int line) #define realloc use_vshRealloc_instead_of_realloc #define strdup use_vshStrdup_instead_of_strdup
-static int idsorter(const void *a, const void *b) { - const int *ia = (const int *)a; - const int *ib = (const int *)b; +static int +namesorter(const void *a, const void *b)
This is code motion, but the name isn't very namespace friendly. It might be worth a followup patch that renames this vshNameSorter and adjusts all clients. Splitting code motion into separate patches from new code makes both patches easier to review.
+ +static int +domsorter(const void *a, const void *b)
Likewise, I would name this vshDomSorter.
+#define MATCH(FLAG) (flags & (FLAG)) +static int +vshDomList(vshControl *ctl, vshDomainListPtr domlist, unsigned int flags)
In my patch proposal, I had the list collected as the result, as in: static vshDomainListPtr vshDomListCollect(vshControl *ctl, unsigned int flags) rather than making the caller pre-allocate vshDomainListPtr.
+ + /* try the list with flags support */
In my snapshot patches, I tried to mention a bit more in the comments, such as 0.9.13 or newer...
+ if ((ndoms = virConnectListAllDomains(ctl->conn, &doms, flags)) >= 0) { + domlist->ndomains = ndoms; + domlist->domains = doms;
Would it make any more sense to just directly import into domlist->domains instead of going through a temporary doms?
+ doms = NULL; + goto finished; + } + + /* check if the command is actualy supported */
s/actualy/actually/
+ if ((err = virGetLastError()) && + err->code == VIR_ERR_NO_SUPPORT) + goto fallback; + + if ((err= virGetLastError()) &&
Missing space before =
+ err->code == VIR_ERR_INVALID_ARG) {
and double space after ==
+ /* try again the new API but without flags this time */
grammar: try the new API again, but without flags this time
+ if ((ndoms = virConnectListAllDomains(ctl->conn, &doms, 0)) >= 0)
This misses _all_ flags, but the 'filter:' label assumes that the _ACTIVE/_INACTIVE flag was already honored. Again, if we promise in the API call that the _ACTIVE/_INACTIVE group is always supported, then here you could pass 'flags & (_ACTIVE|_INACTIVE)' instead of 0, so that 'filter' is operating from the same state.
+ goto filter; + } + + /* there was an error during the first or second call */ + vshError(ctl, "%s", _("Failed to list domains")); + goto cleanup; + + +fallback: + /* fall back to old method */
...mainly 0.9.12 and earlier.
+ + /* get active domains */ + for (i = 0; i < nids; i++) { + if (!(dom = virDomainLookupByID(ctl->conn, ids[i]))) + continue; + doms[ndoms++] = dom; + } + + /* get inctive domains */
s/inctive/inactive/
+ for (i = 0; i < nnames; i++) { + if (!(dom = virDomainLookupByName(ctl->conn, names[i]))) + continue; + doms[ndoms++] = dom;
Again, instead of going through a temporary doms, would it be worth directly sticking the virDomainLookupByName() result into domlist->domains?
+ } + +filter: + /* filter list the list if the list was acquired by fallback means */ + for (i = 0; i < ndoms; i++) { + dom = doms[i]; + + /* active state filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_INACTIVE)) {
I'm not sure you need to repeat this - if we guarantee that the new API always supports _ACTIVE/_INACTIVE, and the older API already guarantees it by virtue of the split API call, then this filter has already been applied by the time we get here.
+ /* autostart filter */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART | + VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) { + if (virDomainGetAutostart(dom, &autostart) < 0) { + vshError(ctl, "%s", _("Failed to get domain autostart state")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && autostart) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && autostart)))
Missing '!' before the second 'autostart'
+ + /* we're shortening the array, so it's safe to ignore value */ + ignore_value(VIR_REALLOC_N(doms, count));
I'm not sure if VIR_SHRINK_N does any better here, but what you have works.
+ + domlist->domains = doms; + domlist->ndomains = count; + doms = NULL; + +finished: + /* sort the list */ + if (domlist->domains && domlist->ndomains > 0) + qsort(domlist->domains, domlist->ndomains, + sizeof(*domlist->domains), domsorter);
In my snapshot patch series, I left the NULL entries in place, then taught the sorter to sink NULL entries to the end of the array, and did the sort before shrinking the size of the array instead of reassigning. And in fact, I think you have a bug in your approach, because you are packing things up front without clearing out the old location. Consider: - you reach the filter: label with 3 elements: [dom0], [dom1], [dom2] - dom0 fails the first filter, so you clean it up right away. - dom1 passes, and you copy it to the front of the array - something goes wrong, and you hit an error while querying whether dom2 needs to be filtered - now you reach the cleanup: label with [dom1], [dom1], [dom2]; and you now end up calling virDomainFree(dom1) twice. Oops. I think your approach of repositioning would be safe _if_ you also set the old position to NULL at the time you moved things (but be careful not to set the old position to NULL if the old and new position are identical); but if you don't try to pack the array during the filtering, but instead let the qsort() do the packing, then you don't even have to worry about the partial case that I listed above.
+ +To filter the list of domains present on the hypervisor you may specify one or +more of filtering flags supported by the B<list> command. These flags are +grouped by function. Specifying one or more of flags from a group enables the
s/of flags/flags/
+=item B<Domain state> + +Following filter flags to select domains by its state are available:
s/Following/The following/ s/to select domains/select a domain/
+I<--state-running> for runnign domains, I<--state-paused> for paused domains,
s/runnign/running/
+I<--state-shutoff> for turned off domains and I<--state-other> for all +other states as a fallback. + +=item B<Autostarting domains> + +To list autostarting domains use the flag I<--autostart-yes>. To list domains +with this feature disabled use I<--autostart-no>. + +=item B<Snapshot existence> + +Domains that have snapshot images can be listed using flagI<--snapshot-yes>, s/flagI</flag I</
+ +First attempt to acquire the domain list is done by the non-racy listing API. +If this API is not available for the current connection the list is constructed +using fallback code that might miss domains transitioning states when the +fallback code is executed.
I'd word this paragraph as: When talking to older servers, this command is forced to use a series of API calls with an inherent race, where a domain might not be listed or might appear more than once if it changed state between calls while the list was being collected. Newer servers do not have this problem. Getting closer. Do you need me to post my suggested improvements as a v4, or are you comfortable respinning this one? -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/11/12 22:16, Eric Blake wrote:
On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch makes use of the newly added api virConnectListAllDomains() to list domains in virsh.
Virsh now represents lists of domains using an internal structure vshDomainList. This structure contains the virDomainPtr list as provided by virConnectListAllDomains() and the count of domains in the list.
For backwards compatiblity function vshDomList was added that tries to
s/compatiblity/compatibility, the/
enumerate the domains using the new API and if the API is not supported falls back to the older approach with the two list functions. The helper function also simulates filtering by all currently supported flags added with virConnectListAllDomains().
This patch also cleans up the "list" command handler to use the new helpers and adds new command line flags to make use of filtering. --- Diff to v2: - moved this patch right after API implementation to make testing fallback easier - added support for all filtering flags both in fallback code and in "list" command - fixed messed up syntax check silencing :) - fixed spelling errors but probably introduced a ton of new as I've added new docs --- tools/virsh.c | 555 ++++++++++++++++++++++++++++++++++++++----------------- tools/virsh.pod | 91 +++++++--- 2 files changed, 449 insertions(+), 197 deletions(-)
This turned into a rather large patch; I'm not sure if it is worth trying to subdivide it at all, but in the interest of getting this in sooner rather than later, I'll go ahead and review it as-is.
I'm not sure if VIR_SHRINK_N does any better here, but what you have works.
Well, VIR_SHRINK_N takes number of elements to remove from the end but VIR_REALLOC_N takes the desired new size, so it was more intuitive to use REALLOC. but VIR_SHRINK_N(doms, ndoms, ndoms-count) looks okay too.
+ + domlist->domains = doms; + domlist->ndomains = count; + doms = NULL; +
I'd word this paragraph as:
When talking to older servers, this command is forced to use a series of API calls with an inherent race, where a domain might not be listed or might appear more than once if it changed state between calls while the list was being collected. Newer servers do not have this problem.
Getting closer. Do you need me to post my suggested improvements as a v4, or are you comfortable respinning this one?
I'll do the respin. Thanks for the suggestions. Peter

This patch adds export of the new API function virConnectListAllDomains() to the libvirt-python bindings. The virConnect object now has method "listAllDomains" that takes only the flags parameter and returns a python list of virDomain object corresponding to virDomainPtrs returned by the underlying api. The implementation is done manually as the generator does not support wrapping list of virDomainPtrs into virDomain objects. --- Diff to v2: - Added check for NULL return from libvirt_virDomainPtrWrap() --- python/libvirt-override-api.xml | 12 ++++++-- python/libvirt-override-virConnect.py | 12 ++++++++ python/libvirt-override.c | 50 ++++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index 0bafd21..2fd6dec 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -19,17 +19,23 @@ <function name='virConnectListDefinedDomains' file='python'> <info>list the defined domains, stores the pointers to the names in @names</info> <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> - <return type='str *' info='the list of Names of None in case of error'/> + <return type='str *' info='the list of Names or None in case of error'/> + </function> + <function name='virConnectListAllDomains' file='python'> + <info>returns list of all defined domains</info> + <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> + <arg name='flags' type='unsigned int' info='optional flags'/> + <return type='domain *' info='the list of domains or None in case of error'/> </function> <function name='virConnectListNetworks' file='python'> <info>list the networks, stores the pointers to the names in @names</info> <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> - <return type='str *' info='the list of Names of None in case of error'/> + <return type='str *' info='the list of Names or None in case of error'/> </function> <function name='virConnectListDefinedNetworks' file='python'> <info>list the defined networks, stores the pointers to the names in @names</info> <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> - <return type='str *' info='the list of Names of None in case of error'/> + <return type='str *' info='the list of Names or None in case of error'/> </function> <function name='virDomainLookupByUUID' file='python'> <info>Try to lookup a domain on the given hypervisor based on its UUID.</info> diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index 811e16b..ecb5680 100644 --- a/python/libvirt-override-virConnect.py +++ b/python/libvirt-override-virConnect.py @@ -185,3 +185,15 @@ raise libvirtError ('virConnectDomainEventRegisterAny() failed', conn=self) self.domainEventCallbackID[ret] = opaque return ret + + def listAllDomains(self, flags): + """List all domains and returns a list of domain objects""" + ret = libvirtmod.virConnectListAllDomains(self._o, flags) + if ret is None: + raise libvirtError("virConnectListAllDomains() failed", conn=self) + + retlist = list() + for domptr in ret: + retlist.append(virDomain(self, _obj=domptr)) + + return retlist diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 130e702..0a3f56e 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -1944,7 +1944,7 @@ libvirt_virConnectGetLibVersion (PyObject *self ATTRIBUTE_UNUSED, static PyObject * libvirt_virConnectListDomainsID(PyObject *self ATTRIBUTE_UNUSED, - PyObject *args) { + PyObject *args) { PyObject *py_retval; int *ids = NULL, c_retval, i; virConnectPtr conn; @@ -1986,6 +1986,53 @@ libvirt_virConnectListDomainsID(PyObject *self ATTRIBUTE_UNUSED, } static PyObject * +libvirt_virConnectListAllDomains(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + PyObject *pyobj_conn; + PyObject *py_retval = NULL; + PyObject *tmp = NULL; + virConnectPtr conn; + virDomainPtr *doms = NULL; + int c_retval = 0; + int i; + unsigned int flags; + + if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllDomains", + &pyobj_conn, &flags)) + return NULL; + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virConnectListAllDomains(conn, &doms, flags); + LIBVIRT_END_ALLOW_THREADS; + if (c_retval < 0) + return VIR_PY_NONE; + + if (!(py_retval = PyList_New(c_retval))) + goto cleanup; + + for (i = 0; i < c_retval; i++) { + if (!((tmp = libvirt_virDomainPtrWrap(doms[i])) && + !(PyList_SetItem(py_retval, i, tmp) < 0))) { + Py_XDECREF(tmp); + Py_DECREF(py_retval); + py_retval = NULL; + goto cleanup; + } + /* python steals the pointer */ + doms[i] = NULL; + } + +cleanup: + for (i = 0; i < c_retval; i++) + if (doms[i]) + virDomainFree(doms[i]); + VIR_FREE(doms); + return py_retval; +} + +static PyObject * libvirt_virConnectListDefinedDomains(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; @@ -5618,6 +5665,7 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virConnectOpenAuth", libvirt_virConnectOpenAuth, METH_VARARGS, NULL}, {(char *) "virConnectListDomainsID", libvirt_virConnectListDomainsID, METH_VARARGS, NULL}, {(char *) "virConnectListDefinedDomains", libvirt_virConnectListDefinedDomains, METH_VARARGS, NULL}, + {(char *) "virConnectListAllDomains", libvirt_virConnectListAllDomains, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventRegister", libvirt_virConnectDomainEventRegister, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventDeregister", libvirt_virConnectDomainEventDeregister, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL}, -- 1.7.3.4

On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch adds export of the new API function virConnectListAllDomains() to the libvirt-python bindings. The virConnect object now has method "listAllDomains" that takes only the flags parameter and returns a python list of virDomain object corresponding to virDomainPtrs returned by the underlying api.
The implementation is done manually as the generator does not support wrapping list of virDomainPtrs into virDomain objects. --- Diff to v2: - Added check for NULL return from libvirt_virDomainPtrWrap()
static PyObject * libvirt_virConnectListDomainsID(PyObject *self ATTRIBUTE_UNUSED, - PyObject *args) { + PyObject *args) {
As long as we're touching this line, move the { that starts a function body to its own line.
+ + for (i = 0; i < c_retval; i++) { + if (!((tmp = libvirt_virDomainPtrWrap(doms[i])) && + !(PyList_SetItem(py_retval, i, tmp) < 0))) {
Accurate, but too many '!' and () to be read easily. I'd write this as: if ((tmp = libvirt_virDomainPtrWrap(doms[i])) == NULL || PyList_SetItem(py_retval, i, tmp) < 0) { or maybe if (!(tmp = libvirt_virDomainPtrWrap(doms[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/11/12 23:02, Eric Blake wrote:
On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch adds export of the new API function virConnectListAllDomains() to the libvirt-python bindings. The virConnect object now has method "listAllDomains" that takes only the flags parameter and returns a python list of virDomain object corresponding to virDomainPtrs returned by the underlying api.
The implementation is done manually as the generator does not support wrapping list of virDomainPtrs into virDomain objects. --- + + for (i = 0; i < c_retval; i++) { + if (!((tmp = libvirt_virDomainPtrWrap(doms[i])) && + !(PyList_SetItem(py_retval, i, tmp) < 0))) {
Accurate, but too many '!' and () to be read easily. I'd write this as:
if ((tmp = libvirt_virDomainPtrWrap(doms[i])) == NULL || PyList_SetItem(py_retval, i, tmp) < 0) {
or maybe
if (!(tmp = libvirt_virDomainPtrWrap(doms[i])) || PyList_SetItem(py_retval, i, tmp) < 0) {
I've gone with this version.
ACK.
Pushed; Thanks. Peter

This patch wires up the RPC protocol handlers for virConnectListAllDomains(). The RPC generator has no support for the way how virConnectListAllDomains() returns the results so the handler code had to be done manually. The new api is handled by REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS, with number 271 and marked with high priority. --- Diff to v2: - fixed spelling and style nits - changed the boolean flag that tells the remote side if the list is needed to ing - fixed returning of the correct count if no list is requested (I didn't fill and use ret.ret) --- daemon/remote.c | 54 +++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 64 ++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 14 ++++++++- src/remote_protocol-structs | 12 ++++++++ 4 files changed, 143 insertions(+), 1 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index a02c09b..8dd5a4f 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -996,6 +996,60 @@ no_memory: } static int +remoteDispatchConnectListAllDomains(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_connect_list_all_domains_args *args, + remote_connect_list_all_domains_ret *ret) +{ + virDomainPtr *doms = NULL; + int ndomains = 0; + int i; + int rv = -1; + struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if ((ndomains = virConnectListAllDomains(priv->conn, + args->need_results ? &doms : NULL, + args->flags)) < 0) + goto cleanup; + + if (doms) { + if (VIR_ALLOC_N(ret->domains.domains_val, ndomains) < 0) { + virReportOOMError(); + goto cleanup; + } + + ret->domains.domains_len = ndomains; + + for (i = 0; i < ndomains; i++) + make_nonnull_domain(ret->domains.domains_val + i, doms[i]); + } else { + ret->domains.domains_len = 0; + ret->domains.domains_val = NULL; + } + + ret->ret = ndomains; + + rv = 0; + +cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + if (doms) { + for (i = 0; i < ndomains; i++) + virDomainFree(doms[i]); + VIR_FREE(doms); + } + return rv; +} + +static int remoteDispatchDomainGetSchedulerParametersFlags(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 299cd69..53ddef3 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -1265,6 +1265,69 @@ done: return rv; } +static int +remoteConnectListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + int rv = -1; + int i; + virDomainPtr *doms = NULL; + remote_connect_list_all_domains_args args; + remote_connect_list_all_domains_ret ret; + + struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); + + args.need_results = !!domains; + args.flags = flags; + + memset(&ret, 0, sizeof(ret)); + if (call(conn, + priv, + 0, + REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS, + (xdrproc_t) xdr_remote_connect_list_all_domains_args, + (char *) &args, + (xdrproc_t) xdr_remote_connect_list_all_domains_ret, + (char *) &ret) == -1) + goto done; + + if (domains) { + if (VIR_ALLOC_N(doms, ret.domains.domains_len + 1) < 0) { + virReportOOMError(); + goto cleanup; + } + + for (i = 0; i < ret.domains.domains_len; i++) { + doms[i] = get_nonnull_domain(conn, ret.domains.domains_val[i]); + if (!doms[i]) { + virReportOOMError(); + goto cleanup; + } + } + *domains = doms; + doms = NULL; + } + + rv = ret.ret; + +cleanup: + if (doms) { + for (i = 0; i < ret.domains.domains_len; i++) + if (doms[i]) + virDomainFree(doms[i]); + VIR_FREE(doms); + } + + xdr_free((xdrproc_t) xdr_remote_connect_list_all_domains_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + /* Helper to free typed parameters. */ static void remoteFreeTypedParameters(remote_typed_param *args_params_val, @@ -5111,6 +5174,7 @@ static virDriver remote_driver = { .domainGetDiskErrors = remoteDomainGetDiskErrors, /* 0.9.10 */ .domainSetMetadata = remoteDomainSetMetadata, /* 0.9.10 */ .domainGetMetadata = remoteDomainGetMetadata, /* 0.9.10 */ + .listAllDomains = remoteConnectListAllDomains, /* 0.9.13 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index d8a6576..e117ec3 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2463,6 +2463,16 @@ struct remote_domain_get_disk_errors_ret { int nerrors; }; +struct remote_connect_list_all_domains_args { + int need_results; + unsigned int flags; +}; + +struct remote_connect_list_all_domains_ret { + remote_nonnull_domain domains<>; + unsigned int ret; +}; + /*----- Protocol. -----*/ @@ -2782,7 +2792,9 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, /* autogen autogen */ REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, /* autogen autogen */ REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269, /* autogen autogen */ - REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270 /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270, /* autogen autogen */ + + REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS = 271 /* skipgen skipgen priority:high */ /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 9b2414f..9539509 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1921,6 +1921,17 @@ struct remote_domain_get_disk_errors_ret { } errors; int nerrors; }; +struct remote_connect_list_all_domains_args { + int need_results; + u_int flags; +}; +struct remote_connect_list_all_domains_ret { + struct { + u_int domains_len; + remote_nonnull_domain * domains_val; + } domains; + u_int ret; +}; enum remote_procedure { REMOTE_PROC_OPEN = 1, REMOTE_PROC_CLOSE = 2, @@ -2192,4 +2203,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269, REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270, + REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS = 271, }; -- 1.7.3.4

On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch wires up the RPC protocol handlers for virConnectListAllDomains(). The RPC generator has no support for the way how virConnectListAllDomains() returns the results so the handler code had to be done manually.
The new api is handled by REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS, with number 271 and marked with high priority.
271 is already claimed <evil_laugh>MuaaHaHa</evil_laugh> You'll have to tweak this to apply onto the latest libvirt.git, but the conflict resolution should be trivial.
--- Diff to v2: - fixed spelling and style nits - changed the boolean flag that tells the remote side if the list is needed to ing
s/ing/int/
static int +remoteDispatchConnectListAllDomains(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_connect_list_all_domains_args *args, + remote_connect_list_all_domains_ret *ret) +{ + virDomainPtr *doms = NULL; + int ndomains = 0; + int i; + int rv = -1; + struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if ((ndomains = virConnectListAllDomains(priv->conn, + args->need_results ? &doms : NULL, + args->flags)) < 0) + goto cleanup; + + if (doms) {
if (doms && ndomains) { to avoid a pointless alloc.
@@ -5111,6 +5174,7 @@ static virDriver remote_driver = { .domainGetDiskErrors = remoteDomainGetDiskErrors, /* 0.9.10 */ .domainSetMetadata = remoteDomainSetMetadata, /* 0.9.10 */ .domainGetMetadata = remoteDomainGetMetadata, /* 0.9.10 */ + .listAllDomains = remoteConnectListAllDomains, /* 0.9.13 */
I would have listed this earlier, next to the remoteConnectListDomains entry, but no big deal. ACK with the rebase and nit fixed. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/12/12 00:26, Eric Blake wrote:
On 06/11/2012 04:33 AM, Peter Krempa wrote:
This patch wires up the RPC protocol handlers for virConnectListAllDomains(). The RPC generator has no support for the way how virConnectListAllDomains() returns the results so the handler code had to be done manually.
The new api is handled by REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS, with number 271 and marked with high priority.
271 is already claimed <evil_laugh>MuaaHaHa</evil_laugh>
You'll have to tweak this to apply onto the latest libvirt.git, but the conflict resolution should be trivial.
---
The new procedure number is 273. I fixed the driver struct initialisation ordering and pushed. Thanks. Peter

This patch stores existence of the image in the object. At start of the daemon the state is checked and then updated in key moments in domain lifecycle. --- New in series. --- src/conf/domain_conf.h | 2 + src/libxl/libxl_driver.c | 41 ++++++++++++++++++++++++++++++++------ src/qemu/qemu_driver.c | 48 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8d5b35a..019f767 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1817,6 +1817,8 @@ struct _virDomainObj { virDomainSnapshotObjList snapshots; virDomainSnapshotObjPtr current_snapshot; + bool hasManagedSave; + void *privateData; void (*privateDataFreeFunc)(void *); diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 500d51b..0520ce9 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -59,6 +59,11 @@ /* Number of Xen scheduler parameters */ #define XEN_SCHED_CREDIT_NPARAM 2 +static void libxlDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque); + + static libxlDriverPrivatePtr libxl_driver = NULL; /* Function declarations */ @@ -647,6 +652,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, VIR_WARN("Failed to remove the managed state %s", managed_save_path); } + vm->hasManagedSave = false; } VIR_FREE(managed_save_path); } @@ -983,6 +989,9 @@ libxlStartup(int privileged) { virHashForEach(libxl_driver->domains.objs, libxlAutostartDomain, libxl_driver); + virHashForEach(libxl_driver->domains.objs, libxlDomainManagedSaveLoad, + libxl_driver); + libxlDriverUnlock(libxl_driver); return 0; @@ -1868,6 +1877,8 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto cleanup; } + vm->hasManagedSave = true; + if (!vm->persistent) { virDomainRemoveInactive(&driver->domains, vm); vm = NULL; @@ -2124,13 +2135,33 @@ cleanup: return ret; } +static void +libxlDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque) +{ + virDomainObjPtr vm = payload; + libxlDriverPrivatePtr driver = opaque; + char *name; + + virDomainObjLock(vm); + + if (!(name = libxlDomainManagedSavePath(driver, vm))) + goto cleanup; + + vm->hasManagedSave = virFileExists(name); + +cleanup: + virDomainObjUnlock(vm); + VIR_FREE(name); +} + static int libxlDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) { libxlDriverPrivatePtr driver = dom->conn->privateData; virDomainObjPtr vm = NULL; int ret = -1; - char *name = NULL; virCheckFlags(0, -1); @@ -2144,14 +2175,9 @@ libxlDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) goto cleanup; } - name = libxlDomainManagedSavePath(driver, vm); - if (name == NULL) - goto cleanup; - - ret = virFileExists(name); + ret = vm->hasManagedSave; cleanup: - VIR_FREE(name); if (vm) virDomainObjUnlock(vm); libxlDriverUnlock(driver); @@ -2183,6 +2209,7 @@ libxlDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) goto cleanup; ret = unlink(name); + vm->hasManagedSave = false; cleanup: VIR_FREE(name); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d3f74d2..d667329 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -139,6 +139,11 @@ static int qemuDomainObjStart(virConnectPtr conn, static int qemudDomainGetMaxVcpus(virDomainPtr dom); +static void qemuDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque); + + struct qemud_driver *qemu_driver = NULL; @@ -734,6 +739,9 @@ qemudStartup(int privileged) { virHashForEach(qemu_driver->domains.objs, qemuDomainSnapshotLoad, qemu_driver->snapshotDir); + virHashForEach(qemu_driver->domains.objs, qemuDomainManagedSaveLoad, + qemu_driver); + qemu_driver->workerPool = virThreadPoolNew(0, 1, 0, processWatchdogEvent, qemu_driver); if (!qemu_driver->workerPool) goto error; @@ -2729,6 +2737,7 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, } ret = 0; + vm->hasManagedSave = true; /* Shut it down */ qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_SAVED); @@ -2918,13 +2927,33 @@ cleanup: return ret; } +static void +qemuDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque) +{ + virDomainObjPtr vm = payload; + struct qemud_driver *driver = opaque; + char *name; + + virDomainObjLock(vm); + + if (!(name = qemuDomainManagedSavePath(driver, vm))) + goto cleanup; + + vm->hasManagedSave = virFileExists(name); + +cleanup: + virDomainObjUnlock(vm); + VIR_FREE(name); +} + static int qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm = NULL; int ret = -1; - char *name = NULL; virCheckFlags(0, -1); @@ -2938,14 +2967,9 @@ qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) goto cleanup; } - name = qemuDomainManagedSavePath(driver, vm); - if (name == NULL) - goto cleanup; - - ret = virFileExists(name); + ret = vm->hasManagedSave; cleanup: - VIR_FREE(name); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -2977,6 +3001,7 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) goto cleanup; ret = unlink(name); + vm->hasManagedSave = false; cleanup: VIR_FREE(name); @@ -4786,8 +4811,13 @@ qemuDomainObjStart(virConnectPtr conn, ret = qemuDomainObjRestore(conn, driver, vm, managed_save, start_paused, bypass_cache); - if (ret == 0 && unlink(managed_save) < 0) - VIR_WARN("Failed to remove the managed state %s", managed_save); + if (ret == 0) { + if (unlink(managed_save) < 0) + VIR_WARN("Failed to remove the managed state %s", managed_save); + else + vm->hasManagedSave = false; + } + if (ret > 0) VIR_WARN("Ignoring incomplete managed state %s", managed_save); else -- 1.7.3.4

On 06/11/2012 04:34 AM, Peter Krempa wrote:
This patch stores existence of the image in the object. At start of the daemon the state is checked and then updated in key moments in domain lifecycle. --- New in series. --- src/conf/domain_conf.h | 2 + src/libxl/libxl_driver.c | 41 ++++++++++++++++++++++++++++++++------ src/qemu/qemu_driver.c | 48 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 16 deletions(-)
ACK. Exactly what I had in mind in my v2 review. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/13/12 01:32, Eric Blake wrote:
On 06/11/2012 04:34 AM, Peter Krempa wrote:
This patch stores existence of the image in the object. At start of the daemon the state is checked and then updated in key moments in domain lifecycle. --- New in series. --- src/conf/domain_conf.h | 2 + src/libxl/libxl_driver.c | 41 ++++++++++++++++++++++++++++++++------ src/qemu/qemu_driver.c | 48 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 16 deletions(-)
ACK. Exactly what I had in mind in my v2 review.
Thanks; Pushed. Peter

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@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@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

On 06/11/2012 04:34 AM, Peter Krempa wrote:
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
I see why you needed the new file, after all, since I hit the same link problem when trying to add a helper for snapshot listing. But since I am now proposing to use it for snapshots, maybe we should think about naming it virobjlist.[hc] (a file for all sorts of virObjects: virDomainPtr, virDomainSnapshotPtr, ...). Or maybe not; right now, domain snapshots are mostly handled by domain_conf.c instead of being split into a separate file.
+ + /* managed save filter function is provided from the driver */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_MANAGEDSAVE) &&
Comment is outdated.
+ /* filter by snapshot existence */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_SNAPSHOT)) { + int nsnap = virDomainSnapshotObjListNum(&vm->snapshots, 0);
I've got a pending patch which will conflict with this; I'll post my v2 series as if this patch had already been applied.
+ +# define VIR_CONNECT_LIST_FILTERS_ACTIVE \ + (VIR_CONNECT_LIST_DOMAINS_ACTIVE | \ + VIR_CONNECT_LIST_DOMAINS_INACTIVE)
Nice. I should probably add my snapshot filters into this header, too. ACK with comment fix. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/14/12 01:36, Eric Blake wrote:
On 06/11/2012 04:34 AM, Peter Krempa wrote:
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
ACK with comment fix.
Fixed && pushed. Thanks. Peter

This patch adds support for listing all domains into drivers that use the common virDomainObj implementation: libxl, lxc, openvz, qemu, test, uml, vmware. For drivers that don't support managed save images the guests are treated as if they had none, so filtering guests that do have such an image on this driver succeeds and produces 0 results. --- Diff to v2: - removed driver specific checks now that they're not needed - changed flag check to use new macros - reordered assignment of the function pointer do driver struct --- src/libxl/libxl_driver.c | 20 ++++++++++++++++++++ src/lxc/lxc_driver.c | 19 +++++++++++++++++++ src/openvz/openvz_driver.c | 19 +++++++++++++++++++ src/qemu/qemu_driver.c | 19 +++++++++++++++++++ src/test/test_driver.c | 19 +++++++++++++++++++ src/uml/uml_driver.c | 18 ++++++++++++++++++ src/vmware/vmware_driver.c | 20 ++++++++++++++++++++ 7 files changed, 134 insertions(+), 0 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 0520ce9..41388ed 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -45,6 +45,7 @@ #include "xen_xm.h" #include "virtypedparam.h" #include "viruri.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_LIBXL @@ -3858,6 +3859,24 @@ libxlIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) return 1; } +static int +libxlListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + libxlDriverPrivatePtr driver = conn->privateData; + int ret = -1; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, 1); + + libxlDriverLock(driver); + ret = virDomainList(conn, driver->domains.objs, domains, flags); + libxlDriverUnlock(driver); + + return ret; +} + + static virDriver libxlDriver = { .no = VIR_DRV_LIBXL, @@ -3872,6 +3891,7 @@ static virDriver libxlDriver = { .getCapabilities = libxlGetCapabilities, /* 0.9.0 */ .listDomains = libxlListDomains, /* 0.9.0 */ .numOfDomains = libxlNumDomains, /* 0.9.0 */ + .listAllDomains = libxlListAllDomains, /* 0.9.13 */ .domainCreateXML = libxlDomainCreateXML, /* 0.9.0 */ .domainLookupByID = libxlDomainLookupByID, /* 0.9.0 */ .domainLookupByUUID = libxlDomainLookupByUUID, /* 0.9.0 */ diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 919f4ab..365effd 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -61,6 +61,7 @@ #include "virtime.h" #include "virtypedparam.h" #include "viruri.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -3821,6 +3822,23 @@ cleanup: } static int +lxcListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + lxc_driver_t *driver = conn->privateData; + int ret = -1; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + lxcDriverLock(driver); + ret = virDomainList(conn, driver->domains.objs, domains, flags); + lxcDriverUnlock(driver); + + return ret; +} + +static int lxcVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED, virHashIterator iter, void *data) { @@ -3912,6 +3930,7 @@ static virDriver lxcDriver = { .domainOpenConsole = lxcDomainOpenConsole, /* 0.8.6 */ .isAlive = lxcIsAlive, /* 0.9.8 */ .nodeSuspendForDuration = nodeSuspendForDuration, /* 0.9.8 */ + .listAllDomains = lxcListAllDomains, /* 0.9.13 */ }; static virStateDriver lxcStateDriver = { diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index fb72cde..1d08cec 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -60,6 +60,7 @@ #include "command.h" #include "viruri.h" #include "stats_linux.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_OPENVZ @@ -1945,6 +1946,23 @@ cleanup: return ret; } +static int +openvzListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + struct openvz_driver *driver = conn->privateData; + int ret = -1; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + openvzDriverLock(driver); + ret = virDomainList(conn, driver->domains.objs, domains, flags); + openvzDriverUnlock(driver); + + return ret; +} + static virDriver openvzDriver = { .no = VIR_DRV_OPENVZ, @@ -1963,6 +1981,7 @@ static virDriver openvzDriver = { .getCapabilities = openvzGetCapabilities, /* 0.4.6 */ .listDomains = openvzListDomains, /* 0.3.1 */ .numOfDomains = openvzNumDomains, /* 0.3.1 */ + .listAllDomains = openvzListAllDomains, /* 0.9.13 */ .domainCreateXML = openvzDomainCreateXML, /* 0.3.3 */ .domainLookupByID = openvzDomainLookupByID, /* 0.3.1 */ .domainLookupByUUID = openvzDomainLookupByUUID, /* 0.3.1 */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d667329..e6e8280 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -92,6 +92,7 @@ #include "virnodesuspend.h" #include "virtime.h" #include "virtypedparam.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -12976,6 +12977,23 @@ cleanup: return ret; } +static int +qemuListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + struct qemud_driver *driver = conn->privateData; + int ret = -1; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + qemuDriverLock(driver); + ret = virDomainList(conn, driver->domains.objs, domains, flags); + qemuDriverUnlock(driver); + + return ret; +} + static virDriver qemuDriver = { .no = VIR_DRV_QEMU, .name = QEMU_DRIVER_NAME, @@ -12991,6 +13009,7 @@ static virDriver qemuDriver = { .getCapabilities = qemudGetCapabilities, /* 0.2.1 */ .listDomains = qemudListDomains, /* 0.2.0 */ .numOfDomains = qemudNumDomains, /* 0.2.0 */ + .listAllDomains = qemuListAllDomains, /* 0.9.13 */ .domainCreateXML = qemudDomainCreate, /* 0.2.0 */ .domainLookupByID = qemudDomainLookupByID, /* 0.2.0 */ .domainLookupByUUID = qemudDomainLookupByUUID, /* 0.2.0 */ diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 7038741..b3b774d 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -52,6 +52,7 @@ #include "virfile.h" #include "virtypedparam.h" #include "virrandom.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_TEST @@ -5517,6 +5518,23 @@ static int testNWFilterClose(virConnectPtr conn) { return 0; } +static int testListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + testConnPtr privconn = conn->privateData; + int ret; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + testDriverLock(privconn); + ret = virDomainList(conn, privconn->domains.objs, domains, flags); + testDriverUnlock(privconn); + + return ret; +} + + static virDriver testDriver = { .no = VIR_DRV_TEST, .name = "Test", @@ -5529,6 +5547,7 @@ static virDriver testDriver = { .getCapabilities = testGetCapabilities, /* 0.2.1 */ .listDomains = testListDomains, /* 0.1.1 */ .numOfDomains = testNumOfDomains, /* 0.1.1 */ + .listAllDomains = testListAllDomains, /* 0.9.13 */ .domainCreateXML = testDomainCreateXML, /* 0.1.4 */ .domainLookupByID = testLookupDomainByID, /* 0.1.1 */ .domainLookupByUUID = testLookupDomainByUUID, /* 0.1.1 */ diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 219246d..098ee7b 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -64,6 +64,7 @@ #include "virnetdevtap.h" #include "virnodesuspend.h" #include "viruri.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_UML @@ -2519,6 +2520,22 @@ static void umlDomainEventQueue(struct uml_driver *driver, virDomainEventStateQueue(driver->domainEventState, event); } +static int umlListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + struct uml_driver *driver = conn->privateData; + int ret = -1; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + umlDriverLock(driver); + ret = virDomainList(conn, driver->domains.objs, domains, flags); + umlDriverUnlock(driver); + + return ret; +} + static virDriver umlDriver = { @@ -2533,6 +2550,7 @@ static virDriver umlDriver = { .getCapabilities = umlGetCapabilities, /* 0.5.0 */ .listDomains = umlListDomains, /* 0.5.0 */ .numOfDomains = umlNumDomains, /* 0.5.0 */ + .listAllDomains = umlListAllDomains, /* 0.9.13 */ .domainCreateXML = umlDomainCreate, /* 0.5.0 */ .domainLookupByID = umlDomainLookupByID, /* 0.5.0 */ .domainLookupByUUID = umlDomainLookupByUUID, /* 0.5.0 */ diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 8f9d922..a335651 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -33,6 +33,7 @@ #include "vmx.h" #include "vmware_conf.h" #include "vmware_driver.h" +#include "virdomainlist.h" static const char *vmw_types[] = { "player", "ws" }; @@ -994,6 +995,24 @@ vmwareIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) return 1; } +static int +vmwareListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + struct vmware_driver *driver = conn->privateData; + int ret = -1; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + vmwareDriverLock(driver); + ret = virDomainList(conn, driver->domains.objs, domains, flags); + vmwareDriverUnlock(driver); + return ret; +} + + + static virDriver vmwareDriver = { .no = VIR_DRV_VMWARE, .name = "VMWARE", @@ -1003,6 +1022,7 @@ static virDriver vmwareDriver = { .version = vmwareGetVersion, /* 0.8.7 */ .listDomains = vmwareListDomains, /* 0.8.7 */ .numOfDomains = vmwareNumDomains, /* 0.8.7 */ + .listAllDomains = vmwareListAllDomains, /* 0.9.13 */ .domainCreateXML = vmwareDomainCreateXML, /* 0.8.7 */ .domainLookupByID = vmwareDomainLookupByID, /* 0.8.7 */ .domainLookupByUUID = vmwareDomainLookupByUUID, /* 0.8.7 */ -- 1.7.3.4

On 06/11/2012 04:34 AM, Peter Krempa wrote:
This patch adds support for listing all domains into drivers that use the common virDomainObj implementation: libxl, lxc, openvz, qemu, test, uml, vmware.
For drivers that don't support managed save images the guests are treated as if they had none, so filtering guests that do have such an image on this driver succeeds and produces 0 results. --- Diff to v2: - removed driver specific checks now that they're not needed - changed flag check to use new macros - reordered assignment of the function pointer do driver struct --- src/libxl/libxl_driver.c | 20 ++++++++++++++++++++ src/lxc/lxc_driver.c | 19 +++++++++++++++++++ src/openvz/openvz_driver.c | 19 +++++++++++++++++++ src/qemu/qemu_driver.c | 19 +++++++++++++++++++ src/test/test_driver.c | 19 +++++++++++++++++++ src/uml/uml_driver.c | 18 ++++++++++++++++++ src/vmware/vmware_driver.c | 20 ++++++++++++++++++++
+static int +libxlListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + libxlDriverPrivatePtr driver = conn->privateData; + int ret = -1; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, 1);
s/1/-1/, otherwise you aren't properly reporting failure.
@@ -3912,6 +3930,7 @@ static virDriver lxcDriver = { .domainOpenConsole = lxcDomainOpenConsole, /* 0.8.6 */ .isAlive = lxcIsAlive, /* 0.9.8 */ .nodeSuspendForDuration = nodeSuspendForDuration, /* 0.9.8 */ + .listAllDomains = lxcListAllDomains, /* 0.9.13 */
Is it worth listing this line next to the other listing callbacks? ACK with the libxl bug fixed. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/18/12 21:01, Eric Blake wrote:
On 06/11/2012 04:34 AM, Peter Krempa wrote:
This patch adds support for listing all domains into drivers that use the common virDomainObj implementation: libxl, lxc, openvz, qemu, test, uml, vmware.
For drivers that don't support managed save images the guests are treated as if they had none, so filtering guests that do have such an image on this driver succeeds and produces 0 results. --- Diff to v2: - removed driver specific checks now that they're not needed - changed flag check to use new macros - reordered assignment of the function pointer do driver struct ---
Is it worth listing this line next to the other listing callbacks?
ACK with the libxl bug fixed.
I've fixed the libxl flag checking and reordered the callback registration in lxc and pushed. Thanks Peter

VirtualBox doesn't use the common virDomainObj implementation so this patch adds a separate implementation using the VirtualBox API. This driver implementation supports all currently defined flags. As VirtualBox does not support transient guests, managed save images and autostarting we assume all guests are persistent, don't have a managed save image and are not autostarted. Filtering for existence of those properities results in empty list. --- Diff to v2: -added support for all filter flags -changed allocation of domains array --- src/vbox/vbox_tmpl.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 170 insertions(+), 0 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 4b0ee2e..bc3c4f8 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -57,6 +57,7 @@ #include "virfile.h" #include "fdstream.h" #include "viruri.h" +#include "virdomainlist.h" /* This one changes from version to version. */ #if VBOX_API_VERSION == 2002 @@ -9097,6 +9098,174 @@ endjob: } #endif /* VBOX_API_VERSION >= 4000 */ + +#define MATCH(FLAG) (flags & (FLAG)) +static int +vboxListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + VBOX_OBJECT_CHECK(conn, int, -1); + vboxArray machines = VBOX_ARRAY_INITIALIZER; + char *machineNameUtf8 = NULL; + PRUnichar *machineNameUtf16 = NULL; + unsigned char uuid[VIR_UUID_BUFLEN]; + vboxIID iid = VBOX_IID_INITIALIZER; + PRUint32 state; + nsresult rc; + int i; + virDomainPtr dom; + virDomainPtr *doms = NULL; + int count = 0; + bool active; + PRUint32 snapshotCount; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + /* filter out flag options that will produce 0 results in vbox driver: + * - managed save: vbox guests don't have managed save images + * - autostart: vbox doesn't support autostarting guests + * - persistance: vbox doesn't support transient guests + */ + if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) { + if (domains && + VIR_ALLOC_N(*domains, 1) < 0) + goto no_memory; + + ret = 0; + goto cleanup; + } + + rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines); + if (NS_FAILED(rc)) { + vboxError(VIR_ERR_INTERNAL_ERROR, + _("Could not get list of domains, rc=%08x"), (unsigned)rc); + goto cleanup; + } + + if (domains && + VIR_ALLOC_N(doms, machines.count+1) < 0) + goto no_memory; + + for (i = 0; i < machines.count; i++) { + IMachine *machine = machines.items[i]; + + if (machine) { + PRBool isAccessible = PR_FALSE; + machine->vtbl->GetAccessible(machine, &isAccessible); + if (isAccessible) { + machine->vtbl->GetState(machine, &state); + + if (state >= MachineState_FirstOnline && + state <= MachineState_LastOnline) + active = true; + else + active = false; + + /* filter by active state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_ACTIVE) && + !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && active) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) && !active))) + continue; + + /* filter by snapshot existence */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_SNAPSHOT)) { + rc = machine->vtbl->GetSnapshotCount(machine, &snapshotCount); + if (NS_FAILED(rc)) { + vboxError(VIR_ERR_INTERNAL_ERROR, + _("could not get snapshot count for listed domains")); + goto cleanup; + } + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && + snapshotCount > 0) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && + snapshotCount == 0))) + continue; + } + + /* filter by machine state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_STATE) && + !((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) && + state == MachineState_Running) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) && + state == MachineState_Paused) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) && + state == MachineState_PoweredOff) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) && + (state != MachineState_Running && + state != MachineState_Paused && + state != MachineState_PoweredOff)))) + continue; + + /* just count the machines */ + if (!doms) { + count++; + continue; + } + + machine->vtbl->GetName(machine, &machineNameUtf16); + VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8); + machine->vtbl->GetId(machine, &iid.value); + vboxIIDToUUID(&iid, uuid); + vboxIIDUnalloc(&iid); + + dom = virGetDomain(conn, machineNameUtf8, uuid); + + if (machineNameUtf8) { + VBOX_UTF8_FREE(machineNameUtf8); + machineNameUtf8 = NULL; + } + + if (machineNameUtf16) { + VBOX_COM_UNALLOC_MEM(machineNameUtf16); + machineNameUtf16 = NULL; + } + + if (!dom) + goto no_memory; + + if (active) + dom->id = i + 1; + + doms[count++] = dom; + } + } + } + + if (doms) { + /* safe to ignore, new size will be less or equal than + * previous allocation*/ + ignore_value(VIR_REALLOC_N(doms, count+1)); + *domains = doms; + } + doms = NULL; + ret = count; + +cleanup: + if (doms) { + for (i = 0; i < count; i++) { + if (doms[i]) + virDomainFree(doms[i]); + } + } + VIR_FREE(doms); + + vboxArrayRelease(&machines); + return ret; + +no_memory: + virReportOOMError(); + goto cleanup; +} +#undef MATCH + + + /** * Function Tables */ @@ -9113,6 +9282,7 @@ virDriver NAME(Driver) = { .getCapabilities = vboxGetCapabilities, /* 0.6.3 */ .listDomains = vboxListDomains, /* 0.6.3 */ .numOfDomains = vboxNumOfDomains, /* 0.6.3 */ + .listAllDomains = vboxListAllDomains, /* 0.9.13 */ .domainCreateXML = vboxDomainCreateXML, /* 0.6.3 */ .domainLookupByID = vboxDomainLookupByID, /* 0.6.3 */ .domainLookupByUUID = vboxDomainLookupByUUID, /* 0.6.3 */ -- 1.7.3.4

On 06/11/2012 04:34 AM, Peter Krempa wrote:
VirtualBox doesn't use the common virDomainObj implementation so this patch adds a separate implementation using the VirtualBox API.
This driver implementation supports all currently defined flags. As VirtualBox does not support transient guests, managed save images and autostarting we assume all guests are persistent, don't have a managed save image and are not autostarted. Filtering for existence of those properities results in empty list. --- Diff to v2: -added support for all filter flags -changed allocation of domains array --- src/vbox/vbox_tmpl.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 170 insertions(+), 0 deletions(-)
Compile-tested, but not runtime tested. If you'd like a runtime test, I'd suggest waiting for some feedback from Matthias (cc'd). Meanwhile, even by inspection, I found a logic bug, so this needs a tweak:
+ +#define MATCH(FLAG) (flags & (FLAG)) +static int +vboxListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{
+ virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + /* filter out flag options that will produce 0 results in vbox driver: + * - managed save: vbox guests don't have managed save images + * - autostart: vbox doesn't support autostarting guests + * - persistance: vbox doesn't support transient guests + */ + if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) { + if (domains && + VIR_ALLOC_N(*domains, 1) < 0)
Nice pre-filter, and good that you remembered to still allocate the trailing NULL.
+ + if (domains && + VIR_ALLOC_N(doms, machines.count+1) < 0)
Style nit - space around '+'.
+ if (state >= MachineState_FirstOnline && + state <= MachineState_LastOnline) + active = true; + else + active = false;
Here, you check active domains, then you filter, ...
+ if (!dom) + goto no_memory; + + if (active) + dom->id = i + 1;
...and finally, you compute domain ids. But if the filter removed a domain, you forgot to increment your counter. You need to float the active domain counting prior to any filtering, even though you only assign it into dom->id after filtering succeeds.
+ if (doms) { + /* safe to ignore, new size will be less or equal than + * previous allocation*/ + ignore_value(VIR_REALLOC_N(doms, count+1));
Another place for space around '+'.
+ *domains = doms; + } + doms = NULL; + ret = count; + +cleanup: + if (doms) {
Technically, count is only ever non-zero if doms was successfully allocated, in which case you can lose this outer 'if', and...
+ for (i = 0; i < count; i++) {
...this 'for' will still do the right thing...
+ if (doms[i])
...at preventing a dereference of uninitialized doms.
+ virDomainFree(doms[i]); + } + } + VIR_FREE(doms); + + vboxArrayRelease(&machines); + return ret; +
Nearly there. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/18/12 22:06, Eric Blake wrote:
On 06/11/2012 04:34 AM, Peter Krempa wrote:
VirtualBox doesn't use the common virDomainObj implementation so this patch adds a separate implementation using the VirtualBox API.
This driver implementation supports all currently defined flags. As VirtualBox does not support transient guests, managed save images and autostarting we assume all guests are persistent, don't have a managed save image and are not autostarted. Filtering for existence of those properities results in empty list. --- Diff to v2: -added support for all filter flags -changed allocation of domains array --- src/vbox/vbox_tmpl.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 170 insertions(+), 0 deletions(-)
Compile-tested, but not runtime tested. If you'd like a runtime test, I'd suggest waiting for some feedback from Matthias (cc'd). Meanwhile, even by inspection, I found a logic bug, so this needs a tweak:
+ +#define MATCH(FLAG) (flags & (FLAG)) +static int +vboxListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{
+ virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + /* filter out flag options that will produce 0 results in vbox driver: + * - managed save: vbox guests don't have managed save images + * - autostart: vbox doesn't support autostarting guests + * - persistance: vbox doesn't support transient guests + */ + if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) { + if (domains && + VIR_ALLOC_N(*domains, 1) < 0)
Nice pre-filter, and good that you remembered to still allocate the trailing NULL.
+ + if (domains && + VIR_ALLOC_N(doms, machines.count+1) < 0)
Style nit - space around '+'.
+ if (state >= MachineState_FirstOnline && + state <= MachineState_LastOnline) + active = true; + else + active = false;
Here, you check active domains, then you filter, ...
+ if (!dom) + goto no_memory; + + if (active) + dom->id = i + 1;
...and finally, you compute domain ids. But if the filter removed a domain, you forgot to increment your counter. You need to float the active domain counting prior to any filtering, even though you only assign it into dom->id after filtering succeeds.
i is the iteration variable of the outer for loop, so it's incremented automaticaly in the for statement and is unique per domain. This loop is actualy stol..borrowed from the legacy listing code.
+ if (doms) { + /* safe to ignore, new size will be less or equal than + * previous allocation*/ + ignore_value(VIR_REALLOC_N(doms, count+1));
Another place for space around '+'.
+ *domains = doms; + } + doms = NULL; + ret = count; + +cleanup: + if (doms) {
Technically, count is only ever non-zero if doms was successfully allocated, in which case you can lose this outer 'if', and...
Well, count is non zero and doms is NULL when you try to count the machines so we need to keep this check.
Peter

Hyperv doesn't use the common virDomainObj implementation so this patch adds a separate implementation. This driver supports all currently added flags for filtering although some of those don't make sense with this driver (no support yet) and thus produce no output when used. --- Diff to v2: - added support for all flags WARNING!!! Absoultely untested! --- src/hyperv/hyperv_driver.c | 136 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 136 insertions(+), 0 deletions(-) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3b15292..7a4937d 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -42,6 +42,7 @@ #include "hyperv_util.h" #include "hyperv_wmi.h" #include "openwsman.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_HYPERV @@ -1259,6 +1260,140 @@ hypervDomainManagedSaveRemove(virDomainPtr domain, unsigned int flags) } +#define MATCH(FLAG) (flags & (FLAG)) +static int +hypervListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + hypervPrivate *priv = conn->privateData; + virBuffer query = VIR_BUFFER_INITIALIZER; + Msvm_ComputerSystem *computerSystemList = NULL; + Msvm_ComputerSystem *computerSystem = NULL; + size_t ndoms; + virDomainPtr domain; + virDomainPtr *doms = NULL; + int count = 0; + int ret = -1; + int i; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + /* check for filter combinations that return no results: + * persistent: all hyperv guests are persistent + * snapshot: the driver does not support snapshot management + * autostart: the driver does not support autostarting guests + */ + if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT))) { + if (domains && + VIR_ALLOC_N(*domains, 1) < 0) + goto no_memory; + + ret = 0; + goto cleanup; + } + + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT); + virBufferAddLit(&query, "where "); + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL); + + /* construct query with filter depending on flags */ + if (!(flags & VIR_CONNECT_LIST_DOMAINS_ACTIVE && + flags & VIR_CONNECT_LIST_DOMAINS_INACTIVE)) { + if (flags & VIR_CONNECT_LIST_DOMAINS_ACTIVE) { + virBufferAddLit(&query, "and "); + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_ACTIVE); + } + if (flags & VIR_CONNECT_LIST_DOMAINS_INACTIVE) { + virBufferAddLit(&query, "and "); + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_INACTIVE); + } + } + + if (hypervGetMsvmComputerSystemList(priv, &query, + &computerSystemList) < 0) + goto cleanup; + + if (domains) { + if (VIR_ALLOC_N(doms, 1) < 0) + goto no_memory; + ndoms = 1; + } + + for (computerSystem = computerSystemList; computerSystem != NULL; + computerSystem = computerSystem->next) { + + /* filter by domain state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_STATE)) { + int st = hypervMsvmComputerSystemEnabledStateToDomainState(computerSystem); + 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)))) + continue; + } + + /* managed save filter */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_MANAGEDSAVE)) { + bool mansave = computerSystem->data->EnabledState == + MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED; + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && mansave) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) && !mansave))) + continue; + } + + if (!doms) { + count++; + continue; + } + + if (VIR_RESIZE_N(doms, ndoms, count, 2) < 0) + goto no_memory; + + if (hypervMsvmComputerSystemToDomain(conn, computerSystem, + &domain) < 0) + goto cleanup; + + doms[count++] = domain; + } + + if (doms) + *domains = doms; + doms = NULL; + ret = count; + +cleanup: + if (doms) { + for (i = 0; i < count; ++i) { + if (doms[i]) + virDomainFree(doms[i]); + } + } + + VIR_FREE(doms); + hypervFreeObject(priv, (hypervObject *)computerSystemList); + return ret; + +no_memory: + virReportOOMError(); + goto cleanup; +} +#undef MATCH + + + static virDriver hypervDriver = { .no = VIR_DRV_HYPERV, @@ -1270,6 +1405,7 @@ static virDriver hypervDriver = { .nodeGetInfo = hypervNodeGetInfo, /* 0.9.5 */ .listDomains = hypervListDomains, /* 0.9.5 */ .numOfDomains = hypervNumberOfDomains, /* 0.9.5 */ + .listAllDomains = hypervListAllDomains, /* 0.9.13 */ .domainLookupByID = hypervDomainLookupByID, /* 0.9.5 */ .domainLookupByUUID = hypervDomainLookupByUUID, /* 0.9.5 */ .domainLookupByName = hypervDomainLookupByName, /* 0.9.5 */ -- 1.7.3.4

Esx doesn't use the common virDomainObj implementation so this patch adds a separate implementation. This driver supports all currently defined filtering flags, but as with other drivers some combinations yield a empty result list. --- Diff to v2: -added support for all filtering flags WARNING!! Just compile-tested!! --- src/esx/esx_driver.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 194 insertions(+), 0 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index b3f1948..09f09cc 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -45,6 +45,7 @@ #include "esx_vi_methods.h" #include "esx_util.h" #include "viruri.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_ESX @@ -4947,6 +4948,198 @@ esxDomainGetMemoryParameters(virDomainPtr domain, virTypedParameterPtr params, return result; } +#define MATCH(FLAG) (flags & (FLAG)) +static int +esxListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + int ret = -1; + esxPrivate *priv = conn->privateData; + virDomainPtr dom; + virDomainPtr *doms = NULL; + size_t ndoms = 0; + esxVI_ObjectContent *virtualMachineList = NULL; + esxVI_ObjectContent *virtualMachine = NULL; + esxVI_String *propertyNameList = NULL; + esxVI_AutoStartDefaults *autostart_defaults = NULL; + esxVI_VirtualMachinePowerState powerState; + esxVI_AutoStartPowerInfo *powerInfoList = NULL; + esxVI_AutoStartPowerInfo *powerInfo = NULL; + esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; + char *name = NULL; + int id; + unsigned char uuid[VIR_UUID_BUFLEN]; + int count = 0; + int snapshotCount; + bool autostart; + int state; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + /* check for flags that would produce empty output lists: + * - persistence: all esx machines are persistent + * - managed save: esx doesn't support managed save + */ + if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) { + if (domains && + VIR_ALLOC_N(*domains, 1) < 0) + goto no_memory; + + ret = 0; + goto cleanup; + } + + if (esxVI_EnsureSession(priv->primary) < 0) + return -1; + + /* check system default autostart value */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_AUTOSTART)) { + if (esxVI_LookupAutoStartDefaults(priv->primary, + &autostart_defaults) < 0) + goto cleanup; + + if (esxVI_LookupAutoStartPowerInfoList(priv->primary, + &powerInfoList) < 0) + goto cleanup; + } + + if (esxVI_String_AppendValueToList(&propertyNameList, + "runtime.powerState") < 0 || + esxVI_LookupVirtualMachineList(priv->primary, propertyNameList, + &virtualMachineList) < 0) + goto cleanup; + + if (domains) { + if (VIR_ALLOC_N(doms, 1) < 0) + goto no_memory; + ndoms = 1; + } + + for (virtualMachine = virtualMachineList; virtualMachine != NULL; + virtualMachine = virtualMachine->_next) { + + VIR_FREE(name); + + if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, uuid) < 0 || + esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) + goto cleanup; + + /* filter by active state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_ACTIVE) && + !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && + powerState != esxVI_VirtualMachinePowerState_PoweredOff) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) && + powerState == esxVI_VirtualMachinePowerState_PoweredOff))) + continue; + + /* filter by snapshot existence */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_SNAPSHOT)) { + if (esxVI_LookupRootSnapshotTreeList(priv->primary, uuid, + &rootSnapshotTreeList) < 0) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("Could not retrieve snapshot list for domain")); + goto cleanup; + } + + snapshotCount = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList, + true, false); + + esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList); + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && + snapshotCount > 0) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && + snapshotCount == 0))) + continue; + } + + /* filter by autostart */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_AUTOSTART)) { + autostart = false; + + for (powerInfo = powerInfoList; powerInfo != NULL; + powerInfo = powerInfo->_next) { + if (STREQ(powerInfo->key->value, virtualMachine->obj->value)) { + if (STRCASEEQ(powerInfo->startAction, "powerOn")) + autostart = true; + + break; + } + } + + autostart = autostart && + autostart_defaults->enabled == esxVI_Boolean_True; + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && + autostart) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && + !autostart))) + goto cleanup; + } + + /* filter by domain state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_STATE)) { + state = esxVI_VirtualMachinePowerState_ConvertToLibvirt(powerState); + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) && + state == VIR_DOMAIN_RUNNING) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) && + state == VIR_DOMAIN_PAUSED) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) && + state == VIR_DOMAIN_SHUTOFF) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) && + (state != VIR_DOMAIN_RUNNING && + state != VIR_DOMAIN_PAUSED && + state != VIR_DOMAIN_SHUTOFF)))) + goto cleanup; + } + + /* just count the machines */ + if (!doms) { + count++; + continue; + } + + if (!(dom = virGetDomain(conn, name, uuid))) + goto no_memory; + + /* Only running/suspended virtual machines have an ID != -1 */ + if (powerState != esxVI_VirtualMachinePowerState_PoweredOff) + dom->id = id; + else + dom->id = -1; + + if (VIR_EXPAND_N(doms, ndoms, 1) < 0) + goto no_memory; + doms[count++] = dom; + } + + if (doms) + *domains = doms; + doms = NULL; + ret = count; + +cleanup: + if (doms) { + for (id = 0; id < count; id++) { + if (doms[id]) + virDomainFree(doms[id]); + } + } + VIR_FREE(doms); + VIR_FREE(name); + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&virtualMachineList); + return ret; + +no_memory: + virReportOOMError(); + goto cleanup; +} +#undef MATCH static virDriver esxDriver = { @@ -4962,6 +5155,7 @@ static virDriver esxDriver = { .getCapabilities = esxGetCapabilities, /* 0.7.1 */ .listDomains = esxListDomains, /* 0.7.0 */ .numOfDomains = esxNumberOfDomains, /* 0.7.0 */ + .listAllDomains = esxListAllDomains, /* 0.9.13 */ .domainLookupByID = esxDomainLookupByID, /* 0.7.0 */ .domainLookupByUUID = esxDomainLookupByUUID, /* 0.7.0 */ .domainLookupByName = esxDomainLookupByName, /* 0.7.0 */ -- 1.7.3.4

--- New in series, optional. --- src/driver.h | 736 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 368 insertions(+), 368 deletions(-) diff --git a/src/driver.h b/src/driver.h index c4e558f..6cbd23c 100644 --- a/src/driver.h +++ b/src/driver.h @@ -66,21 +66,21 @@ typedef enum { (drv)->supports_feature((conn), (feature)) > 0 : 0) typedef virDrvOpenStatus - (*virDrvOpen) (virConnectPtr conn, - virConnectAuthPtr auth, - unsigned int flags); + (*virDrvOpen) (virConnectPtr conn, + virConnectAuthPtr auth, + unsigned int flags); typedef int - (*virDrvClose) (virConnectPtr conn); + (*virDrvClose) (virConnectPtr conn); typedef int (*virDrvDrvSupportsFeature) (virConnectPtr conn, int feature); typedef const char * - (*virDrvGetType) (virConnectPtr conn); + (*virDrvGetType) (virConnectPtr conn); typedef int - (*virDrvGetVersion) (virConnectPtr conn, - unsigned long *hvVer); + (*virDrvGetVersion) (virConnectPtr conn, + unsigned long *hvVer); typedef int - (*virDrvGetLibVersion) (virConnectPtr conn, - unsigned long *libVer); + (*virDrvGetLibVersion) (virConnectPtr conn, + unsigned long *libVer); typedef char * (*virDrvGetHostname) (virConnectPtr conn); typedef char * @@ -89,69 +89,69 @@ typedef char * (*virDrvGetSysinfo) (virConnectPtr conn, unsigned int flags); typedef int - (*virDrvGetMaxVcpus) (virConnectPtr conn, + (*virDrvGetMaxVcpus) (virConnectPtr conn, const char *type); typedef int - (*virDrvNodeGetInfo) (virConnectPtr conn, + (*virDrvNodeGetInfo) (virConnectPtr conn, virNodeInfoPtr info); typedef char * - (*virDrvGetCapabilities) (virConnectPtr conn); + (*virDrvGetCapabilities) (virConnectPtr conn); typedef int - (*virDrvListDomains) (virConnectPtr conn, + (*virDrvListDomains) (virConnectPtr conn, int *ids, int maxids); typedef int - (*virDrvNumOfDomains) (virConnectPtr conn); + (*virDrvNumOfDomains) (virConnectPtr conn); typedef virDomainPtr - (*virDrvDomainCreateXML) (virConnectPtr conn, + (*virDrvDomainCreateXML) (virConnectPtr conn, const char *xmlDesc, unsigned int flags); typedef virDomainPtr - (*virDrvDomainLookupByID) (virConnectPtr conn, + (*virDrvDomainLookupByID) (virConnectPtr conn, int id); typedef virDomainPtr - (*virDrvDomainLookupByUUID) (virConnectPtr conn, + (*virDrvDomainLookupByUUID) (virConnectPtr conn, const unsigned char *uuid); typedef virDomainPtr - (*virDrvDomainLookupByName) (virConnectPtr conn, + (*virDrvDomainLookupByName) (virConnectPtr conn, const char *name); typedef int - (*virDrvDomainSuspend) (virDomainPtr domain); + (*virDrvDomainSuspend) (virDomainPtr domain); typedef int - (*virDrvDomainResume) (virDomainPtr domain); + (*virDrvDomainResume) (virDomainPtr domain); typedef int (*virDrvDomainPMSuspendForDuration) (virDomainPtr, unsigned int target, unsigned long long duration, unsigned int flags); typedef int - (*virDrvDomainPMWakeup) (virDomainPtr domain, - unsigned int flags); + (*virDrvDomainPMWakeup) (virDomainPtr domain, + unsigned int flags); typedef int - (*virDrvDomainShutdown) (virDomainPtr domain); + (*virDrvDomainShutdown) (virDomainPtr domain); typedef int - (*virDrvDomainReboot) (virDomainPtr domain, + (*virDrvDomainReboot) (virDomainPtr domain, unsigned int flags); typedef int - (*virDrvDomainReset) (virDomainPtr domain, + (*virDrvDomainReset) (virDomainPtr domain, unsigned int flags); typedef int - (*virDrvDomainDestroy) (virDomainPtr domain); + (*virDrvDomainDestroy) (virDomainPtr domain); typedef int - (*virDrvDomainDestroyFlags) (virDomainPtr domain, + (*virDrvDomainDestroyFlags) (virDomainPtr domain, unsigned int flags); typedef char * - (*virDrvDomainGetOSType) (virDomainPtr domain); + (*virDrvDomainGetOSType) (virDomainPtr domain); typedef unsigned long long - (*virDrvDomainGetMaxMemory) (virDomainPtr domain); + (*virDrvDomainGetMaxMemory) (virDomainPtr domain); typedef int - (*virDrvDomainSetMaxMemory) (virDomainPtr domain, + (*virDrvDomainSetMaxMemory) (virDomainPtr domain, unsigned long memory); typedef int - (*virDrvDomainSetMemory) (virDomainPtr domain, + (*virDrvDomainSetMemory) (virDomainPtr domain, unsigned long memory); typedef int - (*virDrvDomainSetMemoryFlags) (virDomainPtr domain, + (*virDrvDomainSetMemoryFlags) (virDomainPtr domain, unsigned long memory, unsigned int flags); typedef int @@ -192,7 +192,7 @@ typedef int int *nparams, unsigned int flags); typedef int - (*virDrvDomainGetInfo) (virDomainPtr domain, + (*virDrvDomainGetInfo) (virDomainPtr domain, virDomainInfoPtr info); typedef int (*virDrvDomainGetState) (virDomainPtr domain, @@ -204,18 +204,18 @@ typedef int virDomainControlInfoPtr info, unsigned int flags); typedef int - (*virDrvDomainSave) (virDomainPtr domain, + (*virDrvDomainSave) (virDomainPtr domain, const char *to); typedef int - (*virDrvDomainSaveFlags) (virDomainPtr domain, + (*virDrvDomainSaveFlags) (virDomainPtr domain, const char *to, const char *dxml, unsigned int flags); typedef int - (*virDrvDomainRestore) (virConnectPtr conn, + (*virDrvDomainRestore) (virConnectPtr conn, const char *from); typedef int - (*virDrvDomainRestoreFlags) (virConnectPtr conn, + (*virDrvDomainRestoreFlags) (virConnectPtr conn, const char *from, const char *dxml, unsigned int flags); @@ -229,17 +229,17 @@ typedef int const char *dxml, unsigned int flags); typedef int - (*virDrvDomainCoreDump) (virDomainPtr domain, + (*virDrvDomainCoreDump) (virDomainPtr domain, const char *to, unsigned int flags); typedef char * - (*virDrvDomainScreenshot) (virDomainPtr domain, + (*virDrvDomainScreenshot) (virDomainPtr domain, virStreamPtr stream, unsigned int screen, unsigned int flags); typedef char * - (*virDrvDomainGetXMLDesc) (virDomainPtr dom, - unsigned int flags); + (*virDrvDomainGetXMLDesc) (virDomainPtr dom, + unsigned int flags); typedef char * (*virDrvConnectDomainXMLFromNative) (virConnectPtr conn, const char *nativeFormat, @@ -251,40 +251,40 @@ typedef char * const char *domainXml, unsigned int flags); typedef int - (*virDrvListDefinedDomains) (virConnectPtr conn, - char **const names, - int maxnames); + (*virDrvListDefinedDomains) (virConnectPtr conn, + char **const names, + int maxnames); typedef int - (*virDrvListAllDomains) (virConnectPtr conn, - virDomainPtr **domains, - unsigned int flags); + (*virDrvListAllDomains) (virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags); typedef int - (*virDrvNumOfDefinedDomains) (virConnectPtr conn); + (*virDrvNumOfDefinedDomains) (virConnectPtr conn); typedef int - (*virDrvDomainCreate) (virDomainPtr dom); + (*virDrvDomainCreate) (virDomainPtr dom); typedef int - (*virDrvDomainCreateWithFlags) (virDomainPtr dom, + (*virDrvDomainCreateWithFlags) (virDomainPtr dom, unsigned int flags); typedef virDomainPtr - (*virDrvDomainDefineXML) (virConnectPtr conn, + (*virDrvDomainDefineXML) (virConnectPtr conn, const char *xml); typedef int - (*virDrvDomainUndefine) (virDomainPtr dom); + (*virDrvDomainUndefine) (virDomainPtr dom); typedef int - (*virDrvDomainUndefineFlags) (virDomainPtr dom, + (*virDrvDomainUndefineFlags) (virDomainPtr dom, unsigned int flags); typedef int - (*virDrvDomainSetVcpus) (virDomainPtr domain, + (*virDrvDomainSetVcpus) (virDomainPtr domain, unsigned int nvcpus); typedef int - (*virDrvDomainSetVcpusFlags) (virDomainPtr domain, + (*virDrvDomainSetVcpusFlags) (virDomainPtr domain, unsigned int nvcpus, unsigned int flags); typedef int - (*virDrvDomainGetVcpusFlags) (virDomainPtr domain, + (*virDrvDomainGetVcpusFlags) (virDomainPtr domain, unsigned int flags); typedef int - (*virDrvDomainPinVcpu) (virDomainPtr domain, + (*virDrvDomainPinVcpu) (virDomainPtr domain, unsigned int vcpu, unsigned char *cpumap, int maplen); @@ -302,29 +302,29 @@ typedef int unsigned int flags); typedef int - (*virDrvDomainGetVcpus) (virDomainPtr domain, + (*virDrvDomainGetVcpus) (virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, int maplen); typedef int - (*virDrvDomainGetMaxVcpus) (virDomainPtr domain); + (*virDrvDomainGetMaxVcpus) (virDomainPtr domain); typedef int - (*virDrvDomainGetSecurityLabel) (virDomainPtr domain, + (*virDrvDomainGetSecurityLabel) (virDomainPtr domain, virSecurityLabelPtr seclabel); typedef int - (*virDrvNodeGetSecurityModel) (virConnectPtr conn, + (*virDrvNodeGetSecurityModel) (virConnectPtr conn, virSecurityModelPtr secmodel); typedef int - (*virDrvDomainAttachDevice) (virDomainPtr domain, + (*virDrvDomainAttachDevice) (virDomainPtr domain, const char *xml); typedef int (*virDrvDomainAttachDeviceFlags) (virDomainPtr domain, const char *xml, unsigned int flags); typedef int - (*virDrvDomainDetachDevice) (virDomainPtr domain, + (*virDrvDomainDetachDevice) (virDomainPtr domain, const char *xml); typedef int (*virDrvDomainDetachDeviceFlags) (virDomainPtr domain, @@ -335,14 +335,14 @@ typedef int const char *xml, unsigned int flags); typedef int - (*virDrvDomainGetAutostart) (virDomainPtr domain, - int *autostart); + (*virDrvDomainGetAutostart) (virDomainPtr domain, + int *autostart); typedef int - (*virDrvDomainSetAutostart) (virDomainPtr domain, + (*virDrvDomainSetAutostart) (virDomainPtr domain, int autostart); typedef char * - (*virDrvDomainGetSchedulerType) (virDomainPtr domain, + (*virDrvDomainGetSchedulerType) (virDomainPtr domain, int *nparams); typedef int @@ -855,218 +855,218 @@ typedef char * * - close */ struct _virDriver { - int no; /* the number virDrvNo */ - const char * name; /* the name of the driver */ - virDrvOpen open; - virDrvClose close; - virDrvDrvSupportsFeature supports_feature; - virDrvGetType type; - virDrvGetVersion version; - virDrvGetLibVersion libvirtVersion; - virDrvGetHostname getHostname; - virDrvGetSysinfo getSysinfo; - virDrvGetMaxVcpus getMaxVcpus; - virDrvNodeGetInfo nodeGetInfo; - virDrvGetCapabilities getCapabilities; - virDrvListDomains listDomains; - virDrvNumOfDomains numOfDomains; - virDrvListAllDomains listAllDomains; - virDrvDomainCreateXML domainCreateXML; - virDrvDomainLookupByID domainLookupByID; - virDrvDomainLookupByUUID domainLookupByUUID; - virDrvDomainLookupByName domainLookupByName; - virDrvDomainSuspend domainSuspend; - virDrvDomainResume domainResume; - virDrvDomainPMSuspendForDuration domainPMSuspendForDuration; - virDrvDomainPMWakeup domainPMWakeup; - virDrvDomainShutdown domainShutdown; - virDrvDomainShutdownFlags domainShutdownFlags; - virDrvDomainReboot domainReboot; - virDrvDomainReset domainReset; - virDrvDomainDestroy domainDestroy; - virDrvDomainDestroyFlags domainDestroyFlags; - virDrvDomainGetOSType domainGetOSType; - virDrvDomainGetMaxMemory domainGetMaxMemory; - virDrvDomainSetMaxMemory domainSetMaxMemory; - virDrvDomainSetMemory domainSetMemory; - virDrvDomainSetMemoryFlags domainSetMemoryFlags; - virDrvDomainSetMemoryParameters domainSetMemoryParameters; - virDrvDomainGetMemoryParameters domainGetMemoryParameters; - virDrvDomainSetNumaParameters domainSetNumaParameters; - virDrvDomainGetNumaParameters domainGetNumaParameters; - virDrvDomainSetBlkioParameters domainSetBlkioParameters; - virDrvDomainGetBlkioParameters domainGetBlkioParameters; - virDrvDomainGetInfo domainGetInfo; - virDrvDomainGetState domainGetState; - virDrvDomainGetControlInfo domainGetControlInfo; - virDrvDomainSave domainSave; - virDrvDomainSaveFlags domainSaveFlags; - virDrvDomainRestore domainRestore; - virDrvDomainRestoreFlags domainRestoreFlags; - virDrvDomainSaveImageGetXMLDesc domainSaveImageGetXMLDesc; - virDrvDomainSaveImageDefineXML domainSaveImageDefineXML; - virDrvDomainCoreDump domainCoreDump; - virDrvDomainScreenshot domainScreenshot; - virDrvDomainSetVcpus domainSetVcpus; - virDrvDomainSetVcpusFlags domainSetVcpusFlags; - virDrvDomainGetVcpusFlags domainGetVcpusFlags; - virDrvDomainPinVcpu domainPinVcpu; - virDrvDomainPinVcpuFlags domainPinVcpuFlags; - virDrvDomainGetVcpuPinInfo domainGetVcpuPinInfo; - virDrvDomainGetVcpus domainGetVcpus; - virDrvDomainGetMaxVcpus domainGetMaxVcpus; - virDrvDomainGetSecurityLabel domainGetSecurityLabel; - virDrvNodeGetSecurityModel nodeGetSecurityModel; - virDrvDomainGetXMLDesc domainGetXMLDesc; - virDrvConnectDomainXMLFromNative domainXMLFromNative; - virDrvConnectDomainXMLToNative domainXMLToNative; - virDrvListDefinedDomains listDefinedDomains; - virDrvNumOfDefinedDomains numOfDefinedDomains; - virDrvDomainCreate domainCreate; - virDrvDomainCreateWithFlags domainCreateWithFlags; - virDrvDomainDefineXML domainDefineXML; - virDrvDomainUndefine domainUndefine; - virDrvDomainUndefineFlags domainUndefineFlags; - virDrvDomainAttachDevice domainAttachDevice; - virDrvDomainAttachDeviceFlags domainAttachDeviceFlags; - virDrvDomainDetachDevice domainDetachDevice; - virDrvDomainDetachDeviceFlags domainDetachDeviceFlags; - virDrvDomainUpdateDeviceFlags domainUpdateDeviceFlags; - virDrvDomainGetAutostart domainGetAutostart; - virDrvDomainSetAutostart domainSetAutostart; - virDrvDomainGetSchedulerType domainGetSchedulerType; - virDrvDomainGetSchedulerParameters domainGetSchedulerParameters; + int no; /* the number virDrvNo */ + const char *name; /* the name of the driver */ + virDrvOpen open; + virDrvClose close; + virDrvDrvSupportsFeature supports_feature; + virDrvGetType type; + virDrvGetVersion version; + virDrvGetLibVersion libvirtVersion; + virDrvGetHostname getHostname; + virDrvGetSysinfo getSysinfo; + virDrvGetMaxVcpus getMaxVcpus; + virDrvNodeGetInfo nodeGetInfo; + virDrvGetCapabilities getCapabilities; + virDrvListDomains listDomains; + virDrvNumOfDomains numOfDomains; + virDrvListAllDomains listAllDomains; + virDrvDomainCreateXML domainCreateXML; + virDrvDomainLookupByID domainLookupByID; + virDrvDomainLookupByUUID domainLookupByUUID; + virDrvDomainLookupByName domainLookupByName; + virDrvDomainSuspend domainSuspend; + virDrvDomainResume domainResume; + virDrvDomainPMSuspendForDuration domainPMSuspendForDuration; + virDrvDomainPMWakeup domainPMWakeup; + virDrvDomainShutdown domainShutdown; + virDrvDomainShutdownFlags domainShutdownFlags; + virDrvDomainReboot domainReboot; + virDrvDomainReset domainReset; + virDrvDomainDestroy domainDestroy; + virDrvDomainDestroyFlags domainDestroyFlags; + virDrvDomainGetOSType domainGetOSType; + virDrvDomainGetMaxMemory domainGetMaxMemory; + virDrvDomainSetMaxMemory domainSetMaxMemory; + virDrvDomainSetMemory domainSetMemory; + virDrvDomainSetMemoryFlags domainSetMemoryFlags; + virDrvDomainSetMemoryParameters domainSetMemoryParameters; + virDrvDomainGetMemoryParameters domainGetMemoryParameters; + virDrvDomainSetNumaParameters domainSetNumaParameters; + virDrvDomainGetNumaParameters domainGetNumaParameters; + virDrvDomainSetBlkioParameters domainSetBlkioParameters; + virDrvDomainGetBlkioParameters domainGetBlkioParameters; + virDrvDomainGetInfo domainGetInfo; + virDrvDomainGetState domainGetState; + virDrvDomainGetControlInfo domainGetControlInfo; + virDrvDomainSave domainSave; + virDrvDomainSaveFlags domainSaveFlags; + virDrvDomainRestore domainRestore; + virDrvDomainRestoreFlags domainRestoreFlags; + virDrvDomainSaveImageGetXMLDesc domainSaveImageGetXMLDesc; + virDrvDomainSaveImageDefineXML domainSaveImageDefineXML; + virDrvDomainCoreDump domainCoreDump; + virDrvDomainScreenshot domainScreenshot; + virDrvDomainSetVcpus domainSetVcpus; + virDrvDomainSetVcpusFlags domainSetVcpusFlags; + virDrvDomainGetVcpusFlags domainGetVcpusFlags; + virDrvDomainPinVcpu domainPinVcpu; + virDrvDomainPinVcpuFlags domainPinVcpuFlags; + virDrvDomainGetVcpuPinInfo domainGetVcpuPinInfo; + virDrvDomainGetVcpus domainGetVcpus; + virDrvDomainGetMaxVcpus domainGetMaxVcpus; + virDrvDomainGetSecurityLabel domainGetSecurityLabel; + virDrvNodeGetSecurityModel nodeGetSecurityModel; + virDrvDomainGetXMLDesc domainGetXMLDesc; + virDrvConnectDomainXMLFromNative domainXMLFromNative; + virDrvConnectDomainXMLToNative domainXMLToNative; + virDrvListDefinedDomains listDefinedDomains; + virDrvNumOfDefinedDomains numOfDefinedDomains; + virDrvDomainCreate domainCreate; + virDrvDomainCreateWithFlags domainCreateWithFlags; + virDrvDomainDefineXML domainDefineXML; + virDrvDomainUndefine domainUndefine; + virDrvDomainUndefineFlags domainUndefineFlags; + virDrvDomainAttachDevice domainAttachDevice; + virDrvDomainAttachDeviceFlags domainAttachDeviceFlags; + virDrvDomainDetachDevice domainDetachDevice; + virDrvDomainDetachDeviceFlags domainDetachDeviceFlags; + virDrvDomainUpdateDeviceFlags domainUpdateDeviceFlags; + virDrvDomainGetAutostart domainGetAutostart; + virDrvDomainSetAutostart domainSetAutostart; + virDrvDomainGetSchedulerType domainGetSchedulerType; + virDrvDomainGetSchedulerParameters domainGetSchedulerParameters; virDrvDomainGetSchedulerParametersFlags domainGetSchedulerParametersFlags; - virDrvDomainSetSchedulerParameters domainSetSchedulerParameters; + virDrvDomainSetSchedulerParameters domainSetSchedulerParameters; virDrvDomainSetSchedulerParametersFlags domainSetSchedulerParametersFlags; - virDrvDomainMigratePrepare domainMigratePrepare; - virDrvDomainMigratePerform domainMigratePerform; - virDrvDomainMigrateFinish domainMigrateFinish; - virDrvDomainBlockResize domainBlockResize; - virDrvDomainBlockStats domainBlockStats; - virDrvDomainBlockStatsFlags domainBlockStatsFlags; - virDrvDomainInterfaceStats domainInterfaceStats; - virDrvDomainSetInterfaceParameters domainSetInterfaceParameters; - virDrvDomainGetInterfaceParameters domainGetInterfaceParameters; - virDrvDomainMemoryStats domainMemoryStats; - virDrvDomainBlockPeek domainBlockPeek; - virDrvDomainMemoryPeek domainMemoryPeek; - virDrvDomainGetBlockInfo domainGetBlockInfo; - virDrvNodeGetCPUStats nodeGetCPUStats; - virDrvNodeGetMemoryStats nodeGetMemoryStats; - virDrvNodeGetCellsFreeMemory nodeGetCellsFreeMemory; - virDrvNodeGetFreeMemory nodeGetFreeMemory; - virDrvDomainEventRegister domainEventRegister; - virDrvDomainEventDeregister domainEventDeregister; - virDrvDomainMigratePrepare2 domainMigratePrepare2; - virDrvDomainMigrateFinish2 domainMigrateFinish2; - virDrvNodeDeviceDettach nodeDeviceDettach; - virDrvNodeDeviceReAttach nodeDeviceReAttach; - virDrvNodeDeviceReset nodeDeviceReset; - virDrvDomainMigratePrepareTunnel domainMigratePrepareTunnel; - virDrvConnectIsEncrypted isEncrypted; - virDrvConnectIsSecure isSecure; - virDrvDomainIsActive domainIsActive; - virDrvDomainIsPersistent domainIsPersistent; - virDrvDomainIsUpdated domainIsUpdated; - virDrvCompareCPU cpuCompare; - virDrvBaselineCPU cpuBaseline; - virDrvDomainGetJobInfo domainGetJobInfo; - virDrvDomainAbortJob domainAbortJob; - virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime; - virDrvDomainMigrateGetMaxSpeed domainMigrateGetMaxSpeed; - virDrvDomainMigrateSetMaxSpeed domainMigrateSetMaxSpeed; - virDrvDomainEventRegisterAny domainEventRegisterAny; - virDrvDomainEventDeregisterAny domainEventDeregisterAny; - virDrvDomainManagedSave domainManagedSave; - virDrvDomainHasManagedSaveImage domainHasManagedSaveImage; - virDrvDomainManagedSaveRemove domainManagedSaveRemove; - virDrvDomainSnapshotCreateXML domainSnapshotCreateXML; - virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc; - virDrvDomainSnapshotNum domainSnapshotNum; - virDrvDomainSnapshotListNames domainSnapshotListNames; - virDrvDomainSnapshotNumChildren domainSnapshotNumChildren; + virDrvDomainMigratePrepare domainMigratePrepare; + virDrvDomainMigratePerform domainMigratePerform; + virDrvDomainMigrateFinish domainMigrateFinish; + virDrvDomainBlockResize domainBlockResize; + virDrvDomainBlockStats domainBlockStats; + virDrvDomainBlockStatsFlags domainBlockStatsFlags; + virDrvDomainInterfaceStats domainInterfaceStats; + virDrvDomainSetInterfaceParameters domainSetInterfaceParameters; + virDrvDomainGetInterfaceParameters domainGetInterfaceParameters; + virDrvDomainMemoryStats domainMemoryStats; + virDrvDomainBlockPeek domainBlockPeek; + virDrvDomainMemoryPeek domainMemoryPeek; + virDrvDomainGetBlockInfo domainGetBlockInfo; + virDrvNodeGetCPUStats nodeGetCPUStats; + virDrvNodeGetMemoryStats nodeGetMemoryStats; + virDrvNodeGetCellsFreeMemory nodeGetCellsFreeMemory; + virDrvNodeGetFreeMemory nodeGetFreeMemory; + virDrvDomainEventRegister domainEventRegister; + virDrvDomainEventDeregister domainEventDeregister; + virDrvDomainMigratePrepare2 domainMigratePrepare2; + virDrvDomainMigrateFinish2 domainMigrateFinish2; + virDrvNodeDeviceDettach nodeDeviceDettach; + virDrvNodeDeviceReAttach nodeDeviceReAttach; + virDrvNodeDeviceReset nodeDeviceReset; + virDrvDomainMigratePrepareTunnel domainMigratePrepareTunnel; + virDrvConnectIsEncrypted isEncrypted; + virDrvConnectIsSecure isSecure; + virDrvDomainIsActive domainIsActive; + virDrvDomainIsPersistent domainIsPersistent; + virDrvDomainIsUpdated domainIsUpdated; + virDrvCompareCPU cpuCompare; + virDrvBaselineCPU cpuBaseline; + virDrvDomainGetJobInfo domainGetJobInfo; + virDrvDomainAbortJob domainAbortJob; + virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime; + virDrvDomainMigrateGetMaxSpeed domainMigrateGetMaxSpeed; + virDrvDomainMigrateSetMaxSpeed domainMigrateSetMaxSpeed; + virDrvDomainEventRegisterAny domainEventRegisterAny; + virDrvDomainEventDeregisterAny domainEventDeregisterAny; + virDrvDomainManagedSave domainManagedSave; + virDrvDomainHasManagedSaveImage domainHasManagedSaveImage; + virDrvDomainManagedSaveRemove domainManagedSaveRemove; + virDrvDomainSnapshotCreateXML domainSnapshotCreateXML; + virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc; + virDrvDomainSnapshotNum domainSnapshotNum; + virDrvDomainSnapshotListNames domainSnapshotListNames; + virDrvDomainSnapshotNumChildren domainSnapshotNumChildren; virDrvDomainSnapshotListChildrenNames domainSnapshotListChildrenNames; - virDrvDomainSnapshotLookupByName domainSnapshotLookupByName; - virDrvDomainHasCurrentSnapshot domainHasCurrentSnapshot; - virDrvDomainSnapshotGetParent domainSnapshotGetParent; - virDrvDomainSnapshotCurrent domainSnapshotCurrent; - virDrvDomainRevertToSnapshot domainRevertToSnapshot; - virDrvDomainSnapshotDelete domainSnapshotDelete; - virDrvDomainQemuMonitorCommand qemuDomainMonitorCommand; - virDrvDomainQemuAttach qemuDomainAttach; - virDrvDomainOpenConsole domainOpenConsole; - virDrvDomainOpenGraphics domainOpenGraphics; - virDrvDomainInjectNMI domainInjectNMI; - virDrvDomainMigrateBegin3 domainMigrateBegin3; - virDrvDomainMigratePrepare3 domainMigratePrepare3; - virDrvDomainMigratePrepareTunnel3 domainMigratePrepareTunnel3; - virDrvDomainMigratePerform3 domainMigratePerform3; - virDrvDomainMigrateFinish3 domainMigrateFinish3; - virDrvDomainMigrateConfirm3 domainMigrateConfirm3; - virDrvDomainSendKey domainSendKey; - virDrvDomainBlockJobAbort domainBlockJobAbort; - virDrvDomainGetBlockJobInfo domainGetBlockJobInfo; - virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed; - virDrvDomainBlockPull domainBlockPull; - virDrvDomainBlockRebase domainBlockRebase; - virDrvSetKeepAlive setKeepAlive; - virDrvConnectIsAlive isAlive; - virDrvNodeSuspendForDuration nodeSuspendForDuration; - virDrvDomainSetBlockIoTune domainSetBlockIoTune; - virDrvDomainGetBlockIoTune domainGetBlockIoTune; - virDrvDomainGetCPUStats domainGetCPUStats; - virDrvDomainGetDiskErrors domainGetDiskErrors; - virDrvDomainSetMetadata domainSetMetadata; - virDrvDomainGetMetadata domainGetMetadata; + virDrvDomainSnapshotLookupByName domainSnapshotLookupByName; + virDrvDomainHasCurrentSnapshot domainHasCurrentSnapshot; + virDrvDomainSnapshotGetParent domainSnapshotGetParent; + virDrvDomainSnapshotCurrent domainSnapshotCurrent; + virDrvDomainRevertToSnapshot domainRevertToSnapshot; + virDrvDomainSnapshotDelete domainSnapshotDelete; + virDrvDomainQemuMonitorCommand qemuDomainMonitorCommand; + virDrvDomainQemuAttach qemuDomainAttach; + virDrvDomainOpenConsole domainOpenConsole; + virDrvDomainOpenGraphics domainOpenGraphics; + virDrvDomainInjectNMI domainInjectNMI; + virDrvDomainMigrateBegin3 domainMigrateBegin3; + virDrvDomainMigratePrepare3 domainMigratePrepare3; + virDrvDomainMigratePrepareTunnel3 domainMigratePrepareTunnel3; + virDrvDomainMigratePerform3 domainMigratePerform3; + virDrvDomainMigrateFinish3 domainMigrateFinish3; + virDrvDomainMigrateConfirm3 domainMigrateConfirm3; + virDrvDomainSendKey domainSendKey; + virDrvDomainBlockJobAbort domainBlockJobAbort; + virDrvDomainGetBlockJobInfo domainGetBlockJobInfo; + virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed; + virDrvDomainBlockPull domainBlockPull; + virDrvDomainBlockRebase domainBlockRebase; + virDrvSetKeepAlive setKeepAlive; + virDrvConnectIsAlive isAlive; + virDrvNodeSuspendForDuration nodeSuspendForDuration; + virDrvDomainSetBlockIoTune domainSetBlockIoTune; + virDrvDomainGetBlockIoTune domainGetBlockIoTune; + virDrvDomainGetCPUStats domainGetCPUStats; + virDrvDomainGetDiskErrors domainGetDiskErrors; + virDrvDomainSetMetadata domainSetMetadata; + virDrvDomainGetMetadata domainGetMetadata; }; typedef int - (*virDrvNumOfNetworks) (virConnectPtr conn); + (*virDrvNumOfNetworks) (virConnectPtr conn); typedef int - (*virDrvListNetworks) (virConnectPtr conn, + (*virDrvListNetworks) (virConnectPtr conn, char **const names, int maxnames); typedef int - (*virDrvNumOfDefinedNetworks) (virConnectPtr conn); + (*virDrvNumOfDefinedNetworks) (virConnectPtr conn); typedef int - (*virDrvListDefinedNetworks) (virConnectPtr conn, + (*virDrvListDefinedNetworks) (virConnectPtr conn, char **const names, int maxnames); typedef virNetworkPtr - (*virDrvNetworkLookupByUUID) (virConnectPtr conn, + (*virDrvNetworkLookupByUUID) (virConnectPtr conn, const unsigned char *uuid); typedef virNetworkPtr - (*virDrvNetworkLookupByName) (virConnectPtr conn, + (*virDrvNetworkLookupByName) (virConnectPtr conn, const char *name); typedef virNetworkPtr - (*virDrvNetworkCreateXML) (virConnectPtr conn, + (*virDrvNetworkCreateXML) (virConnectPtr conn, const char *xmlDesc); typedef virNetworkPtr - (*virDrvNetworkDefineXML) (virConnectPtr conn, + (*virDrvNetworkDefineXML) (virConnectPtr conn, const char *xml); typedef int - (*virDrvNetworkUndefine) (virNetworkPtr network); + (*virDrvNetworkUndefine) (virNetworkPtr network); typedef int - (*virDrvNetworkCreate) (virNetworkPtr network); + (*virDrvNetworkCreate) (virNetworkPtr network); typedef int - (*virDrvNetworkDestroy) (virNetworkPtr network); + (*virDrvNetworkDestroy) (virNetworkPtr network); typedef char * - (*virDrvNetworkGetXMLDesc) (virNetworkPtr network, + (*virDrvNetworkGetXMLDesc) (virNetworkPtr network, unsigned int flags); typedef char * - (*virDrvNetworkGetBridgeName) (virNetworkPtr network); + (*virDrvNetworkGetBridgeName) (virNetworkPtr network); typedef int - (*virDrvNetworkGetAutostart) (virNetworkPtr network, + (*virDrvNetworkGetAutostart) (virNetworkPtr network, int *autostart); typedef int - (*virDrvNetworkSetAutostart) (virNetworkPtr network, + (*virDrvNetworkSetAutostart) (virNetworkPtr network, int autostart); typedef int - (*virDrvNetworkIsActive)(virNetworkPtr net); + (*virDrvNetworkIsActive) (virNetworkPtr net); typedef int - (*virDrvNetworkIsPersistent)(virNetworkPtr net); + (*virDrvNetworkIsPersistent) (virNetworkPtr net); @@ -1084,26 +1084,26 @@ typedef virNetworkDriver *virNetworkDriverPtr; * - close */ struct _virNetworkDriver { - const char * name; /* the name of the driver */ - virDrvOpen open; - virDrvClose close; - virDrvNumOfNetworks numOfNetworks; - virDrvListNetworks listNetworks; - virDrvNumOfDefinedNetworks numOfDefinedNetworks; - virDrvListDefinedNetworks listDefinedNetworks; - virDrvNetworkLookupByUUID networkLookupByUUID; - virDrvNetworkLookupByName networkLookupByName; - virDrvNetworkCreateXML networkCreateXML; - virDrvNetworkDefineXML networkDefineXML; - virDrvNetworkUndefine networkUndefine; - virDrvNetworkCreate networkCreate; - virDrvNetworkDestroy networkDestroy; - virDrvNetworkGetXMLDesc networkGetXMLDesc; - virDrvNetworkGetBridgeName networkGetBridgeName; - virDrvNetworkGetAutostart networkGetAutostart; - virDrvNetworkSetAutostart networkSetAutostart; - virDrvNetworkIsActive networkIsActive; - virDrvNetworkIsPersistent networkIsPersistent; + const char * name; /* the name of the driver */ + virDrvOpen open; + virDrvClose close; + virDrvNumOfNetworks numOfNetworks; + virDrvListNetworks listNetworks; + virDrvNumOfDefinedNetworks numOfDefinedNetworks; + virDrvListDefinedNetworks listDefinedNetworks; + virDrvNetworkLookupByUUID networkLookupByUUID; + virDrvNetworkLookupByName networkLookupByName; + virDrvNetworkCreateXML networkCreateXML; + virDrvNetworkDefineXML networkDefineXML; + virDrvNetworkUndefine networkUndefine; + virDrvNetworkCreate networkCreate; + virDrvNetworkDestroy networkDestroy; + virDrvNetworkGetXMLDesc networkGetXMLDesc; + virDrvNetworkGetBridgeName networkGetBridgeName; + virDrvNetworkGetAutostart networkGetAutostart; + virDrvNetworkSetAutostart networkSetAutostart; + virDrvNetworkIsActive networkIsActive; + virDrvNetworkIsPersistent networkIsPersistent; }; /*-------*/ @@ -1144,7 +1144,7 @@ typedef int unsigned int flags); typedef int - (*virDrvInterfaceIsActive)(virInterfacePtr iface); + (*virDrvInterfaceIsActive) (virInterfacePtr iface); typedef int (*virDrvInterfaceChangeBegin) (virConnectPtr conn, @@ -1340,48 +1340,48 @@ typedef virStorageDriver *virStorageDriverPtr; */ struct _virStorageDriver { const char * name; /* the name of the driver */ - virDrvOpen open; - virDrvClose close; - - virDrvConnectNumOfStoragePools numOfPools; - virDrvConnectListStoragePools listPools; - virDrvConnectNumOfDefinedStoragePools numOfDefinedPools; - virDrvConnectListDefinedStoragePools listDefinedPools; - virDrvConnectFindStoragePoolSources findPoolSources; - virDrvStoragePoolLookupByName poolLookupByName; - virDrvStoragePoolLookupByUUID poolLookupByUUID; - virDrvStoragePoolLookupByVolume poolLookupByVolume; - virDrvStoragePoolCreateXML poolCreateXML; - virDrvStoragePoolDefineXML poolDefineXML; - virDrvStoragePoolBuild poolBuild; - virDrvStoragePoolUndefine poolUndefine; - virDrvStoragePoolCreate poolCreate; - virDrvStoragePoolDestroy poolDestroy; - virDrvStoragePoolDelete poolDelete; - virDrvStoragePoolRefresh poolRefresh; - virDrvStoragePoolGetInfo poolGetInfo; - virDrvStoragePoolGetXMLDesc poolGetXMLDesc; - virDrvStoragePoolGetAutostart poolGetAutostart; - virDrvStoragePoolSetAutostart poolSetAutostart; - virDrvStoragePoolNumOfVolumes poolNumOfVolumes; - virDrvStoragePoolListVolumes poolListVolumes; - - virDrvStorageVolLookupByName volLookupByName; - virDrvStorageVolLookupByKey volLookupByKey; - virDrvStorageVolLookupByPath volLookupByPath; - virDrvStorageVolCreateXML volCreateXML; - virDrvStorageVolCreateXMLFrom volCreateXMLFrom; - virDrvStorageVolDownload volDownload; - virDrvStorageVolUpload volUpload; - virDrvStorageVolDelete volDelete; - virDrvStorageVolWipe volWipe; - virDrvStorageVolWipePattern volWipePattern; - virDrvStorageVolGetInfo volGetInfo; - virDrvStorageVolGetXMLDesc volGetXMLDesc; - virDrvStorageVolGetPath volGetPath; - virDrvStorageVolResize volResize; - virDrvStoragePoolIsActive poolIsActive; - virDrvStoragePoolIsPersistent poolIsPersistent; + virDrvOpen open; + virDrvClose close; + + virDrvConnectNumOfStoragePools numOfPools; + virDrvConnectListStoragePools listPools; + virDrvConnectNumOfDefinedStoragePools numOfDefinedPools; + virDrvConnectListDefinedStoragePools listDefinedPools; + virDrvConnectFindStoragePoolSources findPoolSources; + virDrvStoragePoolLookupByName poolLookupByName; + virDrvStoragePoolLookupByUUID poolLookupByUUID; + virDrvStoragePoolLookupByVolume poolLookupByVolume; + virDrvStoragePoolCreateXML poolCreateXML; + virDrvStoragePoolDefineXML poolDefineXML; + virDrvStoragePoolBuild poolBuild; + virDrvStoragePoolUndefine poolUndefine; + virDrvStoragePoolCreate poolCreate; + virDrvStoragePoolDestroy poolDestroy; + virDrvStoragePoolDelete poolDelete; + virDrvStoragePoolRefresh poolRefresh; + virDrvStoragePoolGetInfo poolGetInfo; + virDrvStoragePoolGetXMLDesc poolGetXMLDesc; + virDrvStoragePoolGetAutostart poolGetAutostart; + virDrvStoragePoolSetAutostart poolSetAutostart; + virDrvStoragePoolNumOfVolumes poolNumOfVolumes; + virDrvStoragePoolListVolumes poolListVolumes; + + virDrvStorageVolLookupByName volLookupByName; + virDrvStorageVolLookupByKey volLookupByKey; + virDrvStorageVolLookupByPath volLookupByPath; + virDrvStorageVolCreateXML volCreateXML; + virDrvStorageVolCreateXMLFrom volCreateXMLFrom; + virDrvStorageVolDownload volDownload; + virDrvStorageVolUpload volUpload; + virDrvStorageVolDelete volDelete; + virDrvStorageVolWipe volWipe; + virDrvStorageVolWipePattern volWipePattern; + virDrvStorageVolGetInfo volGetInfo; + virDrvStorageVolGetXMLDesc volGetXMLDesc; + virDrvStorageVolGetPath volGetPath; + virDrvStorageVolResize volResize; + virDrvStoragePoolIsActive poolIsActive; + virDrvStoragePoolIsPersistent poolIsPersistent; }; # ifdef WITH_LIBVIRTD @@ -1444,17 +1444,17 @@ typedef int (*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev); */ struct _virDeviceMonitor { const char * name; /* the name of the driver */ - virDrvOpen open; - virDrvClose close; - virDevMonNumOfDevices numOfDevices; - virDevMonListDevices listDevices; + virDrvOpen open; + virDrvClose close; + virDevMonNumOfDevices numOfDevices; + virDevMonListDevices listDevices; virDevMonDeviceLookupByName deviceLookupByName; - virDevMonDeviceGetXMLDesc deviceGetXMLDesc; - virDevMonDeviceGetParent deviceGetParent; - virDevMonDeviceNumOfCaps deviceNumOfCaps; - virDevMonDeviceListCaps deviceListCaps; - virDrvNodeDeviceCreateXML deviceCreateXML; - virDrvNodeDeviceDestroy deviceDestroy; + virDevMonDeviceGetXMLDesc deviceGetXMLDesc; + virDevMonDeviceGetParent deviceGetParent; + virDevMonDeviceNumOfCaps deviceNumOfCaps; + virDevMonDeviceListCaps deviceListCaps; + virDrvNodeDeviceCreateXML deviceCreateXML; + virDrvNodeDeviceDestroy deviceDestroy; }; enum { @@ -1471,30 +1471,30 @@ typedef virSecretPtr int usageType, const char *usageID); typedef virSecretPtr - (*virDrvSecretDefineXML) (virConnectPtr conn, - const char *xml, - unsigned int flags); + (*virDrvSecretDefineXML) (virConnectPtr conn, + const char *xml, + unsigned int flags); typedef char * - (*virDrvSecretGetXMLDesc) (virSecretPtr secret, - unsigned int flags); + (*virDrvSecretGetXMLDesc) (virSecretPtr secret, + unsigned int flags); typedef int - (*virDrvSecretSetValue) (virSecretPtr secret, - const unsigned char *value, - size_t value_size, - unsigned int flags); + (*virDrvSecretSetValue) (virSecretPtr secret, + const unsigned char *value, + size_t value_size, + unsigned int flags); typedef unsigned char * - (*virDrvSecretGetValue) (virSecretPtr secret, - size_t *value_size, - unsigned int flags, - unsigned int internalFlags); + (*virDrvSecretGetValue) (virSecretPtr secret, + size_t *value_size, + unsigned int flags, + unsigned int internalFlags); typedef int - (*virDrvSecretUndefine) (virSecretPtr secret); + (*virDrvSecretUndefine) (virSecretPtr secret); typedef int (*virDrvNumOfSecrets) (virConnectPtr conn); typedef int (*virDrvListSecrets) (virConnectPtr conn, - char **uuids, - int maxuuids); + char **uuids, + int maxuuids); typedef struct _virSecretDriver virSecretDriver; typedef virSecretDriver *virSecretDriverPtr; @@ -1511,18 +1511,18 @@ typedef virSecretDriver *virSecretDriverPtr; */ struct _virSecretDriver { const char *name; - virDrvOpen open; - virDrvClose close; - - virDrvNumOfSecrets numOfSecrets; - virDrvListSecrets listSecrets; - virDrvSecretLookupByUUID lookupByUUID; - virDrvSecretLookupByUsage lookupByUsage; - virDrvSecretDefineXML defineXML; - virDrvSecretGetXMLDesc getXMLDesc; - virDrvSecretSetValue setValue; - virDrvSecretGetValue getValue; - virDrvSecretUndefine undefine; + virDrvOpen open; + virDrvClose close; + + virDrvNumOfSecrets numOfSecrets; + virDrvListSecrets listSecrets; + virDrvSecretLookupByUUID lookupByUUID; + virDrvSecretLookupByUsage lookupByUsage; + virDrvSecretDefineXML defineXML; + virDrvSecretGetXMLDesc getXMLDesc; + virDrvSecretSetValue setValue; + virDrvSecretGetValue getValue; + virDrvSecretUndefine undefine; }; @@ -1550,13 +1550,13 @@ typedef int (*virDrvStreamAbort)(virStreamPtr st); struct _virStreamDriver { - virDrvStreamSend streamSend; - virDrvStreamRecv streamRecv; - virDrvStreamEventAddCallback streamAddCallback; + virDrvStreamSend streamSend; + virDrvStreamRecv streamRecv; + virDrvStreamEventAddCallback streamAddCallback; virDrvStreamEventUpdateCallback streamUpdateCallback; virDrvStreamEventRemoveCallback streamRemoveCallback; - virDrvStreamFinish streamFinish; - virDrvStreamAbort streamAbort; + virDrvStreamFinish streamFinish; + virDrvStreamAbort streamAbort; }; @@ -1567,20 +1567,20 @@ typedef int char **const names, int maxnames); typedef virNWFilterPtr - (*virDrvNWFilterLookupByName) (virConnectPtr conn, - const char *name); + (*virDrvNWFilterLookupByName) (virConnectPtr conn, + const char *name); typedef virNWFilterPtr - (*virDrvNWFilterLookupByUUID) (virConnectPtr conn, - const unsigned char *uuid); + (*virDrvNWFilterLookupByUUID) (virConnectPtr conn, + const unsigned char *uuid); typedef virNWFilterPtr - (*virDrvNWFilterDefineXML) (virConnectPtr conn, - const char *xmlDesc); + (*virDrvNWFilterDefineXML) (virConnectPtr conn, + const char *xmlDesc); typedef int - (*virDrvNWFilterUndefine) (virNWFilterPtr nwfilter); + (*virDrvNWFilterUndefine) (virNWFilterPtr nwfilter); typedef char * - (*virDrvNWFilterGetXMLDesc) (virNWFilterPtr nwfilter, - unsigned int flags); + (*virDrvNWFilterGetXMLDesc) (virNWFilterPtr nwfilter, + unsigned int flags); typedef struct _virNWFilterDriver virNWFilterDriver; @@ -1598,16 +1598,16 @@ typedef virNWFilterDriver *virNWFilterDriverPtr; */ struct _virNWFilterDriver { const char * name; /* the name of the driver */ - virDrvOpen open; - virDrvClose close; + virDrvOpen open; + virDrvClose close; virDrvConnectNumOfNWFilters numOfNWFilters; - virDrvConnectListNWFilters listNWFilters; - virDrvNWFilterLookupByName nwfilterLookupByName; - virDrvNWFilterLookupByUUID nwfilterLookupByUUID; - virDrvNWFilterDefineXML defineXML; - virDrvNWFilterUndefine undefine; - virDrvNWFilterGetXMLDesc getXMLDesc; + virDrvConnectListNWFilters listNWFilters; + virDrvNWFilterLookupByName nwfilterLookupByName; + virDrvNWFilterLookupByUUID nwfilterLookupByUUID; + virDrvNWFilterDefineXML defineXML; + virDrvNWFilterUndefine undefine; + virDrvNWFilterGetXMLDesc getXMLDesc; }; -- 1.7.3.4

On 06/11/2012 04:34 AM, Peter Krempa wrote:
--- New in series, optional. --- src/driver.h | 736 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 368 insertions(+), 368 deletions(-)
I like it. ACK (verified by applying the patch, then using 'git diff -b' to see that it really was whitespace-only). -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/18/12 22:09, Eric Blake wrote:
On 06/11/2012 04:34 AM, Peter Krempa wrote:
--- New in series, optional. --- src/driver.h | 736 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 368 insertions(+), 368 deletions(-)
I like it. ACK (verified by applying the patch, then using 'git diff -b' to see that it really was whitespace-only).
Thanks; pushed. Peter

The ignore_value macro is used across libvirt. This patch includes it in the internal header and cleans all other includes. --- New in series, optional. --- src/conf/domain_audit.c | 1 - src/conf/domain_conf.c | 1 - src/conf/virdomainlist.c | 1 - src/internal.h | 1 + src/network/bridge_driver.c | 1 - src/node_device/node_device_hal.c | 1 - src/openvz/openvz_conf.c | 1 - src/qemu/qemu_domain.c | 1 - src/qemu/qemu_monitor_json.c | 1 - src/util/command.c | 1 - src/util/event_poll.c | 1 - src/util/logging.c | 1 - src/util/memory.c | 1 - src/util/threadpool.c | 1 - src/util/virfile.h | 1 - src/util/virnetdevbandwidth.c | 1 - src/xenapi/xenapi_driver.c | 1 - tests/shunloadtest.c | 1 - 18 files changed, 1 insertions(+), 17 deletions(-) diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index 653657b..e3f3681 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -31,7 +31,6 @@ #include "uuid.h" #include "logging.h" #include "memory.h" -#include "ignore-value.h" /* Return nn:mm in hex for block and character devices, and NULL * for other file types, stat failure, or allocation failure. */ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 221e1d0..ada517b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -44,7 +44,6 @@ #include "c-ctype.h" #include "logging.h" #include "nwfilter_conf.h" -#include "ignore-value.h" #include "storage_file.h" #include "virfile.h" #include "bitmap.h" diff --git a/src/conf/virdomainlist.c b/src/conf/virdomainlist.c index 8889fee..5a399fd 100644 --- a/src/conf/virdomainlist.c +++ b/src/conf/virdomainlist.c @@ -30,7 +30,6 @@ #include "memory.h" #include "datatypes.h" #include "virterror_internal.h" -#include "ignore-value.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN diff --git a/src/internal.h b/src/internal.h index 1b1598b..856b1ee 100644 --- a/src/internal.h +++ b/src/internal.h @@ -45,6 +45,7 @@ # include "libvirt_internal.h" # include "c-strcase.h" +# include "ignore-value.h" /* On architectures which lack these limits, define them (ie. Cygwin). * Note that the libvirt code should be robust enough to handle the diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 5f3132c..bebb255 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -58,7 +58,6 @@ #include "logging.h" #include "dnsmasq.h" #include "configmake.h" -#include "ignore-value.h" #include "virnetdev.h" #include "virnetdevbridge.h" #include "virnetdevtap.h" diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c index b2e502e..7f8b076 100644 --- a/src/node_device/node_device_hal.c +++ b/src/node_device/node_device_hal.c @@ -38,7 +38,6 @@ #include "pci.h" #include "logging.h" #include "node_device_driver.h" -#include "ignore-value.h" #include "virdbus.h" #define VIR_FROM_THIS VIR_FROM_NODEDEV diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 72cd1e6..31556be 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -53,7 +53,6 @@ #include "nodeinfo.h" #include "virfile.h" #include "command.h" -#include "ignore-value.h" #define VIR_FROM_THIS VIR_FROM_OPENVZ diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3752ddf..d0a65fd 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -32,7 +32,6 @@ #include "virterror_internal.h" #include "c-ctype.h" #include "cpu/cpu.h" -#include "ignore-value.h" #include "uuid.h" #include "virfile.h" #include "domain_event.h" diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 9030347..6ea61cd 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -41,7 +41,6 @@ #include "datatypes.h" #include "virterror_internal.h" #include "json.h" -#include "ignore-value.h" #ifdef WITH_DTRACE_PROBES # include "libvirt_qemu_probes.h" diff --git a/src/util/command.c b/src/util/command.c index 62848cd..5838d45 100644 --- a/src/util/command.c +++ b/src/util/command.c @@ -41,7 +41,6 @@ #include "virfile.h" #include "virpidfile.h" #include "buf.h" -#include "ignore-value.h" #define VIR_FROM_THIS VIR_FROM_NONE diff --git a/src/util/event_poll.c b/src/util/event_poll.c index 038e75f..3841673 100644 --- a/src/util/event_poll.c +++ b/src/util/event_poll.c @@ -37,7 +37,6 @@ #include "memory.h" #include "util.h" #include "virfile.h" -#include "ignore-value.h" #include "virterror_internal.h" #include "virtime.h" diff --git a/src/util/logging.c b/src/util/logging.c index cf62184..f8233cd 100644 --- a/src/util/logging.c +++ b/src/util/logging.c @@ -38,7 +38,6 @@ # include <execinfo.h> #endif -#include "ignore-value.h" #include "virterror_internal.h" #include "logging.h" #include "memory.h" diff --git a/src/util/memory.c b/src/util/memory.c index bfa32a8..90ca29a 100644 --- a/src/util/memory.c +++ b/src/util/memory.c @@ -24,7 +24,6 @@ #include <stdlib.h> #include "memory.h" -#include "ignore-value.h" #if TEST_OOM diff --git a/src/util/threadpool.c b/src/util/threadpool.c index e8689d9..305a22f 100644 --- a/src/util/threadpool.c +++ b/src/util/threadpool.c @@ -29,7 +29,6 @@ #include "memory.h" #include "threads.h" #include "virterror_internal.h" -#include "ignore-value.h" #define VIR_FROM_THIS VIR_FROM_NONE diff --git a/src/util/virfile.h b/src/util/virfile.h index 6882a73..fb8109b 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -29,7 +29,6 @@ # include <stdio.h> # include "internal.h" -# include "ignore-value.h" typedef enum virFileCloseFlags { VIR_FILE_CLOSE_PRESERVE_ERRNO = 1 << 0, diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c index b9bd2e3..596ffd6 100644 --- a/src/util/virnetdevbandwidth.c +++ b/src/util/virnetdevbandwidth.c @@ -26,7 +26,6 @@ #include "command.h" #include "memory.h" #include "virterror_internal.h" -#include "ignore-value.h" #define VIR_FROM_THIS VIR_FROM_NONE diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 0ad6aff..298ab21 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -40,7 +40,6 @@ #include "xenapi_driver.h" #include "xenapi_driver_private.h" #include "xenapi_utils.h" -#include "ignore-value.h" #define VIR_FROM_THIS VIR_FROM_XENAPI diff --git a/tests/shunloadtest.c b/tests/shunloadtest.c index 8113ef3..45ef0a1 100644 --- a/tests/shunloadtest.c +++ b/tests/shunloadtest.c @@ -50,7 +50,6 @@ # include <signal.h> # include "internal.h" -# include "ignore-value.h" # include "testutils.h" pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -- 1.7.3.4

On 06/11/2012 04:34 AM, Peter Krempa wrote:
The ignore_value macro is used across libvirt. This patch includes it in the internal header and cleans all other includes. --- New in series, optional. ---
I'm 50-50. It is indeed used all over the place, but making it easier to use makes it a tiny bit easier to forget to ask ourselves why we are using it, and whether we should paying attention to the return value after all. Anyone else have an opinion? If no one else chimes in over the course of a week, then take this as an ACK and push it. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Peter Krempa