diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 683aadb908d7aa520b2c7bd5f011739b4b053860..b95d751e622a4d61ca4e393099f03790aa2b5ef6 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -39,6 +39,9 @@ module Libvirtd_qemu = | str_entry "spice_tls_x509_cert_dir" | str_entry "spice_password" + let remote_display_entry = int_entry "remote_display_port_min" + | int_entry "remote_display_port_max" + let security_entry = str_entry "security_driver" | bool_entry "security_default_confined" | bool_entry "security_require_confined" @@ -72,6 +75,7 @@ module Libvirtd_qemu = (* Each enty in the config is one of the following three ... *) let entry = vnc_entry | spice_entry + | remote_display_entry | security_entry | save_entry | process_entry diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 257a477cccbc4baadde9b38fd535ff883f2ecdda..fb22b7cd8916daf63c64f0280df332a73964a524 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -140,6 +140,20 @@ #spice_password = "XYZ12345" +# Override the port for creating both VNC and SPICE sessions (min). +# This defaults to 5900 and increases for consecutive sessions +# or when ports are occupied, until it hits the maximum. +# +# Minimum must be greater than or equal to 5900 as lower number would +# result into negative vnc display number. +# +# Maximum must be less than 65536, because higher numbers do not make +# sense as a port number. +# +#remote_display_port_min = 5900 +#remote_display_port_max = 65535 + + # The default security driver is SELinux. If SELinux is disabled # on the host, then the security driver will automatically disable # itself. If you wish to disable QEMU SELinux security driver while diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 14afd9bbad742bc838351667cfd982ffee1610db..7c5e8ddfd4873d4c21f5c67183dbed1ffba730d0 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -37,6 +37,13 @@ # define QEMU_VIRTIO_SERIAL_PREFIX "virtio-serial" # define QEMU_FSDEV_HOST_PREFIX "fsdev-" +/* These are only defaults, they can be changed now in qemu.conf and + * explicitely specified port is checked against these two (makes + * sense to limit the values). + * + * This limitation is mentioned in qemu.conf, so bear in mind that the + * configuration file should reflect any changes made to these values. + */ # define QEMU_REMOTE_PORT_MIN 5900 # define QEMU_REMOTE_PORT_MAX 65535 diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index ed6d8326db300e50bc12931a3869d4e047e11f65..e9e15c50292d416ee542b0f6d57fd60978d311f8 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1,7 +1,7 @@ /* * qemu_conf.c: QEMU configuration management * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -38,6 +38,7 @@ #include "virterror_internal.h" #include "qemu_conf.h" +#include "qemu_command.h" #include "qemu_capabilities.h" #include "qemu_bridge_filter.h" #include "uuid.h" @@ -89,6 +90,10 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, virReportOOMError(); return -1; } + + driver->remotePortMin = QEMU_REMOTE_PORT_MIN; + driver->remotePortMax = QEMU_REMOTE_PORT_MAX; + if (!(driver->vncTLSx509certdir = strdup(SYSCONFDIR "/pki/libvirt-vnc"))) { virReportOOMError(); return -1; @@ -295,6 +300,47 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, } } + p = virConfGetValue (conf, "remote_display_port_min"); + CHECK_TYPE ("remote_display_port_min", VIR_CONF_LONG); + if (p) { + if (p->l < QEMU_REMOTE_PORT_MIN) { + /* if the port is too low, we can't get the display name + * to tell to vnc (usually subtract 5900, e.g. localhost:1 + * for port 5901) */ + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s: remote_display_port_min: port must be greater than or equal to %d"), + filename, QEMU_REMOTE_PORT_MIN); + virConfFree(conf); + return -1; + } + driver->remotePortMin = p->l; + } + + p = virConfGetValue (conf, "remote_display_port_max"); + CHECK_TYPE ("remote_display_port_max", VIR_CONF_LONG); + if (p) { + if (p->l > QEMU_REMOTE_PORT_MAX || + p->l < driver->remotePortMin) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s: remote_display_port_max: port must be between the minimal port and %d"), + filename, QEMU_REMOTE_PORT_MAX); + virConfFree(conf); + return -1; + } + /* increasing the value by 1 makes all the loops going through + the bitmap (i = remotePortMin; i < remotePortMax; i++), work as + expected. */ + driver->remotePortMax = p->l + 1; + } + + if (driver->remotePortMin > driver->remotePortMax) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s: remote_display_port_min: min port must not be greater than max port"), + filename); + virConfFree(conf); + return -1; + } + p = virConfGetValue (conf, "user"); CHECK_TYPE ("user", VIR_CONF_STRING); if (!(user = strdup(p && p->str ? p->str : QEMU_USER))) { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index cfebe35a69902f241c8ba560be3df6a600500f9a..ac285f6ed46d8e6fb3d2e4ed4b9b275d12edd5dc 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -95,6 +95,8 @@ struct qemud_driver { char *spiceTLSx509certdir; char *spiceListen; char *spicePassword; + int remotePortMin; + int remotePortMax; char *hugetlbfs_mount; char *hugepage_path; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 00eb4447664eaf36a954e93775e3844e5f703615..f94ddb18ff6fb313acdd67977e9aa31e97c6eae9 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -590,11 +590,6 @@ qemudStartup(int privileged) { if (!qemu_driver->domainEventState) goto error; - /* Allocate bitmap for vnc port reservation */ - if ((qemu_driver->reservedRemotePorts = - virBitmapAlloc(QEMU_REMOTE_PORT_MAX - QEMU_REMOTE_PORT_MIN)) == NULL) - goto out_of_memory; - /* read the host sysinfo */ if (privileged) qemu_driver->hostsysinfo = virSysinfoRead(); @@ -720,6 +715,13 @@ qemudStartup(int privileged) { } VIR_FREE(driverConf); + /* Allocate bitmap for remote display port reservations. We cannot + * do this before the config is loaded properly, since the port + * numbers are configurable now */ + if ((qemu_driver->reservedRemotePorts = + virBitmapAlloc(qemu_driver->remotePortMax - qemu_driver->remotePortMin)) == NULL) + goto out_of_memory; + /* We should always at least have the 'nop' manager, so * NULLs here are a fatal error */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 4a13f6664f1b8ce0d437b948b0bda10073bfcf92..4463134be4d0f054570c7feefe520258c5273f52 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2454,15 +2454,15 @@ static int qemuProcessNextFreePort(struct qemud_driver *driver, { int i; - for (i = startPort ; i < QEMU_REMOTE_PORT_MAX; i++) { + for (i = startPort ; i < driver->remotePortMax; i++) { int fd; int reuse = 1; struct sockaddr_in addr; bool used = false; if (virBitmapGetBit(driver->reservedRemotePorts, - i - QEMU_REMOTE_PORT_MIN, &used) < 0) - VIR_DEBUG("virBitmapGetBit failed on bit %d", i - QEMU_REMOTE_PORT_MIN); + i - driver->remotePortMin, &used) < 0) + VIR_DEBUG("virBitmapGetBit failed on bit %d", i - driver->remotePortMin); if (used) continue; @@ -2484,9 +2484,9 @@ static int qemuProcessNextFreePort(struct qemud_driver *driver, VIR_FORCE_CLOSE(fd); /* Add port to bitmap of reserved ports */ if (virBitmapSetBit(driver->reservedRemotePorts, - i - QEMU_REMOTE_PORT_MIN) < 0) { + i - driver->remotePortMin) < 0) { VIR_DEBUG("virBitmapSetBit failed on bit %d", - i - QEMU_REMOTE_PORT_MIN); + i - driver->remotePortMin); } return i; } @@ -2507,11 +2507,11 @@ static void qemuProcessReturnPort(struct qemud_driver *driver, int port) { - if (port < QEMU_REMOTE_PORT_MIN) + if (port < driver->remotePortMin) return; if (virBitmapClearBit(driver->reservedRemotePorts, - port - QEMU_REMOTE_PORT_MIN) < 0) + port - driver->remotePortMin) < 0) VIR_DEBUG("Could not mark port %d as unused", port); } diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index 959f2501a5275875cc0c4f8c2a5212c836780afc..eac5882d8480aee5280eee0e67df35bac315e4b2 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -15,6 +15,8 @@ module Test_libvirtd_qemu = { "spice_tls" = "1" } { "spice_tls_x509_cert_dir" = "/etc/pki/libvirt-spice" } { "spice_password" = "XYZ12345" } +{ "remote_display_port_min" = "5900" } +{ "remote_display_port_max" = "65535" } { "security_driver" = "selinux" } { "security_default_confined" = "1" } { "security_require_confined" = "1" }