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. --- daemon/remote.c | 196 +++++++++++++-------------------------------- src/libvirt_private.syms | 1 + src/remote/remote_driver.c | 96 +++++----------------- src/rpc/gendispatch.pl | 4 +- src/util/virtypedparam.c | 92 +++++++++++++++++++++ src/util/virtypedparam.h | 6 ++ 6 files changed, 175 insertions(+), 220 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index d655cfd..ca692a9 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -102,13 +102,6 @@ static void make_nonnull_nwfilter(remote_nonnull_nwfilter *net_dst, virNWFilterP 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, remote_domain_disk_error **ret_errors_val, @@ -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 { diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 690e957..69be352 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2355,6 +2355,7 @@ virTypedParamsFilter; virTypedParamsGetStringList; virTypedParamsRemoteFree; virTypedParamsReplaceString; +virTypedParamsSerialize; virTypedParamsValidate; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 4d569c9..58787cd 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -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; diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index 9d64e63..658efae 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -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" . " }"); diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c index 1bc7865..138fc64 100644 --- a/src/util/virtypedparam.c +++ b/src/util/virtypedparam.c @@ -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; +} diff --git a/src/util/virtypedparam.h b/src/util/virtypedparam.h index df3547f..73f710a 100644 --- a/src/util/virtypedparam.h +++ b/src/util/virtypedparam.h @@ -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) \ -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list