[libvirt] [PATCH 3/4] conf: Add basic support for RNG configuration

Peter Krempa pkrempa at redhat.com
Fri Jan 11 17:00:43 UTC 2013


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




More information about the libvir-list mailing list