---
 00-README.conf                            | 13 ++++-
 Makefile.am                               |  8 ++-
 README                                    |  1 +
 configure.ac                              | 18 ++++++
 src/base/daemon.c                         | 96 +++++++++++++++++++++++++++++--
 src/nid/opensafd.in                       |  7 +++
 tools/devel/gcov_collect/osaf_gcov_dump.c | 40 +++++++++++++
 7 files changed, 176 insertions(+), 7 deletions(-)
 create mode 100644 tools/devel/gcov_collect/osaf_gcov_dump.c

diff --git a/00-README.conf b/00-README.conf
index f64aa031c..c42a37563 100644
--- a/00-README.conf
+++ b/00-README.conf
@@ -610,4 +610,15 @@ A message will be written if the latency is > 0.1 second, 
example below shows a
 
 messages.1:Sep 12 13:09:26 SC-1 osafimmd[26732]: NO MDS timerfd expired 10 
times
 
-If the latency exceeds 4 seconds a sigalrm will be sent and the process will 
be aborted.
\ No newline at end of file
+If the latency exceeds 4 seconds a sigalrm will be sent and the process will 
be aborted.
+
+# To enable gcov run ./configure --enable-gcov
+# In each daemon a thread will be created that listens to a default multicast 
group 239.0.0.1 port 4712.
+# To change default, update /etc/init.d/opensafd setup_env function, example:
+# export OPENSAF_GCOV_MULTICAST_GROUP="224.0.0.1"
+# export OPENSAF_GCOV_MULTICAST_PORT="4711"
+# and if running in UML uncomment the line:
+# echo 100 >  /proc/sys/net/ipv4/igmp_max_memberships
+# To collect gcov data use program tools/develop/gcov_collect/osaf_gcov_dump.
+# Check the MULTICAST_PORT and MULTICAST_GROUP settings are the same as 
multicast group and port
+# above.
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
index 7763f313c..0a69f752d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -56,7 +56,13 @@ AM_CPPFLAGS = \
 
 AM_CFLAGS = -pipe -std=gnu11 @OSAF_HARDEN_FLAGS@ -Wall -Wformat=2 -Werror
 AM_CXXFLAGS = -pipe -std=gnu++11 @OSAF_HARDEN_FLAGS@ -Wall -Wformat=2 -Werror
-AM_LDFLAGS = @OSAF_HARDEN_FLAGS@ -Wl,--as-needed -ldl -lrt -pthread -rdynamic
+
+if ENABLE_GCOV
+AM_CFLAGS += --coverage
+AM_CXXFLAGS += --coverage
+endif
+
+AM_LDFLAGS = @OSAF_HARDEN_FLAGS@ -Wl,--as-needed -ldl -lrt -pthread -rdynamic 
-lgcov
 ACLOCAL_AMFLAGS = -I m4
 OSAF_LIB_FLAGS =
 
diff --git a/README b/README
index 13c0eb352..d51314a4b 100644
--- a/README
+++ b/README
@@ -534,6 +534,7 @@ available w.r.t enabling/disabling the build for a 
particular OpenSAF service:
                           produced.
   --disable-rpm-target    disable support for the "make rpm" target
                           [default=no]
+  --enable-gcov           enable code coverage [default=no]
   --enable-experimental   enable experimental code [default=no]
   --enable-python         enable the Python AIS bindings [default=yes]
   --enable-java           enable the Java AIS interface mapping [default=no]
diff --git a/configure.ac b/configure.ac
index 74655ddce..56b17ab36 100644
--- a/configure.ac
+++ b/configure.ac
@@ -188,6 +188,24 @@ fi
 AM_CONDITIONAL([ENABLE_EXPERIMENTAL], [test "$enable_experimental" = yes])
 AC_SUBST([EXPERIMENTAL_ENABLED], ["$enable_experimental"])
 
+#
+# Enable/disable gcov
+#
+AC_MSG_CHECKING([whether to build with gcov])
+AC_ARG_ENABLE([gcov],
+        [AS_HELP_STRING([--enable-gcov],
+                [enable building with gcov [default=no]])],
+        [],
+        [enable_gcov=no])
+AC_MSG_RESULT([$enable_gcov])
+
+if test "$enable_gcov" = yes; then
+        AC_DEFINE([ENABLE_GCOV], 1, [Define if gcov is enabled])
+fi
+
+AM_CONDITIONAL([ENABLE_GCOV], [test "$enable_gcov" = yes])
+AC_SUBST([GCOV_ENABLED], ["$enable_gcov"])
+
 #
 # Enable/disable the Python AIS bindings
 #
diff --git a/src/base/daemon.c b/src/base/daemon.c
index 575588575..3e6ca7357 100644
--- a/src/base/daemon.c
+++ b/src/base/daemon.c
@@ -15,7 +15,13 @@
  * Author(s): Wind River Systems
  *
  */
+#ifdef HAVE_CONFIG_H
+#include "osaf/config.h"
+#endif
 
+#include <pthread.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <ctype.h>
 #include <sched.h>
 #include <stdio.h>
@@ -56,8 +62,6 @@
 
 static const char *internal_version_id_;
 
-extern void __gcov_flush(void) __attribute__((weak));
-
 static char fifo_file[NAME_MAX];
 static char __pidfile[NAME_MAX];
 static char __tracefile[NAME_MAX];
@@ -69,6 +73,87 @@ static int fifo_fd = -1;
 
 static void install_fatal_signal_handlers(void);
 
+#ifdef ENABLE_GCOV
+
+// default multicast group for gcov collection
+#define DFLT_MULTICAST_GROUP "239.0.0.1"
+
+extern void __gcov_dump();
+extern void __gcov_reset();
+
+static void* gcov_flush_thread(void* arg) {
+       int listenfd;
+       const int on = 1;
+       struct sockaddr_in servaddr;
+       struct ip_mreq mreq;
+       char buf[40];
+       struct sockaddr_in addr;
+       socklen_t addr_len;
+       int multicast_port = 4712; // default multicast group for gcov 
collection
+       const char *multicast_port_str;
+       const char *multicast_group;
+
+       if ((multicast_group = getenv("OPENSAF_GCOV_MULTICAST_GROUP")) == NULL) 
{
+               multicast_group = DFLT_MULTICAST_GROUP;
+       }
+
+       if ((multicast_port_str = getenv("OPENSAF_GCOV_MULTICAST_PORT")) != 
NULL) {
+               multicast_port = strtol(multicast_port_str, NULL, 0);
+       }
+
+       listenfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+       if ((setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == 
-1)) {
+               syslog(LOG_ERR, "%s: setsockpot failed: %s", __FUNCTION__, 
strerror(errno));
+               return 0;
+       }
+
+       memset(&servaddr, 0, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(multicast_port);
+
+       if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0) 
{
+               syslog(LOG_ERR, "%s: bind failed: %s", __FUNCTION__, 
strerror(errno));
+               return 0;
+       }
+
+       //
+       mreq.imr_multiaddr.s_addr=inet_addr(multicast_group);
+       mreq.imr_interface.s_addr=htonl(INADDR_ANY);
+       if (setsockopt(listenfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, 
sizeof(mreq)) < 0) {
+               syslog(LOG_ERR, "%s: setsockopt failed: %s", __FUNCTION__, 
strerror(errno));
+               return 0;
+       } else {
+               syslog(LOG_NOTICE, "%s: joined multicast group %s port %d\n",
+                       __FUNCTION__, multicast_group, multicast_port);
+       }
+
+       for(;;) {
+               addr_len = sizeof(addr);
+               recvfrom(listenfd, &buf, sizeof(buf), 0, (struct sockaddr *) 
&addr, &addr_len);
+               __gcov_dump();
+               __gcov_reset();
+               syslog(LOG_NOTICE, "__gov_dump() and __gcov_reset() called");
+       }
+       return 0;
+};
+
+static void create_gcov_flush_thread(void) {
+       pthread_t thread;
+       pthread_attr_t attr;
+       pthread_attr_init(&attr);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+       if (pthread_create(&thread, &attr, gcov_flush_thread, 0) != 0) {
+               syslog(LOG_ERR, "pthread_create FAILED: %s", strerror(errno));
+       }
+
+       pthread_attr_destroy(&attr);
+}
+
+#endif
+
 static void __print_usage(const char *progname, FILE *stream, int exit_code)
 {
        fprintf(stream, "Usage:  %s [OPTIONS]...\n", progname);
@@ -398,6 +483,10 @@ void daemonize(int argc, char *argv[])
 
        create_fifofile(fifo_file);
 
+#ifdef ENABLE_GCOV
+       create_gcov_flush_thread();
+#endif
+
        /* Create the process PID file */
        if (__create_pidfile(__pidfile) != 0)
                exit(EXIT_FAILURE);
@@ -537,9 +626,6 @@ void daemon_exit(void)
        unlink(fifo_file);
        unlink(__pidfile);
 
-       if (__gcov_flush) {
-               __gcov_flush();
-       }
        _Exit(0);
 }
 
diff --git a/src/nid/opensafd.in b/src/nid/opensafd.in
index 428b222c2..effe87d41 100644
--- a/src/nid/opensafd.in
+++ b/src/nid/opensafd.in
@@ -72,6 +72,13 @@ check_tipc() {
 }
 
 setup_env() {
+       # The following lines if --enable-gcov is configured
+       # If running in UML uncomment the next line
+       # echo 100 >  /proc/sys/net/ipv4/igmp_max_memberships
+       # gcov collecton is using multicast, to change default multicast group 
and multicast group:
+       # export OPENSAF_GCOV_MULTICAST_GROUP="224.0.0.1"
+       # export OPENSAF_GCOV_MULTICAST_PORT="4711"
+
        # Make sure this kernel has POSIX shared memory configured
        if [ ! -d /dev/shm ]; then
                logger -s -t $osafprog "POSIX shared memory (/dev/shm) not 
enabled, exiting."
diff --git a/tools/devel/gcov_collect/osaf_gcov_dump.c 
b/tools/devel/gcov_collect/osaf_gcov_dump.c
new file mode 100644
index 000000000..9999d2b51
--- /dev/null
+++ b/tools/devel/gcov_collect/osaf_gcov_dump.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+// gcc -g -o osaf_gcov_dump osaf_gcov_dump.c
+#define MULTICAST_PORT 4712
+#define MULTICAST_GROUP "239.0.0.1"
+
+int main()
+{
+       struct sockaddr_in addr;
+       int fd, cnt;
+       struct ip_mreq mreq;
+       const char message[] = "Not used";
+
+       if ((fd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
+               perror("socket");
+               exit(1);
+       }
+
+       memset(&addr,0,sizeof(addr));
+       addr.sin_family=AF_INET;
+       addr.sin_addr.s_addr=inet_addr(MULTICAST_GROUP);
+       addr.sin_port=htons(MULTICAST_PORT);
+
+       if (sendto(fd, message, sizeof(message), 0, (struct sockaddr *) &addr,
+                  sizeof(addr)) < 0) {
+               perror("sendto");
+       } else {
+               printf("sendto %s %d ok!\n", MULTICAST_GROUP, MULTICAST_PORT);
+       }
+       return 0;
+}
-- 
2.14.1


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to