[libvirt] [PATCHv2] qemu: escape ipv6 for rbd network disk hosts
Osier Yang
jyang at redhat.com
Fri Jan 25 05:24:57 UTC 2013
On 2013年01月25日 10:45, Josh Durgin wrote:
> Hosts for rbd are ceph monitor daemons. These have fixed IP addresses,
> so they are often referenced by IP rather than hostname for
> convenience, or to avoid relying on DNS. Using IPv4 addresses as the
> host name works already, but IPv6 addresses require rbd-specific
> escaping because the colon is used as an option separator in the
> string passed to qemu.
>
> Escape these colons, and enclose the IPv6 address in square brackets
> so it is distinguished from the port, which is currently mandatory.
>
> Acked-by: Osier Yang<jyang at redhat.com>
> Signed-off-by: Josh Durgin<josh.durgin at inktank.com>
> ---
>
> Since v1, in response to Osier's review:
> - corrected commit message
> - eliminated extra call to strstr() in qemuAddRBDHost
>
> docs/schemas/domaincommon.rng | 5 ++-
> src/qemu/qemu_command.c | 33 ++++++++++++++----
> tests/qemuargv2xmltest.c | 1 +
> .../qemuxml2argv-disk-drive-network-rbd-ipv6.args | 9 +++++
> .../qemuxml2argv-disk-drive-network-rbd-ipv6.xml | 36 ++++++++++++++++++++
> tests/qemuxml2argvtest.c | 2 +
> 6 files changed, 78 insertions(+), 8 deletions(-)
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.args
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.xml
>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 7f3320e..273e54c 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -1099,7 +1099,10 @@
> </attribute>
> </optional>
> <attribute name="name">
> -<ref name="dnsName"/>
> +<choice>
> +<ref name="dnsName"/>
> +<ref name="ipAddr"/>
> +</choice>
> </attribute>
> <attribute name="port">
> <ref name="unsignedInt"/>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 02fe015..f6273c1 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -34,6 +34,7 @@
> #include "virerror.h"
> #include "virutil.h"
> #include "virfile.h"
> +#include "virstring.h"
> #include "viruuid.h"
> #include "c-ctype.h"
> #include "domain_nwfilter.h"
> @@ -1937,13 +1938,16 @@ qemuBuildRBDString(virConnectPtr conn,
> if (i) {
> virBufferAddLit(opt, "\\;");
> }
> - if (disk->hosts[i].port) {
> - virBufferAsprintf(opt, "%s\\:%s",
> - disk->hosts[i].name,
> - disk->hosts[i].port);
> +
> + /* assume host containing : is ipv6 */
> + if (strchr(disk->hosts[i].name, ':')) {
> + virBufferEscape(opt, '\\', ":", "[%s]", disk->hosts[i].name);
> } else {
> virBufferAsprintf(opt, "%s", disk->hosts[i].name);
> }
> + if (disk->hosts[i].port) {
> + virBufferAsprintf(opt, "\\:%s", disk->hosts[i].port);
> + }
> }
> }
>
> @@ -1961,15 +1965,25 @@ error:
> static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport)
> {
> char *port;
> + size_t skip;
> + char **parts;
>
> disk->nhosts++;
> if (VIR_REALLOC_N(disk->hosts, disk->nhosts)< 0)
> goto no_memory;
>
> - port = strstr(hostport, "\\:");
> + if ((port = strchr(hostport, ']'))) {
> + /* ipv6, strip brackets */
> + hostport += 1;
> + skip = 3;
> + } else {
> + port = strstr(hostport, "\\:");
> + skip = 2;
> + }
> +
> if (port) {
> *port = '\0';
> - port += 2;
> + port += skip;
> disk->hosts[disk->nhosts-1].port = strdup(port);
> if (!disk->hosts[disk->nhosts-1].port)
> goto no_memory;
> @@ -1978,7 +1992,12 @@ static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport)
> if (!disk->hosts[disk->nhosts-1].port)
> goto no_memory;
> }
> - disk->hosts[disk->nhosts-1].name = strdup(hostport);
> +
> + parts = virStringSplit(hostport, "\\:", 0);
> + if (!parts)
> + goto no_memory;
> + disk->hosts[disk->nhosts-1].name = virStringJoin((const char **)parts, ":");
> + virStringFreeList(parts);
> if (!disk->hosts[disk->nhosts-1].name)
> goto no_memory;
>
> diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
> index 2923324..e465f3d 100644
> --- a/tests/qemuargv2xmltest.c
> +++ b/tests/qemuargv2xmltest.c
> @@ -185,6 +185,7 @@ mymain(void)
> DO_TEST("disk-drive-network-nbd");
> DO_TEST("disk-drive-network-gluster");
> DO_TEST("disk-drive-network-rbd");
> + DO_TEST("disk-drive-network-rbd-ipv6");
> /* older format using CEPH_ARGS env var */
> DO_TEST("disk-drive-network-rbd-ceph-env");
> DO_TEST("disk-drive-network-sheepdog");
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.args
> new file mode 100644
> index 0000000..0c67229
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.args
> @@ -0,0 +1,9 @@
> +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
> +/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor \
> +unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -drive \
> +file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive \
> +'file=rbd:pool/image:auth_supported=none:\
> +mon_host=[\:\:1]\:6321\;example.org\:6789\;\
> +[ffff\:1234\:567\:abc\:\:0f]\:6322\;\
> +[2001\:db8\:\:ff00\:42\:8329]\:6322,\
> +if=virtio,format=raw' -net none -serial none -parallel none
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.xml
> new file mode 100644
> index 0000000..a2ca2d2
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-ipv6.xml
> @@ -0,0 +1,36 @@
> +<domain type='qemu'>
> +<name>QEMUGuest1</name>
> +<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
> +<memory unit='KiB'>219136</memory>
> +<currentMemory unit='KiB'>219136</currentMemory>
> +<vcpu placement='static'>1</vcpu>
> +<os>
> +<type arch='i686' machine='pc'>hvm</type>
> +<boot dev='hd'/>
> +</os>
> +<clock offset='utc'/>
> +<on_poweroff>destroy</on_poweroff>
> +<on_reboot>restart</on_reboot>
> +<on_crash>destroy</on_crash>
> +<devices>
> +<emulator>/usr/bin/qemu</emulator>
> +<disk type='block' device='disk'>
> +<source dev='/dev/HostVG/QEMUGuest1'/>
> +<target dev='hda' bus='ide'/>
> +<address type='drive' controller='0' bus='0' target='0' unit='0'/>
> +</disk>
> +<disk type='network' device='disk'>
> +<driver name='qemu' type='raw'/>
> +<source protocol='rbd' name='pool/image'>
> +<host name='::1' port='6321'/>
> +<host name='example.org' port='6789'/>
> +<host name='ffff:1234:567:abc::0f' port='6322'/>
> +<host name='2001:db8::ff00:42:8329' port='6322'/>
> +</source>
> +<target dev='vda' bus='virtio'/>
> +</disk>
> +<controller type='usb' index='0'/>
> +<controller type='ide' index='0'/>
> +<memballoon model='virtio'/>
> +</devices>
> +</domain>
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index 31ed116..88e1c36 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -478,6 +478,8 @@ mymain(void)
> QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
> DO_TEST("disk-drive-network-rbd-auth",
> QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
> + DO_TEST("disk-drive-network-rbd-ipv6",
> + QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
> DO_TEST("disk-drive-no-boot",
> QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_BOOTINDEX);
> DO_TEST("disk-usb", NONE);
Though now it's already in freezing. But I guess you will want the
feature as soon as posible, and I don't think it could cause any problem
for the build, so pushed.
Osier
More information about the libvir-list
mailing list