Detected in this valgrind run:
https://bugzilla.redhat.com/show_bug.cgi?id=690734
==13864== 10 bytes in 1 blocks are definitely lost in loss record 10 of 34
==13864== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==13864== by 0x308587FD91: strdup (in /lib64/libc-2.12.so)
==13864== by 0x3BB68BA0A3: doRemoteOpen (remote_driver.c:451)
==13864== by 0x3BB68BCFCF: remoteOpen (remote_driver.c:1111)
==13864== by 0x3BB689A0FF: do_open (libvirt.c:1290)
==13864== by 0x3BB689ADD5: virConnectOpenAuth (libvirt.c:1545)
==13864== by 0x41F659: main (virsh.c:11613)
* src/remote/remote_driver.c (doRemoteClose): Move up.
(remoteOpenSecondaryDriver, remoteOpen): Avoid leak on failure.
---
src/remote/remote_driver.c | 120 +++++++++++++++++++++++---------------------
1 files changed, 62 insertions(+), 58 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index b05bbcb..4c7df17 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -998,6 +998,64 @@ retry:
goto cleanup;
}
+static int
+doRemoteClose (virConnectPtr conn, struct private_data *priv)
+{
+ if (priv->eventFlushTimer >= 0) {
+ /* Remove timeout */
+ virEventRemoveTimeout(priv->eventFlushTimer);
+ /* Remove handle for remote events */
+ virEventRemoveHandle(priv->watch);
+ priv->watch = -1;
+ }
+
+ if (call (conn, priv, 0, REMOTE_PROC_CLOSE,
+ (xdrproc_t) xdr_void, (char *) NULL,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ /* Close socket. */
+ if (priv->uses_tls && priv->session) {
+ gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit (priv->session);
+ }
+#if HAVE_SASL
+ if (priv->saslconn)
+ sasl_dispose (&priv->saslconn);
+#endif
+ VIR_FORCE_CLOSE(priv->sock);
+ VIR_FORCE_CLOSE(priv->errfd);
+
+#ifndef WIN32
+ if (priv->pid > 0) {
+ pid_t reap;
+ do {
+retry:
+ reap = waitpid(priv->pid, NULL, 0);
+ if (reap == -1 && errno == EINTR)
+ goto retry;
+ } while (reap != -1 && reap != priv->pid);
+ }
+#endif
+ VIR_FORCE_CLOSE(priv->wakeupReadFD);
+ VIR_FORCE_CLOSE(priv->wakeupSendFD);
+
+
+ /* Free hostname copy */
+ VIR_FREE(priv->hostname);
+
+ /* See comment for remoteType. */
+ VIR_FREE(priv->type);
+
+ /* Free callback list */
+ virDomainEventCallbackListFree(priv->callbackList);
+
+ /* Free queued events */
+ virDomainEventQueueFree(priv->domainEvents);
+
+ return 0;
+}
+
static struct private_data *
remoteAllocPrivateData(void)
{
@@ -1039,7 +1097,9 @@ remoteOpenSecondaryDriver(virConnectPtr conn,
ret = doRemoteOpen(conn, *priv, auth, rflags);
if (ret != VIR_DRV_OPEN_SUCCESS) {
+ doRemoteClose(conn, *priv);
remoteDriverUnlock(*priv);
+ virMutexDestroy(&(*priv)->lock);
VIR_FREE(*priv);
} else {
(*priv)->localUses = 1;
@@ -1111,7 +1171,9 @@ remoteOpen (virConnectPtr conn,
ret = doRemoteOpen(conn, priv, auth, rflags);
if (ret != VIR_DRV_OPEN_SUCCESS) {
conn->privateData = NULL;
+ doRemoteClose(conn, priv);
remoteDriverUnlock(priv);
+ virMutexDestroy(&priv->lock);
VIR_FREE(priv);
} else {
conn->privateData = priv;
@@ -1538,64 +1600,6 @@ verify_certificate (virConnectPtr conn ATTRIBUTE_UNUSED,
static int
-doRemoteClose (virConnectPtr conn, struct private_data *priv)
-{
- if (priv->eventFlushTimer >= 0) {
- /* Remove timeout */
- virEventRemoveTimeout(priv->eventFlushTimer);
- /* Remove handle for remote events */
- virEventRemoveHandle(priv->watch);
- priv->watch = -1;
- }
-
- if (call (conn, priv, 0, REMOTE_PROC_CLOSE,
- (xdrproc_t) xdr_void, (char *) NULL,
- (xdrproc_t) xdr_void, (char *) NULL) == -1)
- return -1;
-
- /* Close socket. */
- if (priv->uses_tls && priv->session) {
- gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
- gnutls_deinit (priv->session);
- }
-#if HAVE_SASL
- if (priv->saslconn)
- sasl_dispose (&priv->saslconn);
-#endif
- VIR_FORCE_CLOSE(priv->sock);
- VIR_FORCE_CLOSE(priv->errfd);
-
-#ifndef WIN32
- if (priv->pid > 0) {
- pid_t reap;
- do {
-retry:
- reap = waitpid(priv->pid, NULL, 0);
- if (reap == -1 && errno == EINTR)
- goto retry;
- } while (reap != -1 && reap != priv->pid);
- }
-#endif
- VIR_FORCE_CLOSE(priv->wakeupReadFD);
- VIR_FORCE_CLOSE(priv->wakeupSendFD);
-
-
- /* Free hostname copy */
- VIR_FREE(priv->hostname);
-
- /* See comment for remoteType. */
- VIR_FREE(priv->type);
-
- /* Free callback list */
- virDomainEventCallbackListFree(priv->callbackList);
-
- /* Free queued events */
- virDomainEventQueueFree(priv->domainEvents);
-
- return 0;
-}
-
-static int
remoteClose (virConnectPtr conn)
{
int ret = 0;
--
1.7.4