From: Ben Pfaff Date: Tue, 5 May 2009 17:23:02 +0000 (-0700) Subject: Add support for coverage counters. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26066d656b15d2713172c810be6ff2aeb7a08034;p=openvswitch Add support for coverage counters. This commit implements a simple form of coverage instrumentation. Points in source code that are of interest must be explicitly annotated with COVERAGE_INC. The coverage counters may be logged at any time with coverage_log(). This form of coverage instrumentation is intended to be so lightweight that it can be enabled in production builds. It is obviously not a substitute for traditional coverage instrumentation with e.g. "gcov", but it is still a useful debugging tool. --- diff --git a/lib/.gitignore b/lib/.gitignore index b069cc18..6a3f65ce 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,3 +1,4 @@ /Makefile /Makefile.in /dhparams.c +/coverage-counters.c diff --git a/lib/automake.mk b/lib/automake.mk index 66edf493..e76881aa 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -12,6 +12,10 @@ lib_libopenflow_a_SOURCES = \ lib/command-line.c \ lib/command-line.h \ lib/compiler.h \ + lib/coverage.c \ + lib/coverage.h \ + lib/coverage-counters.c \ + lib/coverage-counters.h \ lib/csum.c \ lib/csum.h \ lib/daemon.c \ @@ -152,3 +156,28 @@ install-data-local: $(MKDIR_P) $(DESTDIR)$(RUNDIR) $(MKDIR_P) $(DESTDIR)$(PKIDIR) $(MKDIR_P) $(DESTDIR)$(LOGDIR) + +# All the source files that have coverage counters. +COVERAGE_SOURCES = \ + lib/dpif.c \ + lib/flow.c \ + lib/hmap.c \ + lib/mac-learning.c \ + lib/netdev.c \ + lib/netlink.c \ + lib/odp-util.c \ + lib/poll-loop.c \ + lib/process.c \ + lib/rconn.c \ + lib/timeval.c \ + lib/unixctl.c \ + lib/util.c \ + lib/vconn.c \ + secchan/ofproto.c \ + secchan/pktbuf.c \ + vswitchd/bridge.c \ + vswitchd/mgmt.c +lib/coverage-counters.c: $(COVERAGE_SOURCES) lib/coverage-scan.pl + (cd $(srcdir) && $(PERL) lib/coverage-scan.pl $(COVERAGE_SOURCES)) > $@.tmp + mv $@.tmp $@ +EXTRA_DIST += lib/coverage-scan.pl diff --git a/lib/coverage-counters.h b/lib/coverage-counters.h new file mode 100644 index 00000000..e6adbed0 --- /dev/null +++ b/lib/coverage-counters.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2009 The Board of Trustees of The Leland Stanford Junior + * University + * + * We are making the OpenFlow specification and associated documentation + * (Software) available for public use and benefit with the expectation + * that others will use, modify and enhance the Software and contribute + * those enhancements back to the community. However, since we would + * like to make the Software available for broadest use, with as few + * restrictions as possible permission is hereby granted, free of + * charge, to any person obtaining a copy of this Software to deal in + * the Software under the copyrights without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The name and trademarks of copyright holder(s) may NOT be used in + * advertising or publicity pertaining to the Software or any + * derivatives without specific, written prior permission. + */ + +#ifndef COVERAGE_COUNTERS_H +#define COVERAGE_COUNTERS_H 1 + +#include + +extern struct coverage_counter *coverage_counters[]; +extern size_t coverage_n_counters; + +#endif /* coverage.h */ diff --git a/lib/coverage-scan.pl b/lib/coverage-scan.pl new file mode 100755 index 00000000..f9dc2d82 --- /dev/null +++ b/lib/coverage-scan.pl @@ -0,0 +1,65 @@ +# Copyright (c) 2009 The Board of Trustees of The Leland Stanford Junior +# University +# +# We are making the OpenFlow specification and associated documentation +# (Software) available for public use and benefit with the expectation +# that others will use, modify and enhance the Software and contribute +# those enhancements back to the community. However, since we would +# like to make the Software available for broadest use, with as few +# restrictions as possible permission is hereby granted, free of +# charge, to any person obtaining a copy of this Software to deal in +# the Software under the copyrights without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# The name and trademarks of copyright holder(s) may NOT be used in +# advertising or publicity pertaining to the Software or any +# derivatives without specific, written prior permission. + +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 < +#include "coverage.h" +#include "util.h" + +EOF + +for my $counter (sort(keys(%counters))) { + my $locations = join(', ', @{$counters{$counter}}); + print < +#include "coverage.h" +#include "coverage-counters.h" +#include "dynamic-string.h" +#include "util.h" + +#define THIS_MODULE VLM_coverage +#include "vlog.h" + +static unsigned int epoch; + +static void +coverage_log_counter(enum vlog_level level, const struct coverage_counter *c) +{ + VLOG(level, "%-24s %5u / %9llu", c->name, c->count, c->count + c->total); +} + +/* Logs the coverage counters at the given vlog 'level'. */ +void +coverage_log(enum vlog_level level) +{ + size_t i; + size_t n_never_hit; + + if (!vlog_is_enabled(THIS_MODULE, level)) { + return; + } + + n_never_hit = 0; + VLOG(level, "Event coverage (epoch %u/entire run):", epoch); + for (i = 0; i < coverage_n_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++) { + struct coverage_counter *c = coverage_counters[i]; + if (!c->count) { + if (c->total) { + coverage_log_counter(level, c); + } else { + n_never_hit++; + } + } + } + VLOG(level, "%zu events never hit", n_never_hit); +} + +/* Advances to the next epoch of coverage, resetting all the counters to 0. */ +void +coverage_clear(void) +{ + size_t i; + + epoch++; + for (i = 0; i < coverage_n_counters; i++) { + struct coverage_counter *c = coverage_counters[i]; + c->total += c->count; + c->count = 0; + } +} diff --git a/lib/coverage.h b/lib/coverage.h new file mode 100644 index 00000000..1d5bcc2f --- /dev/null +++ b/lib/coverage.h @@ -0,0 +1,75 @@ +/* Copyright (c) 2009 The Board of Trustees of The Leland Stanford Junior + * University + * + * We are making the OpenFlow specification and associated documentation + * (Software) available for public use and benefit with the expectation + * that others will use, modify and enhance the Software and contribute + * those enhancements back to the community. However, since we would + * like to make the Software available for broadest use, with as few + * restrictions as possible permission is hereby granted, free of + * charge, to any person obtaining a copy of this Software to deal in + * the Software under the copyrights without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The name and trademarks of copyright holder(s) may NOT be used in + * advertising or publicity pertaining to the Software or any + * derivatives without specific, written prior permission. + */ + +#ifndef COVERAGE_H +#define COVERAGE_H 1 + +/* This file implements a simple form of coverage instrumentation. Points in + * source code that are of interest must be explicitly annotated with + * COVERAGE_INC. The coverage counters may be logged at any time with + * coverage_log(). + * + * This form of coverage instrumentation is intended to be so lightweight that + * it can be enabled in production builds. It is obviously not a substitute + * for traditional coverage instrumentation with e.g. "gcov", but it is still + * a useful debugging tool. */ + +#include "vlog.h" + +/* A coverage counter. */ +struct coverage_counter { + const char *name; /* Textual name. */ + unsigned int count; /* Count within the current epoch. */ + 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_SOURCES 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) + +void coverage_log(enum vlog_level); +void coverage_clear(void); + +#endif /* coverage.h */ diff --git a/lib/dpif.c b/lib/dpif.c index 0ff68a5a..f30b0bba 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -51,6 +51,7 @@ #include #include +#include "coverage.h" #include "dynamic-string.h" #include "flow.h" #include "netlink.h" @@ -203,6 +204,7 @@ dpif_get_name(struct dpif *dpif, char *name, size_t name_size) int dpif_delete(struct dpif *dpif) { + COVERAGE_INC(dpif_destroy); return do_ioctl(dpif, ODP_DP_DESTROY, "ODP_DP_DESTROY", NULL); } @@ -254,6 +256,8 @@ dpif_purge(struct dpif *dpif) unsigned int i; int error; + COVERAGE_INC(dpif_purge); + error = dpif_get_dp_stats(dpif, &stats); if (error) { return error; @@ -275,6 +279,7 @@ dpif_port_add(struct dpif *dpif, const char *devname, uint16_t port_no) { struct odp_port port; + COVERAGE_INC(dpif_port_add); memset(&port, 0, sizeof port); strncpy(port.devname, devname, sizeof port.devname); port.port = port_no; @@ -294,6 +299,7 @@ int dpif_port_del(struct dpif *dpif, uint16_t port_no) { int tmp = port_no; + COVERAGE_INC(dpif_port_del); return do_ioctl(dpif, ODP_PORT_DEL, "ODP_PORT_DEL", &tmp); } @@ -369,6 +375,7 @@ dpif_port_group_set(struct dpif *dpif, uint16_t group, { struct odp_port_group pg; + COVERAGE_INC(dpif_port_group_set); assert(n_ports <= UINT16_MAX); pg.group = group; pg.ports = (uint16_t *) ports; @@ -397,6 +404,7 @@ dpif_port_group_get(const struct dpif *dpif, uint16_t group, int dpif_flow_flush(struct dpif *dpif) { + COVERAGE_INC(dpif_flow_flush); return do_ioctl(dpif, ODP_FLOW_FLUSH, "ODP_FLOW_FLUSH", NULL); } @@ -461,6 +469,7 @@ int dpif_flow_put(struct dpif *dpif, struct odp_flow_put *put) { int error = do_ioctl(dpif, ODP_FLOW_PUT, NULL, put); + COVERAGE_INC(dpif_flow_put); if (should_log_flow_message(error)) { struct ds operation = DS_EMPTY_INITIALIZER; ds_put_cstr(&operation, "put"); @@ -488,6 +497,7 @@ dpif_flow_put(struct dpif *dpif, struct odp_flow_put *put) int dpif_flow_del(struct dpif *dpif, struct odp_flow *flow) { + COVERAGE_INC(dpif_flow_del); check_rw_odp_flow(flow); memset(&flow->stats, 0, sizeof flow->stats); return do_flow_ioctl(dpif, ODP_FLOW_DEL, flow, "delete flow", true); @@ -496,6 +506,7 @@ dpif_flow_del(struct dpif *dpif, struct odp_flow *flow) int dpif_flow_get(const struct dpif *dpif, struct odp_flow *flow) { + COVERAGE_INC(dpif_flow_query); check_rw_odp_flow(flow); memset(&flow->stats, 0, sizeof flow->stats); return do_flow_ioctl(dpif, ODP_FLOW_GET, flow, "get flow", true); @@ -508,6 +519,7 @@ dpif_flow_get_multiple(const struct dpif *dpif, struct odp_flowvec fv; size_t i; + COVERAGE_ADD(dpif_flow_query_multiple, n); fv.flows = flows; fv.n_flows = n; for (i = 0; i < n; i++) { @@ -525,6 +537,7 @@ dpif_flow_list(const struct dpif *dpif, struct odp_flow flows[], size_t n, uint32_t i; int error; + COVERAGE_INC(dpif_flow_query_list); fv.flows = flows; fv.n_flows = n; if (RUNNING_ON_VALGRIND) { @@ -541,6 +554,7 @@ dpif_flow_list(const struct dpif *dpif, struct odp_flow flows[], size_t n, VLOG_WARN_RL(&error_rl, "dp%u: flow list failed (%s)", dpif->minor, strerror(error)); } else { + COVERAGE_ADD(dpif_flow_query_list_n, fv.n_flows); *n_out = fv.n_flows; VLOG_DBG_RL(&dpmsg_rl, "dp%u: listed %zu flows", dpif->minor, *n_out); } @@ -588,6 +602,7 @@ dpif_execute(struct dpif *dpif, uint16_t in_port, { int error; + COVERAGE_INC(dpif_execute); if (n_actions > 0) { struct odp_execute execute; memset(&execute, 0, sizeof execute); @@ -620,6 +635,7 @@ dpif_execute(struct dpif *dpif, uint16_t in_port, int dpif_snat_add_port(struct dpif *dpif, const struct odp_snat_config *osc) { + COVERAGE_INC(dpif_snat_add_port); return do_ioctl(dpif, ODP_SNAT_ADD_PORT, "ODP_SNAT_ADD_PORT", osc); } @@ -627,6 +643,7 @@ int dpif_snat_del_port(struct dpif *dpif, uint16_t port) { int tmp = port; + COVERAGE_INC(dpif_snat_del_port); return do_ioctl(dpif, ODP_SNAT_DEL_PORT, "ODP_SNAT_DEL_PORT", &tmp); } @@ -663,6 +680,7 @@ dpif_recv(struct dpif *dpif, struct ofpbuf **bufp) free(s); } *bufp = buf; + COVERAGE_INC(dpif_recv); return 0; } else { VLOG_WARN_RL(&error_rl, "dp%u: discarding message truncated " @@ -790,8 +808,10 @@ again: if (!for_us) { /* Not for us, try again. */ ofpbuf_delete(buf); + COVERAGE_INC(dpifmon_poll_false_wakeup); goto again; } + COVERAGE_INC(dpifmon_poll_changed); *devnamep = xstrdup(devname); } ofpbuf_delete(buf); diff --git a/lib/flow.c b/lib/flow.c index 156416a1..d2545d5f 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -37,6 +37,7 @@ #include #include #include +#include "coverage.h" #include "dynamic-string.h" #include "hash.h" #include "ofpbuf.h" @@ -105,6 +106,8 @@ flow_extract(struct ofpbuf *packet, uint16_t in_port, flow_t *flow) struct eth_header *eth; int retval = 0; + COVERAGE_INC(flow_extract); + memset(flow, 0, sizeof *flow); flow->dl_vlan = htons(OFP_VLAN_NONE); flow->in_port = in_port; diff --git a/lib/hmap.c b/lib/hmap.c index f05bdb77..e55e6076 100644 --- a/lib/hmap.c +++ b/lib/hmap.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford +/* Copyright (c) 2008, 2009 The Board of Trustees of The Leland Stanford * Junior University * * We are making the OpenFlow specification and associated documentation @@ -35,6 +35,7 @@ #include "hmap.h" #include #include +#include "coverage.h" #include "util.h" /* Initializes 'hmap' as an empty hash table. */ @@ -91,9 +92,14 @@ resize(struct hmap *hmap, size_t new_mask) } for (i = 0; i <= hmap->mask; i++) { struct hmap_node *node, *next; + int count = 0; for (node = hmap->buckets[i]; node; node = next) { next = node->next; hmap_insert_fast(&tmp, node, node->hash); + count++; + } + if (count > 5) { + COVERAGE_INC(hmap_pathological); } } hmap_swap(hmap, &tmp); @@ -126,6 +132,7 @@ hmap_expand(struct hmap *hmap) { size_t new_mask = calc_mask(hmap->n); if (new_mask > hmap->mask) { + COVERAGE_INC(hmap_expand); resize(hmap, new_mask); } } @@ -136,6 +143,7 @@ hmap_shrink(struct hmap *hmap) { size_t new_mask = calc_mask(hmap->n); if (new_mask < hmap->mask) { + COVERAGE_INC(hmap_shrink); resize(hmap, new_mask); } } @@ -148,6 +156,7 @@ hmap_reserve(struct hmap *hmap, size_t n) { size_t new_mask = calc_mask(n); if (new_mask > hmap->mask) { + COVERAGE_INC(hmap_reserve); resize(hmap, new_mask); } } diff --git a/lib/mac-learning.c b/lib/mac-learning.c index 73e1eef9..f82e030b 100644 --- a/lib/mac-learning.c +++ b/lib/mac-learning.c @@ -38,6 +38,7 @@ #include #include +#include "coverage.h" #include "hash.h" #include "list.h" #include "poll-loop.h" @@ -225,6 +226,7 @@ mac_learning_learn(struct mac_learning *ml, tag_type old_tag = e->tag; e->port = src_port; e->tag = tag_create_random(); + COVERAGE_INC(mac_learning_learned); return old_tag; } return 0; @@ -283,6 +285,7 @@ mac_learning_run(struct mac_learning *ml, struct tag_set *set) { struct mac_entry *e; while (get_lru(ml, &e) && time_now() >= e->expires) { + COVERAGE_INC(mac_learning_expired); if (set) { tag_set_add(set, e->tag); } diff --git a/lib/netdev.c b/lib/netdev.c index 5704777c..0935efa2 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -59,6 +59,7 @@ #include #include +#include "coverage.h" #include "dynamic-string.h" #include "fatal-signal.h" #include "list.h" @@ -201,6 +202,7 @@ do_ethtool(struct netdev *netdev, struct ethtool_cmd *ecmd, ifr.ifr_data = (caddr_t) ecmd; ecmd->cmd = cmd; + COVERAGE_INC(netdev_ethtool); if (ioctl(netdev->netdev_fd, SIOCETHTOOL, &ifr) == 0) { return 0; } else { @@ -419,6 +421,7 @@ do_open_netdev(const char *name, int ethertype, int tap_fd, init_netdev(); *netdev_ = NULL; + COVERAGE_INC(netdev_open); /* Create raw socket. */ netdev_fd = socket(PF_PACKET, SOCK_RAW, @@ -590,6 +593,7 @@ netdev_recv(struct netdev *netdev, struct ofpbuf *buffer) } return errno; } else { + COVERAGE_INC(netdev_received); buffer->size += n_bytes; /* When the kernel internally sends out an Ethernet frame on an @@ -657,6 +661,7 @@ netdev_send(struct netdev *netdev, const struct ofpbuf *buffer) (int) n_bytes, buffer->size, netdev->name); return EMSGSIZE; } else { + COVERAGE_INC(netdev_sent); return 0; } } @@ -803,6 +808,7 @@ netdev_get_in4(const struct netdev *netdev, struct in_addr *in4) strncpy(ifr.ifr_name, netdev->name, sizeof ifr.ifr_name); ifr.ifr_addr.sa_family = AF_INET; + COVERAGE_INC(netdev_get_in4); if (ioctl(af_inet_sock, SIOCGIFADDR, &ifr) == 0) { struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr; ip = sin->sin_addr; @@ -838,6 +844,7 @@ do_set_addr(struct netdev *netdev, int sock, strncpy(ifr.ifr_name, netdev->name, sizeof ifr.ifr_name); make_in4_sockaddr(&ifr.ifr_addr, addr); + COVERAGE_INC(netdev_set_in4); error = ioctl(sock, ioctl_nr, &ifr) < 0 ? errno : 0; if (error) { VLOG_WARN("ioctl(%s): %s", ioctl_name, strerror(error)); @@ -875,6 +882,7 @@ netdev_add_router(struct in_addr router) make_in4_sockaddr(&rt.rt_gateway, router); make_in4_sockaddr(&rt.rt_genmask, any); rt.rt_flags = RTF_UP | RTF_GATEWAY; + COVERAGE_INC(netdev_add_router); error = ioctl(af_inet_sock, SIOCADDRT, &rt) < 0 ? errno : 0; if (error) { VLOG_WARN("ioctl(SIOCADDRT): %s", strerror(error)); @@ -994,6 +1002,7 @@ netdev_arp_lookup(const struct netdev *netdev, r.arp_ha.sa_family = ARPHRD_ETHER; r.arp_flags = 0; strncpy(r.arp_dev, netdev->name, sizeof r.arp_dev); + COVERAGE_INC(netdev_arp_lookup); retval = ioctl(af_inet_sock, SIOCGARP, &r) < 0 ? errno : 0; if (!retval) { memcpy(mac, r.arp_ha.sa_data, ETH_ADDR_LEN); @@ -1176,6 +1185,7 @@ netdev_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { int error; + COVERAGE_INC(netdev_get_stats); if (use_netlink_stats) { int ifindex; @@ -1206,6 +1216,7 @@ netdev_nodev_set_policing(const char *netdev_name, uint32_t kbits_rate, init_netdev(); + COVERAGE_INC(netdev_set_policing); if (kbits_rate) { if (!kbits_burst) { /* Default to 10 kilobits if not specified. */ @@ -1318,6 +1329,7 @@ netdev_get_vlan_vid(const char *netdev_name, int *vlan_vid) int error; char *fn; + COVERAGE_INC(netdev_get_vlan_vid); fn = xasprintf("/proc/net/vlan/%s", netdev_name); stream = fopen(fn, "r"); if (!stream) { @@ -1419,6 +1431,7 @@ restore_flags(struct netdev *netdev) /* Get current flags. */ strncpy(ifr.ifr_name, netdev->name, sizeof ifr.ifr_name); + COVERAGE_INC(netdev_get_flags); if (ioctl(netdev->netdev_fd, SIOCGIFFLAGS, &ifr) < 0) { return errno; } @@ -1428,6 +1441,7 @@ restore_flags(struct netdev *netdev) if ((ifr.ifr_flags ^ netdev->save_flags) & restore_flags) { ifr.ifr_flags &= ~restore_flags; ifr.ifr_flags |= netdev->save_flags & restore_flags; + COVERAGE_INC(netdev_set_flags); if (ioctl(netdev->netdev_fd, SIOCSIFFLAGS, &ifr) < 0) { return errno; } @@ -1452,6 +1466,7 @@ get_flags(const char *netdev_name, int *flags) { struct ifreq ifr; strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); + COVERAGE_INC(netdev_get_flags); if (ioctl(af_inet_sock, SIOCGIFFLAGS, &ifr) < 0) { VLOG_ERR("ioctl(SIOCGIFFLAGS) on %s device failed: %s", netdev_name, strerror(errno)); @@ -1467,6 +1482,7 @@ set_flags(const char *netdev_name, int flags) struct ifreq ifr; strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); ifr.ifr_flags = flags; + COVERAGE_INC(netdev_set_flags); if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) < 0) { VLOG_ERR("ioctl(SIOCSIFFLAGS) on %s device failed: %s", netdev_name, strerror(errno)); @@ -1481,6 +1497,7 @@ do_get_ifindex(const char *netdev_name) struct ifreq ifr; strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); + COVERAGE_INC(netdev_get_ifindex); if (ioctl(af_inet_sock, SIOCGIFINDEX, &ifr) < 0) { VLOG_WARN_RL(&rl, "ioctl(SIOCGIFINDEX) on %s device failed: %s", netdev_name, strerror(errno)); @@ -1512,6 +1529,7 @@ get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN], memset(&ifr, 0, sizeof ifr); strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); + COVERAGE_INC(netdev_get_hwaddr); if (ioctl(af_inet_sock, SIOCGIFHWADDR, &ifr) < 0) { VLOG_ERR("ioctl(SIOCGIFHWADDR) on %s device failed: %s", netdev_name, strerror(errno)); @@ -1539,6 +1557,7 @@ set_etheraddr(const char *netdev_name, int hwaddr_family, strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); ifr.ifr_hwaddr.sa_family = hwaddr_family; memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ADDR_LEN); + COVERAGE_INC(netdev_set_hwaddr); if (ioctl(af_inet_sock, SIOCSIFHWADDR, &ifr) < 0) { VLOG_ERR("ioctl(SIOCSIFHWADDR) on %s device failed: %s", netdev_name, strerror(errno)); diff --git a/lib/netlink.c b/lib/netlink.c index 52416a63..301a2e84 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -41,6 +41,7 @@ #include #include #include +#include "coverage.h" #include "dynamic-string.h" #include "netlink-protocol.h" #include "ofpbuf.h" @@ -229,6 +230,9 @@ nl_sock_send(struct nl_sock *sock, const struct ofpbuf *msg, bool wait) error = retval < 0 ? errno : 0; } while (error == EINTR); log_nlmsg(__func__, error, msg->data, msg->size); + if (!error) { + COVERAGE_INC(netlink_sent); + } return error; } @@ -246,6 +250,7 @@ nl_sock_sendv(struct nl_sock *sock, const struct iovec iov[], size_t n_iov, struct msghdr msg; int error; + COVERAGE_INC(netlink_send); memset(&msg, 0, sizeof msg); msg.msg_iov = (struct iovec *) iov; msg.msg_iovlen = n_iov; @@ -256,6 +261,9 @@ nl_sock_sendv(struct nl_sock *sock, const struct iovec iov[], size_t n_iov, } while (error == EINTR); if (error != EAGAIN) { log_nlmsg(__func__, error, iov[0].iov_base, iov[0].iov_len); + if (!error) { + COVERAGE_INC(netlink_sent); + } } return error; } @@ -306,6 +314,7 @@ try_again: return errno; } if (msg.msg_flags & MSG_TRUNC) { + COVERAGE_INC(netlink_recv_retry); bufsize *= 2; ofpbuf_reinit(buf, bufsize); goto try_again; @@ -324,6 +333,7 @@ try_again: * was dropped. We have to pass this along to the caller in case * it wants to retry a request. So kill the buffer, which we can * re-read next time. */ + COVERAGE_INC(netlink_overflow); ofpbuf_delete(buf); return ENOBUFS; } else { @@ -341,6 +351,7 @@ try_again: } *bufp = buf; log_nlmsg(__func__, 0, buf->data, buf->size); + COVERAGE_INC(netlink_received); return 0; } @@ -402,6 +413,7 @@ recv: retval = nl_sock_recv(sock, &reply, true); if (retval) { if (retval == ENOBUFS) { + COVERAGE_INC(netlink_overflow); VLOG_DBG_RL(&rl, "receive buffer overflow, resending request"); goto send; } else { diff --git a/lib/odp-util.c b/lib/odp-util.c index 63b3da16..9c2a57c3 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -36,6 +36,7 @@ #include #include #include +#include "coverage.h" #include "dynamic-string.h" #include "flow.h" #include "packets.h" @@ -49,6 +50,7 @@ odp_actions_add(struct odp_actions *actions, uint16_t type) if (actions->n_actions < MAX_ODP_ACTIONS) { a = &actions->actions[actions->n_actions++]; } else { + COVERAGE_INC(odp_overflow); actions->n_actions = MAX_ODP_ACTIONS + 1; a = &actions->actions[MAX_ODP_ACTIONS - 1]; } diff --git a/lib/poll-loop.c b/lib/poll-loop.c index 09df0361..aed21265 100644 --- a/lib/poll-loop.c +++ b/lib/poll-loop.c @@ -39,6 +39,7 @@ #include #include #include "backtrace.h" +#include "coverage.h" #include "dynamic-string.h" #include "list.h" #include "timeval.h" @@ -92,6 +93,7 @@ static struct poll_waiter *new_waiter(int fd, short int events); struct poll_waiter * poll_fd_wait(int fd, short int events) { + COVERAGE_INC(poll_fd_wait); return new_waiter(fd, events); } @@ -176,6 +178,9 @@ poll_block(void) n_pollfds++; } + if (!timeout) { + COVERAGE_INC(poll_zero_timeout); + } retval = time_poll(pollfds, n_pollfds, timeout); if (retval < 0) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); diff --git a/lib/process.c b/lib/process.c index e27f6547..755ad2e1 100644 --- a/lib/process.c +++ b/lib/process.c @@ -42,6 +42,7 @@ #include #include #include +#include "coverage.h" #include "dynamic-string.h" #include "list.h" #include "poll-loop.h" @@ -156,6 +157,7 @@ process_start(char **argv, *pp = NULL; process_init(); + COVERAGE_INC(process_start); if (VLOG_IS_DBG_ENABLED()) { char *args = process_escape_args(argv); @@ -289,6 +291,7 @@ process_run(char **argv, struct process *p; int retval; + COVERAGE_INC(process_run); retval = process_start(argv, keep_fds, n_keep_fds, null_fds, n_null_fds, &p); if (retval) { @@ -377,6 +380,7 @@ sigchld_handler(int signr UNUSED) { struct process *p; + COVERAGE_INC(process_sigchld); LIST_FOR_EACH (p, struct process, node, &all_processes) { if (!p->exited) { int retval, status; diff --git a/lib/rconn.c b/lib/rconn.c index f7a5e4b5..b0453422 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -38,6 +38,7 @@ #include #include #include +#include "coverage.h" #include "ofpbuf.h" #include "openflow/openflow.h" #include "poll-loop.h" @@ -548,6 +549,7 @@ rconn_send(struct rconn *rc, struct ofpbuf *b, struct rconn_packet_counter *counter) { if (rconn_is_connected(rc)) { + COVERAGE_INC(rconn_queued); copy_to_monitor(rc, b); b->private = counter; if (counter) { @@ -587,6 +589,7 @@ rconn_send_with_limit(struct rconn *rc, struct ofpbuf *b, int retval; retval = counter->n >= queue_limit ? EAGAIN : rconn_send(rc, b, counter); if (retval) { + COVERAGE_INC(rconn_overflow); ofpbuf_delete(b); } return retval; @@ -800,6 +803,7 @@ try_send(struct rconn *rc) } return retval; } + COVERAGE_INC(rconn_sent); rc->packets_sent++; if (counter) { rconn_packet_counter_dec(counter); @@ -864,6 +868,7 @@ flush_queue(struct rconn *rc) if (counter) { rconn_packet_counter_dec(counter); } + COVERAGE_INC(rconn_discarded); ofpbuf_delete(b); } poll_immediate_wake(); diff --git a/lib/timeval.c b/lib/timeval.c index 00cf0551..0755e0d2 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -39,6 +39,7 @@ #include #include #include +#include "coverage.h" #include "fatal-signal.h" #include "util.h" @@ -166,6 +167,7 @@ time_poll(struct pollfd *pollfds, int n_pollfds, int timeout) time_refresh(); log_poll_interval(last_wakeup); + coverage_clear(); start = time_msec(); blocked = false; for (;;) { @@ -264,6 +266,7 @@ log_poll_interval(long long int last_wakeup) "the weighted mean interval %u ms (%u samples)", (interval + 8) / 16, interval / mean_interval, (mean_interval + 8) / 16, n_samples); + coverage_log(VLL_WARN); } /* Update exponentially weighted moving average. With these parameters, a diff --git a/lib/unixctl.c b/lib/unixctl.c index 81794f27..4bf1c7a4 100644 --- a/lib/unixctl.c +++ b/lib/unixctl.c @@ -42,6 +42,7 @@ #include #include #include +#include "coverage.h" #include "dirs.h" #include "dynamic-string.h" #include "fatal-signal.h" @@ -145,6 +146,7 @@ unixctl_command_reply(struct unixctl_conn *conn, { struct ds *out = &conn->out; + COVERAGE_INC(unixctl_replied); assert(conn->state == S_PROCESS); conn->state = S_SEND; conn->out_pos = 0; @@ -286,6 +288,7 @@ process_command(struct unixctl_conn *conn, char *s) size_t name_len; char *name, *args; + COVERAGE_INC(unixctl_received); conn->state = S_PROCESS; name = s; diff --git a/lib/util.c b/lib/util.c index 21cc28d2..d39a9318 100644 --- a/lib/util.c +++ b/lib/util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford +/* Copyright (c) 2008, 2009 The Board of Trustees of The Leland Stanford * Junior University * * We are making the OpenFlow specification and associated documentation @@ -38,6 +38,7 @@ #include #include #include +#include "coverage.h" const char *program_name; @@ -51,6 +52,7 @@ void * xcalloc(size_t count, size_t size) { void *p = count && size ? calloc(count, size) : malloc(1); + COVERAGE_INC(util_xalloc); if (p == NULL) { out_of_memory(); } @@ -61,6 +63,7 @@ void * xmalloc(size_t size) { void *p = malloc(size ? size : 1); + COVERAGE_INC(util_xalloc); if (p == NULL) { out_of_memory(); } @@ -71,6 +74,7 @@ void * xrealloc(void *p, size_t size) { p = realloc(p, size ? size : 1); + COVERAGE_INC(util_xalloc); if (p == NULL) { out_of_memory(); } diff --git a/lib/vconn.c b/lib/vconn.c index df7d5c0e..ec1da4b4 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -40,6 +40,7 @@ #include #include #include +#include "coverage.h" #include "dynamic-string.h" #include "flow.h" #include "ofp-print.h" @@ -196,6 +197,7 @@ vconn_open(const char *name, int min_version, struct vconn **vconnp) size_t prefix_len; size_t i; + COVERAGE_INC(vconn_open); check_vconn_classes(); *vconnp = NULL; @@ -455,6 +457,7 @@ again: if (!retval) { struct ofp_header *oh; + COVERAGE_INC(vconn_received); if (VLOG_IS_DBG_ENABLED()) { char *s = ofp_to_string((*msgp)->data, (*msgp)->size, 1); VLOG_DBG_RL(&ofmsg_rl, "%s: received: %s", vconn->name, s); @@ -533,6 +536,7 @@ do_send(struct vconn *vconn, struct ofpbuf *msg) assert(msg->size >= sizeof(struct ofp_header)); assert(((struct ofp_header *) msg->data)->length == htons(msg->size)); if (!VLOG_IS_DBG_ENABLED()) { + COVERAGE_INC(vconn_sent); retval = (vconn->class->send)(vconn, msg); } else { char *s = ofp_to_string(msg->data, msg->size, 1); diff --git a/lib/vlog-modules.def b/lib/vlog-modules.def index 94f28d79..f0f52f5b 100644 --- a/lib/vlog-modules.def +++ b/lib/vlog-modules.def @@ -5,6 +5,7 @@ VLOG_MODULE(bridge) VLOG_MODULE(chain) VLOG_MODULE(cfg) VLOG_MODULE(controller) +VLOG_MODULE(coverage) VLOG_MODULE(ctlpath) VLOG_MODULE(daemon) VLOG_MODULE(datapath) diff --git a/secchan/ofproto.c b/secchan/ofproto.c index 6675692f..b3bc065b 100644 --- a/secchan/ofproto.c +++ b/secchan/ofproto.c @@ -40,6 +40,7 @@ #include #include #include "classifier.h" +#include "coverage.h" #include "discovery.h" #include "dpif.h" #include "executer.h" @@ -843,6 +844,7 @@ ofproto_run1(struct ofproto *p) } if (time_msec() >= p->next_expiration) { + COVERAGE_INC(ofproto_expiration); p->next_expiration = time_msec() + 1000; update_used(p); @@ -874,6 +876,7 @@ ofproto_run2(struct ofproto *p, bool revalidate_all) cbdata.revalidate_subrules = p->need_revalidate; cbdata.revalidate_set = p->revalidate_set; tag_set_init(&p->revalidate_set); + COVERAGE_INC(ofproto_revalidate); classifier_for_each(&p->cls, CLS_INC_EXACT, revalidate_cb, &cbdata); p->need_revalidate = false; } @@ -1008,6 +1011,7 @@ destroy_rule(struct cls_rule *rule_, void *ofproto_) void ofproto_flush_flows(struct ofproto *ofproto) { + COVERAGE_INC(ofproto_flush); classifier_for_each(&ofproto->cls, CLS_INC_ALL, destroy_rule, ofproto); dpif_flow_flush(&ofproto->dpif); if (ofproto->in_band) { @@ -1198,6 +1202,7 @@ update_port(struct ofproto *p, const char *devname) struct ofport *ofport; int error; + COVERAGE_INC(ofproto_update_port); ofport = shash_find_data(&p->port_by_name, devname); error = dpif_port_query_by_name(&p->dpif, devname, &odp_port); if (!error) { @@ -1331,6 +1336,8 @@ ofconn_wait(struct ofconn *ofconn) rconn_run_wait(ofconn->rconn); if (rconn_packet_counter_read (ofconn->reply_counter) < OFCONN_REPLY_MAX) { rconn_recv_wait(ofconn->rconn); + } else { + COVERAGE_INC(ofproto_ofconn_stuck); } } @@ -1483,6 +1490,7 @@ rule_insert(struct ofproto *p, struct rule *rule, struct ofpbuf *packet, /* Install the rule in the datapath only after sending the packet, to * avoid packet reordering. */ if (rule->cr.wc.wildcards) { + COVERAGE_INC(ofproto_add_wc_flow); p->need_revalidate = true; } else { rule_install(p, rule, displaced_rule); @@ -1500,6 +1508,7 @@ rule_create_subrule(struct ofproto *ofproto, struct rule *rule, { struct rule *subrule = rule_create(rule, NULL, 0, rule->idle_timeout, rule->hard_timeout); + COVERAGE_INC(ofproto_subrule_create); cls_rule_from_flow(&subrule->cr, flow, 0, (rule->cr.priority <= UINT16_MAX ? UINT16_MAX : rule->cr.priority)); @@ -1512,6 +1521,7 @@ static void rule_remove(struct ofproto *ofproto, struct rule *rule) { if (rule->cr.wc.wildcards) { + COVERAGE_INC(ofproto_del_wc_flow); ofproto->need_revalidate = true; } else { rule_uninstall(ofproto, rule); @@ -1539,6 +1549,7 @@ rule_make_actions(struct ofproto *p, struct rule *rule, actions_len = a.n_actions * sizeof *a.actions; if (rule->n_odp_actions != a.n_actions || memcmp(rule->odp_actions, a.actions, actions_len)) { + COVERAGE_INC(ofproto_odp_unchanged); free(rule->odp_actions); rule->n_odp_actions = a.n_actions; rule->odp_actions = xmemdup(a.actions, actions_len); @@ -1586,6 +1597,7 @@ rule_reinstall(struct ofproto *ofproto, struct rule *rule) { if (rule->installed) { struct odp_flow_put put; + COVERAGE_INC(ofproto_dp_missed); do_put_flow(ofproto, rule, ODPPF_CREATE | ODPPF_MODIFY, &put); } else { rule_install(ofproto, rule, NULL); @@ -1687,6 +1699,7 @@ send_error(const struct ofconn *ofconn, const struct ofp_header *oh, return; } + COVERAGE_INC(ofproto_error); oem = make_openflow_xid(len + sizeof *oem, OFPT_ERROR, oh ? oh->xid : 0, &buf); oem->type = htons((unsigned int) error >> 16); @@ -1879,6 +1892,7 @@ lookup_valid_rule(struct ofproto *ofproto, const flow_t *flow) && rule->super && ofproto->need_revalidate && !revalidate_rule(ofproto, rule)) { + COVERAGE_INC(ofproto_invalidated); return NULL; } @@ -1925,6 +1939,7 @@ xlate_output_action(struct action_xlate_ctx *ctx, if (!ctx->ofproto->ofhooks->normal_cb(ctx->flow, ctx->packet, ctx->out, ctx->tags, ctx->ofproto->aux)) { + COVERAGE_INC(ofproto_uninstallable); ctx->may_setup_flow = false; } break; @@ -2057,6 +2072,7 @@ xlate_actions(const union ofp_action *in, size_t n_in, { tag_type no_tags = 0; struct action_xlate_ctx ctx; + COVERAGE_INC(ofproto_ofp2odp); odp_actions_init(out); ctx.flow = flow; ctx.recurse = 0; @@ -2094,6 +2110,7 @@ handle_packet_out(struct ofproto *p, struct ofconn *ofconn, } opo = (struct ofp_packet_out *) oh; + COVERAGE_INC(ofproto_packet_out); if (opo->buffer_id != htonl(UINT32_MAX)) { error = pktbuf_retrieve(ofconn->pktbuf, ntohl(opo->buffer_id), &buffer, &in_port); @@ -2133,6 +2150,7 @@ update_port_config(struct ofproto *p, struct ofport *port, } #define REVALIDATE_BITS (OFPPC_NO_RECV | OFPPC_NO_RECV_STP | OFPPC_NO_FWD) if (mask & REVALIDATE_BITS) { + COVERAGE_INC(ofproto_costly_flags); port->opp.config ^= mask & REVALIDATE_BITS; p->need_revalidate = true; } @@ -2419,6 +2437,7 @@ handle_flow_stats_request(struct ofproto *p, struct ofconn *ofconn, } fsr = (struct ofp_flow_stats_request *) osr->body; + COVERAGE_INC(ofproto_flows_req); cbdata.ofproto = p; cbdata.ofconn = ofconn; cbdata.out_port = fsr->out_port; @@ -2473,6 +2492,7 @@ handle_aggregate_stats_request(struct ofproto *p, struct ofconn *ofconn, } asr = (struct ofp_aggregate_stats_request *) osr->body; + COVERAGE_INC(ofproto_agg_request); cbdata.ofproto = p; cbdata.out_port = asr->out_port; cbdata.packet_count = 0; @@ -2608,6 +2628,7 @@ modify_flow(struct ofproto *p, const struct ofp_flow_mod *ofm, rule->n_actions = n_actions; if (rule->cr.wc.wildcards) { + COVERAGE_INC(ofproto_mod_wc_flow); p->need_revalidate = true; } else { rule_update_actions(p, rule); @@ -2831,6 +2852,7 @@ handle_openflow(struct ofconn *ofconn, struct ofproto *p, struct ofp_header *oh = ofp_msg->data; int error; + COVERAGE_INC(ofproto_recv_openflow); switch (oh->type) { case OFPT_ECHO_REQUEST: error = handle_echo_request(ofconn, oh); @@ -2898,6 +2920,7 @@ handle_odp_msg(struct ofproto *p, struct ofpbuf *packet) /* Handle controller actions. */ if (msg->type == _ODPL_ACTION_NR) { + COVERAGE_INC(ofproto_ctlr_action); pinsched_send(p->action_sched, in_port, packet, send_packet_in_action, p); return; @@ -2913,6 +2936,7 @@ handle_odp_msg(struct ofproto *p, struct ofpbuf *packet) struct ofport *port = port_array_get(&p->ports, msg->port); if (port) { if (port->opp.config & OFPPC_NO_PACKET_IN) { + COVERAGE_INC(ofproto_no_packet_in); /* XXX install 'drop' flow entry */ ofpbuf_delete(packet); return; @@ -2921,6 +2945,7 @@ handle_odp_msg(struct ofproto *p, struct ofpbuf *packet) VLOG_WARN_RL(&rl, "packet-in on unknown port %"PRIu16, msg->port); } + COVERAGE_INC(ofproto_packet_in); pinsched_send(p->miss_sched, in_port, packet, send_packet_in_miss, p); return; } @@ -2962,6 +2987,7 @@ revalidate_rule(struct ofproto *p, struct rule *rule) { const flow_t *flow = &rule->cr.flow; + COVERAGE_INC(ofproto_revalidate_rule); if (rule->super) { struct rule *super; super = rule_from_cls_rule(classifier_lookup_wild(&p->cls, flow)); @@ -2969,6 +2995,7 @@ revalidate_rule(struct ofproto *p, struct rule *rule) rule_remove(p, rule); return false; } else if (super != rule->super) { + COVERAGE_INC(ofproto_revalidate_moved); list_remove(&rule->list); list_push_back(&super->list, &rule->list); rule->super = super; @@ -3073,6 +3100,7 @@ expire_rule(struct cls_rule *cls_rule, void *p_) return; } + COVERAGE_INC(ofproto_expired); if (rule->cr.wc.wildcards) { /* Update stats. (This code will be a no-op if the rule expired * due to an idle timeout, because in that case the rule has no @@ -3109,6 +3137,7 @@ update_used(struct ofproto *p) rule = rule_from_cls_rule( classifier_find_rule_exactly(&p->cls, &f->key, 0, UINT16_MAX)); if (!rule || !rule->installed) { + COVERAGE_INC(ofproto_unexpected_rule); dpif_flow_del(&p->dpif, f); continue; } diff --git a/secchan/pktbuf.c b/secchan/pktbuf.c index 1370f649..ba0b5d2e 100644 --- a/secchan/pktbuf.c +++ b/secchan/pktbuf.c @@ -35,6 +35,7 @@ #include "pktbuf.h" #include #include +#include "coverage.h" #include "ofpbuf.h" #include "timeval.h" #include "util.h" @@ -137,12 +138,15 @@ pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp, *bufferp = buffer; *in_port = p->in_port; p->buffer = NULL; + COVERAGE_INC(pktbuf_retrieved); return 0; } else { + COVERAGE_INC(pktbuf_reuse_error); VLOG_WARN_RL(&rl, "attempt to reuse buffer %08"PRIx32, id); error = ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BUFFER_EMPTY); } } else { + COVERAGE_INC(pktbuf_bad_cookie); VLOG_WARN_RL(&rl, "cookie mismatch: %08"PRIx32" != %08"PRIx32, id, (id & PKTBUF_MASK) | (p->cookie << PKTBUF_BITS)); error = ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_COOKIE); diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index e0706a85..f2692817 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -43,6 +43,7 @@ #include #include "bitmap.h" #include "cfg.h" +#include "coverage.h" #include "dirs.h" #include "dpif.h" #include "flow.h" @@ -346,6 +347,8 @@ bridge_reconfigure(void) struct bridge *br, *next; size_t i, j; + COVERAGE_INC(bridge_reconfigure); + /* Collect old bridges. */ svec_init(&old_br); LIST_FOR_EACH (br, struct bridge, node, &all_bridges) { @@ -739,6 +742,7 @@ bridge_wait(void) static void bridge_flush(struct bridge *br) { + COVERAGE_INC(bridge_flush); br->flush = true; if (br->ml) { mac_learning_flush(br->ml); @@ -1789,6 +1793,7 @@ bridge_normal_ofhook_cb(const flow_t *flow, const struct ofpbuf *packet, } #endif + COVERAGE_INC(bridge_process_flow); return process_flow(br, flow, packet, actions, tags); } diff --git a/vswitchd/mgmt.c b/vswitchd/mgmt.c index ab1b36a9..5ffccb70 100644 --- a/vswitchd/mgmt.c +++ b/vswitchd/mgmt.c @@ -34,6 +34,7 @@ #include "bridge.h" #include "cfg.h" +#include "coverage.h" #include "list.h" #include "mgmt.h" #include "openflow/nicira-ext.h" @@ -583,6 +584,8 @@ handle_msg(uint32_t xid, const void *msg, size_t length) struct ofp_header *oh; size_t min_size; + COVERAGE_INC(mgmt_received); + /* Check encapsulated length. */ oh = (struct ofp_header *) msg; if (ntohs(oh->length) > length) {