diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 563981d435c6b3ab073c9c34c4fe9936b3fc3b90..1ae5b36a5b64057a12fb61359ff73c3a1b0c8900 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1200,7 +1200,7 @@ - + @@ -1247,7 +1247,7 @@ - + @@ -1383,7 +1383,7 @@ - + @@ -2376,6 +2376,11 @@ ([0-2]?[0-9]?[0-9]\.){3}[0-2]?[0-9]?[0-9] + + + (([0-2]?[0-9]?[0-9]\.){3}[0-2]?[0-9]?[0-9])|(([0-9a-fA-F]+|:)+[0-9a-fA-F]+)|([a-zA-Z0-9_\.\+\-]*) + + (0x)?[0-9a-fA-F]{1,4} diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 839405f04983376ed71bd7c6985d1d396aff2222..316f0ec6f2d5a346d09fa62ac36e939e5d584b79 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3893,11 +3893,14 @@ qemuBuildCommandLine(virConnectPtr conn, def->graphics[0]->data.vnc.socket); } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) { - if (def->graphics[0]->data.vnc.listenAddr) - virBufferAdd(&opt, def->graphics[0]->data.vnc.listenAddr, -1); - else if (driver->vncListen) - virBufferAdd(&opt, driver->vncListen, -1); - + const char *addr = def->graphics[0]->data.vnc.listenAddr ? + def->graphics[0]->data.vnc.listenAddr : + driver->vncListen; + bool escapeAddr = strchr(addr, ':') != NULL; + if (escapeAddr) + virBufferAsprintf(&opt, "[%s]", addr); + else + virBufferAdd(&opt, addr, -1); virBufferAsprintf(&opt, ":%d", def->graphics[0]->data.vnc.port - 5900); @@ -5737,32 +5740,46 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC; if (STRPREFIX(val, "unix:")) { + /* -vnc unix:/some/big/path */ vnc->data.vnc.socket = strdup(val + 5); if (!vnc->data.vnc.socket) { VIR_FREE(vnc); goto no_memory; } } else { - tmp = strchr(val, ':'); - if (tmp) { - char *opts; - if (virStrToLong_i(tmp+1, &opts, 10, - &vnc->data.vnc.port) < 0) { - VIR_FREE(vnc); - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse VNC port '%s'"), tmp+1); - goto error; - } + /* + * -vnc 127.0.0.1:4 + * -vnc [2001:1:2:3:4:5:1234:1234]:4 + * -vnc some.host.name:4 + */ + char *opts; + const char *sep = ":"; + if (val[0] == '[') + sep = "]:"; + tmp = strstr(val, sep); + if (!tmp) { + VIR_FREE(vnc); + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("missing VNC port number in '%s'"), val); + goto error; + } + if (virStrToLong_i(tmp+strlen(sep), &opts, 10, + &vnc->data.vnc.port) < 0) { + VIR_FREE(vnc); + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot parse VNC port '%s'"), tmp+1); + goto error; + } + if (val[0] == '[') + vnc->data.vnc.listenAddr = strndup(val+1, tmp-(val+1)); + else vnc->data.vnc.listenAddr = strndup(val, tmp-val); - if (!vnc->data.vnc.listenAddr) { - VIR_FREE(vnc); - goto no_memory; - } - vnc->data.vnc.port += 5900; - vnc->data.vnc.autoport = 0; - } else { - vnc->data.vnc.autoport = 1; + if (!vnc->data.vnc.listenAddr) { + VIR_FREE(vnc); + goto no_memory; } + vnc->data.vnc.port += 5900; + vnc->data.vnc.autoport = 0; } if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args index 13aa1383c6cd5167005bfbc1eed4ed90f8a77829..2af154065c15afc2172c795c0d03960f9fe65590 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args @@ -1,4 +1,4 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ /usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor unix:/tmp/test-monitor,server,\ nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none \ --parallel none -usb -vnc 127.0.0.1:3 +-parallel none -usb -vnc [2001:1:2:3:4:5:1234:1234]:3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml index eb6be7d9253afad19ecc40eb5f0ea2a3006f6b19..6304104e6ca0d2f798e4275133bae2342aa3434d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml @@ -21,7 +21,7 @@ - +