Blob Blame History Raw
diff -Naurp pcp-3.9.10-orig/configure pcp-3.9.10-fche/configure
--- pcp-3.9.10-orig/configure	2014-09-05 14:18:39.000000000 +1000
+++ pcp-3.9.10-fche/configure	2014-09-06 02:50:03.000000000 +1000
@@ -622,7 +622,12 @@ ac_includes_default="\
 ac_subst_vars='PACKAGE_CONFIGURE
 BUILD_PMMGR
 HAVE_RPMLIB
+HAVE_CAIRO
+cairo_LIBS
+cairo_CFLAGS
 HAVE_LIBMICROHTTPD
+libmicrohttpd_LIBS
+libmicrohttpd_CFLAGS
 lib_for_curses
 lib_for_readline
 pcp_mpi_dirs
@@ -935,7 +940,11 @@ YACC
 YFLAGS
 SYSTEMD_CFLAGS
 SYSTEMD_LIBS
-XMKMF'
+XMKMF
+libmicrohttpd_CFLAGS
+libmicrohttpd_LIBS
+cairo_CFLAGS
+cairo_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1622,6 +1631,13 @@ Some influential environment variables:
   SYSTEMD_LIBS
               linker flags for SYSTEMD, overriding pkg-config
   XMKMF       Path to xmkmf, Makefile generator for X Window System
+  libmicrohttpd_CFLAGS
+              C compiler flags for libmicrohttpd, overriding pkg-config
+  libmicrohttpd_LIBS
+              linker flags for libmicrohttpd, overriding pkg-config
+  cairo_CFLAGS
+              C compiler flags for cairo, overriding pkg-config
+  cairo_LIBS  linker flags for cairo, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -13784,33 +13800,153 @@ $as_echo "no" >&6; }
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-savedLIBS=$LIBS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmicrohttpd > 0.9.9" >&5
-$as_echo_n "checking for libmicrohttpd > 0.9.9... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <microhttpd.h>
-int
-main ()
-{
-(void)MHD_RESPMEM_PERSISTENT;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-    have_libmicrohttpd=1
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmicrohttpd" >&5
+$as_echo_n "checking for libmicrohttpd... " >&6; }
+
+if test -n "$libmicrohttpd_CFLAGS"; then
+    pkg_cv_libmicrohttpd_CFLAGS="$libmicrohttpd_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd > 0.9.9\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libmicrohttpd > 0.9.9") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_libmicrohttpd_CFLAGS=`$PKG_CONFIG --cflags "libmicrohttpd > 0.9.9" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$libmicrohttpd_LIBS"; then
+    pkg_cv_libmicrohttpd_LIBS="$libmicrohttpd_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd > 0.9.9\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libmicrohttpd > 0.9.9") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_libmicrohttpd_LIBS=`$PKG_CONFIG --libs "libmicrohttpd > 0.9.9" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-    have_libmicrohttpd=0
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        libmicrohttpd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmicrohttpd > 0.9.9" 2>&1`
+        else
+	        libmicrohttpd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmicrohttpd > 0.9.9" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$libmicrohttpd_PKG_ERRORS" >&5
+
+	have_libmicrohttpd=
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	have_libmicrohttpd=
+else
+	libmicrohttpd_CFLAGS=$pkg_cv_libmicrohttpd_CFLAGS
+	libmicrohttpd_LIBS=$pkg_cv_libmicrohttpd_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	have_libmicrohttpd=1
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 HAVE_LIBMICROHTTPD=$have_libmicrohttpd
 
-LIBS=$savedLIBS
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cairo" >&5
+$as_echo_n "checking for cairo... " >&6; }
+
+if test -n "$cairo_CFLAGS"; then
+    pkg_cv_cairo_CFLAGS="$cairo_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_cairo_CFLAGS=`$PKG_CONFIG --cflags "cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$cairo_LIBS"; then
+    pkg_cv_cairo_LIBS="$cairo_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_cairo_LIBS=`$PKG_CONFIG --libs "cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        cairo_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2" 2>&1`
+        else
+	        cairo_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$cairo_PKG_ERRORS" >&5
+
+	have_cairo=0
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	have_cairo=0
+else
+	cairo_CFLAGS=$pkg_cv_cairo_CFLAGS
+	cairo_LIBS=$pkg_cv_cairo_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	have_cairo=1
+fi
+HAVE_CAIRO=$have_cairo
+
 
 savedLIBS=$LIBS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rpmlib > 4.4.2" >&5
diff -Naurp pcp-3.9.10-orig/configure.ac pcp-3.9.10-fche/configure.ac
--- pcp-3.9.10-orig/configure.ac	2014-09-05 14:18:39.000000000 +1000
+++ pcp-3.9.10-fche/configure.ac	2014-09-06 02:50:03.000000000 +1000
@@ -2456,18 +2456,12 @@ AC_TRY_COMPILE(
 ], AC_DEFINE(HAVE_AI_ADDRCONFIG) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no))
 
 dnl Do you have system microhttpd libraries for pmwebapi?
-savedLIBS=$LIBS
-AC_MSG_CHECKING([for libmicrohttpd > 0.9.9])
-AC_COMPILE_IFELSE(
-   [AC_LANG_PROGRAM([[#include <microhttpd.h>]],
-                    [[(void)MHD_RESPMEM_PERSISTENT;]])],
-   [AC_MSG_RESULT([yes])
-    have_libmicrohttpd=1],
-   [AC_MSG_RESULT([no])
-    have_libmicrohttpd=0])
-dnl AC_CHECK_LIB(microhttpd,MHD_start_daemon,[have_libmicrohttpd=1],[have_libmicrohttpd=0])
+PKG_CHECK_MODULES([libmicrohttpd], [libmicrohttpd > 0.9.9], [have_libmicrohttpd=1], [have_libmicrohttpd=])
 AC_SUBST(HAVE_LIBMICROHTTPD,[$have_libmicrohttpd])
-LIBS=$savedLIBS
+
+dnl Do you have graphics libraries for pmwebapi?
+PKG_CHECK_MODULES([cairo], [cairo >= 1.2, cairo-ft >= 1.2, cairo-png >= 1.2], [have_cairo=1], [have_cairo=0])
+AC_SUBST(HAVE_CAIRO,[$have_cairo])
 
 dnl Do you have RPM Package Manager libraries for pmdarpm?
 savedLIBS=$LIBS
diff -Naurp pcp-3.9.10-orig/qa/666 pcp-3.9.10-fche/qa/666
--- pcp-3.9.10-orig/qa/666	1970-01-01 10:00:00.000000000 +1000
+++ pcp-3.9.10-fche/qa/666	2014-09-06 02:50:03.000000000 +1000
@@ -0,0 +1,179 @@
+#! /bin/sh
+# PCP QA Test No. 666
+# checks basic pmmgr functionality
+#
+# Copyright (c) 2014 Red Hat, Inc.  All Rights Reserved.
+#
+seq=`basename $0`
+echo "QA output created by $seq"
+
+# get standard environment, filters and checks
+. ./common.product
+. ./common.filter
+. ./common.check
+
+
+which pmmgr >/dev/null 2>&1 || _notrun "No pmmgr binary installed"
+echo pmmgr ok
+
+$sudo rm -fr $tmp.dir
+$sudo rm -f $tmp.*
+rm -f $seq.full
+
+signal=$PCP_BINADM_DIR/pmsignal
+status=1	# failure is the default!
+username=`id -u -n`
+trap "_cleanup" 0 1 2 3 15
+
+
+# Shorten timeouts because of the rapid-fire pmcd/pmmgr-daemon livespan tests
+PMCD_WAIT_TIMEOUT=1
+PMCD_CONNECT_TIMEOUT=1
+PMCD_RECONNECT_TIMEOUT=1
+
+
+_cleanup()
+{
+    if [ -n "$pid" ]; then kill $pid; fi
+    $sudo rm -fr $tmp.dir
+    $sudo rm -f $tmp.*
+    exit $status
+}
+
+_filter()
+{
+    tee -a $seq.full |
+    sed -e 's,^\[.*\],TIMESTAMP,' \
+        -e 's,pmmgr.[0-9]*/[0-9]*.,pmmgr(PID/TID),' \
+        -e 's,hostid [a-zA-Z0-9_-.]*,hostid HOSTID,' \
+        -e 's,at [a-zA-Z0-9_-.:]*,at LOCAL,' \
+        -e 's,'$tmp.dir',TMPDIR,'
+}
+
+_filter2()
+{
+    tee -a $seq.full |
+    sed -e 's,'`hostname`',HOSTNAME,' \
+        -e 's,[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\.[0-9][0-9][0-9][0-9][0-9][0-9],YYYYMMDD-HHMMSS,'
+}
+
+# This test prereqs only pmcd running locally.
+# In the future, remote, avahi
+
+date >> $seq.full
+echo "=== 1. prepare blank pmmgr config directory  ===" | tee -a $seq.full
+$sudo rm -rf $tmp.dir
+mkdir $tmp.dir
+
+date >> $seq.full
+echo "=== 2. pmmgr barenaked startup  ===" | tee -a $seq.full
+echo 'local:' > $tmp.dir/target-host
+echo 'localhost' > $tmp.dir/target-host
+echo 'localhost6' > $tmp.dir/target-host
+$PCP_BINADM_DIR/pmmgr -U $username -v -p 4 -l $tmp.out -c $tmp.dir &
+pid=$!
+echo "pid=$!" >>$seq.full
+
+date >> $seq.full
+echo "=== 3. look for pmmgr starting no daemons ===" | tee -a $seq.full
+sleep 30
+ls -1 $tmp.dir # should be almost empty
+
+date >> $seq.full
+echo "=== 4. add control files to start pmlogger and pmie ===" | tee -a $seq.full
+echo '-t 10' > $tmp.dir/pmlogger
+touch $tmp.dir/pmie
+touch $tmp.dir/pmlogconf
+touch $tmp.dir/pmieconf
+echo $tmp.dir > $tmp.dir/log-directory  # same dir
+
+date >> $seq.full
+echo "=== 5. restart pmcd a few times to get a bunch of pmlogger archives ===" | tee -a $seq.full
+for x in `seq 4`
+do
+echo $x
+$sudo $PCP_RC_DIR/pmcd restart >/dev/null 2>&1
+sleep 30 # give time for pmlogconf/pmieconf to run
+done
+
+date >> $seq.full
+echo "=== 6. check the directories ===" | tee -a $seq.full
+ls -1 $tmp.dir/`hostname` | _filter2
+ls -lR $tmp.dir >> $seq.full # for reference
+for f in $tmp.dir/`hostname`/*.meta; do
+    echo == $f ==>> $seq.full
+    pmloglabel -L $f >> $seq.full
+done
+
+date >> $seq.full
+echo "=== 7. add log-merging/rewriting, stop pmFOOconf and kill pmcd once more ===" | tee -a $seq.full
+$sudo $PCP_RC_DIR/pmcd stop >/dev/null 2>&1
+touch $tmp.dir/pmlogrewrite
+touch $tmp.dir/pmlogmerge
+echo '-t 1 -c '$tmp.dir/`hostname`/config.pmlogger > $tmp.dir/pmlogger
+echo '-c '$tmp.dir/`hostname`/config.pmie > $tmp.dir/pmie
+rm $tmp.dir/pmlogconf
+rm $tmp.dir/pmieconf
+# ^^^ so pmmgr will react to pmcd restarts rather quickly
+echo 6min > $tmp.dir/pmlogmerge-retain
+sleep 10
+$sudo $PCP_RC_DIR/pmcd restart >/dev/null 2>&1
+sleep 30 # enough time to get new daemons started up 
+
+date >> $seq.full
+echo "=== 8. recheck the directories past retain/merge ===" | tee -a $seq.full
+ls -1 $tmp.dir/`hostname` | _filter2
+ls -lR $tmp.dir >> $seq.full # for reference
+for f in $tmp.dir/`hostname`/*.meta; do
+    echo == $f == >> $seq.full
+    pmloglabel -L $f >> $seq.full
+done
+
+date >> $seq.full
+echo "=== 9. how about some granular mode ===" | tee -a $seq.full
+$sudo $PCP_RC_DIR/pmcd stop >/dev/null 2>&1
+echo 30sec > $tmp.dir/pmlogmerge
+rm $tmp.dir/pmlogrewrite # separately tested
+touch $tmp.dir/pmlogmerge-granular
+echo 90sec > $tmp.dir/pmlogmerge-retain
+sleep 20  # ensure pmmgr has killed all the daemons
+$sudo $PCP_RC_DIR/pmcd restart >/dev/null 2>&1
+
+date >> $seq.full
+echo "=== 10. wait a bit ===" | tee -a $seq.full
+# long enough for all the old archives to age out, only new granular stuff to survive
+# not an exact multiple of the pmlogmerge period, to avoid testing the edge moments
+for x in `seq 9`
+do
+    echo $x
+    sleep 15
+done
+$sudo $PCP_RC_DIR/pmcd stop >/dev/null 2>&1  # ensure daemons stop & no new ones are started
+
+date >> $seq.full
+echo "=== 11. admire grained / retained data ===" | tee -a $seq.full
+ls -1 $tmp.dir/`hostname` | _filter2
+ls -lR $tmp.dir >> $seq.full # for reference
+for f in $tmp.dir/`hostname`/*.meta; do
+    echo == $f ==>> $seq.full
+    pmloglabel -L $f >> $seq.full
+done
+
+date >> $seq.full
+echo "=== ZZZ kill pmmgr ===" | tee -a $seq.full
+kill $pid
+pid=
+sleep 2
+
+echo "== full pmmgr logs:" >> $seq.full
+cat $tmp.out >> $seq.full
+
+echo "== recent daemon logs:" >> $seq.full
+grep . $tmp.dir/`hostname`/*.log >> $seq.full
+
+# restart pmcd
+$sudo $PCP_RC_DIR/pmcd restart >/dev/null 2>&1
+
+status=0
+sleep 2
+exit
diff -Naurp pcp-3.9.10-orig/qa/666.out pcp-3.9.10-fche/qa/666.out
--- pcp-3.9.10-orig/qa/666.out	1970-01-01 10:00:00.000000000 +1000
+++ pcp-3.9.10-fche/qa/666.out	2014-09-06 02:50:03.000000000 +1000
@@ -0,0 +1,70 @@
+QA output created by 666
+pmmgr ok
+=== 1. prepare blank pmmgr config directory  ===
+=== 2. pmmgr barenaked startup  ===
+=== 3. look for pmmgr starting no daemons ===
+target-host
+=== 4. add control files to start pmlogger and pmie ===
+=== 5. restart pmcd a few times to get a bunch of pmlogger archives ===
+1
+2
+3
+4
+=== 6. check the directories ===
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+config.pmie
+config.pmlogger
+pmie.log
+pmlogger.log
+=== 7. add log-merging/rewriting, stop pmFOOconf and kill pmcd once more ===
+=== 8. recheck the directories past retain/merge ===
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+config.pmie
+config.pmlogger
+pmie.log
+pmlogger.log
+=== 9. how about some granular mode ===
+=== 10. wait a bit ===
+1
+2
+3
+4
+5
+6
+7
+8
+9
+=== 11. admire grained / retained data ===
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+archive-YYYYMMDD-HHMMSS.0
+archive-YYYYMMDD-HHMMSS.index
+archive-YYYYMMDD-HHMMSS.meta
+config.pmie
+config.pmlogger
+pmie.log
+pmlogger.log
+=== ZZZ kill pmmgr ===
diff -Naurp pcp-3.9.10-orig/src/include/builddefs.in pcp-3.9.10-fche/src/include/builddefs.in
--- pcp-3.9.10-orig/src/include/builddefs.in	2014-09-05 14:18:45.000000000 +1000
+++ pcp-3.9.10-fche/src/include/builddefs.in	2014-09-06 02:50:03.000000000 +1000
@@ -116,6 +116,7 @@ NSSCFLAGS = @NSSCFLAGS@
 NSPRCFLAGS = @NSPRCFLAGS@
 SASLCFLAGS = @SASLCFLAGS@
 AVAHICFLAGS = @avahi_CFLAGS@
+LIBMICROHTTPDCFLAGS = @libmicrohttpd_CFLAGS@
 
 LDFLAGS += $(PLDFLAGS) $(WARN_OFF) $(PCP_LIBS) $(LLDFLAGS)
 
@@ -238,9 +239,12 @@ LIB_FOR_SASL = @lib_for_sasl@
 LIB_FOR_SSL = @lib_for_ssl@
 LIB_FOR_AVAHI = @lib_for_avahi@
 LIB_FOR_ATOMIC = @lib_for_atomic@
+LIB_FOR_CAIRO = @cairo_LIBS@
+LIB_FOR_LIBMICROHTTPD = @libmicrohttpd_LIBS@
 
 HAVE_LIBMICROHTTPD = @HAVE_LIBMICROHTTPD@
 HAVE_RPMLIB = @HAVE_RPMLIB@
+HAVE_CAIRO = @HAVE_CAIRO@
 
 SHELL = /bin/sh
 IMAGES_DIR = $(TOPDIR)/all-images
diff -Naurp pcp-3.9.10-orig/src/pmmgr/pmmgr.cxx pcp-3.9.10-fche/src/pmmgr/pmmgr.cxx
--- pcp-3.9.10-orig/src/pmmgr/pmmgr.cxx	2014-06-30 11:46:07.000000000 +1000
+++ pcp-3.9.10-fche/src/pmmgr/pmmgr.cxx	2014-09-06 02:50:03.000000000 +1000
@@ -19,7 +19,6 @@
 #include "impl.h"
 
 #include <sys/stat.h>
-#include <cassert>
 #include <cstdlib>
 #include <fstream>
 #include <iostream>
@@ -628,8 +627,26 @@ pmmgr_daemon::~pmmgr_daemon()
   if (pid != 0)
     {
       int ignored;
+
       (void) kill ((pid_t) pid, SIGTERM);
-      (void) waitpid ((pid_t) pid, &ignored, 0); // collect zombie
+
+      // Unfortunately, some daemons don't always respond to SIGTERM
+      // immediately, so we mustn't simply hang in a waitpid().  This
+      // has been observed with 3.9.6-era pmie.
+
+      for (unsigned c=0; c<10; c++) { // try to kill/reap only a brief while
+        struct timespec killpoll;
+        killpoll.tv_sec = 0;
+        killpoll.tv_nsec = 250*1000*1000; // 250 milliseconds
+        (void) nanosleep (&killpoll, NULL);
+
+        int rc = waitpid ((pid_t) pid, &ignored, WNOHANG); // collect zombie
+        if (rc == pid)
+          break;
+
+        // not dead yet ... try again a little harder
+        (void) kill ((pid_t) pid, SIGKILL);
+      }
       if (pmDebug & DBG_TRACE_APPL0)
         timestamp(cout) << "daemon pid " << pid << " killed" << endl;
     }
@@ -653,6 +670,11 @@ void pmmgr_daemon::poll()
             timestamp(cout) << "daemon pid " << pid << " found dead" << endl;
           pid = 0;
           // we will try again immediately
+          sleep (1);
+          // .. but but quite immediately; if a pmmgr daemon in
+          // granular mode shut down one second before the end of its
+          // period, the restarted form shouldn't be started in that
+          // exact same second.
         }
     }
 
@@ -813,7 +835,14 @@ pmmgr_pmlogger_daemon::daemon_command_li
           __pmtimevalNow (&now_tv);
           time_t period_s = period_tv.tv_sec;
           if (period_s < 1) period_s = 1; // at least one second
-          time_t period_end = ((now_tv.tv_sec + period_s - 1) / period_s) * period_s;
+          time_t period_end = ((now_tv.tv_sec + 1 + period_s) / period_s) * period_s - 1;
+
+          // Assert calculation sanity: we want to avoid the case
+          // where a daemon launches for 0 seconds.  This should already
+          // be prevented by the "+ 1" above.
+          if (period_end == now_tv.tv_sec)
+            period_end ++;
+
           period = string(" @") +
             string(ctime(& period_end)).substr(0,24); // 24: ctime(3) magic value, sans \n
         }
@@ -833,8 +862,10 @@ pmmgr_pmlogger_daemon::daemon_command_li
           __pmtimevalNow (&now_tv);
           time_t period_s = period_tv.tv_sec;
           if (period_s < 1) period_s = 1; // at least one second
-          time_t prior_period_start = ((now_tv.tv_sec - period_s) / period_s) * period_s;
-          time_t prior_period_end = prior_period_start + period_s;
+          time_t prior_period_start = ((now_tv.tv_sec + 1 - period_s) / period_s) * period_s;
+          time_t prior_period_end = prior_period_start + period_s - 1; 
+          // schedule end -before- the period boundary, so that the
+          // last recorded metric timestamp is strictly before the end
 
           for (unsigned i=0; i<the_blob.gl_pathc; i++)
             {