
On 08/26/14 11:47, Li Wei wrote:
On 08/26/2014 01:05 AM, Peter Krempa wrote:
Implement the remote driver support for shuffling the domain stats around. --- daemon/remote.c | 91 ++++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 88 ++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 26 ++++++++++++- src/remote_protocol-structs | 23 +++++++++++ 4 files changed, 227 insertions(+), 1 deletion(-)
diff --git a/daemon/remote.c b/daemon/remote.c index ea16789..34e6950 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -6337,6 +6337,97 @@ remoteDispatchNetworkGetDHCPLeases(virNetServerPtr server ATTRIBUTE_UNUSED, }
+static int +remoteDispatchDomainListGetStats(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_list_get_stats_args *args, + remote_domain_list_get_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 (!(virConnectGetAllDomainStats(priv->conn, + args->stats, + &retStats, + args->flags)) < 0)
if ((nrecords = virConnectGetAllDomainStats(priv->conn, args->stats, &retStats, args->flags)) < 0)
Good catch.
+ goto cleanup; + } + + if (nrecords > REMOTE_DOMAIN_LIST_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 (retStats && nrecords) { + ret->retStats.retStats_len = nrecords; + + if (VIR_ALLOC_N(ret->retStats.retStats_val, nrecords) < 0) + goto cleanup; + + for (i = 0; i < nrecords; i++) { + virDomainStatsRecordPtr src = retStats[i]; + remote_domain_stats_record *dst = ret->retStats.retStats_val + i; + + make_nonnull_domain(&dst->dom, src->dom); + + if (remoteSerializeTypedParameters(src->params, src->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; + } + + ret->ret = nrecords; + rv = 0; + + cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + if (retStats) + virDomainStatsRecordListFree(retStats); + if (args->doms.doms_len) { + for (i = 0; i < args->doms.doms_len; i++) + virDomainFree(doms[i]); + + VIR_FREE(doms); + } + return rv; +} + + /*----- Helpers. -----*/
/* get_nonnull_domain and get_nonnull_network turn an on-wire diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 9a1d78f..41c807a 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7670,6 +7670,93 @@ remoteNetworkGetDHCPLeases(virNetworkPtr net, }
+static int +remoteDomainListGetStats(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_domain_list_get_stats_args args; + remote_domain_list_get_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_DOMAIN_LIST_GET_STATS, + (xdrproc_t)xdr_remote_domain_list_get_stats_args, (char *)&args, + (xdrproc_t)xdr_remote_domain_list_get_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 (ret.retStats.retStats_len) { + if (VIR_ALLOC_N(tmpret, ret.retStats.retStats_len) < 0)
Shouldn't we need to allocate one plus pointer here to act as a NULL sentinel for virDomainStatsRecordListFree()?
Definitely. Thanks for pointing this out.
Thanks, Li Wei
Both problems are fixed in v2. Peter