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(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f4875f5..cd52c17 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -166,7 +166,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",
@@ -692,6 +693,16 @@ VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode,
"static",
"auto");
+VIR_ENUM_IMPL(virDomainRNGModel,
+ VIR_DOMAIN_RNG_MODEL_LAST,
+ "none",
+ "virtio");
+
+VIR_ENUM_IMPL(virDomainRNGSource,
+ VIR_DOMAIN_RNG_SOURCE_LAST,
+ "none",
+ "random");
+
#define VIR_DOMAIN_XML_WRITE_FLAGS VIR_DOMAIN_XML_SECURE
#define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE
@@ -1562,6 +1573,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:
@@ -7185,6 +7199,76 @@ error:
}
+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:
+ case VIR_DOMAIN_RNG_SOURCE_LAST:
+ /* don't configure anything */
+ break;
+
+ case VIR_DOMAIN_RNG_SOURCE_RANDOM:
+ def->address = virXPathString("string(./source)", ctxt);
+ 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)
@@ -7959,6 +8043,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"));
@@ -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"));
+ 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;
@@ -13371,6 +13475,45 @@ virDomainWatchdogDefFormat(virBufferPtr buf,
}
+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);
+ else
+ virBufferAddLit(buf, "/>\n");
+
+ break;
+ }
+ virBufferAddLit(buf, " </rng>\n");
+
+ return 0;
+}
+
+void
+virDomainRNGDefFree(virDomainRNGDefPtr def)
+{
+ if (!def)
+ return;
+
+ VIR_FREE(def->address);
+ VIR_FREE(def->service);
+}
+
static void
virDomainVideoAccelDefFormat(virBufferPtr buf,
virDomainVideoAccelDefPtr def)
@@ -14567,6 +14710,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->memballoon)
virDomainMemballoonDefFormat(buf, def->memballoon, flags);
+ if (def->rng)
+ virDomainRNGDefFormat(buf, def->rng);
+
virBufferAddLit(buf, " </devices>\n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 2ac338c..2872932 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -115,6 +115,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,
@@ -134,6 +137,7 @@ typedef enum {
VIR_DOMAIN_DEVICE_SMARTCARD,
VIR_DOMAIN_DEVICE_CHR,
VIR_DOMAIN_DEVICE_MEMBALLOON,
+ VIR_DOMAIN_DEVICE_RNG,
VIR_DOMAIN_DEVICE_LAST
} virDomainDeviceType;
@@ -159,6 +163,7 @@ struct _virDomainDeviceDef {
virDomainSmartcardDefPtr smartcard;
virDomainChrDefPtr chr;
virDomainMemballoonDefPtr memballoon;
+ virDomainRNGDefPtr rng;
} data;
};
@@ -1699,6 +1704,32 @@ struct _virBlkioDeviceWeight {
unsigned int weight;
};
+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, */
+
+ VIR_DOMAIN_RNG_SOURCE_LAST
+};
+
+struct _virDomainRNGDef {
+ int model;
+ int source;
+
+ char *address; /* file name/socket name/pool name/address */
+ char *service; /* port, class name */
+
+ virDomainDeviceInfo info;
+};
+
void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
int ndevices);
@@ -1837,6 +1868,7 @@ struct _virDomainDef {
virCPUDefPtr cpu;
virSysinfoDefPtr sysinfo;
virDomainRedirFilterDefPtr redirfilter;
+ virDomainRNGDefPtr rng;
void *namespaceData;
virDomainXMLNamespace ns;
@@ -2050,6 +2082,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);
@@ -2307,6 +2341,8 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
VIR_ENUM_DECL(virDomainNumatuneMemMode)
VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
VIR_ENUM_DECL(virDomainHyperv)
+VIR_ENUM_DECL(virDomainRNGModel)
+VIR_ENUM_DECL(virDomainRNGSource)
/* from libvirt.h */
VIR_ENUM_DECL(virDomainState)
VIR_ENUM_DECL(virDomainNostateReason)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7be58ee..48ba631 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -496,6 +496,8 @@ virDomainPMStateTypeToString;
virDomainRedirdevBusTypeFromString;
virDomainRedirdevBusTypeToString;
virDomainRemoveInactive;
+virDomainRNGModelTypeToString;
+virDomainRNGSourceTypeToString;
virDomainRunningReasonTypeFromString;
virDomainRunningReasonTypeToString;
virDomainSaveConfig;
--
1.8.1