[libvirt] [PATCH 2/6] conf: Add support for RNG device configuration in XML

John Ferlan jferlan at redhat.com
Tue Feb 19 13:20:19 UTC 2013


On 02/13/2013 05:59 AM, Peter Krempa wrote:
> This patch adds basic configuration support for the RNG device suporting
> the virtio model with the "random" and "egd" backend types as described
> in the schema in the previous patch.
> ---
>  src/conf/domain_conf.c   | 196 ++++++++++++++++++++++++++++++++++++++++++++++-
>  src/conf/domain_conf.h   |  37 +++++++++
>  src/libvirt_private.syms |   2 +
>  3 files changed, 234 insertions(+), 1 deletion(-)
> 
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 7a2b012..a16d70b 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -175,7 +175,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
>                "redirdev",
>                "smartcard",
>                "chr",
> -              "memballoon")
> +              "memballoon",
> +              "rng")
> 
>  VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
>                "none",
> @@ -700,6 +701,15 @@ VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode,
>                "static",
>                "auto");
> 
> +VIR_ENUM_IMPL(virDomainRNGModel,
> +              VIR_DOMAIN_RNG_MODEL_LAST,
> +              "virtio");
> +
> +VIR_ENUM_IMPL(virDomainRNGBackend,
> +              VIR_DOMAIN_RNG_BACKEND_LAST,
> +              "random",
> +              "egd");
> +
>  #define VIR_DOMAIN_XML_WRITE_FLAGS  VIR_DOMAIN_XML_SECURE
>  #define VIR_DOMAIN_XML_READ_FLAGS   VIR_DOMAIN_XML_INACTIVE
> 
> @@ -1597,6 +1607,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
>      case VIR_DOMAIN_DEVICE_REDIRDEV:
>          virDomainRedirdevDefFree(def->data.redirdev);
>          break;
> +    case VIR_DOMAIN_DEVICE_RNG:
> +        virDomainRNGDefFree(def->data.rng);
> +        break;
>      case VIR_DOMAIN_DEVICE_NONE:
>      case VIR_DOMAIN_DEVICE_FS:
>      case VIR_DOMAIN_DEVICE_SMARTCARD:
> @@ -7403,6 +7416,109 @@ error:
>  }
> 
> 
> +static virDomainRNGDefPtr
> +virDomainRNGDefParseXML(const xmlNodePtr node,
> +                        xmlXPathContextPtr ctxt,
> +                        unsigned int flags)
> +{
> +    const char *model;
> +    const char *backend;

Init to NULL

> +    virDomainRNGDefPtr def;
> +    xmlNodePtr save = ctxt->node;
> +    xmlNodePtr *backends = NULL;
> +    int nbackends;
> +
> +    if (VIR_ALLOC(def) < 0) {
> +        virReportOOMError();
> +        return NULL;
> +    }
> +
> +    if (!(model = virXMLPropString(node, "model"))) {
> +        virReportError(VIR_ERR_XML_ERROR, "%s", _("missing RNG device model"));
> +        goto error;
> +    }
model needs a VIR_FREE, right?

> +
> +    if ((def->model = virDomainRNGModelTypeFromString(model)) < 0) {
> +        virReportError(VIR_ERR_XML_ERROR, _("unknown RNG model '%s'"), model);
> +        goto error;
> +    }
> +
> +    ctxt->node = node;
> +
> +    if ((nbackends = virXPathNodeSet("./backend", ctxt, &backends)) < 0)
> +        goto error;
> +
> +    if (nbackends != 1) {
> +        virReportError(VIR_ERR_XML_ERROR, "%s",
> +                       _("only one RNG backend is supported"));
> +        goto error;
> +    }
Does there need to be a specific/different message if nbackends == 0?

> +
> +    if (!(backend = virXMLPropString(backends[0], "model"))) {
> +        virReportError(VIR_ERR_XML_ERROR, "%s",
> +                       _("missing RNG device backend model"));
> +        goto error;
> +    }
backend needs a VIR_FREE too, right?

> +
> +    if ((def->backend = virDomainRNGBackendTypeFromString(backend)) < 0) {
> +        virReportError(VIR_ERR_XML_ERROR,
> +                       _("unknown RNG backend model '%s'"), backend);
> +        goto error;
> +    }
> +
> +    switch ((enum virDomainRNGBackend) def->backend) {
> +    case VIR_DOMAIN_RNG_BACKEND_RANDOM:
> +        def->source.file = virXPathString("string(./backend)", ctxt);
> +        break;
> +
> +    case VIR_DOMAIN_RNG_BACKEND_EGD:
> +        {
> +            char *type = virXMLPropString(backends[0], "type");
> +            if (!type) {
> +                virReportError(VIR_ERR_XML_ERROR, "%s",
> +                               _("missing EGD backend type"));
> +                goto error;
> +            }
type needs a VIR_FREE, right?
> +
> +
> +            if (VIR_ALLOC(def->source.chardev) < 0) {
> +                virReportOOMError();
> +                goto error;
> +            }
> +
> +            def->source.chardev->type = virDomainChrTypeFromString(type);
> +            if (def->source.chardev->type < 0) {
> +                virReportError(VIR_ERR_XML_ERROR,
> +                               _("unknown backend type '%s' for egd"),
> +                               type);
> +                goto error;
> +            }
> +
> +            if (virDomainChrSourceDefParseXML(def->source.chardev,
> +                                              backends[0]->children, flags,
> +                                              NULL, ctxt, NULL, 0) < 0)
> +                goto error;
> +        }
> +        break;
> +
> +    case VIR_DOMAIN_RNG_BACKEND_LAST:
> +        break;
> +    }
> +
> +    if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
> +        goto error;
> +
> +cleanup:
> +    ctxt->node = save;
> +    return def;
> +
> +error:
> +    virDomainRNGDefFree(def);
> +    def = NULL;
> +    goto cleanup;
> +}
> +
> +
>  static virDomainMemballoonDefPtr
>  virDomainMemballoonDefParseXML(const xmlNodePtr node,
>                                 unsigned int flags)
> @@ -8196,6 +8312,10 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
>          dev->type = VIR_DOMAIN_DEVICE_REDIRDEV;
>          if (!(dev->data.redirdev = virDomainRedirdevDefParseXML(node, NULL, flags)))
>              goto error;
> +    } else if (xmlStrEqual(node->name, BAD_CAST "rng")) {
> +        dev->type = VIR_DOMAIN_DEVICE_RNG;
> +        if (!(dev->data.rng = virDomainRNGDefParseXML(node, ctxt, flags)))
> +            goto error;
>      } else {
>          virReportError(VIR_ERR_XML_ERROR,
>                         "%s", _("unknown device type"));
> @@ -10552,6 +10672,22 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
>          }
>      }
> 
> +    /* Parse the RNG device */
> +    if ((n = virXPathNodeSet("./devices/rng", ctxt, &nodes)) < 0)
> +        goto error;
> +
> +    if (n > 1) {
> +        virReportError(VIR_ERR_XML_ERROR, "%s",
> +                       _("only a single memory balloon device is supported"));
Looks like a cut-n-paste error      ^^^^^^^^^^^^^^^^^^^^^

> +        goto error;
> +    }
> +
> +    if (n > 0) {
> +        if (!(def->rng = virDomainRNGDefParseXML(nodes[0], ctxt, flags)))
> +            goto error;
> +        VIR_FREE(nodes);
> +    }
> +
>      /* analysis of the hub devices */
>      if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) {
>          goto error;
> @@ -13614,6 +13750,61 @@ virDomainWatchdogDefFormat(virBufferPtr buf,
>  }
> 
> 
> +static int
> +virDomainRNGDefFormat(virBufferPtr buf,
> +                      virDomainRNGDefPtr def,
> +                      unsigned int flags)
> +{
> +    const char *model = virDomainRNGModelTypeToString(def->model);
> +    const char *backend = virDomainRNGBackendTypeToString(def->backend);
> +
> +    virBufferAsprintf(buf, "    <rng model='%s'>\n", model);
> +    virBufferAsprintf(buf, "      <backend model='%s'", backend);
> +
> +    switch ((enum virDomainRNGBackend) def->backend) {
> +    case VIR_DOMAIN_RNG_BACKEND_RANDOM:
> +        if (def->source.file)
> +            virBufferAsprintf(buf, ">%s</backend>\n", def->source.file);
> +        else
> +            virBufferAddLit(buf, "/>\n");
> +
> +        break;
> +
> +    case VIR_DOMAIN_RNG_BACKEND_EGD:
> +        virBufferAdjustIndent(buf, 2);
> +        if (virDomainChrSourceDefFormat(buf, def->source.chardev,
> +                                        false, flags) < 0)
> +            return -1;
> +        virBufferAdjustIndent(buf, -2);
> +        virBufferAddLit(buf, "      </backend>\n");
> +
> +    case VIR_DOMAIN_RNG_BACKEND_LAST:
> +        break;
> +    }
> +
> +    virBufferAddLit(buf, "    </rng>\n");
> +
> +    return 0;
> +}
> +
> +void
> +virDomainRNGDefFree(virDomainRNGDefPtr def)
> +{
> +    if (!def)
> +        return;
> +
> +    switch ((enum virDomainRNGBackend) def->backend) {
> +    case VIR_DOMAIN_RNG_BACKEND_RANDOM:
> +        VIR_FREE(def->source.file);
> +        break;
> +    case VIR_DOMAIN_RNG_BACKEND_EGD:
> +        virDomainChrSourceDefFree(def->source.chardev);
> +        break;
> +    case VIR_DOMAIN_RNG_BACKEND_LAST:
> +        break;
> +    }

VIR_FREE(def);

> +}
> +
>  static void
>  virDomainVideoAccelDefFormat(virBufferPtr buf,
>                               virDomainVideoAccelDefPtr def)
> @@ -14812,6 +15003,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
>      if (def->memballoon)
>          virDomainMemballoonDefFormat(buf, def->memballoon, flags);
> 
> +    if (def->rng)
> +        virDomainRNGDefFormat(buf, def->rng, flags);
> +
>      virBufferAddLit(buf, "  </devices>\n");
> 
>      virBufferAdjustIndent(buf, 2);
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 9232ff9..b78a04c 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -114,6 +114,9 @@ typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;
>  typedef struct _virDomainSnapshotObjList virDomainSnapshotObjList;
>  typedef virDomainSnapshotObjList *virDomainSnapshotObjListPtr;
> 
> +typedef struct _virDomainRNGDef virDomainRNGDef;
> +typedef virDomainRNGDef *virDomainRNGDefPtr;
> +
>  /* Flags for the 'type' field in virDomainDeviceDef */
>  typedef enum {
>      VIR_DOMAIN_DEVICE_NONE = 0,
> @@ -133,6 +136,7 @@ typedef enum {
>      VIR_DOMAIN_DEVICE_SMARTCARD,
>      VIR_DOMAIN_DEVICE_CHR,
>      VIR_DOMAIN_DEVICE_MEMBALLOON,
> +    VIR_DOMAIN_DEVICE_RNG,
> 
>      VIR_DOMAIN_DEVICE_LAST
>  } virDomainDeviceType;
> @@ -158,6 +162,7 @@ struct _virDomainDeviceDef {
>          virDomainSmartcardDefPtr smartcard;
>          virDomainChrDefPtr chr;
>          virDomainMemballoonDefPtr memballoon;
> +        virDomainRNGDefPtr rng;
>      } data;
>  };
> 
> @@ -1714,6 +1719,33 @@ struct _virBlkioDeviceWeight {
>      unsigned int weight;
>  };
> 
> +enum virDomainRNGModel {
> +    VIR_DOMAIN_RNG_MODEL_VIRTIO,
> +
> +    VIR_DOMAIN_RNG_MODEL_LAST
> +};
> +
> +enum virDomainRNGBackend {
> +    VIR_DOMAIN_RNG_BACKEND_RANDOM,
> +    VIR_DOMAIN_RNG_BACKEND_EGD,
> +    /* VIR_DOMAIN_RNG_BACKEND_POOL, */
> +
> +    VIR_DOMAIN_RNG_BACKEND_LAST
> +};
> +
> +struct _virDomainRNGDef {
> +    int model;
> +    int backend;
> +
> +    union {
> +        char *file; /* file name for 'random' source */
> +        virDomainChrSourceDefPtr chardev; /* a char backend for
> +                                             the EGD source */
> +    } source;
> +
> +    virDomainDeviceInfo info;
> +};
> +
>  void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
>                                      int ndevices);
> 
> @@ -1852,6 +1884,7 @@ struct _virDomainDef {
>      virCPUDefPtr cpu;
>      virSysinfoDefPtr sysinfo;
>      virDomainRedirFilterDefPtr redirfilter;
> +    virDomainRNGDefPtr rng;
> 
>      void *namespaceData;
>      virDomainXMLNamespace ns;
> @@ -2062,6 +2095,8 @@ int virDomainEmulatorPinAdd(virDomainDefPtr def,
> 
>  int virDomainEmulatorPinDel(virDomainDefPtr def);
> 
> +void virDomainRNGDefFree(virDomainRNGDefPtr def);
> +
>  int virDomainDiskIndexByName(virDomainDefPtr def, const char *name,
>                               bool allow_ambiguous);
>  const char *virDomainDiskPathByName(virDomainDefPtr, const char *name);
> @@ -2322,6 +2357,8 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
>  VIR_ENUM_DECL(virDomainNumatuneMemMode)
>  VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
>  VIR_ENUM_DECL(virDomainHyperv)
> +VIR_ENUM_DECL(virDomainRNGModel)
> +VIR_ENUM_DECL(virDomainRNGBackend)
>  /* from libvirt.h */
>  VIR_ENUM_DECL(virDomainState)
>  VIR_ENUM_DECL(virDomainNostateReason)
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index b9d45a2..814e66f 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -498,6 +498,8 @@ virDomainPMSuspendedReasonTypeFromString;
>  virDomainPMSuspendedReasonTypeToString;
>  virDomainRedirdevBusTypeFromString;
>  virDomainRedirdevBusTypeToString;
> +virDomainRNGBackendTypeToString;
> +virDomainRNGModelTypeToString;
>  virDomainRunningReasonTypeFromString;
>  virDomainRunningReasonTypeToString;
>  virDomainSaveConfig;
> 




More information about the libvir-list mailing list