
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 :|