util: Export remoteSerializeTypedParameters internally via util

Same as for deserializer, this method might get handy for admin one day.
The major reason for this patch is to stay consistent with idea, i.e.
when deserializer can be shared, why not serializer as well. The only
problem to be solved was that the daemon side serializer uses a code
snippet which handles sparse arrays returned by some APIs as well as
removes any string parameters that can't be returned to older clients.
This patch makes of the new virTypedParameterRemote datatype introduced
by one of the pvious patches.
This commit is contained in:
Erik Skultety 2016-02-02 14:13:15 +01:00
parent 9afc115f73
commit 8cd1d546e6
6 changed files with 175 additions and 220 deletions

View File

@ -101,13 +101,6 @@ static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr
static void make_nonnull_nwfilter(remote_nonnull_nwfilter *net_dst, virNWFilterPtr nwfilter_src);
static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
static int
remoteSerializeTypedParameters(virTypedParameterPtr params,
int nparams,
remote_typed_param **ret_params_val,
u_int *ret_params_len,
unsigned int flags);
static int
remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors,
int nerrors,
@ -989,10 +982,10 @@ remoteRelayDomainEventTunable(virConnectPtr conn,
data.callbackID = callback->callbackID;
make_nonnull_domain(&data.dom, dom);
if (remoteSerializeTypedParameters(params, nparams,
&data.params.params_val,
&data.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &data.params.params_val,
&data.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0)
return -1;
remoteDispatchObjectEventSend(callback->client, remoteProgram,
@ -1410,85 +1403,6 @@ remoteDispatchDomainGetSchedulerType(virNetServerPtr server ATTRIBUTE_UNUSED,
return rv;
}
/* Helper to serialize typed parameters. This also filters out any string
* parameters that must not be returned to older clients. */
static int
remoteSerializeTypedParameters(virTypedParameterPtr params,
int nparams,
remote_typed_param **ret_params_val,
u_int *ret_params_len,
unsigned int flags)
{
size_t i;
size_t j;
int rv = -1;
remote_typed_param *val;
*ret_params_len = nparams;
if (VIR_ALLOC_N(val, nparams) < 0)
goto cleanup;
for (i = 0, j = 0; i < nparams; ++i) {
/* 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;
}
/* remoteDispatchClientRequest will free this: */
if (VIR_STRDUP(val[j].field, params[i].field) < 0)
goto cleanup;
val[j].value.type = params[i].type;
switch (params[i].type) {
case VIR_TYPED_PARAM_INT:
val[j].value.remote_typed_param_value_u.i = params[i].value.i;
break;
case VIR_TYPED_PARAM_UINT:
val[j].value.remote_typed_param_value_u.ui = params[i].value.ui;
break;
case VIR_TYPED_PARAM_LLONG:
val[j].value.remote_typed_param_value_u.l = params[i].value.l;
break;
case VIR_TYPED_PARAM_ULLONG:
val[j].value.remote_typed_param_value_u.ul = params[i].value.ul;
break;
case VIR_TYPED_PARAM_DOUBLE:
val[j].value.remote_typed_param_value_u.d = params[i].value.d;
break;
case VIR_TYPED_PARAM_BOOLEAN:
val[j].value.remote_typed_param_value_u.b = params[i].value.b;
break;
case VIR_TYPED_PARAM_STRING:
if (VIR_STRDUP(val[j].value.remote_typed_param_value_u.s, params[i].value.s) < 0)
goto cleanup;
break;
default:
virReportError(VIR_ERR_RPC, _("unknown parameter type: %d"),
params[i].type);
goto cleanup;
}
j++;
}
*ret_params_val = val;
val = NULL;
rv = 0;
cleanup:
if (val) {
for (i = 0; i < nparams; i++) {
VIR_FREE(val[i].field);
if (val[i].value.type == VIR_TYPED_PARAM_STRING)
VIR_FREE(val[i].value.remote_typed_param_value_u.s);
}
VIR_FREE(val);
}
return rv;
}
static int
remoteDispatchDomainGetSchedulerParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client ATTRIBUTE_UNUSED,
@ -1523,10 +1437,10 @@ remoteDispatchDomainGetSchedulerParameters(virNetServerPtr server ATTRIBUTE_UNUS
if (virDomainGetSchedulerParameters(dom, params, &nparams) < 0)
goto cleanup;
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
0) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
0) < 0)
goto cleanup;
rv = 0;
@ -1632,10 +1546,10 @@ remoteDispatchDomainGetSchedulerParametersFlags(virNetServerPtr server ATTRIBUTE
args->flags) < 0)
goto cleanup;
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
goto cleanup;
rv = 0;
@ -1805,11 +1719,11 @@ remoteDispatchDomainBlockStatsFlags(virNetServerPtr server ATTRIBUTE_UNUSED,
goto success;
}
/* Serialise the block stats. */
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
/* Serialize the block stats. */
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
goto cleanup;
success:
@ -2472,10 +2386,10 @@ remoteDispatchDomainGetMemoryParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
goto success;
}
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
goto cleanup;
success:
@ -2534,10 +2448,10 @@ remoteDispatchDomainGetNumaParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
goto success;
}
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
flags) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
flags) < 0)
goto cleanup;
success:
@ -2596,10 +2510,10 @@ remoteDispatchDomainGetBlkioParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
goto success;
}
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
goto cleanup;
success:
@ -2841,11 +2755,11 @@ remoteDispatchDomainGetBlockIoTune(virNetServerPtr server ATTRIBUTE_UNUSED,
goto success;
}
/* Serialise the block I/O tuning parameters. */
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
/* Serialize the block I/O tuning parameters. */
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
goto cleanup;
success:
@ -4381,10 +4295,10 @@ remoteDispatchDomainGetInterfaceParameters(virNetServerPtr server ATTRIBUTE_UNUS
goto success;
}
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
flags) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
flags) < 0)
goto cleanup;
success:
@ -4443,10 +4357,10 @@ remoteDispatchDomainGetCPUStats(virNetServerPtr server ATTRIBUTE_UNUSED,
if (args->nparams == 0)
goto success;
if (remoteSerializeTypedParameters(params, args->nparams * args->ncpus,
&ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
if (virTypedParamsSerialize(params, args->nparams * args->ncpus,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
goto cleanup;
success:
@ -5112,10 +5026,10 @@ remoteDispatchNodeGetMemoryParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
goto success;
}
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
args->flags) < 0)
goto cleanup;
success:
@ -5259,10 +5173,10 @@ remoteDispatchDomainGetJobStats(virNetServerPtr server ATTRIBUTE_UNUSED,
goto cleanup;
}
if (remoteSerializeTypedParameters(params, nparams,
&ret->params.params_val,
&ret->params.params_len,
0) < 0)
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
0) < 0)
goto cleanup;
rv = 0;
@ -6305,11 +6219,11 @@ remoteDispatchConnectGetAllDomainStats(virNetServerPtr server ATTRIBUTE_UNUSED,
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)
if (virTypedParamsSerialize(retStats[i]->params,
retStats[i]->nparams,
(virTypedParameterRemotePtr *) &dst->params.params_val,
&dst->params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0)
goto cleanup;
}
} else {

View File

@ -2355,6 +2355,7 @@ virTypedParamsFilter;
virTypedParamsGetStringList;
virTypedParamsRemoteFree;
virTypedParamsReplaceString;
virTypedParamsSerialize;
virTypedParamsValidate;

View File

@ -1663,66 +1663,6 @@ remoteConnectListAllDomains(virConnectPtr conn,
return rv;
}
/* Helper to serialize typed parameters. */
static int
remoteSerializeTypedParameters(virTypedParameterPtr params,
int nparams,
remote_typed_param **args_params_val,
u_int *args_params_len)
{
size_t i;
int rv = -1;
remote_typed_param *val;
*args_params_len = nparams;
if (VIR_ALLOC_N(val, nparams) < 0)
goto cleanup;
for (i = 0; i < nparams; ++i) {
/* call() will free this: */
if (VIR_STRDUP(val[i].field, params[i].field) < 0)
goto cleanup;
val[i].value.type = params[i].type;
switch (params[i].type) {
case VIR_TYPED_PARAM_INT:
val[i].value.remote_typed_param_value_u.i = params[i].value.i;
break;
case VIR_TYPED_PARAM_UINT:
val[i].value.remote_typed_param_value_u.ui = params[i].value.ui;
break;
case VIR_TYPED_PARAM_LLONG:
val[i].value.remote_typed_param_value_u.l = params[i].value.l;
break;
case VIR_TYPED_PARAM_ULLONG:
val[i].value.remote_typed_param_value_u.ul = params[i].value.ul;
break;
case VIR_TYPED_PARAM_DOUBLE:
val[i].value.remote_typed_param_value_u.d = params[i].value.d;
break;
case VIR_TYPED_PARAM_BOOLEAN:
val[i].value.remote_typed_param_value_u.b = params[i].value.b;
break;
case VIR_TYPED_PARAM_STRING:
if (VIR_STRDUP(val[i].value.remote_typed_param_value_u.s,
params[i].value.s) < 0)
goto cleanup;
break;
default:
virReportError(VIR_ERR_RPC, _("unknown parameter type: %d"),
params[i].type);
goto cleanup;
}
}
*args_params_val = val;
val = NULL;
rv = 0;
cleanup:
virTypedParamsRemoteFree((virTypedParameterRemotePtr) val, nparams);
return rv;
}
static int
remoteDeserializeDomainDiskErrors(remote_domain_disk_error *ret_errors_val,
u_int ret_errors_len,
@ -6944,9 +6884,9 @@ remoteDomainMigrateBegin3Params(virDomainPtr domain,
goto cleanup;
}
if (remoteSerializeTypedParameters(params, nparams,
&args.params.params_val,
&args.params.params_len) < 0) {
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len, 0) < 0) {
xdr_free((xdrproc_t) xdr_remote_domain_migrate_begin3_params_args,
(char *) &args);
goto cleanup;
@ -7011,9 +6951,9 @@ remoteDomainMigratePrepare3Params(virConnectPtr dconn,
goto cleanup;
}
if (remoteSerializeTypedParameters(params, nparams,
&args.params.params_val,
&args.params.params_len) < 0) {
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len, 0) < 0) {
xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare3_params_args,
(char *) &args);
goto cleanup;
@ -7098,9 +7038,9 @@ remoteDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
args.cookie_in.cookie_in_len = cookieinlen;
args.flags = flags;
if (remoteSerializeTypedParameters(params, nparams,
&args.params.params_val,
&args.params.params_len) < 0) {
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len, 0) < 0) {
xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_args,
(char *) &args);
goto cleanup;
@ -7187,9 +7127,9 @@ remoteDomainMigratePerform3Params(virDomainPtr dom,
args.cookie_in.cookie_in_len = cookieinlen;
args.flags = flags;
if (remoteSerializeTypedParameters(params, nparams,
&args.params.params_val,
&args.params.params_len) < 0) {
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len, 0) < 0) {
xdr_free((xdrproc_t) xdr_remote_domain_migrate_perform3_params_args,
(char *) &args);
goto cleanup;
@ -7259,9 +7199,9 @@ remoteDomainMigrateFinish3Params(virConnectPtr dconn,
args.flags = flags;
args.cancelled = cancelled;
if (remoteSerializeTypedParameters(params, nparams,
&args.params.params_val,
&args.params.params_len) < 0) {
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len, 0) < 0) {
xdr_free((xdrproc_t) xdr_remote_domain_migrate_finish3_params_args,
(char *) &args);
goto cleanup;
@ -7333,9 +7273,9 @@ remoteDomainMigrateConfirm3Params(virDomainPtr domain,
args.flags = flags;
args.cancelled = cancelled;
if (remoteSerializeTypedParameters(params, nparams,
&args.params.params_val,
&args.params.params_len) < 0) {
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len, 0) < 0) {
xdr_free((xdrproc_t) xdr_remote_domain_migrate_confirm3_params_args,
(char *) &args);
goto cleanup;

View File

@ -1213,7 +1213,9 @@ elsif ($mode eq "client") {
} elsif ($args_member =~ m/^remote_typed_param (\S+)<(\S+)>;/) {
push(@args_list, "virTypedParameterPtr $1");
push(@args_list, "int n$1");
push(@setters_list2, "if (remoteSerializeTypedParameters($1, n$1, &args.$1.$1_val, &args.$1.$1_len) < 0) {\n" .
push(@setters_list2, "if (virTypedParamsSerialize($1, n$1,\n" .
" (virTypedParameterRemotePtr *) &args.$1.$1_val,\n" .
" &args.$1.$1_len, 0) < 0) {\n" .
" xdr_free((xdrproc_t)xdr_$call->{args}, (char *)&args);\n" .
" goto done;\n" .
" }");

View File

@ -1469,3 +1469,95 @@ virTypedParamsDeserialize(virTypedParameterRemotePtr remote_params,
}
return rv;
}
/**
* virTypedParamsSerialize:
* @params: array of parameters to be serialized and later sent to remote side
* @nparams: number of elements in @params
* @remote_params_val: protocol independent remote representation of @params
* @remote_params_len: the final number of elements in @remote_params_val
* @flags: bitwise-OR of virTypedParameterFlags
*
* This method serializes typed parameters provided by @params into
* @remote_params_val which is the representation actually being sent.
*
* Server side using this method also filters out any string parameters that
* must not be returned to older clients and handles possibly sparse arrays
* returned by some APIs.
*
* Returns 0 on success, -1 on error.
*/
int
virTypedParamsSerialize(virTypedParameterPtr params,
int nparams,
virTypedParameterRemotePtr *remote_params_val,
unsigned int *remote_params_len,
unsigned int flags)
{
size_t i;
size_t j;
int rv = -1;
virTypedParameterRemotePtr params_val;
*remote_params_len = nparams;
if (VIR_ALLOC_N(params_val, nparams) < 0)
goto cleanup;
for (i = 0, j = 0; i < nparams; ++i) {
virTypedParameterPtr param = params + i;
virTypedParameterRemotePtr val = params_val + j;
/* NOTE: Following snippet is relevant to server only, because
* virDomainGetCPUStats can return a sparse array; also, we can't pass
* back strings to older clients. */
if (!param->type ||
(!(flags & VIR_TYPED_PARAM_STRING_OKAY) &&
param->type == VIR_TYPED_PARAM_STRING)) {
--*remote_params_len;
continue;
}
/* This will be either freed by virNetServerDispatchCall or call(),
* depending on the calling side, i.e. server or client */
if (VIR_STRDUP(val->field, param->field) < 0)
goto cleanup;
val->value.type = param->type;
switch (param->type) {
case VIR_TYPED_PARAM_INT:
val->value.remote_typed_param_value.i = param->value.i;
break;
case VIR_TYPED_PARAM_UINT:
val->value.remote_typed_param_value.ui = param->value.ui;
break;
case VIR_TYPED_PARAM_LLONG:
val->value.remote_typed_param_value.l = param->value.l;
break;
case VIR_TYPED_PARAM_ULLONG:
val->value.remote_typed_param_value.ul = param->value.ul;
break;
case VIR_TYPED_PARAM_DOUBLE:
val->value.remote_typed_param_value.d = param->value.d;
break;
case VIR_TYPED_PARAM_BOOLEAN:
val->value.remote_typed_param_value.b = param->value.b;
break;
case VIR_TYPED_PARAM_STRING:
if (VIR_STRDUP(val->value.remote_typed_param_value.s, param->value.s) < 0)
goto cleanup;
break;
default:
virReportError(VIR_ERR_RPC, _("unknown parameter type: %d"),
param->type);
goto cleanup;
}
j++;
}
*remote_params_val = params_val;
params_val = NULL;
rv = 0;
cleanup:
virTypedParamsRemoteFree(params_val, nparams);
return rv;
}

View File

@ -113,6 +113,12 @@ int virTypedParamsDeserialize(virTypedParameterRemotePtr remote_params,
virTypedParameterPtr *params,
int *nparams);
int virTypedParamsSerialize(virTypedParameterPtr params,
int nparams,
virTypedParameterRemotePtr *remote_params_val,
unsigned int *remote_params_len,
unsigned int flags);
VIR_ENUM_DECL(virTypedParameter)
# define VIR_TYPED_PARAMS_DEBUG(params, nparams) \