[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