Ack with minor comments, marked AndersW> below.
regards,
Anders Widell
On 10/06/2017 04:11 PM, Hans Nordeback wrote:
---
00-README.conf | 3 +
src/base/Makefile.am | 1 +
src/base/daemon.c | 87 +------------
src/base/osaf_gcov.c | 199 ++++++++++++++++++++++++++++++
src/base/osaf_gcov.h | 40 ++++++
src/nid/opensafd.in | 3 +
tools/devel/gcov_collect/osaf_gcov_dump.c | 110 ++++++++++++++---
7 files changed, 343 insertions(+), 100 deletions(-)
create mode 100644 src/base/osaf_gcov.c
create mode 100644 src/base/osaf_gcov.h
diff --git a/00-README.conf b/00-README.conf
index b67da8ee7..0cbc778ab 100644
--- a/00-README.conf
+++ b/00-README.conf
@@ -615,7 +615,10 @@ If the latency exceeds 4 seconds a sigalrm will be sent
and the process will be
# 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:
+# IPv4:
# export OPENSAF_GCOV_MULTICAST_GROUP="224.0.0.1"
+# IPv6:
+# export OPENSAF_GCOV_MULTICAST_GROUP="ff02::1"
# export OPENSAF_GCOV_MULTICAST_PORT="4711"
# and if running in UML uncomment the line:
# echo 100 > /proc/sys/net/ipv4/igmp_max_memberships
diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index f278a8ffb..4717af863 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -60,6 +60,7 @@ lib_libopensaf_core_la_SOURCES += \
src/base/osaf_timerfd.c \
src/base/osaf_unicode.c \
src/base/osaf_utility.c \
+ src/base/osaf_gcov.c \
src/base/patricia.c \
src/base/process.cc \
src/base/saf_edu.c \
diff --git a/src/base/daemon.c b/src/base/daemon.c
index c1efbce00..47684d611 100644
--- a/src/base/daemon.c
+++ b/src/base/daemon.c
@@ -19,9 +19,6 @@
#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>
@@ -53,6 +50,10 @@
#include "base/osaf_secutil.h"
#include "base/osaf_time.h"
+#ifdef ENABLE_GCOV
+#include "base/osaf_gcov.h"
+#endif
+
AndersW> I would prever to remove the #ifdefs, so that all header files
are included unconditionally. Shouldn't cause any problems, and
otherwise I worry that dependencies could be wrong after changing build
configuration options.
#include <sys/types.h>
#include <time.h>
@@ -73,86 +74,6 @@ 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);
diff --git a/src/base/osaf_gcov.c b/src/base/osaf_gcov.c
new file mode 100644
index 000000000..5602cf865
--- /dev/null
+++ b/src/base/osaf_gcov.c
@@ -0,0 +1,199 @@
+/* -*- OpenSAF -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ * (C) Copyright 2017 Ericsson AB - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include <pthread.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdlib.h>
+
+#ifdef HAVE_CONFIG_H
+#include "osaf/config.h"
+#endif
+
+#ifdef ENABLE_GCOV
+// default multicast group for gcov collection
+#define DFLT_MULTICAST_GROUP "239.0.0.1"
+#define DFLT_MULTICAST_PORT "4712"
+
+extern void __gcov_dump();
+extern void __gcov_reset();
+
+static int mcast_join_group(int socket_fd, const struct addrinfo*
multicast_addr) {
+ if (multicast_addr->ai_family == PF_INET &&
AndersW> There are double spaces before == on the line above.
+ multicast_addr->ai_addrlen == sizeof(struct sockaddr_in)){
+ struct ip_mreq multicast_request;
+
+ memcpy(&multicast_request.imr_multiaddr,
+ &((struct
sockaddr_in*)(multicast_addr->ai_addr))->sin_addr,
+ sizeof(multicast_request.imr_multiaddr));
+
+ multicast_request.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if (setsockopt(socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &multicast_request, sizeof(multicast_request)) != 0 ) {
+ syslog(LOG_NOTICE, "%s: setsockopt: %s", __FUNCTION__,
strerror(errno));
+ return -1;
+ }
+ } else if (multicast_addr->ai_family == PF_INET6 &&
AndersW> There are double spaces before == on the line above.
+ multicast_addr->ai_addrlen == sizeof(struct sockaddr_in6)) {
+ struct ipv6_mreq multicast_request;
+
+ memcpy(&multicast_request.ipv6mr_multiaddr,
+ &((struct
sockaddr_in6*)(multicast_addr->ai_addr))->sin6_addr,
+ sizeof(multicast_request.ipv6mr_multiaddr));
+
+ // Accept on any interface
+ multicast_request.ipv6mr_interface = 0;
+
+ if (setsockopt(socket_fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
+ &multicast_request, sizeof(multicast_request)) != 0 ) {
+ syslog(LOG_NOTICE, "%s: setsockopt: %s", __FUNCTION__,
strerror(errno));
+ return -1;
+ }
+ } else {
+ syslog(LOG_NOTICE, "%s: Unknown AI_FAMILY: %d", __FUNCTION__,
multicast_addr->ai_family);
+ return -1;
+ }
+ return 0;
+}
+
+static int udp_socket(const char *host, const char *serv,
+ struct sockaddr **local_addr_ptr, socklen_t *local_addr_len_ptr,
+ struct addrinfo **mcast_addr_ptr) {
+ int sock_fd;
+ int rc;
+ struct addrinfo hints;
+ struct addrinfo *multicast_addr;
+ struct addrinfo *local_addr;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6
+ hints.ai_flags = AI_NUMERICHOST;
+
+ rc = getaddrinfo(host, serv, &hints, &multicast_addr);
+ if (rc != 0) {
+ syslog(LOG_NOTICE, "%s: getaddrinfo: %s", __FUNCTION__,
gai_strerror(rc));
+ return -1;
+ }
+
+ hints.ai_family = multicast_addr->ai_family;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_PASSIVE;
+
+ rc = getaddrinfo(NULL, serv, &hints, &local_addr);
+ if (rc != 0) {
+ syslog(LOG_NOTICE, "%s: getaddrinfo: %s", __FUNCTION__,
gai_strerror(rc));
+ return -1;
+ }
+
+ if ((sock_fd = socket(local_addr->ai_family, local_addr->ai_socktype, 0))
< 0 ) {
+ syslog(LOG_NOTICE, "%s: socket: %s", __FUNCTION__,
gai_strerror(rc));
+ return -1;
+ }
+
+ *local_addr_ptr = malloc(local_addr->ai_addrlen);
+ memcpy(*local_addr_ptr, local_addr->ai_addr, local_addr->ai_addrlen);
+ *local_addr_len_ptr = local_addr->ai_addrlen;
+
+ *mcast_addr_ptr = malloc(sizeof(*multicast_addr));
+ memcpy(*mcast_addr_ptr, multicast_addr, sizeof(*multicast_addr));
+
+ freeaddrinfo(multicast_addr);
+ freeaddrinfo(local_addr);
+
+ return sock_fd;
+}
+
+static void* gcov_flush_thread(void* arg) {
+ int socket_fd;
+ const int on = 1;
+ struct sockaddr *local_addr = 0;
+ struct addrinfo *multicast_addr = 0;
+
+ socklen_t local_addr_len = 0;
+
+ char buf[40];
+ struct sockaddr *addr;
+ socklen_t addr_len;
+
+ const char *multicast_port;
+ const char *multicast_group;
+
+ if ((multicast_group = getenv("OPENSAF_GCOV_MULTICAST_GROUP")) == NULL)
{
+ multicast_group = DFLT_MULTICAST_GROUP;
+ }
+
+ if ((multicast_port = getenv("OPENSAF_GCOV_MULTICAST_PORT")) == NULL) {
+ multicast_port = DFLT_MULTICAST_PORT;
+ }
+
+ if ((socket_fd = udp_socket(multicast_group, multicast_port,
+ &local_addr, &local_addr_len, &multicast_addr)) > 0) {
+ if ((setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on)) == -1)) {
+ syslog(LOG_ERR, "%s: setsockopt failed: %s",
__FUNCTION__, strerror(errno));
+ return 0;
+ }
+
+ if ((bind(socket_fd, local_addr, local_addr_len)) < 0) {
+ syslog(LOG_ERR, "%s: bind failed: %s", __FUNCTION__,
strerror(errno));
+ return 0;
+ }
+
+ if (mcast_join_group(socket_fd, multicast_addr) == 0) {
+ syslog(LOG_NOTICE, "%s: joined multicast group %s port
%s", __FUNCTION__,
+ multicast_group, multicast_port);
+ addr = malloc(local_addr_len);
+ for(;;) {
+ addr_len = local_addr_len;
+ recvfrom(socket_fd, &buf, sizeof(buf), 0, addr,
&addr_len);
+ __gcov_dump();
+ __gcov_reset();
+ syslog(LOG_NOTICE, "%s: __gov_dump() and
__gcov_reset() called", __FUNCTION__);
+ }
+
+ free(local_addr);
+ free(multicast_addr);
+ free(addr);
+
+ return 0;
+ }
+ }
+ syslog(LOG_ERR, "%s: failed to setup multicast group %s %s, reason: %s",
+ __FUNCTION__, multicast_group, multicast_port, strerror(errno));
+ return 0;
+}
+
+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, "%s: pthread_create FAILED: %s", __FUNCTION__,
strerror(errno));
+ }
+
+ pthread_attr_destroy(&attr);
+}
+
+#endif // ENABLE_GCOV
\ No newline at end of file
diff --git a/src/base/osaf_gcov.h b/src/base/osaf_gcov.h
new file mode 100644
index 000000000..fb9c81732
--- /dev/null
+++ b/src/base/osaf_gcov.h
@@ -0,0 +1,40 @@
+/* -*- OpenSAF -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ * (C) Copyright 2017 Ericsson AB - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef BASE_OSAF_GCOV_H_
+#define BASE_OSAF_GCOV_H_
+
+#ifdef HAVE_CONFIG_H
+#include "osaf/config.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef ENABLE_GCOV
+
+extern void create_gcov_flush_thread(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BASE_OSAF_GCOV_H_
diff --git a/src/nid/opensafd.in b/src/nid/opensafd.in
index effe87d41..742f5f1e9 100644
--- a/src/nid/opensafd.in
+++ b/src/nid/opensafd.in
@@ -76,7 +76,10 @@ setup_env() {
# 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:
+ # IPv4:
# export OPENSAF_GCOV_MULTICAST_GROUP="224.0.0.1"
+ # IPv6:
+ # export OPENSAF_GCOV_MULTICAST_GROUP="ff02::1"
# export OPENSAF_GCOV_MULTICAST_PORT="4711"
# Make sure this kernel has POSIX shared memory configured
diff --git a/tools/devel/gcov_collect/osaf_gcov_dump.c
b/tools/devel/gcov_collect/osaf_gcov_dump.c
index b84b27589..d82517cf5 100644
--- a/tools/devel/gcov_collect/osaf_gcov_dump.c
+++ b/tools/devel/gcov_collect/osaf_gcov_dump.c
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
@@ -27,32 +28,107 @@
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <errno.h>
// gcc -g -Wall -o osaf_gcov_dump osaf_gcov_dump.c
-#define MULTICAST_PORT 4712
-#define MULTICAST_GROUP "239.0.0.1"
-int main()
+#define DFLT_MULTICAST_PORT "4712"
+#define DFLT_MULTICAST_GROUP "239.0.0.1"
+
+// ./osaf_gcov_dump
+// ./osaf_gcov_dump 224.0.0.1 4712
+// ./osaf_gcov_dump ff02::1 4712
+
+static int udp_socket(const char *host, const char *serv,
+ struct sockaddr **sa_ptr, socklen_t *salen_ptr) {
+ int sock_fd;
+ int rc;
+ struct addrinfo hints;
+ struct addrinfo *res;
+ struct addrinfo *rp;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6
+ hints.ai_socktype = SOCK_DGRAM;
+
+ rc = getaddrinfo(host, serv, &hints, &res);
+ if (rc != 0) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rc));
+ exit(EXIT_FAILURE);
+ }
+
+ for (rp = res; rp != NULL; rp = rp->ai_next) {
+ sock_fd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
+ if (sock_fd >= 0) {
+ break;
+ }
+ }
+
+ if (rp == NULL) {
+ fprintf(stderr, "Could not create socket for %s port %s: %s\n",
+ host, serv, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (rp->ai_family == PF_INET) {
+ in_addr_t iface = INADDR_ANY;
+ if (setsockopt(sock_fd, IPPROTO_IP, IP_MULTICAST_IF,
+ &iface, sizeof(iface)) != 0) {
+ fprintf(stderr, "setsockopt failed: %s\n",
strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ }
+
+ if (rp->ai_family == PF_INET6) {
+ unsigned int ifindex = 0;
+ if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ &ifindex, sizeof(ifindex)) != 0) {
+ fprintf(stderr, "setsockopt failed: %s\n",
strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ }
+
+ *sa_ptr = malloc(rp->ai_addrlen);
+ memcpy(*sa_ptr, rp->ai_addr, rp->ai_addrlen);
+ *salen_ptr = rp->ai_addrlen;
+
+ freeaddrinfo(res);
+
+ return sock_fd;
+}
+
+int main(int argc, char *argv[])
{
- struct sockaddr_in addr;
- int fd;
- const char message[] = "Not used";
+ char host[128];
+ char port[10];
+
+ struct sockaddr *sa;
+ socklen_t sa_len;
+ int sock_fd;
- if ((fd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
- perror("socket");
- exit(1);
+ if (argc == 1) {
+ strncpy(host, DFLT_MULTICAST_GROUP, sizeof(host));
+ strncpy(port, DFLT_MULTICAST_PORT, sizeof(port));
+ } else if (argc == 3) {
+ strncpy(host, argv[1], sizeof(host));
+ strncpy(port, argv[2], sizeof(port));
+ } else {
+ fprintf(stderr, "Usage: %s [host port]\n", argv[0]);
+ exit(EXIT_FAILURE);
}
- 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);
+ sock_fd = udp_socket(host, port, &sa, &sa_len);
- if (sendto(fd, message, sizeof(message), 0, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- perror("sendto");
+ if ((sendto(sock_fd, "", 1, 0, sa, sa_len)) < 0) {
+ fprintf(stderr, "sendto: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
} else {
- printf("sendto %s %d ok!\n", MULTICAST_GROUP, MULTICAST_PORT);
+ fprintf(stdout, "sendto %s port %s ok!\n", host, port);
}
+
+ free(sa);
+
return 0;
}
------------------------------------------------------------------------------
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