bhyve: add vga configuration for video driver

Add support for vgaconf driver configuration. In domain xml it looks like
this:

  <video>
    <driver vgaconf='io|on|off'>
    <model .../>
  </video>

It was added with bhyve gop video in mind to allow users control how the
video device is exposed to the guest, specifically, how VGA I/O is
handled.

One can refer to the bhyve manual page to get more detailed description
of the possible VGA configuration options:

https://www.freebsd.org/cgi/man.cgi?query=bhyve&manpath=FreeBSD+12-current

The relevant part could be found using the 'vgaconf' keyword.

Also, add some tests for this new feature.

Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Roman Bogorodskiy 2017-05-09 14:48:30 +04:00
parent e4574da0b7
commit 78fc843c7b
20 changed files with 356 additions and 6 deletions

View File

@ -6156,7 +6156,14 @@ qemu-kvm -net nic,model=? /dev/null
<dt>virtio options</dt> <dt>virtio options</dt>
<dd> <dd>
<a href="#elementsVirtio">Virtio-specific options</a> can also be <a href="#elementsVirtio">Virtio-specific options</a> can also be
set. (<span class="since">Since 3.5.0</span>) set (<span class="since">Since 3.5.0</span>)
</dd>
<dt>VGA configuration</dt>
<dd>
Control how the video devices exposed to the guest using the
<code>vgaconf</code> attribute which takes the value "io", "on" or "off".
At present, it's only applicable to the bhyve's "gop" video model type
(<span class="since">Since 3.5.0</span>)
</dd> </dd>
</dl> </dl>
</dd> </dd>

View File

@ -3220,7 +3220,18 @@
<element name="video"> <element name="video">
<optional> <optional>
<element name="driver"> <element name="driver">
<ref name="virtioOptions"/> <optional>
<ref name="virtioOptions"/>
</optional>
<optional>
<attribute name="vgaconf">
<choice>
<value>io</value>
<value>on</value>
<value>off</value>
</choice>
</attribute>
</optional>
</element> </element>
</optional> </optional>
<optional> <optional>

View File

@ -408,6 +408,10 @@ bhyveBuildGraphicsArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
_("Unsupported listen type")); _("Unsupported listen type"));
} }
if (video->driver)
virBufferAsprintf(&opt, ",vga=%s",
virDomainVideoVGAConfTypeToString(video->driver->vgaconf));
virCommandAddArg(cmd, "-s"); virCommandAddArg(cmd, "-s");
virCommandAddArgBuffer(cmd, &opt); virCommandAddArgBuffer(cmd, &opt);
return 0; return 0;

View File

@ -560,6 +560,11 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
"virtio", "virtio",
"gop") "gop")
VIR_ENUM_IMPL(virDomainVideoVGAConf, VIR_DOMAIN_VIDEO_VGACONF_LAST,
"io",
"on",
"off")
VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST, VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
"mouse", "mouse",
"tablet", "tablet",
@ -2355,6 +2360,7 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def)
VIR_FREE(def->accel); VIR_FREE(def->accel);
VIR_FREE(def->virtio); VIR_FREE(def->virtio);
VIR_FREE(def->driver);
VIR_FREE(def); VIR_FREE(def);
} }
@ -13598,6 +13604,43 @@ virDomainVideoAccelDefParseXML(xmlNodePtr node)
return def; return def;
} }
static virDomainVideoDriverDefPtr
virDomainVideoDriverDefParseXML(xmlNodePtr node)
{
xmlNodePtr cur;
virDomainVideoDriverDefPtr def;
char *vgaconf = NULL;
int val;
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
if (!vgaconf &&
xmlStrEqual(cur->name, BAD_CAST "driver")) {
vgaconf = virXMLPropString(cur, "vgaconf");
}
}
cur = cur->next;
}
if (!vgaconf)
return NULL;
if (VIR_ALLOC(def) < 0)
goto cleanup;
if ((val = virDomainVideoVGAConfTypeFromString(vgaconf)) <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown vgaconf value '%s'"), vgaconf);
goto cleanup;
}
def->vgaconf = val;
cleanup:
VIR_FREE(vgaconf);
return def;
}
static virDomainVideoDefPtr static virDomainVideoDefPtr
virDomainVideoDefParseXML(xmlNodePtr node, virDomainVideoDefParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt, xmlXPathContextPtr ctxt,
@ -13721,6 +13764,8 @@ virDomainVideoDefParseXML(xmlNodePtr node,
if (virDomainVirtioOptionsParseXML(ctxt, &def->virtio) < 0) if (virDomainVirtioOptionsParseXML(ctxt, &def->virtio) < 0)
goto error; goto error;
def->driver = virDomainVideoDriverDefParseXML(node);
cleanup: cleanup:
ctxt->node = saved; ctxt->node = saved;
@ -23455,7 +23500,6 @@ virDomainVideoAccelDefFormat(virBufferPtr buf,
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");
} }
static int static int
virDomainVideoDefFormat(virBufferPtr buf, virDomainVideoDefFormat(virBufferPtr buf,
virDomainVideoDefPtr def, virDomainVideoDefPtr def,
@ -23475,9 +23519,13 @@ virDomainVideoDefFormat(virBufferPtr buf,
virDomainVirtioOptionsFormat(&driverBuf, def->virtio); virDomainVirtioOptionsFormat(&driverBuf, def->virtio);
if (virBufferCheckError(&driverBuf) < 0) if (virBufferCheckError(&driverBuf) < 0)
return -1; return -1;
if (virBufferUse(&driverBuf)) { if (virBufferUse(&driverBuf) || (def->driver && def->driver->vgaconf)) {
virBufferAddLit(buf, "<driver"); virBufferAddLit(buf, "<driver");
virBufferAddBuffer(buf, &driverBuf); if (virBufferUse(&driverBuf))
virBufferAddBuffer(buf, &driverBuf);
if (def->driver && def->driver->vgaconf)
virBufferAsprintf(buf, " vgaconf='%s'",
virDomainVideoVGAConfTypeToString(def->driver->vgaconf));
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");
} }
virBufferAsprintf(buf, "<model type='%s'", virBufferAsprintf(buf, "<model type='%s'",
@ -23497,7 +23545,8 @@ virDomainVideoDefFormat(virBufferPtr buf,
if (def->accel) { if (def->accel) {
virBufferAddLit(buf, ">\n"); virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
virDomainVideoAccelDefFormat(buf, def->accel); if (def->accel)
virDomainVideoAccelDefFormat(buf, def->accel);
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</model>\n"); virBufferAddLit(buf, "</model>\n");
} else { } else {

View File

@ -1359,6 +1359,16 @@ typedef enum {
} virDomainVideoType; } virDomainVideoType;
typedef enum {
VIR_DOMAIN_VIDEO_VGACONF_IO = 0,
VIR_DOMAIN_VIDEO_VGACONF_ON,
VIR_DOMAIN_VIDEO_VGACONF_OFF,
VIR_DOMAIN_VIDEO_VGACONF_LAST
} virDomainVideoVGAConf;
VIR_ENUM_DECL(virDomainVideoVGAConf)
typedef struct _virDomainVideoAccelDef virDomainVideoAccelDef; typedef struct _virDomainVideoAccelDef virDomainVideoAccelDef;
typedef virDomainVideoAccelDef *virDomainVideoAccelDefPtr; typedef virDomainVideoAccelDef *virDomainVideoAccelDefPtr;
struct _virDomainVideoAccelDef { struct _virDomainVideoAccelDef {
@ -1367,6 +1377,12 @@ struct _virDomainVideoAccelDef {
}; };
typedef struct _virDomainVideoDriverDef virDomainVideoDriverDef;
typedef virDomainVideoDriverDef *virDomainVideoDriverDefPtr;
struct _virDomainVideoDriverDef {
virDomainVideoVGAConf vgaconf;
};
struct _virDomainVideoDef { struct _virDomainVideoDef {
int type; int type;
unsigned int ram; /* kibibytes (multiples of 1024) */ unsigned int ram; /* kibibytes (multiples of 1024) */
@ -1376,6 +1392,7 @@ struct _virDomainVideoDef {
unsigned int heads; unsigned int heads;
bool primary; bool primary;
virDomainVideoAccelDefPtr accel; virDomainVideoAccelDefPtr accel;
virDomainVideoDriverDefPtr driver;
virDomainDeviceInfo info; virDomainDeviceInfo info;
virDomainVirtioOptionsPtr virtio; virDomainVirtioOptionsPtr virtio;
}; };

View File

@ -530,6 +530,8 @@ virDomainVideoDefaultType;
virDomainVideoDefFree; virDomainVideoDefFree;
virDomainVideoTypeFromString; virDomainVideoTypeFromString;
virDomainVideoTypeToString; virDomainVideoTypeToString;
virDomainVideoVGAConfTypeFromString;
virDomainVideoVGAConfTypeToString;
virDomainVirtTypeFromString; virDomainVirtTypeFromString;
virDomainVirtTypeToString; virDomainVirtTypeToString;
virDomainWatchdogActionTypeFromString; virDomainWatchdogActionTypeFromString;

View File

@ -0,0 +1,12 @@
/usr/sbin/bhyve \
-c 1 \
-m 214 \
-u \
-H \
-P \
-s 0:0,hostbridge \
-l bootrom,/path/to/test.fd \
-s 2:0,ahci,hd:/tmp/freebsd.img \
-s 3:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \
-s 4:0,fbuf,tcp=127.0.0.1:5904,vga=io \
-s 1,lpc bhyve

View File

@ -0,0 +1 @@
dummy

View File

@ -0,0 +1,30 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory>219136</memory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
<loader readonly="yes" type="pflash">/path/to/test.fd</loader>
</os>
<devices>
<disk type='file'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<interface type='bridge'>
<model type='virtio'/>
<source bridge="virbr0"/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<graphics type='vnc' port='5904'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<driver vgaconf="io"/>
<model type='gop' heads='1' primary='yes'/>
</video>
</devices>
</domain>

View File

@ -0,0 +1,12 @@
/usr/sbin/bhyve \
-c 1 \
-m 214 \
-u \
-H \
-P \
-s 0:0,hostbridge \
-l bootrom,/path/to/test.fd \
-s 2:0,ahci,hd:/tmp/freebsd.img \
-s 3:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \
-s 4:0,fbuf,tcp=127.0.0.1:5904,vga=off \
-s 1,lpc bhyve

View File

@ -0,0 +1 @@
dummy

View File

@ -0,0 +1,30 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory>219136</memory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
<loader readonly="yes" type="pflash">/path/to/test.fd</loader>
</os>
<devices>
<disk type='file'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<interface type='bridge'>
<model type='virtio'/>
<source bridge="virbr0"/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<graphics type='vnc' port='5904'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<driver vgaconf="off"/>
<model type='gop' heads='1' primary='yes'/>
</video>
</devices>
</domain>

View File

@ -0,0 +1,12 @@
/usr/sbin/bhyve \
-c 1 \
-m 214 \
-u \
-H \
-P \
-s 0:0,hostbridge \
-l bootrom,/path/to/test.fd \
-s 2:0,ahci,hd:/tmp/freebsd.img \
-s 3:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \
-s 4:0,fbuf,tcp=127.0.0.1:5904,vga=on \
-s 1,lpc bhyve

View File

@ -0,0 +1 @@
dummy

View File

@ -0,0 +1,30 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory>219136</memory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
<loader readonly="yes" type="pflash">/path/to/test.fd</loader>
</os>
<devices>
<disk type='file'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<interface type='bridge'>
<model type='virtio'/>
<source bridge="virbr0"/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<graphics type='vnc' port='5904'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<driver vgaconf="on"/>
<model type='gop' heads='1' primary='yes'/>
</video>
</devices>
</domain>

View File

@ -193,6 +193,9 @@ mymain(void)
DO_TEST("net-e1000"); DO_TEST("net-e1000");
DO_TEST("uefi"); DO_TEST("uefi");
DO_TEST("vnc"); DO_TEST("vnc");
DO_TEST("vnc-vgaconf-on");
DO_TEST("vnc-vgaconf-off");
DO_TEST("vnc-vgaconf-io");
/* Address allocation tests */ /* Address allocation tests */
DO_TEST("addr-single-sata-disk"); DO_TEST("addr-single-sata-disk");

View File

@ -0,0 +1,41 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<loader readonly='yes' type='pflash'>/path/to/test.fd</loader>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='file' device='disk'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<controller type='pci' index='0' model='pci-root'/>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:00:00:00'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<graphics type='vnc' port='5904' autoport='no' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<model type='gop' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</video>
</devices>
</domain>

View File

@ -0,0 +1,42 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<loader readonly='yes' type='pflash'>/path/to/test.fd</loader>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='file' device='disk'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<controller type='pci' index='0' model='pci-root'/>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:00:00:00'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<graphics type='vnc' port='5904' autoport='no' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<driver vgaconf='off'/>
<model type='gop' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</video>
</devices>
</domain>

View File

@ -0,0 +1,42 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<loader readonly='yes' type='pflash'>/path/to/test.fd</loader>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='file' device='disk'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<controller type='pci' index='0' model='pci-root'/>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:00:00:00'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<graphics type='vnc' port='5904' autoport='no' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<driver vgaconf='on'/>
<model type='gop' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</video>
</devices>
</domain>

View File

@ -105,6 +105,9 @@ mymain(void)
DO_TEST_DIFFERENT("serial-grub"); DO_TEST_DIFFERENT("serial-grub");
DO_TEST_DIFFERENT("serial-grub-nocons"); DO_TEST_DIFFERENT("serial-grub-nocons");
DO_TEST_DIFFERENT("vnc"); DO_TEST_DIFFERENT("vnc");
DO_TEST_DIFFERENT("vnc-vgaconf-on");
DO_TEST_DIFFERENT("vnc-vgaconf-off");
DO_TEST_DIFFERENT("vnc-vgaconf-io");
/* Address allocation tests */ /* Address allocation tests */
DO_TEST_DIFFERENT("addr-single-sata-disk"); DO_TEST_DIFFERENT("addr-single-sata-disk");