From: Stephen Hemminger Date: Sun, 2 Nov 2014 20:49:19 +0000 (-0800) Subject: ip: add iec formatted option and cleanup code X-Git-Tag: v3.18.0~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e264abc3a3d8c303b235c8f15c420e4feabb7fe;p=thirdparty%2Fiproute2.git ip: add iec formatted option and cleanup code Add a new -iec option in addition to -human. Cleanup code so the formatting of numbers is done in one function, not 2 ways and 2 sizes. --- diff --git a/include/utils.h b/include/utils.h index 7bb19e97b..eef9c42d2 100644 --- a/include/utils.h +++ b/include/utils.h @@ -12,6 +12,7 @@ extern int preferred_family; extern int human_readable; +extern int use_iec; extern int show_stats; extern int show_details; extern int show_raw; diff --git a/ip/ip.c b/ip/ip.c index 6b352c8a7..e4b201fd8 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -25,6 +25,7 @@ int preferred_family = AF_UNSPEC; int human_readable = 0; +int use_iec = 0; int show_stats = 0; int show_details = 0; int resolve_hosts = 0; @@ -48,7 +49,7 @@ static void usage(void) " tunnel | tuntap | maddr | mroute | mrule | monitor | xfrm |\n" " netns | l2tp | tcp_metrics | token | netconf }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" -" -h[uman-readable] |\n" +" -h[uman-readable] | -iec |\n" " -f[amily] { inet | inet6 | ipx | dnet | bridge | link } |\n" " -4 | -6 | -I | -D | -B | -0 |\n" " -l[oops] { maximum-addr-flush-attempts } |\n" @@ -217,6 +218,8 @@ int main(int argc, char **argv) } else if (matches(opt, "-human") == 0 || matches(opt, "-human-readable") == 0) { ++human_readable; + } else if (matches(opt, "-iec") == 0) { + ++use_iec; } else if (matches(opt, "-stats") == 0 || matches(opt, "-statistics") == 0) { ++show_stats; diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 4b8ddca29..efea88c7e 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -319,61 +319,34 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) } } - -static void print_human64(FILE *fp, int length, uint64_t count) +static void print_num(FILE *fp, unsigned width, uint64_t count) { - char * prefix = "kMGTPE"; - int written = 0, i; + const char *prefix = "kMGTPE"; + const unsigned int base = use_iec ? 1024 : 1000; uint64_t powi = 1; + char buf[64]; - if (count < 1000) { - /* we are below 1000, so no precision and no prefix */ - written = fprintf(fp, "%"PRIu64, count); - } else { - /* increase value by a factor of 1000 and print - * if result is something a human can read */ - for (i = 0; i < 6; i++) { - powi *= 1000; - if (count / 1000 < powi) { - written = fprintf(fp, "%"PRIu64".%"PRIu64"%c", - count / powi, count * 10 / powi % 10, *prefix); - break; - } - prefix++; - } + if (!human_readable || count < base) { + fprintf(fp, "%-*"PRIu64, width, count); + return; } - do { - fputc(' ', fp); - } while (written++ < length); -} - -static void print_human32(FILE *fp, int length, uint32_t count) -{ - char * prefix = "KMG"; - int written = 0, i; - uint32_t powi = 1; + /* increase value by a factor of 1000/1024 and print + * if result is something a human can read */ + for(;;) { + powi *= base; + if (count / base < powi) + break; - if (count < 1000) { - /* we are below 1000, so no precision and no prefix */ - written = fprintf(fp, "%u", count); - } else { - /* increase value by a factor of 1000 and print - * if result is something a human can read */ - for (i = 0; i < 3; i++) { - powi *= 1000; - if (count / 1000 < powi) { - written = fprintf(fp, "%u.%u%c", - count / powi, count * 10 / powi % 10, *prefix); - break; - } - prefix++; - } + if (!prefix[1]) + break; + ++prefix; } - do { - fputc(' ', fp); - } while (written++ < length); + snprintf(buf, sizeof(buf), "%.1f%c%s", (double) count / powi, + *prefix, use_iec ? "i" : ""); + + fprintf(fp, "%-*s", width, buf); } static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s, @@ -382,76 +355,45 @@ static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s, /* RX stats */ fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", s->rx_compressed ? "compressed" : "", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human64(fp, 10, (uint64_t)s->rx_bytes); - print_human64(fp, 8, (uint64_t)s->rx_packets); - print_human64(fp, 7, (uint64_t)s->rx_errors); - print_human64(fp, 7, (uint64_t)s->rx_dropped); - print_human64(fp, 7, (uint64_t)s->rx_over_errors); - print_human64(fp, 7, (uint64_t)s->multicast); - if (s->rx_compressed) - print_human64(fp, 7, (uint64_t)s->rx_compressed); - } else { - fprintf(fp, " %-10"PRIu64" %-8"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"", - (uint64_t)s->rx_bytes, - (uint64_t)s->rx_packets, - (uint64_t)s->rx_errors, - (uint64_t)s->rx_dropped, - (uint64_t)s->rx_over_errors, - (uint64_t)s->multicast); - if (s->rx_compressed) - fprintf(fp, " %-7"PRIu64"", - (uint64_t)s->rx_compressed); - } + + fprintf(fp, " "); + print_num(fp, 10, s->rx_bytes); + print_num(fp, 8, s->rx_packets); + print_num(fp, 7, s->rx_errors); + print_num(fp, 7, s->rx_dropped); + print_num(fp, 7, s->rx_over_errors); + print_num(fp, 7, s->multicast); + if (s->rx_compressed) + print_num(fp, 7, s->rx_compressed); /* RX error stats */ if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human64(fp, 8, (uint64_t)s->rx_length_errors); - print_human64(fp, 7, (uint64_t)s->rx_crc_errors); - print_human64(fp, 7, (uint64_t)s->rx_frame_errors); - print_human64(fp, 7, (uint64_t)s->rx_fifo_errors); - print_human64(fp, 7, (uint64_t)s->rx_missed_errors); - } else { - fprintf(fp, " %-8"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"", - (uint64_t)s->rx_length_errors, - (uint64_t)s->rx_crc_errors, - (uint64_t)s->rx_frame_errors, - (uint64_t)s->rx_fifo_errors, - (uint64_t)s->rx_missed_errors); - } + + fprintf(fp, " "); + print_num(fp, 8, s->rx_length_errors); + print_num(fp, 7, s->rx_crc_errors); + print_num(fp, 7, s->rx_frame_errors); + print_num(fp, 7, s->rx_fifo_errors); + print_num(fp, 7, s->rx_missed_errors); } fprintf(fp, "%s", _SL_); /* TX stats */ fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", - (uint64_t)s->tx_compressed ? "compressed" : "", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human64(fp, 10, (uint64_t)s->tx_bytes); - print_human64(fp, 8, (uint64_t)s->tx_packets); - print_human64(fp, 7, (uint64_t)s->tx_errors); - print_human64(fp, 7, (uint64_t)s->tx_dropped); - print_human64(fp, 7, (uint64_t)s->tx_carrier_errors); - print_human64(fp, 7, (uint64_t)s->collisions); - if (s->tx_compressed) - print_human64(fp, 7, (uint64_t)s->tx_compressed); - } else { - fprintf(fp, " %-10"PRIu64" %-8"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"", - (uint64_t)s->tx_bytes, - (uint64_t)s->tx_packets, - (uint64_t)s->tx_errors, - (uint64_t)s->tx_dropped, - (uint64_t)s->tx_carrier_errors, - (uint64_t)s->collisions); - if (s->tx_compressed) - fprintf(fp, " %-7"PRIu64"", - (uint64_t)s->tx_compressed); - } + s->tx_compressed ? "compressed" : "", _SL_); + + + fprintf(fp, " "); + print_num(fp, 10, s->tx_bytes); + print_num(fp, 8, s->tx_packets); + print_num(fp, 7, s->tx_errors); + print_num(fp, 7, s->tx_dropped); + print_num(fp, 7, s->tx_carrier_errors); + print_num(fp, 7, s->collisions); + if (s->tx_compressed) + print_num(fp, 7, s->tx_compressed); /* TX error stats */ if (show_stats > 1) { @@ -460,24 +402,14 @@ static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s, if (carrier_changes) fprintf(fp, " transns"); fprintf(fp, "%s", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human64(fp, 8, (uint64_t)s->tx_aborted_errors); - print_human64(fp, 7, (uint64_t)s->tx_fifo_errors); - print_human64(fp, 7, (uint64_t)s->tx_window_errors); - print_human64(fp, 7, (uint64_t)s->tx_heartbeat_errors); - if (carrier_changes) - print_human64(fp, 7, (uint64_t)*(uint32_t*)RTA_DATA(carrier_changes)); - } else { - fprintf(fp, " %-8"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"", - (uint64_t)s->tx_aborted_errors, - (uint64_t)s->tx_fifo_errors, - (uint64_t)s->tx_window_errors, - (uint64_t)s->tx_heartbeat_errors); - if (carrier_changes) - fprintf(fp, " %-7u", - *(uint32_t*)RTA_DATA(carrier_changes)); - } + + fprintf(fp, " "); + print_num(fp, 8, s->tx_aborted_errors); + print_num(fp, 7, s->tx_fifo_errors); + print_num(fp, 7, s->tx_window_errors); + print_num(fp, 7, s->tx_heartbeat_errors); + if (carrier_changes) + print_num(fp, 7, *(uint32_t*)RTA_DATA(carrier_changes)); } } @@ -487,67 +419,44 @@ static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s, /* RX stats */ fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", s->rx_compressed ? "compressed" : "", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human32(fp, 10, s->rx_bytes); - print_human32(fp, 8, s->rx_packets); - print_human32(fp, 7, s->rx_errors); - print_human32(fp, 7, s->rx_dropped); - print_human32(fp, 7, s->rx_over_errors); - print_human32(fp, 7, s->multicast); - if (s->rx_compressed) - print_human32(fp, 7, s->rx_compressed); - } else { - fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", - s->rx_bytes, s->rx_packets, s->rx_errors, - s->rx_dropped, s->rx_over_errors, - s->multicast); - if (s->rx_compressed) - fprintf(fp, " %-7u", s->rx_compressed); - } + + + fprintf(fp, " "); + print_num(fp, 10, s->rx_bytes); + print_num(fp, 8, s->rx_packets); + print_num(fp, 7, s->rx_errors); + print_num(fp, 7, s->rx_dropped); + print_num(fp, 7, s->rx_over_errors); + print_num(fp, 7, s->multicast); + if (s->rx_compressed) + print_num(fp, 7, s->rx_compressed); /* RX error stats */ if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human32(fp, 8, s->rx_length_errors); - print_human32(fp, 7, s->rx_crc_errors); - print_human32(fp, 7, s->rx_frame_errors); - print_human32(fp, 7, s->rx_fifo_errors); - print_human32(fp, 7, s->rx_missed_errors); - } else { - fprintf(fp, " %-8u %-7u %-7u %-7u %-7u", - s->rx_length_errors, - s->rx_crc_errors, - s->rx_frame_errors, - s->rx_fifo_errors, - s->rx_missed_errors); - } + fprintf(fp, " "); + print_num(fp, 8, s->rx_length_errors); + print_num(fp, 7, s->rx_crc_errors); + print_num(fp, 7, s->rx_frame_errors); + print_num(fp, 7, s->rx_fifo_errors); + print_num(fp, 7, s->rx_missed_errors); } fprintf(fp, "%s", _SL_); /* TX stats */ fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", s->tx_compressed ? "compressed" : "", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human32(fp, 10, s->tx_bytes); - print_human32(fp, 8, s->tx_packets); - print_human32(fp, 7, s->tx_errors); - print_human32(fp, 7, s->tx_dropped); - print_human32(fp, 7, s->tx_carrier_errors); - print_human32(fp, 7, s->collisions); - if (s->tx_compressed) - print_human32(fp, 7, s->tx_compressed); - } else { - fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", - s->tx_bytes, s->tx_packets, s->tx_errors, - s->tx_dropped, s->tx_carrier_errors, s->collisions); - if (s->tx_compressed) - fprintf(fp, " %-7u", s->tx_compressed); - } + + fprintf(fp, " "); + print_num(fp, 10, s->tx_bytes); + print_num(fp, 8, s->tx_packets); + print_num(fp, 7, s->tx_errors); + print_num(fp, 7, s->tx_dropped); + print_num(fp, 7, s->tx_carrier_errors); + print_num(fp, 7, s->collisions); + if (s->tx_compressed) + print_num(fp, 7, s->tx_compressed); /* TX error stats */ if (show_stats > 1) { @@ -556,24 +465,14 @@ static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s, if (carrier_changes) fprintf(fp, " transns"); fprintf(fp, "%s", _SL_); - if (human_readable) { - fprintf(fp, " "); - print_human32(fp, 8, s->tx_aborted_errors); - print_human32(fp, 7, s->tx_fifo_errors); - print_human32(fp, 7, s->tx_window_errors); - print_human32(fp, 7, s->tx_heartbeat_errors); - if (carrier_changes) - print_human32(fp, 7, *(uint32_t*)RTA_DATA(carrier_changes)); - } else { - fprintf(fp, " %-8u %-7u %-7u %-7u", - s->tx_aborted_errors, - s->tx_fifo_errors, - s->tx_window_errors, - s->tx_heartbeat_errors); - if (carrier_changes) - fprintf(fp, " %-7u", - *(uint32_t*)RTA_DATA(carrier_changes)); - } + + fprintf(fp, " "); + print_num(fp, 8, s->tx_aborted_errors); + print_num(fp, 7, s->tx_fifo_errors); + print_num(fp, 7, s->tx_window_errors); + print_num(fp, 7, s->tx_heartbeat_errors); + if (carrier_changes) + print_num(fp, 7, *(uint32_t*)RTA_DATA(carrier_changes)); } } diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 9747c4cc0..4ee1d627e 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -661,11 +661,23 @@ specifies what group of devices to show. .B up only display running interfaces. -.SH "NOTES" -Human readable values are calculated with SI prefixes, so with a decimal -base, not binary. (This is unlike -.BR ifconfig (8) -, with uses binary prefix.) 1,000 bytes are 1 kB, 1,000 kB are 1 MB, ... +The show command has additional formatting options: + +.TP +.BR "\-s" , " \-stats", " \-statistics" +output more statistics about packet usage. + +.TP +.BR "\-d", " \-details" +output more detailed information. + +.TP +.BR "\-h", " \-human", " \-human-readble" +output statistics with human readable values number followed by suffix + +.TP +.BR "\-iec" +print human readable rates in IEC units (ie. 1K = 1024). .SH "EXAMPLES" .PP