[libvirt] [PATCH 2/7] remote: consolidate typed parameter handling

Eric Blake eblake at redhat.com
Tue May 17 22:42:10 UTC 2011


* src/remote/remote_protocol.x (remote_typed_param_value)
(remote_typed_param):  New types.
(remote_sched_param_value, remote_sched_param)
(remote_blkio_param_value, remote_blkio_param)
(remote_memory_param_value, remote_memory_param): Delete.
(remote_domain_get_scheduler_parameters_ret)
(remote_domain_set_scheduler_parameters_args)
(remote_domain_set_scheduler_parameters_flags_args)
(remote_domain_set_blkio_parameters_args)
(remote_domain_get_blkio_parameters_ret)
(remote_domain_set_memory_parameters_args)
(remote_domain_get_memory_parameters_ret): Update clients.
* src/remote_protocol-structs: Likewise.
* src/remote/remote_driver.c (remoteSerializeTypedParameters)
(remoteDeserializeTypedParameters): New functions.
(remoteDomainSetMemoryParameters)
(remoteDomainGetMemoryParameters, remoteDomainSetBlkioParameters)
(remoteDomainGetBlkioParameters)
(remoteDomainGetSchedulerParameters)
(remoteDomainSetSchedulerParameters)
(remoteDomainSetSchedulerParametersFlags): Update clients.
* daemon/remote.c (remoteSerializeTypedParameters)
(remoteDeserializeTypedParameters): New functions.
(remoteDispatchDomainGetSchedulerParameters)
(remoteDispatchDomainSetSchedulerParameters)
(remoteDispatchDomainSetSchedulerParametersFlags)
(remoteDispatchDomainSetMemoryParameters)
(remoteDispatchDomainGetMemoryParameters)
(remoteDispatchDomainSetBlkioParameters)
(remoteDispatchDomainGetBlkioParameters): Update clients.
---

I checked that on-the-wire format of the RPC call is identical.

 daemon/remote.c              |  502 ++++++++++++++---------------------------
 src/remote/remote_driver.c   |  471 ++++++++++++++-------------------------
 src/remote/remote_protocol.x |   74 ++-----
 src/remote_protocol-structs  |   52 +----
 4 files changed, 367 insertions(+), 732 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 42e1cb9..001e5bf 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -531,6 +531,143 @@ cleanup:
     return rv;
 }

+/* Helper to serialize typed parameters. */
+static int
+remoteSerializeTypedParameters(virTypedParameterPtr params,
+                               int nparams,
+                               u_int *ret_params_len,
+                               remote_typed_param **ret_params_val)
+{
+    int i;
+    int rv = -1;
+    remote_typed_param *val;
+
+    *ret_params_len = nparams;
+    if (VIR_ALLOC_N(val, nparams) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    for (i = 0; i < nparams; ++i) {
+        /* remoteDispatchClientRequest will free this: */
+        val[i].field = strdup (params[i].field);
+        if (val[i].field == NULL) {
+            virReportOOMError();
+            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;
+        default:
+            virNetError(VIR_ERR_RPC, _("unknown parameter type: %d"),
+                        params[i].type);
+            goto cleanup;
+        }
+    }
+
+    *ret_params_val = val;
+    val = NULL;
+    rv = 0;
+
+cleanup:
+    if (val) {
+        for (i = 0; i < nparams; i++)
+            VIR_FREE(val[i].field);
+        VIR_FREE(val);
+    }
+    return rv;
+}
+
+/* Helper to deserialize typed parameters. */
+static virTypedParameterPtr
+remoteDeserializeTypedParameters(u_int args_params_len,
+                                 remote_typed_param *args_params_val,
+                                 int limit,
+                                 int *nparams)
+{
+    int i;
+    int rv = -1;
+    virTypedParameterPtr params = NULL;
+
+    /* Check the length of the returned list carefully. */
+    if (args_params_len > limit) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
+        goto cleanup;
+    }
+    if (VIR_ALLOC_N(params, args_params_len) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    *nparams = args_params_len;
+
+    /* Deserialise the result. */
+    for (i = 0; i < args_params_len; ++i) {
+        if (virStrcpyStatic(params[i].field,
+                            args_params_val[i].field) == NULL) {
+            virNetError(VIR_ERR_INTERNAL_ERROR,
+                        _("Parameter %s too big for destination"),
+                        args_params_val[i].field);
+            goto cleanup;
+        }
+        params[i].type = args_params_val[i].value.type;
+        switch (params[i].type) {
+        case VIR_TYPED_PARAM_INT:
+            params[i].value.i =
+                args_params_val[i].value.remote_typed_param_value_u.i;
+            break;
+        case VIR_TYPED_PARAM_UINT:
+            params[i].value.ui =
+                args_params_val[i].value.remote_typed_param_value_u.ui;
+            break;
+        case VIR_TYPED_PARAM_LLONG:
+            params[i].value.l =
+                args_params_val[i].value.remote_typed_param_value_u.l;
+            break;
+        case VIR_TYPED_PARAM_ULLONG:
+            params[i].value.ul =
+                args_params_val[i].value.remote_typed_param_value_u.ul;
+            break;
+        case VIR_TYPED_PARAM_DOUBLE:
+            params[i].value.d =
+                args_params_val[i].value.remote_typed_param_value_u.d;
+            break;
+        case VIR_TYPED_PARAM_BOOLEAN:
+            params[i].value.b =
+                args_params_val[i].value.remote_typed_param_value_u.b;
+            break;
+        default:
+            virNetError(VIR_ERR_INTERNAL_ERROR, _("unknown parameter type: %d"),
+                        params[i].type);
+            goto cleanup;
+        }
+    }
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0)
+        VIR_FREE(params);
+    return params;
+}
+
 static int
 remoteDispatchDomainGetSchedulerParameters(struct qemud_server *server ATTRIBUTE_UNUSED,
                                            struct qemud_client *client ATTRIBUTE_UNUSED,
@@ -542,7 +679,6 @@ remoteDispatchDomainGetSchedulerParameters(struct qemud_server *server ATTRIBUTE
 {
     virDomainPtr dom = NULL;
     virSchedParameterPtr params = NULL;
-    int i;
     int nparams = args->nparams;
     int rv = -1;

@@ -564,48 +700,16 @@ remoteDispatchDomainGetSchedulerParameters(struct qemud_server *server ATTRIBUTE
     if (virDomainGetSchedulerParameters(dom, params, &nparams) < 0)
         goto cleanup;

-    /* Serialise the scheduler parameters. */
-    ret->params.params_len = nparams;
-    if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0)
-        goto no_memory;
-
-    for (i = 0; i < nparams; ++i) {
-        /* remoteDispatchClientRequest will free this: */
-        ret->params.params_val[i].field = strdup(params[i].field);
-        if (ret->params.params_val[i].field == NULL)
-            goto no_memory;
-
-        ret->params.params_val[i].value.type = params[i].type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_SCHED_FIELD_INT:
-            ret->params.params_val[i].value.remote_sched_param_value_u.i = params[i].value.i; break;
-        case VIR_DOMAIN_SCHED_FIELD_UINT:
-            ret->params.params_val[i].value.remote_sched_param_value_u.ui = params[i].value.ui; break;
-        case VIR_DOMAIN_SCHED_FIELD_LLONG:
-            ret->params.params_val[i].value.remote_sched_param_value_u.l = params[i].value.l; break;
-        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
-            ret->params.params_val[i].value.remote_sched_param_value_u.ul = params[i].value.ul; break;
-        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
-            ret->params.params_val[i].value.remote_sched_param_value_u.d = params[i].value.d; break;
-        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
-            ret->params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break;
-        default:
-            virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("unknown type"));
-            goto cleanup;
-        }
-    }
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &ret->params.params_len,
+                                       &ret->params.params_val) < 0)
+        goto cleanup;

     rv = 0;

 cleanup:
-    if (rv < 0) {
+    if (rv < 0)
         remoteDispatchError(rerr);
-        if (ret->params.params_val) {
-            for (i = 0 ; i < nparams ; i++)
-                VIR_FREE(ret->params.params_val[i].field);
-            VIR_FREE(ret->params.params_val);
-        }
-    }
     if (dom)
         virDomainFree(dom);
     VIR_FREE(params);
@@ -627,7 +731,7 @@ remoteDispatchDomainSetSchedulerParameters(struct qemud_server *server ATTRIBUTE
 {
     virDomainPtr dom = NULL;
     virSchedParameterPtr params = NULL;
-    int i, nparams;
+    int nparams;
     int rv = -1;

     if (!conn) {
@@ -637,38 +741,11 @@ remoteDispatchDomainSetSchedulerParameters(struct qemud_server *server ATTRIBUTE

     nparams = args->params.params_len;

-    if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
-        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
+    if ((params = remoteDeserializeTypedParameters(args->params.params_len,
+                                                   args->params.params_val,
+                                                   REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX,
+                                                   &nparams)) == NULL)
         goto cleanup;
-    }
-    if (VIR_ALLOC_N(params, nparams) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    /* Deserialise parameters. */
-    for (i = 0; i < nparams; ++i) {
-        if (virStrcpyStatic(params[i].field, args->params.params_val[i].field) == NULL) {
-            virNetError(VIR_ERR_INTERNAL_ERROR, _("Field %s too big for destination"),
-                                      args->params.params_val[i].field);
-            goto cleanup;
-        }
-        params[i].type = args->params.params_val[i].value.type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_SCHED_FIELD_INT:
-            params[i].value.i = args->params.params_val[i].value.remote_sched_param_value_u.i; break;
-        case VIR_DOMAIN_SCHED_FIELD_UINT:
-            params[i].value.ui = args->params.params_val[i].value.remote_sched_param_value_u.ui; break;
-        case VIR_DOMAIN_SCHED_FIELD_LLONG:
-            params[i].value.l = args->params.params_val[i].value.remote_sched_param_value_u.l; break;
-        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
-            params[i].value.ul = args->params.params_val[i].value.remote_sched_param_value_u.ul; break;
-        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
-            params[i].value.d = args->params.params_val[i].value.remote_sched_param_value_u.d; break;
-        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
-            params[i].value.b = args->params.params_val[i].value.remote_sched_param_value_u.b; break;
-        }
-    }

     if (!(dom = get_nonnull_domain(conn, args->dom)))
         goto cleanup;
@@ -698,7 +775,7 @@ remoteDispatchDomainSetSchedulerParametersFlags(struct qemud_server *server ATTR
 {
     virDomainPtr dom = NULL;
     virSchedParameterPtr params = NULL;
-    int i, nparams;
+    int nparams;
     int rv = -1;

     if (!conn) {
@@ -706,40 +783,11 @@ remoteDispatchDomainSetSchedulerParametersFlags(struct qemud_server *server ATTR
         goto cleanup;
     }

-    nparams = args->params.params_len;
-
-    if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
-        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
+    if ((params = remoteDeserializeTypedParameters(args->params.params_len,
+                                                   args->params.params_val,
+                                                   REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX,
+                                                   &nparams)) == NULL)
         goto cleanup;
-    }
-    if (VIR_ALLOC_N(params, nparams) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    /* Deserialise parameters. */
-    for (i = 0; i < nparams; ++i) {
-        if (virStrcpyStatic(params[i].field, args->params.params_val[i].field) == NULL) {
-            virNetError(VIR_ERR_INTERNAL_ERROR, _("Field %s too big for destination"),
-                                      args->params.params_val[i].field);
-            goto cleanup;
-        }
-        params[i].type = args->params.params_val[i].value.type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_SCHED_FIELD_INT:
-            params[i].value.i = args->params.params_val[i].value.remote_sched_param_value_u.i; break;
-        case VIR_DOMAIN_SCHED_FIELD_UINT:
-            params[i].value.ui = args->params.params_val[i].value.remote_sched_param_value_u.ui; break;
-        case VIR_DOMAIN_SCHED_FIELD_LLONG:
-            params[i].value.l = args->params.params_val[i].value.remote_sched_param_value_u.l; break;
-        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
-            params[i].value.ul = args->params.params_val[i].value.remote_sched_param_value_u.ul; break;
-        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
-            params[i].value.d = args->params.params_val[i].value.remote_sched_param_value_u.d; break;
-        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
-            params[i].value.b = args->params.params_val[i].value.remote_sched_param_value_u.b; break;
-        }
-    }

     if (!(dom = get_nonnull_domain(conn, args->dom)))
         goto cleanup;
@@ -1340,7 +1388,7 @@ remoteDispatchDomainSetMemoryParameters(struct qemud_server *server
 {
     virDomainPtr dom = NULL;
     virMemoryParameterPtr params = NULL;
-    int i, nparams;
+    int nparams;
     unsigned int flags;
     int rv = -1;

@@ -1349,61 +1397,13 @@ remoteDispatchDomainSetMemoryParameters(struct qemud_server *server
         goto cleanup;
     }

-    nparams = args->params.params_len;
     flags = args->flags;

-    if (nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) {
-        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
+    if ((params = remoteDeserializeTypedParameters(args->params.params_len,
+                                                   args->params.params_val,
+                                                   REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
+                                                   &nparams)) == NULL)
         goto cleanup;
-    }
-    if (VIR_ALLOC_N(params, nparams) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    /* Deserialise parameters. */
-    for (i = 0; i < nparams; ++i) {
-        if (virStrcpyStatic
-            (params[i].field, args->params.params_val[i].field) == NULL) {
-            virNetError(VIR_ERR_INTERNAL_ERROR,
-                        _("Field %s too big for destination"),
-                        args->params.params_val[i].field);
-            goto cleanup;
-        }
-        params[i].type = args->params.params_val[i].value.type;
-        switch (params[i].type) {
-            case VIR_DOMAIN_MEMORY_PARAM_INT:
-                params[i].value.i =
-                    args->params.params_val[i].value.
-                    remote_memory_param_value_u.i;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_UINT:
-                params[i].value.ui =
-                    args->params.params_val[i].value.
-                    remote_memory_param_value_u.ui;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_LLONG:
-                params[i].value.l =
-                    args->params.params_val[i].value.
-                    remote_memory_param_value_u.l;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
-                params[i].value.ul =
-                    args->params.params_val[i].value.
-                    remote_memory_param_value_u.ul;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_DOUBLE:
-                params[i].value.d =
-                    args->params.params_val[i].value.
-                    remote_memory_param_value_u.d;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_BOOLEAN:
-                params[i].value.b =
-                    args->params.params_val[i].value.
-                    remote_memory_param_value_u.b;
-                break;
-        }
-    }

     if (!(dom = get_nonnull_domain(conn, args->dom)))
         goto cleanup;
@@ -1438,7 +1438,6 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
 {
     virDomainPtr dom = NULL;
     virMemoryParameterPtr params = NULL;
-    int i;
     int nparams = args->nparams;
     unsigned int flags;
     int rv = -1;
@@ -1473,75 +1472,21 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
         goto success;
     }

-    /* Serialise the memory parameters. */
-    ret->params.params_len = nparams;
-    if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0)
-        goto no_memory;
-
-    for (i = 0; i < nparams; ++i) {
-        /* remoteDispatchClientRequest will free this: */
-        ret->params.params_val[i].field = strdup(params[i].field);
-        if (ret->params.params_val[i].field == NULL)
-            goto no_memory;
-
-        ret->params.params_val[i].value.type = params[i].type;
-        switch (params[i].type) {
-            case VIR_DOMAIN_MEMORY_PARAM_INT:
-                ret->params.params_val[i].
-                    value.remote_memory_param_value_u.i =
-                    params[i].value.i;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_UINT:
-                ret->params.params_val[i].
-                    value.remote_memory_param_value_u.ui =
-                    params[i].value.ui;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_LLONG:
-                ret->params.params_val[i].
-                    value.remote_memory_param_value_u.l =
-                    params[i].value.l;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
-                ret->params.params_val[i].
-                    value.remote_memory_param_value_u.ul =
-                    params[i].value.ul;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_DOUBLE:
-                ret->params.params_val[i].
-                    value.remote_memory_param_value_u.d =
-                    params[i].value.d;
-                break;
-            case VIR_DOMAIN_MEMORY_PARAM_BOOLEAN:
-                ret->params.params_val[i].
-                    value.remote_memory_param_value_u.b =
-                    params[i].value.b;
-                break;
-            default:
-                virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("unknown type"));
-                goto cleanup;
-        }
-    }
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &ret->params.params_len,
+                                       &ret->params.params_val) < 0)
+        goto cleanup;

 success:
     rv = 0;

 cleanup:
-    if (rv < 0) {
+    if (rv < 0)
         remoteDispatchError(rerr);
-        if (ret->params.params_val) {
-            for (i = 0; i < nparams; i++)
-                VIR_FREE(ret->params.params_val[i].field);
-            VIR_FREE(ret->params.params_val);
-        }
-    }
     if (dom)
         virDomainFree(dom);
     VIR_FREE(params);
     return rv;
-
-no_memory:
-    virReportOOMError();
-    goto cleanup;
 }

 static int
@@ -1558,7 +1503,7 @@ remoteDispatchDomainSetBlkioParameters(struct qemud_server *server
 {
     virDomainPtr dom = NULL;
     virBlkioParameterPtr params = NULL;
-    int i, nparams;
+    int nparams;
     unsigned int flags;
     int rv = -1;

@@ -1567,61 +1512,13 @@ remoteDispatchDomainSetBlkioParameters(struct qemud_server *server
         goto cleanup;
     }

-    nparams = args->params.params_len;
     flags = args->flags;

-    if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) {
-        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
-        goto cleanup;
-    }
-    if (VIR_ALLOC_N(params, nparams) < 0) {
-        virReportOOMError();
+    if ((params = remoteDeserializeTypedParameters(args->params.params_len,
+                                                   args->params.params_val,
+                                                   REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX,
+                                                   &nparams)) == NULL)
         goto cleanup;
-    }
-
-    /* Deserialise parameters. */
-    for (i = 0; i < nparams; ++i) {
-        if (virStrcpyStatic
-            (params[i].field, args->params.params_val[i].field) == NULL) {
-            virNetError(VIR_ERR_INTERNAL_ERROR,
-                        _("Field %s too big for destination"),
-                        args->params.params_val[i].field);
-            goto cleanup;
-        }
-        params[i].type = args->params.params_val[i].value.type;
-        switch (params[i].type) {
-            case VIR_DOMAIN_BLKIO_PARAM_INT:
-                params[i].value.i =
-                    args->params.params_val[i].value.
-                    remote_blkio_param_value_u.i;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_UINT:
-                params[i].value.ui =
-                    args->params.params_val[i].value.
-                    remote_blkio_param_value_u.ui;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_LLONG:
-                params[i].value.l =
-                    args->params.params_val[i].value.
-                    remote_blkio_param_value_u.l;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_ULLONG:
-                params[i].value.ul =
-                    args->params.params_val[i].value.
-                    remote_blkio_param_value_u.ul;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_DOUBLE:
-                params[i].value.d =
-                    args->params.params_val[i].value.
-                    remote_blkio_param_value_u.d;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN:
-                params[i].value.b =
-                    args->params.params_val[i].value.
-                    remote_blkio_param_value_u.b;
-                break;
-        }
-    }

     if (!(dom = get_nonnull_domain(conn, args->dom)))
         goto cleanup;
@@ -1656,7 +1553,6 @@ remoteDispatchDomainGetBlkioParameters(struct qemud_server *server
 {
     virDomainPtr dom = NULL;
     virBlkioParameterPtr params = NULL;
-    int i;
     int nparams = args->nparams;
     unsigned int flags;
     int rv = -1;
@@ -1691,75 +1587,21 @@ remoteDispatchDomainGetBlkioParameters(struct qemud_server *server
         goto success;
     }

-    /* Serialise the blkio parameters. */
-    ret->params.params_len = nparams;
-    if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0)
-        goto no_memory;
-
-    for (i = 0; i < nparams; ++i) {
-        // remoteDispatchClientRequest will free this:
-        ret->params.params_val[i].field = strdup(params[i].field);
-        if (ret->params.params_val[i].field == NULL)
-            goto no_memory;
-
-        ret->params.params_val[i].value.type = params[i].type;
-        switch (params[i].type) {
-            case VIR_DOMAIN_BLKIO_PARAM_INT:
-                ret->params.params_val[i].
-                    value.remote_blkio_param_value_u.i =
-                    params[i].value.i;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_UINT:
-                ret->params.params_val[i].
-                    value.remote_blkio_param_value_u.ui =
-                    params[i].value.ui;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_LLONG:
-                ret->params.params_val[i].
-                    value.remote_blkio_param_value_u.l =
-                    params[i].value.l;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_ULLONG:
-                ret->params.params_val[i].
-                    value.remote_blkio_param_value_u.ul =
-                    params[i].value.ul;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_DOUBLE:
-                ret->params.params_val[i].
-                    value.remote_blkio_param_value_u.d =
-                    params[i].value.d;
-                break;
-            case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN:
-                ret->params.params_val[i].
-                    value.remote_blkio_param_value_u.b =
-                    params[i].value.b;
-                break;
-            default:
-                virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("unknown type"));
-                goto cleanup;
-        }
-    }
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &ret->params.params_len,
+                                       &ret->params.params_val) < 0)
+        goto cleanup;

 success:
     rv = 0;

 cleanup:
-    if (rv < 0) {
+    if (rv < 0)
         remoteDispatchError(rerr);
-        if (ret->params.params_val) {
-            for (i = 0; i < nparams; i++)
-                VIR_FREE(ret->params.params_val[i].field);
-            VIR_FREE(ret->params.params_val);
-        }
-    }
     VIR_FREE(params);
     if (dom)
         virDomainFree(dom);
     return rv;
-
-no_memory:
-    virReportOOMError();
-    goto cleanup;
 }

 static int
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 8c69743..5348ea3 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1780,64 +1780,157 @@ done:
     return rv;
 }

+/* Helper to serialize typed parameters. */
 static int
-remoteDomainSetMemoryParameters (virDomainPtr domain,
-                                 virMemoryParameterPtr params,
-                                 int nparams,
-                                 unsigned int flags)
+remoteSerializeTypedParameters(virTypedParameterPtr params,
+                               int nparams,
+                               u_int *args_params_len,
+                               remote_typed_param **args_params_val)
 {
+    int i;
     int rv = -1;
-    remote_domain_set_memory_parameters_args args;
-    int i, do_error;
-    struct private_data *priv = domain->conn->privateData;
+    remote_typed_param *val;

-    remoteDriverLock(priv);
-
-    make_nonnull_domain (&args.dom, domain);
-
-    /* Serialise the memory parameters. */
-    args.params.params_len = nparams;
-    args.flags = flags;
-    if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) {
+    *args_params_len = nparams;
+    if (VIR_ALLOC_N(val, nparams) < 0) {
         virReportOOMError();
-        goto done;
+        goto cleanup;
     }

-    do_error = 0;
     for (i = 0; i < nparams; ++i) {
         /* call() will free this: */
-        args.params.params_val[i].field = strdup (params[i].field);
-        if (args.params.params_val[i].field == NULL) {
+        val[i].field = strdup (params[i].field);
+        if (val[i].field == NULL) {
             virReportOOMError();
-            do_error = 1;
+            goto cleanup;
         }
-        args.params.params_val[i].value.type = params[i].type;
+        val[i].value.type = params[i].type;
         switch (params[i].type) {
-        case VIR_DOMAIN_MEMORY_PARAM_INT:
-            args.params.params_val[i].value.remote_memory_param_value_u.i =
-                params[i].value.i; break;
-        case VIR_DOMAIN_MEMORY_PARAM_UINT:
-            args.params.params_val[i].value.remote_memory_param_value_u.ui =
-                params[i].value.ui; break;
-        case VIR_DOMAIN_MEMORY_PARAM_LLONG:
-            args.params.params_val[i].value.remote_memory_param_value_u.l =
-                params[i].value.l; break;
-        case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
-            args.params.params_val[i].value.remote_memory_param_value_u.ul =
-                params[i].value.ul; break;
-        case VIR_DOMAIN_MEMORY_PARAM_DOUBLE:
-            args.params.params_val[i].value.remote_memory_param_value_u.d =
-                params[i].value.d; break;
-        case VIR_DOMAIN_MEMORY_PARAM_BOOLEAN:
-            args.params.params_val[i].value.remote_memory_param_value_u.b =
-                params[i].value.b; break;
+        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;
         default:
-            remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type"));
-            do_error = 1;
+            remoteError(VIR_ERR_RPC, _("unknown parameter type: %d"),
+                params[i].type);
+            goto cleanup;
         }
     }

-    if (do_error) {
+    *args_params_val = val;
+    val = NULL;
+    rv = 0;
+
+cleanup:
+    if (val) {
+        for (i = 0; i < nparams; i++)
+            VIR_FREE(val[i].field);
+        VIR_FREE(val);
+    }
+    return rv;
+}
+
+/* Helper to deserialize typed parameters. */
+static int
+remoteDeserializeTypedParameters(u_int ret_params_len,
+                                 remote_typed_param *ret_params_val,
+                                 int limit,
+                                 virTypedParameterPtr params,
+                                 int *nparams)
+{
+    int i;
+    int rv = -1;
+
+    /* Check the length of the returned list carefully. */
+    if (ret_params_len > limit || ret_params_len > *nparams) {
+        remoteError(VIR_ERR_RPC, "%s",
+                    _("returned number of parameters exceeds limit"));
+        goto cleanup;
+    }
+
+    *nparams = ret_params_len;
+
+    /* Deserialise the result. */
+    for (i = 0; i < ret_params_len; ++i) {
+        if (virStrcpyStatic(params[i].field,
+                            ret_params_val[i].field) == NULL) {
+            remoteError(VIR_ERR_INTERNAL_ERROR,
+                        _("Parameter %s too big for destination"),
+                        ret_params_val[i].field);
+            goto cleanup;
+        }
+        params[i].type = ret_params_val[i].value.type;
+        switch (params[i].type) {
+        case VIR_TYPED_PARAM_INT:
+            params[i].value.i =
+                ret_params_val[i].value.remote_typed_param_value_u.i;
+            break;
+        case VIR_TYPED_PARAM_UINT:
+            params[i].value.ui =
+                ret_params_val[i].value.remote_typed_param_value_u.ui;
+            break;
+        case VIR_TYPED_PARAM_LLONG:
+            params[i].value.l =
+                ret_params_val[i].value.remote_typed_param_value_u.l;
+            break;
+        case VIR_TYPED_PARAM_ULLONG:
+            params[i].value.ul =
+                ret_params_val[i].value.remote_typed_param_value_u.ul;
+            break;
+        case VIR_TYPED_PARAM_DOUBLE:
+            params[i].value.d =
+                ret_params_val[i].value.remote_typed_param_value_u.d;
+            break;
+        case VIR_TYPED_PARAM_BOOLEAN:
+            params[i].value.b =
+                ret_params_val[i].value.remote_typed_param_value_u.b;
+            break;
+        default:
+            remoteError(VIR_ERR_RPC, _("unknown parameter type: %d"),
+                        params[i].type);
+            goto cleanup;
+        }
+    }
+
+    rv = 0;
+
+cleanup:
+    return rv;
+}
+
+static int
+remoteDomainSetMemoryParameters (virDomainPtr domain,
+                                 virMemoryParameterPtr params,
+                                 int nparams,
+                                 unsigned int flags)
+{
+    int rv = -1;
+    remote_domain_set_memory_parameters_args args;
+    struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_domain (&args.dom, domain);
+
+    args.flags = flags;
+
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &args.params.params_len,
+                                       &args.params.params_val) < 0) {
         xdr_free ((xdrproc_t) xdr_remote_domain_set_memory_parameters_args,
                   (char *) &args);
         goto done;
@@ -1863,7 +1956,6 @@ remoteDomainGetMemoryParameters (virDomainPtr domain,
     int rv = -1;
     remote_domain_get_memory_parameters_args args;
     remote_domain_get_memory_parameters_ret ret;
-    int i = -1;
     struct private_data *priv = domain->conn->privateData;

     remoteDriverLock(priv);
@@ -1878,14 +1970,6 @@ remoteDomainGetMemoryParameters (virDomainPtr domain,
               (xdrproc_t) xdr_remote_domain_get_memory_parameters_ret, (char *) &ret) == -1)
         goto done;

-    /* Check the length of the returned list carefully. */
-    if (ret.params.params_len > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX ||
-        ret.params.params_len > *nparams) {
-        remoteError(VIR_ERR_RPC, "%s",
-                    _("remoteDomainGetMemoryParameters: "
-                      "returned number of parameters exceeds limit"));
-        goto cleanup;
-    }
     /* Handle the case when the caller does not know the number of parameters
      * and is asking for the number of parameters supported
      */
@@ -1895,49 +1979,12 @@ remoteDomainGetMemoryParameters (virDomainPtr domain,
         goto cleanup;
     }

-    *nparams = ret.params.params_len;
-
-    /* Deserialise the result. */
-    for (i = 0; i < *nparams; ++i) {
-        if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) {
-            remoteError(VIR_ERR_INTERNAL_ERROR,
-                        _("Parameter %s too big for destination"),
-                        ret.params.params_val[i].field);
-            goto cleanup;
-        }
-        params[i].type = ret.params.params_val[i].value.type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_MEMORY_PARAM_INT:
-            params[i].value.i =
-                ret.params.params_val[i].value.remote_memory_param_value_u.i;
-            break;
-        case VIR_DOMAIN_MEMORY_PARAM_UINT:
-            params[i].value.ui =
-                ret.params.params_val[i].value.remote_memory_param_value_u.ui;
-            break;
-        case VIR_DOMAIN_MEMORY_PARAM_LLONG:
-            params[i].value.l =
-                ret.params.params_val[i].value.remote_memory_param_value_u.l;
-            break;
-        case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
-            params[i].value.ul =
-                ret.params.params_val[i].value.remote_memory_param_value_u.ul;
-            break;
-        case VIR_DOMAIN_MEMORY_PARAM_DOUBLE:
-            params[i].value.d =
-                ret.params.params_val[i].value.remote_memory_param_value_u.d;
-            break;
-        case VIR_DOMAIN_MEMORY_PARAM_BOOLEAN:
-            params[i].value.b =
-                ret.params.params_val[i].value.remote_memory_param_value_u.b;
-            break;
-        default:
-            remoteError(VIR_ERR_RPC, "%s",
-                        _("remoteDomainGetMemoryParameters: "
-                          "unknown parameter type"));
-            goto cleanup;
-        }
-    }
+    if (remoteDeserializeTypedParameters(ret.params.params_len,
+                                         ret.params.params_val,
+                                         REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
+                                         params,
+                                         nparams) < 0)
+        goto cleanup;

     rv = 0;

@@ -1952,61 +1999,22 @@ done:
 static int
 remoteDomainSetBlkioParameters (virDomainPtr domain,
                                 virBlkioParameterPtr params,
-                                 int nparams,
-                                 unsigned int flags)
+                                int nparams,
+                                unsigned int flags)
 {
     int rv = -1;
     remote_domain_set_blkio_parameters_args args;
-    int i, do_error;
     struct private_data *priv = domain->conn->privateData;

     remoteDriverLock(priv);

     make_nonnull_domain (&args.dom, domain);

-    /* Serialise the blkio parameters. */
-    args.params.params_len = nparams;
     args.flags = flags;
-    if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) {
-        virReportOOMError();
-        goto done;
-    }
-
-    do_error = 0;
-    for (i = 0; i < nparams; ++i) {
-        // call() will free this:
-        args.params.params_val[i].field = strdup (params[i].field);
-        if (args.params.params_val[i].field == NULL) {
-            virReportOOMError();
-            do_error = 1;
-        }
-        args.params.params_val[i].value.type = params[i].type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_BLKIO_PARAM_INT:
-            args.params.params_val[i].value.remote_blkio_param_value_u.i =
-                params[i].value.i; break;
-        case VIR_DOMAIN_BLKIO_PARAM_UINT:
-            args.params.params_val[i].value.remote_blkio_param_value_u.ui =
-                params[i].value.ui; break;
-        case VIR_DOMAIN_BLKIO_PARAM_LLONG:
-            args.params.params_val[i].value.remote_blkio_param_value_u.l =
-                params[i].value.l; break;
-        case VIR_DOMAIN_BLKIO_PARAM_ULLONG:
-            args.params.params_val[i].value.remote_blkio_param_value_u.ul =
-                params[i].value.ul; break;
-        case VIR_DOMAIN_BLKIO_PARAM_DOUBLE:
-            args.params.params_val[i].value.remote_blkio_param_value_u.d =
-                params[i].value.d; break;
-        case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN:
-            args.params.params_val[i].value.remote_blkio_param_value_u.b =
-                params[i].value.b; break;
-        default:
-            remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type"));
-            do_error = 1;
-        }
-    }

-    if (do_error) {
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &args.params.params_len,
+                                       &args.params.params_val) < 0) {
         xdr_free ((xdrproc_t) xdr_remote_domain_set_blkio_parameters_args,
                   (char *) &args);
         goto done;
@@ -2032,7 +2040,6 @@ remoteDomainGetBlkioParameters (virDomainPtr domain,
     int rv = -1;
     remote_domain_get_blkio_parameters_args args;
     remote_domain_get_blkio_parameters_ret ret;
-    int i = -1;
     struct private_data *priv = domain->conn->privateData;

     remoteDriverLock(priv);
@@ -2047,14 +2054,6 @@ remoteDomainGetBlkioParameters (virDomainPtr domain,
               (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, (char *) &ret) == -1)
         goto done;

-    /* Check the length of the returned list carefully. */
-    if (ret.params.params_len > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX ||
-        ret.params.params_len > *nparams) {
-        remoteError(VIR_ERR_RPC, "%s",
-                    _("remoteDomainGetBlkioParameters: "
-                      "returned number of parameters exceeds limit"));
-        goto cleanup;
-    }
     /* Handle the case when the caller does not know the number of parameters
      * and is asking for the number of parameters supported
      */
@@ -2064,49 +2063,12 @@ remoteDomainGetBlkioParameters (virDomainPtr domain,
         goto cleanup;
     }

-    *nparams = ret.params.params_len;
-
-    /* Deserialise the result. */
-    for (i = 0; i < *nparams; ++i) {
-        if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) {
-            remoteError(VIR_ERR_INTERNAL_ERROR,
-                        _("Parameter %s too big for destination"),
-                        ret.params.params_val[i].field);
-            goto cleanup;
-        }
-        params[i].type = ret.params.params_val[i].value.type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_BLKIO_PARAM_INT:
-            params[i].value.i =
-                ret.params.params_val[i].value.remote_blkio_param_value_u.i;
-            break;
-        case VIR_DOMAIN_BLKIO_PARAM_UINT:
-            params[i].value.ui =
-                ret.params.params_val[i].value.remote_blkio_param_value_u.ui;
-            break;
-        case VIR_DOMAIN_BLKIO_PARAM_LLONG:
-            params[i].value.l =
-                ret.params.params_val[i].value.remote_blkio_param_value_u.l;
-            break;
-        case VIR_DOMAIN_BLKIO_PARAM_ULLONG:
-            params[i].value.ul =
-                ret.params.params_val[i].value.remote_blkio_param_value_u.ul;
-            break;
-        case VIR_DOMAIN_BLKIO_PARAM_DOUBLE:
-            params[i].value.d =
-                ret.params.params_val[i].value.remote_blkio_param_value_u.d;
-            break;
-        case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN:
-            params[i].value.b =
-                ret.params.params_val[i].value.remote_blkio_param_value_u.b;
-            break;
-        default:
-            remoteError(VIR_ERR_RPC, "%s",
-                        _("remoteDomainGetBlkioParameters: "
-                          "unknown parameter type"));
-            goto cleanup;
-        }
-    }
+    if (remoteDeserializeTypedParameters(ret.params.params_len,
+                                         ret.params.params_val,
+                                         REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX,
+                                         params,
+                                         nparams) < 0)
+        goto cleanup;

     rv = 0;

@@ -2508,7 +2470,6 @@ remoteDomainGetSchedulerParameters (virDomainPtr domain,
     int rv = -1;
     remote_domain_get_scheduler_parameters_args args;
     remote_domain_get_scheduler_parameters_ret ret;
-    int i = -1;
     struct private_data *priv = domain->conn->privateData;

     remoteDriverLock(priv);
@@ -2522,45 +2483,12 @@ remoteDomainGetSchedulerParameters (virDomainPtr domain,
               (xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret, (char *) &ret) == -1)
         goto done;

-    /* Check the length of the returned list carefully. */
-    if (ret.params.params_len > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX ||
-        ret.params.params_len > *nparams) {
-        remoteError(VIR_ERR_RPC, "%s",
-                    _("remoteDomainGetSchedulerParameters: "
-                      "returned number of parameters exceeds limit"));
+    if (remoteDeserializeTypedParameters(ret.params.params_len,
+                                         ret.params.params_val,
+                                         REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX,
+                                         params,
+                                         nparams) < 0)
         goto cleanup;
-    }
-    *nparams = ret.params.params_len;
-
-    /* Deserialise the result. */
-    for (i = 0; i < *nparams; ++i) {
-        if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) {
-            remoteError(VIR_ERR_INTERNAL_ERROR,
-                        _("Parameter %s too big for destination"),
-                        ret.params.params_val[i].field);
-            goto cleanup;
-        }
-        params[i].type = ret.params.params_val[i].value.type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_SCHED_FIELD_INT:
-            params[i].value.i = ret.params.params_val[i].value.remote_sched_param_value_u.i; break;
-        case VIR_DOMAIN_SCHED_FIELD_UINT:
-            params[i].value.ui = ret.params.params_val[i].value.remote_sched_param_value_u.ui; break;
-        case VIR_DOMAIN_SCHED_FIELD_LLONG:
-            params[i].value.l = ret.params.params_val[i].value.remote_sched_param_value_u.l; break;
-        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
-            params[i].value.ul = ret.params.params_val[i].value.remote_sched_param_value_u.ul; break;
-        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
-            params[i].value.d = ret.params.params_val[i].value.remote_sched_param_value_u.d; break;
-        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
-            params[i].value.b = ret.params.params_val[i].value.remote_sched_param_value_u.b; break;
-        default:
-            remoteError(VIR_ERR_RPC, "%s",
-                        _("remoteDomainGetSchedulerParameters: "
-                          "unknown parameter type"));
-            goto cleanup;
-        }
-    }

     rv = 0;

@@ -2577,50 +2505,17 @@ remoteDomainSetSchedulerParameters (virDomainPtr domain,
 {
     int rv = -1;
     remote_domain_set_scheduler_parameters_args args;
-    int i, do_error;
     struct private_data *priv = domain->conn->privateData;

     remoteDriverLock(priv);

     make_nonnull_domain (&args.dom, domain);

-    /* Serialise the scheduler parameters. */
-    args.params.params_len = nparams;
-    if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) {
-        virReportOOMError();
-        goto done;
-    }
-
-    do_error = 0;
-    for (i = 0; i < nparams; ++i) {
-        /* call() will free this: */
-        args.params.params_val[i].field = strdup (params[i].field);
-        if (args.params.params_val[i].field == NULL) {
-            virReportOOMError();
-            do_error = 1;
-        }
-        args.params.params_val[i].value.type = params[i].type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_SCHED_FIELD_INT:
-            args.params.params_val[i].value.remote_sched_param_value_u.i = params[i].value.i; break;
-        case VIR_DOMAIN_SCHED_FIELD_UINT:
-            args.params.params_val[i].value.remote_sched_param_value_u.ui = params[i].value.ui; break;
-        case VIR_DOMAIN_SCHED_FIELD_LLONG:
-            args.params.params_val[i].value.remote_sched_param_value_u.l = params[i].value.l; break;
-        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
-            args.params.params_val[i].value.remote_sched_param_value_u.ul = params[i].value.ul; break;
-        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
-            args.params.params_val[i].value.remote_sched_param_value_u.d = params[i].value.d; break;
-        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
-            args.params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break;
-        default:
-            remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type"));
-            do_error = 1;
-        }
-    }
-
-    if (do_error) {
-        xdr_free ((xdrproc_t) xdr_remote_domain_set_scheduler_parameters_args, (char *) &args);
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &args.params.params_len,
+                                       &args.params.params_val) < 0) {
+        xdr_free ((xdrproc_t) xdr_remote_domain_set_scheduler_parameters_args,
+                  (char *) &args);
         goto done;
     }

@@ -2644,51 +2539,19 @@ remoteDomainSetSchedulerParametersFlags(virDomainPtr domain,
 {
     int rv = -1;
     remote_domain_set_scheduler_parameters_flags_args args;
-    int i, do_error;
     struct private_data *priv = domain->conn->privateData;

     remoteDriverLock(priv);

     make_nonnull_domain (&args.dom, domain);

-    /* Serialise the scheduler parameters. */
-    args.params.params_len = nparams;
     args.flags = flags;
-    if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) {
-        virReportOOMError();
-        goto done;
-    }
-
-    do_error = 0;
-    for (i = 0; i < nparams; ++i) {
-        /* call() will free this: */
-        args.params.params_val[i].field = strdup (params[i].field);
-        if (args.params.params_val[i].field == NULL) {
-            virReportOOMError();
-            do_error = 1;
-        }
-        args.params.params_val[i].value.type = params[i].type;
-        switch (params[i].type) {
-        case VIR_DOMAIN_SCHED_FIELD_INT:
-            args.params.params_val[i].value.remote_sched_param_value_u.i = params[i].value.i; break;
-        case VIR_DOMAIN_SCHED_FIELD_UINT:
-            args.params.params_val[i].value.remote_sched_param_value_u.ui = params[i].value.ui; break;
-        case VIR_DOMAIN_SCHED_FIELD_LLONG:
-            args.params.params_val[i].value.remote_sched_param_value_u.l = params[i].value.l; break;
-        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
-            args.params.params_val[i].value.remote_sched_param_value_u.ul = params[i].value.ul; break;
-        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
-            args.params.params_val[i].value.remote_sched_param_value_u.d = params[i].value.d; break;
-        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
-            args.params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break;
-        default:
-            remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type"));
-            do_error = 1;
-        }
-    }

-    if (do_error) {
-        xdr_free ((xdrproc_t) xdr_remote_domain_set_scheduler_parameters_flags_args, (char *) &args);
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &args.params.params_len,
+                                       &args.params.params_val) < 0) {
+        xdr_free ((xdrproc_t) xdr_remote_domain_set_scheduler_parameters_flags_args,
+                  (char *) &args);
         goto done;
     }

diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 5932b2c..16141df 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -296,67 +296,27 @@ struct remote_vcpu_info {
     int cpu;
 };

-/* Wire encoding of virDomainSchedParameter.
+/* Wire encoding of virTypedParameter.
  * Note the enum (type) which must remain binary compatible.
  */
-union remote_sched_param_value switch (int type) {
- case VIR_DOMAIN_SCHED_FIELD_INT:
+union remote_typed_param_value switch (int type) {
+ case VIR_TYPED_PARAM_INT:
      int i;
- case VIR_DOMAIN_SCHED_FIELD_UINT:
+ case VIR_TYPED_PARAM_UINT:
      unsigned int ui;
- case VIR_DOMAIN_SCHED_FIELD_LLONG:
+ case VIR_TYPED_PARAM_LLONG:
      hyper l;
- case VIR_DOMAIN_SCHED_FIELD_ULLONG:
+ case VIR_TYPED_PARAM_ULLONG:
      unsigned hyper ul;
- case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
+ case VIR_TYPED_PARAM_DOUBLE:
      double d;
- case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
+ case VIR_TYPED_PARAM_BOOLEAN:
      int b;
 };

-struct remote_sched_param {
+struct remote_typed_param {
     remote_nonnull_string field;
-    remote_sched_param_value value;
-};
-
-union remote_blkio_param_value switch (int type) {
- case VIR_DOMAIN_BLKIO_PARAM_INT:
-     int i;
- case VIR_DOMAIN_BLKIO_PARAM_UINT:
-     unsigned int ui;
- case VIR_DOMAIN_BLKIO_PARAM_LLONG:
-     hyper l;
- case VIR_DOMAIN_BLKIO_PARAM_ULLONG:
-     unsigned hyper ul;
- case VIR_DOMAIN_BLKIO_PARAM_DOUBLE:
-     double d;
- case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN:
-     int b;
-};
-
-struct remote_blkio_param {
-    remote_nonnull_string field;
-    remote_blkio_param_value value;
-};
-
-union remote_memory_param_value switch (int type) {
- case VIR_DOMAIN_MEMORY_PARAM_INT:
-     int i;
- case VIR_DOMAIN_MEMORY_PARAM_UINT:
-     unsigned int ui;
- case VIR_DOMAIN_MEMORY_PARAM_LLONG:
-     hyper l;
- case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
-     unsigned hyper ul;
- case VIR_DOMAIN_MEMORY_PARAM_DOUBLE:
-     double d;
- case VIR_DOMAIN_MEMORY_PARAM_BOOLEAN:
-     int b;
-};
-
-struct remote_memory_param {
-    remote_nonnull_string field;
-    remote_memory_param_value value;
+    remote_typed_param_value value;
 };

 /*----- Calls. -----*/
@@ -468,23 +428,23 @@ struct remote_domain_get_scheduler_parameters_args {
 };

 struct remote_domain_get_scheduler_parameters_ret {
-    remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>;
+    remote_typed_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>;
 };

 struct remote_domain_set_scheduler_parameters_args {
     remote_nonnull_domain dom;
-    remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>;
+    remote_typed_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>;
 };

 struct remote_domain_set_scheduler_parameters_flags_args {
     remote_nonnull_domain dom;
-    remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>;
+    remote_typed_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>;
     unsigned int flags;
 };

 struct remote_domain_set_blkio_parameters_args {
     remote_nonnull_domain dom;
-    remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>;
+    remote_typed_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>;
     unsigned int flags;
 };

@@ -495,13 +455,13 @@ struct remote_domain_get_blkio_parameters_args {
 };

 struct remote_domain_get_blkio_parameters_ret {
-    remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>;
+    remote_typed_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>;
     int nparams;
 };

 struct remote_domain_set_memory_parameters_args {
     remote_nonnull_domain dom;
-    remote_memory_param params<REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX>;
+    remote_typed_param params<REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX>;
     unsigned int flags;
 };

@@ -512,7 +472,7 @@ struct remote_domain_get_memory_parameters_args {
 };

 struct remote_domain_get_memory_parameters_ret {
-    remote_memory_param params<REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX>;
+    remote_typed_param params<REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX>;
     int nparams;
 };

diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 5b43cb4..64222cc 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -56,7 +56,7 @@ struct remote_vcpu_info {
         uint64_t                   cpu_time;
         int                        cpu;
 };
-struct remote_sched_param_value {
+struct remote_typed_param_value {
         int                        type;
         union {
                 int                i;
@@ -65,41 +65,11 @@ struct remote_sched_param_value {
                 uint64_t           ul;
                 double             d;
                 int                b;
-        } remote_sched_param_value_u;
+        } remote_typed_param_value_u;
 };
-struct remote_sched_param {
+struct remote_typed_param {
         remote_nonnull_string      field;
-        remote_sched_param_value   value;
-};
-struct remote_blkio_param_value {
-        int                        type;
-        union {
-                int                i;
-                u_int              ui;
-                int64_t            l;
-                uint64_t           ul;
-                double             d;
-                int                b;
-        } remote_blkio_param_value_u;
-};
-struct remote_blkio_param {
-        remote_nonnull_string      field;
-        remote_blkio_param_value   value;
-};
-struct remote_memory_param_value {
-        int                        type;
-        union {
-                int                i;
-                u_int              ui;
-                int64_t            l;
-                uint64_t           ul;
-                double             d;
-                int                b;
-        } remote_memory_param_value_u;
-};
-struct remote_memory_param {
-        remote_nonnull_string      field;
-        remote_memory_param_value  value;
+        remote_typed_param_value   value;
 };
 struct remote_open_args {
         remote_string              name;
@@ -178,21 +148,21 @@ struct remote_domain_get_scheduler_parameters_args {
 struct remote_domain_get_scheduler_parameters_ret {
         struct {
                 u_int              params_len;
-                remote_sched_param * params_val;
+                remote_typed_param * params_val;
         } params;
 };
 struct remote_domain_set_scheduler_parameters_args {
         remote_nonnull_domain      dom;
         struct {
                 u_int              params_len;
-                remote_sched_param * params_val;
+                remote_typed_param * params_val;
         } params;
 };
 struct remote_domain_set_scheduler_parameters_flags_args {
         remote_nonnull_domain      dom;
         struct {
                 u_int              params_len;
-                remote_sched_param * params_val;
+                remote_typed_param * params_val;
         } params;
         u_int                      flags;
 };
@@ -200,7 +170,7 @@ struct remote_domain_set_blkio_parameters_args {
         remote_nonnull_domain      dom;
         struct {
                 u_int              params_len;
-                remote_blkio_param * params_val;
+                remote_typed_param * params_val;
         } params;
         u_int                      flags;
 };
@@ -212,7 +182,7 @@ struct remote_domain_get_blkio_parameters_args {
 struct remote_domain_get_blkio_parameters_ret {
         struct {
                 u_int              params_len;
-                remote_blkio_param * params_val;
+                remote_typed_param * params_val;
         } params;
         int                        nparams;
 };
@@ -220,7 +190,7 @@ struct remote_domain_set_memory_parameters_args {
         remote_nonnull_domain      dom;
         struct {
                 u_int              params_len;
-                remote_memory_param * params_val;
+                remote_typed_param * params_val;
         } params;
         u_int                      flags;
 };
@@ -232,7 +202,7 @@ struct remote_domain_get_memory_parameters_args {
 struct remote_domain_get_memory_parameters_ret {
         struct {
                 u_int              params_len;
-                remote_memory_param * params_val;
+                remote_typed_param * params_val;
         } params;
         int                        nparams;
 };
-- 
1.7.4.4




More information about the libvir-list mailing list