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; > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list