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; + 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; + } + + 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; + } + + if (!(backend = virXMLPropString(backends[0], "model"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing RNG device backend model")); + goto error; + } + + 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; + } + + + 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")); + 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; + } +} + 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; -- 1.8.1.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list