[libvirt] PATCH: Work in progress suport for video device config

Pritesh Kothari Pritesh.Kothari at Sun.COM
Tue May 19 12:51:07 UTC 2009


On Tuesday 19 May 2009 11:35:40 Daniel P. Berrange wrote:
> We discussed adding a new XML element for representing video devices a
> few weeks back. This is my work in progress patch for the XML parsing
> routines supporting
>
>    <video>
>      <model type='vga|cirrus|vmvga|xen' vram='64' heads='1'/>
>    </video>
>
>
> For compatability, if an existing guest has a <graphics> tag, but no
> <video> tag, then the parser automatically adds a <video> tag for
> type=cirrus. Still todo
>
>  - Tweak the addition of default <video> tag a little so it uses the
>    correct type for the type of guest - eg it should use type=xen in
>    some cases.
>  - Add RNG XML schemas & website docs
>  - Make QEMU driver use this info for setting -vga argument
>  - Make Xen drivers use this info for setting stdvga=1|0 config arg
>  - Make VirtualBox use this info in whatever way it needs
>
> Daniel
>
>  domain_conf.c |  168
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ domain_conf.h | 
>  26 ++++++++
>  2 files changed, 194 insertions(+)
>
>
> diff -r 66fa9bfc797c src/domain_conf.c
> --- a/src/domain_conf.c	Mon May 18 11:28:46 2009 +0100
> +++ b/src/domain_conf.c	Mon May 18 11:29:00 2009 +0100
> @@ -80,6 +80,7 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAI
>                "interface",
>                "input",
>                "sound",
> +              "video",
>                "hostdev")
>
>  VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
> @@ -140,6 +141,12 @@ VIR_ENUM_IMPL(virDomainSoundModel, VIR_D
>                "pcspk",
>                "ac97")
>
> +VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
> +              "vga",
> +              "cirrus",
> +              "vmvga",
> +              "xen")
> +
>  VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
>                "mouse",
>                "tablet")
> @@ -372,6 +379,14 @@ void virDomainSoundDefFree(virDomainSoun
>      VIR_FREE(def);
>  }
>
> +void virDomainVideoDefFree(virDomainVideoDefPtr def)
> +{
> +    if (!def)
> +        return;
> +
> +    VIR_FREE(def);
> +}
> +
>  void virDomainHostdevDefFree(virDomainHostdevDefPtr def)
>  {
>      if (!def)
> @@ -399,6 +414,9 @@ void virDomainDeviceDefFree(virDomainDev
>      case VIR_DOMAIN_DEVICE_SOUND:
>          virDomainSoundDefFree(def->data.sound);
>          break;
> +    case VIR_DOMAIN_DEVICE_VIDEO:
> +        virDomainVideoDefFree(def->data.video);
> +        break;
>      case VIR_DOMAIN_DEVICE_HOSTDEV:
>          virDomainHostdevDefFree(def->data.hostdev);
>          break;
> @@ -456,6 +474,10 @@ void virDomainDefFree(virDomainDefPtr de
>          virDomainSoundDefFree(def->sounds[i]);
>      VIR_FREE(def->sounds);
>
> +    for (i = 0 ; i < def->nvideos ; i++)
> +        virDomainVideoDefFree(def->videos[i]);
> +    VIR_FREE(def->videos);
> +
>      for (i = 0 ; i < def->nhostdevs ; i++)
>          virDomainHostdevDefFree(def->hostdevs[i]);
>      VIR_FREE(def->hostdevs);
> @@ -1638,6 +1660,84 @@ error:
>      goto cleanup;
>  }
>
> +static virDomainVideoDefPtr
> +virDomainVideoDefParseXML(virConnectPtr conn,
> +                          const xmlNodePtr node,
> +                          int flags ATTRIBUTE_UNUSED) {
> +    virDomainVideoDefPtr def;
> +    xmlNodePtr cur;
> +    char *type = NULL;
> +    char *heads = NULL;
> +    char *vram = NULL;
> +
> +    if (VIR_ALLOC(def) < 0) {
> +        virReportOOMError(conn);
> +        return NULL;
> +    }
> +
> +    cur = node->children;
> +    while (cur != NULL) {
> +        if (cur->type == XML_ELEMENT_NODE) {
> +            if ((type == NULL) && (vram == NULL) && (heads == NULL) &&
> +                xmlStrEqual(cur->name, BAD_CAST "model")) {
> +                type = virXMLPropString(cur, "type");
> +                vram = virXMLPropString(cur, "vram");
> +                heads = virXMLPropString(cur, "heads");
> +            }
> +        }
> +        cur = cur->next;
> +    }
> +
> +    if (type &&
> +        (def->type = virDomainVideoTypeFromString(type)) < 0) {
> +        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                             _("unknown video model '%s'"), type);
> +        goto error;
> +    }
> +
> +    if (vram &&
> +        virStrToLong_ui(vram, NULL, 10, &def->vram) < 0) {
> +        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                             _("cannot parse video ram '%s'"), vram);
> +        goto error;
> +    } else {
> +        switch (def->type) {
> +            /* Wierd, QEMU defaults to 9 MB ??! */
> +        case VIR_DOMAIN_VIDEO_TYPE_VGA:

in case of vbox this defaults to 8MB any way of handling that here?

> +        case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
> +        case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
> +            def->vram = 9 * 1024;
> +            break;
> +        case VIR_DOMAIN_VIDEO_TYPE_XEN:
> +            /* Original PVFB hardcoded to 4 MB */
> +            def->vram = 4 * 1024;
> +            break;
> +        }
> +    }
> +
> +    if (heads &&
> +        virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
> +        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                             _("cannot parse video heads '%s'"), heads);
> +        goto error;
> +    } else {
> +        def->heads = 1;
> +    }
> +
> +    VIR_FREE(type);
> +    VIR_FREE(vram);
> +    VIR_FREE(heads);
> +
> +    return def;
> +
> +error:
> +    virDomainVideoDefFree(def);
> +    VIR_FREE(type);
> +    VIR_FREE(vram);
> +    VIR_FREE(heads);
> +    return NULL;
> +}
> +
>  static int
>  virDomainHostdevSubsysUsbDefParseXML(virConnectPtr conn,
>                                       const xmlNodePtr node,
> @@ -2064,6 +2164,10 @@ virDomainDeviceDefPtr virDomainDeviceDef
>          dev->type = VIR_DOMAIN_DEVICE_SOUND;
>          if (!(dev->data.sound = virDomainSoundDefParseXML(conn, node,
> flags))) goto error;
> +    } else if (xmlStrEqual(node->name, BAD_CAST "video")) {
> +        dev->type = VIR_DOMAIN_DEVICE_VIDEO;
> +        if (!(dev->data.video = virDomainVideoDefParseXML(conn, node,
> flags))) +            goto error;
>      } else if (xmlStrEqual(node->name, BAD_CAST "hostdev")) {
>          dev->type = VIR_DOMAIN_DEVICE_HOSTDEV;
>          if (!(dev->data.hostdev = virDomainHostdevDefParseXML(conn, node,
> flags))) @@ -2584,6 +2688,40 @@ static virDomainDefPtr virDomainDefParse
>      }
>      VIR_FREE(nodes);
>
> +    /* analysis of the video devices */
> +    if ((n = virXPathNodeSet(conn, "./devices/video", ctxt, &nodes)) < 0)
> { +        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                             "%s", _("cannot extract video devices"));
> +        goto error;
> +    }
> +    if (n && VIR_ALLOC_N(def->videos, n) < 0)
> +        goto no_memory;
> +    for (i = 0 ; i < n ; i++) {
> +        virDomainVideoDefPtr video = virDomainVideoDefParseXML(conn,
> +                                                               nodes[i],
> +                                                               flags);
> +        if (!video)
> +            goto error;
> +        def->videos[def->nvideos++] = video;
> +    }
> +    VIR_FREE(nodes);
> +
> +    /* For backwards compatability, if no <video> tag is set but there
> +     * is a <graphics> tag, then we add a single video tag */
> +    if (def->ngraphics && !def->nvideos) {
> +        virDomainVideoDefPtr video;
> +        if (VIR_ALLOC(video) < 0)
> +            goto no_memory;
> +        video->type = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
> +        video->vram = 9 * 1024;
> +        video->heads = 1;
> +        if (VIR_ALLOC_N(def->videos, 1) < 0) {
> +            virDomainVideoDefFree(video);
> +            goto no_memory;
> +        }
> +        def->videos[def->nvideos++] = video;
> +    }
> +
>      /* analysis of the host devices */
>      if ((n = virXPathNodeSet(conn, "./devices/hostdev", ctxt, &nodes)) <
> 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
> @@ -3286,6 +3424,32 @@ virDomainSoundDefFormat(virConnectPtr co
>  }
>
>  static int
> +virDomainVideoDefFormat(virConnectPtr conn,
> +                        virBufferPtr buf,
> +                        virDomainVideoDefPtr def)
> +{
> +    const char *model = virDomainVideoTypeToString(def->type);
> +
> +    if (!model) {
> +        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                             _("unexpected video model %d"), def->type);
> +        return -1;
> +    }
> +
> +    virBufferAddLit(buf, "    <video>\n");
> +    virBufferVSprintf(buf, "      <model type='%s'",
> +                      model);
> +    if (def->vram)
> +        virBufferVSprintf(buf, " vram='%u'", def->vram);
> +    if (def->heads)
> +        virBufferVSprintf(buf, " heads='%u'", def->heads);
> +    virBufferAddLit(buf, "/>\n");
> +    virBufferAddLit(buf, "    </video>\n");
> +
> +    return 0;
> +}
> +
> +static int
>  virDomainInputDefFormat(virConnectPtr conn,
>                          virBufferPtr buf,
>                          virDomainInputDefPtr def)
> @@ -3660,6 +3824,10 @@ char *virDomainDefFormat(virConnectPtr c
>          if (virDomainSoundDefFormat(conn, &buf, def->sounds[n]) < 0)
>              goto cleanup;
>
> +    for (n = 0 ; n < def->nvideos ; n++)
> +        if (virDomainVideoDefFormat(conn, &buf, def->videos[n]) < 0)
> +            goto cleanup;
> +
>      for (n = 0 ; n < def->nhostdevs ; n++)
>          if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0)
>              goto cleanup;
> diff -r 66fa9bfc797c src/domain_conf.h
> --- a/src/domain_conf.h	Mon May 18 11:28:46 2009 +0100
> +++ b/src/domain_conf.h	Mon May 18 11:29:00 2009 +0100
> @@ -264,6 +264,25 @@ struct _virDomainSoundDef {
>      int model;
>  };
>
> +
> +enum virDomainVideoType {
> +    VIR_DOMAIN_VIDEO_TYPE_VGA,
> +    VIR_DOMAIN_VIDEO_TYPE_CIRRUS,
> +    VIR_DOMAIN_VIDEO_TYPE_VMVGA,
> +    VIR_DOMAIN_VIDEO_TYPE_XEN,

can we add  VIR_DOMAIN_VIDEO_TYPE_VBOX as well here, cause the the graphics
adapter shows up as "VirtualBox Graphics Adapter" in hardware list and has its
own drivers installed via the guest additions.

> +
> +    VIR_DOMAIN_VIDEO_TYPE_LAST
> +};
> +
> +
> +typedef struct _virDomainVideoDef virDomainVideoDef;
> +typedef virDomainVideoDef *virDomainVideoDefPtr;
> +struct _virDomainVideoDef {
> +    int type;
> +    unsigned int vram;
> +    unsigned int heads;

can we add "unsigned int 3dSupport;" here cause VirtualBox has support for 3d 
acceleration and it needs to be specified in video adapter category. (it is not 
boolean, but an int cause there could be multiple option, like supporting 
acceleration via opengl, directx, etc, just trying to be future proof.. :) )

> +};
> +
>  /* 3 possible graphics console modes */
>  enum virDomainGraphicsType {
>      VIR_DOMAIN_GRAPHICS_TYPE_SDL,
> @@ -360,6 +379,7 @@ enum virDomainDeviceType {
>      VIR_DOMAIN_DEVICE_NET,
>      VIR_DOMAIN_DEVICE_INPUT,
>      VIR_DOMAIN_DEVICE_SOUND,
> +    VIR_DOMAIN_DEVICE_VIDEO,
>      VIR_DOMAIN_DEVICE_HOSTDEV,
>
>      VIR_DOMAIN_DEVICE_LAST,
> @@ -375,6 +395,7 @@ struct _virDomainDeviceDef {
>          virDomainNetDefPtr net;
>          virDomainInputDefPtr input;
>          virDomainSoundDefPtr sound;
> +        virDomainVideoDefPtr video;
>          virDomainHostdevDefPtr hostdev;
>      } data;
>  };
> @@ -491,6 +512,9 @@ struct _virDomainDef {
>      int nsounds;
>      virDomainSoundDefPtr *sounds;
>
> +    int nvideos;
> +    virDomainVideoDefPtr *videos;
> +
>      int nhostdevs;
>      virDomainHostdevDefPtr *hostdevs;
>
> @@ -557,6 +581,7 @@ void virDomainFSDefFree(virDomainFSDefPt
>  void virDomainNetDefFree(virDomainNetDefPtr def);
>  void virDomainChrDefFree(virDomainChrDefPtr def);
>  void virDomainSoundDefFree(virDomainSoundDefPtr def);
> +void virDomainVideoDefFree(virDomainVideoDefPtr def);
>  void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
>  void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
>  void virDomainDefFree(virDomainDefPtr vm);
> @@ -671,6 +696,7 @@ VIR_ENUM_DECL(virDomainFS)
>  VIR_ENUM_DECL(virDomainNet)
>  VIR_ENUM_DECL(virDomainChr)
>  VIR_ENUM_DECL(virDomainSoundModel)
> +VIR_ENUM_DECL(virDomainVideo)
>  VIR_ENUM_DECL(virDomainHostdevMode)
>  VIR_ENUM_DECL(virDomainHostdevSubsys)
>  VIR_ENUM_DECL(virDomainInput)

rest of the patch seems fine,

Regards,
Pritesh




More information about the libvir-list mailing list