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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list