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 | 91 +++-------------------------------------------
src/libvirt_private.syms | 1 +
src/remote/remote_driver.c | 66 +++------------------------------
src/util/virtypedparam.c | 90 +++++++++++++++++++++++++++++++++++++++++++++
src/util/virtypedparam.h | 6 +++
5 files changed, 108 insertions(+), 146 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index f76a176..cc6474a 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -108,13 +108,11 @@ static void
make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapsho
(virTypedParameterRemotePtr) remote_params_val, \
remote_params_len, limit, params, nparams)
-static int
-remoteSerializeTypedParameters(virTypedParameterPtr params,
- int nparams,
- remote_typed_param **ret_params_val,
- u_int *ret_params_len,
- unsigned int flags);
-
+#define remoteSerializeTypedParameters(params, nparams, remote_params_val, \
+ remote_params_len, flags) \
+ virTypedParamsSerialize(params, nparams, \
+ (virTypedParameterRemotePtr *) remote_params_val, \
+ remote_params_len, flags)
static int
remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors,
int nerrors,
@@ -1417,85 +1415,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,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5f34875..a4cc14e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2354,6 +2354,7 @@ virTypedParamsFilter;
virTypedParamsGetStringList;
virTypedParamsRemoteFree;
virTypedParamsReplaceString;
+virTypedParamsSerialize;
virTypedParamsValidate;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 2702fcb..bf32802 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -76,6 +76,12 @@ VIR_LOG_INIT("remote.remote_driver");
virTypedParamsRemoteFree((virTypedParameterRemotePtr) remote_params_val, \
remote_params_len)
+#define remoteSerializeTypedParameters(params, nparams, remote_params_val, \
+ remote_params_len) \
+ virTypedParamsSerialize(params, nparams, \
+ (virTypedParameterRemotePtr *) remote_params_val, \
+ remote_params_len, 0)
+
#define remoteDeserializeTypedParameters(remote_params_val, \
remote_params_len, \
limit, params, nparams) \
@@ -1674,66 +1680,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:
- remoteFreeTypedParameters(val, nparams);
- return rv;
-}
-
static int
remoteDeserializeDomainDiskErrors(remote_domain_disk_error *ret_errors_val,
u_int ret_errors_len,
diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c
index 3363147..f6e4f1e 100644
--- a/src/util/virtypedparam.c
+++ b/src/util/virtypedparam.c
@@ -1471,3 +1471,93 @@ virTypedParamsDeserialize(const char *funcname,
}
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 val;
+
+ *remote_params_len = nparams;
+ if (VIR_ALLOC_N(val, nparams) < 0)
+ goto cleanup;
+
+ for (i = 0, j = 0; i < nparams; ++i) {
+ /* 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 (!params[i].type ||
+ (!(flags & VIR_TYPED_PARAM_STRING_OKAY) &&
+ params[i].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[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.i = params[i].value.i;
+ break;
+ case VIR_TYPED_PARAM_UINT:
+ val[j].value.remote_typed_param_value.ui = params[i].value.ui;
+ break;
+ case VIR_TYPED_PARAM_LLONG:
+ val[j].value.remote_typed_param_value.l = params[i].value.l;
+ break;
+ case VIR_TYPED_PARAM_ULLONG:
+ val[j].value.remote_typed_param_value.ul = params[i].value.ul;
+ break;
+ case VIR_TYPED_PARAM_DOUBLE:
+ val[j].value.remote_typed_param_value.d = params[i].value.d;
+ break;
+ case VIR_TYPED_PARAM_BOOLEAN:
+ val[j].value.remote_typed_param_value.b = params[i].value.b;
+ break;
+ case VIR_TYPED_PARAM_STRING:
+ if (VIR_STRDUP(val[j].value.remote_typed_param_value.s, params[i].value.s)
< 0)
+ goto cleanup;
+ break;
+ default:
+ virReportError(VIR_ERR_RPC, _("unknown parameter type: %d"),
+ params[i].type);
+ goto cleanup;
+ }
+ j++;
+ }
+
+ *remote_params_val = val;
+ val = NULL;
+ rv = 0;
+
+ cleanup:
+ virTypedParamsRemoteFree(val, nparams);
+ return rv;
+}
diff --git a/src/util/virtypedparam.h b/src/util/virtypedparam.h
index 72d10c2..c303b50 100644
--- a/src/util/virtypedparam.h
+++ b/src/util/virtypedparam.h
@@ -114,6 +114,12 @@ int virTypedParamsDeserialize(const char *funcname,
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