mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
conf: Add support for RNG device configuration in XML
This patch adds basic configuration support for the RNG device supporting the virtio model with the "random" and "egd" backend types as described in the schema in the previous patch.
This commit is contained in:
parent
fa16c80f52
commit
e2a0dfcfe9
@ -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:
|
||||
@ -2342,6 +2355,12 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
|
||||
if (cb(def, &device, &def->memballoon->info, opaque) < 0)
|
||||
return -1;
|
||||
}
|
||||
if (def->rng) {
|
||||
device.type = VIR_DOMAIN_DEVICE_RNG;
|
||||
device.data.rng = def->rng;
|
||||
if (cb(def, &device, &def->rng->info, opaque) < 0)
|
||||
return -1;
|
||||
}
|
||||
device.type = VIR_DOMAIN_DEVICE_HUB;
|
||||
for (i = 0; i < def->nhubs ; i++) {
|
||||
device.data.hub = def->hubs[i];
|
||||
@ -2374,6 +2393,7 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
|
||||
case VIR_DOMAIN_DEVICE_CHR:
|
||||
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
||||
case VIR_DOMAIN_DEVICE_LAST:
|
||||
case VIR_DOMAIN_DEVICE_RNG:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -7452,6 +7472,110 @@ error:
|
||||
}
|
||||
|
||||
|
||||
static virDomainRNGDefPtr
|
||||
virDomainRNGDefParseXML(const xmlNodePtr node,
|
||||
xmlXPathContextPtr ctxt,
|
||||
unsigned int flags)
|
||||
{
|
||||
const char *model = NULL;
|
||||
const char *backend = NULL;
|
||||
const char *type = 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;
|
||||
}
|
||||
|
||||
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:
|
||||
if (!(type = virXMLPropString(backends[0], "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:
|
||||
VIR_FREE(model);
|
||||
VIR_FREE(backend);
|
||||
VIR_FREE(type);
|
||||
VIR_FREE(backends);
|
||||
ctxt->node = save;
|
||||
return def;
|
||||
|
||||
error:
|
||||
virDomainRNGDefFree(def);
|
||||
def = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
static virDomainMemballoonDefPtr
|
||||
virDomainMemballoonDefParseXML(const xmlNodePtr node,
|
||||
unsigned int flags)
|
||||
@ -8249,6 +8373,10 @@ 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"));
|
||||
@ -10603,6 +10731,22 @@ 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 RNG 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;
|
||||
@ -13625,6 +13769,63 @@ 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)
|
||||
virBufferEscapeString(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)
|
||||
@ -14818,6 +15019,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);
|
||||
@ -16088,6 +16292,9 @@ virDomainDeviceDefCopy(virCapsPtr caps,
|
||||
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
||||
rc = virDomainRedirdevDefFormat(&buf, src->data.redirdev, flags);
|
||||
break;
|
||||
case VIR_DOMAIN_DEVICE_RNG:
|
||||
rc = virDomainRNGDefFormat(&buf, src->data.rng, flags);
|
||||
break;
|
||||
case VIR_DOMAIN_DEVICE_NONE:
|
||||
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
||||
case VIR_DOMAIN_DEVICE_CHR:
|
||||
|
@ -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;
|
||||
@ -2065,6 +2098,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);
|
||||
@ -2325,6 +2360,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)
|
||||
|
@ -286,6 +286,8 @@ virDomainPMSuspendedReasonTypeFromString;
|
||||
virDomainPMSuspendedReasonTypeToString;
|
||||
virDomainRedirdevBusTypeFromString;
|
||||
virDomainRedirdevBusTypeToString;
|
||||
virDomainRNGBackendTypeToString;
|
||||
virDomainRNGModelTypeToString;
|
||||
virDomainRunningReasonTypeFromString;
|
||||
virDomainRunningReasonTypeToString;
|
||||
virDomainSaveConfig;
|
||||
|
Loading…
Reference in New Issue
Block a user