remote: Implement bulk domain stats APIs in the remote driver

Implement the remote driver support for shuffling the domain stats
around.
This commit is contained in:
Peter Krempa 2014-08-25 13:22:13 +02:00
parent 1438807b7e
commit 89a706681c
4 changed files with 216 additions and 1 deletions

View File

@ -6383,6 +6383,92 @@ remoteDispatchNetworkGetDHCPLeases(virNetServerPtr server ATTRIBUTE_UNUSED,
}
static int
remoteDispatchConnectGetAllDomainStats(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
remote_connect_get_all_domain_stats_args *args,
remote_connect_get_all_domain_stats_ret *ret)
{
int rv = -1;
size_t i;
struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
virDomainStatsRecordPtr *retStats = NULL;
int nrecords = 0;
virDomainPtr *doms = NULL;
if (!priv->conn) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
goto cleanup;
}
if (args->doms.doms_len) {
if (VIR_ALLOC_N(doms, args->doms.doms_len + 1) < 0)
goto cleanup;
for (i = 0; i < args->doms.doms_len; i++) {
if (!(doms[i] = get_nonnull_domain(priv->conn, args->doms.doms_val[i])))
goto cleanup;
}
if ((nrecords = virDomainListGetStats(doms,
args->stats,
&retStats,
args->flags)) < 0)
goto cleanup;
} else {
if ((nrecords = virConnectGetAllDomainStats(priv->conn,
args->stats,
&retStats,
args->flags)) < 0)
goto cleanup;
}
if (nrecords > REMOTE_CONNECT_GET_ALL_DOMAIN_STATS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of domain stats records is %d, "
"which exceeds max limit: %d"),
nrecords, REMOTE_DOMAIN_LIST_MAX);
goto cleanup;
}
if (nrecords) {
if (VIR_ALLOC_N(ret->retStats.retStats_val, nrecords) < 0)
goto cleanup;
ret->retStats.retStats_len = nrecords;
for (i = 0; i < nrecords; i++) {
remote_domain_stats_record *dst = ret->retStats.retStats_val + i;
make_nonnull_domain(&dst->dom, retStats[i]->dom);
if (remoteSerializeTypedParameters(retStats[i]->params,
retStats[i]->nparams,
&dst->params.params_val,
&dst->params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0)
goto cleanup;
}
} else {
ret->retStats.retStats_len = 0;
ret->retStats.retStats_val = NULL;
}
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
virDomainStatsRecordListFree(retStats);
virDomainListFree(doms);
return rv;
}
/*----- Helpers. -----*/
/* get_nonnull_domain and get_nonnull_network turn an on-wire

View File

@ -7717,6 +7717,89 @@ remoteNetworkGetDHCPLeases(virNetworkPtr net,
}
static int
remoteConnectGetAllDomainStats(virConnectPtr conn,
virDomainPtr *doms,
unsigned int ndoms,
unsigned int stats,
virDomainStatsRecordPtr **retStats,
unsigned int flags)
{
struct private_data *priv = conn->networkPrivateData;
int rv = -1;
size_t i;
remote_connect_get_all_domain_stats_args args;
remote_connect_get_all_domain_stats_ret ret;
virDomainStatsRecordPtr *tmpret = NULL;
if (ndoms) {
if (VIR_ALLOC_N(args.doms.doms_val, ndoms) < 0)
goto cleanup;
for (i = 0; i < ndoms; i++)
make_nonnull_domain(args.doms.doms_val + i, doms[i]);
}
args.doms.doms_len = ndoms;
args.stats = stats;
args.flags = flags;
memset(&ret, 0, sizeof(ret));
remoteDriverLock(priv);
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS,
(xdrproc_t)xdr_remote_connect_get_all_domain_stats_args, (char *)&args,
(xdrproc_t)xdr_remote_connect_get_all_domain_stats_ret, (char *)&ret) == -1) {
remoteDriverUnlock(priv);
goto cleanup;
}
remoteDriverUnlock(priv);
if (ret.retStats.retStats_len > REMOTE_DOMAIN_LIST_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of stats entries is %d, which exceeds max limit: %d"),
ret.retStats.retStats_len, REMOTE_DOMAIN_LIST_MAX);
goto cleanup;
}
*retStats = NULL;
if (VIR_ALLOC_N(tmpret, ret.retStats.retStats_len + 1) < 0)
goto cleanup;
for (i = 0; i < ret.retStats.retStats_len; i++) {
virDomainStatsRecordPtr elem;
remote_domain_stats_record *rec = ret.retStats.retStats_val + i;
if (VIR_ALLOC(elem) < 0)
goto cleanup;
if (!(elem->dom = get_nonnull_domain(conn, rec->dom)))
goto cleanup;
if (remoteDeserializeTypedParameters(rec->params.params_val,
rec->params.params_len,
REMOTE_CONNECT_GET_ALL_DOMAIN_STATS_MAX,
&elem->params,
&elem->nparams))
goto cleanup;
tmpret[i] = elem;
}
*retStats = tmpret;
tmpret = NULL;
rv = ret.retStats.retStats_len;
cleanup:
virDomainStatsRecordListFree(tmpret);
xdr_free((xdrproc_t)xdr_remote_connect_get_all_domain_stats_ret,
(char *) &ret);
return rv;
}
/* get_nonnull_domain and get_nonnull_network turn an on-wire
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
* These can return NULL if underlying memory allocations fail,
@ -8056,6 +8139,7 @@ static virDriver remote_driver = {
.domainSetTime = remoteDomainSetTime, /* 1.2.5 */
.nodeGetFreePages = remoteNodeGetFreePages, /* 1.2.6 */
.connectGetDomainCapabilities = remoteConnectGetDomainCapabilities, /* 1.2.7 */
.connectGetAllDomainStats = remoteConnectGetAllDomainStats, /* 1.2.8 */
};
static virNetworkDriver network_driver = {

View File

@ -241,6 +241,9 @@ const REMOTE_DOMAIN_FSFREEZE_MOUNTPOINTS_MAX = 256;
/* Upper limit on the maximum number of leases in one lease file */
const REMOTE_NETWORK_DHCP_LEASES_MAX = 65536;
/* Upper limit on count of parameters returned via bulk stats API */
const REMOTE_CONNECT_GET_ALL_DOMAIN_STATS_MAX = 4096;
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@ -3063,6 +3066,20 @@ struct remote_network_get_dhcp_leases_ret {
unsigned int ret;
};
struct remote_domain_stats_record {
remote_nonnull_domain dom;
remote_typed_param params<REMOTE_CONNECT_GET_ALL_DOMAIN_STATS_MAX>;
};
struct remote_connect_get_all_domain_stats_args {
remote_nonnull_domain doms<REMOTE_DOMAIN_LIST_MAX>;
unsigned int stats;
unsigned int flags;
};
struct remote_connect_get_all_domain_stats_ret {
remote_domain_stats_record retStats<REMOTE_DOMAIN_LIST_MAX>;
};
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@ -5432,6 +5449,12 @@ enum remote_procedure {
* @generate: none
* @acl: domain:open_graphics
*/
REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343
REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343,
/**
* @generate: none
* @acl: connect:search_domains
* @aclfilter: domain:read
*/
REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS = 344
};

View File

@ -2524,6 +2524,27 @@ struct remote_network_get_dhcp_leases_ret {
} leases;
u_int ret;
};
struct remote_domain_stats_record {
remote_nonnull_domain dom;
struct {
u_int params_len;
remote_typed_param * params_val;
} params;
};
struct remote_connect_get_all_domain_stats_args {
struct {
u_int doms_len;
remote_nonnull_domain * doms_val;
} doms;
u_int stats;
u_int flags;
};
struct remote_connect_get_all_domain_stats_ret {
struct {
u_int retStats_len;
remote_domain_stats_record * retStats_val;
} retStats;
};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@ -2868,4 +2889,5 @@ enum remote_procedure {
REMOTE_PROC_NETWORK_GET_DHCP_LEASES = 341,
REMOTE_PROC_CONNECT_GET_DOMAIN_CAPABILITIES = 342,
REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343,
REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS = 344,
};