提交 04664327 编写于 作者: F Fabian Freyer 提交者: Roman Bogorodskiy

bhyve: add video support

bhyve supports 'gop' video device that allows clients to connect
to VMs using VNC clients. This commit adds support for that to
the bhyve driver:

 - Introducr 'gop' video device type
 - Add capabilities probing for the 'fbuf' device that's
   responsible for graphics
 - Update command builder routines to let users configure
   domain's VNC via gop graphics.
Signed-off-by: NRoman Bogorodskiy <bogorodskiy@gmail.com>
上级 58b49d0c
...@@ -5891,8 +5891,9 @@ qemu-kvm -net nic,model=? /dev/null ...@@ -5891,8 +5891,9 @@ qemu-kvm -net nic,model=? /dev/null
<p> <p>
The <code>model</code> element has a mandatory <code>type</code> The <code>model</code> element has a mandatory <code>type</code>
attribute which takes the value "vga", "cirrus", "vmvga", "xen", attribute which takes the value "vga", "cirrus", "vmvga", "xen",
"vbox", "qxl" (<span class="since">since 0.8.6</span>) or "vbox", "qxl" (<span class="since">since 0.8.6</span>),
"virtio" (<span class="since">since 1.3.0</span>) "virtio" (<span class="since">since 1.3.0</span>)
or "gop" (<span class="since">since 3.2.0</span>)
depending on the hypervisor features available. depending on the hypervisor features available.
</p> </p>
<p> <p>
......
...@@ -3166,6 +3166,7 @@ ...@@ -3166,6 +3166,7 @@
<value>xen</value> <value>xen</value>
<value>vbox</value> <value>vbox</value>
<value>virtio</value> <value>virtio</value>
<value>gop</value>
</choice> </choice>
</attribute> </attribute>
<group> <group>
......
...@@ -12,6 +12,7 @@ gnulib/lib/getopt.c ...@@ -12,6 +12,7 @@ gnulib/lib/getopt.c
gnulib/lib/regcomp.c gnulib/lib/regcomp.c
src/access/viraccessdriverpolkit.c src/access/viraccessdriverpolkit.c
src/access/viraccessmanager.c src/access/viraccessmanager.c
src/bhyve/bhyve_capabilities.c
src/bhyve/bhyve_command.c src/bhyve/bhyve_command.c
src/bhyve/bhyve_device.c src/bhyve/bhyve_device.c
src/bhyve/bhyve_domain.c src/bhyve/bhyve_domain.c
......
...@@ -117,6 +117,7 @@ virBhyveDomainCapsBuild(const char *emulatorbin, ...@@ -117,6 +117,7 @@ virBhyveDomainCapsBuild(const char *emulatorbin,
virDomainVirtType virttype) virDomainVirtType virttype)
{ {
virDomainCapsPtr caps = NULL; virDomainCapsPtr caps = NULL;
unsigned int bhyve_caps = 0;
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
const char *firmware_dir = "/usr/local/share/uefi-firmware"; const char *firmware_dir = "/usr/local/share/uefi-firmware";
...@@ -125,6 +126,12 @@ virBhyveDomainCapsBuild(const char *emulatorbin, ...@@ -125,6 +126,12 @@ virBhyveDomainCapsBuild(const char *emulatorbin,
if (!(caps = virDomainCapsNew(emulatorbin, machine, arch, virttype))) if (!(caps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
goto cleanup; goto cleanup;
if (virBhyveProbeCaps(&bhyve_caps)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed probing capabilities"));
goto cleanup;
}
caps->os.supported = true; caps->os.supported = true;
caps->os.loader.supported = true; caps->os.loader.supported = true;
VIR_DOMAIN_CAPS_ENUM_SET(caps->os.loader.type, VIR_DOMAIN_CAPS_ENUM_SET(caps->os.loader.type,
...@@ -155,6 +162,12 @@ virBhyveDomainCapsBuild(const char *emulatorbin, ...@@ -155,6 +162,12 @@ virBhyveDomainCapsBuild(const char *emulatorbin,
VIR_DOMAIN_DISK_BUS_SATA, VIR_DOMAIN_DISK_BUS_SATA,
VIR_DOMAIN_DISK_BUS_VIRTIO); VIR_DOMAIN_DISK_BUS_VIRTIO);
if (bhyve_caps & BHYVE_CAP_FBUF) {
caps->graphics.supported = true;
caps->video.supported = true;
VIR_DOMAIN_CAPS_ENUM_SET(caps->graphics.type, VIR_DOMAIN_GRAPHICS_TYPE_VNC);
VIR_DOMAIN_CAPS_ENUM_SET(caps->video.modelType, VIR_DOMAIN_VIDEO_TYPE_GOP);
}
cleanup: cleanup:
VIR_DIR_CLOSE(dir); VIR_DIR_CLOSE(dir);
return caps; return caps;
...@@ -290,6 +303,30 @@ bhyveProbeCapsLPC_Bootrom(unsigned int *caps, char *binary) ...@@ -290,6 +303,30 @@ bhyveProbeCapsLPC_Bootrom(unsigned int *caps, char *binary)
return ret; return ret;
} }
static int
bhyveProbeCapsFramebuffer(unsigned int *caps, char *binary)
{
char *error;
virCommandPtr cmd = NULL;
int ret = -1, exit;
cmd = virCommandNew(binary);
virCommandAddArgList(cmd, "-s", "0,fbuf", NULL);
virCommandSetErrorBuffer(cmd, &error);
if (virCommandRun(cmd, &exit) < 0)
goto cleanup;
if (strstr(error, "pci slot 0:0: unknown device \"fbuf\"") == NULL)
*caps |= BHYVE_CAP_FBUF;
ret = 0;
cleanup:
VIR_FREE(error);
virCommandFree(cmd);
return ret;
}
int int
virBhyveProbeCaps(unsigned int *caps) virBhyveProbeCaps(unsigned int *caps)
{ {
...@@ -314,6 +351,9 @@ virBhyveProbeCaps(unsigned int *caps) ...@@ -314,6 +351,9 @@ virBhyveProbeCaps(unsigned int *caps)
if ((ret = bhyveProbeCapsLPC_Bootrom(caps, binary))) if ((ret = bhyveProbeCapsLPC_Bootrom(caps, binary)))
goto out; goto out;
if ((ret = bhyveProbeCapsFramebuffer(caps, binary)))
goto out;
out: out:
VIR_FREE(binary); VIR_FREE(binary);
return ret; return ret;
......
...@@ -41,6 +41,7 @@ typedef enum { ...@@ -41,6 +41,7 @@ typedef enum {
BHYVE_CAP_AHCI32SLOT = 1 << 1, BHYVE_CAP_AHCI32SLOT = 1 << 1,
BHYVE_CAP_NET_E1000 = 1 << 2, BHYVE_CAP_NET_E1000 = 1 << 2,
BHYVE_CAP_LPC_BOOTROM = 1 << 3, BHYVE_CAP_LPC_BOOTROM = 1 << 3,
BHYVE_CAP_FBUF = 1 << 4,
} virBhyveCapsFlags; } virBhyveCapsFlags;
int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps); int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps);
......
...@@ -290,6 +290,94 @@ bhyveBuildLPCArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, ...@@ -290,6 +290,94 @@ bhyveBuildLPCArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
return 0; return 0;
} }
static int
bhyveBuildGraphicsArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
virDomainGraphicsDefPtr graphics,
virDomainVideoDefPtr video,
virConnectPtr conn,
virCommandPtr cmd)
{
virBuffer opt = VIR_BUFFER_INITIALIZER;
virDomainGraphicsListenDefPtr glisten = NULL;
bool escapeAddr;
if (!(bhyveDriverGetCaps(conn) & BHYVE_CAP_LPC_BOOTROM) ||
def->os.bootloader ||
!def->os.loader) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Graphics are only supported"
" when booting using UEFI"));
return -1;
}
if (!(bhyveDriverGetCaps(conn) & BHYVE_CAP_FBUF)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Bhyve version does not support framebuffer"));
return -1;
}
if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Only VNC supported"));
return -1;
}
if (!(glisten = virDomainGraphicsGetListen(graphics, 0))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing listen element"));
goto error;
}
virBufferAsprintf(&opt, "%d:%d,fbuf", video->info.addr.pci.slot, video->info.addr.pci.function);
switch (glisten->type) {
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
virBufferAddLit(&opt, ",tcp=");
if (!graphics->data.vnc.autoport &&
(graphics->data.vnc.port < 5900 ||
graphics->data.vnc.port > 65535)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("vnc port must be in range [5900,65535]"));
goto error;
}
if (graphics->data.vnc.auth.passwd) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("vnc password auth not supported"));
goto error;
} else {
/* Bhyve doesn't support VNC Auth yet, so print a warning about
* unauthenticated VNC sessions */
VIR_WARN("%s", _("Security warning: currently VNC auth is not"
" supported."));
}
if (glisten->address) {
escapeAddr = strchr(glisten->address, ':') != NULL;
if (escapeAddr)
virBufferAsprintf(&opt, "[%s]", glisten->address);
else
virBufferAdd(&opt, glisten->address, -1);
}
virBufferAsprintf(&opt, ":%d", graphics->data.vnc.port);
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Unsupported listen type"));
}
virCommandAddArg(cmd, "-s");
virCommandAddArgBuffer(cmd, &opt);
return 0;
error:
virBufferFreeAndReset(&opt);
return -1;
}
virCommandPtr virCommandPtr
virBhyveProcessBuildBhyveCmd(virConnectPtr conn, virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
virDomainDefPtr def, bool dryRun) virDomainDefPtr def, bool dryRun)
...@@ -413,6 +501,18 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, ...@@ -413,6 +501,18 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
} }
} }
if (def->ngraphics && def->nvideos) {
if (def->ngraphics == 1 && def->nvideos == 1) {
if (bhyveBuildGraphicsArgStr(def, def->graphics[0], def->videos[0], conn, cmd) < 0)
goto error;
add_lpc = true;
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Multiple graphics devices are not supported"));
goto error;
}
}
if (add_lpc || def->nserials) if (add_lpc || def->nserials)
bhyveBuildLPCArgStr(def, cmd); bhyveBuildLPCArgStr(def, cmd);
......
...@@ -145,6 +145,17 @@ bhyveAssignDevicePCISlots(virDomainDefPtr def, ...@@ -145,6 +145,17 @@ bhyveAssignDevicePCISlots(virDomainDefPtr def,
goto error; goto error;
} }
for (i = 0; i < def->nvideos; i++) {
if (!virDeviceInfoPCIAddressWanted(&def->videos[i]->info))
continue;
if (virDomainPCIAddressReserveNextAddr(addrs,
&def->videos[i]->info,
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
-1) < 0)
goto error;
}
return 0; return 0;
error: error:
......
...@@ -545,7 +545,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, ...@@ -545,7 +545,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
"vbox", "vbox",
"qxl", "qxl",
"parallels", "parallels",
"virtio") "virtio",
"gop")
VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST, VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
"mouse", "mouse",
...@@ -13049,6 +13050,8 @@ virDomainVideoDefaultType(const virDomainDef *def) ...@@ -13049,6 +13050,8 @@ virDomainVideoDefaultType(const virDomainDef *def)
return VIR_DOMAIN_VIDEO_TYPE_VGA; return VIR_DOMAIN_VIDEO_TYPE_VGA;
else else
return VIR_DOMAIN_VIDEO_TYPE_PARALLELS; return VIR_DOMAIN_VIDEO_TYPE_PARALLELS;
case VIR_DOMAIN_VIRT_BHYVE:
return VIR_DOMAIN_VIDEO_TYPE_GOP;
default: default:
return -1; return -1;
} }
......
...@@ -1335,6 +1335,7 @@ typedef enum { ...@@ -1335,6 +1335,7 @@ typedef enum {
VIR_DOMAIN_VIDEO_TYPE_QXL, VIR_DOMAIN_VIDEO_TYPE_QXL,
VIR_DOMAIN_VIDEO_TYPE_PARALLELS, /* pseudo device for VNC in containers */ VIR_DOMAIN_VIDEO_TYPE_PARALLELS, /* pseudo device for VNC in containers */
VIR_DOMAIN_VIDEO_TYPE_VIRTIO, VIR_DOMAIN_VIDEO_TYPE_VIRTIO,
VIR_DOMAIN_VIDEO_TYPE_GOP,
VIR_DOMAIN_VIDEO_TYPE_LAST VIR_DOMAIN_VIDEO_TYPE_LAST
} virDomainVideoType; } virDomainVideoType;
......
...@@ -101,7 +101,8 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, ...@@ -101,7 +101,8 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
"", /* don't support vbox */ "", /* don't support vbox */
"qxl", "qxl",
"", /* don't support parallels */ "", /* don't support parallels */
"" /* no need for virtio */); "", /* no need for virtio */
"" /* don't support gop */);
VIR_ENUM_DECL(qemuDeviceVideo) VIR_ENUM_DECL(qemuDeviceVideo)
...@@ -113,7 +114,8 @@ VIR_ENUM_IMPL(qemuDeviceVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, ...@@ -113,7 +114,8 @@ VIR_ENUM_IMPL(qemuDeviceVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
"", /* don't support vbox */ "", /* don't support vbox */
"qxl-vga", "qxl-vga",
"", /* don't support parallels */ "", /* don't support parallels */
"virtio-vga"); "virtio-vga",
"" /* don't support gop */);
VIR_ENUM_DECL(qemuDeviceVideoSecondary) VIR_ENUM_DECL(qemuDeviceVideoSecondary)
...@@ -125,7 +127,8 @@ VIR_ENUM_IMPL(qemuDeviceVideoSecondary, VIR_DOMAIN_VIDEO_TYPE_LAST, ...@@ -125,7 +127,8 @@ VIR_ENUM_IMPL(qemuDeviceVideoSecondary, VIR_DOMAIN_VIDEO_TYPE_LAST,
"", /* don't support vbox */ "", /* don't support vbox */
"qxl", "qxl",
"", /* don't support parallels */ "", /* don't support parallels */
"virtio-gpu-pci"); "virtio-gpu-pci",
"" /* don't support gop */);
VIR_ENUM_DECL(qemuSoundCodec) VIR_ENUM_DECL(qemuSoundCodec)
......
...@@ -742,6 +742,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev, ...@@ -742,6 +742,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
case VIR_DOMAIN_VIDEO_TYPE_PARALLELS: case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
return pciFlags; return pciFlags;
case VIR_DOMAIN_VIDEO_TYPE_GOP:
case VIR_DOMAIN_VIDEO_TYPE_LAST: case VIR_DOMAIN_VIDEO_TYPE_LAST:
return 0; return 0;
} }
......
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
<value>qxl</value> <value>qxl</value>
<value>parallels</value> <value>parallels</value>
<value>virtio</value> <value>virtio</value>
<value>gop</value>
</enum> </enum>
</video> </video>
<hostdev supported='yes'> <hostdev supported='yes'>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册