[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