Fix QEMU -vnc arg generation with raw IPv6 addresses

Since -vnc uses ':' to separate the address from the port, raw
IPv6 addresses need to be escaped like [addr]:port

* src/qemu/qemu_command.c: Escape raw IPv6 addresses with []
* tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args,
  tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml: Tweak
  to test Ipv6 escaping
* docs/schemas/domain.rng: Allow Ipv6 addresses, or hostnames
  in <graphics> listen attributes
This commit is contained in:
Daniel P. Berrange
2011-05-19 06:39:35 -04:00
parent 65e1acad80
commit 58765b58a3
4 changed files with 51 additions and 29 deletions

View File

@@ -1200,7 +1200,7 @@
</optional> </optional>
<optional> <optional>
<attribute name="listen"> <attribute name="listen">
<ref name="addrIP"/> <ref name="addrIPorName"/>
</attribute> </attribute>
</optional> </optional>
</group> </group>
@@ -1247,7 +1247,7 @@
</optional> </optional>
<optional> <optional>
<attribute name="listen"> <attribute name="listen">
<ref name="addrIP"/> <ref name="addrIPorName"/>
</attribute> </attribute>
</optional> </optional>
<optional> <optional>
@@ -1383,7 +1383,7 @@
</optional> </optional>
<optional> <optional>
<attribute name="listen"> <attribute name="listen">
<ref name="addrIP"/> <ref name="addrIPorName"/>
</attribute> </attribute>
</optional> </optional>
</group> </group>
@@ -2376,6 +2376,11 @@
<param name="pattern">([0-2]?[0-9]?[0-9]\.){3}[0-2]?[0-9]?[0-9]</param> <param name="pattern">([0-2]?[0-9]?[0-9]\.){3}[0-2]?[0-9]?[0-9]</param>
</data> </data>
</define> </define>
<define name="addrIPorName">
<data type="string">
<param name="pattern">(([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_\.\+\-]*)</param>
</data>
</define>
<define name="usbId"> <define name="usbId">
<data type="string"> <data type="string">
<param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param>

View File

@@ -3893,11 +3893,14 @@ qemuBuildCommandLine(virConnectPtr conn,
def->graphics[0]->data.vnc.socket); def->graphics[0]->data.vnc.socket);
} else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) { } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
if (def->graphics[0]->data.vnc.listenAddr) const char *addr = def->graphics[0]->data.vnc.listenAddr ?
virBufferAdd(&opt, def->graphics[0]->data.vnc.listenAddr, -1); def->graphics[0]->data.vnc.listenAddr :
else if (driver->vncListen) driver->vncListen;
virBufferAdd(&opt, driver->vncListen, -1); bool escapeAddr = strchr(addr, ':') != NULL;
if (escapeAddr)
virBufferAsprintf(&opt, "[%s]", addr);
else
virBufferAdd(&opt, addr, -1);
virBufferAsprintf(&opt, ":%d", virBufferAsprintf(&opt, ":%d",
def->graphics[0]->data.vnc.port - 5900); def->graphics[0]->data.vnc.port - 5900);
@@ -5737,32 +5740,46 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC; vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
if (STRPREFIX(val, "unix:")) { if (STRPREFIX(val, "unix:")) {
/* -vnc unix:/some/big/path */
vnc->data.vnc.socket = strdup(val + 5); vnc->data.vnc.socket = strdup(val + 5);
if (!vnc->data.vnc.socket) { if (!vnc->data.vnc.socket) {
VIR_FREE(vnc); VIR_FREE(vnc);
goto no_memory; goto no_memory;
} }
} else { } else {
tmp = strchr(val, ':'); /*
if (tmp) { * -vnc 127.0.0.1:4
char *opts; * -vnc [2001:1:2:3:4:5:1234:1234]:4
if (virStrToLong_i(tmp+1, &opts, 10, * -vnc some.host.name:4
&vnc->data.vnc.port) < 0) { */
VIR_FREE(vnc); char *opts;
qemuReportError(VIR_ERR_INTERNAL_ERROR, const char *sep = ":";
_("cannot parse VNC port '%s'"), tmp+1); if (val[0] == '[')
goto error; sep = "]:";
} tmp = strstr(val, sep);
vnc->data.vnc.listenAddr = strndup(val, tmp-val); if (!tmp) {
if (!vnc->data.vnc.listenAddr) { VIR_FREE(vnc);
VIR_FREE(vnc); qemuReportError(VIR_ERR_INTERNAL_ERROR,
goto no_memory; _("missing VNC port number in '%s'"), val);
} goto error;
vnc->data.vnc.port += 5900;
vnc->data.vnc.autoport = 0;
} else {
vnc->data.vnc.autoport = 1;
} }
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;
} }
if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) { if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) {

View File

@@ -1,4 +1,4 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ 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,\ /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 \ 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

View File

@@ -21,7 +21,7 @@
</disk> </disk>
<controller type='ide' index='0'/> <controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/> <input type='mouse' bus='ps2'/>
<graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> <graphics type='vnc' port='5903' autoport='no' listen='2001:1:2:3:4:5:1234:1234'/>
<video> <video>
<model type='cirrus' vram='9216' heads='1'/> <model type='cirrus' vram='9216' heads='1'/>
</video> </video>