lib/compiler.h \
lib/coverage.c \
lib/coverage.h \
- lib/coverage-counters.h \
lib/csum.c \
lib/csum.h \
lib/daemon.c \
lib/vlog.c \
lib/vlog.h
nodist_lib_libopenvswitch_a_SOURCES = \
- lib/coverage-counters.c \
lib/dirs.c
CLEANFILES += $(nodist_lib_libopenvswitch_a_SOURCES)
$(MKDIR_P) $(DESTDIR)$(PKIDIR)
$(MKDIR_P) $(DESTDIR)$(LOGDIR)
+if !USE_LINKER_SECTIONS
# All distributed sources, with names adjust properly for referencing
# from $(builddir).
all_sources = \
fi; \
done`
-# All the source files that have coverage counters.
-COVERAGE_FILES = \
- lib/dpif.c \
- lib/flow.c \
- lib/lockfile.c \
- lib/hmap.c \
- lib/mac-learning.c \
- lib/netdev.c \
- lib/netdev-linux.c \
- lib/netlink.c \
- lib/odp-util.c \
- lib/poll-loop.c \
- lib/process.c \
- lib/rconn.c \
- lib/rtnetlink.c \
- lib/stream.c \
- lib/stream-ssl.c \
- lib/timeval.c \
- lib/unixctl.c \
- lib/util.c \
- lib/vconn.c \
- ofproto/ofproto.c \
- ofproto/pktbuf.c \
- vswitchd/bridge.c \
- vswitchd/ovs-brcompatd.c
-lib/coverage-counters.c: $(COVERAGE_FILES) lib/coverage-scan.pl
- (cd $(srcdir) && $(PERL) lib/coverage-scan.pl $(COVERAGE_FILES)) > $@.tmp
- mv $@.tmp $@
-EXTRA_DIST += lib/coverage-scan.pl
+lib/coverage.$(OBJEXT): lib/coverage.def
+lib/coverage.def: $(DIST_SOURCES)
+ sed -n 's|^COVERAGE_DEFINE(\([_a-zA-Z0-9]\{1,\}\)).*$$|COVERAGE_COUNTER(\1)|p' $(all_sources) | LC_ALL=C sort -u > $@
+CLEANFILES += lib/coverage.def
-if !USE_LINKER_SECTIONS
lib/vlog.$(OBJEXT): lib/vlog-modules.def
lib/vlog-modules.def: $(DIST_SOURCES)
sed -n 's|^VLOG_DEFINE_\(THIS_\)\{0,1\}MODULE(\([_a-zA-Z0-9]\{1,\}\)).*$$|VLOG_MODULE(\2)|p' $(all_sources) | LC_ALL=C sort -u > $@
+++ /dev/null
-/*
- * Copyright (c) 2009 Nicira Networks.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COVERAGE_COUNTERS_H
-#define COVERAGE_COUNTERS_H 1
-
-#include <stddef.h>
-
-extern struct coverage_counter *coverage_counters[];
-extern size_t coverage_n_counters;
-
-#endif /* coverage.h */
+++ /dev/null
-# Copyright (c) 2009 Nicira Networks.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use strict;
-use warnings;
-
-my %counters;
-while (<>) {
- my ($counter) = /^\s*COVERAGE_(?:INC|ADD)\s*\(\s*([a-zA-Z_][a-zA-Z_0-9]*)/
- or next;
- push (@{$counters{$counter}}, "$ARGV:$.");
-} continue {
- # This magic resets $. from one file to the next. See "perldoc -f eof".
- close ARGV if eof;
-}
-
-print <<EOF;
-#include "coverage-counters.h"
-#include <stddef.h>
-#include "coverage.h"
-#include "util.h"
-
-EOF
-
-for my $counter (sort(keys(%counters))) {
- my $locations = join(', ', @{$counters{$counter}});
- print <<EOF;
-/* $locations */
-struct coverage_counter ${counter}_count = { "$counter", 0, 0 };
-
-EOF
-}
-print "struct coverage_counter *coverage_counters[] = {\n";
-print " \&${_}_count,\n" foreach (sort(keys(%counters)));
-print "};\n";
-print "size_t coverage_n_counters = ARRAY_SIZE(coverage_counters);\n";
#include "coverage.h"
#include <inttypes.h>
#include <stdlib.h>
-#include "coverage-counters.h"
#include "dynamic-string.h"
#include "hash.h"
#include "unixctl.h"
VLOG_DEFINE_THIS_MODULE(coverage);
+/* The coverage counters. */
+#if USE_LINKER_SECTIONS
+extern struct coverage_counter *__start_coverage[];
+extern struct coverage_counter *__stop_coverage[];
+#define coverage_counters __start_coverage
+#define n_coverage_counters (__stop_coverage - __start_coverage)
+#else /* !USE_LINKER_SECTIONS */
+#define COVERAGE_COUNTER(NAME) COVERAGE_DEFINE__(NAME);
+#include "coverage.def"
+#undef COVERAGE_COUNTER
+
+struct coverage_counter *coverage_counters[] = {
+#define COVERAGE_COUNTER(NAME) &counter_##NAME,
+#include "coverage.def"
+#undef COVERAGE_COUNTER
+};
+#define n_coverage_counters ARRAY_SIZE(coverage_counters)
+#endif /* !USE_LINKER_SECTIONS */
+
static unsigned int epoch;
static void
int n_groups, i;
/* Sort coverage counters into groups with equal counts. */
- c = xmalloc(coverage_n_counters * sizeof *c);
- for (i = 0; i < coverage_n_counters; i++) {
+ c = xmalloc(n_coverage_counters * sizeof *c);
+ for (i = 0; i < n_coverage_counters; i++) {
c[i] = coverage_counters[i];
}
- qsort(c, coverage_n_counters, sizeof *c, compare_coverage_counters);
+ qsort(c, n_coverage_counters, sizeof *c, compare_coverage_counters);
/* Hash the names in each group along with the rank. */
n_groups = 0;
- for (i = 0; i < coverage_n_counters; ) {
+ for (i = 0; i < n_coverage_counters; ) {
int j;
if (!c[i]->count) {
}
n_groups++;
hash = hash_int(i, hash);
- for (j = i; j < coverage_n_counters; j++) {
+ for (j = i; j < n_coverage_counters; j++) {
if (c[j]->count != c[i]->count) {
break;
}
n_never_hit = 0;
VLOG(level, "Event coverage (epoch %u/entire run), hash=%08"PRIx32":",
epoch, hash);
- for (i = 0; i < coverage_n_counters; i++) {
+ for (i = 0; i < n_coverage_counters; i++) {
struct coverage_counter *c = coverage_counters[i];
if (c->count) {
coverage_log_counter(level, c);
}
}
- for (i = 0; i < coverage_n_counters; i++) {
+ for (i = 0; i < n_coverage_counters; i++) {
struct coverage_counter *c = coverage_counters[i];
if (!c->count) {
if (c->total) {
size_t i;
epoch++;
- for (i = 0; i < coverage_n_counters; i++) {
+ for (i = 0; i < n_coverage_counters; i++) {
struct coverage_counter *c = coverage_counters[i];
c->total += c->count;
c->count = 0;
/*
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
unsigned long long int total; /* Total count over all epochs. */
};
-/* Increments the counter with the given NAME. Coverage counters need not be
- * declared explicitly, but when you add the first coverage counter to a given
- * file, you must also add that file to COVERAGE_FILES in lib/automake.mk. */
-#define COVERAGE_INC(NAME) \
- do { \
- extern struct coverage_counter NAME##_count; \
- NAME##_count.count++; \
- } while (0)
-
-/* Adds AMOUNT to the coverage counter with the given NAME. */
-#define COVERAGE_ADD(NAME, AMOUNT) \
- do { \
- extern struct coverage_counter NAME##_count; \
- NAME##_count.count += AMOUNT; \
- } while (0)
+/* Defines COUNTER. There must be exactly one such definition at file scope
+ * within a program. */
+#if USE_LINKER_SECTIONS
+#define COVERAGE_DEFINE(COUNTER) \
+ COVERAGE_DEFINE__(COUNTER); \
+ struct coverage_counter *counter_ptr_##COUNTER \
+ __attribute__((section("coverage"))) = &counter_##COUNTER
+#else
+#define COVERAGE_DEFINE(MODULE) \
+ extern struct coverage_counter counter_##MODULE
+#endif
+
+/* Adds 1 to COUNTER. */
+#define COVERAGE_INC(COUNTER) counter_##COUNTER.count++;
+
+/* Adds AMOUNT to COUNTER. */
+#define COVERAGE_ADD(COUNTER, AMOUNT) counter_##COUNTER.count += (AMOUNT);
void coverage_init(void);
void coverage_log(enum vlog_level, bool suppress_dups);
void coverage_clear(void);
+/* Implementation detail. */
+#define COVERAGE_DEFINE__(COUNTER) \
+ struct coverage_counter counter_##COUNTER = { #COUNTER, 0, 0 }
+
#endif /* coverage.h */
VLOG_DEFINE_THIS_MODULE(dpif);
+COVERAGE_DEFINE(dpif_destroy);
+COVERAGE_DEFINE(dpif_port_add);
+COVERAGE_DEFINE(dpif_port_del);
+COVERAGE_DEFINE(dpif_flow_flush);
+COVERAGE_DEFINE(dpif_flow_get);
+COVERAGE_DEFINE(dpif_flow_put);
+COVERAGE_DEFINE(dpif_flow_del);
+COVERAGE_DEFINE(dpif_flow_query_list);
+COVERAGE_DEFINE(dpif_flow_query_list_n);
+COVERAGE_DEFINE(dpif_execute);
+COVERAGE_DEFINE(dpif_purge);
+
static const struct dpif_class *base_dpif_classes[] = {
#ifdef HAVE_NETLINK
&dpif_linux_class,
}
}
+
/* Destroys the datapath that 'dpif' is connected to, first removing all of its
* ports. After calling this function, it does not make sense to pass 'dpif'
* to any functions other than dpif_name() or dpif_close(). */
VLOG_DEFINE_THIS_MODULE(flow);
+COVERAGE_DEFINE(flow_extract);
+
static struct arp_eth_header *
pull_arp(struct ofpbuf *packet)
{
#include "random.h"
#include "util.h"
+COVERAGE_DEFINE(hmap_pathological);
+COVERAGE_DEFINE(hmap_expand);
+COVERAGE_DEFINE(hmap_shrink);
+COVERAGE_DEFINE(hmap_reserve);
+
/* Initializes 'hmap' as an empty hash table. */
void
hmap_init(struct hmap *hmap)
VLOG_DEFINE_THIS_MODULE(lockfile);
+COVERAGE_DEFINE(lockfile_lock);
+COVERAGE_DEFINE(lockfile_timeout);
+COVERAGE_DEFINE(lockfile_error);
+COVERAGE_DEFINE(lockfile_unlock);
+
struct lockfile {
struct hmap_node hmap_node;
char *name;
VLOG_DEFINE_THIS_MODULE(mac_learning);
+COVERAGE_DEFINE(mac_learning_learned);
+COVERAGE_DEFINE(mac_learning_expired);
+
/* Returns the number of seconds since 'e' was last learned. */
int
mac_entry_age(const struct mac_entry *e)
#include "vlog.h"
VLOG_DEFINE_THIS_MODULE(netdev_linux);
+
+COVERAGE_DEFINE(netdev_get_vlan_vid);
+COVERAGE_DEFINE(netdev_set_policing);
+COVERAGE_DEFINE(netdev_arp_lookup);
+COVERAGE_DEFINE(netdev_get_ifindex);
+COVERAGE_DEFINE(netdev_get_hwaddr);
+COVERAGE_DEFINE(netdev_set_hwaddr);
+COVERAGE_DEFINE(netdev_ethtool);
\f
/* These were introduced in Linux 2.6.14, so they might be missing if we have
* old headers. */
VLOG_DEFINE_THIS_MODULE(netdev);
+COVERAGE_DEFINE(netdev_received);
+COVERAGE_DEFINE(netdev_sent);
+COVERAGE_DEFINE(netdev_add_router);
+COVERAGE_DEFINE(netdev_get_stats);
+
static struct shash netdev_classes = SHASH_INITIALIZER(&netdev_classes);
/* All created network devices. */
VLOG_DEFINE_THIS_MODULE(netlink);
+COVERAGE_DEFINE(netlink_overflow);
+COVERAGE_DEFINE(netlink_received);
+COVERAGE_DEFINE(netlink_recv_retry);
+COVERAGE_DEFINE(netlink_send);
+COVERAGE_DEFINE(netlink_sent);
+
/* Linux header file confusion causes this to be undefined. */
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
VLOG_DEFINE_THIS_MODULE(poll_loop);
+COVERAGE_DEFINE(poll_fd_wait);
+COVERAGE_DEFINE(poll_zero_timeout);
+
/* An event that will wake the following call to poll_block(). */
struct poll_waiter {
/* Set when the waiter is created. */
VLOG_DEFINE_THIS_MODULE(process);
+COVERAGE_DEFINE(process_run);
+COVERAGE_DEFINE(process_run_capture);
+COVERAGE_DEFINE(process_sigchld);
+COVERAGE_DEFINE(process_start);
+
struct process {
struct list node;
char *name;
VLOG_DEFINE_THIS_MODULE(rconn);
+COVERAGE_DEFINE(rconn_discarded);
+COVERAGE_DEFINE(rconn_overflow);
+COVERAGE_DEFINE(rconn_queued);
+COVERAGE_DEFINE(rconn_sent);
+
#define STATES \
STATE(VOID, 1 << 0) \
STATE(BACKOFF, 1 << 1) \
VLOG_DEFINE_THIS_MODULE(rtnetlink);
+COVERAGE_DEFINE(rtnetlink_changed);
+
/* rtnetlink socket. */
static struct nl_sock *notify_sock;
VLOG_DEFINE_THIS_MODULE(stream_ssl);
+COVERAGE_DEFINE(ssl_session);
+COVERAGE_DEFINE(ssl_session_reused);
+
/* Active SSL. */
enum ssl_state {
VLOG_DEFINE_THIS_MODULE(stream);
+COVERAGE_DEFINE(pstream_open);
+COVERAGE_DEFINE(stream_open);
+
/* State of an active stream.*/
enum stream_state {
SCS_CONNECTING, /* Underlying stream is not connected. */
#endif
VLOG_DEFINE_THIS_MODULE(unixctl);
+
+COVERAGE_DEFINE(unixctl_received);
+COVERAGE_DEFINE(unixctl_replied);
\f
struct unixctl_command {
unixctl_cb_func *cb;
VLOG_DEFINE_THIS_MODULE(util);
+COVERAGE_DEFINE(util_xalloc);
+
const char *program_name;
void
VLOG_DEFINE_THIS_MODULE(vconn);
+COVERAGE_DEFINE(vconn_open);
+COVERAGE_DEFINE(vconn_received);
+COVERAGE_DEFINE(vconn_sent);
+
/* State of an active vconn.*/
enum vconn_state {
/* This is the ordinary progression of states. */
VLOG_DEFINE_THIS_MODULE(ofproto);
+COVERAGE_DEFINE(odp_overflow);
+COVERAGE_DEFINE(ofproto_add_wc_flow);
+COVERAGE_DEFINE(ofproto_agg_request);
+COVERAGE_DEFINE(ofproto_costly_flags);
+COVERAGE_DEFINE(ofproto_ctlr_action);
+COVERAGE_DEFINE(ofproto_del_wc_flow);
+COVERAGE_DEFINE(ofproto_dp_missed);
+COVERAGE_DEFINE(ofproto_error);
+COVERAGE_DEFINE(ofproto_expiration);
+COVERAGE_DEFINE(ofproto_expired);
+COVERAGE_DEFINE(ofproto_flows_req);
+COVERAGE_DEFINE(ofproto_flush);
+COVERAGE_DEFINE(ofproto_invalidated);
+COVERAGE_DEFINE(ofproto_mod_wc_flow);
+COVERAGE_DEFINE(ofproto_no_packet_in);
+COVERAGE_DEFINE(ofproto_odp_unchanged);
+COVERAGE_DEFINE(ofproto_ofconn_stuck);
+COVERAGE_DEFINE(ofproto_ofp2odp);
+COVERAGE_DEFINE(ofproto_packet_in);
+COVERAGE_DEFINE(ofproto_packet_out);
+COVERAGE_DEFINE(ofproto_queue_req);
+COVERAGE_DEFINE(ofproto_recv_openflow);
+COVERAGE_DEFINE(ofproto_reinit_ports);
+COVERAGE_DEFINE(ofproto_revalidate);
+COVERAGE_DEFINE(ofproto_revalidate_moved);
+COVERAGE_DEFINE(ofproto_revalidate_rule);
+COVERAGE_DEFINE(ofproto_subrule_create);
+COVERAGE_DEFINE(ofproto_unexpected_rule);
+COVERAGE_DEFINE(ofproto_uninstallable);
+COVERAGE_DEFINE(ofproto_update_port);
+
#include "sflow_api.h"
struct ofport {
VLOG_DEFINE_THIS_MODULE(pktbuf);
+COVERAGE_DEFINE(pktbuf_buffer_unknown);
+COVERAGE_DEFINE(pktbuf_null_cookie);
+COVERAGE_DEFINE(pktbuf_retrieved);
+COVERAGE_DEFINE(pktbuf_reuse_error);
+
/* Buffers are identified by a 32-bit opaque ID. We divide the ID
* into a buffer number (low bits) and a cookie (high bits). The buffer number
* is an index into an array of buffers. The cookie distinguishes between
VLOG_DEFINE_THIS_MODULE(bridge);
+COVERAGE_DEFINE(bridge_flush);
+COVERAGE_DEFINE(bridge_process_flow);
+COVERAGE_DEFINE(bridge_reconfigure);
+
struct dst {
uint16_t vlan;
uint16_t dp_ifidx;