On 01/09/2013 07:54 AM, John Ferlan wrote: > The phypUUIDTable_Push and phypUUIDTable_Pull leaked their fd's on normal > return. I also noted that the Read function had a cut-n-paste error from > the write function on a couple of VIR_WARN's > > The openSSHSession leaked the sock on the failure path. Additionally that > turns into the internal_socket in the phypOpen code. That was neither saved > nor closed on any path. So I used the connnection_data->sock field to save > the socket for eventual close. Of interest here is that phypExec used the > connection_data->sock field even though it had never been initialized. > --- > src/phyp/phyp_driver.c | 19 ++++++++++++++----- > 1 file changed, 14 insertions(+), 5 deletions(-) > > diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c > index f89871f..b74cab8 100644 > --- a/src/phyp/phyp_driver.c > +++ b/src/phyp/phyp_driver.c > @@ -577,6 +577,7 @@ phypUUIDTable_Push(virConnectPtr conn) > libssh2_channel_free(channel); > channel = NULL; > } > + VIR_FORCE_FCLOSE(fd); Who named their FILE* 'fd' anyways? But not your fault that you are trying to clean up some notoriously hairy code. > virBufferFreeAndReset(&username); > return 0; Hmm, the code feels rather repetitive: if (channel) { libssh2_channel_send_eof(channel); libssh2_channel_wait_eof(channel); libssh2_channel_wait_closed(channel); libssh2_channel_free(channel); channel = NULL; } VIR_FORCE_FCLOSE(fd); virBufferFreeAndReset(&username); return 0; err: if (channel) { libssh2_channel_send_eof(channel); libssh2_channel_wait_eof(channel); libssh2_channel_wait_closed(channel); libssh2_channel_free(channel); channel = NULL; } VIR_FORCE_FCLOSE(fd); return -1; } Also, the virBufferFreeAndReset(&username) on the success path is useless (the only way to get there is if username was already freed earlier), and the rest of the code is identical except for the return value. Oh, and the entire 'username' variable is pointless - it is either empty or precisely conn->uri->user; no need to malloc a buffer to copy a string when we can just use the string directly. How about we do this instead: diff --git i/src/phyp/phyp_driver.c w/src/phyp/phyp_driver.c index f89871f..87a94c0 100644 --- i/src/phyp/phyp_driver.c +++ w/src/phyp/phyp_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Red Hat, Inc. + * Copyright (C) 2010-2013 Red Hat, Inc. * Copyright IBM Corp. 2009 * * phyp_driver.c: ssh layer to access Power Hypervisors @@ -493,42 +493,30 @@ phypUUIDTable_Push(virConnectPtr conn) ConnectionData *connection_data = conn->networkPrivateData; LIBSSH2_SESSION *session = connection_data->session; LIBSSH2_CHANNEL *channel = NULL; - virBuffer username = VIR_BUFFER_INITIALIZER; struct stat local_fileinfo; char buffer[1024]; int rc = 0; - FILE *fd = NULL; + FILE *f = NULL; size_t nread, sent; char *ptr; char local_file[] = "./uuid_table"; char *remote_file = NULL; + int ret = -1; - if (conn->uri->user != NULL) { - virBufferAdd(&username, conn->uri->user, -1); - - if (virBufferError(&username)) { - virBufferFreeAndReset(&username); - virReportOOMError(); - goto err; - } - } - - if (virAsprintf - (&remote_file, "/home/%s/libvirt_uuid_table", - virBufferContentAndReset(&username)) - < 0) { + if (virAsprintf(&remote_file, "/home/%s/libvirt_uuid_table", + NULLSTR(conn->uri->user)) < 0) { virReportOOMError(); - goto err; + goto cleanup; } if (stat(local_file, &local_fileinfo) == -1) { VIR_WARN("Unable to stat local file."); - goto err; + goto cleanup; } - if (!(fd = fopen(local_file, "rb"))) { + if (!(f = fopen(local_file, "rb"))) { VIR_WARN("Unable to open local file."); - goto err; + goto cleanup; } do { @@ -539,18 +527,18 @@ phypUUIDTable_Push(virConnectPtr conn) if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) - goto err; + goto cleanup; } while (!channel); do { - nread = fread(buffer, 1, sizeof(buffer), fd); + nread = fread(buffer, 1, sizeof(buffer), f); if (nread <= 0) { - if (feof(fd)) { + if (feof(f)) { /* end of file */ break; } else { VIR_ERROR(_("Failed to read from %s"), local_file); - goto err; + goto cleanup; } } ptr = buffer; @@ -570,17 +558,9 @@ phypUUIDTable_Push(virConnectPtr conn) } while (rc > 0 && sent < nread); } while (1); - if (channel) { - libssh2_channel_send_eof(channel); - libssh2_channel_wait_eof(channel); - libssh2_channel_wait_closed(channel); - libssh2_channel_free(channel); - channel = NULL; - } - virBufferFreeAndReset(&username); - return 0; + ret = 0; -err: +cleanup: if (channel) { libssh2_channel_send_eof(channel); libssh2_channel_wait_eof(channel); @@ -588,8 +568,8 @@ err: libssh2_channel_free(channel); channel = NULL; } - VIR_FORCE_FCLOSE(fd); - return -1; + VIR_FORCE_FCLOSE(f); + return ret; } static int [I didn't look at the rest of the patch, I was so distracted by the poor quality of this one function] -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list