diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2012-01-28 15:21:31 +0900 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2012-01-28 11:09:31 -0700 |
commit | c6ec021b3c19c3ecc97d60d35b12eaa0b94da701 (patch) | |
tree | 01a401f3c9a0df900803b704bdda2cace7920993 /daemon | |
parent | docs: reorder public header (diff) | |
download | libvirt-c6ec021b3c19c3ecc97d60d35b12eaa0b94da701.tar.gz libvirt-c6ec021b3c19c3ecc97d60d35b12eaa0b94da701.tar.bz2 libvirt-c6ec021b3c19c3ecc97d60d35b12eaa0b94da701.zip |
remote handler for virDomainGetCPUStats()
Unlike other users of virTypedParameter with RPC, this interface
can return zero-filled entries because the interface assumes
2 dimensional array. We compress these entries out from the
server when generating the over-the-wire contents, then reconstitute
them in the client.
Signed-off-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/remote.c | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/daemon/remote.c b/daemon/remote.c index d2150bf54..cb8423a33 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -704,8 +704,11 @@ remoteSerializeTypedParameters(virTypedParameterPtr params, } for (i = 0, j = 0; i < nparams; ++i) { - if (!(flags & VIR_TYPED_PARAM_STRING_OKAY) && - params[i].type == VIR_TYPED_PARAM_STRING) { + /* virDomainGetCPUStats can return a sparse array; also, we + * can't pass back strings to older clients. */ + if (!params[i].type || + (!(flags & VIR_TYPED_PARAM_STRING_OKAY) && + params[i].type == VIR_TYPED_PARAM_STRING)) { --*ret_params_len; continue; } @@ -3523,6 +3526,75 @@ cleanup: return rv; } +static int +remoteDispatchDomainGetCPUStats(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr hdr ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_cpu_stats_args *args, + remote_domain_get_cpu_stats_ret *ret) +{ + virDomainPtr dom = NULL; + struct daemonClientPrivate *priv; + virTypedParameterPtr params = NULL; + int rv = -1; + int percpu_len = 0; + + priv = virNetServerClientGetPrivateData(client); + if (!priv->conn) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if (args->nparams > REMOTE_NODE_CPU_STATS_MAX) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large")); + goto cleanup; + } + if (args->ncpus > REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("ncpus too large")); + goto cleanup; + } + + if (args->nparams > 0 && + VIR_ALLOC_N(params, args->ncpus * args->nparams) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (!(dom = get_nonnull_domain(priv->conn, args->dom))) + goto cleanup; + + percpu_len = virDomainGetCPUStats(dom, params, args->nparams, + args->start_cpu, args->ncpus, + args->flags); + if (percpu_len < 0) + goto cleanup; + /* If nparams == 0, the function returns a single value */ + if (args->nparams == 0) + goto success; + + if (remoteSerializeTypedParameters(params, args->nparams * args->ncpus, + &ret->params.params_val, + &ret->params.params_len, + args->flags) < 0) + goto cleanup; + + percpu_len = ret->params.params_len / args->ncpus; + +success: + rv = 0; + ret->nparams = percpu_len; + +cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + virTypedParameterArrayClear(params, args->ncpus * args->nparams); + VIR_FREE(params); + if (dom) + virDomainFree(dom); + return rv; +} + /*----- Helpers. -----*/ /* get_nonnull_domain and get_nonnull_network turn an on-wire |