CEPH filesystem development
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Cc: libvir-list@redhat.com, sheepdog@lists.wpkg.org,
	ceph-devel@vger.kernel.org
Subject: Re: [PATCH] add network disk support
Date: Thu, 2 Dec 2010 13:19:28 +0000	[thread overview]
Message-ID: <20101202131928.GV2502@redhat.com> (raw)
In-Reply-To: <1290718196-14080-1-git-send-email-morita.kazutaka@lab.ntt.co.jp>

On Fri, Nov 26, 2010 at 05:49:56AM +0900, MORITA Kazutaka wrote:
> This patch adds network disk support to libvirt/QEMU.  The currently
> supported protcols are nbd, rbd, and sheepdog.  The XML syntax is like
> this:
> 
>     <disk type="network" device="disk">
>       <driver name="qemu" type="raw" />
>       <source protocol='rbd|sheepdog|nbd' name="...some image identifier...">
>         <host name="mon1.example.org" port="6000">
>         <host name="mon2.example.org" port="6000">
>         <host name="mon3.example.org" port="6000">
>       </source>
>       <target dev="vda" bus="virtio" />
>     </disk>

This design looks good to me.

> 
> Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
> ---
> 
> This patch addresses the discussion on
>   https://www.redhat.com/archives/libvir-list/2010-November/msg00759.html
> 
> Josh mentioned that the monitor hostnames of RBD can be set through
> the environment variables, but I couldn't find any documentations
> about it, so the monitors are not set in this patch.  I hope someone
> who is familiar with RBD implements it.
> 
> @@ -1620,6 +1629,30 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>                  case VIR_DOMAIN_DISK_TYPE_DIR:
>                      source = virXMLPropString(cur, "dir");
>                      break;
> +                case VIR_DOMAIN_DISK_TYPE_NETWORK:
> +                    protocol = virXMLPropString(cur, "protocol");
> +                    if (protocol == NULL) {
> +                        virDomainReportError(VIR_ERR_XML_ERROR,
> +                                             "%s", _("missing protocol type"));
> +                        break;
> +                    }
> +                    def->protocol = virDomainDiskProtocolTypeFromString(protocol);

Should check for def->protocal < 0 & raise an error, which
would indicate that 'protocol' was not one of the expected
values.

> +                    source = virXMLPropString(cur, "name");
> +                    host = cur->children;
> +                    while (host != NULL) {
> +                        if (host->type == XML_ELEMENT_NODE &&
> +                            xmlStrEqual(host->name, BAD_CAST "host")) {
> +                            if (VIR_REALLOC_N(hosts, def->nhosts + 1) < 0) {
> +                                virReportOOMError();
> +                                goto error;
> +                            }
> +                            hosts[def->nhosts].name = virXMLPropString(host, "name");
> +                            hosts[def->nhosts].port = virXMLPropString(host, "port");
> +                            def->nhosts++;

Ought to check for NULLs returned by virXMLPropString here
I think.


> +                        }
> +                        host = host->next;
> +                    }
> +                    break;
>                  default:
>                      virDomainReportError(VIR_ERR_INTERNAL_ERROR,
>                                           _("unexpected disk type %s"),
> @@ -1685,7 +1718,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>  
>      /* Only CDROM and Floppy devices are allowed missing source path
>       * to indicate no media present */
> -    if (source == NULL &&
> +    if (source == NULL && hosts == NULL &&
>          def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
>          def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
>          virDomainReportError(VIR_ERR_NO_SOURCE,
> @@ -1791,6 +1824,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>      source = NULL;
>      def->dst = target;
>      target = NULL;
> +    def->hosts = hosts;
> +    hosts = NULL;
>      def->driverName = driverName;
>      driverName = NULL;
>      def->driverType = driverType;
> @@ -1819,6 +1854,8 @@ cleanup:
>      VIR_FREE(type);
>      VIR_FREE(target);
>      VIR_FREE(source);
> +    VIR_FREE(hosts);

I think you need to free the fields inside 'hosts' too, otherwise
we'd leak memory for the port + host strings in the error path.

> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index 35caccc..63abd75 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -2714,7 +2714,7 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
>          break;
>      }
>  
> -    if (disk->src) {
> +    if (disk->src || disk->nhosts > 0) {

If you check for nhosts > 0 here

>          if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
>              /* QEMU only supports magic FAT format for now */
>              if (disk->driverType &&
> @@ -2733,6 +2733,24 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
>                  virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src);
>              else
>                  virBufferVSprintf(&opt, "file=fat:%s,", disk->src);
> +        } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
> +            switch (disk->protocol) {
> +            case VIR_DOMAIN_DISK_PROTOCOL_NBD:
> +                virBufferVSprintf(&opt, "file=nbd:%s:%s,",
> +                                  disk->hosts->name, disk->hosts->port);
> +                break;
> +            case VIR_DOMAIN_DISK_PROTOCOL_RBD:
> +                virBufferVSprintf(&opt, "file=rbd:%s,", disk->src);
> +                break;
> +            case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
> +                if (disk->nhosts > 0)
> +                    virBufferVSprintf(&opt, "file=sheepdog:%s:%s:%s,",
> +                                      disk->hosts->name, disk->hosts->port,
> +                                      disk->src);
> +                else
> +                    virBufferVSprintf(&opt, "file=sheepdog:%s,", disk->src);
> +                break;

This else branch for sheepdog will never execute. So I think
it is better to check the nhosts value in each of these
conditionals. eg We should report an error if nhosts == 0,
or nhosts > 1 for NBD since it only wants 1 host. Likewise
for other protocols as nedeed.

> @@ -5794,7 +5830,67 @@ qemuParseCommandLineDisk(virCapsPtr caps,
>                  values[i] = NULL;
>                  if (STRPREFIX(def->src, "/dev/"))
>                      def->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
> -                else
> +                else if (STRPREFIX(def->src, "nbd:")) {
> +                    char *host, *port;
> +
> +                    def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
> +                    host = def->src + strlen("nbd:");
> +                    port = strchr(host, ':');
> +                    if (!port) {
> +                        def = NULL;
> +                        qemuReportError(VIR_ERR_INTERNAL_ERROR,
> +                                        _("cannot parse nbd filename '%s'"), def->src);
> +                        goto cleanup;
> +                    }
> +                    *port++ = '\0';
> +                    if (VIR_ALLOC(def->hosts) < 0) {
> +                        virReportOOMError();
> +                        goto cleanup;
> +                    }
> +                    def->nhosts = 1;
> +                    def->hosts->name = strdup(host);
> +                    def->hosts->port = strdup(port);

Should check for NULL in both of these strdup cases.

> +
> +                    VIR_FREE(def->src);
> +                    def->src = NULL;
> +                } else if (STRPREFIX(def->src, "rbd:")) {
> +                    char *p = def->src;
> +
> +                    def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
> +                    def->src = strdup(p + strlen("rbd:"));

And this one, and a few more strdup's later in the patch.

Regards,
Daniel

  reply	other threads:[~2010-12-02 13:19 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-25 20:49 [PATCH] add network disk support MORITA Kazutaka
2010-12-02 13:19 ` Daniel P. Berrange [this message]
     [not found]   ` <20101202131928.GV2502-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-12-06  7:24     ` [PATCH v2] " MORITA Kazutaka
2010-12-07 19:54       ` [PATCH 0/2] rbd " Josh Durgin
     [not found]       ` <1291620249-19645-1-git-send-email-morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2010-12-07 19:56         ` [PATCH 1/2] qemu: Add RBD support and some network disk fixes Josh Durgin
2010-12-09 11:10           ` [libvirt] " Daniel P. Berrange
2010-12-07 19:57       ` [PATCH 2/2] tests: Add tests for network disks Josh Durgin
2010-12-09 11:10         ` [libvirt] " Daniel P. Berrange
2010-12-09 11:09       ` [PATCH v2] add network disk support Daniel P. Berrange
2010-12-09 19:13         ` [libvirt] " Eric Blake
2010-12-09 21:31           ` Eric Blake

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101202131928.GV2502@redhat.com \
    --to=berrange@redhat.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=libvir-list@redhat.com \
    --cc=morita.kazutaka@lab.ntt.co.jp \
    --cc=sheepdog@lists.wpkg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox