[libvirt] [RFC PATCH 2/5] conf: Parse and format ivshmem device XML

Wang Rui moon.wangrui at huawei.com
Wed Aug 6 09:30:51 UTC 2014


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 at 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;





More information about the libvir-list mailing list