[libvirt] [PATCH] graphics: add support for action_if_connected in qemu

This option accepts 3 values: -keep, to keep current client connected (Spice+VNC) -disconnect, to disconnect client (Spice) -fail, to fail setting password if there is a client connected (Spice) --- docs/schemas/domain.rng | 16 ++++++++++++++++ src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 11 +++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_hotplug.c | 11 ++++++++--- 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index c270815..f0efe60 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1227,6 +1227,13 @@ <data type="dateTime"/> </attribute> </optional> + <optional> + <attribute name="connected"> + <choice> + <value>keep</value> + </choice> + </attribute> + </optional> </group> <group> <attribute name="type"> @@ -1270,6 +1277,15 @@ <data type="dateTime"/> </attribute> </optional> + <optional> + <attribute name="connected"> + <choice> + <value>fail</value> + <value>disconnect</value> + <value>keep</value> + </choice> + </attribute> + </optional> <interleave> <zeroOrMore> <element name="channel"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fbef61e..571fcf4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -313,6 +313,13 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST, "desktop", "spice") +VIR_ENUM_IMPL(virDomainGraphicsAuthConnected, + VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_LAST, + "default", + "fail", + "disconnect", + "keep") + VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelName, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST, "main", @@ -3803,9 +3810,12 @@ error: static int -virDomainGraphicsAuthDefParseXML(xmlNodePtr node, virDomainGraphicsAuthDefPtr def) +virDomainGraphicsAuthDefParseXML(xmlNodePtr node, + virDomainGraphicsAuthDefPtr def, + int type) { char *validTo = NULL; + char *connected = virXMLPropString(node, "connected"); def->passwd = virXMLPropString(node, "passwd"); @@ -3846,6 +3856,28 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node, virDomainGraphicsAuthDefPtr de def->expires = 1; } + if (connected) { + int action = virDomainGraphicsAuthConnectedTypeFromString(connected); + if (action < 0) { + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown connected value %s"), + connected); + VIR_FREE(connected); + return -1; + } + VIR_FREE(connected); + + /* VNC supports connected='keep' only */ + if (type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && + action != VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_KEEP) { + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VNC supports connected='keep' only")); + return -1; + } + + def->connected = action; + } + return 0; } @@ -3915,7 +3947,8 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { !def->data.vnc.listenAddr[0]) VIR_FREE(def->data.vnc.listenAddr); - if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth) < 0) + if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth, + def->type) < 0) goto error; } else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { char *fullscreen = virXMLPropString(node, "fullscreen"); @@ -4051,7 +4084,8 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { !def->data.spice.listenAddr[0]) VIR_FREE(def->data.spice.listenAddr); - if (virDomainGraphicsAuthDefParseXML(node, &def->data.spice.auth) < 0) + if (virDomainGraphicsAuthDefParseXML(node, &def->data.spice.auth, + def->type) < 0) goto error; cur = node->children; @@ -7995,6 +8029,10 @@ virDomainGraphicsAuthDefFormatAttr(virBufferPtr buf, strftime(strbuf, sizeof(strbuf), "%Y-%m-%dT%H:%M:%S", tm); virBufferAsprintf(buf, " passwdValidTo='%s'", strbuf); } + + if (def->connected) + virBufferEscapeString(buf, " connected='%s'", + virDomainGraphicsAuthConnectedTypeToString(def->connected)); } static int diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8c94d4d..d090b9a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -631,12 +631,22 @@ enum virDomainGraphicsType { VIR_DOMAIN_GRAPHICS_TYPE_LAST, }; +enum virDomainGraphicsAuthConnectedType { + VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_DEFAULT = 0, + VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_FAIL, + VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_DISCONNECT, + VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_KEEP, + + VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_LAST +}; + typedef struct _virDomainGraphicsAuthDef virDomainGraphicsAuthDef; typedef virDomainGraphicsAuthDef *virDomainGraphicsAuthDefPtr; struct _virDomainGraphicsAuthDef { char *passwd; unsigned int expires: 1; /* Whether there is an expiry time set */ time_t validTo; /* seconds since epoch */ + int connected; /* action if connected */ }; enum virDomainGraphicsSpiceChannelName { @@ -1514,6 +1524,7 @@ VIR_ENUM_DECL(virDomainHostdevSubsys) VIR_ENUM_DECL(virDomainInput) VIR_ENUM_DECL(virDomainInputBus) VIR_ENUM_DECL(virDomainGraphics) +VIR_ENUM_DECL(virDomainGraphicsAuthConnected) VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName) VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode) VIR_ENUM_DECL(virDomainGraphicsSpiceImageCompression) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 321df2a..bb331a3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -263,6 +263,8 @@ virDomainFindByID; virDomainFindByName; virDomainFindByUUID; virDomainGetRootFilesystem; +virDomainGraphicsAuthConnectedTypeFromString; +virDomainGraphicsAuthConnectedTypeToString; virDomainGraphicsDefFree; virDomainGraphicsSpiceChannelModeTypeFromString; virDomainGraphicsSpiceChannelModeTypeToString; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 3cf7d35..c0c4a15 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1017,10 +1017,12 @@ qemuDomainChangeGraphics(struct qemud_driver *driver, return -1; } - /* If a password lifetime was, or is set, then we must always run, - * even if new password matches old password */ + /* If a password lifetime was, or is set, or action if connected has + * changed, then we must always run, even if new password matches + * old password */ if (olddev->data.vnc.auth.expires || dev->data.vnc.auth.expires || + olddev->data.vnc.auth.connected != dev->data.vnc.auth.connected || STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd, dev->data.vnc.auth.passwd)) { VIR_DEBUG("Updating password on VNC server %p %p", dev->data.vnc.auth.passwd, driver->vncPassword); ret = qemuDomainChangeGraphicsPasswords(driver, vm, VIR_DOMAIN_GRAPHICS_TYPE_VNC, @@ -1032,6 +1034,7 @@ qemuDomainChangeGraphics(struct qemud_driver *driver, dev->data.vnc.auth.passwd = NULL; olddev->data.vnc.auth.validTo = dev->data.vnc.auth.validTo; olddev->data.vnc.auth.expires = dev->data.vnc.auth.expires; + olddev->data.vnc.auth.connected = dev->data.vnc.auth.connected; } else { ret = 0; } @@ -1060,6 +1063,7 @@ qemuDomainChangeGraphics(struct qemud_driver *driver, * even if new password matches old password */ if (olddev->data.spice.auth.expires || dev->data.spice.auth.expires || + olddev->data.spice.auth.connected != dev->data.spice.auth.connected || STRNEQ_NULLABLE(olddev->data.spice.auth.passwd, dev->data.spice.auth.passwd)) { VIR_DEBUG("Updating password on SPICE server %p %p", dev->data.spice.auth.passwd, driver->spicePassword); ret = qemuDomainChangeGraphicsPasswords(driver, vm, VIR_DOMAIN_GRAPHICS_TYPE_SPICE, @@ -1071,6 +1075,7 @@ qemuDomainChangeGraphics(struct qemud_driver *driver, dev->data.spice.auth.passwd = NULL; olddev->data.spice.auth.validTo = dev->data.spice.auth.validTo; olddev->data.spice.auth.expires = dev->data.spice.auth.expires; + olddev->data.spice.auth.connected = dev->data.spice.auth.connected; } else { VIR_DEBUG("Not updating since password didn't change"); ret = 0; @@ -1755,7 +1760,7 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver, ret = qemuMonitorSetPassword(priv->mon, type, auth->passwd ? auth->passwd : defaultPasswd, - NULL); + auth->connected ? virDomainGraphicsAuthConnectedTypeToString(auth->connected) : NULL); if (ret == -2) { if (type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) { -- 1.7.5.rc3

2011/5/30 Michal Privoznik <mprivozn@redhat.com>:
This option accepts 3 values: -keep, to keep current client connected (Spice+VNC) -disconnect, to disconnect client (Spice) -fail, to fail setting password if there is a client connected (Spice) --- docs/schemas/domain.rng | 16 ++++++++++++++++ src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 11 +++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_hotplug.c | 11 ++++++++--- 5 files changed, 78 insertions(+), 6 deletions(-)
Without reviewing this in detail, domain XML extensions must be documented, but you patch lacks documentation. Matthias

On 05/30/2011 09:45 AM, Michal Privoznik wrote:
This option accepts 3 values: -keep, to keep current client connected (Spice+VNC) -disconnect, to disconnect client (Spice) -fail, to fail setting password if there is a client connected (Spice) --- docs/schemas/domain.rng | 16 ++++++++++++++++ src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 11 +++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_hotplug.c | 11 ++++++++--- 5 files changed, 78 insertions(+), 6 deletions(-)
In addition to Matthias' correct note that we need a patch to docs/formatdomain.html.in,
+virDomainGraphicsAuthDefParseXML(xmlNodePtr node, + virDomainGraphicsAuthDefPtr def, + int type) { char *validTo = NULL; + char *connected = virXMLPropString(node, "connected");
def->passwd = virXMLPropString(node, "passwd");
@@ -3846,6 +3856,28 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node, virDomainGraphicsAuthDefPtr de def->expires = 1; }
+ if (connected) { + int action = virDomainGraphicsAuthConnectedTypeFromString(connected); + if (action < 0) { + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown connected value %s"),
Do we want to allow parsing "default"? If not, then change this to 'if (action <= 0)'.
@@ -1755,7 +1760,7 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver, ret = qemuMonitorSetPassword(priv->mon, type, auth->passwd ? auth->passwd : defaultPasswd, - NULL); + auth->connected ? virDomainGraphicsAuthConnectedTypeToString(auth->connected) : NULL);
Style - this results in a long line. It might be nicer to do: const char *connected = NULL; if (auth->connected) connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected); ... qemuMonitorSetPassword(priv->mon, type, auth->passwd ? auth->passwd : defaultPasswd, connected); This is a new XML feature, but has missed the rc1 freeze, so v2 should not be applied until after the 0.9.2 release, although you can post it for review before then. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On 05/31/2011 03:09 PM, Eric Blake wrote:
+ if (connected) { + int action = virDomainGraphicsAuthConnectedTypeFromString(connected); + if (action < 0) { + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown connected value %s"),
Do we want to allow parsing "default"? If not, then change this to 'if (action <= 0)'.
Still applicable to v2.
@@ -1755,7 +1760,7 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver, ret = qemuMonitorSetPassword(priv->mon, type, auth->passwd ? auth->passwd : defaultPasswd, - NULL); + auth->connected ? virDomainGraphicsAuthConnectedTypeToString(auth->connected) : NULL);
Style - this results in a long line. It might be nicer to do:
const char *connected = NULL; if (auth->connected) connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected); ... qemuMonitorSetPassword(priv->mon, type, auth->passwd ? auth->passwd : defaultPasswd, connected);
This is a new XML feature, but has missed the rc1 freeze, so v2 should not be applied until after the 0.9.2 release, although you can post it for review before then.
Serves me right for reading my inbox in order - I see you already posted v2: https://www.redhat.com/archives/libvir-list/2011-May/msg01871.html And now I'm wavering on whether this is a completely new feature, or enough of a bug-fix that we could get it into 0.9.2 anyways, since it is certainly minimal impact; so opinions from others would be helpful here. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
participants (3)
-
Eric Blake
-
Matthias Bolte
-
Michal Privoznik