From: Michal Privoznik <mprivozn@xxxxxxxxxx> 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) --- diff to v1: -Eric's review suggestions included -update 'Since' docs/formatdomain.html.in | 13 +++++++++++-- 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 | 15 ++++++++++++--- 6 files changed, 93 insertions(+), 8 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 225e0c8..5dd54ca 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1801,7 +1801,11 @@ qemu-kvm -net nic,model=? /dev/null in clear text. The <code>keymap</code> attribute specifies the keymap to use. It is possible to set a limit on the validity of the password be giving an timestamp <code>passwdValidTo='2010-04-09T15:51:00'</code> - assumed to be in UTC. NB, this may not be supported by all hypervisors.<br/> + assumed to be in UTC. <span class="since">Since 0.8.5</span> + The <code>connected</code> attribute allows control of connected client + during password changes. VNC accepts <code>keep</code> value only. + <span class="since">since 0.9.3</span> + NB, this may not be supported by all hypervisors.<br/> <br/> Rather than using listen/port, QEMU supports a <code>socket</code> attribute for listening on a unix domain socket path. @@ -1820,7 +1824,12 @@ qemu-kvm -net nic,model=? /dev/null in clear text. The <code>keymap</code> attribute specifies the keymap to use. It is possible to set a limit on the validity of the password be giving an timestamp <code>passwdValidTo='2010-04-09T15:51:00'</code> - assumed to be in UTC. NB, this may not be supported by all hypervisors. + assumed to be in UTC. <span class="since">Since 0.8.5</span> + The <code>connected</code> attribute allows control of connected client + during password changes. SPICE accepts <code>keep</code> to keep client + connected, <code>disconnect</code> to disconnect client and + <code>fail</code> to fail changing password. <span class="since">Since 0.9.3</span> + NB, this may not be supported by all hypervisors. <span class="since">"spice" since 0.8.6</span>. </p> <p> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 0be0371..e71b683 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1250,6 +1250,13 @@ <data type="dateTime"/> </attribute> </optional> + <optional> + <attribute name="connected"> + <choice> + <value>keep</value> + </choice> + </attribute> + </optional> </group> <group> <attribute name="type"> @@ -1293,6 +1300,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 0d9fef4..19f22e0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -311,6 +311,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", @@ -3892,9 +3899,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"); @@ -3935,6 +3945,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; } @@ -4004,7 +4036,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"); @@ -4140,7 +4173,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; @@ -9075,6 +9109,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 41c8136..6bfc337 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -640,12 +640,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 { @@ -1546,6 +1556,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 e6ab870..c3ce412 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -267,6 +267,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 fe47896..ead2cfc 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1059,10 +1059,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, @@ -1074,6 +1076,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; } @@ -1102,6 +1105,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, @@ -1113,6 +1117,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; @@ -1797,16 +1802,20 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver, qemuDomainObjPrivatePtr priv = vm->privateData; time_t now = time(NULL); char expire_time [64]; + const char *connected; int ret; if (!auth->passwd && !driver->vncPassword) return 0; + if (auth->connected) + connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected)l + qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorSetPassword(priv->mon, type, auth->passwd ? auth->passwd : defaultPasswd, - NULL); + connected); if (ret == -2) { if (type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) { -- 1.7.5.rc3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list