[libvirt] [PATCHv2 3/3] util: use new virTypedParameter helpers

Eric Blake eblake at redhat.com
Sat Jan 7 12:51:50 UTC 2012


Reusing common code makes things smaller; it also buys us some
additional safety, such as now rejecting duplicate parameters
during a set operation.

* src/qemu/qemu_driver.c (qemuDomainSetBlkioParameters)
(qemuDomainSetMemoryParameters, qemuDomainSetNumaParameters)
(qemuSetSchedulerParametersFlags)
(qemuDomainSetInterfaceParameters, qemuDomainSetBlockIoTune)
(qemuDomainGetBlkioParameters, qemuDomainGetMemoryParameters)
(qemuDomainGetNumaParameters, qemuGetSchedulerParametersFlags)
(qemuDomainBlockStatsFlags, qemuDomainGetInterfaceParameters)
(qemuDomainGetBlockIoTune): Use new helpers.
* src/esx/esx_driver.c (esxDomainSetSchedulerParametersFlags)
(esxDomainSetMemoryParameters)
(esxDomainGetSchedulerParametersFlags)
(esxDomainGetMemoryParameters): Likewise.
* src/libxl/libxl_driver.c
(libxlDomainSetSchedulerParametersFlags)
(libxlDomainGetSchedulerParametersFlags): Likewise.
* src/lxc/lxc_driver.c (lxcDomainSetMemoryParameters)
(lxcSetSchedulerParametersFlags, lxcDomainSetBlkioParameters)
(lxcDomainGetMemoryParameters, lxcGetSchedulerParametersFlags)
(lxcDomainGetBlkioParameters): Likewise.
* src/test/test_driver.c (testDomainSetSchedulerParamsFlags)
(testDomainGetSchedulerParamsFlags): Likewise.
* src/xen/xen_hypervisor.c (xenHypervisorSetSchedulerParameters)
(xenHypervisorGetSchedulerParameters): Likewise.

Conflicts:

	src/lxc/lxc_driver.c
---
 src/esx/esx_driver.c     |   83 +++----
 src/libxl/libxl_driver.c |   48 +---
 src/lxc/lxc_driver.c     |  218 +++++-----------
 src/qemu/qemu_driver.c   |  656 ++++++++++++++--------------------------------
 src/test/test_driver.c   |   29 +--
 src/xen/xen_hypervisor.c |   51 ++--
 6 files changed, 354 insertions(+), 731 deletions(-)

diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 1e424eb..9c9330c 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2,7 +2,7 @@
 /*
  * esx_driver.c: core driver functions for managing VMware ESX hosts
  *
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2012 Red Hat, Inc.
  * Copyright (C) 2009-2011 Matthias Bolte <matthias.bolte at googlemail.com>
  * Copyright (C) 2009 Maximilian Wilhelm <max at rfc2324.org>
  *
@@ -32,6 +32,7 @@
 #include "logging.h"
 #include "uuid.h"
 #include "vmx.h"
+#include "virtypedparam.h"
 #include "esx_driver.h"
 #include "esx_interface_driver.h"
 #include "esx_network_driver.h"
@@ -3660,43 +3661,38 @@ esxDomainGetSchedulerParametersFlags(virDomainPtr domain,
          dynamicProperty = dynamicProperty->_next) {
         if (STREQ(dynamicProperty->name, "config.cpuAllocation.reservation") &&
             ! (mask & (1 << 0))) {
-            snprintf (params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH, "%s",
-                      VIR_DOMAIN_SCHEDULER_RESERVATION);
-
-            params[i].type = VIR_TYPED_PARAM_LLONG;
-
             if (esxVI_AnyType_ExpectType(dynamicProperty->val,
                                          esxVI_Type_Long) < 0) {
                 goto cleanup;
             }
-
-            params[i].value.l = dynamicProperty->val->int64;
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_SCHEDULER_RESERVATION,
+                                        VIR_TYPED_PARAM_LLONG,
+                                        dynamicProperty->val->int64) < 0)
+                goto cleanup;
             mask |= 1 << 0;
             ++i;
         } else if (STREQ(dynamicProperty->name,
                          "config.cpuAllocation.limit") &&
                    ! (mask & (1 << 1))) {
-            snprintf (params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH, "%s",
-                      VIR_DOMAIN_SCHEDULER_LIMIT);
-
-            params[i].type = VIR_TYPED_PARAM_LLONG;
-
             if (esxVI_AnyType_ExpectType(dynamicProperty->val,
                                          esxVI_Type_Long) < 0) {
                 goto cleanup;
             }
-
-            params[i].value.l = dynamicProperty->val->int64;
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_SCHEDULER_LIMIT,
+                                        VIR_TYPED_PARAM_LLONG,
+                                        dynamicProperty->val->int64) < 0)
+                goto cleanup;
             mask |= 1 << 1;
             ++i;
         } else if (STREQ(dynamicProperty->name,
                          "config.cpuAllocation.shares") &&
                    ! (mask & (1 << 2))) {
-            snprintf (params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH, "%s",
-                      VIR_DOMAIN_SCHEDULER_SHARES);
-
-            params[i].type = VIR_TYPED_PARAM_INT;
-
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_SCHEDULER_SHARES,
+                                        VIR_TYPED_PARAM_INT, 0) < 0)
+                goto cleanup;
             if (esxVI_SharesInfo_CastFromAnyType(dynamicProperty->val,
                                                  &sharesInfo) < 0) {
                 goto cleanup;
@@ -3769,6 +3765,15 @@ esxDomainSetSchedulerParametersFlags(virDomainPtr domain,
     int i;

     virCheckFlags(0, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_SCHEDULER_RESERVATION,
+                                       VIR_TYPED_PARAM_LLONG,
+                                       VIR_DOMAIN_SCHEDULER_LIMIT,
+                                       VIR_TYPED_PARAM_LLONG,
+                                       VIR_DOMAIN_SCHEDULER_SHARES,
+                                       VIR_TYPED_PARAM_INT,
+                                       NULL) < 0)
+        return -1;

     if (esxVI_EnsureSession(priv->primary) < 0) {
         return -1;
@@ -3783,8 +3788,7 @@ esxDomainSetSchedulerParametersFlags(virDomainPtr domain,
     }

     for (i = 0; i < nparams; ++i) {
-        if (STREQ (params[i].field, VIR_DOMAIN_SCHEDULER_RESERVATION) &&
-            params[i].type == VIR_TYPED_PARAM_LLONG) {
+        if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_RESERVATION)) {
             if (esxVI_Long_Alloc(&spec->cpuAllocation->reservation) < 0) {
                 goto cleanup;
             }
@@ -3797,8 +3801,7 @@ esxDomainSetSchedulerParametersFlags(virDomainPtr domain,
             }

             spec->cpuAllocation->reservation->value = params[i].value.l;
-        } else if (STREQ (params[i].field, VIR_DOMAIN_SCHEDULER_LIMIT) &&
-                   params[i].type == VIR_TYPED_PARAM_LLONG) {
+        } else if(STREQ (params[i].field, VIR_DOMAIN_SCHEDULER_LIMIT)) {
             if (esxVI_Long_Alloc(&spec->cpuAllocation->limit) < 0) {
                 goto cleanup;
             }
@@ -3812,8 +3815,7 @@ esxDomainSetSchedulerParametersFlags(virDomainPtr domain,
             }

             spec->cpuAllocation->limit->value = params[i].value.l;
-        } else if (STREQ (params[i].field, VIR_DOMAIN_SCHEDULER_SHARES) &&
-                   params[i].type == VIR_TYPED_PARAM_INT) {
+        } else if(STREQ (params[i].field, VIR_DOMAIN_SCHEDULER_SHARES)) {
             if (esxVI_SharesInfo_Alloc(&sharesInfo) < 0 ||
                 esxVI_Int_Alloc(&sharesInfo->shares) < 0) {
                 goto cleanup;
@@ -3851,10 +3853,6 @@ esxDomainSetSchedulerParametersFlags(virDomainPtr domain,
                     goto cleanup;
                 }
             }
-        } else {
-            ESX_ERROR(VIR_ERR_INVALID_ARG, _("Unknown field '%s'"),
-                      params[i].field);
-            goto cleanup;
         }
     }

@@ -4828,6 +4826,11 @@ esxDomainSetMemoryParameters(virDomainPtr domain, virTypedParameterPtr params,
     int i;

     virCheckFlags(0, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_MEMORY_MIN_GUARANTEE,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       NULL) < 0)
+        return -1;

     if (esxVI_EnsureSession(priv->primary) < 0) {
         return -1;
@@ -4842,18 +4845,13 @@ esxDomainSetMemoryParameters(virDomainPtr domain, virTypedParameterPtr params,
     }

     for (i = 0; i < nparams; ++i) {
-        if (STREQ (params[i].field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE) &&
-            params[i].type == VIR_TYPED_PARAM_ULLONG) {
+        if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) {
             if (esxVI_Long_Alloc(&spec->memoryAllocation->reservation) < 0) {
                 goto cleanup;
             }

             spec->memoryAllocation->reservation->value =
               VIR_DIV_UP(params[i].value.ul, 1024); /* Scale from kilobytes to megabytes */
-        } else {
-            ESX_ERROR(VIR_ERR_INVALID_ARG, _("Unknown field '%s'"),
-                      params[i].field);
-            goto cleanup;
         }
     }

@@ -4917,16 +4915,11 @@ esxDomainGetMemoryParameters(virDomainPtr domain, virTypedParameterPtr params,
         goto cleanup;
     }

-    if (virStrcpyStatic(params[0].field,
-                        VIR_DOMAIN_MEMORY_MIN_GUARANTEE) == NULL) {
-        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                  _("Field %s too big for destination"),
-                  VIR_DOMAIN_MEMORY_MIN_GUARANTEE);
+    /* Scale from megabytes to kilobytes */
+    if (virTypedParameterAssign(params, VIR_DOMAIN_MEMORY_MIN_GUARANTEE,
+                                VIR_TYPED_PARAM_ULLONG,
+                                reservation->value * 1024) < 0)
         goto cleanup;
-    }
-
-    params[0].type = VIR_TYPED_PARAM_ULLONG;
-    params[0].value.ul = reservation->value * 1024; /* Scale from megabytes to kilobytes */

     *nparams = 1;
     result = 0;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 0500ed0..53b863a 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------*/
-/*  Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+/*  Copyright (C) 2006-2012 Red Hat, Inc.
+ *  Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
  *  Copyright (C) 2011 Univention GmbH.
- *  Copyright (C) 2006-2011 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -43,7 +43,7 @@
 #include "libxl_driver.h"
 #include "libxl_conf.h"
 #include "xen_xm.h"
-
+#include "virtypedparam.h"

 #define VIR_FROM_THIS VIR_FROM_LIBXL

@@ -3610,26 +3610,14 @@ libxlDomainGetSchedulerParametersFlags(virDomainPtr dom,
         goto cleanup;
     }

-    params[0].value.ui = sc_info.weight;
-    params[0].type = VIR_TYPED_PARAM_UINT;
-    if (virStrcpyStatic(params[0].field,
-                        VIR_DOMAIN_SCHEDULER_WEIGHT) == NULL) {
-        libxlError(VIR_ERR_INTERNAL_ERROR,
-                   _("Field name '%s' too long"),
-                   VIR_DOMAIN_SCHEDULER_WEIGHT);
+    if (virTypedParameterAssign(&params[0], VIR_DOMAIN_SCHEDULER_WEIGHT,
+                                VIR_TYPED_PARAM_UINT, sc_info.weight) < 0)
         goto cleanup;
-    }

     if (*nparams > 1) {
-        params[1].value.ui = sc_info.cap;
-        params[1].type = VIR_TYPED_PARAM_UINT;
-        if (virStrcpyStatic(params[1].field,
-                            VIR_DOMAIN_SCHEDULER_CAP) == NULL) {
-            libxlError(VIR_ERR_INTERNAL_ERROR,
-                       _("Field name '%s' too long"),
-                       VIR_DOMAIN_SCHEDULER_CAP);
+        if (virTypedParameterAssign(&params[0], VIR_DOMAIN_SCHEDULER_CAP,
+                                    VIR_TYPED_PARAM_UINT, sc_info.cap) < 0)
             goto cleanup;
-        }
     }

     if (*nparams > XEN_SCHED_CREDIT_NPARAM)
@@ -3664,6 +3652,13 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom,
     int ret = -1;

     virCheckFlags(0, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_SCHEDULER_WEIGHT,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_SCHEDULER_CAP,
+                                       VIR_TYPED_PARAM_UINT,
+                                       NULL) < 0)
+        return -1;

     libxlDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -3705,24 +3700,9 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];

         if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_WEIGHT)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                libxlError(VIR_ERR_INVALID_ARG, "%s",
-                           _("invalid type for weight tunable, expected a 'uint'"));
-                goto cleanup;
-            }
             sc_info.weight = params[i].value.ui;
-
         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CAP)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                libxlError(VIR_ERR_INVALID_ARG, "%s",
-                           _("invalid type for cap tunable, expected a 'uint'"));
-                goto cleanup;
-            }
             sc_info.cap = params[i].value.ui;
-        } else {
-            libxlError(VIR_ERR_INVALID_ARG,
-                       _("Invalid parameter '%s'"), param->field);
-            goto cleanup;
         }
     }

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 7d6ac59..851028a 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -58,6 +58,7 @@
 #include "virnetdev.h"
 #include "virnodesuspend.h"
 #include "virtime.h"
+#include "virtypedparam.h"

 #define VIR_FROM_THIS VIR_FROM_LXC

@@ -778,18 +779,29 @@ cleanup:
     return ret;
 }

-static int lxcDomainSetMemoryParameters(virDomainPtr dom,
-                                        virTypedParameterPtr params,
-                                        int nparams,
-                                        unsigned int flags)
+static int
+lxcDomainSetMemoryParameters(virDomainPtr dom,
+                             virTypedParameterPtr params,
+                             int nparams,
+                             unsigned int flags)
 {
     lxc_driver_t *driver = dom->conn->privateData;
     int i;
     virCgroupPtr cgroup = NULL;
     virDomainObjPtr vm = NULL;
     int ret = -1;
+    int rc;

     virCheckFlags(0, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_MEMORY_HARD_LIMIT,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_MEMORY_SOFT_LIMIT,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       NULL) < 0)
+        return -1;

     lxcDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -813,14 +825,6 @@ static int lxcDomainSetMemoryParameters(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];

         if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
-            int rc;
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                lxcError(VIR_ERR_INVALID_ARG, "%s",
-                         _("invalid type for memory hard_limit tunable, expected a 'ullong'"));
-                ret = -1;
-                continue;
-            }
-
             rc = virCgroupSetMemoryHardLimit(cgroup, params[i].value.ul);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
@@ -828,14 +832,6 @@ static int lxcDomainSetMemoryParameters(virDomainPtr dom,
                 ret = -1;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
-            int rc;
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                lxcError(VIR_ERR_INVALID_ARG, "%s",
-                         _("invalid type for memory soft_limit tunable, expected a 'ullong'"));
-                ret = -1;
-                continue;
-            }
-
             rc = virCgroupSetMemorySoftLimit(cgroup, params[i].value.ul);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
@@ -843,28 +839,12 @@ static int lxcDomainSetMemoryParameters(virDomainPtr dom,
                 ret = -1;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
-            int rc;
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                lxcError(VIR_ERR_INVALID_ARG, "%s",
-                         _("invalid type for swap_hard_limit tunable, expected a 'ullong'"));
-                ret = -1;
-                continue;
-            }
-
             rc = virCgroupSetMemSwapHardLimit(cgroup, params[i].value.ul);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to set swap_hard_limit tunable"));
                 ret = -1;
             }
-        } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) {
-            lxcError(VIR_ERR_INVALID_ARG,
-                     _("Memory tunable `%s' not implemented"), param->field);
-            ret = -1;
-        } else {
-            lxcError(VIR_ERR_INVALID_ARG,
-                     _("Parameter `%s' not supported"), param->field);
-            ret = -1;
         }
     }

@@ -877,10 +857,11 @@ cleanup:
     return ret;
 }

-static int lxcDomainGetMemoryParameters(virDomainPtr dom,
-                                        virTypedParameterPtr params,
-                                        int *nparams,
-                                        unsigned int flags)
+static int
+lxcDomainGetMemoryParameters(virDomainPtr dom,
+                             virTypedParameterPtr params,
+                             int *nparams,
+                             unsigned int flags)
 {
     lxc_driver_t *driver = dom->conn->privateData;
     int i;
@@ -919,8 +900,6 @@ static int lxcDomainGetMemoryParameters(virDomainPtr dom,
     for (i = 0; i < LXC_NB_MEM_PARAM && i < *nparams; i++) {
         virTypedParameterPtr param = &params[i];
         val = 0;
-        param->value.ul = 0;
-        param->type = VIR_TYPED_PARAM_ULLONG;

         switch(i) {
         case 0: /* fill memory hard limit here */
@@ -930,14 +909,10 @@ static int lxcDomainGetMemoryParameters(virDomainPtr dom,
                                      _("unable to get memory hard limit"));
                 goto cleanup;
             }
-            if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) {
-                lxcError(VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("Field memory hard limit too long for destination"));
+            if (virTypedParameterAssign(param, VIR_DOMAIN_MEMORY_HARD_LIMIT,
+                                        VIR_TYPED_PARAM_ULLONG, val) < 0)
                 goto cleanup;
-            }
-            param->value.ul = val;
             break;
-
         case 1: /* fill memory soft limit here */
             rc = virCgroupGetMemorySoftLimit(cgroup, &val);
             if (rc != 0) {
@@ -945,14 +920,10 @@ static int lxcDomainGetMemoryParameters(virDomainPtr dom,
                                      _("unable to get memory soft limit"));
                 goto cleanup;
             }
-            if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) {
-                lxcError(VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("Field memory soft limit too long for destination"));
+            if (virTypedParameterAssign(param, VIR_DOMAIN_MEMORY_SOFT_LIMIT,
+                                        VIR_TYPED_PARAM_ULLONG, val) < 0)
                 goto cleanup;
-            }
-            param->value.ul = val;
             break;
-
         case 2: /* fill swap hard limit here */
             rc = virCgroupGetMemSwapHardLimit(cgroup, &val);
             if (rc != 0) {
@@ -960,12 +931,10 @@ static int lxcDomainGetMemoryParameters(virDomainPtr dom,
                                      _("unable to get swap hard limit"));
                 goto cleanup;
             }
-            if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT) == NULL) {
-                lxcError(VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("Field swap hard limit too long for destination"));
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT,
+                                        VIR_TYPED_PARAM_ULLONG, val) < 0)
                 goto cleanup;
-            }
-            param->value.ul = val;
             break;

         default:
@@ -2753,6 +2722,15 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom,

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_SCHEDULER_CPU_SHARES,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_SCHEDULER_VCPU_PERIOD,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
+                                       VIR_TYPED_PARAM_LLONG,
+                                       NULL) < 0)
+        return -1;

     lxcDriverLock(driver);

@@ -2793,12 +2771,6 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];

         if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) {
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                lxcError(VIR_ERR_INVALID_ARG, "%s",
-                         _("invalid type for cpu_shares tunable, expected a 'ullong'"));
-                goto cleanup;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = virCgroupSetCpuShares(group, params[i].value.ul);
                 if (rc != 0) {
@@ -2814,13 +2786,6 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom,
                 vmdef->cputune.shares = params[i].value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD)) {
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                lxcError(VIR_ERR_INVALID_ARG, "%s",
-                         _("invalid type for vcpu_period tunable,"
-                           " expected a 'ullong'"));
-                goto cleanup;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = lxcSetVcpuBWLive(group, params[i].value.ul, 0);
                 if (rc != 0)
@@ -2834,13 +2799,6 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom,
                 vmdef->cputune.period = params[i].value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA)) {
-            if (param->type != VIR_TYPED_PARAM_LLONG) {
-                lxcError(VIR_ERR_INVALID_ARG, "%s",
-                         _("invalid type for vcpu_quota tunable,"
-                           " expected a 'llong'"));
-                goto cleanup;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = lxcSetVcpuBWLive(group, 0, params[i].value.l);
                 if (rc != 0)
@@ -2853,10 +2811,6 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom,
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
                 vmdef->cputune.quota = params[i].value.l;
             }
-        } else {
-            lxcError(VIR_ERR_INVALID_ARG,
-                     _("Invalid parameter `%s'"), param->field);
-            goto cleanup;
         }
     }

@@ -2968,42 +2922,25 @@ lxcGetSchedulerParametersFlags(virDomainPtr dom,
             goto cleanup;
     }
 out:
-    params[0].value.ul = shares;
-    params[0].type = VIR_TYPED_PARAM_ULLONG;
-    if (virStrcpyStatic(params[0].field,
-                        VIR_DOMAIN_SCHEDULER_CPU_SHARES) == NULL) {
-        lxcError(VIR_ERR_INTERNAL_ERROR,
-                 _("Field name '%s' too long"),
-                 VIR_DOMAIN_SCHEDULER_CPU_SHARES);
+    if (virTypedParameterAssign(&params[0], VIR_DOMAIN_SCHEDULER_CPU_SHARES,
+                                VIR_TYPED_PARAM_ULLONG, shares) < 0)
         goto cleanup;
-    }
-
     saved_nparams++;

     if (cpu_bw_status) {
         if (*nparams > saved_nparams) {
-            params[1].value.ul = period;
-            params[1].type = VIR_TYPED_PARAM_ULLONG;
-            if (virStrcpyStatic(params[1].field,
-                                VIR_DOMAIN_SCHEDULER_VCPU_PERIOD) == NULL) {
-                lxcError(VIR_ERR_INTERNAL_ERROR,
-                         _("Field name '%s' too long"),
-                         VIR_DOMAIN_SCHEDULER_VCPU_PERIOD);
+            if (virTypedParameterAssign(&params[1],
+                                        VIR_DOMAIN_SCHEDULER_VCPU_PERIOD,
+                                        VIR_TYPED_PARAM_ULLONG, shares) < 0)
                 goto cleanup;
-            }
             saved_nparams++;
         }

         if (*nparams > saved_nparams) {
-            params[2].value.ul = quota;
-            params[2].type = VIR_TYPED_PARAM_LLONG;
-            if (virStrcpyStatic(params[2].field,
-                                VIR_DOMAIN_SCHEDULER_VCPU_QUOTA) == NULL) {
-                lxcError(VIR_ERR_INTERNAL_ERROR,
-                         _("Field name '%s' too long"),
-                         VIR_DOMAIN_SCHEDULER_VCPU_QUOTA);
+            if (virTypedParameterAssign(&params[2],
+                                        VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
+                                        VIR_TYPED_PARAM_LLONG, quota) < 0)
                 goto cleanup;
-            }
             saved_nparams++;
         }
     }
@@ -3029,10 +2966,11 @@ lxcGetSchedulerParameters(virDomainPtr domain,
 }


-static int lxcDomainSetBlkioParameters(virDomainPtr dom,
-                                       virTypedParameterPtr params,
-                                       int nparams,
-                                       unsigned int flags)
+static int
+lxcDomainSetBlkioParameters(virDomainPtr dom,
+                            virTypedParameterPtr params,
+                            int nparams,
+                            unsigned int flags)
 {
     lxc_driver_t *driver = dom->conn->privateData;
     int i;
@@ -3043,6 +2981,12 @@ static int lxcDomainSetBlkioParameters(virDomainPtr dom,

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_BLKIO_WEIGHT,
+                                       VIR_TYPED_PARAM_UINT,
+                                       NULL) < 0)
+        return -1;
+
     lxcDriverLock(driver);

     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -3074,11 +3018,6 @@ static int lxcDomainSetBlkioParameters(virDomainPtr dom,

             if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
                 int rc;
-                if (param->type != VIR_TYPED_PARAM_UINT) {
-                    lxcError(VIR_ERR_INVALID_ARG, "%s",
-                             _("invalid type for blkio weight tunable, expected a 'unsigned int'"));
-                    goto cleanup;
-                }

                 if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
                     lxcError(VIR_ERR_INVALID_ARG, "%s",
@@ -3092,10 +3031,6 @@ static int lxcDomainSetBlkioParameters(virDomainPtr dom,
                                          _("unable to set blkio weight tunable"));
                     goto cleanup;
                 }
-            } else {
-                lxcError(VIR_ERR_INVALID_ARG,
-                         _("Parameter `%s' not supported"), param->field);
-                goto cleanup;
             }
         }
     }
@@ -3107,12 +3042,6 @@ static int lxcDomainSetBlkioParameters(virDomainPtr dom,
             virTypedParameterPtr param = &params[i];

             if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
-                if (param->type != VIR_TYPED_PARAM_UINT) {
-                    lxcError(VIR_ERR_INVALID_ARG, "%s",
-                             _("invalid type for blkio weight tunable, expected a 'unsigned int'"));
-                    goto cleanup;
-                }
-
                 if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
                     lxcError(VIR_ERR_INVALID_ARG, "%s",
                              _("out of blkio weight range."));
@@ -3120,10 +3049,6 @@ static int lxcDomainSetBlkioParameters(virDomainPtr dom,
                 }

                 persistentDef->blkio.weight = params[i].value.ui;
-            } else {
-                lxcError(VIR_ERR_INVALID_ARG,
-                         _("Parameter `%s' not supported"), param->field);
-                goto cleanup;
             }
         }

@@ -3142,10 +3067,11 @@ cleanup:


 #define LXC_NB_BLKIO_PARAM  1
-static int lxcDomainGetBlkioParameters(virDomainPtr dom,
-                                       virTypedParameterPtr params,
-                                       int *nparams,
-                                       unsigned int flags)
+static int
+lxcDomainGetBlkioParameters(virDomainPtr dom,
+                            virTypedParameterPtr params,
+                            int *nparams,
+                            unsigned int flags)
 {
     lxc_driver_t *driver = dom->conn->privateData;
     int i;
@@ -3194,8 +3120,6 @@ static int lxcDomainGetBlkioParameters(virDomainPtr dom,
         for (i = 0; i < *nparams && i < LXC_NB_BLKIO_PARAM; i++) {
             virTypedParameterPtr param = &params[i];
             val = 0;
-            param->value.ui = 0;
-            param->type = VIR_TYPED_PARAM_UINT;

             switch (i) {
             case 0: /* fill blkio weight here */
@@ -3205,13 +3129,9 @@ static int lxcDomainGetBlkioParameters(virDomainPtr dom,
                                          _("unable to get blkio weight"));
                     goto cleanup;
                 }
-                if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) {
-                    lxcError(VIR_ERR_INTERNAL_ERROR,
-                             _("Field name '%s' too long"),
-                             VIR_DOMAIN_BLKIO_WEIGHT);
+                if (virTypedParameterAssign(param, VIR_DOMAIN_BLKIO_WEIGHT,
+                                            VIR_TYPED_PARAM_UINT, val) < 0)
                     goto cleanup;
-                }
-                param->value.ui = val;
                 break;

             default:
@@ -3222,19 +3142,13 @@ static int lxcDomainGetBlkioParameters(virDomainPtr dom,
     } else if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
         for (i = 0; i < *nparams && i < LXC_NB_BLKIO_PARAM; i++) {
             virTypedParameterPtr param = &params[i];
-            val = 0;
-            param->value.ui = 0;
-            param->type = VIR_TYPED_PARAM_UINT;

             switch (i) {
             case 0: /* fill blkio weight here */
-                if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) {
-                    lxcError(VIR_ERR_INTERNAL_ERROR,
-                             _("Field name '%s' too long"),
-                             VIR_DOMAIN_BLKIO_WEIGHT);
+                if (virTypedParameterAssign(param, VIR_DOMAIN_BLKIO_WEIGHT,
+                                            VIR_TYPED_PARAM_UINT,
+                                            persistentDef->blkio.weight) < 0)
                     goto cleanup;
-                }
-                param->value.ui = persistentDef->blkio.weight;
                 break;

             default:
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b60aad6..ecf61f6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -90,6 +90,7 @@
 #include "virkeycode.h"
 #include "virnodesuspend.h"
 #include "virtime.h"
+#include "virtypedparam.h"

 #define VIR_FROM_THIS VIR_FROM_QEMU

@@ -5913,10 +5914,11 @@ qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *def, size_t *def_size,
     return 0;
 }

-static int qemuDomainSetBlkioParameters(virDomainPtr dom,
-                                         virTypedParameterPtr params,
-                                         int nparams,
-                                         unsigned int flags)
+static int
+qemuDomainSetBlkioParameters(virDomainPtr dom,
+                             virTypedParameterPtr params,
+                             int nparams,
+                             unsigned int flags)
 {
     struct qemud_driver *driver = dom->conn->privateData;
     int i;
@@ -5927,8 +5929,15 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
-    qemuDriverLock(driver);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_BLKIO_WEIGHT,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+                                       VIR_TYPED_PARAM_STRING,
+                                       NULL) < 0)
+        return -1;

+    qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);

     if (vm == NULL) {
@@ -5943,13 +5952,15 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,

     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
         if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
-            qemuReportError(VIR_ERR_OPERATION_INVALID, _("blkio cgroup isn't mounted"));
+            qemuReportError(VIR_ERR_OPERATION_INVALID,
+                            _("blkio cgroup isn't mounted"));
             goto cleanup;
         }

         if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
             qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("cannot find cgroup for domain %s"), vm->def->name);
+                            _("cannot find cgroup for domain %s"),
+                            vm->def->name);
             goto cleanup;
         }
     }
@@ -5961,13 +5972,6 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
             virTypedParameterPtr param = &params[i];

             if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
-                if (param->type != VIR_TYPED_PARAM_UINT) {
-                    qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                    _("invalid type for blkio weight tunable, expected a 'unsigned int'"));
-                    ret = -1;
-                    continue;
-                }
-
                 if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
                     qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                                     _("out of blkio weight range."));
@@ -5986,14 +5990,6 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
                 virBlkioDeviceWeightPtr devices = NULL;
                 int j;

-                if (param->type != VIR_TYPED_PARAM_STRING) {
-                    qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                    _("invalid type for device_weight tunable, "
-                                      "expected a 'char *'"));
-                    ret = -1;
-                    continue;
-                }
-
                 if (qemuDomainParseDeviceWeightStr(params[i].value.s,
                                                    &devices,
                                                    &ndevices) < 0) {
@@ -6019,11 +6015,6 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
                     ret = -1;
                 virBlkioDeviceWeightArrayClear(devices, ndevices);
                 VIR_FREE(devices);
-            } else {
-                qemuReportError(VIR_ERR_INVALID_ARG,
-                                _("Parameter `%s' not supported"),
-                                param->field);
-                ret = -1;
             }
         }
     }
@@ -6037,13 +6028,6 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
             virTypedParameterPtr param = &params[i];

             if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
-                if (param->type != VIR_TYPED_PARAM_UINT) {
-                    qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                    _("invalid type for blkio weight tunable, expected a 'unsigned int'"));
-                    ret = -1;
-                    continue;
-                }
-
                 if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
                     qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                                     _("out of blkio weight range."));
@@ -6055,13 +6039,7 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
             } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
                 virBlkioDeviceWeightPtr devices = NULL;
                 size_t ndevices;
-                if (param->type != VIR_TYPED_PARAM_STRING) {
-                    qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                    _("invalid type for device_weight tunable, "
-                                      "expected a 'char *'"));
-                    ret = -1;
-                    continue;
-                }
+
                 if (qemuDomainParseDeviceWeightStr(params[i].value.s,
                                                    &devices,
                                                    &ndevices) < 0) {
@@ -6074,11 +6052,6 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
                     ret = -1;
                 virBlkioDeviceWeightArrayClear(devices, ndevices);
                 VIR_FREE(devices);
-            } else {
-                qemuReportError(VIR_ERR_INVALID_ARG,
-                                _("Parameter `%s' not supported"),
-                                param->field);
-                ret = -1;
             }
         }

@@ -6094,10 +6067,11 @@ cleanup:
     return ret;
 }

-static int qemuDomainGetBlkioParameters(virDomainPtr dom,
-                                         virTypedParameterPtr params,
-                                         int *nparams,
-                                         unsigned int flags)
+static int
+qemuDomainGetBlkioParameters(virDomainPtr dom,
+                             virTypedParameterPtr params,
+                             int *nparams,
+                             unsigned int flags)
 {
     struct qemud_driver *driver = dom->conn->privateData;
     int i, j;
@@ -6154,8 +6128,6 @@ static int qemuDomainGetBlkioParameters(virDomainPtr dom,
         for (i = 0; i < *nparams && i < QEMU_NB_BLKIO_PARAM; i++) {
             virTypedParameterPtr param = &params[i];
             val = 0;
-            param->value.ui = 0;
-            param->type = VIR_TYPED_PARAM_UINT;

             switch (i) {
             case 0: /* fill blkio weight here */
@@ -6165,13 +6137,9 @@ static int qemuDomainGetBlkioParameters(virDomainPtr dom,
                                          _("unable to get blkio weight"));
                     goto cleanup;
                 }
-                if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) {
-                    qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                    _("Field name '%s' too long"),
-                                    VIR_DOMAIN_BLKIO_WEIGHT);
+                if (virTypedParameterAssign(param, VIR_DOMAIN_BLKIO_WEIGHT,
+                                            VIR_TYPED_PARAM_UINT, val) < 0)
                     goto cleanup;
-                }
-                param->value.ui = val;
                 break;
             case 1: /* blkiotune.device_weight */
                 if (vm->def->blkio.ndevices > 0) {
@@ -6195,21 +6163,11 @@ static int qemuDomainGetBlkioParameters(virDomainPtr dom,
                     }
                     param->value.s = virBufferContentAndReset(&buf);
                 }
-                if (!param->value.s) {
-                    param->value.s = strdup("");
-                    if (!param->value.s) {
-                        virReportOOMError();
-                        goto cleanup;
-                    }
-                }
-                param->type = VIR_TYPED_PARAM_STRING;
-                if (virStrcpyStatic(param->field,
-                                    VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) == NULL) {
-                    qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                    _("Field name '%s' too long"),
-                                    VIR_DOMAIN_BLKIO_DEVICE_WEIGHT);
+                if (virTypedParameterAssign(param,
+                                            VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+                                            VIR_TYPED_PARAM_STRING,
+                                            param->value.s) < 0)
                     goto cleanup;
-                }
                 break;

             default:
@@ -6294,10 +6252,11 @@ cleanup:
     return ret;
 }

-static int qemuDomainSetMemoryParameters(virDomainPtr dom,
-                                         virTypedParameterPtr params,
-                                         int nparams,
-                                         unsigned int flags)
+static int
+qemuDomainSetMemoryParameters(virDomainPtr dom,
+                              virTypedParameterPtr params,
+                              int nparams,
+                              unsigned int flags)
 {
     struct qemud_driver *driver = dom->conn->privateData;
     int i;
@@ -6305,9 +6264,19 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
     virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     int ret = -1;
+    int rc;

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_MEMORY_HARD_LIMIT,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_MEMORY_SOFT_LIMIT,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       NULL) < 0)
+        return -1;

     qemuDriverLock(driver);

@@ -6342,14 +6311,6 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];

         if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
-            int rc;
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for memory hard_limit tunable, expected a 'ullong'"));
-                ret = -1;
-                continue;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = virCgroupSetMemoryHardLimit(group, params[i].value.ul);
                 if (rc != 0) {
@@ -6363,14 +6324,6 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
                 persistentDef->mem.hard_limit = params[i].value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
-            int rc;
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for memory soft_limit tunable, expected a 'ullong'"));
-                ret = -1;
-                continue;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = virCgroupSetMemorySoftLimit(group, params[i].value.ul);
                 if (rc != 0) {
@@ -6384,14 +6337,6 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
                 persistentDef->mem.soft_limit = params[i].value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
-            int rc;
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for swap_hard_limit tunable, expected a 'ullong'"));
-                ret = -1;
-                continue;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = virCgroupSetMemSwapHardLimit(group, params[i].value.ul);
                 if (rc != 0) {
@@ -6403,15 +6348,6 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
                 persistentDef->mem.swap_hard_limit = params[i].value.ul;
             }
-        } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) {
-            qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("Memory tunable `%s' not implemented"),
-                            param->field);
-            ret = -1;
-        } else {
-            qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("Parameter `%s' not supported"), param->field);
-            ret = -1;
         }
     }

@@ -6428,17 +6364,17 @@ cleanup:
     return ret;
 }

-static int qemuDomainGetMemoryParameters(virDomainPtr dom,
-                                         virTypedParameterPtr params,
-                                         int *nparams,
-                                         unsigned int flags)
+static int
+qemuDomainGetMemoryParameters(virDomainPtr dom,
+                              virTypedParameterPtr params,
+                              int *nparams,
+                              unsigned int flags)
 {
     struct qemud_driver *driver = dom->conn->privateData;
     int i;
     virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
-    unsigned long long val;
     int ret = -1;
     int rc;

@@ -6487,39 +6423,30 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
         for (i = 0; i < *nparams && i < QEMU_NB_MEM_PARAM; i++) {
             virMemoryParameterPtr param = &params[i];
-            val = 0;
-            param->value.ul = 0;
-            param->type = VIR_TYPED_PARAM_ULLONG;

             switch (i) {
             case 0: /* fill memory hard limit here */
-                if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) {
-                    qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                    _("Field name '%s' too long"),
-                                    VIR_DOMAIN_MEMORY_HARD_LIMIT);
+                if (virTypedParameterAssign(param,
+                                            VIR_DOMAIN_MEMORY_HARD_LIMIT,
+                                            VIR_TYPED_PARAM_ULLONG,
+                                            persistentDef->mem.hard_limit) < 0)
                     goto cleanup;
-                }
-                param->value.ul = persistentDef->mem.hard_limit;
                 break;

             case 1: /* fill memory soft limit here */
-                if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) {
-                    qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                    _("Field name '%s' too long"),
-                                    VIR_DOMAIN_MEMORY_SOFT_LIMIT);
+                if (virTypedParameterAssign(param,
+                                            VIR_DOMAIN_MEMORY_SOFT_LIMIT,
+                                            VIR_TYPED_PARAM_ULLONG,
+                                            persistentDef->mem.soft_limit) < 0)
                     goto cleanup;
-                }
-                param->value.ul = persistentDef->mem.soft_limit;
                 break;

             case 2: /* fill swap hard limit here */
-                if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT) == NULL) {
-                    qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                    _("Field name '%s' too long"),
-                                    VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT);
+                if (virTypedParameterAssign(param,
+                                            VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT,
+                                            VIR_TYPED_PARAM_ULLONG,
+                                            persistentDef->mem.swap_hard_limit) < 0)
                     goto cleanup;
-                }
-                param->value.ul = persistentDef->mem.swap_hard_limit;
                 break;

             default:
@@ -6532,9 +6459,7 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,

     for (i = 0; i < *nparams && i < QEMU_NB_MEM_PARAM; i++) {
         virTypedParameterPtr param = &params[i];
-        val = 0;
-        param->value.ul = 0;
-        param->type = VIR_TYPED_PARAM_ULLONG;
+        unsigned long long val = 0;

         /* Coverity does not realize that if we get here, group is set.  */
         sa_assert(group);
@@ -6547,13 +6472,10 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
                                      _("unable to get memory hard limit"));
                 goto cleanup;
             }
-            if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_MEMORY_HARD_LIMIT);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_MEMORY_HARD_LIMIT,
+                                        VIR_TYPED_PARAM_ULLONG, val) < 0)
                 goto cleanup;
-            }
-            param->value.ul = val;
             break;

         case 1: /* fill memory soft limit here */
@@ -6563,13 +6485,10 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
                                      _("unable to get memory soft limit"));
                 goto cleanup;
             }
-            if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_MEMORY_SOFT_LIMIT);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_MEMORY_SOFT_LIMIT,
+                                        VIR_TYPED_PARAM_ULLONG, val) < 0)
                 goto cleanup;
-            }
-            param->value.ul = val;
             break;

         case 2: /* fill swap hard limit here */
@@ -6579,13 +6498,10 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
                                      _("unable to get swap hard limit"));
                 goto cleanup;
             }
-            if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT,
+                                        VIR_TYPED_PARAM_ULLONG, val) < 0)
                 goto cleanup;
-            }
-            param->value.ul = val;
             break;

         default:
@@ -6623,6 +6539,13 @@ qemuDomainSetNumaParameters(virDomainPtr dom,

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_NUMA_MODE,
+                                       VIR_TYPED_PARAM_INT,
+                                       VIR_DOMAIN_NUMA_NODESET,
+                                       VIR_TYPED_PARAM_STRING,
+                                       NULL) < 0)
+        return -1;

     qemuDriverLock(driver);

@@ -6658,14 +6581,6 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];

         if (STREQ(param->field, VIR_DOMAIN_NUMA_MODE)) {
-            if (param->type != VIR_TYPED_PARAM_INT) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for numa strict tunable, "
-                                  "expected an 'int'"));
-                ret = -1;
-                continue;
-            }
-
             if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
                 vm->def->numatune.memory.mode != params[i].value.i) {
                 qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -6681,13 +6596,6 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
             int rc;
             bool savedmask;
             char oldnodemask[VIR_DOMAIN_CPUMASK_LEN];
-            if (param->type != VIR_TYPED_PARAM_STRING) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for numa nodeset tunable, "
-                                  "expected a 'string'"));
-                ret = -1;
-                continue;
-            }

             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 if (vm->def->numatune.memory.mode !=
@@ -6762,10 +6670,6 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                     continue;
                 }
             }
-        } else {
-            qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("Parameter `%s' not supported"), param->field);
-            ret = -1;
         }
     }

@@ -6846,13 +6750,9 @@ qemuDomainGetNumaParameters(virDomainPtr dom,

         switch (i) {
         case 0: /* fill numa mode here */
-            if (!virStrcpyStatic(param->field, VIR_DOMAIN_NUMA_MODE)) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field '%s' too long for destination"),
-                                VIR_DOMAIN_NUMA_MODE);
+            if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_MODE,
+                                        VIR_TYPED_PARAM_INT, 0) < 0)
                 goto cleanup;
-            }
-            param->type = VIR_TYPED_PARAM_INT;
             if (flags & VIR_DOMAIN_AFFECT_CONFIG)
                 param->value.i = persistentDef->numatune.memory.mode;
             else
@@ -6860,12 +6760,6 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
             break;

         case 1: /* fill numa nodeset here */
-            if (!virStrcpyStatic(param->field, VIR_DOMAIN_NUMA_NODESET)) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field '%s' too long for destination"),
-                                VIR_DOMAIN_NUMA_NODESET);
-                goto cleanup;
-            }
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
                 char *mask = persistentDef->numatune.memory.nodemask;
                 if (mask)
@@ -6881,12 +6775,9 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
                     goto cleanup;
                 }
             }
-            if (!nodeset) {
-                virReportOOMError();
+            if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_NODESET,
+                                        VIR_TYPED_PARAM_STRING, nodeset) < 0)
                 goto cleanup;
-            }
-            param->type = VIR_TYPED_PARAM_STRING;
-            param->value.s = nodeset;
             break;

         default:
@@ -7014,10 +6905,11 @@ cleanup:
     return -1;
 }

-static int qemuSetSchedulerParametersFlags(virDomainPtr dom,
-                                           virTypedParameterPtr params,
-                                           int nparams,
-                                           unsigned int flags)
+static int
+qemuSetSchedulerParametersFlags(virDomainPtr dom,
+                                virTypedParameterPtr params,
+                                int nparams,
+                                unsigned int flags)
 {
     struct qemud_driver *driver = dom->conn->privateData;
     int i;
@@ -7029,6 +6921,15 @@ static int qemuSetSchedulerParametersFlags(virDomainPtr dom,

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_SCHEDULER_CPU_SHARES,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_SCHEDULER_VCPU_PERIOD,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
+                                       VIR_TYPED_PARAM_LLONG,
+                                       NULL) < 0)
+        return -1;

     qemuDriverLock(driver);

@@ -7069,12 +6970,6 @@ static int qemuSetSchedulerParametersFlags(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];

         if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) {
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for cpu_shares tunable, expected a 'ullong'"));
-                goto cleanup;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = virCgroupSetCpuShares(group, params[i].value.ul);
                 if (rc != 0) {
@@ -7090,13 +6985,6 @@ static int qemuSetSchedulerParametersFlags(virDomainPtr dom,
                 vmdef->cputune.shares = params[i].value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD)) {
-            if (param->type != VIR_TYPED_PARAM_ULLONG) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for vcpu_period tunable,"
-                                  " expected a 'ullong'"));
-                goto cleanup;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = qemuSetVcpusBWLive(vm, group, params[i].value.ul, 0);
                 if (rc != 0)
@@ -7110,13 +6998,6 @@ static int qemuSetSchedulerParametersFlags(virDomainPtr dom,
                 vmdef->cputune.period = params[i].value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA)) {
-            if (param->type != VIR_TYPED_PARAM_LLONG) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for vcpu_quota tunable,"
-                                  " expected a 'llong'"));
-                goto cleanup;
-            }
-
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 rc = qemuSetVcpusBWLive(vm, group, 0, params[i].value.l);
                 if (rc != 0)
@@ -7129,10 +7010,6 @@ static int qemuSetSchedulerParametersFlags(virDomainPtr dom,
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
                 vmdef->cputune.quota = params[i].value.l;
             }
-        } else {
-            qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("Invalid parameter `%s'"), param->field);
-            goto cleanup;
         }
     }

@@ -7160,9 +7037,10 @@ cleanup:
     return ret;
 }

-static int qemuSetSchedulerParameters(virDomainPtr dom,
-                                      virTypedParameterPtr params,
-                                      int nparams)
+static int
+qemuSetSchedulerParameters(virDomainPtr dom,
+                           virTypedParameterPtr params,
+                           int nparams)
 {
     return qemuSetSchedulerParametersFlags(dom,
                                            params,
@@ -7315,42 +7193,25 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
             goto cleanup;
     }
 out:
-    params[0].value.ul = shares;
-    params[0].type = VIR_TYPED_PARAM_ULLONG;
-    if (virStrcpyStatic(params[0].field,
-                        VIR_DOMAIN_SCHEDULER_CPU_SHARES) == NULL) {
-        qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                        _("Field name '%s' too long"),
-                        VIR_DOMAIN_SCHEDULER_CPU_SHARES);
+    if (virTypedParameterAssign(&params[0], VIR_DOMAIN_SCHEDULER_CPU_SHARES,
+                                VIR_TYPED_PARAM_ULLONG, shares) < 0)
         goto cleanup;
-    }
-
     saved_nparams++;

     if (cpu_bw_status) {
         if (*nparams > saved_nparams) {
-            params[1].value.ul = period;
-            params[1].type = VIR_TYPED_PARAM_ULLONG;
-            if (virStrcpyStatic(params[1].field,
-                                VIR_DOMAIN_SCHEDULER_VCPU_PERIOD) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_SCHEDULER_VCPU_PERIOD);
+            if (virTypedParameterAssign(&params[1],
+                                        VIR_DOMAIN_SCHEDULER_VCPU_PERIOD,
+                                        VIR_TYPED_PARAM_ULLONG, period) < 0)
                 goto cleanup;
-            }
             saved_nparams++;
         }

         if (*nparams > saved_nparams) {
-            params[2].value.ul = quota;
-            params[2].type = VIR_TYPED_PARAM_LLONG;
-            if (virStrcpyStatic(params[2].field,
-                                VIR_DOMAIN_SCHEDULER_VCPU_QUOTA) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_SCHEDULER_VCPU_QUOTA);
+            if (virTypedParameterAssign(&params[2],
+                                        VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
+                                        VIR_TYPED_PARAM_LLONG, quota) < 0)
                 goto cleanup;
-            }
             saved_nparams++;
         }
     }
@@ -7642,113 +7503,69 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,

     if (tmp < *nparams && wr_bytes != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES);
+        if (virTypedParameterAssign(param, VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES,
+                                    VIR_TYPED_PARAM_LLONG, wr_bytes) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = wr_bytes;
         tmp++;
     }

     if (tmp < *nparams && wr_req != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_WRITE_REQ) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_WRITE_REQ);
+        if (virTypedParameterAssign(param, VIR_DOMAIN_BLOCK_STATS_WRITE_REQ,
+                                    VIR_TYPED_PARAM_LLONG, wr_req) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = wr_req;
         tmp++;
     }

     if (tmp < *nparams && rd_bytes != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_READ_BYTES) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_READ_BYTES);
+        if (virTypedParameterAssign(param, VIR_DOMAIN_BLOCK_STATS_READ_BYTES,
+                                    VIR_TYPED_PARAM_LLONG, rd_bytes) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = rd_bytes;
         tmp++;
     }

     if (tmp < *nparams && rd_req != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_READ_REQ) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_READ_REQ);
+        if (virTypedParameterAssign(param, VIR_DOMAIN_BLOCK_STATS_READ_REQ,
+                                    VIR_TYPED_PARAM_LLONG, rd_req) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = rd_req;
         tmp++;
     }

     if (tmp < *nparams && flush_req != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ);
+        if (virTypedParameterAssign(param, VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ,
+                                    VIR_TYPED_PARAM_LLONG, flush_req) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = flush_req;
         tmp++;
     }

     if (tmp < *nparams && wr_total_times != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES);
+        if (virTypedParameterAssign(param,
+                                    VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES,
+                                    VIR_TYPED_PARAM_LLONG, wr_total_times) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = wr_total_times;
         tmp++;
     }

     if (tmp < *nparams && rd_total_times != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES);
+        if (virTypedParameterAssign(param,
+                                    VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES,
+                                    VIR_TYPED_PARAM_LLONG, rd_total_times) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = rd_total_times;
         tmp++;
     }

     if (tmp < *nparams && flush_total_times != -1) {
         param = &params[tmp];
-        if (virStrcpyStatic(param->field,
-                            VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES) == NULL) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Field name '%s' too long"),
-                            VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES);
+        if (virTypedParameterAssign(param,
+                                    VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES,
+                                    VIR_TYPED_PARAM_LLONG,
+                                    flush_total_times) < 0)
             goto endjob;
-        }
-        param->type = VIR_TYPED_PARAM_LLONG;
-        param->value.l = flush_total_times;
         tmp++;
     }

@@ -7846,8 +7663,23 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
-    qemuDriverLock(driver);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_BANDWIDTH_IN_AVERAGE,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_BANDWIDTH_IN_PEAK,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_BANDWIDTH_IN_BURST,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_BANDWIDTH_OUT_PEAK,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_BANDWIDTH_OUT_BURST,
+                                       VIR_TYPED_PARAM_UINT,
+                                       NULL) < 0)
+        return -1;

+    qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);

     if (vm == NULL) {
@@ -7896,64 +7728,17 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];

         if (STREQ(param->field, VIR_DOMAIN_BANDWIDTH_IN_AVERAGE)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for bandwidth average tunable, "
-                                  "expected an 'unsigned int'"));
-                goto cleanup;
-            }
-
             bandwidth->in->average = params[i].value.ui;
         } else if (STREQ(param->field, VIR_DOMAIN_BANDWIDTH_IN_PEAK)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for bandwidth peak tunable, "
-                                  "expected an 'unsigned int'"));
-                goto cleanup;
-            }
-
             bandwidth->in->peak = params[i].value.ui;
         } else if (STREQ(param->field, VIR_DOMAIN_BANDWIDTH_IN_BURST)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for bandwidth burst tunable, "
-                                  "expected an 'unsigned int'"));
-                goto cleanup;
-            }
-
             bandwidth->in->burst = params[i].value.ui;
         } else if (STREQ(param->field, VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for bandwidth average tunable, "
-                                  "expected an 'unsigned int'"));
-                goto cleanup;
-            }
-
             bandwidth->out->average = params[i].value.ui;
         } else if (STREQ(param->field, VIR_DOMAIN_BANDWIDTH_OUT_PEAK)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for bandwidth peak tunable, "
-                                  "expected an 'unsigned int'"));
-                goto cleanup;
-            }
-
             bandwidth->out->peak = params[i].value.ui;
         } else if (STREQ(param->field, VIR_DOMAIN_BANDWIDTH_OUT_BURST)) {
-            if (param->type != VIR_TYPED_PARAM_UINT) {
-                qemuReportError(VIR_ERR_INVALID_ARG, "%s",
-                                _("invalid type for bandwidth burst tunable, "
-                                  "expected an 'unsigned int'"));
-                goto cleanup;
-            }
-
             bandwidth->out->burst = params[i].value.ui;
-        } else {
-            qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("Parameter `%s' not supported"),
-                            param->field);
-            goto cleanup;
         }
     }

@@ -8100,67 +7885,52 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom,
     }

     for (i = 0; i < *nparams && i < QEMU_NB_BANDWIDTH_PARAM; i++) {
-        params[i].value.ui = 0;
-        params[i].type = VIR_TYPED_PARAM_UINT;
-
         switch(i) {
         case 0: /* inbound.average */
-            if (virStrcpyStatic(params[i].field, VIR_DOMAIN_BANDWIDTH_IN_AVERAGE) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BANDWIDTH_IN_AVERAGE);
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_BANDWIDTH_IN_AVERAGE,
+                                        VIR_TYPED_PARAM_UINT, 0) < 0)
                 goto cleanup;
-            }
             if (net->bandwidth && net->bandwidth->in)
                 params[i].value.ui = net->bandwidth->in->average;
             break;
         case 1: /* inbound.peak */
-            if (virStrcpyStatic(params[i].field, VIR_DOMAIN_BANDWIDTH_IN_PEAK) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BANDWIDTH_IN_PEAK);
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_BANDWIDTH_IN_PEAK,
+                                        VIR_TYPED_PARAM_UINT, 0) < 0)
                 goto cleanup;
-            }
             if (net->bandwidth && net->bandwidth->in)
                 params[i].value.ui = net->bandwidth->in->peak;
             break;
         case 2: /* inbound.burst */
-            if (virStrcpyStatic(params[i].field, VIR_DOMAIN_BANDWIDTH_IN_BURST) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BANDWIDTH_IN_BURST);
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_BANDWIDTH_IN_BURST,
+                                        VIR_TYPED_PARAM_UINT, 0) < 0)
                 goto cleanup;
-            }
             if (net->bandwidth && net->bandwidth->in)
                 params[i].value.ui = net->bandwidth->in->burst;
             break;
         case 3: /* outbound.average */
-            if (virStrcpyStatic(params[i].field, VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE);
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE,
+                                        VIR_TYPED_PARAM_UINT, 0) < 0)
                 goto cleanup;
-            }
             if (net->bandwidth && net->bandwidth->out)
                 params[i].value.ui = net->bandwidth->out->average;
             break;
         case 4: /* outbound.peak */
-            if (virStrcpyStatic(params[i].field, VIR_DOMAIN_BANDWIDTH_OUT_PEAK) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BANDWIDTH_OUT_PEAK);
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_BANDWIDTH_OUT_PEAK,
+                                        VIR_TYPED_PARAM_UINT, 0) < 0)
                 goto cleanup;
-            }
             if (net->bandwidth && net->bandwidth->out)
                 params[i].value.ui = net->bandwidth->out->peak;
             break;
         case 5: /* outbound.burst */
-            if (virStrcpyStatic(params[i].field, VIR_DOMAIN_BANDWIDTH_OUT_BURST) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BANDWIDTH_OUT_BURST);
+            if (virTypedParameterAssign(&params[i],
+                                        VIR_DOMAIN_BANDWIDTH_OUT_BURST,
+                                        VIR_TYPED_PARAM_UINT, 0) < 0)
                 goto cleanup;
-            }
             if (net->bandwidth && net->bandwidth->out)
                 params[i].value.ui = net->bandwidth->out->burst;
             break;
@@ -11555,6 +11325,21 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,

     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC,
+                                       VIR_TYPED_PARAM_ULLONG,
+                                       NULL) < 0)
+        return -1;

     memset(&info, 0, sizeof(info));

@@ -11582,13 +11367,6 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
     for (i = 0; i < nparams; i++) {
         virTypedParameterPtr param = &params[i];

-        if (param->type != VIR_TYPED_PARAM_ULLONG) {
-            qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("expected unsigned long long for parameter %s"),
-                            param->field);
-            goto endjob;
-        }
-
         if (STREQ(param->field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC)) {
             info.total_bytes_sec = param->value.ul;
         } else if (STREQ(param->field,
@@ -11606,11 +11384,6 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
         } else if (STREQ(param->field,
                          VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) {
             info.write_iops_sec = param->value.ul;
-        } else {
-            qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("Unrecognized parameter %s"),
-                            param->field);
-            goto endjob;
         }
     }

@@ -11734,74 +11507,49 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,

     for (i = 0; i < QEMU_NB_BLOCK_IO_TUNE_PARAM && i < *nparams; i++) {
         virTypedParameterPtr param = &params[i];
-        param->value.ul = 0;
-        param->type = VIR_TYPED_PARAM_ULLONG;

         switch(i) {
         case 0:
-            if (virStrcpyStatic(param->field,
-                                VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC,
+                                        VIR_TYPED_PARAM_ULLONG,
+                                        reply.total_bytes_sec) < 0)
                 goto endjob;
-            }
-            param->value.ul = reply.total_bytes_sec;
             break;
-
         case 1:
-            if (virStrcpyStatic(param->field,
-                                VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC,
+                                        VIR_TYPED_PARAM_ULLONG,
+                                        reply.read_bytes_sec) < 0)
                 goto endjob;
-            }
-            param->value.ul = reply.read_bytes_sec;
             break;
-
         case 2:
-            if (virStrcpyStatic(param->field,
-                                VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC,
+                                        VIR_TYPED_PARAM_ULLONG,
+                                        reply.write_bytes_sec) < 0)
                 goto endjob;
-            }
-            param->value.ul = reply.write_bytes_sec;
             break;
-
         case 3:
-            if (virStrcpyStatic(param->field,
-                                VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC,
+                                        VIR_TYPED_PARAM_ULLONG,
+                                        reply.total_iops_sec) < 0)
                 goto endjob;
-            }
-            param->value.ul = reply.total_iops_sec;
             break;
-
         case 4:
-            if (virStrcpyStatic(param->field,
-                                VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC,
+                                        VIR_TYPED_PARAM_ULLONG,
+                                        reply.read_iops_sec) < 0)
                 goto endjob;
-            }
-            param->value.ul = reply.read_iops_sec;
             break;
-
         case 5:
-            if (virStrcpyStatic(param->field,
-                                VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC) == NULL) {
-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Field name '%s' too long"),
-                                VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC);
+            if (virTypedParameterAssign(param,
+                                        VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC,
+                                        VIR_TYPED_PARAM_ULLONG,
+                                        reply.write_iops_sec) < 0)
                 goto endjob;
-            }
-            param->value.ul = reply.write_iops_sec;
             break;
         default:
             break;
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 0c88bcf..fa531c0 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1,7 +1,7 @@
 /*
  * test.c: A "mock" hypervisor for use by application unit tests
  *
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -50,6 +50,7 @@
 #include "threads.h"
 #include "logging.h"
 #include "virfile.h"
+#include "virtypedparam.h"

 #define VIR_FROM_THIS VIR_FROM_TEST

@@ -2691,16 +2692,11 @@ testDomainGetSchedulerParamsFlags(virDomainPtr domain,
         goto cleanup;
     }

-    if (virStrcpyStatic(params[0].field,
-                        VIR_DOMAIN_SCHEDULER_WEIGHT) == NULL) {
-        testError(VIR_ERR_INTERNAL_ERROR, _("Field name '%s' too long"),
-                  VIR_DOMAIN_SCHEDULER_WEIGHT);
+    if (virTypedParameterAssign(params, VIR_DOMAIN_SCHEDULER_WEIGHT,
+                                VIR_TYPED_PARAM_UINT, 50) < 0)
         goto cleanup;
-    }
-    params[0].type = VIR_TYPED_PARAM_UINT;
     /* XXX */
     /*params[0].value.ui = privdom->weight;*/
-    params[0].value.ui = 50;

     *nparams = 1;
     ret = 0;
@@ -2730,6 +2726,11 @@ testDomainSetSchedulerParamsFlags(virDomainPtr domain,
     int ret = -1, i;

     virCheckFlags(0, -1);
+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_SCHEDULER_WEIGHT,
+                                       VIR_TYPED_PARAM_UINT,
+                                       NULL) < 0)
+        return -1;

     testDriverLock(privconn);
     privdom = virDomainFindByName(&privconn->domains,
@@ -2742,16 +2743,10 @@ testDomainSetSchedulerParamsFlags(virDomainPtr domain,
     }

     for (i = 0; i < nparams; i++) {
-        if (STRNEQ(params[i].field, VIR_DOMAIN_SCHEDULER_WEIGHT)) {
-            testError(VIR_ERR_INVALID_ARG, "field");
-            goto cleanup;
-        }
-        if (params[i].type != VIR_TYPED_PARAM_UINT) {
-            testError(VIR_ERR_INVALID_ARG, "type");
-            goto cleanup;
+        if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_WEIGHT)) {
+            /* XXX */
+            /*privdom->weight = params[i].value.ui;*/
         }
-        /* XXX */
-        /*privdom->weight = params[i].value.ui;*/
     }

     ret = 0;
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
index ee3a59c..0c92be8 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -1,7 +1,7 @@
 /*
  * xen_internal.c: direct access to Xen hypervisor level
  *
- * Copyright (C) 2005-2011 Red Hat, Inc.
+ * Copyright (C) 2005-2012 Red Hat, Inc.
  *
  * See COPYING.LIB for the License of this software
  *
@@ -67,6 +67,7 @@
 #include "memory.h"
 #include "virfile.h"
 #include "virnodesuspend.h"
+#include "virtypedparam.h"

 #define VIR_FROM_THIS VIR_FROM_XEN

@@ -1335,27 +1336,18 @@ xenHypervisorGetSchedulerParameters(virDomainPtr domain,
                 if (ret < 0)
                     return(-1);

-                if (virStrcpyStatic(params[0].field,
-                                    VIR_DOMAIN_SCHEDULER_WEIGHT) == NULL) {
-                    virXenError(VIR_ERR_INTERNAL_ERROR,
-                                "Weight %s too big for destination",
-                                VIR_DOMAIN_SCHEDULER_WEIGHT);
+                if (virTypedParameterAssign(&params[0],
+                                            VIR_DOMAIN_SCHEDULER_WEIGHT,
+                                            VIR_TYPED_PARAM_UINT,
+                                            op_dom.u.getschedinfo.u.credit.weight) < 0)
                     return -1;
-                }
-                params[0].type = VIR_TYPED_PARAM_UINT;
-                params[0].value.ui = op_dom.u.getschedinfo.u.credit.weight;
-
-                if (*nparams > 1) {
-                    if (virStrcpyStatic(params[1].field,
-                                        VIR_DOMAIN_SCHEDULER_CAP) == NULL) {
-                        virXenError(VIR_ERR_INTERNAL_ERROR,
-                                    "Cap %s too big for destination",
-                                    VIR_DOMAIN_SCHEDULER_CAP);
+
+                if (*nparams > 1 &&
+                    virTypedParameterAssign(&params[1],
+                                            VIR_DOMAIN_SCHEDULER_CAP,
+                                            VIR_TYPED_PARAM_UINT,
+                                            op_dom.u.getschedinfo.u.credit.cap) < 0)
                         return -1;
-                    }
-                    params[1].type = VIR_TYPED_PARAM_UINT;
-                    params[1].value.ui = op_dom.u.getschedinfo.u.credit.cap;
-                }

                 if (*nparams > XEN_SCHED_CRED_NPARAM)
                     *nparams = XEN_SCHED_CRED_NPARAM;
@@ -1399,6 +1391,14 @@ xenHypervisorSetSchedulerParameters(virDomainPtr domain,
         return 0;
     }

+    if (virTypedParameterArrayValidate(params, nparams,
+                                       VIR_DOMAIN_SCHEDULER_WEIGHT,
+                                       VIR_TYPED_PARAM_UINT,
+                                       VIR_DOMAIN_SCHEDULER_CAP,
+                                       VIR_TYPED_PARAM_UINT,
+                                       NULL) < 0)
+        return -1;
+
     priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
     if (priv->handle < 0) {
         virXenErrorFunc(VIR_ERR_INTERNAL_ERROR, __FUNCTION__,
@@ -1453,8 +1453,7 @@ xenHypervisorSetSchedulerParameters(virDomainPtr domain,

             for (i = 0; i < nparams; i++) {
                 memset(&buf, 0, sizeof(buf));
-                if (STREQ (params[i].field, VIR_DOMAIN_SCHEDULER_WEIGHT) &&
-                    params[i].type == VIR_TYPED_PARAM_UINT) {
+                if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_WEIGHT)) {
                     val = params[i].value.ui;
                     if ((val < 1) || (val > USHRT_MAX)) {
                         snprintf(buf, sizeof(buf), _("Credit scheduler weight parameter (%d) is out of range (1-65535)"), val);
@@ -1462,8 +1461,7 @@ xenHypervisorSetSchedulerParameters(virDomainPtr domain,
                         return(-1);
                     }
                     op_dom.u.getschedinfo.u.credit.weight = val;
-                } else if (STREQ (params[i].field, VIR_DOMAIN_SCHEDULER_CAP) &&
-                    params[i].type == VIR_TYPED_PARAM_UINT) {
+                } else if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_CAP)) {
                     val = params[i].value.ui;
                     if (val >= USHRT_MAX) {
                         snprintf(buf, sizeof(buf), _("Credit scheduler cap parameter (%d) is out of range (0-65534)"), val);
@@ -1471,11 +1469,6 @@ xenHypervisorSetSchedulerParameters(virDomainPtr domain,
                         return(-1);
                     }
                     op_dom.u.getschedinfo.u.credit.cap = val;
-                } else {
-                    virXenErrorFunc(VIR_ERR_INVALID_ARG, __FUNCTION__,
-                                    "Credit scheduler accepts 'cap' and 'weight' integer parameters",
-                                    0);
-                    return(-1);
                 }
             }

-- 
1.7.7.5




More information about the libvir-list mailing list