diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 05c1e913df..bb0faf52d8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17106,47 +17106,51 @@ virDomainGetRootFilesystem(virDomainDefPtr def) } -static void -virDomainObjListCountActive(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *data) -{ - virDomainObjPtr obj = payload; - int *count = data; - virObjectLock(obj); - if (virDomainObjIsActive(obj)) - (*count)++; - virObjectUnlock(obj); -} +struct virDomainObjListData { + virDomainObjListFilter filter; + virConnectPtr conn; + bool active; + int count; +}; static void -virDomainObjListCountInactive(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *data) +virDomainObjListCount(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) { virDomainObjPtr obj = payload; - int *count = data; + struct virDomainObjListData *data = opaque; virObjectLock(obj); - if (!virDomainObjIsActive(obj)) - (*count)++; + if (data->filter && + !data->filter(data->conn, obj->def)) + goto cleanup; + if (virDomainObjIsActive(obj)) { + if (data->active) + data->count++; + } else { + if (!data->active) + data->count++; + } +cleanup: virObjectUnlock(obj); } int virDomainObjListNumOfDomains(virDomainObjListPtr doms, - int active) + bool active, + virDomainObjListFilter filter, + virConnectPtr conn) { - int count = 0; + struct virDomainObjListData data = { filter, conn, active, 0 }; virObjectLock(doms); - if (active) - virHashForEach(doms->objs, virDomainObjListCountActive, &count); - else - virHashForEach(doms->objs, virDomainObjListCountInactive, &count); + virHashForEach(doms->objs, virDomainObjListCount, &data); virObjectUnlock(doms); - return count; + return data.count; } struct virDomainIDData { + virDomainObjListFilter filter; + virConnectPtr conn; int numids; int maxids; int *ids; @@ -17160,17 +17164,24 @@ virDomainObjListCopyActiveIDs(void *payload, virDomainObjPtr obj = payload; struct virDomainIDData *data = opaque; virObjectLock(obj); + if (data->filter && + !data->filter(data->conn, obj->def)) + goto cleanup; if (virDomainObjIsActive(obj) && data->numids < data->maxids) data->ids[data->numids++] = obj->def->id; +cleanup: virObjectUnlock(obj); } int virDomainObjListGetActiveIDs(virDomainObjListPtr doms, int *ids, - int maxids) + int maxids, + virDomainObjListFilter filter, + virConnectPtr conn) { - struct virDomainIDData data = { 0, maxids, ids }; + struct virDomainIDData data = { filter, conn, + 0, maxids, ids }; virObjectLock(doms); virHashForEach(doms->objs, virDomainObjListCopyActiveIDs, &data); virObjectUnlock(doms); @@ -17178,6 +17189,8 @@ virDomainObjListGetActiveIDs(virDomainObjListPtr doms, } struct virDomainNameData { + virDomainObjListFilter filter; + virConnectPtr conn; int oom; int numnames; int maxnames; @@ -17196,12 +17209,16 @@ virDomainObjListCopyInactiveNames(void *payload, return; virObjectLock(obj); + if (data->filter && + !data->filter(data->conn, obj->def)) + goto cleanup; if (!virDomainObjIsActive(obj) && data->numnames < data->maxnames) { if (VIR_STRDUP(data->names[data->numnames], obj->def->name) < 0) data->oom = 1; else data->numnames++; } +cleanup: virObjectUnlock(obj); } @@ -17209,9 +17226,12 @@ virDomainObjListCopyInactiveNames(void *payload, int virDomainObjListGetInactiveNames(virDomainObjListPtr doms, char **const names, - int maxnames) + int maxnames, + virDomainObjListFilter filter, + virConnectPtr conn) { - struct virDomainNameData data = { 0, 0, maxnames, names }; + struct virDomainNameData data = { filter, conn, + 0, 0, maxnames, names }; int i; virObjectLock(doms); virHashForEach(doms->objs, virDomainObjListCopyInactiveNames, &data); @@ -17927,6 +17947,7 @@ cleanup: struct virDomainListData { virConnectPtr conn; virDomainPtr *domains; + virDomainObjListFilter filter; unsigned int flags; int ndomains; bool error; @@ -17948,6 +17969,11 @@ virDomainListPopulate(void *payload, virObjectLock(vm); /* check if the domain matches the filter */ + /* filter by the callback function (access control checks) */ + if (data->filter != NULL && + !data->filter(data->conn, vm->def)) + goto cleanup; + /* filter by active state */ if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) && !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && @@ -18027,12 +18053,17 @@ int virDomainObjListExport(virDomainObjListPtr doms, virConnectPtr conn, virDomainPtr **domains, + virDomainObjListFilter filter, unsigned int flags) { int ret = -1; int i; - struct virDomainListData data = { conn, NULL, flags, 0, false }; + struct virDomainListData data = { + conn, NULL, + filter, + flags, 0, false + }; virObjectLock(doms); if (domains) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2b55de5691..7200062232 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2073,6 +2073,9 @@ struct _virDomainObj { typedef struct _virDomainObjList virDomainObjList; typedef virDomainObjList *virDomainObjListPtr; +typedef bool (*virDomainObjListFilter)(virConnectPtr conn, + virDomainDefPtr def); + /* This structure holds various callbacks and data needed * while parsing and creating domain XMLs */ @@ -2426,14 +2429,21 @@ int virDomainFSIndexByName(virDomainDefPtr def, const char *name); int virDomainVideoDefaultType(virDomainDefPtr def); int virDomainVideoDefaultRAM(virDomainDefPtr def, int type); -int virDomainObjListNumOfDomains(virDomainObjListPtr doms, int active); +int virDomainObjListNumOfDomains(virDomainObjListPtr doms, + bool active, + virDomainObjListFilter filter, + virConnectPtr conn); int virDomainObjListGetActiveIDs(virDomainObjListPtr doms, int *ids, - int maxids); + int maxids, + virDomainObjListFilter filter, + virConnectPtr conn); int virDomainObjListGetInactiveNames(virDomainObjListPtr doms, char **const names, - int maxnames); + int maxnames, + virDomainObjListFilter filter, + virConnectPtr conn); typedef int (*virDomainObjListIterator)(virDomainObjPtr dom, void *opaque); @@ -2643,6 +2653,7 @@ VIR_ENUM_DECL(virDomainStartupPolicy) int virDomainObjListExport(virDomainObjListPtr doms, virConnectPtr conn, virDomainPtr **domains, + virDomainObjListFilter filter, unsigned int flags); virDomainVcpuPinDefPtr virDomainLookupVcpuPin(virDomainDefPtr def, diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index a3a917192f..2428623b52 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -1574,7 +1574,8 @@ libxlConnectListDomains(virConnectPtr conn, int *ids, int nids) return -1; libxlDriverLock(driver); - n = virDomainObjListGetActiveIDs(driver->domains, ids, nids); + n = virDomainObjListGetActiveIDs(driver->domains, ids, nids, + virConnectListDomainsCheckACL, conn); libxlDriverUnlock(driver); return n; @@ -1590,7 +1591,8 @@ libxlConnectNumOfDomains(virConnectPtr conn) return -1; libxlDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 1); + n = virDomainObjListNumOfDomains(driver->domains, true, + virConnectNumOfDomainsCheckACL, conn); libxlDriverUnlock(driver); return n; @@ -3202,7 +3204,8 @@ libxlConnectListDefinedDomains(virConnectPtr conn, return -1; libxlDriverLock(driver); - n = virDomainObjListGetInactiveNames(driver->domains, names, nnames); + n = virDomainObjListGetInactiveNames(driver->domains, names, nnames, + virConnectListDefinedDomainsCheckACL, conn); libxlDriverUnlock(driver); return n; } @@ -3217,7 +3220,8 @@ libxlConnectNumOfDefinedDomains(virConnectPtr conn) return -1; libxlDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 0); + n = virDomainObjListNumOfDomains(driver->domains, false, + virConnectNumOfDefinedDomainsCheckACL, NULL); libxlDriverUnlock(driver); return n; @@ -4654,7 +4658,8 @@ libxlConnectListAllDomains(virConnectPtr conn, return -1; libxlDriverLock(driver); - ret = virDomainObjListExport(driver->domains, conn, domains, flags); + ret = virDomainObjListExport(driver->domains, conn, domains, + virConnectListAllDomainsCheckACL, flags); libxlDriverUnlock(driver); return ret; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 8d02c52618..1a6d086cb5 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -392,7 +392,8 @@ static int lxcConnectListDomains(virConnectPtr conn, int *ids, int nids) { return -1; lxcDriverLock(driver); - n = virDomainObjListGetActiveIDs(driver->domains, ids, nids); + n = virDomainObjListGetActiveIDs(driver->domains, ids, nids, + virConnectListDomainsCheckACL, conn); lxcDriverUnlock(driver); return n; @@ -406,7 +407,8 @@ static int lxcConnectNumOfDomains(virConnectPtr conn) { return -1; lxcDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 1); + n = virDomainObjListNumOfDomains(driver->domains, true, + virConnectNumOfDomainsCheckACL, conn); lxcDriverUnlock(driver); return n; @@ -421,7 +423,8 @@ static int lxcConnectListDefinedDomains(virConnectPtr conn, return -1; lxcDriverLock(driver); - n = virDomainObjListGetInactiveNames(driver->domains, names, nnames); + n = virDomainObjListGetInactiveNames(driver->domains, names, nnames, + virConnectListDefinedDomainsCheckACL, conn); lxcDriverUnlock(driver); return n; @@ -436,7 +439,8 @@ static int lxcConnectNumOfDefinedDomains(virConnectPtr conn) { return -1; lxcDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 0); + n = virDomainObjListNumOfDomains(driver->domains, false, + virConnectNumOfDefinedDomainsCheckACL, conn); lxcDriverUnlock(driver); return n; @@ -2829,7 +2833,8 @@ lxcConnectListAllDomains(virConnectPtr conn, return -1; lxcDriverLock(driver); - ret = virDomainObjListExport(driver->domains, conn, domains, flags); + ret = virDomainObjListExport(driver->domains, conn, domains, + virConnectListAllDomainsCheckACL, flags); lxcDriverUnlock(driver); return ret; diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index d04e3ba933..7af0349277 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1566,7 +1566,7 @@ static int openvzConnectNumOfDomains(virConnectPtr conn) { int n; openvzDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 1); + n = virDomainObjListNumOfDomains(driver->domains, true, NULL, NULL); openvzDriverUnlock(driver); return n; @@ -1678,7 +1678,7 @@ static int openvzConnectNumOfDefinedDomains(virConnectPtr conn) { int n; openvzDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 0); + n = virDomainObjListNumOfDomains(driver->domains, false, NULL, NULL); openvzDriverUnlock(driver); return n; @@ -2122,7 +2122,8 @@ openvzConnectListAllDomains(virConnectPtr conn, virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1); openvzDriverLock(driver); - ret = virDomainObjListExport(driver->domains, conn, domains, flags); + ret = virDomainObjListExport(driver->domains, conn, domains, + NULL, flags); openvzDriverUnlock(driver); return ret; diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index b7c4ec4ff3..d5e0ea378f 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -1045,7 +1045,8 @@ parallelsConnectListDomains(virConnectPtr conn, int *ids, int maxids) int n; parallelsDriverLock(privconn); - n = virDomainObjListGetActiveIDs(privconn->domains, ids, maxids); + n = virDomainObjListGetActiveIDs(privconn->domains, ids, maxids, + NULL, NULL); parallelsDriverUnlock(privconn); return n; @@ -1058,7 +1059,8 @@ parallelsConnectNumOfDomains(virConnectPtr conn) int count; parallelsDriverLock(privconn); - count = virDomainObjListNumOfDomains(privconn->domains, 1); + count = virDomainObjListNumOfDomains(privconn->domains, true, + NULL, NULL); parallelsDriverUnlock(privconn); return count; @@ -1073,7 +1075,7 @@ parallelsConnectListDefinedDomains(virConnectPtr conn, char **const names, int m parallelsDriverLock(privconn); memset(names, 0, sizeof(*names) * maxnames); n = virDomainObjListGetInactiveNames(privconn->domains, names, - maxnames); + maxnames, NULL, NULL); parallelsDriverUnlock(privconn); return n; @@ -1086,7 +1088,8 @@ parallelsConnectNumOfDefinedDomains(virConnectPtr conn) int count; parallelsDriverLock(privconn); - count = virDomainObjListNumOfDomains(privconn->domains, 0); + count = virDomainObjListNumOfDomains(privconn->domains, false, + NULL, NULL); parallelsDriverUnlock(privconn); return count; @@ -1102,7 +1105,8 @@ parallelsConnectListAllDomains(virConnectPtr conn, virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1); parallelsDriverLock(privconn); - ret = virDomainObjListExport(privconn->domains, conn, domains, flags); + ret = virDomainObjListExport(privconn->domains, conn, domains, + NULL, flags); parallelsDriverUnlock(privconn); return ret; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 148694585e..94cebe8b71 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1492,7 +1492,8 @@ static int qemuConnectListDomains(virConnectPtr conn, int *ids, int nids) { if (virConnectListDomainsEnsureACL(conn) < 0) return -1; - n = virDomainObjListGetActiveIDs(driver->domains, ids, nids); + n = virDomainObjListGetActiveIDs(driver->domains, ids, nids, + virConnectListDomainsCheckACL, conn); return n; } @@ -1504,7 +1505,8 @@ static int qemuConnectNumOfDomains(virConnectPtr conn) { if (virConnectNumOfDomainsEnsureACL(conn) < 0) return -1; - n = virDomainObjListNumOfDomains(driver->domains, 1); + n = virDomainObjListNumOfDomains(driver->domains, true, + virConnectNumOfDomainsCheckACL, conn); return n; } @@ -5884,7 +5886,8 @@ static int qemuConnectListDefinedDomains(virConnectPtr conn, if (virConnectListDefinedDomainsEnsureACL(conn) < 0) goto cleanup; - ret = virDomainObjListGetInactiveNames(driver->domains, names, nnames); + ret = virDomainObjListGetInactiveNames(driver->domains, names, nnames, + virConnectListDefinedDomainsCheckACL, NULL); cleanup: return ret; @@ -5897,7 +5900,8 @@ static int qemuConnectNumOfDefinedDomains(virConnectPtr conn) { if (virConnectNumOfDefinedDomainsEnsureACL(conn) < 0) goto cleanup; - ret = virDomainObjListNumOfDomains(driver->domains, 0); + ret = virDomainObjListNumOfDomains(driver->domains, false, + virConnectNumOfDefinedDomainsCheckACL, NULL); cleanup: return ret; @@ -15787,7 +15791,8 @@ qemuConnectListAllDomains(virConnectPtr conn, if (virConnectListAllDomainsEnsureACL(conn) < 0) goto cleanup; - ret = virDomainObjListExport(driver->domains, conn, domains, flags); + ret = virDomainObjListExport(driver->domains, conn, domains, + virConnectListAllDomainsCheckACL, flags); cleanup: return ret; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 30c21946e8..88e23a37f8 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1274,7 +1274,7 @@ static int testConnectNumOfDomains(virConnectPtr conn) int count; testDriverLock(privconn); - count = virDomainObjListNumOfDomains(privconn->domains, 1); + count = virDomainObjListNumOfDomains(privconn->domains, true, NULL, NULL); testDriverUnlock(privconn); return count; @@ -1463,7 +1463,7 @@ static int testConnectListDomains(virConnectPtr conn, int n; testDriverLock(privconn); - n = virDomainObjListGetActiveIDs(privconn->domains, ids, maxids); + n = virDomainObjListGetActiveIDs(privconn->domains, ids, maxids, NULL, NULL); testDriverUnlock(privconn); return n; @@ -2475,7 +2475,7 @@ static int testConnectNumOfDefinedDomains(virConnectPtr conn) { int count; testDriverLock(privconn); - count = virDomainObjListNumOfDomains(privconn->domains, 0); + count = virDomainObjListNumOfDomains(privconn->domains, false, NULL, NULL); testDriverUnlock(privconn); return count; @@ -2490,7 +2490,8 @@ static int testConnectListDefinedDomains(virConnectPtr conn, testDriverLock(privconn); memset(names, 0, sizeof(*names)*maxnames); - n = virDomainObjListGetInactiveNames(privconn->domains, names, maxnames); + n = virDomainObjListGetInactiveNames(privconn->domains, names, maxnames, + NULL, NULL); testDriverUnlock(privconn); return n; @@ -5688,6 +5689,7 @@ static int testNWFilterClose(virConnectPtr conn) { return 0; } + static int testConnectListAllDomains(virConnectPtr conn, virDomainPtr **domains, unsigned int flags) @@ -5698,7 +5700,8 @@ static int testConnectListAllDomains(virConnectPtr conn, virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1); testDriverLock(privconn); - ret = virDomainObjListExport(privconn->domains, conn, domains, flags); + ret = virDomainObjListExport(privconn->domains, conn, domains, + NULL, flags); testDriverUnlock(privconn); return ret; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 25b97485f5..df98eb8659 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1545,7 +1545,8 @@ static int umlConnectListDomains(virConnectPtr conn, int *ids, int nids) { return -1; umlDriverLock(driver); - n = virDomainObjListGetActiveIDs(driver->domains, ids, nids); + n = virDomainObjListGetActiveIDs(driver->domains, ids, nids, + virConnectListDomainsCheckACL, conn); umlDriverUnlock(driver); return n; @@ -1558,7 +1559,8 @@ static int umlConnectNumOfDomains(virConnectPtr conn) { return -1; umlDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 1); + n = virDomainObjListNumOfDomains(driver->domains, true, + virConnectNumOfDomainsCheckACL, conn); umlDriverUnlock(driver); return n; @@ -1965,7 +1967,8 @@ static int umlConnectListDefinedDomains(virConnectPtr conn, return -1; umlDriverLock(driver); - n = virDomainObjListGetInactiveNames(driver->domains, names, nnames); + n = virDomainObjListGetInactiveNames(driver->domains, names, nnames, + virConnectListDefinedDomainsCheckACL, conn); umlDriverUnlock(driver); return n; @@ -1979,7 +1982,8 @@ static int umlConnectNumOfDefinedDomains(virConnectPtr conn) { return -1; umlDriverLock(driver); - n = virDomainObjListNumOfDomains(driver->domains, 0); + n = virDomainObjListNumOfDomains(driver->domains, false, + virConnectNumOfDefinedDomainsCheckACL, conn); umlDriverUnlock(driver); return n; @@ -2710,7 +2714,8 @@ static int umlConnectListAllDomains(virConnectPtr conn, return -1; umlDriverLock(driver); - ret = virDomainObjListExport(driver->domains, conn, domains, flags); + ret = virDomainObjListExport(driver->domains, conn, domains, + virConnectListAllDomainsCheckACL, flags); umlDriverUnlock(driver); return ret; diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 8a3fc996e6..ca6615fa01 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -987,7 +987,7 @@ vmwareConnectNumOfDefinedDomains(virConnectPtr conn) vmwareDriverLock(driver); vmwareDomainObjListUpdateAll(driver->domains, driver); - n = virDomainObjListNumOfDomains(driver->domains, 0); + n = virDomainObjListNumOfDomains(driver->domains, false, NULL, NULL); vmwareDriverUnlock(driver); return n; @@ -1001,7 +1001,7 @@ vmwareConnectNumOfDomains(virConnectPtr conn) vmwareDriverLock(driver); vmwareDomainObjListUpdateAll(driver->domains, driver); - n = virDomainObjListNumOfDomains(driver->domains, 1); + n = virDomainObjListNumOfDomains(driver->domains, true, NULL, NULL); vmwareDriverUnlock(driver); return n; @@ -1016,7 +1016,7 @@ vmwareConnectListDomains(virConnectPtr conn, int *ids, int nids) vmwareDriverLock(driver); vmwareDomainObjListUpdateAll(driver->domains, driver); - n = virDomainObjListGetActiveIDs(driver->domains, ids, nids); + n = virDomainObjListGetActiveIDs(driver->domains, ids, nids, NULL, NULL); vmwareDriverUnlock(driver); return n; @@ -1031,7 +1031,8 @@ vmwareConnectListDefinedDomains(virConnectPtr conn, vmwareDriverLock(driver); vmwareDomainObjListUpdateAll(driver->domains, driver); - n = virDomainObjListGetInactiveNames(driver->domains, names, nnames); + n = virDomainObjListGetInactiveNames(driver->domains, names, nnames, + NULL, NULL); vmwareDriverUnlock(driver); return n; } @@ -1121,7 +1122,8 @@ vmwareConnectListAllDomains(virConnectPtr conn, vmwareDriverLock(driver); vmwareDomainObjListUpdateAll(driver->domains, driver); - ret = virDomainObjListExport(driver->domains, conn, domains, flags); + ret = virDomainObjListExport(driver->domains, conn, domains, + NULL, flags); vmwareDriverUnlock(driver); return ret; }