[libvirt] [PATCH V3] Add proxy FS support to libvirt

Daniel P. Berrange berrange at redhat.com
Wed Aug 8 14:03:51 UTC 2012


On Sun, Aug 05, 2012 at 10:04:35AM +0530, M. Mohan Kumar wrote:
> @@ -2575,9 +2577,43 @@ error:
>      return NULL;
>  }
>  
> +/*
> + * Invokes the Proxy Helper with one of the socketpair as its parameter
> + *
> + */
> +static int qemuInvokeProxyHelper(const char *emulator, int sock, const char *path)
> +{
> +#define HELPER "virtfs-proxy-helper"
> +    int ret_val, status;
> +    virCommandPtr cmd;
> +    char *helper, *dname;
> +
> +    dname = dirname(strdup(emulator));

Missing check for NULL from strdup()

> +    if (virAsprintf(&helper, "%s/%s", dname, HELPER) < 0) {
> +        VIR_FREE(dname);
> +        virReportOOMError();
> +        return -1;

You must VIR_FORCE_CLOSE(sock) here, since other exit
paths will close it

> +    }

I think this is slightly bogus - and it'd be  better to
do  virFindFileInPath(HELPER), and if that doesn't work
then also look in /usr/libexec/$HELPER.

> +
> +    cmd = virCommandNewArgList(helper, NULL);
> +    virCommandAddArg(cmd, "-f");
> +    virCommandAddArgFormat(cmd, "%d", sock);
> +    virCommandAddArg(cmd, "-p");
> +    virCommandAddArgFormat(cmd, "%s", path);
> +    virCommandTransferFD(cmd, sock);
> +    virCommandDaemonize(cmd);
> +    ret_val = virCommandRun(cmd, &status);
> +    if (ret_val < 0)
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                            _("%s can't execute"), helper);
> +    virCommandFree(cmd);
> +    VIR_FREE(helper);
> +    VIR_FREE(dname);
> +    return ret_val;
> +}
>  
>  char *qemuBuildFSStr(virDomainFSDefPtr fs,
> -                     virBitmapPtr qemuCaps ATTRIBUTE_UNUSED)
> +                     virBitmapPtr qemuCaps ATTRIBUTE_UNUSED, int qemuSocket)
>  {
>      virBuffer opt = VIR_BUFFER_INITIALIZER;
>      const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
> @@ -2626,6 +2662,10 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
>      }
>  
>      virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
> +
> +    if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_PROXY)
> +        virBufferAsprintf(&opt, ",sock_fd=%d", qemuSocket);
> +
>      virBufferAsprintf(&opt, ",path=%s", fs->src);
>  
>      if (fs->readonly) {
> @@ -5081,10 +5121,35 @@ qemuBuildCommandLine(virConnectPtr conn,
>      if (qemuCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) {
>          for (i = 0 ; i < def->nfss ; i++) {
>              char *optstr;
> +            int sockets[2] = {-1, -1};
>              virDomainFSDefPtr fs = def->fss[i];
>  
> +            /*
> +             * If its a proxy FS, we need to create a socket pair
> +             * and invoke proxy_helper
> +             */
> +            if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_PROXY) {
> +                if (qemuCapsGet(qemuCaps, QEMU_CAPS_FSDEV_PROXY) < 0) {
> +                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                        _("proxy helper not supported"));
> +                    goto error;
> +                }
> +                /* create a socket pair */
> +                if (socketpair(PF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
> +                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",

Use 'virReportSystemError(errno...'

> +                        _("socketpair failed"));
> +                    goto error;
> +                }
> +                virCommandTransferFD(cmd, sockets[1]);
> +                if (qemuInvokeProxyHelper(def->emulator, sockets[0],
> +                                    fs->src) < 0) {
> +                    VIR_FORCE_CLOSE(sockets[0]);
> +                    VIR_FORCE_CLOSE(sockets[1]);

You've already given sockets[i] to virCommandPtr, so that
will take care of closing it when virCommandFree is called.

Liekwise qemuInvokeProxyHelper passes sockets[0] to 
another virCommandPtr so it will get closed on some, but
not all exit paths.

So remove both these VIR_FORCE_CLOSE lines

> +                    goto error;
> +                }
> +            }
>              virCommandAddArg(cmd, "-fsdev");
> -            if (!(optstr = qemuBuildFSStr(fs, qemuCaps)))
> +            if (!(optstr = qemuBuildFSStr(fs, qemuCaps, sockets[1])))
>                  goto error;
>              virCommandAddArg(cmd, optstr);
>              VIR_FREE(optstr);

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list