[libvirt] [PATCH v2 2/3] conf: Introduce new video type 'none'
Erik Skultety
eskultet at redhat.com
Wed Jul 18 16:30:04 UTC 2018
On Fri, Jul 13, 2018 at 01:56:32PM +0200, Ján Tomko wrote:
> On Thu, Jul 12, 2018 at 05:08:47PM +0200, Erik Skultety wrote:
> > Historically, we've always enabled an emulated video device every time we
> > see that graphics should be supported with a guest. With the appearance
> > of mediated devices which can support QEMU's vfio-display capability,
> > users might want to use such a device as the only video device.
> > Therefore introduce a new, effectively a 'disable', type for video
> > device.
> >
> > Signed-off-by: Erik Skultety <eskultet at redhat.com>
> > ---
> > docs/formatdomain.html.in | 13 ++++-
> > docs/schemas/domaincommon.rng | 1 +
> > src/conf/domain_conf.c | 55 ++++++++++++++++------
> > src/conf/domain_conf.h | 1 +
> > src/qemu/qemu_command.c | 14 ++++--
> > src/qemu/qemu_domain.c | 3 ++
> > src/qemu/qemu_domain_address.c | 10 ++++
> > tests/domaincapsschemadata/full.xml | 1 +
> > .../video-invalid-multiple-devices.xml | 33 +++++++++++++
> > tests/qemuxml2argvdata/video-none-device.args | 27 +++++++++++
> > tests/qemuxml2argvdata/video-none-device.xml | 39 +++++++++++++++
> > tests/qemuxml2argvtest.c | 4 +-
> > tests/qemuxml2xmloutdata/video-none-device.xml | 42 +++++++++++++++++
> > tests/qemuxml2xmltest.c | 1 +
> > 14 files changed, 223 insertions(+), 21 deletions(-)
> > create mode 100644 tests/qemuxml2argvdata/video-invalid-multiple-devices.xml
> > create mode 100644 tests/qemuxml2argvdata/video-none-device.args
> > create mode 100644 tests/qemuxml2argvdata/video-none-device.xml
> > create mode 100644 tests/qemuxml2xmloutdata/video-none-device.xml
> >
> > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> > index 84ab5a9d12..03d94f0533 100644
> > --- a/docs/formatdomain.html.in
> > +++ b/docs/formatdomain.html.in
> > @@ -6622,9 +6622,18 @@ qemu-kvm -net nic,model=? /dev/null
> > The <code>model</code> element has a mandatory <code>type</code>
> > attribute which takes the value "vga", "cirrus", "vmvga", "xen",
> > "vbox", "qxl" (<span class="since">since 0.8.6</span>),
> > - "virtio" (<span class="since">since 1.3.0</span>)
> > - or "gop" (<span class="since">since 3.2.0</span>)
> > + "virtio" (<span class="since">since 1.3.0</span>),
> > + "gop" (<span class="since">since 3.2.0</span>), or
> > + "none" (<span class="since">since 4.6.0</span>)
> > depending on the hypervisor features available.
> > + The purpose of the type <code>none</code> is to instruct libvirt not
> > + to add a default video device in the guest (see the paragraph above).
> > + This legacy behaviour can be inconvenient in cases where GPU mediated
> > + devices are meant to be the only rendering device within a guest and
> > + so specifying another <code>video</code> device along with type
> > + <code>none</code>.
> > + Refer to <a id="elementsHostDev">Host device assignment</a> to see
> > + how to add a mediated device into a guest.
> > </p>
> > <p>
> > You can provide the amount of video memory in kibibytes (blocks of
> > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> > index bd687ce9d3..ed989c000f 100644
> > --- a/docs/schemas/domaincommon.rng
> > +++ b/docs/schemas/domaincommon.rng
> > @@ -3451,6 +3451,7 @@
> > <value>vbox</value>
> > <value>virtio</value>
> > <value>gop</value>
> > + <value>none</value>
> > </choice>
> > </attribute>
> > <group>
> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > index 7396616eda..d4927f0226 100644
> > --- a/src/conf/domain_conf.c
> > +++ b/src/conf/domain_conf.c
> > @@ -590,7 +590,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
> > "qxl",
> > "parallels",
> > "virtio",
> > - "gop")
> > + "gop",
> > + "none")
> >
> > VIR_ENUM_IMPL(virDomainVideoVGAConf, VIR_DOMAIN_VIDEO_VGACONF_LAST,
> > "io",
> > @@ -5091,25 +5092,48 @@ static int
> > virDomainDefPostParseVideo(virDomainDefPtr def,
> > void *opaque)
> > {
> > + size_t i;
> > +
> > if (def->nvideos == 0)
> > return 0;
> >
> > - virDomainDeviceDef device = {
> > - .type = VIR_DOMAIN_DEVICE_VIDEO,
> > - .data.video = def->videos[0],
> > - };
> > -
> > - /* Mark the first video as primary. If the user specified
> > - * primary="yes", the parser already inserted the device at
> > - * def->videos[0]
> > + /* it doesn't make sense to pair video device type 'none' with any other
> > + * types, there can be only a single video device in such case
> > */
> > - def->videos[0]->primary = true;
> > + for (i = 0; i < def->nvideos; i++) {
> > + if (def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_NONE &&
> > + def->nvideos > 1) {
> > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> > + _("a '%s' video type must be the only video device "
> > + "defined for the domain"));
> > + return -1;
> > + }
> > + }
>
> This looks like something virDomainDefValidate should do.
>
> >
> > - /* videos[0] might have been added in AddImplicitDevices, after we've
> > - * done the per-device post-parse */
> > - if (virDomainDefPostParseDeviceIterator(def, &device,
> > - NULL, opaque) < 0)
> > - return -1;
> > + if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_NONE) {
> > + /* we don't want to format any values we automatically fill in for
> > + * videos into the XML, so clear them
> > + */
> > + virDomainVideoDefClear(def->videos[0]);
> > + def->videos[0]->type = VIR_DOMAIN_VIDEO_TYPE_NONE;
>
> Is there anything else than 'heads = 1' we fill in by default?
> If we clear other data here, it's because the user specified it, isn't
> it?
>
> Ideally, the parser would only fill in the data that was explicitly
> specified in the XML input and defaults would be filled in here, but
> this will do until we fix the parser.
>
> > + } else {
> > + virDomainDeviceDef device = {
> > + .type = VIR_DOMAIN_DEVICE_VIDEO,
> > + .data.video = def->videos[0],
> > + };
> > +
> > + /* Mark the first video as primary. If the user specified
> > + * primary="yes", the parser already inserted the device at
> > + * def->videos[0]
> > + */
> > + def->videos[0]->primary = true;
> > +
> > + /* videos[0] might have been added in AddImplicitDevices, after we've
> > + * done the per-device post-parse */
> > + if (virDomainDefPostParseDeviceIterator(def, &device,
> > + NULL, opaque) < 0)
> > + return -1;
> > + }
> >
> > return 0;
> > }
> > @@ -15023,6 +15047,7 @@ virDomainVideoDefaultRAM(const virDomainDef *def,
> > case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
> > case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
> > case VIR_DOMAIN_VIDEO_TYPE_GOP:
> > + case VIR_DOMAIN_VIDEO_TYPE_NONE:
> > case VIR_DOMAIN_VIDEO_TYPE_LAST:
> > default:
> > return 0;
> > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> > index 0f10e242fd..fe2fcdc081 100644
> > --- a/src/conf/domain_conf.h
> > +++ b/src/conf/domain_conf.h
> > @@ -1423,6 +1423,7 @@ typedef enum {
> > VIR_DOMAIN_VIDEO_TYPE_PARALLELS, /* pseudo device for VNC in containers */
> > VIR_DOMAIN_VIDEO_TYPE_VIRTIO,
> > VIR_DOMAIN_VIDEO_TYPE_GOP,
> > + VIR_DOMAIN_VIDEO_TYPE_NONE,
> >
> > VIR_DOMAIN_VIDEO_TYPE_LAST
> > } virDomainVideoType;
> > diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> > index 44ae8dcef7..545b979a6f 100644
> > --- a/src/qemu/qemu_command.c
> > +++ b/src/qemu/qemu_command.c
> > @@ -105,7 +105,8 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
> > "qxl",
> > "", /* don't support parallels */
> > "", /* no need for virtio */
> > - "" /* don't support gop */);
> > + "" /* don't support gop */,
> > + "none" /* no display */);
>
> This device is not formatted on the command line, so "" should be
> enough.
>
> >
> > VIR_ENUM_DECL(qemuDeviceVideo)
> >
> > @@ -119,7 +120,8 @@ VIR_ENUM_IMPL(qemuDeviceVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
> > "qxl-vga",
> > "", /* don't support parallels */
> > "virtio-vga",
> > - "" /* don't support gop */);
> > + "" /* don't support gop */,
> > + "none" /* no display */);
>
> Same here.
>
> >
> > VIR_ENUM_DECL(qemuDeviceVideoSecondary)
> >
> > @@ -133,7 +135,8 @@ VIR_ENUM_IMPL(qemuDeviceVideoSecondary, VIR_DOMAIN_VIDEO_TYPE_LAST,
> > "qxl",
> > "", /* don't support parallels */
> > "virtio-gpu",
> > - "" /* don't support gop */);
> > + "" /* don't support gop */,
> > + "" /* 'none' doesn't make sense here */);
> >
> > VIR_ENUM_DECL(qemuSoundCodec)
> >
> > @@ -4447,6 +4450,11 @@ qemuBuildVideoCommandLine(virCommandPtr cmd,
> > {
> > size_t i;
> >
> > + /* no cmdline needed for type 'none' */
> > + if (def->nvideos > 0 &&
> > + def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_NONE)
> > + return 0;
> > +
>
> I'd just do:
>
> if (video->type == VIR_DOMAIN_VIDEO_TYPE_NONE)
> continue;
>
> in the loop below - we already verified that this video can only appear
> once and as the only device in the XML.
>
> > for (i = 0; i < def->nvideos; i++) {
> > char *str = NULL;
> > virDomainVideoDefPtr video = def->videos[i];
> > diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> > index ed76495309..af8c5f8b0b 100644
> > --- a/src/qemu/qemu_domain.c
> > +++ b/src/qemu/qemu_domain.c
> > @@ -4471,6 +4471,9 @@ static int
> > qemuDomainDeviceDefValidateVideo(const virDomainVideoDef *video)
> > {
> > switch ((virDomainVideoType) video->type) {
> > + case VIR_DOMAIN_VIDEO_TYPE_NONE:
> > + /* nothing to be validated for 'none' */
>
> Strictly speaking this is not true, specifying any attributes for type
> none is nonsense. But we cleared the device definition in postParse already.
>
> > + return 0;
> > case VIR_DOMAIN_VIDEO_TYPE_XEN:
> > case VIR_DOMAIN_VIDEO_TYPE_VBOX:
> > case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
> > diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
> > index 6ea80616af..e045b2627e 100644
> > --- a/src/qemu/qemu_domain_address.c
> > +++ b/src/qemu/qemu_domain_address.c
> > @@ -799,6 +799,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> >
> > case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
> > case VIR_DOMAIN_VIDEO_TYPE_GOP:
> > + case VIR_DOMAIN_VIDEO_TYPE_NONE:
> > case VIR_DOMAIN_VIDEO_TYPE_LAST:
> > return 0;
> > }
> > @@ -1518,6 +1519,13 @@ qemuDomainValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
> > * at slot 2.
> > */
> > virDomainVideoDefPtr primaryVideo = def->videos[0];
> > +
> > + /* for video type 'none' skip this whole procedure */
> > + if (primaryVideo->type == VIR_DOMAIN_VIDEO_TYPE_NONE) {
> > + ret = 0;
> > + goto cleanup;
> > + }
>
> I'd rather adjust the above condition to:
>
> if (def->nvideos > 0 &&
> def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE)
>
> to prevent our auto-assignment code to use 0:0:2.0 unless requested,
> but I cannot estimate the likelihood of someone using <video
> type='none'/> wanting to add one in the future.
>
> > +
> > if (virDeviceInfoPCIAddressWanted(&primaryVideo->info)) {
> > memset(&tmp_addr, 0, sizeof(tmp_addr));
> > tmp_addr.slot = 2;
> > @@ -2083,6 +2091,8 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def,
> >
> > /* Video devices */
> > for (i = 0; i < def->nvideos; i++) {
> > + if (def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_NONE)
> > + break;
>
> continue;
>
> for consistency.
>
> >
> > if (!virDeviceInfoPCIAddressWanted(&def->videos[i]->info))
> > continue;
>
> Reviewed-by: Ján Tomko <jtomko at redhat.com>
Thanks, I incorporated your suggestions and pushed the series.
Erik
More information about the libvir-list
mailing list