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
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list