--- ipvsadm.c.original Sat Apr 12 00:02:38 2003 +++ ipvsadm.c Fri May 20 08:53:49 2005 @@ -168,7 +168,8 @@ static const char* cmdnames[] = { #define OPT_STATS 0x01000 #define OPT_RATE 0x02000 #define OPT_SORT 0x04000 -#define NUMBER_OF_OPT 15 +#define OPT_EXACT 0x08000 +#define NUMBER_OF_OPT 16 static const char* optnames[] = { "numeric", @@ -186,6 +187,7 @@ static const char* optnames[] = { "stats", "rate", "sort", + "exact", }; /* @@ -198,22 +200,22 @@ static const char* optnames[] = { */ static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = { - /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st -rt srt */ -/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x'}, -/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' ', ' ', ' '}, -/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x'}, -/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, -/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, + /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st -rt srt -x */ +/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' ', ' ', ' ', ' '}, +/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, +/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}, }; /* printing format flags */ @@ -266,8 +268,8 @@ static void fail(int err, char *msg, ... /* various listing functions */ static void list_conn(unsigned int format); -static void list_service(struct ip_vs_rule_user *ur, unsigned int format); -static void list_all(unsigned int format); +static void list_service(struct ip_vs_rule_user *ur, unsigned int format, unsigned int options); +static void list_all(unsigned int format, unsigned int options); static void list_timeout(void); static void list_daemon(void); @@ -294,7 +296,7 @@ int main(int argc, char **argv) /* list the table if there is no other arguement */ if (argc == 1){ - list_all(FMT_NONE); + list_all(FMT_NONE, OPT_NONE); ipvs_close(); return 0; } @@ -355,6 +357,7 @@ parse_options(int argc, char **argv, str {"stats", '\0', POPT_ARG_NONE, NULL, '7'}, {"rate", '\0', POPT_ARG_NONE, NULL, '8'}, {"sort", '\0', POPT_ARG_NONE, NULL, '9'}, + {"exact", 'x', POPT_ARG_NONE, NULL, 'x'}, {NULL, 0, 0, NULL, 0} }; @@ -522,6 +525,9 @@ parse_options(int argc, char **argv, str set_option(options, OPT_SORT); *format |= FMT_SORT; break; + case 'x': + set_option(options, OPT_EXACT); + break; default: fail(2, "invalid option"); } @@ -567,7 +573,7 @@ parse_options(int argc, char **argv, str int *cmd, unsigned int *options, unsigned int *format) { int c, parse; - const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicn"; + const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicnx"; const struct option long_options[] = { {"add-service", 0, 0, 'A'}, {"edit-service", 0, 0, 'E'}, @@ -605,6 +611,7 @@ parse_options(int argc, char **argv, str {"rate", 0, 0, '8'}, {"sort", 0, 0, '9'}, {"help", 0, 0, 'h'}, + {"exact", 0, 0, 'x'}, {0, 0, 0, 0} }; @@ -794,6 +801,9 @@ parse_options(int argc, char **argv, str set_option(options, OPT_SORT); *format |= FMT_SORT; break; + case 'x': + set_option(options, OPT_EXACT); + break; default: fail(2, "invalid option"); } @@ -859,19 +869,19 @@ static int process_options(int argc, cha if (options & OPT_CONNECTION) list_conn(format); else if (options & OPT_SERVICE) - list_service(&urule, format); + list_service(&urule, format, options); else if (options & OPT_TIMEOUT) list_timeout(); else if (options & OPT_DAEMON) list_daemon(); else - list_all(format); + list_all(format, options); return 0; case IP_VS_SO_SET_RESTORE: return restore_table(argc, argv, reading_stdin); case IP_VS_SO_SET_SAVE: format |= FMT_RULE; - list_all(format); + list_all(format, options); return 0; } @@ -1172,6 +1182,8 @@ static void usage_exit(const char *progr " --daemon output of daemon information\n" " --stats output of statistics information\n" " --rate output of rate information\n" + " --exact -x show raw numbers rather than human-readable numbers.\n" + " used for --stats and --rate options only\n" " --sort sorting output of service/server entries\n" " --numeric -n numeric output of addresses and ports\n", DEF_SCHED); @@ -1399,6 +1411,16 @@ static void print_largenum(unsigned long } +static void print_exactnum(unsigned long long i) +{ + char mytmp[128]; + int mylen; + sprintf(mytmp, "%llu", i); + mylen = strlen(mytmp); + printf("%*llu", mylen<=8?9:mylen+1, i); +} + + static void print_title(unsigned int format) { if (format & FMT_STATS) @@ -1418,7 +1440,7 @@ static void print_title(unsigned int for static void -print_service(struct ip_vs_service_user *svc, unsigned int format) +print_service(struct ip_vs_service_user *svc, unsigned int format, unsigned int options) { struct ip_vs_get_dests *d; char svc_name[64]; @@ -1470,18 +1492,34 @@ print_service(struct ip_vs_service_user } } else if (format & FMT_STATS) { printf("%-33s", svc_name); - print_largenum(svc->stats.conns); - print_largenum(svc->stats.inpkts); - print_largenum(svc->stats.outpkts); - print_largenum(svc->stats.inbytes); - print_largenum(svc->stats.outbytes); + if (options & OPT_EXACT) { + print_exactnum(svc->stats.conns); + print_exactnum(svc->stats.inpkts); + print_exactnum(svc->stats.outpkts); + print_exactnum(svc->stats.inbytes); + print_exactnum(svc->stats.outbytes); + } else { + print_largenum(svc->stats.conns); + print_largenum(svc->stats.inpkts); + print_largenum(svc->stats.outpkts); + print_largenum(svc->stats.inbytes); + print_largenum(svc->stats.outbytes); + } } else if (format & FMT_RATE) { printf("%-33s", svc_name); - print_largenum(svc->stats.cps); - print_largenum(svc->stats.inpps); - print_largenum(svc->stats.outpps); - print_largenum(svc->stats.inbps); - print_largenum(svc->stats.outbps); + if (options & OPT_EXACT) { + print_exactnum(svc->stats.cps); + print_exactnum(svc->stats.inpps); + print_exactnum(svc->stats.outpps); + print_exactnum(svc->stats.inbps); + print_exactnum(svc->stats.outbps); + } else { + print_largenum(svc->stats.cps); + print_largenum(svc->stats.inpps); + print_largenum(svc->stats.outpps); + print_largenum(svc->stats.inbps); + print_largenum(svc->stats.outbps); + } } else { printf("%s %s", svc_name, svc->sched_name); if (svc->flags & IP_VS_SVC_F_PERSISTENT) { @@ -1513,19 +1551,32 @@ print_service(struct ip_vs_service_user fwd_switch(e->flags), e->weight); } else if (format & FMT_STATS) { printf(" -> %-28s", dname); - print_largenum(e->stats.conns); - print_largenum(e->stats.inpkts); - print_largenum(e->stats.outpkts); - print_largenum(e->stats.inbytes); - print_largenum(e->stats.outbytes); + if (options & OPT_EXACT) { + print_exactnum(e->stats.conns); + print_exactnum(e->stats.inpkts); + print_exactnum(e->stats.outpkts); + print_exactnum(e->stats.inbytes); + print_exactnum(e->stats.outbytes); + } else { + print_largenum(e->stats.conns); + print_largenum(e->stats.inpkts); + print_largenum(e->stats.outpkts); + print_largenum(e->stats.inbytes); + print_largenum(e->stats.outbytes); + } printf("\n"); } else if (format & FMT_RATE) { printf(" -> %-28s %8u %8u %8u", dname, e->stats.cps, e->stats.inpps, e->stats.outpps); - print_largenum(e->stats.inbps); - print_largenum(e->stats.outbps); + if (options & OPT_EXACT) { + print_exactnum(e->stats.inbps); + print_exactnum(e->stats.outbps); + } else { + print_largenum(e->stats.inbps); + print_largenum(e->stats.outbps); + } printf("\n"); } else printf(" -> %-28s %-7s %-6d %-10u %-10u\n", @@ -1537,7 +1588,7 @@ print_service(struct ip_vs_service_user } -static void list_service(struct ip_vs_rule_user *ur, unsigned int format) +static void list_service(struct ip_vs_rule_user *ur, unsigned int format, unsigned int options) { struct ip_vs_service_user *svc; @@ -1548,12 +1599,12 @@ static void list_service(struct ip_vs_ru } print_title(format); - print_service(svc, format); + print_service(svc, format, options); free(svc); } -static void list_all(unsigned int format) +static void list_all(unsigned int format, unsigned int options) { struct ip_vs_get_services *get; int i; @@ -1573,7 +1624,7 @@ static void list_all(unsigned int format print_title(format); for (i=0; inum_services; i++) - print_service(&get->entrytable[i], format); + print_service(&get->entrytable[i], format, options); free(get); }