On 2014/8/6 0:48, Maxime Leroy wrote:
This patch adds configuration support for the ivshmem device
as described in the schema in the previous patch.
Signed-off-by: Maxime Leroy <maxime.leroy(a)6wind.com>
---
src/conf/domain_conf.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 40 ++++++++
src/libvirt_private.syms | 4 +
3 files changed, 277 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c25c74b..829f1bf 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
[...]
/* This switch statement is here to trigger compiler warning when adding
* a new device type. When you are adding a new field to the switch you
@@ -2805,6 +2841,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_LAST:
case VIR_DOMAIN_DEVICE_RNG:
+ case VIR_DOMAIN_DEVICE_IVSHMEM:
break;
The function is good in logic. But I think it's better to keep VIR_DOMAIN_DEVICE_LAST
the last case. (Also case VIR_DOMAIN_DEVICE_RNG should be moved ahead of
case VIR_DOMAIN_DEVICE_LAST)
}
@@ -9354,6 +9391,124 @@ virDomainNVRAMDefParseXML(xmlNodePtr node,
return NULL;
}
+static virDomainIvshmemDefPtr
+virDomainIvshmemDefParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
+{
+ virDomainIvshmemDefPtr def;
+ char *use_server = NULL;
+ char *role = NULL;
+ char *ioeventfd = NULL;
+ char *vectors = NULL;
+ xmlNodePtr cur;
+ xmlNodePtr save = ctxt->node;
+
+ if (VIR_ALLOC(def) < 0)
+ return NULL;
+
+ use_server = virXMLPropString(node, "use_server");
+ if (use_server != NULL) {
+ if ((def->use_server
+ = virDomainIvshmemServerTypeFromString(use_server)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown ivshmem use_server tyoe '%s'"),
use_server);
s/tyoe/type
+ goto error;
+ }
+ } else {
+ virReportError(VIR_ERR_XML_ERROR,
+ "%s", _("missing use_server type"));
+ goto error;
+ }
+
[...]
@@ -10210,6 +10365,10 @@ virDomainDeviceDefParse(const char *xmlStr,
if (!(dev->data.nvram = virDomainNVRAMDefParseXML(node, flags)))
goto error;
break;
+ case VIR_DOMAIN_DEVICE_IVSHMEM:
+ if (!(dev->data.ivshmem = virDomainIvshmemDefParseXML(node, ctxt, flags)))
+ goto error;
+ break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LAST:
break;
@@ -13102,6 +13261,25 @@ virDomainDefParseXML(xmlDocPtr xml,
VIR_FREE(nodes);
}
+ /* analysis of the ivshmem devices */
+ if ((n = virXPathNodeSet("./devices/ivshmem", ctxt, &nodes)) < 0)
{
+ goto error;
+ }
+ if (n && VIR_ALLOC_N(def->ivshmems, n) < 0)
+ goto error;
+
+ node = ctxt->node;
+ for (i = 0; i < n; i++) {
+ virDomainIvshmemDefPtr ivshmem;
+ ctxt->node = nodes[i];
+ ivshmem = virDomainIvshmemDefParseXML(nodes[i], ctxt, flags);
+ if (!ivshmem)
+ goto error;
+
+ def->ivshmems[def->nivshmems++] = ivshmem;
+ }
+ ctxt->node = node;
+ VIR_FREE(nodes);
Here actions: node = ctxt->node; ctxt->node = nodes[i]; ctxt->node =
node;
I see other devices' xml parsing function virDomainXXXParseXML (such as
virDomainRNGDefParseXML).
These actions are in the function virDomainXXXparesXML().
So are the actions here are redundant? Or should be moved into
virDomainIvshmemDefParseXML.
/* analysis of the user namespace mapping */
if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
@@ -16701,6 +16879,55 @@ static int virDomainPanicDefFormat(virBufferPtr buf,
return 0;
}
+static int virDomainIvshmemDefFormat(virBufferPtr buf,
+ virDomainIvshmemDefPtr def,
+ unsigned int flags)
+{
+ const char *use_server = virDomainIvshmemServerTypeToString(def->use_server);
+ const char *role = virDomainIvshmemRoleTypeToString(def->role);
+
+ if (!use_server) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected ivshmem server %d"),
def->use_server);
+ return -1;
+ }
+
+ if (!role) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected ivshmem role %d"), def->role);
+ return -1;
+ }
+
+ virBufferAsprintf(buf, "<ivshmem use_server='%s'",
use_server);
+ if (def->role)
+ virBufferAsprintf(buf, " role='%s'", role);
+ virBufferAddLit(buf, ">\n");
def->role is type of int(ENUM). Do you want to check def->role is zero?
In other words, is role='default' illegal ?
+
+ virBufferAdjustIndent(buf, 2);
+ virBufferAsprintf(buf, "<source file='%s'/>\n",
def->file);
+ if (def->size)
+ virBufferAsprintf(buf, "<size
unit='M'>%llu</size>\n",
+ def->size / (1024 * 1024));
+
+ if (def->use_server == VIR_DOMAIN_IVSHMEM_SERVER_ENABLED &&
def->msi.enabled) {
+ virBufferAddLit(buf, "<msi");
+ if (def->msi.vectors)
+ virBufferAsprintf(buf, " vectors='%u'",
def->msi.vectors);
+ if (def->msi.ioeventfd)
+ virBufferAsprintf(buf, " ioeventfd='%s'",
+
virTristateSwitchTypeToString(def->msi.ioeventfd));
+ virBufferAddLit(buf, "/>\n");
+ }
+
+ if (virDomainDeviceInfoIsSet(&def->info, flags) &&
+ virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</ivshmem>\n");
+
+ return 0;
+}
+
static int
virDomainRNGDefFormat(virBufferPtr buf,
virDomainRNGDefPtr def,
@@ -18250,6 +18477,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virDomainPanicDefFormat(buf, def->panic) < 0)
goto error;
+ for (n = 0; n < def->nivshmems; n++)
+ if (virDomainIvshmemDefFormat(buf, def->ivshmems[n], flags) < 0)
+ goto error;
+
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</devices>\n");
@@ -19615,6 +19846,7 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
+ case VIR_DOMAIN_DEVICE_IVSHMEM:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Copying definition of '%d' type "
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bffc0a5..af499b4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -136,6 +136,9 @@ typedef virDomainPanicDef *virDomainPanicDefPtr;
typedef struct _virDomainChrSourceDef virDomainChrSourceDef;
typedef virDomainChrSourceDef *virDomainChrSourceDefPtr;
+typedef struct _virDomainIvshmemDef virDomainIvshmemDef;
+typedef virDomainIvshmemDef *virDomainIvshmemDefPtr;
+
/* Flags for the 'type' field in virDomainDeviceDef */
typedef enum {
VIR_DOMAIN_DEVICE_NONE = 0,
@@ -157,6 +160,7 @@ typedef enum {
VIR_DOMAIN_DEVICE_MEMBALLOON,
VIR_DOMAIN_DEVICE_NVRAM,
VIR_DOMAIN_DEVICE_RNG,
+ VIR_DOMAIN_DEVICE_IVSHMEM,
VIR_DOMAIN_DEVICE_LAST
} virDomainDeviceType;
@@ -184,6 +188,7 @@ struct _virDomainDeviceDef {
virDomainMemballoonDefPtr memballoon;
virDomainNVRAMDefPtr nvram;
virDomainRNGDefPtr rng;
+ virDomainIvshmemDefPtr ivshmem;
} data;
};
@@ -598,6 +603,22 @@ typedef enum {
VIR_DOMAIN_DISK_DISCARD_LAST
} virDomainDiskDiscard;
+typedef enum {
+ VIR_DOMAIN_IVSHMEM_SERVER_ENABLED = 0,
+ VIR_DOMAIN_IVSHMEM_SERVER_DISABLED,
+
+ VIR_DOMAIN_IVSHMEM_SERVER_LAST,
+} virDomainIvshmemServer;
+
+
+typedef enum {
+ VIR_DOMAIN_IVSHMEM_ROLE_DEFAULT = 0,
+ VIR_DOMAIN_IVSHMEM_ROLE_MASTER,
+ VIR_DOMAIN_IVSHMEM_ROLE_PEER,
+
+ VIR_DOMAIN_IVSHMEM_ROLE_LAST,
+} virDomainIvshmemRole;
+
typedef struct _virDomainBlockIoTuneInfo virDomainBlockIoTuneInfo;
struct _virDomainBlockIoTuneInfo {
unsigned long long total_bytes_sec;
@@ -1485,6 +1506,19 @@ struct _virDomainNVRAMDef {
virDomainDeviceInfo info;
};
+struct _virDomainIvshmemDef {
+ int use_server; /* enum virDomainIvshmemServer */
+ int role; /* virDomainIvshmemRole */
+ unsigned long long size;
+ char *file;
+ struct {
+ bool enabled;
+ unsigned vectors;
+ virTristateSwitch ioeventfd;
+ } msi;
+ virDomainDeviceInfo info;
+};
+
typedef enum {
VIR_DOMAIN_SMBIOS_NONE = 0,
VIR_DOMAIN_SMBIOS_EMULATE,
@@ -2006,6 +2040,9 @@ struct _virDomainDef {
size_t nrngs;
virDomainRNGDefPtr *rngs;
+ size_t nivshmems;
+ virDomainIvshmemDefPtr *ivshmems;
+
/* Only 1 */
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
@@ -2203,6 +2240,7 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
void virDomainHubDefFree(virDomainHubDefPtr def);
void virDomainRedirdevDefFree(virDomainRedirdevDefPtr def);
void virDomainRedirFilterDefFree(virDomainRedirFilterDefPtr def);
+void virDomainIvshmemDefFree(virDomainIvshmemDefPtr def);
void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
virDomainDeviceDefPtr virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
const virDomainDef *def,
@@ -2629,6 +2667,8 @@ VIR_ENUM_DECL(virDomainRNGModel)
VIR_ENUM_DECL(virDomainRNGBackend)
VIR_ENUM_DECL(virDomainTPMModel)
VIR_ENUM_DECL(virDomainTPMBackend)
+VIR_ENUM_DECL(virDomainIvshmemServer)
+VIR_ENUM_DECL(virDomainIvshmemRole)
/* from libvirt.h */
VIR_ENUM_DECL(virDomainState)
VIR_ENUM_DECL(virDomainNostateReason)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 08111d4..794f3dd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -300,6 +300,10 @@ virDomainHubTypeToString;
virDomainHypervTypeFromString;
virDomainHypervTypeToString;
virDomainInputDefFree;
+virDomainIvshmemRoleTypeFromString;
+virDomainIvshmemRoleTypeToString;
+virDomainIvshmemServerTypeFromString;
+virDomainIvshmemServerTypeToString;
virDomainLeaseDefFree;
virDomainLeaseIndex;
virDomainLeaseInsert;