On 01/11/2013 10:00 AM, Peter Krempa wrote:
This patch adds basic configuration support for the RNG device
suporting
the virtio model with the "random" backend type.
---
src/conf/domain_conf.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 36 ++++++++++++
src/libvirt_private.syms | 2 +
3 files changed, 185 insertions(+), 1 deletion(-)
We're post-freeze before I reviewed this; on the other hand, I don't
think that adding it now could cause too many issues. So unless anyone
else speaks up in the next 24 hours, I think I could live with this
making it into 1.0.2. Then again, I have enough comments on the series
that it will be worth a v2.
+VIR_ENUM_IMPL(virDomainRNGModel,
+ VIR_DOMAIN_RNG_MODEL_LAST,
+ "none",
+ "virtio");
As in 1/4, I don't think we need this one, or at least, we don't need
the 'none' value. As long as 'virtio' is the only model we support, we
may not even need the model='xxx' attribute. It boils down to a
question of future growth - will it be easier to have model='virtio' now
and add a new model='foo' when (if?) we finally introduce a counterpart
model, or would it be easier to not have model= at all for now, and add
'model=virtio|foo' later on where a missing model defaults to virtio at
that time.
+
+VIR_ENUM_IMPL(virDomainRNGSource,
+ VIR_DOMAIN_RNG_SOURCE_LAST,
+ "none",
+ "random");
This one is fine.
+static virDomainRNGDefPtr
+virDomainRNGDefParseXML(const xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
+{
+ const char *model;
+ const char *source;
+ virDomainRNGDefPtr def;
+ xmlNodePtr save = ctxt->node;
+ xmlNodePtr *sources = NULL;
+ int nsources;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ if (!(model = virXMLPropString(node, "model")))
+ model = "none";
+
+ if ((def->model = virDomainRNGModelTypeFromString(model)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, _("unknown RNG model '%s'"),
model);
+ goto error;
+ }
+
+ ctxt->node = node;
+
+ if ((nsources = virXPathNodeSet("./source", ctxt, &sources)) < 0)
+ goto error;
+
+ if (nsources > 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one RNG source is supported"));
+ goto error;
+ }
+
+ if (nsources == 1 &&
+ (source = virXMLPropString(sources[0], "type"))) {
+ if ((def->source = virDomainRNGSourceTypeFromString(source)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unknown RNG source type '%s'"),
source);
+ goto error;
+ }
+
+ switch ((enum virDomainRNGSource) def->source) {
+ case VIR_DOMAIN_RNG_SOURCE_NONE:
If the user specified <rng><source
type='none'>/path/to/file</source></rng>, should we error out that
a
file name is incompatible with type='none'?
@@ -10309,6 +10397,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"));
Too much copy and paste in this error message.
+static int
+virDomainRNGDefFormat(virBufferPtr buf,
+ virDomainRNGDefPtr def)
+{
+ const char *model = virDomainRNGModelTypeToString(def->model);
+ const char *source = virDomainRNGSourceTypeToString(def->source);
+
+ virBufferAsprintf(buf, " <rng model='%s'>\n", model);
+ virBufferAsprintf(buf, " <source type='%s'", source);
+
+ switch ((enum virDomainRNGSource) def->source) {
+ case VIR_DOMAIN_RNG_SOURCE_LAST:
+ case VIR_DOMAIN_RNG_SOURCE_NONE:
+ virBufferAddLit(buf, "/>\n");
+ break;
+
+ case VIR_DOMAIN_RNG_SOURCE_RANDOM:
+ if (def->address)
+ virBufferAsprintf(buf, ">%s</source>\n",
def->address);
You must use virBufferEscape(), as this is a user-supplied file name
which might contain characters that would mess up valid XML if not
escaped properly.
+void
+virDomainRNGDefFree(virDomainRNGDefPtr def)
+{
+ if (!def)
+ return;
+
+ VIR_FREE(def->address);
+ VIR_FREE(def->service);
We don't set def->service; why are we freeing it? Save that field for a
patch that actually extends the XML to use it.
+++ b/src/conf/domain_conf.h
@@ -115,6 +115,9 @@ typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;
typedef struct _virDomainSnapshotObjList virDomainSnapshotObjList;
typedef virDomainSnapshotObjList *virDomainSnapshotObjListPtr;
+enum virDomainRNGModel {
+ VIR_DOMAIN_RNG_MODEL_NONE,
+ VIR_DOMAIN_RNG_MODEL_VIRTIO,
+
+ VIR_DOMAIN_RNG_MODEL_LAST
+};
+
+enum virDomainRNGSource {
+ VIR_DOMAIN_RNG_SOURCE_NONE,
+ VIR_DOMAIN_RNG_SOURCE_RANDOM,
+ /* VIR_DOMAIN_RNG_SOURCE_EGD, */
+ /* VIR_DOMAIN_RNG_SOURCE_POOL, */
Ah, I see where you plan to add future source types. Comments here are
okay (as a hint about future development)...
+
+ VIR_DOMAIN_RNG_SOURCE_LAST
+};
+
+struct _virDomainRNGDef {
+ int model;
+ int source;
Add /* virDomainRNGSource */, to make it obvious what this int will hold.
+
+ char *address; /* file name/socket name/pool name/address */
+ char *service; /* port, class name */
...but service seems like an unused field, and probably doesn't make
sense to add until you actually implement those future source types.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org