X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=utilities%2Fovs-dpctl.c;h=c7350e5c4433a947c9ba244e79dd6879532979de;hb=6da1e8091eb2e19de7ba5e0c73ac3e7dd437743d;hp=658f6ba106b3f6c0da6b7790edea15acc20e5037;hpb=25608d9720000ba2f4b4a881ca2a8cf519404f96;p=sliver-openvswitch.git diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c index 658f6ba10..c7350e5c4 100644 --- a/utilities/ovs-dpctl.c +++ b/utilities/ovs-dpctl.c @@ -38,13 +38,16 @@ #include "netdev.h" #include "odp-util.h" #include "shash.h" -#include "svec.h" +#include "sset.h" #include "timeval.h" #include "util.h" #include "vlog.h" VLOG_DEFINE_THIS_MODULE(dpctl); +/* -s, --statistics: Print port statistics? */ +static bool print_statistics; + static const struct command all_commands[]; static void usage(void) NO_RETURN; @@ -68,11 +71,12 @@ parse_options(int argc, char *argv[]) VLOG_OPTION_ENUMS }; static struct option long_options[] = { - {"timeout", required_argument, 0, 't'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, + {"statistics", no_argument, NULL, 's'}, + {"timeout", required_argument, NULL, 't'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, VLOG_LONG_OPTIONS, - {0, 0, 0, 0}, + {NULL, 0, NULL, 0}, }; char *short_options = long_options_to_short_options(long_options); @@ -86,6 +90,10 @@ parse_options(int argc, char *argv[]) } switch (c) { + case 's': + print_statistics = true; + break; + case 't': timeout = strtoul(optarg, NULL, 10); if (timeout <= 0) { @@ -146,17 +154,8 @@ static void run(int retval, const char *message, ...) if (retval) { va_list args; - fprintf(stderr, "%s: ", program_name); va_start(args, message); - vfprintf(stderr, message, args); - va_end(args); - if (retval == EOF) { - fputs(": unexpected end of file\n", stderr); - } else { - fprintf(stderr, ": %s\n", strerror(retval)); - } - - exit(EXIT_FAILURE); + ovs_fatal_valist(retval, message, args); } } @@ -329,6 +328,33 @@ do_del_if(int argc OVS_UNUSED, char *argv[]) } } +static void +print_stat(const char *leader, uint64_t value) +{ + fputs(leader, stdout); + if (value != UINT64_MAX) { + printf("%"PRIu64, value); + } else { + putchar('?'); + } +} + +static void +print_human_size(uint64_t value) +{ + if (value == UINT64_MAX) { + /* Nothing to do. */ + } else if (value >= 1024ULL * 1024 * 1024 * 1024) { + printf(" (%.1f TiB)", value / (1024.0 * 1024 * 1024 * 1024)); + } else if (value >= 1024ULL * 1024 * 1024) { + printf(" (%.1f GiB)", value / (1024.0 * 1024 * 1024)); + } else if (value >= 1024ULL * 1024) { + printf(" (%.1f MiB)", value / (1024.0 * 1024)); + } else if (value >= 1024) { + printf(" (%.1f KiB)", value / 1024.0); + } +} + static void show_dpif(struct dpif *dpif) { @@ -380,6 +406,33 @@ show_dpif(struct dpif *dpif) putchar(')'); } putchar('\n'); + + if (print_statistics) { + const struct netdev_stats *s = &dpif_port.stats; + + print_stat("\t\tRX packets:", s->rx_packets); + print_stat(" errors:", s->rx_errors); + print_stat(" dropped:", s->rx_dropped); + print_stat(" overruns:", s->rx_over_errors); + print_stat(" frame:", s->rx_frame_errors); + printf("\n"); + + print_stat("\t\tTX packets:", s->tx_packets); + print_stat(" errors:", s->tx_errors); + print_stat(" dropped:", s->tx_dropped); + print_stat(" aborted:", s->tx_aborted_errors); + print_stat(" carrier:", s->tx_carrier_errors); + printf("\n"); + + print_stat("\t\tcollisions:", s->collisions); + printf("\n"); + + print_stat("\t\tRX bytes:", s->rx_bytes); + print_human_size(s->rx_bytes); + print_stat(" TX bytes:", s->tx_bytes); + print_human_size(s->tx_bytes); + printf("\n"); + } } dpif_close(dpif); } @@ -404,23 +457,21 @@ do_show(int argc, char *argv[]) } } } else { - struct svec types; + struct sset types; const char *type; - size_t i; - svec_init(&types); + sset_init(&types); dp_enumerate_types(&types); - SVEC_FOR_EACH (i, type, &types) { - struct svec names; + SSET_FOR_EACH (type, &types) { + struct sset names; const char *name; - size_t j; - svec_init(&names); + sset_init(&names); if (dp_enumerate_names(type, &names)) { failure = true; continue; } - SVEC_FOR_EACH (j, name, &names) { + SSET_FOR_EACH (name, &names) { struct dpif *dpif; int error; @@ -432,9 +483,9 @@ do_show(int argc, char *argv[]) failure = true; } } - svec_destroy(&names); + sset_destroy(&names); } - svec_destroy(&types); + sset_destroy(&types); } if (failure) { exit(EXIT_FAILURE); @@ -444,34 +495,34 @@ do_show(int argc, char *argv[]) static void do_dump_dps(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { - struct svec dpif_names, dpif_types; - unsigned int i; + struct sset dpif_names, dpif_types; + const char *type; int error = 0; - svec_init(&dpif_names); - svec_init(&dpif_types); + sset_init(&dpif_names); + sset_init(&dpif_types); dp_enumerate_types(&dpif_types); - for (i = 0; i < dpif_types.n; i++) { - unsigned int j; + SSET_FOR_EACH (type, &dpif_types) { + const char *name; int retval; - retval = dp_enumerate_names(dpif_types.names[i], &dpif_names); + retval = dp_enumerate_names(type, &dpif_names); if (retval) { error = retval; } - for (j = 0; j < dpif_names.n; j++) { + SSET_FOR_EACH (name, &dpif_names) { struct dpif *dpif; - if (!dpif_open(dpif_names.names[j], dpif_types.names[i], &dpif)) { + if (!dpif_open(name, type, &dpif)) { printf("%s\n", dpif_name(dpif)); dpif_close(dpif); } } } - svec_destroy(&dpif_names); - svec_destroy(&dpif_types); + sset_destroy(&dpif_names); + sset_destroy(&dpif_types); if (error) { exit(EXIT_FAILURE); }