From ed210660d682bab597d41ccac76c3b2f02233f9f Mon Sep 17 00:00:00 2001 From: Alexander Nusov Date: Mon, 8 May 2017 13:36:43 +0300 Subject: [PATCH] bhyve: Add support for VNC autoport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for automatic VNC port assignment for bhyve guests. Signed-off-by: Roman Bogorodskiy Reviewed-by: Ján Tomko --- src/bhyve/bhyve_command.c | 25 +++++++++-- src/bhyve/bhyve_driver.c | 5 +++ src/bhyve/bhyve_process.c | 20 +++++++++ src/bhyve/bhyve_utils.h | 3 ++ .../bhyvexml2argv-vnc-autoport.args | 12 ++++++ .../bhyvexml2argv-vnc-autoport.ldargs | 1 + .../bhyvexml2argv-vnc-autoport.xml | 26 ++++++++++++ tests/bhyvexml2argvtest.c | 7 ++++ .../bhyvexml2xmlout-vnc-autoport.xml | 41 +++++++++++++++++++ tests/bhyvexml2xmltest.c | 1 + 10 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.xml create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-vnc-autoport.xml diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index b3ae315bde..55032ae1df 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -330,15 +330,19 @@ bhyveBuildLPCArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, } static int -bhyveBuildGraphicsArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, +bhyveBuildGraphicsArgStr(const virDomainDef *def, virDomainGraphicsDefPtr graphics, virDomainVideoDefPtr video, virConnectPtr conn, - virCommandPtr cmd) + virCommandPtr cmd, + bool dryRun) { virBuffer opt = VIR_BUFFER_INITIALIZER; virDomainGraphicsListenDefPtr glisten = NULL; bool escapeAddr; + unsigned short port; + + bhyveConnPtr driver = conn->privateData; if (!(bhyveDriverGetCaps(conn) & BHYVE_CAP_LPC_BOOTROM) || def->os.bootloader || @@ -401,6 +405,20 @@ bhyveBuildGraphicsArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, virBufferAdd(&opt, glisten->address, -1); } + if (!dryRun) { + if (graphics->data.vnc.autoport) { + if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0) + return -1; + graphics->data.vnc.port = port; + } else { + if (virPortAllocatorSetUsed(driver->remotePorts, + graphics->data.vnc.port, + true) < 0) + VIR_WARN("Failed to mark VNC port '%d' as used by '%s'", + graphics->data.vnc.port, def->name); + } + } + virBufferAsprintf(&opt, ":%d", graphics->data.vnc.port); break; default: @@ -557,7 +575,8 @@ 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) + if (bhyveBuildGraphicsArgStr(def, def->graphics[0], def->videos[0], + conn, cmd, dryRun) < 0) goto error; add_lpc = true; } else { diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 550b257cd1..3bcff88975 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -52,6 +52,7 @@ #include "viraccessapicheck.h" #include "virhostcpu.h" #include "virhostmem.h" +#include "virportallocator.h" #include "conf/domain_capabilities.h" #include "bhyve_conf.h" @@ -1219,6 +1220,7 @@ bhyveStateCleanup(void) virObjectUnref(bhyve_driver->closeCallbacks); virObjectUnref(bhyve_driver->domainEventState); virObjectUnref(bhyve_driver->config); + virObjectUnref(bhyve_driver->remotePorts); virMutexDestroy(&bhyve_driver->lock); VIR_FREE(bhyve_driver); @@ -1265,6 +1267,9 @@ bhyveStateInitialize(bool privileged, if (!(bhyve_driver->domainEventState = virObjectEventStateNew())) goto cleanup; + if (!(bhyve_driver->remotePorts = virPortAllocatorNew(_("display"), 5900, 65535, 0))) + goto cleanup; + bhyve_driver->hostsysinfo = virSysinfoRead(); if (!(bhyve_driver->config = virBhyveDriverConfigNew())) diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index a97e300ff7..7211156ca2 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -293,6 +293,16 @@ virBhyveProcessStop(bhyveConnPtr driver, /* Cleanup network interfaces */ bhyveNetCleanup(vm); + /* VNC autoport cleanup */ + if ((vm->def->ngraphics == 1) && + vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) { + if (virPortAllocatorRelease(driver->remotePorts, + vm->def->graphics[0]->data.vnc.port) < 0) { + VIR_WARN("Failed to release VNC port for '%s'", + vm->def->name); + } + } + ret = 0; virCloseCallbacksUnset(driver->closeCallbacks, vm, @@ -412,6 +422,16 @@ virBhyveProcessReconnect(virDomainObjPtr vm, if (STREQ(expected_proctitle, proc_argv[0])) { ret = 0; priv->mon = bhyveMonitorOpen(vm, data->driver); + if (vm->def->ngraphics == 1 && + vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) { + int vnc_port = vm->def->graphics[0]->data.vnc.port; + if (virPortAllocatorSetUsed(data->driver->remotePorts, + vnc_port, + true) < 0) { + VIR_WARN("Failed to mark VNC port '%d' as used by '%s'", + vnc_port, vm->def->name); + } + } } } diff --git a/src/bhyve/bhyve_utils.h b/src/bhyve/bhyve_utils.h index db50e012ac..8ad2698d46 100644 --- a/src/bhyve/bhyve_utils.h +++ b/src/bhyve/bhyve_utils.h @@ -28,6 +28,7 @@ # include "virdomainobjlist.h" # include "virthread.h" # include "virclosecallbacks.h" +# include "virportallocator.h" # define BHYVE_AUTOSTART_DIR SYSCONFDIR "/libvirt/bhyve/autostart" # define BHYVE_CONFIG_DIR SYSCONFDIR "/libvirt/bhyve" @@ -58,6 +59,8 @@ struct _bhyveConn { virCloseCallbacksPtr closeCallbacks; + virPortAllocatorPtr remotePorts; + unsigned bhyvecaps; unsigned grubcaps; }; diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.args b/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.args new file mode 100644 index 0000000000..039526ff35 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.args @@ -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:5900 \ +-s 1,lpc bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.ldargs new file mode 100644 index 0000000000..421376db9e --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.ldargs @@ -0,0 +1 @@ +dummy diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.xml new file mode 100644 index 0000000000..afb73f040e --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-vnc-autoport.xml @@ -0,0 +1,26 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + /path/to/test.fd + + + + + + +
+ + + + +
+ + + + + + diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index 72f10ebc1c..5623044cbd 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -145,6 +145,11 @@ mymain(void) if ((driver.xmlopt = virBhyveDriverCreateXMLConf(&driver)) == NULL) return EXIT_FAILURE; + if (!(driver.remotePorts = virPortAllocatorNew("display", 5900, 65535, + VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK))) + return EXIT_FAILURE; + + # define DO_TEST_FULL(name, flags) \ do { \ static struct testInfo info = { \ @@ -196,6 +201,7 @@ mymain(void) DO_TEST("vnc-vgaconf-on"); DO_TEST("vnc-vgaconf-off"); DO_TEST("vnc-vgaconf-io"); + DO_TEST("vnc-autoport"); /* Address allocation tests */ DO_TEST("addr-single-sata-disk"); @@ -234,6 +240,7 @@ mymain(void) virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); + virObjectUnref(driver.remotePorts); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-vnc-autoport.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-vnc-autoport.xml new file mode 100644 index 0000000000..d6cfe76b70 --- /dev/null +++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-vnc-autoport.xml @@ -0,0 +1,41 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 219136 + 1 + + hvm + /path/to/test.fd + + + + destroy + restart + destroy + + + + + +
+ + + +
+ + + + + +
+ + + + +