Blame SOURCES/redhat-bugzilla-2135314-pmfind-fix.patch

952062
diff -Naurp pcp-5.3.7.orig/qa/1985 pcp-5.3.7/qa/1985
952062
--- pcp-5.3.7.orig/qa/1985	1970-01-01 10:00:00.000000000 +1000
952062
+++ pcp-5.3.7/qa/1985	2022-10-19 21:32:03.971832371 +1100
952062
@@ -0,0 +1,38 @@
952062
+#!/bin/sh
952062
+# PCP QA Test No. 1985
952062
+# Exercise a pmfind fix - valgrind-enabled variant.
952062
+#
952062
+# Copyright (c) 2022 Red Hat.  All Rights Reserved.
952062
+#
952062
+
952062
+seq=`basename $0`
952062
+echo "QA output created by $seq"
952062
+
952062
+# get standard environment, filters and checks
952062
+. ./common.product
952062
+. ./common.filter
952062
+. ./common.check
952062
+
952062
+_check_valgrind
952062
+
952062
+_cleanup()
952062
+{
952062
+    cd $here
952062
+    $sudo rm -rf $tmp $tmp.*
952062
+}
952062
+
952062
+status=0	# success is the default!
952062
+$sudo rm -rf $tmp $tmp.* $seq.full
952062
+trap "_cleanup; exit \$status" 0 1 2 3 15
952062
+
952062
+# real QA test starts here
952062
+export seq
952062
+./1986 --valgrind \
952062
+| $PCP_AWK_PROG '
952062
+skip == 1 && $1 == "==="       { skip = 0 }
952062
+/^=== std err ===/             { skip = 1 }
952062
+skip == 0              { print }
952062
+skip == 1              { print >>"'$here/$seq.full'" }'
952062
+
952062
+# success, all done
952062
+exit
952062
diff -Naurp pcp-5.3.7.orig/qa/1985.out pcp-5.3.7/qa/1985.out
952062
--- pcp-5.3.7.orig/qa/1985.out	1970-01-01 10:00:00.000000000 +1000
952062
+++ pcp-5.3.7/qa/1985.out	2022-10-19 21:32:03.971832371 +1100
952062
@@ -0,0 +1,11 @@
952062
+QA output created by 1985
952062
+QA output created by 1986 --valgrind
952062
+=== std out ===
952062
+SOURCE HOSTNAME
952062
+=== filtered valgrind report ===
952062
+Memcheck, a memory error detector
952062
+Command: pmfind -S -m probe=127.0.0.1/32
952062
+LEAK SUMMARY:
952062
+definitely lost: 0 bytes in 0 blocks
952062
+indirectly lost: 0 bytes in 0 blocks
952062
+ERROR SUMMARY: 0 errors from 0 contexts ...
952062
diff -Naurp pcp-5.3.7.orig/qa/1986 pcp-5.3.7/qa/1986
952062
--- pcp-5.3.7.orig/qa/1986	1970-01-01 10:00:00.000000000 +1000
952062
+++ pcp-5.3.7/qa/1986	2022-10-19 21:32:03.971832371 +1100
952062
@@ -0,0 +1,62 @@
952062
+#!/bin/sh
952062
+# PCP QA Test No. 1986
952062
+# Exercise libpcp_web timers pmfind regression fix.
952062
+#
952062
+# Copyright (c) 2022 Red Hat.  All Rights Reserved.
952062
+#
952062
+
952062
+if [ $# -eq 0 ]
952062
+then
952062
+    seq=`basename $0`
952062
+    echo "QA output created by $seq"
952062
+else
952062
+    # use $seq from caller, unless not set
952062
+    [ -n "$seq" ] || seq=`basename $0`
952062
+    echo "QA output created by `basename $0` $*"
952062
+fi
952062
+
952062
+# get standard environment, filters and checks
952062
+. ./common.product
952062
+. ./common.filter
952062
+. ./common.check
952062
+
952062
+do_valgrind=false
952062
+if [ "$1" = "--valgrind" ]
952062
+then
952062
+    _check_valgrind
952062
+    do_valgrind=true
952062
+fi
952062
+
952062
+test -x $PCP_BIN_DIR/pmfind || _notrun No support for pmfind
952062
+
952062
+_cleanup()
952062
+{
952062
+    cd $here
952062
+    $sudo rm -rf $tmp $tmp.*
952062
+}
952062
+
952062
+status=0	# success is the default!
952062
+hostname=`hostname || echo localhost`
952062
+$sudo rm -rf $tmp $tmp.* $seq.full
952062
+trap "_cleanup; exit \$status" 0 1 2 3 15
952062
+
952062
+_filter()
952062
+{
952062
+    sed \
952062
+	-e "s@$tmp@TMP@g" \
952062
+	-e "s/ $hostname/ HOSTNAME/" \
952062
+	-e 's/^[a-f0-9][a-f0-9]* /SOURCE /' \
952062
+    # end
952062
+}
952062
+
952062
+# real QA test starts here
952062
+if $do_valgrind
952062
+then
952062
+    _run_valgrind pmfind -S -m probe=127.0.0.1/32
952062
+else
952062
+    pmfind -S -m probe=127.0.0.1/32
952062
+fi \
952062
+| _filter
952062
+
952062
+# success, all done
952062
+exit
952062
diff -Naurp pcp-5.3.7.orig/qa/1986.out pcp-5.3.7/qa/1986.out
952062
--- pcp-5.3.7.orig/qa/1986.out	1970-01-01 10:00:00.000000000 +1000
952062
+++ pcp-5.3.7/qa/1986.out	2022-10-19 21:32:03.971832371 +1100
952062
@@ -0,0 +1,2 @@
952062
+QA output created by 1986
952062
+SOURCE HOSTNAME
952062
diff -Naurp pcp-5.3.7.orig/qa/group pcp-5.3.7/qa/group
952062
--- pcp-5.3.7.orig/qa/group	2022-10-19 20:49:42.638708707 +1100
952062
+++ pcp-5.3.7/qa/group	2022-10-19 21:32:03.972832359 +1100
952062
@@ -1974,4 +1974,6 @@ x11
952062
 1957 libpcp local valgrind
952062
 1978 atop local
952062
 1984 pmlogconf pmda.redis local
952062
+1985 pmfind local valgrind
952062
+1986 pmfind local
952062
 4751 libpcp threads valgrind local pcp helgrind
952062
diff -Naurp pcp-5.3.7.orig/src/libpcp_web/src/webgroup.c pcp-5.3.7/src/libpcp_web/src/webgroup.c
952062
--- pcp-5.3.7.orig/src/libpcp_web/src/webgroup.c	2021-11-01 13:02:26.000000000 +1100
952062
+++ pcp-5.3.7/src/libpcp_web/src/webgroup.c	2022-10-19 21:32:03.973832346 +1100
952062
@@ -287,11 +287,24 @@ webgroup_new_context(pmWebGroupSettings
952062
 }
952062
 
952062
 static void
952062
+webgroup_timers_stop(struct webgroups *groups)
952062
+{
952062
+    if (groups->active) {
952062
+	uv_timer_stop(&groups->timer);
952062
+	uv_close((uv_handle_t *)&groups->timer, NULL);
952062
+	pmWebTimerRelease(groups->timerid);
952062
+	groups->timerid = -1;
952062
+	groups->active = 0;
952062
+    }
952062
+}
952062
+
952062
+static void
952062
 webgroup_garbage_collect(struct webgroups *groups)
952062
 {
952062
     dictIterator        *iterator;
952062
     dictEntry           *entry;
952062
     context_t		*cp;
952062
+    unsigned int	count = 0, drops = 0;
952062
 
952062
     if (pmDebugOptions.http || pmDebugOptions.libweb)
952062
 	fprintf(stderr, "%s: started\n", "webgroup_garbage_collect");
952062
@@ -308,33 +321,40 @@ webgroup_garbage_collect(struct webgroup
952062
 		uv_mutex_unlock(&groups->mutex);
952062
 		webgroup_drop_context(cp, groups);
952062
 		uv_mutex_lock(&groups->mutex);
952062
+		drops++;
952062
 	    }
952062
+	    count++;
952062
 	}
952062
 	dictReleaseIterator(iterator);
952062
+
952062
+	/* if dropping the last remaining context, do cleanup */
952062
+	if (groups->active && drops == count) {
952062
+	    if (pmDebugOptions.http || pmDebugOptions.libweb)
952062
+		fprintf(stderr, "%s: freezing\n", "webgroup_garbage_collect");
952062
+	    webgroup_timers_stop(groups);
952062
+	}
952062
 	uv_mutex_unlock(&groups->mutex);
952062
     }
952062
 
952062
     if (pmDebugOptions.http || pmDebugOptions.libweb)
952062
-	fprintf(stderr, "%s: finished\n", "webgroup_garbage_collect");
952062
+	fprintf(stderr, "%s: finished [%u drops from %u entries]\n",
952062
+			"webgroup_garbage_collect", drops, count);
952062
 }
952062
 
952062
 static void
952062
 refresh_maps_metrics(void *data)
952062
 {
952062
     struct webgroups	*groups = (struct webgroups *)data;
952062
+    unsigned int	value;
952062
 
952062
-    if (groups->metrics) {
952062
-	unsigned int	value;
952062
-
952062
-	value = dictSize(contextmap);
952062
-	mmv_set(groups->map, groups->metrics[CONTEXT_MAP_SIZE], &value);
952062
-	value = dictSize(namesmap);
952062
-	mmv_set(groups->map, groups->metrics[NAMES_MAP_SIZE], &value);
952062
-	value = dictSize(labelsmap);
952062
-	mmv_set(groups->map, groups->metrics[LABELS_MAP_SIZE], &value);
952062
-	value = dictSize(instmap);
952062
-	mmv_set(groups->map, groups->metrics[INST_MAP_SIZE], &value);
952062
-    }
952062
+    value = contextmap? dictSize(contextmap) : 0;
952062
+    mmv_set(groups->map, groups->metrics[CONTEXT_MAP_SIZE], &value);
952062
+    value = namesmap? dictSize(namesmap) : 0;
952062
+    mmv_set(groups->map, groups->metrics[NAMES_MAP_SIZE], &value);
952062
+    value = labelsmap? dictSize(labelsmap) : 0;
952062
+    mmv_set(groups->map, groups->metrics[LABELS_MAP_SIZE], &value);
952062
+    value = instmap? dictSize(instmap) : 0;
952062
+    mmv_set(groups->map, groups->metrics[INST_MAP_SIZE], &value);
952062
 }
952062
 
952062
 static void
952062
@@ -487,6 +507,7 @@ pmWebGroupDestroy(pmWebGroupSettings *se
952062
 	if (pmDebugOptions.libweb)
952062
 	    fprintf(stderr, "%s: destroy context %p gp=%p\n", "pmWebGroupDestroy", cp, gp);
952062
 
952062
+	webgroup_deref_context(cp);
952062
 	webgroup_drop_context(cp, gp);
952062
     }
952062
     sdsfree(msg);
952062
@@ -2394,17 +2415,12 @@ pmWebGroupClose(pmWebGroupModule *module
952062
 
952062
     if (groups) {
952062
 	/* walk the contexts, stop timers and free resources */
952062
-	if (groups->active) {
952062
-	    groups->active = 0;
952062
-	    uv_timer_stop(&groups->timer);
952062
-	    pmWebTimerRelease(groups->timerid);
952062
-	    groups->timerid = -1;
952062
-	}
952062
 	iterator = dictGetIterator(groups->contexts);
952062
 	while ((entry = dictNext(iterator)) != NULL)
952062
 	    webgroup_drop_context((context_t *)dictGetVal(entry), NULL);
952062
 	dictReleaseIterator(iterator);
952062
 	dictRelease(groups->contexts);
952062
+	webgroup_timers_stop(groups);
952062
 	memset(groups, 0, sizeof(struct webgroups));
952062
 	free(groups);
952062
     }
952062
diff -Naurp pcp-5.3.7.orig/src/pmfind/source.c pcp-5.3.7/src/pmfind/source.c
952062
--- pcp-5.3.7.orig/src/pmfind/source.c	2021-02-17 15:27:41.000000000 +1100
952062
+++ pcp-5.3.7/src/pmfind/source.c	2022-10-19 21:32:03.973832346 +1100
952062
@@ -1,5 +1,5 @@
952062
 /*
952062
- * Copyright (c) 2020 Red Hat.
952062
+ * Copyright (c) 2020,2022 Red Hat.
952062
  *
952062
  * This program is free software; you can redistribute it and/or modify it
952062
  * under the terms of the GNU General Public License as published by the
952062
@@ -25,6 +25,7 @@ static pmWebGroupSettings settings;
952062
 typedef struct {
952062
     sds			source;
952062
     sds			hostspec;
952062
+    unsigned int	refcount;
952062
 } context_t;
952062
 
952062
 typedef struct {
952062
@@ -38,22 +39,34 @@ typedef struct {
952062
 } sources_t;
952062
 
952062
 static void
952062
+source_release(sources_t *sp, context_t *cp, sds ctx)
952062
+{
952062
+    pmWebGroupDestroy(&settings, ctx, sp);
952062
+    sdsfree(cp->hostspec);
952062
+    sdsfree(cp->source);
952062
+    free(cp);
952062
+}
952062
+
952062
+static void
952062
 sources_release(void *arg, const struct dictEntry *entry)
952062
 {
952062
     sources_t	*sp = (sources_t *)arg;
952062
     context_t	*cp = (context_t *)dictGetVal(entry);
952062
     sds		ctx = (sds)entry->key;
952062
 
952062
-    pmWebGroupDestroy(&settings, ctx, sp);
952062
-    sdsfree(cp->hostspec);
952062
-    sdsfree(cp->source);
952062
+    if (pmDebugOptions.discovery)
952062
+	fprintf(stderr, "releasing context %s\n", ctx);
952062
+
952062
+    source_release(sp, cp, ctx);
952062
 }
952062
 
952062
 static void
952062
-sources_containers(sources_t *sp, sds id, dictEntry *uniq)
952062
+sources_containers(sources_t *sp, context_t *cp, sds id, dictEntry *uniq)
952062
 {
952062
     uv_mutex_lock(&sp->mutex);
952062
-    sp->count++;	/* issuing another PMWEBAPI request */
952062
+    /* issuing another PMWEBAPI request */
952062
+    sp->count++;
952062
+    cp->refcount++;
952062
     uv_mutex_unlock(&sp->mutex);
952062
 
952062
     pmWebGroupScrape(&settings, id, sp->params, sp);
952062
@@ -75,6 +88,7 @@ on_source_context(sds id, pmWebSource *s
952062
 
952062
     cp->source = sdsdup(src->source);
952062
     cp->hostspec = sdsdup(src->hostspec);
952062
+    cp->refcount = 1;
952062
 
952062
     uv_mutex_lock(&sp->mutex);
952062
     dictAdd(sp->contexts, id, cp);
952062
@@ -84,7 +98,7 @@ on_source_context(sds id, pmWebSource *s
952062
     if (entry) {	/* source just discovered */
952062
 	printf("%s %s\n", src->source, src->hostspec);
952062
 	if (containers)
952062
-	    sources_containers(sp, id, entry);
952062
+	    sources_containers(sp, cp, id, entry);
952062
     }
952062
 }
952062
 
952062
@@ -116,7 +130,9 @@ static void
952062
 on_source_done(sds context, int status, sds message, void *arg)
952062
 {
952062
     sources_t	*sp = (sources_t *)arg;
952062
-    int		count = 0, release = 0;
952062
+    context_t	*cp;
952062
+    dictEntry	*he;
952062
+    int		remove = 0, count = 0, release = 0;
952062
 
952062
     if (pmDebugOptions.discovery)
952062
 	fprintf(stderr, "done on context %s (sts=%d)\n", context, status);
952062
@@ -127,19 +143,26 @@ on_source_done(sds context, int status,
952062
     uv_mutex_lock(&sp->mutex);
952062
     if ((count = --sp->count) <= 0)
952062
 	release = 1;
952062
+    if ((he = dictFind(sp->contexts, context)) != NULL &&
952062
+	(cp = (context_t *)dictGetVal(he)) != NULL &&
952062
+	(--cp->refcount <= 0))
952062
+	remove = 1;
952062
     uv_mutex_unlock(&sp->mutex);
952062
 
952062
+    if (remove) {
952062
+	if (pmDebugOptions.discovery)
952062
+	    fprintf(stderr, "remove context %s\n", context);
952062
+	source_release(sp, cp, context);
952062
+	dictDelete(sp->contexts, context);
952062
+    }
952062
+
952062
     if (release) {
952062
 	unsigned long	cursor = 0;
952062
-
952062
-	if (pmDebugOptions.discovery)
952062
-	   fprintf(stderr, "release context %s (sts=%d)\n", context, status);
952062
 	do {
952062
 	    cursor = dictScan(sp->contexts, cursor, sources_release, NULL, sp);
952062
 	} while (cursor);
952062
-    } else {
952062
-	if (pmDebugOptions.discovery)
952062
-	    fprintf(stderr, "not yet releasing (count=%d)\n", count);
952062
+    } else if (pmDebugOptions.discovery) {
952062
+	fprintf(stderr, "not yet releasing (count=%d)\n", count);
952062
     }
952062
 }
952062
 
952062
@@ -190,6 +213,7 @@ sources_discovery_start(uv_timer_t *arg)
952062
     }
952062
 
952062
     dictRelease(dp);
952062
+    pmWebTimerClose();
952062
 }
952062
 
952062
 /*
952062
@@ -214,8 +238,8 @@ source_discovery(int count, char **urls)
952062
     uv_mutex_init(&find.mutex);
952062
     find.urls = urls;
952062
     find.count = count;	/* at least one PMWEBAPI request for each url */
952062
-    find.uniq = dictCreate(&sdsDictCallBacks, NULL);
952062
-    find.params = dictCreate(&sdsDictCallBacks, NULL);
952062
+    find.uniq = dictCreate(&sdsKeyDictCallBacks, NULL);
952062
+    find.params = dictCreate(&sdsOwnDictCallBacks, NULL);
952062
     dictAdd(find.params, sdsnew("name"), sdsnew("containers.state.running"));
952062
     find.contexts = dictCreate(&sdsKeyDictCallBacks, NULL);
952062
 
952062
@@ -230,6 +254,7 @@ source_discovery(int count, char **urls)
952062
 
952062
     pmWebGroupSetup(&settings.module);
952062
     pmWebGroupSetEventLoop(&settings.module, loop);
952062
+    pmWebTimerSetEventLoop(loop);
952062
 
952062
     /*
952062
      * Start a one-shot timer to add a start function into the loop
952062
@@ -244,7 +269,9 @@ source_discovery(int count, char **urls)
952062
     /*
952062
      * Finished, release all resources acquired so far
952062
      */
952062
+    pmWebGroupClose(&settings.module);
952062
     uv_mutex_destroy(&find.mutex);
952062
+    dictRelease(find.uniq);
952062
     dictRelease(find.params);
952062
     dictRelease(find.contexts);
952062
     return find.status;
952062
diff -Naurp pcp-5.3.7.orig/src/pmproxy/src/server.c pcp-5.3.7/src/pmproxy/src/server.c
952062
--- pcp-5.3.7.orig/src/pmproxy/src/server.c	2022-04-05 09:05:43.000000000 +1000
952062
+++ pcp-5.3.7/src/pmproxy/src/server.c	2022-10-19 21:31:43.831093354 +1100
952062
@@ -1,5 +1,5 @@
952062
 /*
952062
- * Copyright (c) 2018-2019,2021 Red Hat.
952062
+ * Copyright (c) 2018-2019,2021-2022 Red Hat.
952062
  *
952062
  * This program is free software; you can redistribute it and/or modify it
952062
  * under the terms of the GNU Lesser General Public License as published
952062
@@ -310,17 +310,21 @@ on_write_callback(uv_callback_t *handle,
952062
     struct client		*client = (struct client *)request->writer.data;
952062
     int				sts;
952062
 
952062
+    (void)handle;
952062
     if (pmDebugOptions.af)
952062
 	fprintf(stderr, "%s: client=%p\n", "on_write_callback", client);
952062
 
952062
     if (client->stream.secure == 0) {
952062
 	sts = uv_write(&request->writer, (uv_stream_t *)&client->stream,
952062
 		 &request->buffer[0], request->nbuffers, request->callback);
952062
-	if (sts != 0)
952062
-	    fprintf(stderr, "%s: ERROR uv_write failed\n", "on_write_callback");
952062
+	if (sts != 0) {
952062
+	    pmNotifyErr(LOG_ERR, "%s: %s - uv_write failed [%s]: %s\n",
952062
+			pmGetProgname(), "on_write_callback",
952062
+			uv_err_name(sts), uv_strerror(sts));
952062
+	    client_close(client);
952062
+	}
952062
     } else
952062
 	secure_client_write(client, request);
952062
-    (void)handle;
952062
     return 0;
952062
 }
952062
 
952062
@@ -455,14 +459,16 @@ on_client_connection(uv_stream_t *stream
952062
     uv_handle_t		*handle;
952062
 
952062
     if (status != 0) {
952062
-	fprintf(stderr, "%s: client connection failed: %s\n",
952062
-			pmGetProgname(), uv_strerror(status));
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - %s failed [%s]: %s\n",
952062
+		    pmGetProgname(), "on_client_connection", "connection",
952062
+		    uv_err_name(status), uv_strerror(status));
952062
 	return;
952062
     }
952062
 
952062
     if ((client = calloc(1, sizeof(*client))) == NULL) {
952062
-	fprintf(stderr, "%s: out-of-memory for new client\n",
952062
-			pmGetProgname());
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - %s failed [%s]: %s\n",
952062
+			pmGetProgname(), "on_client_connection", "calloc",
952062
+			"ENOMEM", strerror(ENOMEM));
952062
 	return;
952062
     }
952062
     if (pmDebugOptions.context | pmDebugOptions.af)
952062
@@ -476,16 +482,18 @@ on_client_connection(uv_stream_t *stream
952062
 
952062
     status = uv_tcp_init(proxy->events, &client->stream.u.tcp);
952062
     if (status != 0) {
952062
-	fprintf(stderr, "%s: client tcp init failed: %s\n",
952062
-			pmGetProgname(), uv_strerror(status));
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - %s failed [%s]: %s\n",
952062
+		    pmGetProgname(), "on_client_connection", "uv_tcp_init",
952062
+		    uv_err_name(status), uv_strerror(status));
952062
 	client_put(client);
952062
 	return;
952062
     }
952062
 
952062
     status = uv_accept(stream, (uv_stream_t *)&client->stream.u.tcp);
952062
     if (status != 0) {
952062
-	fprintf(stderr, "%s: client tcp init failed: %s\n",
952062
-			pmGetProgname(), uv_strerror(status));
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - %s failed [%s]: %s\n",
952062
+		    pmGetProgname(), "on_client_connection", "uv_accept",
952062
+		    uv_err_name(status), uv_strerror(status));
952062
 	client_put(client);
952062
 	return;
952062
     }
952062
@@ -496,8 +504,9 @@ on_client_connection(uv_stream_t *stream
952062
     status = uv_read_start((uv_stream_t *)&client->stream.u.tcp,
952062
 			    on_buffer_alloc, on_client_read);
952062
     if (status != 0) {
952062
-	fprintf(stderr, "%s: client read start failed: %s\n",
952062
-			pmGetProgname(), uv_strerror(status));
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - %s failed [%s]: %s\n",
952062
+		    pmGetProgname(), "on_client_connection", "uv_read_start",
952062
+		    uv_err_name(status), uv_strerror(status));
952062
 	client_close(client);
952062
     }
952062
 }
952062
@@ -530,8 +539,9 @@ open_request_port(struct proxy *proxy, s
952062
 
952062
     sts = uv_listen((uv_stream_t *)&stream->u.tcp, maxpending, on_client_connection);
952062
     if (sts != 0) {
952062
-	fprintf(stderr, "%s: socket listen error %s\n",
952062
-			pmGetProgname(), uv_strerror(sts));
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - uv_listen failed [%s]: %s\n",
952062
+			pmGetProgname(), "open_request_port",
952062
+			uv_err_name(sts), uv_strerror(sts));
952062
 	uv_close(handle, NULL);
952062
 	return -ENOTCONN;
952062
     }
952062
@@ -554,15 +564,23 @@ open_request_local(struct proxy *proxy,
952062
     uv_pipe_init(proxy->events, &stream->u.local, 0);
952062
     handle = (uv_handle_t *)&stream->u.local;
952062
     handle->data = (void *)proxy;
952062
-    uv_pipe_bind(&stream->u.local, name);
952062
+    sts = uv_pipe_bind(&stream->u.local, name);
952062
+    if (sts != 0) {
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - uv_pipe_bind %s failed [%s]: %s\n",
952062
+			pmGetProgname(), "open_request_local", name,
952062
+			uv_err_name(sts), uv_strerror(sts));
952062
+	uv_close(handle, NULL);
952062
+	return -ENOTCONN;
952062
+    }
952062
 #ifdef HAVE_UV_PIPE_CHMOD
952062
     uv_pipe_chmod(&stream->u.local, UV_READABLE | UV_WRITABLE);
952062
 #endif
952062
 
952062
     sts = uv_listen((uv_stream_t *)&stream->u.local, maxpending, on_client_connection);
952062
     if (sts != 0) {
952062
-	fprintf(stderr, "%s: local listen error %s\n",
952062
-			pmGetProgname(), uv_strerror(sts));
952062
+	pmNotifyErr(LOG_ERR, "%s: %s - %s failed [%s]: %s\n",
952062
+		    pmGetProgname(), "open_request_local", "uv_listen",
952062
+		    uv_err_name(sts), uv_strerror(sts));
952062
 	uv_close(handle, NULL);
952062
         return -ENOTCONN;
952062
     }